web/wp-content/plugins/acf-extended/includes/field-groups/field-groups.php (507 lines of code) (raw):

<?php if(!defined('ABSPATH')){ exit; } if(!class_exists('ACFE_Field_Groups')): class ACFE_Field_Groups{ // vars var $view = ''; var $sync = ''; var $old_version = false; /** * construct */ function __construct(){ add_action('current_screen', array($this, 'current_screen')); add_action('acf/add_meta_boxes', array($this, 'seamless_metabox'), 10, 3); } /** * current_screen */ function current_screen(){ // bail early if not Field Groups admin page. if(!acf_is_screen('edit-acf-field-group')){ return; } // old Compatibility if(acf_version_compare(acf_get_setting('version'), '<', '5.9')){ $this->old_version = true; } // acf < 5.9 if($this->old_version){ $this->view = isset($_GET['post_status']) ? sanitize_text_field($_GET['post_status']) : ''; $this->sync = $this->get_sync_compatibility(); // acf >= 5.9 }else{ $this->view = acf_get_instance('ACF_Admin_Field_Groups')->view; $this->sync = acf_get_instance('ACF_Admin_Field_Groups')->sync; } // hooks add_filter('manage_edit-acf-field-group_columns', array($this, 'table_columns'), 20); add_action('manage_acf-field-group_posts_custom_column', array($this, 'table_columns_html'), 10, 2); add_filter('default_hidden_columns', array($this, 'default_hidden_columns'), 10, 2); add_filter('edit_acf-field-group_per_page', array($this, 'posts_per_page')); add_filter('page_row_actions', array($this, 'row_actions'), 20, 2); add_filter('display_post_states', array($this, 'post_states'), 20, 2); add_action('admin_footer', array($this, 'admin_footer')); if($this->view !== 'sync'){ add_filter('bulk_actions-edit-acf-field-group', array($this, 'bulk_actions')); add_filter('handle_bulk_actions-edit-acf-field-group', array($this, 'handle_bulk_actions'), 10, 3); } } /** * table_columns * * @param $columns * * @return array */ function table_columns($columns){ switch($this->view){ // sync case('sync'): { acfe_unset($columns, 'acf-field-group-category'); break; } // local case('acfe-local'): { if($this->old_version){ $columns = array( 'cb' => '<input type="checkbox" />', 'title' => __('Title', 'acf'), 'acfe-source' => __('Source', 'acf'), 'acf-count' => __('Fields', 'acf'), 'acfe-location' => __('Location', 'acf'), ); }else{ $columns = array( 'cb' => '<input type="checkbox" />', 'title' => __('Title', 'acf'), 'acfe-source' => __('Source', 'acf'), 'acf-count' => __('Fields', 'acf'), 'acf-location' => __('Location', 'acf'), ); } if(acf_get_setting('acfe/php') || acf_get_setting('acfe/json')){ $columns['acfe-load'] = __('Load', 'acf'); } if(acf_get_setting('acfe/php')){ $columns['acfe-autosync-php'] = __('PHP Sync'); } if(acf_get_setting('acfe/json')){ $columns['acfe-autosync-json'] = __('Json Sync', 'acf'); } break; } // active/trash default: { // acf < 5.9 if($this->old_version){ acfe_unset($columns, 'acf-fg-status'); $columns['acfe-location'] = __('Location', 'acf'); if(acf_get_setting('acfe/php') || acf_get_setting('acfe/json')){ $columns['acfe-load'] = __('Load', 'acf'); } if(acf_get_setting('acfe/php')){ $columns['acfe-autosync-php'] = __('PHP'); } if(acf_get_setting('acfe/json')){ $columns['acfe-autosync-json'] = __('Json'); } // acf >= 5.9 }else{ // Re-order acfe_unset($columns, 'acf-key'); acfe_unset($columns, 'acf-location'); acfe_unset($columns, 'acf-count'); acfe_unset($columns, 'acf-json'); $columns['acf-count'] = __('Fields', 'acf'); $columns['acf-location'] = __('Location', 'acf'); if(acf_get_setting('acfe/php') || acf_get_setting('acfe/json')){ $columns['acfe-load'] = __('Load', 'acf'); } if(acf_get_setting('acfe/php')){ $columns['acfe-autosync-php'] = __('PHP'); } if(acf_get_setting('json')){ $columns['acfe-autosync-json'] = __('Json'); } } // remove category column if empty if(isset($columns['acf-field-group-category'])){ $categories_count = get_terms(array( 'taxonomy' => 'acf-field-group-category', 'hide_empty' => false, 'fields' => 'count' )); if(empty($categories_count)){ unset($columns['acf-field-group-category']); } } break; } } return $columns; } /** * table_columns_html * * @param $column * @param $post_id */ function table_columns_html($column, $post_id){ $field_group = acf_get_field_group($post_id); if(!$field_group){ return; } $this->render_table_column($column, $field_group); } /** * render_table_column * * @param $column * @param $field_group */ function render_table_column($column, $field_group){ switch($column){ // source case 'acfe-source': { $this->render_admin_table_column_source_html($field_group); break; } // count case 'acfe-count': { echo esc_html( acf_get_field_count($field_group)); break; } // location case 'acfe-location': { acfe_render_field_group_locations_html($field_group); break; } // load case 'acfe-load': { $this->render_admin_table_column_load_html($field_group); break; } // autosync php case 'acfe-autosync-php': { $this->render_admin_table_column_php_html($field_group); break; } // autosync json case 'acfe-autosync-json': { $this->render_admin_table_column_json_html($field_group); break; } } } /** * render_admin_table_column_source_html * * @param $field_group */ function render_admin_table_column_source_html($field_group){ $source = __('Theme/Plugin', 'acf'); // ACF Extended if(in_array($field_group['key'], acfe_get_setting('reserved_field_groups', array()))){ $source = 'ACF Extended'; // Advanced Forms }elseif($field_group['key'] === 'group_form_settings' || $field_group['key'] === 'group_entry_data'){ $source = 'Advanced Forms'; }elseif(acf_maybe_get($field_group, 'acfe_local_source')){ $file = acf_maybe_get($field_group, 'acfe_local_source'); $file_readable = $this->get_human_readable_file_location($file); $source = '<span class="acf-js-tooltip" title="' . $file_readable . '">AutoSync</span>'; } $source = apply_filters('acfe/field_groups_third_party/source', $source, $field_group['key'], $field_group); echo $source; } /** * render_admin_table_column_load_html * * @param $field_group */ function render_admin_table_column_load_html($field_group){ $php = acfe_get_local_php_files(); $local_field_group = acf_get_local_field_group($field_group['key']); // PHP if(isset($php[$field_group['key']]) || acf_maybe_get($local_field_group, 'local') === 'php'){ echo '<span>php</span>'; // Json }elseif(acf_maybe_get($local_field_group, 'local') === 'json'){ echo '<span>Json</span>'; // DB }else{ echo '<span>DB</span>'; } } /** * render_admin_table_column_php_html * * @param $field_group */ function render_admin_table_column_php_html($field_group){ $return = $this->get_php_data($field_group); $wrapper = array( 'class' => '' ); if($return['class']) $wrapper['class'] = $return['class']; if($return['message']){ $wrapper['class'] .= ' acf-js-tooltip'; $wrapper['title'] = $return['message']; } $icons = array(); if($return['icon']){ $icons[] = '<span class="dashicons dashicons-' . $return['icon'] . '"></span>'; } if($return['warning']){ $icons[] = '<span class="dashicons dashicons-warning"></span>'; } ?> <span <?php echo acf_esc_atts($wrapper); ?>> <?php if($return['wrapper_start']){ echo $return['wrapper_start']; } ?> <?php if(!empty($icons)){ ?> <?php echo implode('', $icons); ?> <?php } ?> <?php if($return['wrapper_end']){ echo $return['wrapper_end']; } ?> </span> <?php } /** * get_php_data * * @param $field_group * * @return array */ function get_php_data($field_group){ $return = array( 'message' => false, 'file' => false, 'wrapper_start' => '', 'wrapper_end' => '', 'class' => false, 'warning' => false, 'icon' => false, ); $php = acfe_get_local_php_files(); if(isset($php[ $field_group['key'] ])){ $file = $php[$field_group['key']]; $file_readable = $this->get_human_readable_file_location($file); $local_field_group = acf_get_local_field_group($field_group['key']); if(acf_maybe_get($local_field_group, 'local') === 'php'){ $return['message'] = __('Synchronized', 'acf') . '. ' . $file_readable . '<br/><br/>' . __('Warning: Duplicated PHP code found in theme/plugin.', 'acf'); $return['file'] = $file_readable . '<br/><br/>' . __('Warning: Duplicated PHP code found in theme/plugin.', 'acf'); $return['icon'] = 'yes'; $return['warning'] = true; }else{ $return['message'] = __('Synchronized', 'acf') . '. ' . $file_readable; $return['file'] = $file_readable; $return['icon'] = 'yes'; } }else{ $path = acfe_get_php_save_path($field_group); $found = (bool) is_dir($path) && wp_is_writable($path); $folder = $this->get_human_readable_file_location($path, $found, false); if(acfe_has_php_sync($field_group)){ $return['message'] = __('Awaiting save', 'acf') . '. <br />' . __('Save path', 'acf') . ' ' . lcfirst($folder); $return['file'] = __('Save path', 'acf') . ' ' . lcfirst($folder); $return['class'] = 'secondary'; $return['icon'] = 'yes'; $return['warning'] = true; }else{ $return['file'] = __('Save path', 'acf') . ' ' . lcfirst($folder); $return['class'] = 'secondary'; $return['icon'] = 'no-alt'; } } if($this->view === 'acfe-local'){ $return['message'] = false; $return['warning'] = false; $return['class'] = false; if($return['icon'] !== 'yes'){ $return['class'] = 'secondary'; } } return $return; } /** * render_admin_table_column_json_html * * @param $field_group */ function render_admin_table_column_json_html($field_group){ $return = $this->get_json_data($field_group); $wrapper = array( 'class' => '' ); if($return['class']){ $wrapper['class'] = $return['class']; } if($return['message']){ $wrapper['class'] .= ' acf-js-tooltip'; $wrapper['title'] = $return['message']; } $icons = array(); if($return['icon']){ $icons[] = '<span class="dashicons dashicons-' . $return['icon'] . '"></span>'; } if($return['warning']){ $icons[] = '<span class="dashicons dashicons-warning"></span>'; } ?> <span <?php echo acf_esc_atts($wrapper); ?>> <?php if($return['wrapper_start']){ echo $return['wrapper_start']; } ?> <?php if(!empty($icons)){ ?> <?php echo implode('', $icons); ?> <?php } ?> <?php if($return['wrapper_end']){ echo $return['wrapper_end']; } ?> </span> <?php } /** * get_json_data * * @param $field_group * * @return false[] */ function get_json_data($field_group){ $return = array( 'message' => false, 'file' => false, 'wrapper_start' => false, 'wrapper_end' => false, 'class' => false, 'warning' => false, 'icon' => false, ); $json = acf_get_local_json_files(); if(isset($json[ $field_group['key'] ])){ $file = $json[$field_group['key']]; $file_readable = $this->get_human_readable_file_location($file); if(isset($this->sync[ $field_group['key'] ])){ // vars $nonce = wp_create_nonce('bulk-posts'); if($this->old_version){ $url = admin_url('edit.php?post_type=acf-field-group&post_status=sync&acfsync=' . $field_group['key'] . '&_wpnonce=' . $nonce ); $text = $field_group['ID'] ? __('Sync', 'acf') : __('Import', 'acf'); $wrapper_start = '<a href="' . esc_url($url) . '">'; $wrapper_end = '<div class="row-actions"><span class="review" style="color:#006799;">' . $text . '</span></div></a>'; }else{ $url = admin_url('edit.php?post_type=acf-field-group&acfsync=' . $field_group['key'] . '&_wpnonce=' . $nonce); $text = $field_group['ID'] ? __('Review', 'acf') : __('Import', 'acf'); $wrapper_start = '<a href="#" data-event="review-sync" data-id="' . esc_attr($field_group['ID']) . '" data-href="' . esc_url($url) . '">'; $wrapper_end = '<div class="row-actions"><span class="review" style="color:#006799;">' . $text . '</span></div></a>'; } if($field_group['ID']){ $return['message'] = __('Sync available', 'acf') . '. ' . $file_readable; $return['file'] = $file_readable; $return['icon'] = 'update'; $return['wrapper_start'] = $wrapper_start; $return['wrapper_end'] = $wrapper_end; }else{ $return['message'] = __('Sync available', 'acf') . '. ' . $file_readable; $return['file'] = $file_readable; $return['icon'] = 'update'; $return['wrapper_start'] = $wrapper_start; $return['wrapper_end'] = $wrapper_end; } }else{ $return['message'] = __('Synchronized', 'acf') . '. ' . $file_readable; $return['file'] = $file_readable; $return['icon'] = 'yes'; } }else{ $path = acfe_get_json_save_path($field_group); $found = (bool) is_dir($path) && wp_is_writable($path); $folder = $this->get_human_readable_file_location($path, $found, false); if(acfe_has_json_sync($field_group)){ $return['message'] = __('Awaiting save', 'acf') . '. <br />' . __('Save path', 'acf') . ' ' . lcfirst($folder); $return['file'] = __('Save path', 'acf') . ' ' . lcfirst($folder); $return['class'] = 'secondary'; $return['icon'] = 'yes'; $return['warning'] = 'true'; }else{ $return['file'] = __('Save path', 'acf') . ' ' . lcfirst($folder); $return['class'] = 'secondary'; $return['icon'] = 'no-alt'; } } if($this->view === 'acfe-local'){ $return['message'] = false; $return['warning'] = false; $return['class'] = false; if($return['icon'] !== 'yes'){ $return['class'] = 'secondary'; } } return $return; } /** * default_hidden_columns * * @param $hidden * @param $screen * * @return mixed */ function default_hidden_columns($hidden, $screen){ $hidden[] = 'acf-description'; return $hidden; } /** * posts_per_page * * @return int */ function posts_per_page(){ return 999; } /** * row_actions * * @param $actions * @param $post * * @return mixed */ function row_actions($actions, $post){ // bail early if($post->post_type !== 'acf-field-group'){ return $actions; } $field_group = acf_get_field_group($post->ID); $actions['acfe-export-php'] = '<a href="' . admin_url('edit.php?post_type=acf-field-group&page=acf-tools&tool=export&action=php&keys=' . $field_group['key']) . '">PHP</a>'; $actions['acfe-export-json'] = '<a href="' . admin_url('edit.php?post_type=acf-field-group&page=acf-tools&tool=export&action=json&keys=' . $field_group['key']) . '">Json</a>'; $actions['acfe-key'] = '<code>' . $field_group['key'] . '</code>'; //$actions['acfe-id'] = '<span style="color:#555;">ID: ' . $field_group['ID'] . '</span>'; return $actions; } /** * post_states * * @param $states * @param $post * * @return mixed */ function post_states($states, $post){ // vars $field_group = acf_get_field_group($post->ID); // acf < 5.9 if($this->old_version){ // disabled if($post->post_status === 'acf-disabled'){ $states['acf-disabled'] = '<span class="dashicons dashicons-hidden acf-js-tooltip" title="' . _x('Disabled', 'post status', 'acf') . '"></span>'; } // acf > 5.9 }else{ if(isset($states['acf-disabled'])){ unset($states['acf-disabled']); $states['acf-disabled'] = '<span class="dashicons dashicons-hidden acf-js-tooltip" title="' . _x('Disabled', 'post status', 'acf') . '"></span>'; } } // alternative title $display_title = acf_maybe_get($field_group, 'acfe_display_title'); if(!empty($display_title)){ $states['acfe-title'] = '<span class="acf-js-tooltip" title="' . __('Alternative title', 'acf') . '">' . $display_title . '</span>'; } return $states; } /** * admin_footer */ function admin_footer(){ ?> <!-- ACFE: Label --> <script type="text/html" id="tmpl-acfe-label"> <span style="word-wrap: break-word;padding: 2px 6px;margin-left:1px;border-radius:2px;background:#ca4a1f;color: #fff; font-size: 14px;vertical-align: text-bottom;font-style: italic;">Extended</span> </script> <!-- ACFE: Debug --> <script type="text/html" id="tmpl-acfe-debug"> <div class="acf-box"> </div> </script> <script type="text/javascript"> (function($){ // ACFE: Label $('.acf-column-2 > .acf-box > .inner > h2').append($('#tmpl-acfe-label').html()); // ACFE: Debug //$('#posts-filter').append($('#tmpl-acfe-debug').html()); // Fix no field groups found $('#the-list tr.no-items td').attr('colspan', $('.wp-list-table > thead > tr > .manage-column:visible').length); })(jQuery); </script> <?php } /** * bulk_actions * * @param $actions * * @return mixed */ function bulk_actions($actions){ $actions['acfe_php'] = __( 'Export PHP', 'acf' ); $actions['acfe_json'] = __( 'Export Json', 'acf' ); return $actions; } /** * handle_bulk_actions * * @param $redirect * @param $action * @param $post_ids * * @return mixed|void */ function handle_bulk_actions($redirect, $action, $post_ids){ if(!isset($_REQUEST['post']) || empty($_REQUEST['post'])) return $redirect; // PHP if($action === 'acfe_php'){ $post_ids = $_REQUEST['post']; foreach($post_ids as &$post_id){ $field_group = acf_get_field_group($post_id); $post_id = $field_group['key']; } $url = admin_url('edit.php?post_type=acf-field-group&page=acf-tools&tool=export&action=php&keys=' . implode('+', $post_ids)); wp_redirect($url); exit; } // Json elseif($action === 'acfe_json'){ $post_ids = $_REQUEST['post']; foreach($post_ids as &$post_id){ $field_group = acf_get_field_group($post_id); $post_id = $field_group['key']; } $url = admin_url('edit.php?post_type=acf-field-group&page=acf-tools&tool=export&action=json&keys=' . implode('+', $post_ids)); wp_redirect($url); exit; } return $redirect; } /** * get_human_readable_file_location * * @param $file * @param $found * @param $br * @param $prefix * * @return string */ function get_human_readable_file_location($file, $found = true, $br = true, $prefix = true){ // Generate friendly file path. $theme_path = get_stylesheet_directory(); $located = ''; if( strpos($file, $theme_path) !== false ) { $rel_file = str_replace( $theme_path, '', $file ); if($prefix){ $located .= __($found ? 'Located' : 'Not found', 'acf'); } $located .= ' ' . __('in theme:', 'acf') . (($br) ? "<br/>" : ' '); $located .= $rel_file; } elseif( strpos($file, WP_PLUGIN_DIR) !== false ) { $rel_file = str_replace( WP_PLUGIN_DIR, '', $file ); if($prefix){ $located .= __($found ? 'Located' : 'Not found', 'acf'); } $located .= ' ' . __('in plugin:', 'acf') . (($br) ? "<br/>" : ' '); $located .= $rel_file; } else { $rel_file = str_replace( ABSPATH, '', $file ); if($prefix){ $located .= __($found ? 'Located' : 'Not found', 'acf'); } $located .= ' ' . __('in:', 'acf') . (($br) ? "<br/>" : ' '); $located .= $rel_file; } return $located; } /** * seamless_metabox * * @param $post_type * @param $post * @param $field_groups */ function seamless_metabox($post_type, $post, $field_groups){ // check gutenberg $is_gutenberg = acfe_is_block_editor(); foreach($field_groups as $field_group){ add_filter("postbox_classes_{$post_type}_acf-{$field_group['key']}", function($classes) use($field_group, $is_gutenberg){ // default $classes[] = 'acf-postbox'; // seamless if(!$is_gutenberg && $field_group['style'] === 'seamless'){ $classes[] = 'seamless'; } // left if($field_group['label_placement'] === 'left'){ $classes[] = 'acfe-postbox-left'; } // top if($field_group['label_placement'] === 'top'){ $classes[] = 'acfe-postbox-top'; } // return return $classes; }); } } /** * get_sync_compatibility * * @return array */ function get_sync_compatibility(){ $sync = array(); if(!acf_get_local_json_files()){ return $sync; } $field_groups = acf_get_field_groups(); foreach($field_groups as $field_group){ // Vars $local = acf_maybe_get($field_group, 'local'); $modified = acf_maybe_get($field_group, 'modified'); $private = acf_maybe_get($field_group, 'private'); // Bail early if($private || $local !== 'json'){ continue; } // If field group doesn't exists in DB or modified file date more recent than DB if(!$field_group['ID'] || ($modified && $modified > get_post_modified_time('U', true, $field_group['ID']))){ $sync[$field_group['key']] = $field_group; } } return $sync; } } acf_new_instance('ACFE_Field_Groups'); endif;