PluginProbe
Advanced Custom Fields (ACF®) / 5.9.2
Advanced Custom Fields (ACF®) v5.9.2
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / admin / admin-field-groups.php
admin-field-groups.php
880 lines 23.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
5 if( ! class_exists('ACF_Admin_Field_Groups') ) :
6
7 class ACF_Admin_Field_Groups {
8
9 /**
10 * Array of field groups availbale for sync.
11 *
12 * @since 5.9.0
13 * @var array
14 */
15 public $sync = array();
16
17 /**
18 * The current view (post_status).
19 *
20 * @since 5.9.0
21 * @var string
22 */
23 public $view = '';
24
25 /**
26 * Constructor.
27 *
28 * @date 5/03/2014
29 * @since 5.0.0
30 *
31 * @param void
32 * @return void
33 */
34 public function __construct() {
35
36 // Add hooks.
37 add_action( 'load-edit.php', array( $this, 'handle_redirection') );
38 add_action( 'current_screen', array( $this, 'current_screen' ) );
39
40 // Handle post status change events.
41 add_action( 'trashed_post', array( $this, 'trashed_post') );
42 add_action( 'untrashed_post', array( $this, 'untrashed_post') );
43 add_action( 'deleted_post', array( $this, 'deleted_post') );
44 }
45
46 /**
47 * Returns the Field Groups admin URL.
48 *
49 * @date 27/3/20
50 * @since 5.9.0
51 *
52 * @param string $params Extra URL params.
53 * @return string
54 */
55 public function get_admin_url( $params = '' ) {
56 return admin_url( "edit.php?post_type=acf-field-group{$params}" );
57 }
58
59 /**
60 * Returns the Field Groups admin URL taking into account the current view.
61 *
62 * @date 27/3/20
63 * @since 5.9.0
64 *
65 * @param string $params Extra URL params.
66 * @return string
67 */
68 public function get_current_admin_url( $params = '' ) {
69 return $this->get_admin_url( ( $this->view ? '&post_status=' . $this->view : '' ) . $params );
70 }
71
72 /**
73 * Redirects users from ACF 4.0 admin page.
74 *
75 * @date 17/9/18
76 * @since 5.7.6
77 *
78 * @param void
79 * @return void
80 */
81 public function handle_redirection() {
82 if( isset($_GET['post_type']) && $_GET['post_type'] === 'acf' ) {
83 wp_redirect( $this->get_admin_url() );
84 exit;
85 }
86 }
87
88 /**
89 * Constructor for the Field Groups admin page.
90 *
91 * @date 21/07/2014
92 * @since 5.0.0
93 *
94 * @param void
95 * @return void
96 */
97 public function current_screen() {
98
99 // Bail early if not Field Groups admin page.
100 if( !acf_is_screen('edit-acf-field-group') ) {
101 return;
102 }
103
104 // Get the current view.
105 $this->view = isset( $_GET['post_status'] ) ? sanitize_text_field( $_GET['post_status'] ) : '';
106
107 // Setup and check for custom actions..
108 $this->setup_sync();
109 $this->check_sync();
110 $this->check_duplicate();
111
112 // Modify publish post status text and order.
113 global $wp_post_statuses;
114 $wp_post_statuses['publish']->label_count = _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'acf' );
115 $wp_post_statuses['trash'] = acf_extract_var( $wp_post_statuses, 'trash' );
116
117 // Add hooks.
118 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts') );
119 add_action( 'admin_body_class', array( $this, 'admin_body_class' ) );
120 add_filter( 'views_edit-acf-field-group', array( $this, 'admin_table_views' ), 10, 1 );
121 add_filter( 'manage_acf-field-group_posts_columns', array( $this, 'admin_table_columns' ), 10, 1 );
122 add_action( 'manage_acf-field-group_posts_custom_column', array( $this, 'admin_table_columns_html' ), 10, 2 );
123 add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
124 add_filter( 'bulk_actions-edit-acf-field-group', array( $this, 'admin_table_bulk_actions' ), 10, 1 );
125 add_action( 'admin_footer', array( $this, 'admin_footer' ), 1 );
126 if( $this->view !== 'trash' ) {
127 add_filter( 'page_row_actions', array( $this, 'page_row_actions' ), 10, 2 );
128 }
129
130 // Add hooks for "sync" view.
131 if( $this->view === 'sync' ) {
132 add_action( 'admin_footer', array( $this, 'admin_footer__sync' ), 1 );
133 }
134 }
135
136 /**
137 * Sets up the field groups ready for sync.
138 *
139 * @date 17/4/20
140 * @since 5.9.0
141 *
142 * @param void
143 * @return void
144 */
145 public function setup_sync() {
146
147 // Review local json field groups.
148 if( acf_get_local_json_files() ) {
149
150 // Get all groups in a single cached query to check if sync is available.
151 $all_field_groups = acf_get_field_groups();
152 foreach( $all_field_groups as $field_group ) {
153
154 // Extract vars.
155 $local = acf_maybe_get( $field_group, 'local' );
156 $modified = acf_maybe_get( $field_group, 'modified' );
157 $private = acf_maybe_get( $field_group, 'private' );
158
159 // Ignore if is private.
160 if( $private ) {
161 continue;
162
163 // Ignore not local "json".
164 } elseif( $local !== 'json' ) {
165 continue;
166
167 // Append to sync if not yet in database.
168 } elseif( !$field_group['ID'] ) {
169 $this->sync[ $field_group['key'] ] = $field_group;
170
171 // Append to sync if "json" modified time is newer than database.
172 } elseif( $modified && $modified > get_post_modified_time('U', true, $field_group['ID']) ) {
173 $this->sync[ $field_group['key'] ] = $field_group;
174 }
175 }
176 }
177 }
178
179 /**
180 * Enqueues admin scripts.
181 *
182 * @date 18/4/20
183 * @since 5.9.0
184 *
185 * @param void
186 * @return void
187 */
188 public function admin_enqueue_scripts() {
189 acf_enqueue_script( 'acf' );
190
191 // Localize text.
192 acf_localize_text(array(
193 'Review local JSON changes' => __( 'Review local JSON changes', 'acf' ),
194 'Loading diff' => __( 'Loading diff', 'acf' ),
195 'Sync changes' => __( 'Sync changes', 'acf' ),
196 ));
197 }
198
199 /**
200 * Modifies the admin body class.
201 *
202 * @date 18/4/20
203 * @since 5.9.0
204 *
205 * @param string $classes Space-separated list of CSS classes.
206 * @return string
207 */
208 public function admin_body_class( $classes ) {
209 $classes .= ' acf-admin-field-groups';
210 if( $this->view ) {
211 $classes .= " view-{$this->view}";
212 }
213 return $classes;
214 }
215
216 /**
217 * returns the disabled post state HTML.
218 *
219 * @date 17/4/20
220 * @since 5.9.0
221 *
222 * @param void
223 * @return string
224 */
225 public function get_disabled_post_state() {
226 return '<span class="dashicons dashicons-hidden"></span> ' . _x( 'Disabled', 'post status', 'acf' );
227 }
228
229 /**
230 * Adds the "disabled" post state for the admin table title.
231 *
232 * @date 1/4/20
233 * @since 5.9.0
234 *
235 * @param array $post_states An array of post display states.
236 * @param WP_Post $post The current post object.
237 * @return array
238 */
239 public function display_post_states( $post_states, $post ) {
240 if( $post->post_status === 'acf-disabled' ) {
241 $post_states['acf-disabled'] = $this->get_disabled_post_state();
242 }
243 return $post_states;
244 }
245
246 /**
247 * Customizes the admin table columns.
248 *
249 * @date 1/4/20
250 * @since 5.9.0
251 *
252 * @param array $columns The columns array.
253 * @return array
254 */
255 public function admin_table_columns( $_columns ) {
256 $columns = array(
257 'cb' => $_columns['cb'],
258 'title' => $_columns['title'],
259 'acf-description' => __('Description', 'acf'),
260 'acf-key' => __('Key', 'acf'),
261 'acf-location' => __('Location', 'acf'),
262 'acf-count' => __('Fields', 'acf'),
263 );
264 if( acf_get_local_json_files() ) {
265 $columns['acf-json'] = __('Local JSON', 'acf');
266 }
267 return $columns;
268 }
269
270 /**
271 * Renders the admin table column HTML
272 *
273 * @date 1/4/20
274 * @since 5.9.0
275 *
276 * @param string $column_name The name of the column to display.
277 * @param int $post_id The current post ID.
278 * @return void
279 */
280 public function admin_table_columns_html( $column_name, $post_id ) {
281 $field_group = acf_get_field_group( $post_id );
282 if( $field_group ) {
283 $this->render_admin_table_column( $column_name, $field_group );
284 }
285 }
286
287 /**
288 * Renders a specific admin table column.
289 *
290 * @date 17/4/20
291 * @since 5.9.0
292 *
293 * @param string $column_name The name of the column to display.
294 * @param array $field_group The field group.
295 * @return void
296 */
297 public function render_admin_table_column( $column_name, $field_group ) {
298 switch ( $column_name ) {
299
300 // Key.
301 case 'acf-key':
302 echo esc_html( $field_group['key'] );
303 break;
304
305 // Description.
306 case 'acf-description':
307 if( $field_group['description'] ) {
308 echo '<span class="acf-description">' . acf_esc_html( $field_group['description'] ) . '</span>';
309 }
310 break;
311
312 // Location.
313 case 'acf-location':
314 $this->render_admin_table_column_locations( $field_group );
315 break;
316
317 // Count.
318 case 'acf-count':
319 echo esc_html( acf_get_field_count( $field_group ) );
320 break;
321
322 // Local JSON.
323 case 'acf-json':
324 $this->render_admin_table_column_local_status( $field_group );
325 break;
326 }
327 }
328
329 /**
330 * Displays a visual representation of the field group's locations.
331 *
332 * @date 1/4/20
333 * @since 5.9.0
334 *
335 * @param array $field_group The field group.
336 * @return void
337 */
338 public function render_admin_table_column_locations( $field_group ) {
339 $objects = array();
340
341 // Loop over location rules and determine connected object types.
342 if( $field_group['location'] ) {
343 foreach( $field_group['location'] as $i => $rules ) {
344
345 // Determine object types for each rule.
346 foreach( $rules as $j => $rule ) {
347
348 // Get location type and subtype for the current rule.
349 $location = acf_get_location_rule( $rule['param'] );
350 $location_object_type = '';
351 $location_object_subtype = '';
352 if( $location ) {
353 $location_object_type = $location->get_object_type( $rule );
354 $location_object_subtype = $location->get_object_subtype( $rule );
355 }
356 $rules[ $j ]['object_type'] = $location_object_type;
357 $rules[ $j ]['object_subtype'] = $location_object_subtype;
358 }
359
360 // Now that each $rule conains object type data...
361 $object_types = array_column( $rules, 'object_type' );
362 $object_types = array_filter( $object_types );
363 $object_types = array_values( $object_types );
364 if( $object_types ) {
365 $object_type = $object_types[0];
366 } else {
367 continue;
368 }
369
370 $object_subtypes = array_column( $rules, 'object_subtype' );
371 $object_subtypes = array_filter( $object_subtypes );
372 $object_subtypes = array_values( $object_subtypes );
373 $object_subtypes = array_map('acf_array', $object_subtypes);
374 if( count($object_subtypes) > 1 ) {
375 $object_subtypes = call_user_func_array('array_intersect', $object_subtypes);
376 $object_subtypes = array_values( $object_subtypes );
377 } elseif( $object_subtypes ) {
378 $object_subtypes = $object_subtypes[0];
379 } else {
380 $object_subtypes = array( '' );
381 }
382
383 // Append to objects.
384 foreach( $object_subtypes as $object_subtype ) {
385 $object = acf_get_object_type( $object_type, $object_subtype );
386 if( $object ) {
387 $objects[ $object->name ] = $object;
388 }
389 }
390 }
391 }
392
393 // Reset keys.
394 $objects = array_values( $objects );
395
396 // Display.
397 $html = '';
398 if( $objects ) {
399 $limit = 3;
400 $total = count( $objects );
401
402 // Icon.
403 $html .= '<span class="dashicons ' . $objects[0]->icon . ($total > 1 ? ' acf-multi-dashicon' : '') . '"></span> ';
404
405 // Labels.
406 $labels = array_column( $objects, 'label' );
407 $labels = array_slice( $labels, 0, 3 );
408 $html .= implode(', ', $labels );
409
410 // More.
411 if( $total > $limit ) {
412 $html .= ', ...';
413 }
414 } else {
415 $html = '<span class="dashicons dashicons-businesswoman"></span> ' . __( 'Various', 'acf' );
416 }
417
418 // Filter.
419 echo acf_esc_html( $html );
420 }
421
422 /**
423 * Returns a human readable file location.
424 *
425 * @date 17/4/20
426 * @since 5.9.0
427 *
428 * @param string $file The full file path.
429 * @return string
430 */
431 public function get_human_readable_file_location( $file ) {
432
433 // Generate friendly file path.
434 $theme_path = get_stylesheet_directory();
435 if( strpos($file, $theme_path) !== false ) {
436 $rel_file = str_replace( $theme_path, '', $file );
437 $located = sprintf( __('Located in theme: %s', 'acf'), $rel_file );
438
439 } elseif( strpos($file, WP_PLUGIN_DIR) !== false ) {
440 $rel_file = str_replace( WP_PLUGIN_DIR, '', $file );
441 $located = sprintf( __('Located in plugin: %s', 'acf'), $rel_file );
442
443 } else {
444 $rel_file = str_replace( ABSPATH, '', $file );
445 $located = sprintf( __('Located in: %s', 'acf'), $rel_file );
446 }
447 return $located;
448 }
449
450 /**
451 * Displays the local JSON status of a field group.
452 *
453 * @date 14/4/20
454 * @since 5.9.0
455 *
456 * @param type $var Description. Default.
457 * @return type Description.
458 */
459 public function render_admin_table_column_local_status( $field_group ) {
460 $json = acf_get_local_json_files();
461 if( isset( $json[ $field_group['key'] ] ) ) {
462 $file = $json[ $field_group['key'] ];
463 if( isset($this->sync[ $field_group['key'] ]) ) {
464 $url = $this->get_admin_url( '&acfsync=' . $field_group['key'] . '&_wpnonce=' . wp_create_nonce('bulk-posts') );
465 echo '<strong>' . __( 'Sync available', 'acf' ) . '</strong>';
466 if( $field_group['ID'] ) {
467 echo '<div class="row-actions">
468 <span class="sync"><a href="' . esc_url( $url ) . '">' . __( 'Sync', 'acf' ) . '</a> | </span>
469 <span class="review"><a href="#" data-event="review-sync" data-id="' . esc_attr($field_group['ID']) . '" data-href="' . esc_url( $url ) . '">' . __( 'Review changes', 'acf' ) . '</a></span>
470 </div>';
471 } else {
472 echo '<div class="row-actions">
473 <span class="sync"><a href="' . esc_url( $url ) . '">' . __( 'Import', 'acf' ) . '</a></span>
474 </div>';
475 }
476 } else {
477 echo __( 'Saved', 'acf' );
478 }
479 } else {
480 echo '<span class="acf-secondary-text">' . __( 'Awaiting save', 'acf' ) . '</span>';
481 }
482 }
483
484 /**
485 * Customizes the page row actions visible on hover.
486 *
487 * @date 14/4/20
488 * @since 5.9.0
489 *
490 * @param array $actions The array of actions HTML.
491 * @param WP_Post $post The post.
492 * @return array
493 */
494 public function page_row_actions( $actions, $post ) {
495
496 // Remove "Quick Edit" action.
497 unset( $actions['inline'], $actions['inline hide-if-no-js'] );
498
499 // Append "Duplicate" action.
500 $duplicate_action_url = $this->get_admin_url( '&acfduplicate=' . $post->ID . '&_wpnonce=' . wp_create_nonce('bulk-posts') );
501 $actions[ 'acfduplicate' ] = '<a href="' . esc_url( $duplicate_action_url ) . '" aria-label="' . esc_attr__( 'Duplicate this item', 'acf' ) . '">' . __( 'Duplicate', 'acf' ) . '</a>';
502
503 // Return actions in custom order.
504 $order = array( 'edit', 'acfduplicate', 'trash' );
505 return array_merge( array_flip($order), $actions );
506 }
507
508 /**
509 * Modifies the admin table bulk actions dropdown.
510 *
511 * @date 15/4/20
512 * @since 5.9.0
513 *
514 * @param array $actions The actions array.
515 * @return array
516 */
517 public function admin_table_bulk_actions( $actions ) {
518
519 // Add "duplicate" action.
520 if( $this->view !== 'sync' ) {
521 $actions[ 'acfduplicate' ] = __( 'Duplicate', 'acf' );
522 }
523
524 // Add "Sync" action.
525 if( $this->sync ) {
526 if( $this->view === 'sync' ) {
527 $actions = array();
528 }
529 $actions[ 'acfsync' ] = __( 'Sync changes', 'acf' );
530 }
531 return $actions;
532 }
533
534 /**
535 * Checks for the custom "duplicate" action.
536 *
537 * @date 15/4/20
538 * @since 5.9.0
539 *
540 * @param void
541 * @return void
542 */
543 public function check_duplicate() {
544
545 // Display notice on success redirect.
546 if( isset($_GET['acfduplicatecomplete']) ) {
547 $ids = array_map( 'intval', explode(',', $_GET['acfduplicatecomplete']) );
548
549 // Generate text.
550 $text = sprintf(
551 _n( 'Field group duplicated.', '%s field groups duplicated.', count($ids), 'acf' ),
552 count($ids)
553 );
554
555 // Append links to text.
556 $links = array();
557 foreach( $ids as $id ) {
558 $links[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
559 }
560 $text .= ' ' . implode( ', ', $links );
561
562 // Add notice.
563 acf_add_admin_notice( $text, 'success' );
564 return;
565 }
566
567 // Find items to duplicate.
568 $ids = array();
569 if( isset($_GET['acfduplicate']) ) {
570 $ids[] = intval( $_GET['acfduplicate'] );
571 } elseif( isset($_GET['post'], $_GET['action2']) && $_GET['action2'] === 'acfduplicate' ) {
572 $ids = array_map( 'intval', $_GET['post'] );
573 }
574
575 if( $ids ) {
576 check_admin_referer('bulk-posts');
577
578 // Duplicate field groups and generate array of new IDs.
579 $new_ids = array();
580 foreach( $ids as $id ) {
581 $field_group = acf_duplicate_field_group( $id );
582 $new_ids[] = $field_group['ID'];
583 }
584
585 // Redirect.
586 wp_redirect( $this->get_admin_url( '&acfduplicatecomplete=' . implode(',', $new_ids) ) );
587 exit;
588 }
589 }
590
591 /**
592 * Checks for the custom "acfsync" action.
593 *
594 * @date 15/4/20
595 * @since 5.9.0
596 *
597 * @param void
598 * @return void
599 */
600 public function check_sync() {
601
602 // Display notice on success redirect.
603 if( isset($_GET['acfsynccomplete']) ) {
604 $ids = array_map( 'intval', explode(',', $_GET['acfsynccomplete']) );
605
606 // Generate text.
607 $text = sprintf(
608 _n( 'Field group synchronised.', '%s field groups synchronised.', count($ids), 'acf' ),
609 count($ids)
610 );
611
612 // Append links to text.
613 $links = array();
614 foreach( $ids as $id ) {
615 $links[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
616 }
617 $text .= ' ' . implode( ', ', $links );
618
619 // Add notice.
620 acf_add_admin_notice( $text, 'success' );
621 return;
622 }
623
624 // Find items to sync.
625 $keys = array();
626 if( isset($_GET['acfsync']) ) {
627 $keys[] = sanitize_text_field( $_GET['acfsync'] );
628 } elseif( isset($_GET['post'], $_GET['action2']) && $_GET['action2'] === 'acfsync' ) {
629 $keys = array_map( 'sanitize_text_field', $_GET['post'] );
630 }
631
632 if( $keys && $this->sync ) {
633 check_admin_referer('bulk-posts');
634
635 // Disabled "Local JSON" controller to prevent the .json file from being modified during import.
636 acf_update_setting( 'json', false );
637
638 // Sync field groups and generate array of new IDs.
639 $files = acf_get_local_json_files();
640 $new_ids = array();
641 foreach( $this->sync as $key => $field_group ) {
642 if( $field_group['key'] && in_array($field_group['key'], $keys) ) {
643 // Import.
644 } elseif( $field_group['ID'] && in_array($field_group['ID'], $keys) ) {
645 // Import.
646 } else {
647 // Ignore.
648 continue;
649 }
650 $local_field_group = json_decode( file_get_contents( $files[ $key ] ), true );
651 $local_field_group['ID'] = $field_group['ID'];
652 $result = acf_import_field_group( $local_field_group );
653 $new_ids[] = $result['ID'];
654 }
655
656 // Redirect.
657 wp_redirect( $this->get_current_admin_url( '&acfsynccomplete=' . implode(',', $new_ids) ) );
658 exit;
659 }
660 }
661
662 /**
663 * Customizes the admin table subnav.
664 *
665 * @date 17/4/20
666 * @since 5.9.0
667 *
668 * @param array $views The available views.
669 * @return array
670 */
671 public function admin_table_views( $views ) {
672 global $wp_list_table, $wp_query;
673
674 // Count items.
675 $count = count( $this->sync );
676
677 // Append "sync" link to subnav.
678 if( $count ) {
679 $views['sync'] = sprintf(
680 '<a %s href="%s">%s <span class="count">(%s)</span></a>',
681 ( $this->view === 'sync' ? 'class="current"' : '' ),
682 esc_url( $this->get_admin_url( '&post_status=sync' ) ),
683 esc_html( __('Sync available', 'acf') ),
684 $count
685 );
686 }
687
688 // Modify table pagination args to match JSON data.
689 if( $this->view === 'sync' ) {
690 $wp_list_table->set_pagination_args( array(
691 'total_items' => $count,
692 'total_pages' => 1,
693 'per_page' => $count
694 ));
695 $wp_query->post_count = 1; // At least one post is needed to render bulk drop-down.
696 }
697 return $views;
698 }
699
700 /**
701 * Prints scripts into the admin footer.
702 *
703 * @date 20/4/20
704 * @since 5.9.0
705 *
706 * @param void
707 * @return void
708 */
709 function admin_footer() {
710 ?>
711 <script type="text/javascript">
712 (function($){
713
714 // Displays a modal comparing local changes.
715 function reviewSync( props ) {
716 var modal = acf.newModal({
717 title: acf.__('Review local JSON changes'),
718 content: '<p class="acf-modal-feedback"><i class="acf-loading"></i> ' + acf.__('Loading diff') + '</p>',
719 toolbar: '<a href="' + props.href + '" class="button button-primary button-sync-changes disabled">' + acf.__('Sync changes') + '</a>',
720 });
721
722 // Call AJAX.
723 var xhr = $.ajax({
724 url: acf.get('ajaxurl'),
725 method: 'POST',
726 dataType: 'json',
727 data: acf.prepareForAjax({
728 action: 'acf/ajax/local_json_diff',
729 id: props.id
730 })
731 })
732 .done(function( data, textStatus, jqXHR ) {
733 modal.content( data.html );
734 modal.$('.button-sync-changes').removeClass('disabled');
735 })
736 .fail(function( jqXHR, textStatus, errorThrown ) {
737 if( error = acf.getXhrError(jqXHR) ) {
738 modal.content( '<p class="acf-modal-feedback error">' + error + '</p>' );
739 }
740 });
741 }
742
743 // Add event listener.
744 $(document).on('click', 'a[data-event="review-sync"]', function( e ){
745 e.preventDefault();
746 reviewSync( $(this).data() );
747 });
748 })(jQuery);
749 </script>
750 <?php
751 }
752
753 /**
754 * Customizes the admin table HTML when viewing "sync" post_status.
755 *
756 * @date 17/4/20
757 * @since 5.9.0
758 *
759 * @param array $views The available views.
760 * @return array
761 */
762 public function admin_footer__sync() {
763 global $wp_list_table;
764
765 // Get table columns.
766 $columns = $wp_list_table->get_columns();
767 $hidden = get_hidden_columns( $wp_list_table->screen );
768 ?>
769 <div style="display: none;">
770 <table>
771 <tbody id="acf-the-list">
772 <?php
773 foreach( $this->sync as $k => $field_group ) {
774 echo '<tr>';
775 foreach( $columns as $column_name => $column_label ) {
776 $el = 'td';
777 if( $column_name === 'cb' ) {
778 $el = 'th';
779 $classes = 'check-column';
780 $column_label = '';
781 } elseif( $column_name === 'title' ) {
782 $classes = "$column_name column-$column_name column-primary";
783 } else {
784 $classes = "$column_name column-$column_name";
785 }
786 if( in_array( $column_name, $hidden, true ) ) {
787 $classes .= ' hidden';
788 }
789 echo "<$el class=\"$classes\" data-colname=\"$column_label\">";
790 switch ( $column_name ) {
791
792 // Checkbox.
793 case 'cb':
794 echo '<label for="cb-select-' . esc_attr( $k ) .'" class="screen-reader-text">' .esc_html( sprintf( __( 'Select %s', 'acf' ), $field_group['title'] ) ) . '</label>';
795 echo '<input id="cb-select-' . esc_attr( $k ) .'" type="checkbox" value="'. esc_attr( $k ) .'" name="post[]">';
796 break;
797
798 // Title.
799 case 'title':
800 $post_state = '';
801 if( !$field_group['active'] ) {
802 $post_state = ' — <span class="post-state">' . $this->get_disabled_post_state() . '</span>';
803 }
804 echo '<strong><span class="row-title">' . esc_html( $field_group['title']) . '</span>' . $post_state . '</strong>';
805 echo '<div class="row-actions"><span class="file acf-secondary-text">' . $this->get_human_readable_file_location( $field_group['local_file'] ) . '</span></div>';
806 echo '<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';
807 break;
808
809 // All other columns.
810 default:
811 $this->render_admin_table_column( $column_name, $field_group );
812 break;
813 }
814 echo "</$el>";
815 }
816 echo '</tr>';
817 }
818 ?>
819 </tbody>
820 </table>
821 </div>
822 <script type="text/javascript">
823 (function($){
824 $('#the-list').html( $('#acf-the-list').children() );
825 })(jQuery);
826 </script>
827 <?php
828 }
829
830 /**
831 * Fires when trashing a field group post.
832 *
833 * @date 8/01/2014
834 * @since 5.0.0
835 *
836 * @param int $post_id The post ID.
837 * @return void
838 */
839 public function trashed_post( $post_id ) {
840 if( get_post_type($post_id) === 'acf-field-group' ) {
841 acf_trash_field_group( $post_id );
842 }
843 }
844
845 /**
846 * Fires when untrashing a field group post.
847 *
848 * @date 8/01/2014
849 * @since 5.0.0
850 *
851 * @param int $post_id The post ID.
852 * @return void
853 */
854 public function untrashed_post( $post_id ) {
855 if( get_post_type($post_id) === 'acf-field-group' ) {
856 acf_untrash_field_group( $post_id );
857 }
858 }
859
860 /**
861 * Fires when deleting a field group post.
862 *
863 * @date 8/01/2014
864 * @since 5.0.0
865 *
866 * @param int $post_id The post ID.
867 * @return void
868 */
869 public function deleted_post( $post_id ) {
870 if( get_post_type($post_id) === 'acf-field-group' ) {
871 acf_delete_field_group( $post_id );
872 }
873 }
874 }
875
876 // Instantiate.
877 acf_new_instance('ACF_Admin_Field_Groups');
878
879 endif; // class_exists check
880