886 lines
24 KiB
PHP
886 lines
24 KiB
PHP
<?php
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly
|
|
}
|
|
|
|
if ( ! class_exists( 'ACF_Admin_Field_Groups' ) ) :
|
|
|
|
class ACF_Admin_Field_Groups {
|
|
|
|
/**
|
|
* Array of field groups availbale for sync.
|
|
*
|
|
* @since 5.9.0
|
|
* @var array
|
|
*/
|
|
public $sync = array();
|
|
|
|
/**
|
|
* The current view (post_status).
|
|
*
|
|
* @since 5.9.0
|
|
* @var string
|
|
*/
|
|
public $view = '';
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @date 5/03/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function __construct() {
|
|
|
|
// Add hooks.
|
|
add_action( 'load-edit.php', array( $this, 'handle_redirection' ) );
|
|
add_action( 'current_screen', array( $this, 'current_screen' ) );
|
|
|
|
// Handle post status change events.
|
|
add_action( 'trashed_post', array( $this, 'trashed_post' ) );
|
|
add_action( 'untrashed_post', array( $this, 'untrashed_post' ) );
|
|
add_action( 'deleted_post', array( $this, 'deleted_post' ) );
|
|
}
|
|
|
|
/**
|
|
* Returns the Field Groups admin URL.
|
|
*
|
|
* @date 27/3/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param string $params Extra URL params.
|
|
* @return string
|
|
*/
|
|
public function get_admin_url( $params = '' ) {
|
|
return admin_url( "edit.php?post_type=acf-field-group{$params}" );
|
|
}
|
|
|
|
/**
|
|
* Returns the Field Groups admin URL taking into account the current view.
|
|
*
|
|
* @date 27/3/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param string $params Extra URL params.
|
|
* @return string
|
|
*/
|
|
public function get_current_admin_url( $params = '' ) {
|
|
return $this->get_admin_url( ( $this->view ? '&post_status=' . $this->view : '' ) . $params );
|
|
}
|
|
|
|
/**
|
|
* Redirects users from ACF 4.0 admin page.
|
|
*
|
|
* @date 17/9/18
|
|
* @since 5.7.6
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function handle_redirection() {
|
|
if ( isset( $_GET['post_type'] ) && $_GET['post_type'] === 'acf' ) {
|
|
wp_redirect( $this->get_admin_url() );
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructor for the Field Groups admin page.
|
|
*
|
|
* @date 21/07/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function current_screen() {
|
|
|
|
// Bail early if not Field Groups admin page.
|
|
if ( ! acf_is_screen( 'edit-acf-field-group' ) ) {
|
|
return;
|
|
}
|
|
|
|
// Get the current view.
|
|
$this->view = isset( $_GET['post_status'] ) ? sanitize_text_field( $_GET['post_status'] ) : '';
|
|
|
|
// Setup and check for custom actions..
|
|
$this->setup_sync();
|
|
$this->check_sync();
|
|
$this->check_duplicate();
|
|
|
|
// Modify publish post status text and order.
|
|
global $wp_post_statuses;
|
|
$wp_post_statuses['publish']->label_count = _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'acf' );
|
|
$wp_post_statuses['trash'] = acf_extract_var( $wp_post_statuses, 'trash' );
|
|
|
|
// Add hooks.
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
|
add_action( 'admin_body_class', array( $this, 'admin_body_class' ) );
|
|
add_filter( 'views_edit-acf-field-group', array( $this, 'admin_table_views' ), 10, 1 );
|
|
add_filter( 'manage_acf-field-group_posts_columns', array( $this, 'admin_table_columns' ), 10, 1 );
|
|
add_action( 'manage_acf-field-group_posts_custom_column', array( $this, 'admin_table_columns_html' ), 10, 2 );
|
|
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
|
add_filter( 'bulk_actions-edit-acf-field-group', array( $this, 'admin_table_bulk_actions' ), 10, 1 );
|
|
add_action( 'admin_footer', array( $this, 'admin_footer' ), 1 );
|
|
if ( $this->view !== 'trash' ) {
|
|
add_filter( 'page_row_actions', array( $this, 'page_row_actions' ), 10, 2 );
|
|
}
|
|
|
|
// Add hooks for "sync" view.
|
|
if ( $this->view === 'sync' ) {
|
|
add_action( 'admin_footer', array( $this, 'admin_footer__sync' ), 1 );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets up the field groups ready for sync.
|
|
*
|
|
* @date 17/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function setup_sync() {
|
|
|
|
// Review local json field groups.
|
|
if ( acf_get_local_json_files() ) {
|
|
|
|
// Get all groups in a single cached query to check if sync is available.
|
|
$all_field_groups = acf_get_field_groups();
|
|
foreach ( $all_field_groups as $field_group ) {
|
|
|
|
// Extract vars.
|
|
$local = acf_maybe_get( $field_group, 'local' );
|
|
$modified = acf_maybe_get( $field_group, 'modified' );
|
|
$private = acf_maybe_get( $field_group, 'private' );
|
|
|
|
// Ignore if is private.
|
|
if ( $private ) {
|
|
continue;
|
|
|
|
// Ignore not local "json".
|
|
} elseif ( $local !== 'json' ) {
|
|
continue;
|
|
|
|
// Append to sync if not yet in database.
|
|
} elseif ( ! $field_group['ID'] ) {
|
|
$this->sync[ $field_group['key'] ] = $field_group;
|
|
|
|
// Append to sync if "json" modified time is newer than database.
|
|
} elseif ( $modified && $modified > get_post_modified_time( 'U', true, $field_group['ID'] ) ) {
|
|
$this->sync[ $field_group['key'] ] = $field_group;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enqueues admin scripts.
|
|
*
|
|
* @date 18/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function admin_enqueue_scripts() {
|
|
acf_enqueue_script( 'acf' );
|
|
|
|
// Localize text.
|
|
acf_localize_text(
|
|
array(
|
|
'Review local JSON changes' => __( 'Review local JSON changes', 'acf' ),
|
|
'Loading diff' => __( 'Loading diff', 'acf' ),
|
|
'Sync changes' => __( 'Sync changes', 'acf' ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Modifies the admin body class.
|
|
*
|
|
* @date 18/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param string $classes Space-separated list of CSS classes.
|
|
* @return string
|
|
*/
|
|
public function admin_body_class( $classes ) {
|
|
$classes .= ' acf-admin-field-groups';
|
|
if ( $this->view ) {
|
|
$classes .= " view-{$this->view}";
|
|
}
|
|
return $classes;
|
|
}
|
|
|
|
/**
|
|
* returns the disabled post state HTML.
|
|
*
|
|
* @date 17/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param void
|
|
* @return string
|
|
*/
|
|
public function get_disabled_post_state() {
|
|
return '<span class="dashicons dashicons-hidden"></span> ' . _x( 'Disabled', 'post status', 'acf' );
|
|
}
|
|
|
|
/**
|
|
* Adds the "disabled" post state for the admin table title.
|
|
*
|
|
* @date 1/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $post_states An array of post display states.
|
|
* @param WP_Post $post The current post object.
|
|
* @return array
|
|
*/
|
|
public function display_post_states( $post_states, $post ) {
|
|
if ( $post->post_status === 'acf-disabled' ) {
|
|
$post_states['acf-disabled'] = $this->get_disabled_post_state();
|
|
}
|
|
return $post_states;
|
|
}
|
|
|
|
/**
|
|
* Customizes the admin table columns.
|
|
*
|
|
* @date 1/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $columns The columns array.
|
|
* @return array
|
|
*/
|
|
public function admin_table_columns( $_columns ) {
|
|
$columns = array(
|
|
'cb' => $_columns['cb'],
|
|
'title' => $_columns['title'],
|
|
'acf-description' => __( 'Description', 'acf' ),
|
|
'acf-key' => __( 'Key', 'acf' ),
|
|
'acf-location' => __( 'Location', 'acf' ),
|
|
'acf-count' => __( 'Fields', 'acf' ),
|
|
);
|
|
if ( acf_get_local_json_files() ) {
|
|
$columns['acf-json'] = __( 'Local JSON', 'acf' );
|
|
}
|
|
return $columns;
|
|
}
|
|
|
|
/**
|
|
* Renders the admin table column HTML
|
|
*
|
|
* @date 1/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param string $column_name The name of the column to display.
|
|
* @param int $post_id The current post ID.
|
|
* @return void
|
|
*/
|
|
public function admin_table_columns_html( $column_name, $post_id ) {
|
|
$field_group = acf_get_field_group( $post_id );
|
|
if ( $field_group ) {
|
|
$this->render_admin_table_column( $column_name, $field_group );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders a specific admin table column.
|
|
*
|
|
* @date 17/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param string $column_name The name of the column to display.
|
|
* @param array $field_group The field group.
|
|
* @return void
|
|
*/
|
|
public function render_admin_table_column( $column_name, $field_group ) {
|
|
switch ( $column_name ) {
|
|
|
|
// Key.
|
|
case 'acf-key':
|
|
echo esc_html( $field_group['key'] );
|
|
break;
|
|
|
|
// Description.
|
|
case 'acf-description':
|
|
if ( $field_group['description'] ) {
|
|
echo '<span class="acf-description">' . acf_esc_html( $field_group['description'] ) . '</span>';
|
|
}
|
|
break;
|
|
|
|
// Location.
|
|
case 'acf-location':
|
|
$this->render_admin_table_column_locations( $field_group );
|
|
break;
|
|
|
|
// Count.
|
|
case 'acf-count':
|
|
echo esc_html( acf_get_field_count( $field_group ) );
|
|
break;
|
|
|
|
// Local JSON.
|
|
case 'acf-json':
|
|
$this->render_admin_table_column_local_status( $field_group );
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Displays a visual representation of the field group's locations.
|
|
*
|
|
* @date 1/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $field_group The field group.
|
|
* @return void
|
|
*/
|
|
public function render_admin_table_column_locations( $field_group ) {
|
|
$objects = array();
|
|
|
|
// Loop over location rules and determine connected object types.
|
|
if ( $field_group['location'] ) {
|
|
foreach ( $field_group['location'] as $i => $rules ) {
|
|
|
|
// Determine object types for each rule.
|
|
foreach ( $rules as $j => $rule ) {
|
|
|
|
// Get location type and subtype for the current rule.
|
|
$location = acf_get_location_rule( $rule['param'] );
|
|
$location_object_type = '';
|
|
$location_object_subtype = '';
|
|
if ( $location ) {
|
|
$location_object_type = $location->get_object_type( $rule );
|
|
$location_object_subtype = $location->get_object_subtype( $rule );
|
|
}
|
|
$rules[ $j ]['object_type'] = $location_object_type;
|
|
$rules[ $j ]['object_subtype'] = $location_object_subtype;
|
|
}
|
|
|
|
// Now that each $rule conains object type data...
|
|
$object_types = array_column( $rules, 'object_type' );
|
|
$object_types = array_filter( $object_types );
|
|
$object_types = array_values( $object_types );
|
|
if ( $object_types ) {
|
|
$object_type = $object_types[0];
|
|
} else {
|
|
continue;
|
|
}
|
|
|
|
$object_subtypes = array_column( $rules, 'object_subtype' );
|
|
$object_subtypes = array_filter( $object_subtypes );
|
|
$object_subtypes = array_values( $object_subtypes );
|
|
$object_subtypes = array_map( 'acf_array', $object_subtypes );
|
|
if ( count( $object_subtypes ) > 1 ) {
|
|
$object_subtypes = call_user_func_array( 'array_intersect', $object_subtypes );
|
|
$object_subtypes = array_values( $object_subtypes );
|
|
} elseif ( $object_subtypes ) {
|
|
$object_subtypes = $object_subtypes[0];
|
|
} else {
|
|
$object_subtypes = array( '' );
|
|
}
|
|
|
|
// Append to objects.
|
|
foreach ( $object_subtypes as $object_subtype ) {
|
|
$object = acf_get_object_type( $object_type, $object_subtype );
|
|
if ( $object ) {
|
|
$objects[ $object->name ] = $object;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Reset keys.
|
|
$objects = array_values( $objects );
|
|
|
|
// Display.
|
|
$html = '';
|
|
if ( $objects ) {
|
|
$limit = 3;
|
|
$total = count( $objects );
|
|
|
|
// Icon.
|
|
$html .= '<span class="dashicons ' . $objects[0]->icon . ( $total > 1 ? ' acf-multi-dashicon' : '' ) . '"></span> ';
|
|
|
|
// Labels.
|
|
$labels = array_column( $objects, 'label' );
|
|
$labels = array_slice( $labels, 0, 3 );
|
|
$html .= implode( ', ', $labels );
|
|
|
|
// More.
|
|
if ( $total > $limit ) {
|
|
$html .= ', ...';
|
|
}
|
|
} else {
|
|
$html = '<span class="dashicons dashicons-businesswoman"></span> ' . __( 'Various', 'acf' );
|
|
}
|
|
|
|
// Filter.
|
|
echo acf_esc_html( $html );
|
|
}
|
|
|
|
/**
|
|
* Returns a human readable file location.
|
|
*
|
|
* @date 17/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param string $file The full file path.
|
|
* @return string
|
|
*/
|
|
public function get_human_readable_file_location( $file ) {
|
|
|
|
// Generate friendly file path.
|
|
$theme_path = get_stylesheet_directory();
|
|
if ( strpos( $file, $theme_path ) !== false ) {
|
|
$rel_file = str_replace( $theme_path, '', $file );
|
|
$located = sprintf( __( 'Located in theme: %s', 'acf' ), $rel_file );
|
|
|
|
} elseif ( strpos( $file, WP_PLUGIN_DIR ) !== false ) {
|
|
$rel_file = str_replace( WP_PLUGIN_DIR, '', $file );
|
|
$located = sprintf( __( 'Located in plugin: %s', 'acf' ), $rel_file );
|
|
|
|
} else {
|
|
$rel_file = str_replace( ABSPATH, '', $file );
|
|
$located = sprintf( __( 'Located in: %s', 'acf' ), $rel_file );
|
|
}
|
|
return $located;
|
|
}
|
|
|
|
/**
|
|
* Displays the local JSON status of a field group.
|
|
*
|
|
* @date 14/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param type $var Description. Default.
|
|
* @return type Description.
|
|
*/
|
|
public function render_admin_table_column_local_status( $field_group ) {
|
|
$json = acf_get_local_json_files();
|
|
if ( isset( $json[ $field_group['key'] ] ) ) {
|
|
$file = $json[ $field_group['key'] ];
|
|
if ( isset( $this->sync[ $field_group['key'] ] ) ) {
|
|
$url = $this->get_admin_url( '&acfsync=' . $field_group['key'] . '&_wpnonce=' . wp_create_nonce( 'bulk-posts' ) );
|
|
echo '<strong>' . __( 'Sync available', 'acf' ) . '</strong>';
|
|
if ( $field_group['ID'] ) {
|
|
echo '<div class="row-actions">
|
|
<span class="sync"><a href="' . esc_url( $url ) . '">' . __( 'Sync', 'acf' ) . '</a> | </span>
|
|
<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>
|
|
</div>';
|
|
} else {
|
|
echo '<div class="row-actions">
|
|
<span class="sync"><a href="' . esc_url( $url ) . '">' . __( 'Import', 'acf' ) . '</a></span>
|
|
</div>';
|
|
}
|
|
} else {
|
|
echo __( 'Saved', 'acf' );
|
|
}
|
|
} else {
|
|
echo '<span class="acf-secondary-text">' . __( 'Awaiting save', 'acf' ) . '</span>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Customizes the page row actions visible on hover.
|
|
*
|
|
* @date 14/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $actions The array of actions HTML.
|
|
* @param WP_Post $post The post.
|
|
* @return array
|
|
*/
|
|
public function page_row_actions( $actions, $post ) {
|
|
|
|
// Remove "Quick Edit" action.
|
|
unset( $actions['inline'], $actions['inline hide-if-no-js'] );
|
|
|
|
// Append "Duplicate" action.
|
|
$duplicate_action_url = $this->get_admin_url( '&acfduplicate=' . $post->ID . '&_wpnonce=' . wp_create_nonce( 'bulk-posts' ) );
|
|
$actions['acfduplicate'] = '<a href="' . esc_url( $duplicate_action_url ) . '" aria-label="' . esc_attr__( 'Duplicate this item', 'acf' ) . '">' . __( 'Duplicate', 'acf' ) . '</a>';
|
|
|
|
// Return actions in custom order.
|
|
$order = array( 'edit', 'acfduplicate', 'trash' );
|
|
return array_merge( array_flip( $order ), $actions );
|
|
}
|
|
|
|
/**
|
|
* Modifies the admin table bulk actions dropdown.
|
|
*
|
|
* @date 15/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $actions The actions array.
|
|
* @return array
|
|
*/
|
|
public function admin_table_bulk_actions( $actions ) {
|
|
|
|
// Add "duplicate" action.
|
|
if ( $this->view !== 'sync' ) {
|
|
$actions['acfduplicate'] = __( 'Duplicate', 'acf' );
|
|
}
|
|
|
|
// Add "Sync" action.
|
|
if ( $this->sync ) {
|
|
if ( $this->view === 'sync' ) {
|
|
$actions = array();
|
|
}
|
|
$actions['acfsync'] = __( 'Sync changes', 'acf' );
|
|
}
|
|
return $actions;
|
|
}
|
|
|
|
/**
|
|
* Checks for the custom "duplicate" action.
|
|
*
|
|
* @date 15/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function check_duplicate() {
|
|
|
|
// Display notice on success redirect.
|
|
if ( isset( $_GET['acfduplicatecomplete'] ) ) {
|
|
$ids = array_map( 'intval', explode( ',', $_GET['acfduplicatecomplete'] ) );
|
|
|
|
// Generate text.
|
|
$text = sprintf(
|
|
_n( 'Field group duplicated.', '%s field groups duplicated.', count( $ids ), 'acf' ),
|
|
count( $ids )
|
|
);
|
|
|
|
// Append links to text.
|
|
$links = array();
|
|
foreach ( $ids as $id ) {
|
|
$links[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
|
|
}
|
|
$text .= ' ' . implode( ', ', $links );
|
|
|
|
// Add notice.
|
|
acf_add_admin_notice( $text, 'success' );
|
|
return;
|
|
}
|
|
|
|
// Find items to duplicate.
|
|
$ids = array();
|
|
if ( isset( $_GET['acfduplicate'] ) ) {
|
|
$ids[] = intval( $_GET['acfduplicate'] );
|
|
} elseif ( isset( $_GET['post'], $_GET['action2'] ) && $_GET['action2'] === 'acfduplicate' ) {
|
|
$ids = array_map( 'intval', $_GET['post'] );
|
|
}
|
|
|
|
if ( $ids ) {
|
|
check_admin_referer( 'bulk-posts' );
|
|
|
|
// Duplicate field groups and generate array of new IDs.
|
|
$new_ids = array();
|
|
foreach ( $ids as $id ) {
|
|
$field_group = acf_duplicate_field_group( $id );
|
|
$new_ids[] = $field_group['ID'];
|
|
}
|
|
|
|
// Redirect.
|
|
wp_redirect( $this->get_admin_url( '&acfduplicatecomplete=' . implode( ',', $new_ids ) ) );
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks for the custom "acfsync" action.
|
|
*
|
|
* @date 15/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
public function check_sync() {
|
|
|
|
// Display notice on success redirect.
|
|
if ( isset( $_GET['acfsynccomplete'] ) ) {
|
|
$ids = array_map( 'intval', explode( ',', $_GET['acfsynccomplete'] ) );
|
|
|
|
// Generate text.
|
|
$text = sprintf(
|
|
_n( 'Field group synchronised.', '%s field groups synchronised.', count( $ids ), 'acf' ),
|
|
count( $ids )
|
|
);
|
|
|
|
// Append links to text.
|
|
$links = array();
|
|
foreach ( $ids as $id ) {
|
|
$links[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
|
|
}
|
|
$text .= ' ' . implode( ', ', $links );
|
|
|
|
// Add notice.
|
|
acf_add_admin_notice( $text, 'success' );
|
|
return;
|
|
}
|
|
|
|
// Find items to sync.
|
|
$keys = array();
|
|
if ( isset( $_GET['acfsync'] ) ) {
|
|
$keys[] = sanitize_text_field( $_GET['acfsync'] );
|
|
} elseif ( isset( $_GET['post'], $_GET['action2'] ) && $_GET['action2'] === 'acfsync' ) {
|
|
$keys = array_map( 'sanitize_text_field', $_GET['post'] );
|
|
}
|
|
|
|
if ( $keys && $this->sync ) {
|
|
check_admin_referer( 'bulk-posts' );
|
|
|
|
// Disabled "Local JSON" controller to prevent the .json file from being modified during import.
|
|
acf_update_setting( 'json', false );
|
|
|
|
// Sync field groups and generate array of new IDs.
|
|
$files = acf_get_local_json_files();
|
|
$new_ids = array();
|
|
foreach ( $this->sync as $key => $field_group ) {
|
|
if ( $field_group['key'] && in_array( $field_group['key'], $keys ) ) {
|
|
// Import.
|
|
} elseif ( $field_group['ID'] && in_array( $field_group['ID'], $keys ) ) {
|
|
// Import.
|
|
} else {
|
|
// Ignore.
|
|
continue;
|
|
}
|
|
$local_field_group = json_decode( file_get_contents( $files[ $key ] ), true );
|
|
$local_field_group['ID'] = $field_group['ID'];
|
|
$result = acf_import_field_group( $local_field_group );
|
|
$new_ids[] = $result['ID'];
|
|
}
|
|
|
|
// Redirect.
|
|
wp_redirect( $this->get_current_admin_url( '&acfsynccomplete=' . implode( ',', $new_ids ) ) );
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Customizes the admin table subnav.
|
|
*
|
|
* @date 17/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $views The available views.
|
|
* @return array
|
|
*/
|
|
public function admin_table_views( $views ) {
|
|
global $wp_list_table, $wp_query;
|
|
|
|
// Count items.
|
|
$count = count( $this->sync );
|
|
|
|
// Append "sync" link to subnav.
|
|
if ( $count ) {
|
|
$views['sync'] = sprintf(
|
|
'<a %s href="%s">%s <span class="count">(%s)</span></a>',
|
|
( $this->view === 'sync' ? 'class="current"' : '' ),
|
|
esc_url( $this->get_admin_url( '&post_status=sync' ) ),
|
|
esc_html( __( 'Sync available', 'acf' ) ),
|
|
$count
|
|
);
|
|
}
|
|
|
|
// Modify table pagination args to match JSON data.
|
|
if ( $this->view === 'sync' ) {
|
|
$wp_list_table->set_pagination_args(
|
|
array(
|
|
'total_items' => $count,
|
|
'total_pages' => 1,
|
|
'per_page' => $count,
|
|
)
|
|
);
|
|
$wp_query->post_count = 1; // At least one post is needed to render bulk drop-down.
|
|
}
|
|
return $views;
|
|
}
|
|
|
|
/**
|
|
* Prints scripts into the admin footer.
|
|
*
|
|
* @date 20/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param void
|
|
* @return void
|
|
*/
|
|
function admin_footer() {
|
|
?>
|
|
<script type="text/javascript">
|
|
(function($){
|
|
|
|
// Displays a modal comparing local changes.
|
|
function reviewSync( props ) {
|
|
var modal = acf.newModal({
|
|
title: acf.__('Review local JSON changes'),
|
|
content: '<p class="acf-modal-feedback"><i class="acf-loading"></i> ' + acf.__('Loading diff') + '</p>',
|
|
toolbar: '<a href="' + props.href + '" class="button button-primary button-sync-changes disabled">' + acf.__('Sync changes') + '</a>',
|
|
});
|
|
|
|
// Call AJAX.
|
|
var xhr = $.ajax({
|
|
url: acf.get('ajaxurl'),
|
|
method: 'POST',
|
|
dataType: 'json',
|
|
data: acf.prepareForAjax({
|
|
action: 'acf/ajax/local_json_diff',
|
|
id: props.id
|
|
})
|
|
})
|
|
.done(function( data, textStatus, jqXHR ) {
|
|
modal.content( data.html );
|
|
modal.$('.button-sync-changes').removeClass('disabled');
|
|
})
|
|
.fail(function( jqXHR, textStatus, errorThrown ) {
|
|
if( error = acf.getXhrError(jqXHR) ) {
|
|
modal.content( '<p class="acf-modal-feedback error">' + error + '</p>' );
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add event listener.
|
|
$(document).on('click', 'a[data-event="review-sync"]', function( e ){
|
|
e.preventDefault();
|
|
reviewSync( $(this).data() );
|
|
});
|
|
})(jQuery);
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Customizes the admin table HTML when viewing "sync" post_status.
|
|
*
|
|
* @date 17/4/20
|
|
* @since 5.9.0
|
|
*
|
|
* @param array $views The available views.
|
|
* @return array
|
|
*/
|
|
public function admin_footer__sync() {
|
|
global $wp_list_table;
|
|
|
|
// Get table columns.
|
|
$columns = $wp_list_table->get_columns();
|
|
$hidden = get_hidden_columns( $wp_list_table->screen );
|
|
?>
|
|
<div style="display: none;">
|
|
<table>
|
|
<tbody id="acf-the-list">
|
|
<?php
|
|
foreach ( $this->sync as $k => $field_group ) {
|
|
echo '<tr>';
|
|
foreach ( $columns as $column_name => $column_label ) {
|
|
$el = 'td';
|
|
if ( $column_name === 'cb' ) {
|
|
$el = 'th';
|
|
$classes = 'check-column';
|
|
$column_label = '';
|
|
} elseif ( $column_name === 'title' ) {
|
|
$classes = "$column_name column-$column_name column-primary";
|
|
} else {
|
|
$classes = "$column_name column-$column_name";
|
|
}
|
|
if ( in_array( $column_name, $hidden, true ) ) {
|
|
$classes .= ' hidden';
|
|
}
|
|
echo "<$el class=\"$classes\" data-colname=\"$column_label\">";
|
|
switch ( $column_name ) {
|
|
|
|
// Checkbox.
|
|
case 'cb':
|
|
echo '<label for="cb-select-' . esc_attr( $k ) . '" class="screen-reader-text">' . esc_html( sprintf( __( 'Select %s', 'acf' ), $field_group['title'] ) ) . '</label>';
|
|
echo '<input id="cb-select-' . esc_attr( $k ) . '" type="checkbox" value="' . esc_attr( $k ) . '" name="post[]">';
|
|
break;
|
|
|
|
// Title.
|
|
case 'title':
|
|
$post_state = '';
|
|
if ( ! $field_group['active'] ) {
|
|
$post_state = ' — <span class="post-state">' . $this->get_disabled_post_state() . '</span>';
|
|
}
|
|
echo '<strong><span class="row-title">' . esc_html( $field_group['title'] ) . '</span>' . $post_state . '</strong>';
|
|
echo '<div class="row-actions"><span class="file acf-secondary-text">' . $this->get_human_readable_file_location( $field_group['local_file'] ) . '</span></div>';
|
|
echo '<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';
|
|
break;
|
|
|
|
// All other columns.
|
|
default:
|
|
$this->render_admin_table_column( $column_name, $field_group );
|
|
break;
|
|
}
|
|
echo "</$el>";
|
|
}
|
|
echo '</tr>';
|
|
}
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<script type="text/javascript">
|
|
(function($){
|
|
$('#the-list').html( $('#acf-the-list').children() );
|
|
})(jQuery);
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Fires when trashing a field group post.
|
|
*
|
|
* @date 8/01/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param int $post_id The post ID.
|
|
* @return void
|
|
*/
|
|
public function trashed_post( $post_id ) {
|
|
if ( get_post_type( $post_id ) === 'acf-field-group' ) {
|
|
acf_trash_field_group( $post_id );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fires when untrashing a field group post.
|
|
*
|
|
* @date 8/01/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param int $post_id The post ID.
|
|
* @return void
|
|
*/
|
|
public function untrashed_post( $post_id ) {
|
|
if ( get_post_type( $post_id ) === 'acf-field-group' ) {
|
|
acf_untrash_field_group( $post_id );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fires when deleting a field group post.
|
|
*
|
|
* @date 8/01/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param int $post_id The post ID.
|
|
* @return void
|
|
*/
|
|
public function deleted_post( $post_id ) {
|
|
if ( get_post_type( $post_id ) === 'acf-field-group' ) {
|
|
acf_delete_field_group( $post_id );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Instantiate.
|
|
acf_new_instance( 'ACF_Admin_Field_Groups' );
|
|
|
|
endif; // class_exists check
|