PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / trunk
Secure Custom Fields vtrunk
6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / includes / admin / post-types / admin-field-groups.php
secure-custom-fields / includes / admin / post-types Last commit date
admin-field-group.php 2 months ago admin-field-groups.php 10 months ago admin-post-type.php 1 year ago admin-post-types.php 10 months ago admin-taxonomies.php 10 months ago admin-taxonomy.php 1 year ago class-acf-admin-ui-options-page.php 1 year ago class-acf-admin-ui-options-pages.php 10 months ago index.php 1 year ago
admin-field-groups.php
386 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 if ( ! class_exists( 'ACF_Admin_Field_Groups' ) ) :
8 class ACF_Admin_Field_Groups extends ACF_Admin_Internal_Post_Type_List {
9
10
11 /**
12 * The slug for the internal post type.
13 *
14 * @since ACF 6.1
15 * @var string
16 */
17 public $post_type = 'acf-field-group';
18
19 /**
20 * The admin body class used for the post type.
21 *
22 * @since ACF 6.1
23 * @var string
24 */
25 public $admin_body_class = 'acf-admin-field-groups';
26
27 /**
28 * The name of the store used for the post type.
29 *
30 * @var string
31 */
32 public $store = 'field-groups';
33
34 /**
35 * Constructor.
36 *
37 * @since ACF 5.0.0
38 */
39 public function __construct() {
40 add_action( 'admin_menu', array( $this, 'admin_menu' ), 7 );
41 add_action( 'load-edit.php', array( $this, 'handle_redirection' ) );
42 add_filter( 'post_class', array( $this, 'get_admin_table_post_classes' ), 10, 3 );
43
44 parent::__construct();
45 }
46
47 /**
48 * Add any menu items required for field groups.
49 *
50 * @since ACF 6.1
51 */
52 public function admin_menu() {
53 $parent_slug = 'edit.php?post_type=acf-field-group';
54 $cap = acf_get_setting( 'capability' );
55 add_submenu_page( $parent_slug, __( 'Field Groups', 'secure-custom-fields' ), __( 'Field Groups', 'secure-custom-fields' ), $cap, $parent_slug );
56 }
57
58 /**
59 * Redirects users from ACF 4.0 admin page.
60 *
61 * @since ACF 5.7.6
62 */
63 public function handle_redirection() {
64 if ( isset( $_GET['post_type'] ) && $_GET['post_type'] === 'acf' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
65 wp_safe_redirect( $this->get_admin_url() );
66 exit;
67 }
68 }
69
70 /**
71 * Customizes the admin table columns.
72 *
73 * @date 1/4/20
74 * @since ACF 5.9.0
75 *
76 * @param array $_columns The columns array.
77 * @return array
78 */
79 public function admin_table_columns( $_columns ) {
80 // Set the "no found" label to be our custom HTML for no results.
81 if ( empty( acf_request_arg( 's' ) ) ) {
82 global $wp_post_types;
83 $wp_post_types['acf-field-group']->labels->not_found = $this->get_not_found_html();
84 }
85
86 $columns = array(
87 'cb' => $_columns['cb'],
88 'title' => $_columns['title'],
89 'acf-description' => __( 'Description', 'secure-custom-fields' ),
90 'acf-key' => __( 'Key', 'secure-custom-fields' ),
91 'acf-location' => __( 'Location', 'secure-custom-fields' ),
92 'acf-count' => __( 'Fields', 'secure-custom-fields' ),
93 );
94
95 if ( acf_get_local_json_files( $this->post_type ) ) {
96 $columns['acf-json'] = __( 'Local JSON', 'secure-custom-fields' );
97 }
98
99 return $columns;
100 }
101
102 /**
103 * Renders a specific admin table column.
104 *
105 * @date 17/4/20
106 * @since ACF 5.9.0
107 *
108 * @param string $column_name The name of the column to display.
109 * @param array $post The main ACF post array.
110 * @return void
111 */
112 public function render_admin_table_column( $column_name, $post ) {
113 switch ( $column_name ) {
114
115 // Key.
116 case 'acf-key':
117 echo '<i class="acf-icon acf-icon-key-solid"></i>';
118 echo esc_html( $post['key'] );
119 break;
120
121 // Description.
122 case 'acf-description':
123 if ( ( is_string( $post['description'] ) || is_numeric( $post['description'] ) ) && ! empty( $post['description'] ) ) {
124 echo '<span class="acf-description">' . acf_esc_html( $post['description'] ) . '</span>';
125 } else {
126 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
127 echo '<span class="screen-reader-text">' . esc_html__( 'No description', 'secure-custom-fields' ) . '</span>';
128 }
129 break;
130
131 // Location.
132 case 'acf-location':
133 $this->render_admin_table_column_locations( $post );
134 break;
135
136 // Count.
137 case 'acf-count':
138 $this->render_admin_table_column_num_fields( $post );
139 break;
140
141 // Local JSON.
142 case 'acf-json':
143 $this->render_admin_table_column_local_status( $post );
144 break;
145 }
146 }
147
148 /**
149 * Displays a visual representation of the field group's locations.
150 *
151 * @date 1/4/20
152 * @since ACF 5.9.0
153 *
154 * @param array $field_group The field group.
155 * @return void
156 */
157 public function render_admin_table_column_locations( $field_group ) {
158 $objects = array();
159
160 // Loop over location rules and determine connected object types.
161 if ( $field_group['location'] ) {
162 foreach ( $field_group['location'] as $i => $rules ) {
163
164 // Determine object types for each rule.
165 foreach ( $rules as $j => $rule ) {
166
167 // Get location type and subtype for the current rule.
168 $location = acf_get_location_rule( $rule['param'] );
169 $location_object_type = '';
170 $location_object_subtype = '';
171 if ( $location ) {
172 $location_object_type = $location->get_object_type( $rule );
173 $location_object_subtype = $location->get_object_subtype( $rule );
174 }
175 $rules[ $j ]['object_type'] = $location_object_type;
176 $rules[ $j ]['object_subtype'] = $location_object_subtype;
177 }
178
179 // Now that each $rule contains object type data...
180 $object_types = array_column( $rules, 'object_type' );
181 $object_types = array_filter( $object_types );
182 $object_types = array_values( $object_types );
183 if ( $object_types ) {
184 $object_type = $object_types[0];
185 } else {
186 continue;
187 }
188
189 $object_subtypes = array_column( $rules, 'object_subtype' );
190 $object_subtypes = array_filter( $object_subtypes );
191 $object_subtypes = array_values( $object_subtypes );
192 $object_subtypes = array_map( 'acf_array', $object_subtypes );
193 if ( count( $object_subtypes ) > 1 ) {
194 $object_subtypes = call_user_func_array( 'array_intersect', $object_subtypes );
195 $object_subtypes = array_values( $object_subtypes );
196 } elseif ( $object_subtypes ) {
197 $object_subtypes = $object_subtypes[0];
198 } else {
199 $object_subtypes = array( '' );
200 }
201
202 // Append to objects.
203 foreach ( $object_subtypes as $object_subtype ) {
204 $object = acf_get_object_type( $object_type, $object_subtype );
205 if ( $object ) {
206 $objects[ $object->name ] = $object;
207 }
208 }
209 }
210 }
211
212 // Reset keys.
213 $objects = array_values( $objects );
214
215 // Display.
216 $html = '';
217 if ( $objects ) {
218 $limit = 3;
219 $total = count( $objects );
220
221 // Icon.
222 $html .= '<span class="dashicons ' . $objects[0]->icon . ( $total > 1 ? ' acf-multi-dashicon' : '' ) . '"></span>';
223
224 // Labels.
225 $labels = array_column( $objects, 'label' );
226 $labels = array_slice( $labels, 0, 3 );
227 $html .= implode( ', ', $labels );
228
229 // More.
230 if ( $total > $limit ) {
231 $html .= ', ...';
232 }
233 } else {
234 $html = '<span class="dashicons dashicons-businesswoman"></span> ' . __( 'Various', 'secure-custom-fields' );
235 }
236
237 // Filter.
238 echo acf_esc_html( $html );
239 }
240
241 /**
242 * Renders the number of fields created for the field group in the list table.
243 *
244 * @since ACF 6.1.5
245 *
246 * @param array $field_group The main field group array.
247 * @return void
248 */
249 public function render_admin_table_column_num_fields( $field_group ) {
250 $field_count = acf_get_field_count( $field_group );
251
252 if ( ! $field_count || ! is_numeric( $field_count ) ) {
253 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
254 echo '<span class="screen-reader-text">' . esc_html__( 'No fields', 'secure-custom-fields' ) . '</span>';
255 return;
256 }
257
258 // If in JSON but not synced or in trash, the link won't work.
259 if ( empty( $field_group['ID'] ) || 'trash' === get_post_status( $field_group['ID'] ) ) {
260 echo esc_html( number_format_i18n( $field_count ) );
261 return;
262 }
263
264 printf(
265 '<a href="%s">%s</a>',
266 esc_url( admin_url( 'post.php?action=edit&post=' . $field_group['ID'] ) ),
267 esc_html( number_format_i18n( $field_count ) )
268 );
269 }
270
271 /**
272 * Gets the class(es) to be used by field groups in the list table.
273 *
274 * @since ACF 6.2.8
275 *
276 * @param array $classes An array of the classes used by the field group.
277 * @param array $css_class An array of additional classes added to the field group.
278 * @param integer $post_id The ID of the field group.
279 * @return array
280 */
281 public function get_admin_table_post_classes( $classes, $css_class, $post_id ) {
282 // Bail early if not in the field group list table.
283 if ( ! is_admin() || $this->post_type !== get_post_type( $post_id ) ) {
284 return $classes;
285 }
286
287 return apply_filters( 'acf/field_group/list_table_classes', $classes, $css_class, $post_id );
288 }
289
290 /**
291 * Fires when trashing a field group.
292 *
293 * @date 8/01/2014
294 * @since ACF 5.0.0
295 *
296 * @param integer $post_id The post ID.
297 * @return void
298 */
299 public function trashed_post( $post_id ) {
300 if ( get_post_type( $post_id ) === $this->post_type ) {
301 acf_trash_field_group( $post_id );
302 }
303 }
304
305 /**
306 * Fires when untrashing a field group.
307 *
308 * @date 8/01/2014
309 * @since ACF 5.0.0
310 *
311 * @param integer $post_id The post ID.
312 * @return void
313 */
314 public function untrashed_post( $post_id ) {
315 if ( get_post_type( $post_id ) === $this->post_type ) {
316 acf_untrash_field_group( $post_id );
317 }
318 }
319
320 /**
321 * Fires when deleting a field group.
322 *
323 * @date 8/01/2014
324 * @since ACF 5.0.0
325 *
326 * @param integer $post_id The post ID.
327 * @return void
328 */
329 public function deleted_post( $post_id ) {
330 if ( get_post_type( $post_id ) === $this->post_type ) {
331 acf_delete_field_group( $post_id );
332 }
333 }
334
335 /**
336 * Gets the translated action notice text for list table actions (activate, deactivate, sync, etc.).
337 *
338 * @since ACF 6.1
339 *
340 * @param string $action The action being performed.
341 * @param integer $count The number of items the action was performed on.
342 * @return string
343 */
344 public function get_action_notice_text( $action, $count = 1 ) {
345 $text = '';
346 $count = (int) $count;
347
348 switch ( $action ) {
349 case 'acfactivatecomplete':
350 $text = sprintf(
351 /* translators: %s number of field groups activated */
352 _n( '%s field group activated.', '%s field groups activated.', $count, 'secure-custom-fields' ),
353 $count
354 );
355 break;
356 case 'acfdeactivatecomplete':
357 $text = sprintf(
358 /* translators: %s number of field groups deactivated */
359 _n( '%s field group deactivated.', '%s field groups deactivated.', $count, 'secure-custom-fields' ),
360 $count
361 );
362 break;
363 case 'acfduplicatecomplete':
364 $text = sprintf(
365 /* translators: %s number of field groups duplicated */
366 _n( '%s field group duplicated.', '%s field groups duplicated.', $count, 'secure-custom-fields' ),
367 $count
368 );
369 break;
370 case 'acfsynccomplete':
371 $text = sprintf(
372 /* translators: %s number of field groups synchronized */
373 _n( '%s field group synchronized.', '%s field groups synchronized.', $count, 'secure-custom-fields' ),
374 $count
375 );
376 break;
377 }
378
379 return $text;
380 }
381 }
382
383 // Instantiate.
384 acf_new_instance( 'ACF_Admin_Field_Groups' );
385 endif; // Class exists check.
386