From 8bedb912407d53d3d12fd74e9ad97668437fdcac Mon Sep 17 00:00:00 2001 From: ptt-homme Date: Tue, 14 Sep 2021 18:06:41 +0200 Subject: [PATCH] Update to v5.10.2 --- acf.php | 1292 ++--- assets/build/css/acf-field-group.css | 8 +- assets/build/css/acf-field-group.min.css | 2 +- assets/build/js/acf-field-group.js | 58 +- assets/build/js/acf-field-group.min.js | 2 +- assets/build/js/acf-input.js | 35 +- assets/build/js/acf-input.min.js | 2 +- assets/build/js/pro/acf-pro-blocks-legacy.js | 1850 +++++++ .../build/js/pro/acf-pro-blocks-legacy.min.js | 1 + assets/build/js/pro/acf-pro-blocks.js | 514 +- assets/build/js/pro/acf-pro-blocks.min.js | 2 +- .../wp-color-picker-alpha.js | 635 +++ .../wp-color-picker-alpha.min.js | 11 + assets/inc/select2/3/select2-spinner.gif | Bin assets/inc/select2/3/select2.css | 0 assets/inc/select2/3/select2.js | 0 assets/inc/select2/3/select2.min.js | 0 assets/inc/select2/3/select2.png | Bin assets/inc/select2/3/select2x2.png | Bin assets/inc/select2/4/select2.css | 19 +- assets/inc/select2/4/select2.full.js | 960 +++- assets/inc/select2/4/select2.full.min.js | 4 +- assets/inc/select2/4/select2.js | 943 +++- assets/inc/select2/4/select2.min.css | 2 +- assets/inc/select2/4/select2.min.js | 5 +- .../timepicker/jquery-ui-timepicker-addon.css | 0 .../timepicker/jquery-ui-timepicker-addon.js | 0 .../jquery-ui-timepicker-addon.min.css | 0 .../jquery-ui-timepicker-addon.min.js | 0 includes/acf-field-functions.php | 1298 ++--- includes/acf-field-group-functions.php | 881 +-- includes/acf-form-functions.php | 133 +- includes/acf-helper-functions.php | 322 +- includes/acf-hook-functions.php | 198 +- includes/acf-input-functions.php | 420 +- includes/acf-meta-functions.php | 315 +- includes/acf-post-functions.php | 30 +- includes/acf-user-functions.php | 90 +- includes/acf-utility-functions.php | 102 +- includes/acf-value-functions.php | 290 +- includes/acf-wp-functions.php | 172 +- includes/admin/admin-field-group.php | 1582 +++--- includes/admin/admin-field-groups.php | 1586 +++--- includes/admin/admin-notices.php | 152 +- includes/admin/admin-tools.php | 596 +- includes/admin/admin-upgrade.php | 478 +- includes/admin/admin.php | 406 +- .../tools/class-acf-admin-tool-export.php | 990 ++-- .../tools/class-acf-admin-tool-import.php | 294 +- includes/admin/tools/class-acf-admin-tool.php | 379 +- .../field-group-field-conditional-logic.php | 197 +- includes/admin/views/field-group-field.php | 282 +- includes/admin/views/field-group-fields.php | 82 +- .../admin/views/field-group-locations.php | 39 +- includes/admin/views/field-group-options.php | 228 +- .../admin/views/html-admin-navigation.php | 74 +- .../views/html-admin-page-upgrade-network.php | 96 +- .../admin/views/html-admin-page-upgrade.php | 38 +- includes/admin/views/html-admin-tools.php | 31 +- includes/admin/views/html-location-group.php | 31 +- includes/admin/views/html-location-rule.php | 116 +- includes/admin/views/html-notice-upgrade.php | 37 +- includes/ajax/class-acf-ajax-check-screen.php | 187 +- .../ajax/class-acf-ajax-local-json-diff.php | 120 +- includes/ajax/class-acf-ajax-query-users.php | 536 +- includes/ajax/class-acf-ajax-query.php | 292 +- includes/ajax/class-acf-ajax-upgrade.php | 98 +- includes/ajax/class-acf-ajax-user-setting.php | 72 +- includes/ajax/class-acf-ajax.php | 447 +- includes/api/api-helpers.php | 4797 ++++++++--------- includes/api/api-template.php | 1441 +++-- includes/api/api-term.php | 564 +- includes/assets.php | 1019 ++-- includes/class-acf-data.php | 702 +-- includes/compatibility.php | 940 ++-- includes/deprecated.php | 123 +- includes/fields.php | 454 +- includes/fields/class-acf-field-accordion.php | 325 +- .../fields/class-acf-field-button-group.php | 555 +- includes/fields/class-acf-field-checkbox.php | 1124 ++-- .../fields/class-acf-field-color_picker.php | 412 +- .../fields/class-acf-field-date_picker.php | 529 +- .../class-acf-field-date_time_picker.php | 486 +- includes/fields/class-acf-field-email.php | 344 +- includes/fields/class-acf-field-file.php | 807 +-- .../fields/class-acf-field-google-map.php | 555 +- includes/fields/class-acf-field-group.php | 1270 +++-- includes/fields/class-acf-field-image.php | 809 +-- includes/fields/class-acf-field-link.php | 532 +- includes/fields/class-acf-field-message.php | 378 +- includes/fields/class-acf-field-number.php | 581 +- includes/fields/class-acf-field-oembed.php | 616 ++- includes/fields/class-acf-field-output.php | 135 +- includes/fields/class-acf-field-page_link.php | 1252 +++-- includes/fields/class-acf-field-password.php | 199 +- .../fields/class-acf-field-post_object.php | 1158 ++-- includes/fields/class-acf-field-radio.php | 866 +-- includes/fields/class-acf-field-range.php | 421 +- .../fields/class-acf-field-relationship.php | 1508 +++--- includes/fields/class-acf-field-select.php | 1215 ++--- includes/fields/class-acf-field-separator.php | 163 +- includes/fields/class-acf-field-tab.php | 315 +- includes/fields/class-acf-field-taxonomy.php | 1889 ++++--- includes/fields/class-acf-field-text.php | 331 +- includes/fields/class-acf-field-textarea.php | 432 +- .../fields/class-acf-field-time_picker.php | 322 +- .../fields/class-acf-field-true_false.php | 543 +- includes/fields/class-acf-field-url.php | 314 +- includes/fields/class-acf-field-user.php | 896 +-- includes/fields/class-acf-field-wysiwyg.php | 833 ++- includes/fields/class-acf-field.php | 532 +- includes/forms/form-attachment.php | 429 +- includes/forms/form-comment.php | 583 +- includes/forms/form-customizer.php | 768 ++- includes/forms/form-front.php | 1171 ++-- includes/forms/form-gutenberg.php | 348 +- includes/forms/form-nav-menu.php | 659 +-- includes/forms/form-post.php | 654 +-- includes/forms/form-taxonomy.php | 634 ++- includes/forms/form-user.php | 697 +-- includes/forms/form-widget.php | 489 +- includes/l10n.php | 166 +- includes/legacy/legacy-locations.php | 134 +- includes/local-fields.php | 406 +- includes/local-json.php | 550 +- includes/local-meta.php | 440 +- includes/locations.php | 266 +- .../abstract-acf-legacy-location.php | 118 +- includes/locations/abstract-acf-location.php | 370 +- .../class-acf-location-attachment.php | 180 +- .../locations/class-acf-location-comment.php | 132 +- .../class-acf-location-current-user-role.php | 168 +- .../class-acf-location-current-user.php | 150 +- .../class-acf-location-nav-menu-item.php | 130 +- .../locations/class-acf-location-nav-menu.php | 194 +- .../class-acf-location-page-parent.php | 132 +- .../class-acf-location-page-template.php | 154 +- .../class-acf-location-page-type.php | 230 +- .../locations/class-acf-location-page.php | 142 +- .../class-acf-location-post-category.php | 140 +- .../class-acf-location-post-format.php | 140 +- .../class-acf-location-post-status.php | 156 +- .../class-acf-location-post-taxonomy.php | 220 +- .../class-acf-location-post-template.php | 240 +- .../class-acf-location-post-type.php | 180 +- .../locations/class-acf-location-post.php | 172 +- .../locations/class-acf-location-taxonomy.php | 168 +- .../class-acf-location-user-form.php | 144 +- .../class-acf-location-user-role.php | 164 +- .../locations/class-acf-location-widget.php | 146 +- includes/loop.php | 591 +- includes/media.php | 454 +- includes/revisions.php | 853 ++- includes/third-party.php | 388 +- includes/updates.php | 940 ++-- includes/upgrades.php | 650 +-- includes/validation.php | 612 ++- .../class-acf-walker-nav-menu-edit.php | 140 +- .../class-acf-walker-taxonomy-field.php | 256 +- includes/wpml.php | 606 ++- lang/acf-ar.mo | Bin lang/acf-cs_CZ.mo | Bin lang/acf-de_CH.mo | Bin lang/acf-de_DE.mo | Bin lang/acf-de_DE_formal.mo | Bin lang/acf-fr_FR.mo | Bin lang/acf-id_ID.mo | Bin lang/acf-it_IT.mo | Bin lang/acf-ja.mo | Bin lang/acf-pt_BR.mo | Bin lang/acf-sk_SK.mo | Bin lang/acf-sv_SE.mo | Bin 48648 -> 47307 bytes lang/acf-sv_SE.po | 3803 +++++++------ pro/acf-pro.php | 337 +- pro/admin/admin-options-page.php | 686 ++- pro/admin/admin-updates.php | 673 +-- pro/admin/views/html-options-page.php | 24 +- pro/admin/views/html-settings-updates.php | 98 +- pro/blocks.php | 651 +-- pro/fields/class-acf-field-clone.php | 2522 +++++---- .../class-acf-field-flexible-content.php | 3173 ++++++----- pro/fields/class-acf-field-gallery.php | 1567 +++--- pro/fields/class-acf-field-repeater.php | 1985 ++++--- pro/locations/class-acf-location-block.php | 152 +- .../class-acf-location-options-page.php | 150 +- pro/options-page.php | 943 ++-- pro/updates.php | 336 +- readme.txt | 63 +- 188 files changed, 46044 insertions(+), 41722 deletions(-) create mode 100755 assets/build/js/pro/acf-pro-blocks-legacy.js create mode 100755 assets/build/js/pro/acf-pro-blocks-legacy.min.js create mode 100644 assets/inc/color-picker-alpha/wp-color-picker-alpha.js create mode 100644 assets/inc/color-picker-alpha/wp-color-picker-alpha.min.js mode change 100644 => 100755 assets/inc/select2/3/select2-spinner.gif mode change 100644 => 100755 assets/inc/select2/3/select2.css mode change 100644 => 100755 assets/inc/select2/3/select2.js mode change 100644 => 100755 assets/inc/select2/3/select2.min.js mode change 100644 => 100755 assets/inc/select2/3/select2.png mode change 100644 => 100755 assets/inc/select2/3/select2x2.png mode change 100644 => 100755 assets/inc/select2/4/select2.css mode change 100644 => 100755 assets/inc/select2/4/select2.full.js mode change 100644 => 100755 assets/inc/select2/4/select2.js mode change 100644 => 100755 assets/inc/select2/4/select2.min.css mode change 100644 => 100755 assets/inc/select2/4/select2.min.js mode change 100644 => 100755 assets/inc/timepicker/jquery-ui-timepicker-addon.css mode change 100644 => 100755 assets/inc/timepicker/jquery-ui-timepicker-addon.js mode change 100644 => 100755 assets/inc/timepicker/jquery-ui-timepicker-addon.min.css mode change 100644 => 100755 assets/inc/timepicker/jquery-ui-timepicker-addon.min.js mode change 100644 => 100755 includes/fields.php mode change 100644 => 100755 includes/fields/class-acf-field.php mode change 100644 => 100755 includes/local-meta.php mode change 100644 => 100755 lang/acf-ar.mo mode change 100644 => 100755 lang/acf-cs_CZ.mo mode change 100644 => 100755 lang/acf-de_CH.mo mode change 100644 => 100755 lang/acf-de_DE.mo mode change 100644 => 100755 lang/acf-de_DE_formal.mo mode change 100644 => 100755 lang/acf-fr_FR.mo mode change 100644 => 100755 lang/acf-id_ID.mo mode change 100644 => 100755 lang/acf-it_IT.mo mode change 100644 => 100755 lang/acf-ja.mo mode change 100644 => 100755 lang/acf-pt_BR.mo mode change 100644 => 100755 lang/acf-sk_SK.mo mode change 100644 => 100755 pro/blocks.php mode change 100644 => 100755 pro/locations/class-acf-location-block.php diff --git a/acf.php b/acf.php index 2a71eb4..a945f50 100644 --- a/acf.php +++ b/acf.php @@ -3,655 +3,665 @@ Plugin Name: Advanced Custom Fields PRO Plugin URI: https://www.advancedcustomfields.com Description: Customize WordPress with powerful, professional and intuitive fields. -Version: 5.9.9 +Version: 5.10.2 Author: Delicious Brains Author URI: https://www.advancedcustomfields.com Text Domain: acf Domain Path: /lang */ -if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly - -if( ! class_exists('ACF') ) : - -class ACF { - - /** @var string The plugin version number. */ - var $version = '5.9.9'; - - /** @var array The plugin settings array. */ - var $settings = array(); - - /** @var array The plugin data array. */ - var $data = array(); - - /** @var array Storage for class instances. */ - var $instances = array(); - - /** - * __construct - * - * A dummy constructor to ensure ACF is only setup once. - * - * @date 23/06/12 - * @since 5.0.0 - * - * @param void - * @return void - */ - function __construct() { - // Do nothing. - } - - /** - * initialize - * - * Sets up the ACF plugin. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param void - * @return void - */ - function initialize() { - - // Define constants. - $this->define( 'ACF', true ); - $this->define( 'ACF_PATH', plugin_dir_path( __FILE__ ) ); - $this->define( 'ACF_BASENAME', plugin_basename( __FILE__ ) ); - $this->define( 'ACF_VERSION', $this->version ); - $this->define( 'ACF_MAJOR_VERSION', 5 ); - - // Define settings. - $this->settings = array( - 'name' => __('Advanced Custom Fields', 'acf'), - 'slug' => dirname( ACF_BASENAME ), - 'version' => ACF_VERSION, - 'basename' => ACF_BASENAME, - 'path' => ACF_PATH, - 'file' => __FILE__, - 'url' => plugin_dir_url( __FILE__ ), - 'show_admin' => true, - 'show_updates' => true, - 'stripslashes' => false, - 'local' => true, - 'json' => true, - 'save_json' => '', - 'load_json' => array(), - 'default_language' => '', - 'current_language' => '', - 'capability' => 'manage_options', - 'uploader' => 'wp', - 'autoload' => false, - 'l10n' => true, - 'l10n_textdomain' => '', - 'google_api_key' => '', - 'google_api_client' => '', - 'enqueue_google_maps' => true, - 'enqueue_select2' => true, - 'enqueue_datepicker' => true, - 'enqueue_datetimepicker' => true, - 'select2_version' => 4, - 'row_index_offset' => 1, - 'remove_wp_meta_box' => true - ); - - // Include utility functions. - include_once( ACF_PATH . 'includes/acf-utility-functions.php'); - - // Include previous API functions. - acf_include('includes/api/api-helpers.php'); - acf_include('includes/api/api-template.php'); - acf_include('includes/api/api-term.php'); - - // Include classes. - acf_include('includes/class-acf-data.php'); - acf_include('includes/fields/class-acf-field.php'); - acf_include('includes/locations/abstract-acf-legacy-location.php'); - acf_include('includes/locations/abstract-acf-location.php'); - - // Include functions. - acf_include('includes/acf-helper-functions.php'); - acf_include('includes/acf-hook-functions.php'); - acf_include('includes/acf-field-functions.php'); - acf_include('includes/acf-field-group-functions.php'); - acf_include('includes/acf-form-functions.php'); - acf_include('includes/acf-meta-functions.php'); - acf_include('includes/acf-post-functions.php'); - acf_include('includes/acf-user-functions.php'); - acf_include('includes/acf-value-functions.php'); - acf_include('includes/acf-input-functions.php'); - acf_include('includes/acf-wp-functions.php'); - - // Include core. - acf_include('includes/fields.php'); - acf_include('includes/locations.php'); - acf_include('includes/assets.php'); - acf_include('includes/compatibility.php'); - acf_include('includes/deprecated.php'); - acf_include('includes/l10n.php'); - acf_include('includes/local-fields.php'); - acf_include('includes/local-meta.php'); - acf_include('includes/local-json.php'); - acf_include('includes/loop.php'); - acf_include('includes/media.php'); - acf_include('includes/revisions.php'); - acf_include('includes/updates.php'); - acf_include('includes/upgrades.php'); - acf_include('includes/validation.php'); - - // Include ajax. - acf_include('includes/ajax/class-acf-ajax.php'); - acf_include('includes/ajax/class-acf-ajax-check-screen.php'); - acf_include('includes/ajax/class-acf-ajax-user-setting.php'); - acf_include('includes/ajax/class-acf-ajax-upgrade.php'); - acf_include('includes/ajax/class-acf-ajax-query.php'); - acf_include('includes/ajax/class-acf-ajax-query-users.php'); - acf_include('includes/ajax/class-acf-ajax-local-json-diff.php'); - - // Include forms. - acf_include('includes/forms/form-attachment.php'); - acf_include('includes/forms/form-comment.php'); - acf_include('includes/forms/form-customizer.php'); - acf_include('includes/forms/form-front.php'); - acf_include('includes/forms/form-nav-menu.php'); - acf_include('includes/forms/form-post.php'); - acf_include('includes/forms/form-gutenberg.php'); - acf_include('includes/forms/form-taxonomy.php'); - acf_include('includes/forms/form-user.php'); - acf_include('includes/forms/form-widget.php'); - - // Include admin. - if( is_admin() ) { - acf_include('includes/admin/admin.php'); - acf_include('includes/admin/admin-field-group.php'); - acf_include('includes/admin/admin-field-groups.php'); - acf_include('includes/admin/admin-notices.php'); - acf_include('includes/admin/admin-tools.php'); - acf_include('includes/admin/admin-upgrade.php'); - } - - // Include legacy. - acf_include('includes/legacy/legacy-locations.php'); - - // Include PRO. - acf_include('pro/acf-pro.php'); - - // Include tests. - if( defined('ACF_DEV') && ACF_DEV ) { - acf_include('tests/tests.php'); - } - - // Add actions. - add_action( 'init', array($this, 'init'), 5 ); - add_action( 'init', array($this, 'register_post_types'), 5 ); - add_action( 'init', array($this, 'register_post_status'), 5 ); - - // Add filters. - add_filter( 'posts_where', array($this, 'posts_where'), 10, 2 ); - } - - /** - * init - * - * Completes the setup process on "init" of earlier. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param void - * @return void - */ - function init() { - - // Bail early if called directly from functions.php or plugin file. - if( !did_action('plugins_loaded') ) { - return; - } - - // This function may be called directly from template functions. Bail early if already did this. - if( acf_did('init') ) { - return; - } - - // Update url setting. Allows other plugins to modify the URL (force SSL). - acf_update_setting( 'url', plugin_dir_url( __FILE__ ) ); - - // Load textdomain file. - acf_load_textdomain(); - - // Include 3rd party compatiblity. - acf_include('includes/third-party.php'); - - // Include wpml support. - if( defined('ICL_SITEPRESS_VERSION') ) { - acf_include('includes/wpml.php'); - } - - // Include fields. - acf_include('includes/fields/class-acf-field-text.php'); - acf_include('includes/fields/class-acf-field-textarea.php'); - acf_include('includes/fields/class-acf-field-number.php'); - acf_include('includes/fields/class-acf-field-range.php'); - acf_include('includes/fields/class-acf-field-email.php'); - acf_include('includes/fields/class-acf-field-url.php'); - acf_include('includes/fields/class-acf-field-password.php'); - acf_include('includes/fields/class-acf-field-image.php'); - acf_include('includes/fields/class-acf-field-file.php'); - acf_include('includes/fields/class-acf-field-wysiwyg.php'); - acf_include('includes/fields/class-acf-field-oembed.php'); - acf_include('includes/fields/class-acf-field-select.php'); - acf_include('includes/fields/class-acf-field-checkbox.php'); - acf_include('includes/fields/class-acf-field-radio.php'); - acf_include('includes/fields/class-acf-field-button-group.php'); - acf_include('includes/fields/class-acf-field-true_false.php'); - acf_include('includes/fields/class-acf-field-link.php'); - acf_include('includes/fields/class-acf-field-post_object.php'); - acf_include('includes/fields/class-acf-field-page_link.php'); - acf_include('includes/fields/class-acf-field-relationship.php'); - acf_include('includes/fields/class-acf-field-taxonomy.php'); - acf_include('includes/fields/class-acf-field-user.php'); - acf_include('includes/fields/class-acf-field-google-map.php'); - acf_include('includes/fields/class-acf-field-date_picker.php'); - acf_include('includes/fields/class-acf-field-date_time_picker.php'); - acf_include('includes/fields/class-acf-field-time_picker.php'); - acf_include('includes/fields/class-acf-field-color_picker.php'); - acf_include('includes/fields/class-acf-field-message.php'); - acf_include('includes/fields/class-acf-field-accordion.php'); - acf_include('includes/fields/class-acf-field-tab.php'); - acf_include('includes/fields/class-acf-field-group.php'); - - /** - * Fires after field types have been included. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param int $major_version The major version of ACF. - */ - do_action( 'acf/include_field_types', ACF_MAJOR_VERSION ); - - // Include locations. - acf_include('includes/locations/class-acf-location-post-type.php'); - acf_include('includes/locations/class-acf-location-post-template.php'); - acf_include('includes/locations/class-acf-location-post-status.php'); - acf_include('includes/locations/class-acf-location-post-format.php'); - acf_include('includes/locations/class-acf-location-post-category.php'); - acf_include('includes/locations/class-acf-location-post-taxonomy.php'); - acf_include('includes/locations/class-acf-location-post.php'); - acf_include('includes/locations/class-acf-location-page-template.php'); - acf_include('includes/locations/class-acf-location-page-type.php'); - acf_include('includes/locations/class-acf-location-page-parent.php'); - acf_include('includes/locations/class-acf-location-page.php'); - acf_include('includes/locations/class-acf-location-current-user.php'); - acf_include('includes/locations/class-acf-location-current-user-role.php'); - acf_include('includes/locations/class-acf-location-user-form.php'); - acf_include('includes/locations/class-acf-location-user-role.php'); - acf_include('includes/locations/class-acf-location-taxonomy.php'); - acf_include('includes/locations/class-acf-location-attachment.php'); - acf_include('includes/locations/class-acf-location-comment.php'); - acf_include('includes/locations/class-acf-location-widget.php'); - acf_include('includes/locations/class-acf-location-nav-menu.php'); - acf_include('includes/locations/class-acf-location-nav-menu-item.php'); - - /** - * Fires after location types have been included. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param int $major_version The major version of ACF. - */ - do_action( 'acf/include_location_rules', ACF_MAJOR_VERSION ); - - /** - * Fires during initialization. Used to add local fields. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param int $major_version The major version of ACF. - */ - do_action( 'acf/include_fields', ACF_MAJOR_VERSION ); - - /** - * Fires after ACF is completely "initialized". - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param int $major_version The major version of ACF. - */ - do_action( 'acf/init', ACF_MAJOR_VERSION ); - } - - /** - * register_post_types - * - * Registers the ACF post types. - * - * @date 22/10/2015 - * @since 5.3.2 - * - * @param void - * @return void - */ - function register_post_types() { - - // Vars. - $cap = acf_get_setting('capability'); - - // Register the Field Group post type. - register_post_type('acf-field-group', array( - 'labels' => array( - 'name' => __( 'Field Groups', 'acf' ), - 'singular_name' => __( 'Field Group', 'acf' ), - 'add_new' => __( 'Add New' , 'acf' ), - 'add_new_item' => __( 'Add New Field Group' , 'acf' ), - 'edit_item' => __( 'Edit Field Group' , 'acf' ), - 'new_item' => __( 'New Field Group' , 'acf' ), - 'view_item' => __( 'View Field Group', 'acf' ), - 'search_items' => __( 'Search Field Groups', 'acf' ), - 'not_found' => __( 'No Field Groups found', 'acf' ), - 'not_found_in_trash' => __( 'No Field Groups found in Trash', 'acf' ), - ), - 'public' => false, - 'hierarchical' => true, - 'show_ui' => true, - 'show_in_menu' => false, - '_builtin' => false, - 'capability_type' => 'post', - 'capabilities' => array( - 'edit_post' => $cap, - 'delete_post' => $cap, - 'edit_posts' => $cap, - 'delete_posts' => $cap, - ), - 'supports' => array('title'), - 'rewrite' => false, - 'query_var' => false, - )); - - - // Register the Field post type. - register_post_type('acf-field', array( - 'labels' => array( - 'name' => __( 'Fields', 'acf' ), - 'singular_name' => __( 'Field', 'acf' ), - 'add_new' => __( 'Add New' , 'acf' ), - 'add_new_item' => __( 'Add New Field' , 'acf' ), - 'edit_item' => __( 'Edit Field' , 'acf' ), - 'new_item' => __( 'New Field' , 'acf' ), - 'view_item' => __( 'View Field', 'acf' ), - 'search_items' => __( 'Search Fields', 'acf' ), - 'not_found' => __( 'No Fields found', 'acf' ), - 'not_found_in_trash' => __( 'No Fields found in Trash', 'acf' ), - ), - 'public' => false, - 'hierarchical' => true, - 'show_ui' => false, - 'show_in_menu' => false, - '_builtin' => false, - 'capability_type' => 'post', - 'capabilities' => array( - 'edit_post' => $cap, - 'delete_post' => $cap, - 'edit_posts' => $cap, - 'delete_posts' => $cap, - ), - 'supports' => array('title'), - 'rewrite' => false, - 'query_var' => false, - )); - } - - /** - * register_post_status - * - * Registers the ACF post statuses. - * - * @date 22/10/2015 - * @since 5.3.2 - * - * @param void - * @return void - */ - function register_post_status() { - - // Register the Disabled post status. - register_post_status('acf-disabled', array( - 'label' => _x( 'Disabled', 'post status', 'acf' ), - 'public' => true, - 'exclude_from_search' => false, - 'show_in_admin_all_list' => true, - 'show_in_admin_status_list' => true, - 'label_count' => _n_noop( 'Disabled (%s)', 'Disabled (%s)', 'acf' ), - )); - } - - /** - * posts_where - * - * Filters the $where clause allowing for custom WP_Query args. - * - * @date 31/8/19 - * @since 5.8.1 - * - * @param string $where The WHERE clause. - * @return WP_Query $wp_query The query object. - */ - function posts_where( $where, $wp_query ) { - global $wpdb; - - // Add custom "acf_field_key" arg. - if( $field_key = $wp_query->get('acf_field_key') ) { - $where .= $wpdb->prepare(" AND {$wpdb->posts}.post_name = %s", $field_key ); - } - - // Add custom "acf_field_name" arg. - if( $field_name = $wp_query->get('acf_field_name') ) { - $where .= $wpdb->prepare(" AND {$wpdb->posts}.post_excerpt = %s", $field_name ); - } - - // Add custom "acf_group_key" arg. - if( $group_key = $wp_query->get('acf_group_key') ) { - $where .= $wpdb->prepare(" AND {$wpdb->posts}.post_name = %s", $group_key ); - } - - // Return. - return $where; - } - - /** - * define - * - * Defines a constant if doesnt already exist. - * - * @date 3/5/17 - * @since 5.5.13 - * - * @param string $name The constant name. - * @param mixed $value The constant value. - * @return void - */ - function define( $name, $value = true ) { - if( !defined($name) ) { - define( $name, $value ); - } - } - - /** - * has_setting - * - * Returns true if a setting exists for this name. - * - * @date 2/2/18 - * @since 5.6.5 - * - * @param string $name The setting name. - * @return boolean - */ - function has_setting( $name ) { - return isset($this->settings[ $name ]); - } - - /** - * get_setting - * - * Returns a setting or null if doesn't exist. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param string $name The setting name. - * @return mixed - */ - function get_setting( $name ) { - return isset($this->settings[ $name ]) ? $this->settings[ $name ] : null; - } - - /** - * update_setting - * - * Updates a setting for the given name and value. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param string $name The setting name. - * @param mixed $value The setting value. - * @return true - */ - function update_setting( $name, $value ) { - $this->settings[ $name ] = $value; - return true; - } - - /** - * get_data - * - * Returns data or null if doesn't exist. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param string $name The data name. - * @return mixed - */ - function get_data( $name ) { - return isset($this->data[ $name ]) ? $this->data[ $name ] : null; - } - - /** - * set_data - * - * Sets data for the given name and value. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param string $name The data name. - * @param mixed $value The data value. - * @return void - */ - function set_data( $name, $value ) { - $this->data[ $name ] = $value; - } - - /** - * get_instance - * - * Returns an instance or null if doesn't exist. - * - * @date 13/2/18 - * @since 5.6.9 - * - * @param string $class The instance class name. - * @return object - */ - function get_instance( $class ) { - $name = strtolower($class); - return isset($this->instances[ $name ]) ? $this->instances[ $name ] : null; - } - - /** - * new_instance - * - * Creates and stores an instance of the given class. - * - * @date 13/2/18 - * @since 5.6.9 - * - * @param string $class The instance class name. - * @return object - */ - function new_instance( $class ) { - $instance = new $class(); - $name = strtolower($class); - $this->instances[ $name ] = $instance; - return $instance; - } - - /** - * Magic __isset method for backwards compatibility. - * - * @date 24/4/20 - * @since 5.9.0 - * - * @param string $key Key name. - * @return bool - */ - public function __isset( $key ) { - return in_array( $key, array( 'locations', 'json' ) ); - } - - /** - * Magic __get method for backwards compatibility. - * - * @date 24/4/20 - * @since 5.9.0 - * - * @param string $key Key name. - * @return mixed - */ - public function __get( $key ) { - switch ( $key ) { - case 'locations': - return acf_get_instance( 'ACF_Legacy_Locations' ); - case 'json': - return acf_get_instance( 'ACF_Local_JSON' ); - } - return null; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -/* - * acf - * - * The main function responsible for returning the one true acf Instance to functions everywhere. - * Use this function like you would a global variable, except without needing to declare the global. - * - * Example: - * - * @date 4/09/13 - * @since 4.3.0 - * - * @param void - * @return ACF - */ -function acf() { - global $acf; - - // Instantiate only once. - if( !isset($acf) ) { - $acf = new ACF(); - $acf->initialize(); - } - return $acf; -} +if ( ! class_exists( 'ACF' ) ) : -// Instantiate. -acf(); + class ACF { + + /** @var string The plugin version number. */ + var $version = '5.10.2'; + + /** @var array The plugin settings array. */ + var $settings = array(); + + /** @var array The plugin data array. */ + var $data = array(); + + /** @var array Storage for class instances. */ + var $instances = array(); + + /** + * __construct + * + * A dummy constructor to ensure ACF is only setup once. + * + * @date 23/06/12 + * @since 5.0.0 + * + * @param void + * @return void + */ + function __construct() { + // Do nothing. + } + + /** + * initialize + * + * Sets up the ACF plugin. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + function initialize() { + + // Define constants. + $this->define( 'ACF', true ); + $this->define( 'ACF_PATH', plugin_dir_path( __FILE__ ) ); + $this->define( 'ACF_BASENAME', plugin_basename( __FILE__ ) ); + $this->define( 'ACF_VERSION', $this->version ); + $this->define( 'ACF_MAJOR_VERSION', 5 ); + + // Define settings. + $this->settings = array( + 'name' => __( 'Advanced Custom Fields', 'acf' ), + 'slug' => dirname( ACF_BASENAME ), + 'version' => ACF_VERSION, + 'basename' => ACF_BASENAME, + 'path' => ACF_PATH, + 'file' => __FILE__, + 'url' => plugin_dir_url( __FILE__ ), + 'show_admin' => true, + 'show_updates' => true, + 'stripslashes' => false, + 'local' => true, + 'json' => true, + 'save_json' => '', + 'load_json' => array(), + 'default_language' => '', + 'current_language' => '', + 'capability' => 'manage_options', + 'uploader' => 'wp', + 'autoload' => false, + 'l10n' => true, + 'l10n_textdomain' => '', + 'google_api_key' => '', + 'google_api_client' => '', + 'enqueue_google_maps' => true, + 'enqueue_select2' => true, + 'enqueue_datepicker' => true, + 'enqueue_datetimepicker' => true, + 'select2_version' => 4, + 'row_index_offset' => 1, + 'remove_wp_meta_box' => true, + ); + + // Include utility functions. + include_once ACF_PATH . 'includes/acf-utility-functions.php'; + + // Include previous API functions. + acf_include( 'includes/api/api-helpers.php' ); + acf_include( 'includes/api/api-template.php' ); + acf_include( 'includes/api/api-term.php' ); + + // Include classes. + acf_include( 'includes/class-acf-data.php' ); + acf_include( 'includes/fields/class-acf-field.php' ); + acf_include( 'includes/locations/abstract-acf-legacy-location.php' ); + acf_include( 'includes/locations/abstract-acf-location.php' ); + + // Include functions. + acf_include( 'includes/acf-helper-functions.php' ); + acf_include( 'includes/acf-hook-functions.php' ); + acf_include( 'includes/acf-field-functions.php' ); + acf_include( 'includes/acf-field-group-functions.php' ); + acf_include( 'includes/acf-form-functions.php' ); + acf_include( 'includes/acf-meta-functions.php' ); + acf_include( 'includes/acf-post-functions.php' ); + acf_include( 'includes/acf-user-functions.php' ); + acf_include( 'includes/acf-value-functions.php' ); + acf_include( 'includes/acf-input-functions.php' ); + acf_include( 'includes/acf-wp-functions.php' ); + + // Include core. + acf_include( 'includes/fields.php' ); + acf_include( 'includes/locations.php' ); + acf_include( 'includes/assets.php' ); + acf_include( 'includes/compatibility.php' ); + acf_include( 'includes/deprecated.php' ); + acf_include( 'includes/l10n.php' ); + acf_include( 'includes/local-fields.php' ); + acf_include( 'includes/local-meta.php' ); + acf_include( 'includes/local-json.php' ); + acf_include( 'includes/loop.php' ); + acf_include( 'includes/media.php' ); + acf_include( 'includes/revisions.php' ); + acf_include( 'includes/updates.php' ); + acf_include( 'includes/upgrades.php' ); + acf_include( 'includes/validation.php' ); + + // Include ajax. + acf_include( 'includes/ajax/class-acf-ajax.php' ); + acf_include( 'includes/ajax/class-acf-ajax-check-screen.php' ); + acf_include( 'includes/ajax/class-acf-ajax-user-setting.php' ); + acf_include( 'includes/ajax/class-acf-ajax-upgrade.php' ); + acf_include( 'includes/ajax/class-acf-ajax-query.php' ); + acf_include( 'includes/ajax/class-acf-ajax-query-users.php' ); + acf_include( 'includes/ajax/class-acf-ajax-local-json-diff.php' ); + + // Include forms. + acf_include( 'includes/forms/form-attachment.php' ); + acf_include( 'includes/forms/form-comment.php' ); + acf_include( 'includes/forms/form-customizer.php' ); + acf_include( 'includes/forms/form-front.php' ); + acf_include( 'includes/forms/form-nav-menu.php' ); + acf_include( 'includes/forms/form-post.php' ); + acf_include( 'includes/forms/form-gutenberg.php' ); + acf_include( 'includes/forms/form-taxonomy.php' ); + acf_include( 'includes/forms/form-user.php' ); + acf_include( 'includes/forms/form-widget.php' ); + + // Include admin. + if ( is_admin() ) { + acf_include( 'includes/admin/admin.php' ); + acf_include( 'includes/admin/admin-field-group.php' ); + acf_include( 'includes/admin/admin-field-groups.php' ); + acf_include( 'includes/admin/admin-notices.php' ); + acf_include( 'includes/admin/admin-tools.php' ); + acf_include( 'includes/admin/admin-upgrade.php' ); + } + + // Include legacy. + acf_include( 'includes/legacy/legacy-locations.php' ); + + // Include PRO. + acf_include( 'pro/acf-pro.php' ); + + // Include tests. + if ( defined( 'ACF_DEV' ) && ACF_DEV ) { + acf_include( 'tests/tests.php' ); + } + + // Add actions. + add_action( 'init', array( $this, 'init' ), 5 ); + add_action( 'init', array( $this, 'register_post_types' ), 5 ); + add_action( 'init', array( $this, 'register_post_status' ), 5 ); + + // Add filters. + add_filter( 'posts_where', array( $this, 'posts_where' ), 10, 2 ); + } + + /** + * init + * + * Completes the setup process on "init" of earlier. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + function init() { + + // Bail early if called directly from functions.php or plugin file. + if ( ! did_action( 'plugins_loaded' ) ) { + return; + } + + // This function may be called directly from template functions. Bail early if already did this. + if ( acf_did( 'init' ) ) { + return; + } + + // Update url setting. Allows other plugins to modify the URL (force SSL). + acf_update_setting( 'url', plugin_dir_url( __FILE__ ) ); + + // Load textdomain file. + acf_load_textdomain(); + + // Include 3rd party compatiblity. + acf_include( 'includes/third-party.php' ); + + // Include wpml support. + if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { + acf_include( 'includes/wpml.php' ); + } + + // Include fields. + acf_include( 'includes/fields/class-acf-field-text.php' ); + acf_include( 'includes/fields/class-acf-field-textarea.php' ); + acf_include( 'includes/fields/class-acf-field-number.php' ); + acf_include( 'includes/fields/class-acf-field-range.php' ); + acf_include( 'includes/fields/class-acf-field-email.php' ); + acf_include( 'includes/fields/class-acf-field-url.php' ); + acf_include( 'includes/fields/class-acf-field-password.php' ); + acf_include( 'includes/fields/class-acf-field-image.php' ); + acf_include( 'includes/fields/class-acf-field-file.php' ); + acf_include( 'includes/fields/class-acf-field-wysiwyg.php' ); + acf_include( 'includes/fields/class-acf-field-oembed.php' ); + acf_include( 'includes/fields/class-acf-field-select.php' ); + acf_include( 'includes/fields/class-acf-field-checkbox.php' ); + acf_include( 'includes/fields/class-acf-field-radio.php' ); + acf_include( 'includes/fields/class-acf-field-button-group.php' ); + acf_include( 'includes/fields/class-acf-field-true_false.php' ); + acf_include( 'includes/fields/class-acf-field-link.php' ); + acf_include( 'includes/fields/class-acf-field-post_object.php' ); + acf_include( 'includes/fields/class-acf-field-page_link.php' ); + acf_include( 'includes/fields/class-acf-field-relationship.php' ); + acf_include( 'includes/fields/class-acf-field-taxonomy.php' ); + acf_include( 'includes/fields/class-acf-field-user.php' ); + acf_include( 'includes/fields/class-acf-field-google-map.php' ); + acf_include( 'includes/fields/class-acf-field-date_picker.php' ); + acf_include( 'includes/fields/class-acf-field-date_time_picker.php' ); + acf_include( 'includes/fields/class-acf-field-time_picker.php' ); + acf_include( 'includes/fields/class-acf-field-color_picker.php' ); + acf_include( 'includes/fields/class-acf-field-message.php' ); + acf_include( 'includes/fields/class-acf-field-accordion.php' ); + acf_include( 'includes/fields/class-acf-field-tab.php' ); + acf_include( 'includes/fields/class-acf-field-group.php' ); + + /** + * Fires after field types have been included. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param int $major_version The major version of ACF. + */ + do_action( 'acf/include_field_types', ACF_MAJOR_VERSION ); + + // Include locations. + acf_include( 'includes/locations/class-acf-location-post-type.php' ); + acf_include( 'includes/locations/class-acf-location-post-template.php' ); + acf_include( 'includes/locations/class-acf-location-post-status.php' ); + acf_include( 'includes/locations/class-acf-location-post-format.php' ); + acf_include( 'includes/locations/class-acf-location-post-category.php' ); + acf_include( 'includes/locations/class-acf-location-post-taxonomy.php' ); + acf_include( 'includes/locations/class-acf-location-post.php' ); + acf_include( 'includes/locations/class-acf-location-page-template.php' ); + acf_include( 'includes/locations/class-acf-location-page-type.php' ); + acf_include( 'includes/locations/class-acf-location-page-parent.php' ); + acf_include( 'includes/locations/class-acf-location-page.php' ); + acf_include( 'includes/locations/class-acf-location-current-user.php' ); + acf_include( 'includes/locations/class-acf-location-current-user-role.php' ); + acf_include( 'includes/locations/class-acf-location-user-form.php' ); + acf_include( 'includes/locations/class-acf-location-user-role.php' ); + acf_include( 'includes/locations/class-acf-location-taxonomy.php' ); + acf_include( 'includes/locations/class-acf-location-attachment.php' ); + acf_include( 'includes/locations/class-acf-location-comment.php' ); + acf_include( 'includes/locations/class-acf-location-widget.php' ); + acf_include( 'includes/locations/class-acf-location-nav-menu.php' ); + acf_include( 'includes/locations/class-acf-location-nav-menu-item.php' ); + + /** + * Fires after location types have been included. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param int $major_version The major version of ACF. + */ + do_action( 'acf/include_location_rules', ACF_MAJOR_VERSION ); + + /** + * Fires during initialization. Used to add local fields. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param int $major_version The major version of ACF. + */ + do_action( 'acf/include_fields', ACF_MAJOR_VERSION ); + + /** + * Fires after ACF is completely "initialized". + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param int $major_version The major version of ACF. + */ + do_action( 'acf/init', ACF_MAJOR_VERSION ); + } + + /** + * register_post_types + * + * Registers the ACF post types. + * + * @date 22/10/2015 + * @since 5.3.2 + * + * @param void + * @return void + */ + function register_post_types() { + + // Vars. + $cap = acf_get_setting( 'capability' ); + + // Register the Field Group post type. + register_post_type( + 'acf-field-group', + array( + 'labels' => array( + 'name' => __( 'Field Groups', 'acf' ), + 'singular_name' => __( 'Field Group', 'acf' ), + 'add_new' => __( 'Add New', 'acf' ), + 'add_new_item' => __( 'Add New Field Group', 'acf' ), + 'edit_item' => __( 'Edit Field Group', 'acf' ), + 'new_item' => __( 'New Field Group', 'acf' ), + 'view_item' => __( 'View Field Group', 'acf' ), + 'search_items' => __( 'Search Field Groups', 'acf' ), + 'not_found' => __( 'No Field Groups found', 'acf' ), + 'not_found_in_trash' => __( 'No Field Groups found in Trash', 'acf' ), + ), + 'public' => false, + 'hierarchical' => true, + 'show_ui' => true, + 'show_in_menu' => false, + '_builtin' => false, + 'capability_type' => 'post', + 'capabilities' => array( + 'edit_post' => $cap, + 'delete_post' => $cap, + 'edit_posts' => $cap, + 'delete_posts' => $cap, + ), + 'supports' => array( 'title' ), + 'rewrite' => false, + 'query_var' => false, + ) + ); + + // Register the Field post type. + register_post_type( + 'acf-field', + array( + 'labels' => array( + 'name' => __( 'Fields', 'acf' ), + 'singular_name' => __( 'Field', 'acf' ), + 'add_new' => __( 'Add New', 'acf' ), + 'add_new_item' => __( 'Add New Field', 'acf' ), + 'edit_item' => __( 'Edit Field', 'acf' ), + 'new_item' => __( 'New Field', 'acf' ), + 'view_item' => __( 'View Field', 'acf' ), + 'search_items' => __( 'Search Fields', 'acf' ), + 'not_found' => __( 'No Fields found', 'acf' ), + 'not_found_in_trash' => __( 'No Fields found in Trash', 'acf' ), + ), + 'public' => false, + 'hierarchical' => true, + 'show_ui' => false, + 'show_in_menu' => false, + '_builtin' => false, + 'capability_type' => 'post', + 'capabilities' => array( + 'edit_post' => $cap, + 'delete_post' => $cap, + 'edit_posts' => $cap, + 'delete_posts' => $cap, + ), + 'supports' => array( 'title' ), + 'rewrite' => false, + 'query_var' => false, + ) + ); + } + + /** + * register_post_status + * + * Registers the ACF post statuses. + * + * @date 22/10/2015 + * @since 5.3.2 + * + * @param void + * @return void + */ + function register_post_status() { + + // Register the Disabled post status. + register_post_status( + 'acf-disabled', + array( + 'label' => _x( 'Disabled', 'post status', 'acf' ), + 'public' => true, + 'exclude_from_search' => false, + 'show_in_admin_all_list' => true, + 'show_in_admin_status_list' => true, + 'label_count' => _n_noop( 'Disabled (%s)', 'Disabled (%s)', 'acf' ), + ) + ); + } + + /** + * posts_where + * + * Filters the $where clause allowing for custom WP_Query args. + * + * @date 31/8/19 + * @since 5.8.1 + * + * @param string $where The WHERE clause. + * @return WP_Query $wp_query The query object. + */ + function posts_where( $where, $wp_query ) { + global $wpdb; + + // Add custom "acf_field_key" arg. + if ( $field_key = $wp_query->get( 'acf_field_key' ) ) { + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_name = %s", $field_key ); + } + + // Add custom "acf_field_name" arg. + if ( $field_name = $wp_query->get( 'acf_field_name' ) ) { + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_excerpt = %s", $field_name ); + } + + // Add custom "acf_group_key" arg. + if ( $group_key = $wp_query->get( 'acf_group_key' ) ) { + $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_name = %s", $group_key ); + } + + // Return. + return $where; + } + + /** + * define + * + * Defines a constant if doesnt already exist. + * + * @date 3/5/17 + * @since 5.5.13 + * + * @param string $name The constant name. + * @param mixed $value The constant value. + * @return void + */ + function define( $name, $value = true ) { + if ( ! defined( $name ) ) { + define( $name, $value ); + } + } + + /** + * has_setting + * + * Returns true if a setting exists for this name. + * + * @date 2/2/18 + * @since 5.6.5 + * + * @param string $name The setting name. + * @return boolean + */ + function has_setting( $name ) { + return isset( $this->settings[ $name ] ); + } + + /** + * get_setting + * + * Returns a setting or null if doesn't exist. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $name The setting name. + * @return mixed + */ + function get_setting( $name ) { + return isset( $this->settings[ $name ] ) ? $this->settings[ $name ] : null; + } + + /** + * update_setting + * + * Updates a setting for the given name and value. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $name The setting name. + * @param mixed $value The setting value. + * @return true + */ + function update_setting( $name, $value ) { + $this->settings[ $name ] = $value; + return true; + } + + /** + * get_data + * + * Returns data or null if doesn't exist. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $name The data name. + * @return mixed + */ + function get_data( $name ) { + return isset( $this->data[ $name ] ) ? $this->data[ $name ] : null; + } + + /** + * set_data + * + * Sets data for the given name and value. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $name The data name. + * @param mixed $value The data value. + * @return void + */ + function set_data( $name, $value ) { + $this->data[ $name ] = $value; + } + + /** + * get_instance + * + * Returns an instance or null if doesn't exist. + * + * @date 13/2/18 + * @since 5.6.9 + * + * @param string $class The instance class name. + * @return object + */ + function get_instance( $class ) { + $name = strtolower( $class ); + return isset( $this->instances[ $name ] ) ? $this->instances[ $name ] : null; + } + + /** + * new_instance + * + * Creates and stores an instance of the given class. + * + * @date 13/2/18 + * @since 5.6.9 + * + * @param string $class The instance class name. + * @return object + */ + function new_instance( $class ) { + $instance = new $class(); + $name = strtolower( $class ); + $this->instances[ $name ] = $instance; + return $instance; + } + + /** + * Magic __isset method for backwards compatibility. + * + * @date 24/4/20 + * @since 5.9.0 + * + * @param string $key Key name. + * @return bool + */ + public function __isset( $key ) { + return in_array( $key, array( 'locations', 'json' ) ); + } + + /** + * Magic __get method for backwards compatibility. + * + * @date 24/4/20 + * @since 5.9.0 + * + * @param string $key Key name. + * @return mixed + */ + public function __get( $key ) { + switch ( $key ) { + case 'locations': + return acf_get_instance( 'ACF_Legacy_Locations' ); + case 'json': + return acf_get_instance( 'ACF_Local_JSON' ); + } + return null; + } + } + + /* + * acf + * + * The main function responsible for returning the one true acf Instance to functions everywhere. + * Use this function like you would a global variable, except without needing to declare the global. + * + * Example: + * + * @date 4/09/13 + * @since 4.3.0 + * + * @param void + * @return ACF + */ + function acf() { + global $acf; + + // Instantiate only once. + if ( ! isset( $acf ) ) { + $acf = new ACF(); + $acf->initialize(); + } + return $acf; + } + + // Instantiate. + acf(); endif; // class_exists check diff --git a/assets/build/css/acf-field-group.css b/assets/build/css/acf-field-group.css index d0afe76..7ba8696 100644 --- a/assets/build/css/acf-field-group.css +++ b/assets/build/css/acf-field-group.css @@ -255,7 +255,6 @@ } .rule-groups .rule-group { margin: 0 0 5px; - /* Don't allow user to delete the first field group */ } .rule-groups .rule-group h4 { margin: 0 0 3px; @@ -279,12 +278,13 @@ .rule-groups .rule-group tr:hover td.remove a { visibility: visible; } -.rule-groups .rule-group:first-child tr:first-child td.remove a { - visibility: hidden !important; -} .rule-groups .rule-group select:empty { background: #f8f8f8; } +.rule-groups:not(.rule-groups-multiple) .rule-group:first-child tr:first-child td.remove a { + /* Don't allow user to delete the only rule group */ + visibility: hidden !important; +} /*--------------------------------------------------------------------------------------------- * diff --git a/assets/build/css/acf-field-group.min.css b/assets/build/css/acf-field-group.min.css index 0484ca2..292cee4 100644 --- a/assets/build/css/acf-field-group.min.css +++ b/assets/build/css/acf-field-group.min.css @@ -1 +1 @@ -#acf-field-group-fields>.inside,#acf-field-group-locations>.inside,#acf-field-group-options>.inside{padding:0;margin:0}.postbox .handle-order-higher,.postbox .handle-order-lower{display:none}#minor-publishing-actions,#misc-publishing-actions #visibility,#misc-publishing-actions .edit-timestamp{display:none}#minor-publishing{border-bottom:0 none}#misc-pub-section{border-bottom:0 none}#misc-publishing-actions .misc-pub-section{border-bottom-color:#f5f5f5}#acf-field-group-fields{border:0 none;box-shadow:none}#acf-field-group-fields>.handlediv,#acf-field-group-fields>.hndle,#acf-field-group-fields>.postbox-header{display:none}#acf-field-group-fields a{text-decoration:none}#acf-field-group-fields a:active,#acf-field-group-fields a:focus{outline:0;box-shadow:none}#acf-field-group-fields .li-field-order{width:20%}#acf-field-group-fields .li-field-label{width:30%}#acf-field-group-fields .li-field-name{width:25%}#acf-field-group-fields .li-field-type{width:25%}#acf-field-group-fields .li-field-key{display:none}#acf-field-group-fields.show-field-keys .li-field-key,#acf-field-group-fields.show-field-keys .li-field-label,#acf-field-group-fields.show-field-keys .li-field-name,#acf-field-group-fields.show-field-keys .li-field-type{width:20%}#acf-field-group-fields.show-field-keys .li-field-key{display:block}#acf-field-group-fields .acf-field-list-wrap{border:#ccd0d4 solid 1px}#acf-field-group-fields .acf-field-list{background:#f5f5f5;margin-top:-1px}#acf-field-group-fields .acf-field-list .no-fields-message{padding:15px 15px;background:#fff;display:none}#acf-field-group-fields .acf-field-list.-empty .no-fields-message{display:block}.acf-admin-3-8 #acf-field-group-fields .acf-field-list-wrap{border-color:#dfdfdf}.acf-field-object{border-top:#eee solid 1px;background:#fff}.acf-field-object.ui-sortable-helper{border-top-color:#fff;box-shadow:0 0 0 1px #dfdfdf,0 1px 4px rgba(0,0,0,.1)}.acf-field-object.ui-sortable-placeholder{box-shadow:0 -1px 0 0 #dfdfdf;visibility:visible!important;background:#f9f9f9;border-top-color:transparent;min-height:54px}.acf-field-object.ui-sortable-placeholder:after,.acf-field-object.ui-sortable-placeholder:before{visibility:hidden}.acf-field-object>.meta{display:none}.acf-field-object>.handle a{-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.acf-field-object>.handle li{padding-top:10px;padding-bottom:10px;word-wrap:break-word}.acf-field-object>.handle .acf-icon{margin:1px 0 0;cursor:move;background:0 0;float:left;height:28px;line-height:26px;width:28px;font-size:13px;color:#444;position:relative;z-index:1}.acf-field-object>.handle strong{display:block;padding-bottom:6px;font-size:14px;line-height:14px;min-height:14px}.acf-field-object>.handle .row-options{visibility:hidden}.acf-field-object>.handle .row-options a{margin-right:4px}.acf-field-object>.handle .row-options a.delete-field{color:#a00}.acf-field-object>.handle .row-options a.delete-field:hover{color:red}.acf-field-object.open+.acf-field-object{border-top-color:#e1e1e1}.acf-field-object.open>.handle{background:#2a9bd9;border:#2696d3 solid 1px;text-shadow:#268fbb 0 1px 0;color:#fff;position:relative;margin:-1px -1px 0 -1px}.acf-field-object.open>.handle a{color:#fff!important}.acf-field-object.open>.handle a:hover{text-decoration:underline!important}.acf-field-object.open>.handle .acf-icon{border-color:#fff;color:#fff}.acf-field-object.open>.handle .acf-required{color:#fff}.acf-field-object.-hover>.handle .row-options,.acf-field-object:hover>.handle .row-options{visibility:visible}.acf-field-object>.settings{display:none;width:100%}.acf-field-object>.settings>.acf-table{border:none}.acf-field-object .rule-groups{margin-top:20px}.rule-groups h4{margin:3px 0}.rule-groups .rule-group{margin:0 0 5px}.rule-groups .rule-group h4{margin:0 0 3px}.rule-groups .rule-group td.param{width:35%}.rule-groups .rule-group td.operator{width:20%}.rule-groups .rule-group td.add{width:40px}.rule-groups .rule-group td.remove{width:28px;vertical-align:middle}.rule-groups .rule-group td.remove a{visibility:hidden}.rule-groups .rule-group tr:hover td.remove a{visibility:visible}.rule-groups .rule-group:first-child tr:first-child td.remove a{visibility:hidden!important}.rule-groups .rule-group select:empty{background:#f8f8f8}#acf-field-group-options tr[data-name=hide_on_screen] li{float:left;width:33%}@media (max-width:1100px){#acf-field-group-options tr[data-name=hide_on_screen] li{width:50%}}table.conditional-logic-rules{background:0 0;border:0 none;border-radius:0}table.conditional-logic-rules tbody td{background:0 0;border:0 none!important;padding:5px 2px!important}.acf-field-object-accordion .acf-field-setting-instructions,.acf-field-object-accordion .acf-field-setting-name,.acf-field-object-accordion .acf-field-setting-required,.acf-field-object-accordion .acf-field-setting-warning,.acf-field-object-accordion .acf-field-setting-wrapper,.acf-field-object-tab .acf-field-setting-instructions,.acf-field-object-tab .acf-field-setting-name,.acf-field-object-tab .acf-field-setting-required,.acf-field-object-tab .acf-field-setting-warning,.acf-field-object-tab .acf-field-setting-wrapper{display:none}.acf-field-object-accordion .li-field-name,.acf-field-object-tab .li-field-name{visibility:hidden}.acf-field-object+.acf-field-object-accordion:before,.acf-field-object+.acf-field-object-tab:before{display:block;content:"";height:5px;width:100%;background:#f5f5f5;border-top:#e1e1e1 solid 1px;border-bottom:#e1e1e1 solid 1px;margin-top:-1px}.acf-admin-3-8 .acf-field-object+.acf-field-object-accordion:before,.acf-admin-3-8 .acf-field-object+.acf-field-object-tab:before{border-color:#e5e5e5}.acf-field-object-accordion p:first-child,.acf-field-object-tab p:first-child{margin:.5em 0}.acf-field-object-accordion .acf-field-setting-instructions{display:table-row}.acf-field-object-message tr[data-name=instructions],.acf-field-object-message tr[data-name=name],.acf-field-object-message tr[data-name=required]{display:none!important}.acf-field-object-message .li-field-name{visibility:hidden}.acf-field-object-message textarea{height:175px!important}.acf-field-object-separator tr[data-name=instructions],.acf-field-object-separator tr[data-name=name],.acf-field-object-separator tr[data-name=required]{display:none!important}.acf-field-object-date-picker .acf-radio-list li,.acf-field-object-date-time-picker .acf-radio-list li,.acf-field-object-time-picker .acf-radio-list li{line-height:25px}.acf-field-object-date-picker .acf-radio-list span,.acf-field-object-date-time-picker .acf-radio-list span,.acf-field-object-time-picker .acf-radio-list span{display:inline-block;min-width:10em}.acf-field-object-date-picker .acf-radio-list input[type=text],.acf-field-object-date-time-picker .acf-radio-list input[type=text],.acf-field-object-time-picker .acf-radio-list input[type=text]{width:100px}.acf-field-object-date-time-picker .acf-radio-list span{min-width:15em}.acf-field-object-date-time-picker .acf-radio-list input[type=text]{width:200px}#slugdiv .inside{padding:12px;margin:0}#slugdiv input[type=text]{width:100%;height:28px;font-size:14px}html[dir=rtl] .acf-field-object.open>.handle{margin:-1px -1px 0}html[dir=rtl] .acf-field-object.open>.handle .acf-icon{float:right}html[dir=rtl] .acf-field-object.open>.handle .li-field-order{padding-left:0!important;padding-right:15px!important}@media only screen and (max-width:850px){td.acf-input,td.acf-label,tr.acf-field{display:block!important;width:auto!important;border:0 none!important}tr.acf-field{border-top:#ededed solid 1px!important;margin-bottom:0!important}td.acf-label{background:0 0!important;padding-bottom:0!important}} \ No newline at end of file +#acf-field-group-fields>.inside,#acf-field-group-locations>.inside,#acf-field-group-options>.inside{padding:0;margin:0}.postbox .handle-order-higher,.postbox .handle-order-lower{display:none}#minor-publishing-actions,#misc-publishing-actions #visibility,#misc-publishing-actions .edit-timestamp{display:none}#minor-publishing{border-bottom:0 none}#misc-pub-section{border-bottom:0 none}#misc-publishing-actions .misc-pub-section{border-bottom-color:#f5f5f5}#acf-field-group-fields{border:0 none;box-shadow:none}#acf-field-group-fields>.handlediv,#acf-field-group-fields>.hndle,#acf-field-group-fields>.postbox-header{display:none}#acf-field-group-fields a{text-decoration:none}#acf-field-group-fields a:active,#acf-field-group-fields a:focus{outline:0;box-shadow:none}#acf-field-group-fields .li-field-order{width:20%}#acf-field-group-fields .li-field-label{width:30%}#acf-field-group-fields .li-field-name{width:25%}#acf-field-group-fields .li-field-type{width:25%}#acf-field-group-fields .li-field-key{display:none}#acf-field-group-fields.show-field-keys .li-field-key,#acf-field-group-fields.show-field-keys .li-field-label,#acf-field-group-fields.show-field-keys .li-field-name,#acf-field-group-fields.show-field-keys .li-field-type{width:20%}#acf-field-group-fields.show-field-keys .li-field-key{display:block}#acf-field-group-fields .acf-field-list-wrap{border:#ccd0d4 solid 1px}#acf-field-group-fields .acf-field-list{background:#f5f5f5;margin-top:-1px}#acf-field-group-fields .acf-field-list .no-fields-message{padding:15px 15px;background:#fff;display:none}#acf-field-group-fields .acf-field-list.-empty .no-fields-message{display:block}.acf-admin-3-8 #acf-field-group-fields .acf-field-list-wrap{border-color:#dfdfdf}.acf-field-object{border-top:#eee solid 1px;background:#fff}.acf-field-object.ui-sortable-helper{border-top-color:#fff;box-shadow:0 0 0 1px #dfdfdf,0 1px 4px rgba(0,0,0,.1)}.acf-field-object.ui-sortable-placeholder{box-shadow:0 -1px 0 0 #dfdfdf;visibility:visible!important;background:#f9f9f9;border-top-color:transparent;min-height:54px}.acf-field-object.ui-sortable-placeholder:after,.acf-field-object.ui-sortable-placeholder:before{visibility:hidden}.acf-field-object>.meta{display:none}.acf-field-object>.handle a{-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.acf-field-object>.handle li{padding-top:10px;padding-bottom:10px;word-wrap:break-word}.acf-field-object>.handle .acf-icon{margin:1px 0 0;cursor:move;background:0 0;float:left;height:28px;line-height:26px;width:28px;font-size:13px;color:#444;position:relative;z-index:1}.acf-field-object>.handle strong{display:block;padding-bottom:6px;font-size:14px;line-height:14px;min-height:14px}.acf-field-object>.handle .row-options{visibility:hidden}.acf-field-object>.handle .row-options a{margin-right:4px}.acf-field-object>.handle .row-options a.delete-field{color:#a00}.acf-field-object>.handle .row-options a.delete-field:hover{color:red}.acf-field-object.open+.acf-field-object{border-top-color:#e1e1e1}.acf-field-object.open>.handle{background:#2a9bd9;border:#2696d3 solid 1px;text-shadow:#268fbb 0 1px 0;color:#fff;position:relative;margin:-1px -1px 0 -1px}.acf-field-object.open>.handle a{color:#fff!important}.acf-field-object.open>.handle a:hover{text-decoration:underline!important}.acf-field-object.open>.handle .acf-icon{border-color:#fff;color:#fff}.acf-field-object.open>.handle .acf-required{color:#fff}.acf-field-object.-hover>.handle .row-options,.acf-field-object:hover>.handle .row-options{visibility:visible}.acf-field-object>.settings{display:none;width:100%}.acf-field-object>.settings>.acf-table{border:none}.acf-field-object .rule-groups{margin-top:20px}.rule-groups h4{margin:3px 0}.rule-groups .rule-group{margin:0 0 5px}.rule-groups .rule-group h4{margin:0 0 3px}.rule-groups .rule-group td.param{width:35%}.rule-groups .rule-group td.operator{width:20%}.rule-groups .rule-group td.add{width:40px}.rule-groups .rule-group td.remove{width:28px;vertical-align:middle}.rule-groups .rule-group td.remove a{visibility:hidden}.rule-groups .rule-group tr:hover td.remove a{visibility:visible}.rule-groups .rule-group select:empty{background:#f8f8f8}.rule-groups:not(.rule-groups-multiple) .rule-group:first-child tr:first-child td.remove a{visibility:hidden!important}#acf-field-group-options tr[data-name=hide_on_screen] li{float:left;width:33%}@media (max-width:1100px){#acf-field-group-options tr[data-name=hide_on_screen] li{width:50%}}table.conditional-logic-rules{background:0 0;border:0 none;border-radius:0}table.conditional-logic-rules tbody td{background:0 0;border:0 none!important;padding:5px 2px!important}.acf-field-object-accordion .acf-field-setting-instructions,.acf-field-object-accordion .acf-field-setting-name,.acf-field-object-accordion .acf-field-setting-required,.acf-field-object-accordion .acf-field-setting-warning,.acf-field-object-accordion .acf-field-setting-wrapper,.acf-field-object-tab .acf-field-setting-instructions,.acf-field-object-tab .acf-field-setting-name,.acf-field-object-tab .acf-field-setting-required,.acf-field-object-tab .acf-field-setting-warning,.acf-field-object-tab .acf-field-setting-wrapper{display:none}.acf-field-object-accordion .li-field-name,.acf-field-object-tab .li-field-name{visibility:hidden}.acf-field-object+.acf-field-object-accordion:before,.acf-field-object+.acf-field-object-tab:before{display:block;content:"";height:5px;width:100%;background:#f5f5f5;border-top:#e1e1e1 solid 1px;border-bottom:#e1e1e1 solid 1px;margin-top:-1px}.acf-admin-3-8 .acf-field-object+.acf-field-object-accordion:before,.acf-admin-3-8 .acf-field-object+.acf-field-object-tab:before{border-color:#e5e5e5}.acf-field-object-accordion p:first-child,.acf-field-object-tab p:first-child{margin:.5em 0}.acf-field-object-accordion .acf-field-setting-instructions{display:table-row}.acf-field-object-message tr[data-name=instructions],.acf-field-object-message tr[data-name=name],.acf-field-object-message tr[data-name=required]{display:none!important}.acf-field-object-message .li-field-name{visibility:hidden}.acf-field-object-message textarea{height:175px!important}.acf-field-object-separator tr[data-name=instructions],.acf-field-object-separator tr[data-name=name],.acf-field-object-separator tr[data-name=required]{display:none!important}.acf-field-object-date-picker .acf-radio-list li,.acf-field-object-date-time-picker .acf-radio-list li,.acf-field-object-time-picker .acf-radio-list li{line-height:25px}.acf-field-object-date-picker .acf-radio-list span,.acf-field-object-date-time-picker .acf-radio-list span,.acf-field-object-time-picker .acf-radio-list span{display:inline-block;min-width:10em}.acf-field-object-date-picker .acf-radio-list input[type=text],.acf-field-object-date-time-picker .acf-radio-list input[type=text],.acf-field-object-time-picker .acf-radio-list input[type=text]{width:100px}.acf-field-object-date-time-picker .acf-radio-list span{min-width:15em}.acf-field-object-date-time-picker .acf-radio-list input[type=text]{width:200px}#slugdiv .inside{padding:12px;margin:0}#slugdiv input[type=text]{width:100%;height:28px;font-size:14px}html[dir=rtl] .acf-field-object.open>.handle{margin:-1px -1px 0}html[dir=rtl] .acf-field-object.open>.handle .acf-icon{float:right}html[dir=rtl] .acf-field-object.open>.handle .li-field-order{padding-left:0!important;padding-right:15px!important}@media only screen and (max-width:850px){td.acf-input,td.acf-label,tr.acf-field{display:block!important;width:auto!important;border:0 none!important}tr.acf-field{border-top:#ededed solid 1px!important;margin-bottom:0!important}td.acf-label{background:0 0!important;padding-bottom:0!important}} \ No newline at end of file diff --git a/assets/build/js/acf-field-group.js b/assets/build/js/acf-field-group.js index 50c0de6..1b0c8c2 100644 --- a/assets/build/js/acf-field-group.js +++ b/assets/build/js/acf-field-group.js @@ -1266,6 +1266,36 @@ acf.registerFieldSetting( TimePickerDisplayFormatFieldSetting ); acf.registerFieldSetting( TimePickerReturnFormatFieldSetting ); + /** + * Color Picker Settings. + * + * @date 16/12/20 + * @since 5.9.4 + * + * @param type $var Description. Default. + * @return type Description. + */ + var ColorPickerReturnFormat = acf.FieldSetting.extend({ + type: 'color_picker', + name: 'enable_opacity', + render: function(){ + var $return_format_setting = this.fieldObject.$setting('return_format'); + var $default_value_setting = this.fieldObject.$setting('default_value'); + var $labelText = $return_format_setting.find('input[type="radio"][value="string"]').parent('label').contents().last(); + var $defaultPlaceholder = $default_value_setting.find('input[type="text"]'); + var l10n = acf.get('colorPickerL10n'); + + if( this.field.val() ) { + $labelText.replaceWith( l10n.rgba_string ); + $defaultPlaceholder.attr('placeholder', 'rgba(255,255,255,0.8)'); + } else { + $labelText.replaceWith( l10n.hex_string ); + $defaultPlaceholder.attr('placeholder', '#FFFFFF'); + } + } + }); + acf.registerFieldSetting( ColorPickerReturnFormat ); + })(jQuery); (function($, undefined){ @@ -2166,6 +2196,7 @@ initialize: function(){ this.$el = $('#acf-field-group-locations'); + this.updateGroupsClass(); }, onClickAddRule: function( e, $el ){ @@ -2186,6 +2217,7 @@ addRule: function( $tr ){ acf.duplicate( $tr ); + this.updateGroupsClass(); }, removeRule: function( $tr ){ @@ -2194,6 +2226,13 @@ } else { $tr.remove(); } + + // Update h4 + var $group = this.$('.rule-group:first'); + $group.find('h4').text( acf.__('Show this field group if') ); + + + this.updateGroupsClass(); }, changeRule: function( $rule ){ @@ -2238,7 +2277,24 @@ // remove all tr's except the first one $group2.find('tr').not(':first').remove(); - } + + // update the groups class + this.updateGroupsClass(); + }, + + updateGroupsClass: function () { + var $group = this.$(".rule-group:last"); + + var $ruleGroups = $group.closest(".rule-groups"); + + var rows_count = $ruleGroups.find(".acf-table tr").length; + + if (rows_count > 1) { + $ruleGroups.addClass("rule-groups-multiple"); + } else { + $ruleGroups.removeClass("rule-groups-multiple"); + } + }, }); })(jQuery); diff --git a/assets/build/js/acf-field-group.min.js b/assets/build/js/acf-field-group.min.js index 41a03a0..d38b9cc 100644 --- a/assets/build/js/acf-field-group.min.js +++ b/assets/build/js/acf-field-group.min.js @@ -1 +1 @@ -!function(n){new acf.Model({id:"fieldGroupManager",events:{"submit #post":"onSubmit",'click a[href="#"]':"onClick","click .submitdelete":"onClickTrash"},filters:{find_fields_args:"filterFindFieldArgs"},onSubmit:function(e,t){var i=n("#titlewrap #title");i.val()||(e.preventDefault(),acf.unlockForm(t),alert(acf.__("Field group title is required")),i.trigger("focus"))},onClick:function(e){e.preventDefault()},onClickTrash:function(e){confirm(acf.__("Move to trash. Are you sure?"))||e.preventDefault()},filterFindFieldArgs:function(e){return e.visible=!0,e}}),new acf.Model({id:"screenOptionsManager",wait:"prepare",events:{change:"onChange"},initialize:function(){var e=n("#adv-settings"),t=n("#acf-append-show-on-screen");e.find(".metabox-prefs").append(t.html()),e.find(".metabox-prefs br").remove(),t.remove(),this.$el=n("#acf-field-key-hide"),this.render()},isChecked:function(){return this.$el.prop("checked")},onChange:function(e,t){var i=this.isChecked()?1:0;acf.updateUserSetting("show_field_keys",i),this.render()},render:function(){this.isChecked()?n("#acf-field-group-fields").addClass("show-field-keys"):n("#acf-field-group-fields").removeClass("show-field-keys")}}),new acf.Model({actions:{new_field:"onNewField"},onNewField:function(e){var t,i;e.has("append")&&(i=e.get("append"),(t=e.$el.siblings('[data-name="'+i+'"]').first()).length&&((t=(i=t.children(".acf-input")).children("ul")).length||(i.wrapInner(''),t=i.children("ul")),i=e.$(".acf-input").html(),i=n("
  • "+i+"
  • "),t.append(i),t.attr("data-cols",t.children().length),e.remove()))}})}(jQuery),function(r){acf.FieldObject=acf.Model.extend({eventScope:".acf-field-object",events:{"click .edit-field":"onClickEdit","click .delete-field":"onClickDelete","click .duplicate-field":"duplicate","click .move-field":"move","change .field-type":"onChangeType","change .field-required":"onChangeRequired","blur .field-label":"onChangeLabel","blur .field-name":"onChangeName",change:"onChange",changed:"onChanged"},data:{id:0,key:"",type:""},setup:function(e){this.$el=e,this.inherit(e),this.prop("ID"),this.prop("parent"),this.prop("menu_order")},$input:function(e){return r("#"+this.getInputId()+"-"+e)},$meta:function(){return this.$(".meta:first")},$handle:function(){return this.$(".handle:first")},$settings:function(){return this.$(".settings:first")},$setting:function(e){return this.$(".acf-field-settings:first > .acf-field-setting-"+e)},getParent:function(){return acf.getFieldObjects({child:this.$el,limit:1}).pop()},getParents:function(){return acf.getFieldObjects({child:this.$el})},getFields:function(){return acf.getFieldObjects({parent:this.$el})},getInputName:function(){return"acf_fields["+this.get("id")+"]"},getInputId:function(){return"acf_fields-"+this.get("id")},newInput:function(e,t){var i=this.getInputId(),n=this.getInputName();e&&(i+="-"+e,n+="["+e+"]");t=r("").attr({id:i,name:n,value:t});return this.$("> .meta").append(t),t},getProp:function(e){if(this.has(e))return this.get(e);var t=this.$input(e),t=t.length?t.val():null;return this.set(e,t,!0),t},setProp:function(e,t){var i=this.$input(e);i.val();return i.length||(i=this.newInput(e,t)),null===t?i.remove():i.val(t),this.has(e)?this.set(e,t):this.set(e,t,!0),this},prop:function(e,t){return void 0!==t?this.setProp(e,t):this.getProp(e)},props:function(t){Object.keys(t).map(function(e){this.setProp(e,t[e])},this)},getLabel:function(){var e=this.prop("label");return e=""===e?acf.__("(no label)"):e},getName:function(){return this.prop("name")},getType:function(){return this.prop("type")},getTypeLabel:function(){var e=this.prop("type"),t=acf.get("fieldTypes");return t[e]?t[e].label:e},getKey:function(){return this.prop("key")},initialize:function(){this.addProFields()},addProFields:function(){var e;acf.data.fieldTypes.hasOwnProperty("clone")||((e=r(".field-type").not(".acf-free-field-type")).find('optgroup option[value="group"]').parent().append('"),e.find('optgroup option[value="image"]').parent().append('"),e.addClass("acf-free-field-type"))},render:function(){var e=this.$(".handle:first"),t=this.prop("menu_order"),i=this.getLabel(),n=this.prop("name"),a=this.getTypeLabel(),l=this.prop("key"),o=this.$input("required").prop("checked");e.find(".acf-icon").html(parseInt(t)+1),o&&(i+=' *'),e.find(".li-field-label strong a").html(i),e.find(".li-field-name").text(n),e.find(".li-field-type").text(a),e.find(".li-field-key").text(l),acf.doAction("render_field_object",this)},refresh:function(){acf.doAction("refresh_field_object",this)},isOpen:function(){return this.$el.hasClass("open")},onClickEdit:function(e){this.isOpen()?this.close():this.open()},open:function(){var e=this.$el.children(".settings");e.slideDown(),this.$el.addClass("open"),acf.doAction("open_field_object",this),this.trigger("openFieldObject"),acf.doAction("show",e)},close:function(){var e=this.$el.children(".settings");e.slideUp(),this.$el.removeClass("open"),acf.doAction("close_field_object",this),this.trigger("closeFieldObject"),acf.doAction("hide",e)},serialize:function(){return acf.serialize(this.$el,this.getInputName())},save:function(e){e=e||"settings","settings"!==this.getProp("save")&&(this.setProp("save",e),this.$el.attr("data-save",e),acf.doAction("save_field_object",this,e))},submit:function(){var e=this.getInputName(),t=this.get("save");this.isOpen()&&this.close(),"settings"==t||("meta"==t?this.$('> .settings [name^="'+e+'"]'):this.$('[name^="'+e+'"]')).remove(),acf.doAction("submit_field_object",this)},onChange:function(e,t){this.save(),acf.doAction("change_field_object",this)},onChanged:function(e,t,i,n){"save"!=i&&(-1<["menu_order","parent"].indexOf(i)?this.save("meta"):this.save(),-1<["menu_order","label","required","name","type","key"].indexOf(i)&&this.render(),acf.doAction("change_field_object_"+i,this,n))},onChangeLabel:function(e,t){t=t.val();this.set("label",t),""==this.prop("name")&&(t=acf.applyFilters("generate_field_object_name",acf.strSanitize(t),this),this.prop("name",t))},onChangeName:function(e,t){t=t.val();this.set("name",t),"field_"===t.substr(0,6)&&alert(acf.__('The string "field_" may not be used at the start of a field name'))},onChangeRequired:function(e,t){t=t.prop("checked")?1:0;this.set("required",t)},delete:function(e){e=acf.parseArgs(e,{animate:!0});var t,i=this.prop("ID");i&&(i=(t=r("#_acf_delete_fields")).val()+"|"+i,t.val(i)),acf.doAction("delete_field_object",this),e.animate?this.removeAnimate():this.remove()},onClickDelete:function(e,t){if(e.shiftKey)return this.delete();this.$el.addClass("-hover");acf.newTooltip({confirmRemove:!0,target:t,context:this,confirm:function(){this.delete()},cancel:function(){this.$el.removeClass("-hover")}})},removeAnimate:function(){var e=this,t=this.$el.parent(),i=acf.findFieldObjects({sibling:this.$el});acf.remove({target:this.$el,endHeight:i.length?0:50,complete:function(){e.remove(),acf.doAction("removed_field_object",e,t)}}),acf.doAction("remove_field_object",e,t)},duplicate:function(){var e=acf.uniqid("field_"),t=acf.duplicate({target:this.$el,search:this.get("id"),replace:e});t.attr("data-key",e);var i=acf.getFieldObject(t);this.isOpen()?this.close():i.open();var n=i.$setting("label input");setTimeout(function(){n.trigger("focus")},251);var a,l=i.prop("label"),o=i.prop("name"),c=o.split("_").pop(),t=acf.__("copy");acf.isNumeric(c)?(l=l.replace(c,a=+c+1),o=o.replace(c,a)):0===c.indexOf(t)?(a=+c.replace(t,""),l=l.replace(c,t+(a=a?a+1:2)),o=o.replace(c,t+a)):(l+=" ("+t+")",o+="_"+t),i.prop("ID",0),i.prop("label",l),i.prop("name",o),i.prop("key",e),acf.doAction("duplicate_field_object",this,i),acf.doAction("append_field_object",i)},wipe:function(){var e=this.get("id"),t=this.get("key"),i=acf.uniqid("field_");acf.rename({target:this.$el,search:e,replace:i}),this.set("id",i),this.set("prevId",e),this.set("prevKey",t),this.prop("key",i),this.prop("ID",0),this.$el.attr("data-key",i),this.$el.attr("data-id",i),acf.doAction("wipe_field_object",this)},move:function(){function t(e){return"settings"==e.get("save")}var i,n,a,l,o,c,d=t(this);d||acf.getFieldObjects({parent:this.$el}).map(function(e){d=t(e)||e.changed}),d?alert(acf.__("This field cannot be moved until its changes have been saved")):(i=this.prop("ID"),n=this,a=!1,l=function(e){a.loading(!1),a.content(e),a.on("submit","form",o)},o=function(e,t){e.preventDefault(),acf.startButtonLoading(a.$(".button"));e={action:"acf/field_group/move_field",field_id:i,field_group_id:a.$("select").val()};r.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"html",success:c})},c=function(e){a.content(e),n.removeAnimate()},function(){a=acf.newPopup({title:acf.__("Move Custom Field"),loading:!0,width:"300px"});var e={action:"acf/field_group/move_field",field_id:i};r.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"html",success:l})}())},onChangeType:function(e,t){this.changeTimeout&&clearTimeout(this.changeTimeout),this.changeTimeout=this.setTimeout(function(){this.changeType(t.val())},300)},changeType:function(e){var t=this.prop("type"),i=acf.strSlugify("acf-field-object-"+t),n=acf.strSlugify("acf-field-object-"+e);this.$el.removeClass(i).addClass(n),this.$el.attr("data-type",e),this.$el.data("type",e),this.has("xhr")&&this.get("xhr").abort();var a=this.$("> .settings > table > tbody"),n=a.children('[data-setting="'+t+'"]');if(this.set("settings-"+t,n),n.detach(),this.has("settings-"+e)){var l=this.get("settings-"+e);return this.$setting("conditional_logic").before(l),void this.set("type",e)}var o=r('
    ');this.$setting("conditional_logic").before(o);l={action:"acf/field_group/render_field_settings",field:this.serialize(),prefix:this.getInputName()},l=r.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(l),type:"post",dataType:"html",context:this,success:function(e){e&&(o.after(e),acf.doAction("append",a))},complete:function(){o.remove(),this.set("type",e)}});this.set("xhr",l)},updateParent:function(){var e=acf.get("post_id"),t=this.getParent();t&&(e=parseInt(t.prop("ID"))||t.prop("key")),this.prop("parent",e)}})}(jQuery),function(i){function n(e){return acf.strPascalCase(e||"")+"FieldSetting"}acf.registerFieldSetting=function(e){var t=e.prototype,t=n(t.type+" "+t.name);this.models[t]=e},acf.newFieldSetting=function(e){var t=e.get("setting")||"",i=e.get("name")||"",i=n(t+" "+i),i=acf.models[i]||null;return null!==i&&new i(e)},acf.getFieldSetting=function(e){return(e=e instanceof jQuery?acf.getField(e):e).setting};new acf.Model({actions:{new_field:"onNewField"},onNewField:function(e){e.setting=acf.newFieldSetting(e)}});acf.FieldSetting=acf.Model.extend({field:!1,type:"",name:"",wait:"ready",eventScope:".acf-field",events:{change:"render"},setup:function(e){var t=e.$el;this.$el=t,this.field=e,this.$fieldObject=t.closest(".acf-field-object"),this.fieldObject=acf.getFieldObject(this.$fieldObject),i.extend(this.data,e.data)},initialize:function(){this.render()},render:function(){}});var e=acf.FieldSetting.extend({type:"",name:"",render:function(){var e=this.$('input[type="radio"]:checked');"other"!=e.val()&&this.$('input[type="text"]').val(e.val())}}),t=e.extend({type:"date_picker",name:"display_format"}),a=e.extend({type:"date_picker",name:"return_format"});acf.registerFieldSetting(t),acf.registerFieldSetting(a);t=e.extend({type:"date_time_picker",name:"display_format"}),a=e.extend({type:"date_time_picker",name:"return_format"});acf.registerFieldSetting(t),acf.registerFieldSetting(a);a=e.extend({type:"time_picker",name:"display_format"}),e=e.extend({name:"return_format"});acf.registerFieldSetting(a),acf.registerFieldSetting(e)}(jQuery),function(l){var e=acf.FieldSetting.extend({type:"",name:"conditional_logic",events:{"change .conditions-toggle":"onChangeToggle","click .add-conditional-group":"onClickAddGroup","focus .condition-rule-field":"onFocusField","change .condition-rule-field":"onChangeField","change .condition-rule-operator":"onChangeOperator","click .add-conditional-rule":"onClickAdd","click .remove-conditional-rule":"onClickRemove"},$rule:!1,scope:function(e){return this.$rule=e,this},ruleData:function(e,t){return this.$rule.data.apply(this.$rule,arguments)},$input:function(e){return this.$rule.find(".condition-rule-"+e)},$td:function(e){return this.$rule.find("td."+e)},$toggle:function(){return this.$(".conditions-toggle")},$control:function(){return this.$(".rule-groups")},$groups:function(){return this.$(".rule-group")},$rules:function(){return this.$(".rule")},open:function(){var e=this.$control();e.show(),acf.enable(e)},close:function(){var e=this.$control();e.hide(),acf.disable(e)},render:function(){this.$toggle().prop("checked")?(this.renderRules(),this.open()):this.close()},renderRules:function(){var e=this;this.$rules().each(function(){e.renderRule(l(this))})},renderRule:function(e){this.scope(e),this.renderField(),this.renderOperator(),this.renderValue()},renderField:function(){var i=[],n=this.fieldObject.cid,e=this.$input("field");acf.getFieldObjects().map(function(e){var t={id:e.getKey(),text:e.getLabel()};e.cid===n&&(t.text+=acf.__("(this field)"),t.disabled=!0),acf.getConditionTypes({fieldType:e.getType()}).length||(t.disabled=!0);e=e.getParents().length;t.text="- ".repeat(e)+t.text,i.push(t)}),i.length||i.push({id:"",text:acf.__("No toggle fields available")}),acf.renderSelect(e,i),this.ruleData("field",e.val())},renderOperator:function(){var e,t,i;this.ruleData("field")&&((e=this.$input("operator")).val(),t=[],null===e.val()&&acf.renderSelect(e,[{id:this.ruleData("operator"),text:""}]),i=acf.findFieldObject(this.ruleData("field")),i=acf.getFieldObject(i),acf.getConditionTypes({fieldType:i.getType()}).map(function(e){t.push({id:e.prototype.operator,text:e.prototype.label})}),acf.renderSelect(e,t),this.ruleData("operator",e.val()))},renderValue:function(){var t,e,i,n,a;this.ruleData("field")&&this.ruleData("operator")&&(t=this.$input("value"),e=this.$td("value"),i=t.val(),n=acf.findFieldObject(this.ruleData("field")),n=acf.getFieldObject(n),(n=acf.getConditionTypes({fieldType:n.getType(),operator:this.ruleData("operator")})[0].prototype.choices(n))instanceof Array?(a=l(""),acf.renderSelect(a,n)):a=l(n),t.detach(),e.html(a),setTimeout(function(){["class","name","id"].map(function(e){a.attr(e,t.attr(e))})},0),a.prop("disabled")||acf.val(a,i,!0),this.ruleData("value",a.val()))},onChangeToggle:function(){this.render()},onClickAddGroup:function(e,t){this.addGroup()},addGroup:function(){var e=this.$(".rule-group:last"),e=acf.duplicate(e);e.find("h4").text(acf.__("or")),e.find("tr").not(":first").remove(),this.fieldObject.save()},onFocusField:function(e,t){this.renderField()},onChangeField:function(e,t){this.scope(t.closest(".rule")),this.ruleData("field",t.val()),this.renderOperator(),this.renderValue()},onChangeOperator:function(e,t){this.scope(t.closest(".rule")),this.ruleData("operator",t.val()),this.renderValue()},onClickAdd:function(e,t){t=acf.duplicate(t.closest(".rule"));this.renderRule(t)},onClickRemove:function(e,t){t=t.closest(".rule");this.fieldObject.save(),0==t.siblings(".rule").length&&t.closest(".rule-group").remove(),t.remove()}});acf.registerFieldSetting(e);new acf.Model({actions:{duplicate_field_objects:"onDuplicateFieldObjects"},onDuplicateFieldObjects:function(e,t,i){var n={},a=l();e.map(function(e){n[e.get("prevKey")]=e.get("key"),a=a.add(e.$(".condition-rule-field"))}),a.each(function(){var e=l(this),t=e.val();t&&n[t]&&(e.find("option:selected").attr("value",n[t]),e.val(n[t]))})}})}(jQuery),function(l){acf.findFieldObject=function(e){return acf.findFieldObjects({key:e,limit:1})},acf.findFieldObjects=function(e){e=e||{};var t=".acf-field-object",i=!1;return(e=acf.parseArgs(e,{id:"",key:"",type:"",limit:!1,list:null,parent:!1,sibling:!1,child:!1})).id&&(t+='[data-id="'+e.id+'"]'),e.key&&(t+='[data-key="'+e.key+'"]'),e.type&&(t+='[data-type="'+e.type+'"]'),i=e.list?e.list.children(t):e.parent?e.parent.find(t):e.sibling?e.sibling.siblings(t):e.child?e.child.parents(t):l(t),i=e.limit?i.slice(0,e.limit):i},acf.getFieldObject=function(e){return(e="string"==typeof e?acf.findFieldObject(e):e).data("acf")||acf.newFieldObject(e)},acf.getFieldObjects=function(e){var e=acf.findFieldObjects(e),t=[];return e.each(function(){var e=acf.getFieldObject(l(this));t.push(e)}),t},acf.newFieldObject=function(e){e=new acf.FieldObject(e);return acf.doAction("new_field_object",e),e};new acf.Model({priority:5,initialize:function(){["prepare","ready","append","remove"].map(function(e){this.addFieldActions(e)},this)},addFieldActions:function(e){var n=e+"_field_objects",a=e+"_field_object",l=e+"FieldObject";acf.addAction(e,function(e){var t,i=acf.getFieldObjects({parent:e});i.length&&((t=acf.arrayArgs(arguments)).splice(0,1,n,i),acf.doAction.apply(null,t))},5),acf.addAction(n,function(e){var t=acf.arrayArgs(arguments);t.unshift(a),e.map(function(e){t[1]=e,acf.doAction.apply(null,t)})},5),acf.addAction(a,function(t){var i=acf.arrayArgs(arguments);i.unshift(a);["type","name","key"].map(function(e){i[0]=a+"/"+e+"="+t.get(e),acf.doAction.apply(null,i)}),i.splice(0,2),t.trigger(l,i)},5)}}),new acf.Model({id:"fieldManager",events:{"submit #post":"onSubmit","mouseenter .acf-field-list":"onHoverSortable","click .add-field":"onClickAdd"},actions:{removed_field_object:"onRemovedField",sortstop_field_object:"onReorderField",delete_field_object:"onDeleteField",change_field_object_type:"onChangeFieldType",duplicate_field_object:"onDuplicateField"},onSubmit:function(e,t){acf.getFieldObjects().map(function(e){e.submit()})},setFieldMenuOrder:function(e){this.renderFields(e.$el.parent())},onHoverSortable:function(e,n){n.hasClass("ui-sortable")||n.sortable({handle:".acf-sortable-handle",connectWith:".acf-field-list",start:function(e,t){var i=acf.getFieldObject(t.item);t.placeholder.height(t.item.height()),acf.doAction("sortstart_field_object",i,n)},update:function(e,t){t=acf.getFieldObject(t.item);acf.doAction("sortstop_field_object",t,n)}})},onRemovedField:function(e,t){this.renderFields(t)},onReorderField:function(e,t){e.updateParent(),this.renderFields(t)},onDeleteField:function(e){e.getFields().map(function(e){e.delete({animate:!1})})},onChangeFieldType:function(e){},onDuplicateField:function(e,t){var i=t.getFields();i.length&&(i.map(function(e){e.wipe(),e.updateParent()}),acf.doAction("duplicate_field_objects",i,t,e)),this.setFieldMenuOrder(t)},renderFields:function(e){var t=acf.getFieldObjects({list:e});t.length?(e.removeClass("-empty"),t.map(function(e,t){e.prop("menu_order",t)})):e.addClass("-empty")},onClickAdd:function(e,t){t=t.closest(".acf-tfoot").siblings(".acf-field-list");this.addField(t)},addField:function(i){var e=l("#tmpl-acf-field").html(),t=l(e),n=t.data("id"),e=acf.uniqid("field_"),t=acf.duplicate({target:t,search:n,replace:e,append:function(e,t){i.append(t)}}),n=acf.getFieldObject(t);n.prop("key",e),n.prop("ID",0),n.prop("label",""),n.prop("name",""),t.attr("data-key",e),t.attr("data-id",e),n.updateParent();var a=n.$input("label");setTimeout(function(){a.trigger("focus")},251),n.open(),this.renderFields(i),acf.doAction("add_field_object",n),acf.doAction("append_field_object",n)}})}(jQuery),function(a){new acf.Model({id:"locationManager",wait:"ready",events:{"click .add-location-rule":"onClickAddRule","click .add-location-group":"onClickAddGroup","click .remove-location-rule":"onClickRemoveRule","change .refresh-location-rule":"onChangeRemoveRule"},initialize:function(){this.$el=a("#acf-field-group-locations")},onClickAddRule:function(e,t){this.addRule(t.closest("tr"))},onClickRemoveRule:function(e,t){this.removeRule(t.closest("tr"))},onChangeRemoveRule:function(e,t){this.changeRule(t.closest("tr"))},onClickAddGroup:function(e,t){this.addGroup()},addRule:function(e){acf.duplicate(e)},removeRule:function(e){(0==e.siblings("tr").length?e.closest(".rule-group"):e).remove()},changeRule:function(t){var e=t.closest(".rule-group"),i=t.find("td.param select").attr("name").replace("[param]",""),n={action:"acf/field_group/render_location_rule"};n.rule=acf.serialize(t,i),n.rule.id=t.data("id"),n.rule.group=e.data("id"),acf.disable(t.find("td.value")),a.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(n),type:"post",dataType:"html",success:function(e){e&&t.replaceWith(e)}})},addGroup:function(){var e=this.$(".rule-group:last");$group2=acf.duplicate(e),$group2.find("h4").text(acf.__("or")),$group2.find("tr").not(":first").remove()}})}(jQuery),function(l){var e=acf.getCompatibility(acf);e.field_group={save_field:function(e,t){t=void 0!==t?t:"settings",acf.getFieldObject(e).save(t)},delete_field:function(e,t){t=void 0===t||t,acf.getFieldObject(e).delete({animate:t})},update_field_meta:function(e,t,i){acf.getFieldObject(e).prop(t,i)},delete_field_meta:function(e,t){acf.getFieldObject(e).prop(t,null)}},e.field_group.field_object=acf.model.extend({type:"",o:{},$field:null,$settings:null,tag:function(e){var t=this.type,i=e.split("_");return i.splice(1,0,"field"),e=i.join("_"),t&&(e+="/type="+t),e},selector:function(){var e=".acf-field-object",t=this.type;return t&&(e+="-"+t,e=acf.str_replace("_","-",e)),e},_add_action:function(e,t){var i=this;acf.add_action(this.tag(e),function(e){i.set("$field",e),i[t].apply(i,arguments)})},_add_filter:function(e,t){var i=this;acf.add_filter(this.tag(e),function(e){i.set("$field",e),i[t].apply(i,arguments)})},_add_event:function(e,t){var i=this,n=e.substr(0,e.indexOf(" ")),a=e.substr(e.indexOf(" ")+1),e=this.selector();l(document).on(n,e+" "+a,function(e){e.$el=l(this),e.$field=e.$el.closest(".acf-field-object"),i.set("$field",e.$field),i[t].apply(i,[e])})},_set_$field:function(){this.o=this.$field.data(),this.$settings=this.$field.find("> .settings > table > tbody"),this.focus()},focus:function(){},setting:function(e){return this.$settings.find("> .acf-field-setting-"+e)}});new acf.Model({actions:{open_field_object:"onOpenFieldObject",close_field_object:"onCloseFieldObject",add_field_object:"onAddFieldObject",duplicate_field_object:"onDuplicateFieldObject",delete_field_object:"onDeleteFieldObject",change_field_object_type:"onChangeFieldObjectType",change_field_object_label:"onChangeFieldObjectLabel",change_field_object_name:"onChangeFieldObjectName",change_field_object_parent:"onChangeFieldObjectParent",sortstop_field_object:"onChangeFieldObjectParent"},onOpenFieldObject:function(e){acf.doAction("open_field",e.$el),acf.doAction("open_field/type="+e.get("type"),e.$el),acf.doAction("render_field_settings",e.$el),acf.doAction("render_field_settings/type="+e.get("type"),e.$el)},onCloseFieldObject:function(e){acf.doAction("close_field",e.$el),acf.doAction("close_field/type="+e.get("type"),e.$el)},onAddFieldObject:function(e){acf.doAction("add_field",e.$el),acf.doAction("add_field/type="+e.get("type"),e.$el)},onDuplicateFieldObject:function(e){acf.doAction("duplicate_field",e.$el),acf.doAction("duplicate_field/type="+e.get("type"),e.$el)},onDeleteFieldObject:function(e){acf.doAction("delete_field",e.$el),acf.doAction("delete_field/type="+e.get("type"),e.$el)},onChangeFieldObjectType:function(e){acf.doAction("change_field_type",e.$el),acf.doAction("change_field_type/type="+e.get("type"),e.$el),acf.doAction("render_field_settings",e.$el),acf.doAction("render_field_settings/type="+e.get("type"),e.$el)},onChangeFieldObjectLabel:function(e){acf.doAction("change_field_label",e.$el),acf.doAction("change_field_label/type="+e.get("type"),e.$el)},onChangeFieldObjectName:function(e){acf.doAction("change_field_name",e.$el),acf.doAction("change_field_name/type="+e.get("type"),e.$el)},onChangeFieldObjectParent:function(e){acf.doAction("update_field_parent",e.$el)}})}(jQuery); \ No newline at end of file +!function(n){new acf.Model({id:"fieldGroupManager",events:{"submit #post":"onSubmit",'click a[href="#"]':"onClick","click .submitdelete":"onClickTrash"},filters:{find_fields_args:"filterFindFieldArgs"},onSubmit:function(e,t){var i=n("#titlewrap #title");i.val()||(e.preventDefault(),acf.unlockForm(t),alert(acf.__("Field group title is required")),i.trigger("focus"))},onClick:function(e){e.preventDefault()},onClickTrash:function(e){confirm(acf.__("Move to trash. Are you sure?"))||e.preventDefault()},filterFindFieldArgs:function(e){return e.visible=!0,e}}),new acf.Model({id:"screenOptionsManager",wait:"prepare",events:{change:"onChange"},initialize:function(){var e=n("#adv-settings"),t=n("#acf-append-show-on-screen");e.find(".metabox-prefs").append(t.html()),e.find(".metabox-prefs br").remove(),t.remove(),this.$el=n("#acf-field-key-hide"),this.render()},isChecked:function(){return this.$el.prop("checked")},onChange:function(e,t){var i=this.isChecked()?1:0;acf.updateUserSetting("show_field_keys",i),this.render()},render:function(){this.isChecked()?n("#acf-field-group-fields").addClass("show-field-keys"):n("#acf-field-group-fields").removeClass("show-field-keys")}}),new acf.Model({actions:{new_field:"onNewField"},onNewField:function(e){var t,i;e.has("append")&&(i=e.get("append"),(t=e.$el.siblings('[data-name="'+i+'"]').first()).length&&((t=(i=t.children(".acf-input")).children("ul")).length||(i.wrapInner(''),t=i.children("ul")),i=e.$(".acf-input").html(),i=n("
  • "+i+"
  • "),t.append(i),t.attr("data-cols",t.children().length),e.remove()))}})}(jQuery),function(r){acf.FieldObject=acf.Model.extend({eventScope:".acf-field-object",events:{"click .edit-field":"onClickEdit","click .delete-field":"onClickDelete","click .duplicate-field":"duplicate","click .move-field":"move","change .field-type":"onChangeType","change .field-required":"onChangeRequired","blur .field-label":"onChangeLabel","blur .field-name":"onChangeName",change:"onChange",changed:"onChanged"},data:{id:0,key:"",type:""},setup:function(e){this.$el=e,this.inherit(e),this.prop("ID"),this.prop("parent"),this.prop("menu_order")},$input:function(e){return r("#"+this.getInputId()+"-"+e)},$meta:function(){return this.$(".meta:first")},$handle:function(){return this.$(".handle:first")},$settings:function(){return this.$(".settings:first")},$setting:function(e){return this.$(".acf-field-settings:first > .acf-field-setting-"+e)},getParent:function(){return acf.getFieldObjects({child:this.$el,limit:1}).pop()},getParents:function(){return acf.getFieldObjects({child:this.$el})},getFields:function(){return acf.getFieldObjects({parent:this.$el})},getInputName:function(){return"acf_fields["+this.get("id")+"]"},getInputId:function(){return"acf_fields-"+this.get("id")},newInput:function(e,t){var i=this.getInputId(),n=this.getInputName();e&&(i+="-"+e,n+="["+e+"]");t=r("").attr({id:i,name:n,value:t});return this.$("> .meta").append(t),t},getProp:function(e){if(this.has(e))return this.get(e);var t=this.$input(e),t=t.length?t.val():null;return this.set(e,t,!0),t},setProp:function(e,t){var i=this.$input(e);i.val();return i.length||(i=this.newInput(e,t)),null===t?i.remove():i.val(t),this.has(e)?this.set(e,t):this.set(e,t,!0),this},prop:function(e,t){return void 0!==t?this.setProp(e,t):this.getProp(e)},props:function(t){Object.keys(t).map(function(e){this.setProp(e,t[e])},this)},getLabel:function(){var e=this.prop("label");return e=""===e?acf.__("(no label)"):e},getName:function(){return this.prop("name")},getType:function(){return this.prop("type")},getTypeLabel:function(){var e=this.prop("type"),t=acf.get("fieldTypes");return t[e]?t[e].label:e},getKey:function(){return this.prop("key")},initialize:function(){this.addProFields()},addProFields:function(){var e;acf.data.fieldTypes.hasOwnProperty("clone")||((e=r(".field-type").not(".acf-free-field-type")).find('optgroup option[value="group"]').parent().append('"),e.find('optgroup option[value="image"]').parent().append('"),e.addClass("acf-free-field-type"))},render:function(){var e=this.$(".handle:first"),t=this.prop("menu_order"),i=this.getLabel(),n=this.prop("name"),a=this.getTypeLabel(),l=this.prop("key"),o=this.$input("required").prop("checked");e.find(".acf-icon").html(parseInt(t)+1),o&&(i+=' *'),e.find(".li-field-label strong a").html(i),e.find(".li-field-name").text(n),e.find(".li-field-type").text(a),e.find(".li-field-key").text(l),acf.doAction("render_field_object",this)},refresh:function(){acf.doAction("refresh_field_object",this)},isOpen:function(){return this.$el.hasClass("open")},onClickEdit:function(e){this.isOpen()?this.close():this.open()},open:function(){var e=this.$el.children(".settings");e.slideDown(),this.$el.addClass("open"),acf.doAction("open_field_object",this),this.trigger("openFieldObject"),acf.doAction("show",e)},close:function(){var e=this.$el.children(".settings");e.slideUp(),this.$el.removeClass("open"),acf.doAction("close_field_object",this),this.trigger("closeFieldObject"),acf.doAction("hide",e)},serialize:function(){return acf.serialize(this.$el,this.getInputName())},save:function(e){e=e||"settings","settings"!==this.getProp("save")&&(this.setProp("save",e),this.$el.attr("data-save",e),acf.doAction("save_field_object",this,e))},submit:function(){var e=this.getInputName(),t=this.get("save");this.isOpen()&&this.close(),"settings"==t||("meta"==t?this.$('> .settings [name^="'+e+'"]'):this.$('[name^="'+e+'"]')).remove(),acf.doAction("submit_field_object",this)},onChange:function(e,t){this.save(),acf.doAction("change_field_object",this)},onChanged:function(e,t,i,n){"save"!=i&&(-1<["menu_order","parent"].indexOf(i)?this.save("meta"):this.save(),-1<["menu_order","label","required","name","type","key"].indexOf(i)&&this.render(),acf.doAction("change_field_object_"+i,this,n))},onChangeLabel:function(e,t){t=t.val();this.set("label",t),""==this.prop("name")&&(t=acf.applyFilters("generate_field_object_name",acf.strSanitize(t),this),this.prop("name",t))},onChangeName:function(e,t){t=t.val();this.set("name",t),"field_"===t.substr(0,6)&&alert(acf.__('The string "field_" may not be used at the start of a field name'))},onChangeRequired:function(e,t){t=t.prop("checked")?1:0;this.set("required",t)},delete:function(e){e=acf.parseArgs(e,{animate:!0});var t,i=this.prop("ID");i&&(i=(t=r("#_acf_delete_fields")).val()+"|"+i,t.val(i)),acf.doAction("delete_field_object",this),e.animate?this.removeAnimate():this.remove()},onClickDelete:function(e,t){if(e.shiftKey)return this.delete();this.$el.addClass("-hover");acf.newTooltip({confirmRemove:!0,target:t,context:this,confirm:function(){this.delete()},cancel:function(){this.$el.removeClass("-hover")}})},removeAnimate:function(){var e=this,t=this.$el.parent(),i=acf.findFieldObjects({sibling:this.$el});acf.remove({target:this.$el,endHeight:i.length?0:50,complete:function(){e.remove(),acf.doAction("removed_field_object",e,t)}}),acf.doAction("remove_field_object",e,t)},duplicate:function(){var e=acf.uniqid("field_"),t=acf.duplicate({target:this.$el,search:this.get("id"),replace:e});t.attr("data-key",e);var i=acf.getFieldObject(t);this.isOpen()?this.close():i.open();var n=i.$setting("label input");setTimeout(function(){n.trigger("focus")},251);var a,l=i.prop("label"),o=i.prop("name"),c=o.split("_").pop(),t=acf.__("copy");acf.isNumeric(c)?(l=l.replace(c,a=+c+1),o=o.replace(c,a)):0===c.indexOf(t)?(a=+c.replace(t,""),l=l.replace(c,t+(a=a?a+1:2)),o=o.replace(c,t+a)):(l+=" ("+t+")",o+="_"+t),i.prop("ID",0),i.prop("label",l),i.prop("name",o),i.prop("key",e),acf.doAction("duplicate_field_object",this,i),acf.doAction("append_field_object",i)},wipe:function(){var e=this.get("id"),t=this.get("key"),i=acf.uniqid("field_");acf.rename({target:this.$el,search:e,replace:i}),this.set("id",i),this.set("prevId",e),this.set("prevKey",t),this.prop("key",i),this.prop("ID",0),this.$el.attr("data-key",i),this.$el.attr("data-id",i),acf.doAction("wipe_field_object",this)},move:function(){function t(e){return"settings"==e.get("save")}var i,n,a,l,o,c,d=t(this);d||acf.getFieldObjects({parent:this.$el}).map(function(e){d=t(e)||e.changed}),d?alert(acf.__("This field cannot be moved until its changes have been saved")):(i=this.prop("ID"),n=this,a=!1,l=function(e){a.loading(!1),a.content(e),a.on("submit","form",o)},o=function(e,t){e.preventDefault(),acf.startButtonLoading(a.$(".button"));e={action:"acf/field_group/move_field",field_id:i,field_group_id:a.$("select").val()};r.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"html",success:c})},c=function(e){a.content(e),n.removeAnimate()},function(){a=acf.newPopup({title:acf.__("Move Custom Field"),loading:!0,width:"300px"});var e={action:"acf/field_group/move_field",field_id:i};r.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"html",success:l})}())},onChangeType:function(e,t){this.changeTimeout&&clearTimeout(this.changeTimeout),this.changeTimeout=this.setTimeout(function(){this.changeType(t.val())},300)},changeType:function(e){var t=this.prop("type"),i=acf.strSlugify("acf-field-object-"+t),n=acf.strSlugify("acf-field-object-"+e);this.$el.removeClass(i).addClass(n),this.$el.attr("data-type",e),this.$el.data("type",e),this.has("xhr")&&this.get("xhr").abort();var a=this.$("> .settings > table > tbody"),n=a.children('[data-setting="'+t+'"]');if(this.set("settings-"+t,n),n.detach(),this.has("settings-"+e)){var l=this.get("settings-"+e);return this.$setting("conditional_logic").before(l),void this.set("type",e)}var o=r('
    ');this.$setting("conditional_logic").before(o);l={action:"acf/field_group/render_field_settings",field:this.serialize(),prefix:this.getInputName()},l=r.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(l),type:"post",dataType:"html",context:this,success:function(e){e&&(o.after(e),acf.doAction("append",a))},complete:function(){o.remove(),this.set("type",e)}});this.set("xhr",l)},updateParent:function(){var e=acf.get("post_id"),t=this.getParent();t&&(e=parseInt(t.prop("ID"))||t.prop("key")),this.prop("parent",e)}})}(jQuery),function(i){function n(e){return acf.strPascalCase(e||"")+"FieldSetting"}acf.registerFieldSetting=function(e){var t=e.prototype,t=n(t.type+" "+t.name);this.models[t]=e},acf.newFieldSetting=function(e){var t=e.get("setting")||"",i=e.get("name")||"",i=n(t+" "+i),i=acf.models[i]||null;return null!==i&&new i(e)},acf.getFieldSetting=function(e){return(e=e instanceof jQuery?acf.getField(e):e).setting};new acf.Model({actions:{new_field:"onNewField"},onNewField:function(e){e.setting=acf.newFieldSetting(e)}});acf.FieldSetting=acf.Model.extend({field:!1,type:"",name:"",wait:"ready",eventScope:".acf-field",events:{change:"render"},setup:function(e){var t=e.$el;this.$el=t,this.field=e,this.$fieldObject=t.closest(".acf-field-object"),this.fieldObject=acf.getFieldObject(this.$fieldObject),i.extend(this.data,e.data)},initialize:function(){this.render()},render:function(){}});var e=acf.FieldSetting.extend({type:"",name:"",render:function(){var e=this.$('input[type="radio"]:checked');"other"!=e.val()&&this.$('input[type="text"]').val(e.val())}}),t=e.extend({type:"date_picker",name:"display_format"}),a=e.extend({type:"date_picker",name:"return_format"});acf.registerFieldSetting(t),acf.registerFieldSetting(a);t=e.extend({type:"date_time_picker",name:"display_format"}),a=e.extend({type:"date_time_picker",name:"return_format"});acf.registerFieldSetting(t),acf.registerFieldSetting(a);a=e.extend({type:"time_picker",name:"display_format"}),e=e.extend({name:"return_format"});acf.registerFieldSetting(a),acf.registerFieldSetting(e);e=acf.FieldSetting.extend({type:"color_picker",name:"enable_opacity",render:function(){var e=this.fieldObject.$setting("return_format"),t=this.fieldObject.$setting("default_value"),i=e.find('input[type="radio"][value="string"]').parent("label").contents().last(),e=t.find('input[type="text"]'),t=acf.get("colorPickerL10n");this.field.val()?(i.replaceWith(t.rgba_string),e.attr("placeholder","rgba(255,255,255,0.8)")):(i.replaceWith(t.hex_string),e.attr("placeholder","#FFFFFF"))}});acf.registerFieldSetting(e)}(jQuery),function(l){var e=acf.FieldSetting.extend({type:"",name:"conditional_logic",events:{"change .conditions-toggle":"onChangeToggle","click .add-conditional-group":"onClickAddGroup","focus .condition-rule-field":"onFocusField","change .condition-rule-field":"onChangeField","change .condition-rule-operator":"onChangeOperator","click .add-conditional-rule":"onClickAdd","click .remove-conditional-rule":"onClickRemove"},$rule:!1,scope:function(e){return this.$rule=e,this},ruleData:function(e,t){return this.$rule.data.apply(this.$rule,arguments)},$input:function(e){return this.$rule.find(".condition-rule-"+e)},$td:function(e){return this.$rule.find("td."+e)},$toggle:function(){return this.$(".conditions-toggle")},$control:function(){return this.$(".rule-groups")},$groups:function(){return this.$(".rule-group")},$rules:function(){return this.$(".rule")},open:function(){var e=this.$control();e.show(),acf.enable(e)},close:function(){var e=this.$control();e.hide(),acf.disable(e)},render:function(){this.$toggle().prop("checked")?(this.renderRules(),this.open()):this.close()},renderRules:function(){var e=this;this.$rules().each(function(){e.renderRule(l(this))})},renderRule:function(e){this.scope(e),this.renderField(),this.renderOperator(),this.renderValue()},renderField:function(){var i=[],n=this.fieldObject.cid,e=this.$input("field");acf.getFieldObjects().map(function(e){var t={id:e.getKey(),text:e.getLabel()};e.cid===n&&(t.text+=acf.__("(this field)"),t.disabled=!0),acf.getConditionTypes({fieldType:e.getType()}).length||(t.disabled=!0);e=e.getParents().length;t.text="- ".repeat(e)+t.text,i.push(t)}),i.length||i.push({id:"",text:acf.__("No toggle fields available")}),acf.renderSelect(e,i),this.ruleData("field",e.val())},renderOperator:function(){var e,t,i;this.ruleData("field")&&((e=this.$input("operator")).val(),t=[],null===e.val()&&acf.renderSelect(e,[{id:this.ruleData("operator"),text:""}]),i=acf.findFieldObject(this.ruleData("field")),i=acf.getFieldObject(i),acf.getConditionTypes({fieldType:i.getType()}).map(function(e){t.push({id:e.prototype.operator,text:e.prototype.label})}),acf.renderSelect(e,t),this.ruleData("operator",e.val()))},renderValue:function(){var t,e,i,n,a;this.ruleData("field")&&this.ruleData("operator")&&(t=this.$input("value"),e=this.$td("value"),i=t.val(),n=acf.findFieldObject(this.ruleData("field")),n=acf.getFieldObject(n),(n=acf.getConditionTypes({fieldType:n.getType(),operator:this.ruleData("operator")})[0].prototype.choices(n))instanceof Array?(a=l(""),acf.renderSelect(a,n)):a=l(n),t.detach(),e.html(a),setTimeout(function(){["class","name","id"].map(function(e){a.attr(e,t.attr(e))})},0),a.prop("disabled")||acf.val(a,i,!0),this.ruleData("value",a.val()))},onChangeToggle:function(){this.render()},onClickAddGroup:function(e,t){this.addGroup()},addGroup:function(){var e=this.$(".rule-group:last"),e=acf.duplicate(e);e.find("h4").text(acf.__("or")),e.find("tr").not(":first").remove(),this.fieldObject.save()},onFocusField:function(e,t){this.renderField()},onChangeField:function(e,t){this.scope(t.closest(".rule")),this.ruleData("field",t.val()),this.renderOperator(),this.renderValue()},onChangeOperator:function(e,t){this.scope(t.closest(".rule")),this.ruleData("operator",t.val()),this.renderValue()},onClickAdd:function(e,t){t=acf.duplicate(t.closest(".rule"));this.renderRule(t)},onClickRemove:function(e,t){t=t.closest(".rule");this.fieldObject.save(),0==t.siblings(".rule").length&&t.closest(".rule-group").remove(),t.remove()}});acf.registerFieldSetting(e);new acf.Model({actions:{duplicate_field_objects:"onDuplicateFieldObjects"},onDuplicateFieldObjects:function(e,t,i){var n={},a=l();e.map(function(e){n[e.get("prevKey")]=e.get("key"),a=a.add(e.$(".condition-rule-field"))}),a.each(function(){var e=l(this),t=e.val();t&&n[t]&&(e.find("option:selected").attr("value",n[t]),e.val(n[t]))})}})}(jQuery),function(l){acf.findFieldObject=function(e){return acf.findFieldObjects({key:e,limit:1})},acf.findFieldObjects=function(e){e=e||{};var t=".acf-field-object",i=!1;return(e=acf.parseArgs(e,{id:"",key:"",type:"",limit:!1,list:null,parent:!1,sibling:!1,child:!1})).id&&(t+='[data-id="'+e.id+'"]'),e.key&&(t+='[data-key="'+e.key+'"]'),e.type&&(t+='[data-type="'+e.type+'"]'),i=e.list?e.list.children(t):e.parent?e.parent.find(t):e.sibling?e.sibling.siblings(t):e.child?e.child.parents(t):l(t),i=e.limit?i.slice(0,e.limit):i},acf.getFieldObject=function(e){return(e="string"==typeof e?acf.findFieldObject(e):e).data("acf")||acf.newFieldObject(e)},acf.getFieldObjects=function(e){var e=acf.findFieldObjects(e),t=[];return e.each(function(){var e=acf.getFieldObject(l(this));t.push(e)}),t},acf.newFieldObject=function(e){e=new acf.FieldObject(e);return acf.doAction("new_field_object",e),e};new acf.Model({priority:5,initialize:function(){["prepare","ready","append","remove"].map(function(e){this.addFieldActions(e)},this)},addFieldActions:function(e){var n=e+"_field_objects",a=e+"_field_object",l=e+"FieldObject";acf.addAction(e,function(e){var t,i=acf.getFieldObjects({parent:e});i.length&&((t=acf.arrayArgs(arguments)).splice(0,1,n,i),acf.doAction.apply(null,t))},5),acf.addAction(n,function(e){var t=acf.arrayArgs(arguments);t.unshift(a),e.map(function(e){t[1]=e,acf.doAction.apply(null,t)})},5),acf.addAction(a,function(t){var i=acf.arrayArgs(arguments);i.unshift(a);["type","name","key"].map(function(e){i[0]=a+"/"+e+"="+t.get(e),acf.doAction.apply(null,i)}),i.splice(0,2),t.trigger(l,i)},5)}}),new acf.Model({id:"fieldManager",events:{"submit #post":"onSubmit","mouseenter .acf-field-list":"onHoverSortable","click .add-field":"onClickAdd"},actions:{removed_field_object:"onRemovedField",sortstop_field_object:"onReorderField",delete_field_object:"onDeleteField",change_field_object_type:"onChangeFieldType",duplicate_field_object:"onDuplicateField"},onSubmit:function(e,t){acf.getFieldObjects().map(function(e){e.submit()})},setFieldMenuOrder:function(e){this.renderFields(e.$el.parent())},onHoverSortable:function(e,n){n.hasClass("ui-sortable")||n.sortable({handle:".acf-sortable-handle",connectWith:".acf-field-list",start:function(e,t){var i=acf.getFieldObject(t.item);t.placeholder.height(t.item.height()),acf.doAction("sortstart_field_object",i,n)},update:function(e,t){t=acf.getFieldObject(t.item);acf.doAction("sortstop_field_object",t,n)}})},onRemovedField:function(e,t){this.renderFields(t)},onReorderField:function(e,t){e.updateParent(),this.renderFields(t)},onDeleteField:function(e){e.getFields().map(function(e){e.delete({animate:!1})})},onChangeFieldType:function(e){},onDuplicateField:function(e,t){var i=t.getFields();i.length&&(i.map(function(e){e.wipe(),e.updateParent()}),acf.doAction("duplicate_field_objects",i,t,e)),this.setFieldMenuOrder(t)},renderFields:function(e){var t=acf.getFieldObjects({list:e});t.length?(e.removeClass("-empty"),t.map(function(e,t){e.prop("menu_order",t)})):e.addClass("-empty")},onClickAdd:function(e,t){t=t.closest(".acf-tfoot").siblings(".acf-field-list");this.addField(t)},addField:function(i){var e=l("#tmpl-acf-field").html(),t=l(e),n=t.data("id"),e=acf.uniqid("field_"),t=acf.duplicate({target:t,search:n,replace:e,append:function(e,t){i.append(t)}}),n=acf.getFieldObject(t);n.prop("key",e),n.prop("ID",0),n.prop("label",""),n.prop("name",""),t.attr("data-key",e),t.attr("data-id",e),n.updateParent();var a=n.$input("label");setTimeout(function(){a.trigger("focus")},251),n.open(),this.renderFields(i),acf.doAction("add_field_object",n),acf.doAction("append_field_object",n)}})}(jQuery),function(a){new acf.Model({id:"locationManager",wait:"ready",events:{"click .add-location-rule":"onClickAddRule","click .add-location-group":"onClickAddGroup","click .remove-location-rule":"onClickRemoveRule","change .refresh-location-rule":"onChangeRemoveRule"},initialize:function(){this.$el=a("#acf-field-group-locations"),this.updateGroupsClass()},onClickAddRule:function(e,t){this.addRule(t.closest("tr"))},onClickRemoveRule:function(e,t){this.removeRule(t.closest("tr"))},onChangeRemoveRule:function(e,t){this.changeRule(t.closest("tr"))},onClickAddGroup:function(e,t){this.addGroup()},addRule:function(e){acf.duplicate(e),this.updateGroupsClass()},removeRule:function(e){(0==e.siblings("tr").length?e.closest(".rule-group"):e).remove(),this.$(".rule-group:first").find("h4").text(acf.__("Show this field group if")),this.updateGroupsClass()},changeRule:function(t){var e=t.closest(".rule-group"),i=t.find("td.param select").attr("name").replace("[param]",""),n={action:"acf/field_group/render_location_rule"};n.rule=acf.serialize(t,i),n.rule.id=t.data("id"),n.rule.group=e.data("id"),acf.disable(t.find("td.value")),a.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(n),type:"post",dataType:"html",success:function(e){e&&t.replaceWith(e)}})},addGroup:function(){var e=this.$(".rule-group:last");$group2=acf.duplicate(e),$group2.find("h4").text(acf.__("or")),$group2.find("tr").not(":first").remove(),this.updateGroupsClass()},updateGroupsClass:function(){var e=this.$(".rule-group:last").closest(".rule-groups");1 .settings > table > tbody"),this.focus()},focus:function(){},setting:function(e){return this.$settings.find("> .acf-field-setting-"+e)}});new acf.Model({actions:{open_field_object:"onOpenFieldObject",close_field_object:"onCloseFieldObject",add_field_object:"onAddFieldObject",duplicate_field_object:"onDuplicateFieldObject",delete_field_object:"onDeleteFieldObject",change_field_object_type:"onChangeFieldObjectType",change_field_object_label:"onChangeFieldObjectLabel",change_field_object_name:"onChangeFieldObjectName",change_field_object_parent:"onChangeFieldObjectParent",sortstop_field_object:"onChangeFieldObjectParent"},onOpenFieldObject:function(e){acf.doAction("open_field",e.$el),acf.doAction("open_field/type="+e.get("type"),e.$el),acf.doAction("render_field_settings",e.$el),acf.doAction("render_field_settings/type="+e.get("type"),e.$el)},onCloseFieldObject:function(e){acf.doAction("close_field",e.$el),acf.doAction("close_field/type="+e.get("type"),e.$el)},onAddFieldObject:function(e){acf.doAction("add_field",e.$el),acf.doAction("add_field/type="+e.get("type"),e.$el)},onDuplicateFieldObject:function(e){acf.doAction("duplicate_field",e.$el),acf.doAction("duplicate_field/type="+e.get("type"),e.$el)},onDeleteFieldObject:function(e){acf.doAction("delete_field",e.$el),acf.doAction("delete_field/type="+e.get("type"),e.$el)},onChangeFieldObjectType:function(e){acf.doAction("change_field_type",e.$el),acf.doAction("change_field_type/type="+e.get("type"),e.$el),acf.doAction("render_field_settings",e.$el),acf.doAction("render_field_settings/type="+e.get("type"),e.$el)},onChangeFieldObjectLabel:function(e){acf.doAction("change_field_label",e.$el),acf.doAction("change_field_label/type="+e.get("type"),e.$el)},onChangeFieldObjectName:function(e){acf.doAction("change_field_name",e.$el),acf.doAction("change_field_name/type="+e.get("type"),e.$el)},onChangeFieldObjectParent:function(e){acf.doAction("update_field_parent",e.$el)}})}(jQuery); \ No newline at end of file diff --git a/assets/build/js/acf-input.js b/assets/build/js/acf-input.js index 37aec7b..2c763b6 100644 --- a/assets/build/js/acf-input.js +++ b/assets/build/js/acf-input.js @@ -7729,10 +7729,25 @@ placeholder: this.get('placeholder'), multiple: this.get('multiple'), data: [], - escapeMarkup: function( string ){ - return acf.escHtml( string ); - }, + escapeMarkup: function( markup ) { + if (typeof markup !== 'string') { + return markup; + } + return acf.escHtml( markup ); + } }; + + // Only use the template if SelectWoo is not loaded to work around https://github.com/woocommerce/woocommerce/pull/30473 + if ( ! acf.isset(window, 'jQuery', 'fn', 'selectWoo') ) { + + options.templateSelection = function( selection ) { + var $selection = $(''); + $selection.html( acf.escHtml( selection.text ) ); + $selection.data('element', selection.element); + return $selection; + }; + + } // multiple if( options.multiple ) { @@ -7788,8 +7803,12 @@ // loop $ul.find('.select2-selection__choice').each(function() { - // vars - var $option = $( $(this).data('data').element ); + // Attempt to use .data if it exists (select2 version < 4.0.6) or use our template data instead. + if ( $(this).data('data') ) { + var $option = $( $(this).data('data').element ); + } else { + var $option = $( $(this).children('span.acf-selection').data('element') ); + } // detach and re-append to end $option.detach().appendTo( $select ); @@ -9656,7 +9675,7 @@ var lastPostStatus = ''; wp.data.subscribe(function() { var postStatus = editorSelect.getEditedPostAttribute( 'status' ); - useValidation = ( postStatus === 'publish' ); + useValidation = ( postStatus === 'publish' || postStatus === 'future' ); lastPostStatus = ( postStatus !== 'publish' ) ? postStatus : lastPostStatus; }); @@ -9676,7 +9695,7 @@ return resolve( 'Validation ignored (autosave).' ); } - // Bail early if validation is not neeed. + // Bail early if validation is not needed. if( !useValidation ) { return resolve( 'Validation ignored (draft).' ); } @@ -9728,6 +9747,8 @@ } }).then(function(){ return savePost.apply(_this, _args); + }).catch(function(err){ + // Nothing to do here, user is alerted of validation issues. }); }; } diff --git a/assets/build/js/acf-input.min.js b/assets/build/js/acf-input.min.js index fd1d9f4..f7a16b1 100644 --- a/assets/build/js/acf-input.min.js +++ b/assets/build/js/acf-input.min.js @@ -1 +1 @@ -!function(e,i){var a=[];acf.Field=acf.Model.extend({type:"",eventScope:".acf-field",wait:"ready",setup:function(t){this.$el=t,this.inherit(t),this.inherit(this.$control())},val:function(t){return t!==i?this.setValue(t):this.prop("disabled")?null:this.getValue()},getValue:function(){return this.$input().val()},setValue:function(t){return acf.val(this.$input(),t)},__:function(t){return acf._e(this.type,t)},$control:function(){return!1},$input:function(){return this.$("[name]:first")},$inputWrap:function(){return this.$(".acf-input:first")},$labelWrap:function(){return this.$(".acf-label:first")},getInputName:function(){return this.$input().attr("name")||""},parent:function(){var t=this.parents();return!!t.length&&t[0]},parents:function(){var t=this.$el.parents(".acf-field");return acf.getFields(t)},show:function(t,e){t=acf.show(this.$el,t);return t&&(this.prop("hidden",!1),acf.doAction("show_field",this,e)),t},hide:function(t,e){t=acf.hide(this.$el,t);return t&&(this.prop("hidden",!0),acf.doAction("hide_field",this,e)),t},enable:function(t,e){t=acf.enable(this.$el,t);return t&&(this.prop("disabled",!1),acf.doAction("enable_field",this,e)),t},disable:function(t,e){t=acf.disable(this.$el,t);return t&&(this.prop("disabled",!0),acf.doAction("disable_field",this,e)),t},showEnable:function(t,e){return this.enable.apply(this,arguments),this.show.apply(this,arguments)},hideDisable:function(t,e){return this.disable.apply(this,arguments),this.hide.apply(this,arguments)},showNotice:function(t){"object"!=typeof t&&(t={text:t}),this.notice&&this.notice.remove(),t.target=this.$inputWrap(),this.notice=acf.newNotice(t)},removeNotice:function(t){this.notice&&(this.notice.away(t||0),this.notice=!1)},showError:function(t){this.$el.addClass("acf-error"),t!==i&&this.showNotice({text:t,type:"error",dismiss:!1}),acf.doAction("invalid_field",this),this.$el.one("focus change","input, select, textarea",e.proxy(this.removeError,this))},removeError:function(){this.$el.removeClass("acf-error"),this.removeNotice(250),acf.doAction("valid_field",this)},trigger:function(t,e,i){return"invalidField"==t&&(i=!0),acf.Model.prototype.trigger.apply(this,[t,e,i])}}),acf.newField=function(t){var e=t.data("type"),e=n(e),t=new(acf.models[e]||acf.Field)(t);return acf.doAction("new_field",t),t};var n=function(t){return acf.strPascalCase(t||"")+"Field"};acf.registerFieldType=function(t){var e=t.prototype.type,i=n(e);acf.models[i]=t,a.push(e)},acf.getFieldType=function(t){t=n(t);return acf.models[t]||!1},acf.getFieldTypes=function(i){i=acf.parseArgs(i,{category:""});var n=[];return a.map(function(t){var e=acf.getFieldType(t),t=e.prototype;i.category&&t.category!==i.category||n.push(e)}),n}}(jQuery),function(n){acf.findFields=function(t){var e=".acf-field",i=!1;return(t=!(t=acf.parseArgs(t,{key:"",name:"",type:"",is:"",parent:!1,sibling:!1,limit:!1,visible:!1,suppressFilters:!1})).suppressFilters?acf.applyFilters("find_fields_args",t):t).key&&(e+='[data-key="'+t.key+'"]'),t.type&&(e+='[data-type="'+t.type+'"]'),t.name&&(e+='[data-name="'+t.name+'"]'),t.is&&(e+=t.is),t.visible&&(e+=":visible"),i=t.parent?t.parent.find(e):t.sibling?t.sibling.siblings(e):n(e),t.suppressFilters||(i=i.not(".acf-clone .acf-field"),i=acf.applyFilters("find_fields",i)),i=t.limit?i.slice(0,t.limit):i},acf.findField=function(t,e){return acf.findFields({key:t,limit:1,parent:e,suppressFilters:!0})},acf.getField=function(t){return(t=!(t instanceof jQuery)?acf.findField(t):t).data("acf")||acf.newField(t)},acf.getFields=function(t){t instanceof jQuery||(t=acf.findFields(t));var e=[];return t.each(function(){var t=acf.getField(n(this));e.push(t)}),e},acf.findClosestField=function(t){return t.closest(".acf-field")},acf.getClosestField=function(t){t=acf.findClosestField(t);return this.getField(t)};var e=function(t){var a=t+"_field",s=t+"Field";acf.addAction(a,function(e){var i=acf.arrayArgs(arguments),n=i.slice(1);["type","name","key"].map(function(t){t="/"+t+"="+e.get(t);i=[a+t,e].concat(n),acf.doAction.apply(null,i)}),-1'),e=c('
    '),o=c(''),r=c(""),t.append(n.html()),o.append(r),e.append(o),a.append(t),a.append(e),n.remove(),s.remove(),a.attr("colspan",2),n=t,a=e,s=r),i.addClass("acf-accordion"),n.addClass("acf-accordion-title"),a.addClass("acf-accordion-content"),l++,this.get("multi_expand")&&i.attr("multi-expand",1);var r=acf.getPreference("this.accordions")||[];void 0!==r[l-1]&&this.set("open",r[l-1]),this.get("open")&&(i.addClass("-open"),a.css("display","block")),n.prepend(d.iconHtml({open:this.get("open")}));n=i.parent();s.addClass(n.hasClass("-left")?"-left":""),s.addClass(n.hasClass("-clear")?"-clear":""),s.append(i.nextUntil(".acf-field-accordion",".acf-field")),s.removeAttr("data-open data-multi_expand data-endpoint")}}});acf.registerFieldType(t);var d=new acf.Model({actions:{unload:"onUnload"},events:{"click .acf-accordion-title":"onClick","invalidField .acf-accordion":"onInvalidField"},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},iconHtml:function(t){return acf.isGutenberg()?t.open?'':'':t.open?'':''},open:function(t){var e=acf.isGutenberg()?0:300;t.find(".acf-accordion-content:first").slideDown(e).css("display","block"),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!0})),t.addClass("-open"),acf.doAction("show",t),t.attr("multi-expand")||t.siblings(".acf-accordion.-open").each(function(){d.close(c(this))})},close:function(t){var e=acf.isGutenberg()?0:300;t.find(".acf-accordion-content:first").slideUp(e),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!1})),t.removeClass("-open"),acf.doAction("hide",t)},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},onInvalidField:function(t,e){this.busy||(this.busy=!0,this.setTimeout(function(){this.busy=!1},1e3),this.open(e))},onUnload:function(t){var e=[];c(".acf-accordion").each(function(){var t=c(this).hasClass("-open")?1:0;e.push(t)}),e.length&&acf.setPreference("this.accordions",e)}})}(jQuery),function(){var t=acf.Field.extend({type:"button_group",events:{'click input[type="radio"]':"onClick"},$control:function(){return this.$(".acf-button-group")},$input:function(){return this.$("input:checked")},setValue:function(t){this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClick:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(t)}(jQuery),function(e){var t=acf.Field.extend({type:"checkbox",events:{"change input":"onChange","click .acf-add-checkbox":"onClickAdd","click .acf-checkbox-toggle":"onClickToggle","click .acf-checkbox-custom":"onClickCustom"},$control:function(){return this.$(".acf-checkbox-list")},$toggle:function(){return this.$(".acf-checkbox-toggle")},$input:function(){return this.$('input[type="hidden"]')},$inputs:function(){return this.$('input[type="checkbox"]').not(".acf-checkbox-toggle")},getValue:function(){var t=[];return this.$(":checked").each(function(){t.push(e(this).val())}),!!t.length&&t},onChange:function(t,e){var i=e.prop("checked"),n=e.parent("label"),e=this.$toggle();i?n.addClass("selected"):n.removeClass("selected"),e.length&&(0==this.$inputs().not(":checked").length?e.prop("checked",!0):e.prop("checked",!1))},onClickAdd:function(t,e){var i='
  • ';e.parent("li").before(i)},onClickToggle:function(t,e){var i=e.prop("checked"),n=this.$('input[type="checkbox"]'),e=this.$("label");n.prop("checked",i),i?e.addClass("selected"):e.removeClass("selected")},onClickCustom:function(t,e){var i=e.prop("checked"),n=e.next('input[type="text"]');i?n.prop("disabled",!1):(n.prop("disabled",!0),""==n.val()&&e.parent("li").remove())}});acf.registerFieldType(t)}(jQuery),function(){var t=acf.Field.extend({type:"color_picker",wait:"load",events:{duplicateField:"onDuplicate"},$control:function(){return this.$(".acf-color-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},setValue:function(t){acf.val(this.$input(),t),this.$inputText().iris("color",t)},initialize:function(){var e=this.$input(),i=this.$inputText(),t=function(t){setTimeout(function(){acf.val(e,i.val())},1)},t={defaultColor:!1,palettes:!0,hide:!0,change:t,clear:t},t=acf.applyFilters("color_picker_args",t,this);i.wpColorPicker(t)},onDuplicate:function(t,e,i){$colorPicker=i.find(".wp-picker-container"),$inputText=i.find('input[type="text"]'),$colorPicker.replaceWith($inputText)}});acf.registerFieldType(t)}(jQuery),function(n){var t=acf.Field.extend({type:"date_picker",events:{'blur input[type="text"]':"onBlur",duplicateField:"onDuplicate"},$control:function(){return this.$(".acf-date-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},initialize:function(){if(this.has("save_format"))return this.initializeCompatibility();var t=this.$input(),e=this.$inputText(),t={dateFormat:this.get("date_format"),altField:t,altFormat:"yymmdd",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")},t=acf.applyFilters("date_picker_args",t,this);acf.newDatePicker(e,t),acf.doAction("date_picker_init",e,t,this)},initializeCompatibility:function(){var t=this.$input(),e=this.$inputText();e.val(t.val());var i={dateFormat:this.get("date_format"),altField:t,altFormat:this.get("save_format"),changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")},t=(i=acf.applyFilters("date_picker_args",i,this)).dateFormat;i.dateFormat=this.get("save_format"),acf.newDatePicker(e,i),e.datepicker("option","dateFormat",t),acf.doAction("date_picker_init",e,i,this)},onBlur:function(){this.$inputText().val()||acf.val(this.$input(),"")},onDuplicate:function(t,e,i){i.find('input[type="text"]').removeClass("hasDatepicker").removeAttr("id")}});acf.registerFieldType(t);new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("datePickerL10n");return!!i&&(void 0!==n.datepicker&&(i.isRTL=e,n.datepicker.regional[t]=i,void n.datepicker.setDefaults(i)))}});acf.newDatePicker=function(t,e){if(void 0===n.datepicker)return!1;t.datepicker(e=e||{}),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
    ')}}(jQuery),function(n){var t=acf.models.DatePickerField.extend({type:"date_time_picker",$control:function(){return this.$(".acf-date-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),t={dateFormat:this.get("date_format"),timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altFormat:"yy-mm-dd",altTimeFormat:"HH:mm:ss",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day"),controlType:"select",oneLine:!0},t=acf.applyFilters("date_time_picker_args",t,this);acf.newDateTimePicker(e,t),acf.doAction("date_time_picker_init",e,t,this)}});acf.registerFieldType(t);new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("dateTimePickerL10n");return!!i&&(void 0!==n.timepicker&&(i.isRTL=e,n.timepicker.regional[t]=i,void n.timepicker.setDefaults(i)))}});acf.newDateTimePicker=function(t,e){if(void 0===n.timepicker)return!1;t.datetimepicker(e=e||{}),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
    ')}}(jQuery),function(e){var t=acf.Field.extend({type:"google_map",map:!1,wait:"load",events:{'click a[data-name="clear"]':"onClickClear",'click a[data-name="locate"]':"onClickLocate",'click a[data-name="search"]':"onClickSearch","keydown .search":"onKeydownSearch","keyup .search":"onKeyupSearch","focus .search":"onFocusSearch","blur .search":"onBlurSearch",showField:"onShow"},$control:function(){return this.$(".acf-google-map")},$search:function(){return this.$(".search")},$canvas:function(){return this.$(".canvas")},setState:function(t){this.$control().removeClass("-value -loading -searching"),(t="default"===t?this.val()?"value":"":t)&&this.$control().addClass("-"+t)},getValue:function(){var t=this.$input().val();return!!t&&JSON.parse(t)},setValue:function(t,e){var i="";t&&(i=JSON.stringify(t)),acf.val(this.$input(),i),e||(this.renderVal(t),acf.doAction("google_map_change",t,this.map,this))},renderVal:function(t){t?(this.setState("value"),this.$search().val(t.address),this.setPosition(t.lat,t.lng)):(this.setState(""),this.$search().val(""),this.map.marker.setVisible(!1))},newLatLng:function(t,e){return new google.maps.LatLng(parseFloat(t),parseFloat(e))},setPosition:function(t,e){this.map.marker.setPosition({lat:parseFloat(t),lng:parseFloat(e)}),this.map.marker.setVisible(!0),this.center()},center:function(){var t,e=this.map.marker.getPosition();e=e?(t=e.lat(),e.lng()):(t=this.get("lat"),this.get("lng")),this.map.setCenter({lat:parseFloat(t),lng:parseFloat(e)})},initialize:function(){!function(t){if(a)return t();if(acf.isset(window,"google","maps","Geocoder"))return a=new google.maps.Geocoder,t();acf.addAction("google_map_api_loaded",t),i||(t=acf.get("google_map_api"))&&(i=!0,e.ajax({url:t,dataType:"script",cache:!0,success:function(){a=new google.maps.Geocoder,acf.doAction("google_map_api_loaded")}}))}(this.initializeMap.bind(this))},initializeMap:function(){var t=this.getValue(),e=acf.parseArgs(t,{zoom:this.get("zoom"),lat:this.get("lat"),lng:this.get("lng")}),i={scrollwheel:!1,zoom:parseInt(e.zoom),center:{lat:parseFloat(e.lat),lng:parseFloat(e.lng)},mapTypeId:google.maps.MapTypeId.ROADMAP,marker:{draggable:!0,raiseOnDrag:!0},autocomplete:{}},i=acf.applyFilters("google_map_args",i,this),n=new google.maps.Map(this.$canvas()[0],i),a=acf.parseArgs(i.marker,{draggable:!0,raiseOnDrag:!0,map:n}),a=acf.applyFilters("google_map_marker_args",a,this),e=new google.maps.Marker(a),a=!1;acf.isset(google,"maps","places","Autocomplete")&&(i=i.autocomplete||{},i=acf.applyFilters("google_map_autocomplete_args",i,this),(a=new google.maps.places.Autocomplete(this.$search()[0],i)).bindTo("bounds",n)),this.addMapEvents(this,n,e,a),n.acf=this,n.marker=e,n.autocomplete=a,this.map=n,t&&this.setPosition(t.lat,t.lng),acf.doAction("google_map_init",n,e,this)},addMapEvents:function(i,e,t,n){google.maps.event.addListener(e,"click",function(t){var e=t.latLng.lat(),t=t.latLng.lng();i.searchPosition(e,t)}),google.maps.event.addListener(t,"dragend",function(){var t=this.getPosition().lat(),e=this.getPosition().lng();i.searchPosition(t,e)}),n&&google.maps.event.addListener(n,"place_changed",function(){var t=this.getPlace();i.searchPlace(t)}),google.maps.event.addListener(e,"zoom_changed",function(){var t=i.val();t&&(t.zoom=e.getZoom(),i.setValue(t,!0))})},searchPosition:function(i,n){this.setState("loading"),a.geocode({location:{lat:i,lng:n}},function(t,e){this.setState(""),"OK"!==e?this.showNotice({text:acf.__("Location not found: %s").replace("%s",e),type:"warning"}):((t=this.parseResult(t[0])).lat=i,t.lng=n,this.val(t))}.bind(this))},searchPlace:function(t){var e;t&&(t.geometry?(t.formatted_address=this.$search().val(),e=this.parseResult(t),this.val(e)):t.name&&this.searchAddress(t.name))},searchAddress:function(i){if(i){var t=i.split(",");if(2==t.length){var e=parseFloat(t[0]),t=parseFloat(t[1]);if(e&&t)return this.searchPosition(e,t)}this.setState("loading"),a.geocode({address:i},function(t,e){this.setState(""),"OK"!==e?this.showNotice({text:acf.__("Location not found: %s").replace("%s",e),type:"warning"}):((t=this.parseResult(t[0])).address=i,this.val(t))}.bind(this))}},searchLocation:function(){if(!navigator.geolocation)return alert(acf.__("Sorry, this browser does not support geolocation"));this.setState("loading"),navigator.geolocation.getCurrentPosition(function(t){this.setState("");var e=t.coords.latitude,t=t.coords.longitude;this.searchPosition(e,t)}.bind(this),function(t){this.setState("")}.bind(this))},parseResult:function(t){var e={address:t.formatted_address,lat:t.geometry.location.lat(),lng:t.geometry.location.lng()};e.zoom=this.map.getZoom(),t.place_id&&(e.place_id=t.place_id),t.name&&(e.name=t.name);var i,n={street_number:["street_number"],street_name:["street_address","route"],city:["locality"],state:["administrative_area_level_1","administrative_area_level_2","administrative_area_level_3","administrative_area_level_4","administrative_area_level_5"],post_code:["postal_code"],country:["country"]};for(i in n)for(var a=n[i],s=0;s
    '):this.$el=n('
      '),i.before(this.$el),this.set("index",a,!0),a++},initializeTabs:function(){var t=this.getVisible().shift(),e=(acf.getPreference("this.tabs")||[])[this.get("index")];(t=this.tabs[e]&&this.tabs[e].isVisible()?this.tabs[e]:t)?this.selectTab(t):this.closeTabs(),this.set("initialized",!0)},getVisible:function(){return this.tabs.filter(function(t){return t.isVisible()})},getActive:function(){return this.active},setActive:function(t){return this.active=t},hasActive:function(){return!1!==this.active},isActive:function(t){var e=this.getActive();return e&&e.cid===t.cid},closeActive:function(){this.hasActive()&&this.closeTab(this.getActive())},openTab:function(t){this.closeActive(),t.open(),this.setActive(t)},closeTab:function(t){t.close(),this.setActive(!1)},closeTabs:function(){this.tabs.map(this.closeTab,this)},selectTab:function(e){this.tabs.map(function(t){e.cid!==t.cid&&this.closeTab(t)},this),this.openTab(e)},addTab:function(t,e){t=n("
    • "+t.outerHTML()+"
    • ");this.$("ul").append(t);e=new i({$el:t,field:e,group:this});return this.tabs.push(e),e},reset:function(){return this.closeActive(),this.refresh()},refresh:function(){if(this.hasActive())return!1;var t=this.getVisible().shift();return t&&this.openTab(t),t},onRefresh:function(){var t,e,i;"left"===this.get("placement")&&(t=this.$el.parent(),i=this.$el.children("ul"),e=t.is("td")?"height":"min-height",i=i.position().top+i.outerHeight(!0)-1,t.css(e,i))}}),i=acf.Model.extend({group:!1,field:!1,events:{"click a":"onClick"},index:function(){return this.$el.index()},isVisible:function(){return acf.isVisible(this.$el)},isActive:function(){return this.$el.hasClass("active")},open:function(){this.$el.addClass("active"),this.field.showFields()},close:function(){this.$el.removeClass("active"),this.field.hideFields()},onClick:function(t,e){t.preventDefault(),this.toggle()},toggle:function(){this.isActive()||this.group.openTab(this)}});new acf.Model({priority:50,actions:{prepare:"render",append:"render",unload:"onUnload",invalid_field:"onInvalidField"},findTabs:function(){return n(".acf-tab-wrap")},getTabs:function(){return acf.getInstances(this.findTabs())},render:function(t){this.getTabs().map(function(t){t.get("initialized")||t.initializeTabs()})},onInvalidField:function(t){this.busy||t.hiddenByTab&&(t.hiddenByTab.toggle(),this.busy=!0,this.setTimeout(function(){this.busy=!1},100))},onUnload:function(){var e=[];this.getTabs().map(function(t){t=t.hasActive()?t.getActive().index():0;e.push(t)}),e.length&&acf.setPreference("this.tabs",e)}})}(jQuery),function(){var t=acf.models.SelectField.extend({type:"post_object"});acf.registerFieldType(t)}(jQuery),function(){var t=acf.models.SelectField.extend({type:"page_link"});acf.registerFieldType(t)}(jQuery),function(){var t=acf.models.SelectField.extend({type:"user"});acf.registerFieldType(t)}(jQuery),function(p){var t=acf.Field.extend({type:"taxonomy",data:{ftype:"select"},select2:!1,wait:"load",events:{'click a[data-name="add"]':"onClickAdd",'click input[type="radio"]':"onClickRadio",removeField:"onRemove"},$control:function(){return this.$(".acf-taxonomy-field")},$input:function(){return this.getRelatedPrototype().$input.apply(this,arguments)},getRelatedType:function(){var t=this.get("ftype");return t="multi_select"==t?"select":t},getRelatedPrototype:function(){return acf.getFieldType(this.getRelatedType()).prototype},getValue:function(){return this.getRelatedPrototype().getValue.apply(this,arguments)},setValue:function(){return this.getRelatedPrototype().setValue.apply(this,arguments)},initialize:function(){this.getRelatedPrototype().initialize.apply(this,arguments)},onRemove:function(){var t=this.getRelatedPrototype();t.onRemove&&t.onRemove.apply(this,arguments)},onClickAdd:function(t,e){var i=this,n=!1,a=!1,s=!1,o=!1,r=!1,c=!1,l=function(t){n.loading(!1),n.content(t),a=n.$("form"),s=n.$('input[name="term_name"]'),o=n.$('select[name="term_parent"]'),r=n.$(".acf-submit-button"),s.trigger("focus"),n.on("submit","form",d)},d=function(t,e){if(t.preventDefault(),t.stopImmediatePropagation(),""===s.val())return s.trigger("focus"),!1;acf.startButtonLoading(r);t={action:"acf/fields/taxonomy/add_term",field_key:i.get("key"),term_name:s.val(),term_parent:o.length?o.val():0};p.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(t),type:"post",dataType:"json",success:u})},u=function(t){acf.stopButtonLoading(r),c&&c.remove(),c=acf.isAjaxSuccess(t)?(s.val(""),f(t.data),acf.newNotice({type:"success",text:acf.getAjaxMessage(t),target:a,timeout:2e3,dismiss:!1})):acf.newNotice({type:"error",text:acf.getAjaxError(t),target:a,timeout:2e3,dismiss:!1}),s.trigger("focus")},f=function(e){var t=p('");e.term_parent?o.children('option[value="'+e.term_parent+'"]').after(t):o.append(t),acf.getFields({type:"taxonomy"}).map(function(t){t.get("taxonomy")==i.get("taxonomy")&&t.appendTerm(e)}),i.selectTerm(e.term_id)};!function(){n=acf.newPopup({title:e.attr("title"),loading:!0,width:"300px"});var t={action:"acf/fields/taxonomy/add_term",field_key:i.get("key")};p.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(t),type:"post",dataType:"html",success:l})}()},appendTerm:function(t){"select"==this.getRelatedType()?this.appendTermSelect(t):this.appendTermCheckbox(t)},appendTermSelect:function(t){this.select2.addOption({id:t.term_id,text:t.term_label})},appendTermCheckbox:function(t){var e=this.$("[name]:first").attr("name"),i=this.$("ul:first");"checkbox"==this.getRelatedType()&&(e+="[]");e=p(['
    • ',"","
    • "].join(""));t.term_parent&&((i=(t=i.find('li[data-id="'+t.term_parent+'"]')).children("ul")).exists()||(i=p('
        '),t.append(i))),i.append(e)},selectTerm:function(t){"select"==this.getRelatedType()?this.select2.selectOption(t):this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClickRadio:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(t)}(jQuery),function(i){var t=acf.models.DatePickerField.extend({type:"time_picker",$control:function(){return this.$(".acf-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),t={timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altTimeFormat:"HH:mm:ss",showButtonPanel:!0,controlType:"select",oneLine:!0,closeText:acf.get("dateTimePickerL10n").selectText,timeOnly:!0,onClose:function(t,e,i){e=e.dpDiv.find(".ui-datepicker-close");!t&&e.is(":hover")&&i._updateDateTime()}},t=acf.applyFilters("time_picker_args",t,this);acf.newTimePicker(e,t),acf.doAction("time_picker_init",e,t,this)}});acf.registerFieldType(t),acf.newTimePicker=function(t,e){if(void 0===i.timepicker)return!1;t.timepicker(e=e||{}),i("body > #ui-datepicker-div").exists()&&i("body > #ui-datepicker-div").wrap('
        ')}}(jQuery),function(){var t=acf.Field.extend({type:"true_false",events:{"change .acf-switch-input":"onChange","focus .acf-switch-input":"onFocus","blur .acf-switch-input":"onBlur","keypress .acf-switch-input":"onKeypress"},$input:function(){return this.$('input[type="checkbox"]')},$switch:function(){return this.$(".acf-switch")},getValue:function(){return this.$input().prop("checked")?1:0},initialize:function(){this.render()},render:function(){var t,e,i=this.$switch();i.length&&(t=i.children(".acf-switch-on"),e=i.children(".acf-switch-off"),(i=Math.max(t.width(),e.width()))&&(t.css("min-width",i),e.css("min-width",i)))},switchOn:function(){this.$input().prop("checked",!0),this.$switch().addClass("-on")},switchOff:function(){this.$input().prop("checked",!1),this.$switch().removeClass("-on")},onChange:function(t,e){e.prop("checked")?this.switchOn():this.switchOff()},onFocus:function(t,e){this.$switch().addClass("-focus")},onBlur:function(t,e){this.$switch().removeClass("-focus")},onKeypress:function(t,e){return 37===t.keyCode?this.switchOff():39===t.keyCode?this.switchOn():void 0}});acf.registerFieldType(t)}(jQuery),function(){var t=acf.Field.extend({type:"url",events:{'keyup input[type="url"]':"onkeyup"},$control:function(){return this.$(".acf-input-wrap")},$input:function(){return this.$('input[type="url"]')},initialize:function(){this.render()},isValid:function(){var t=this.val();return!!t&&(-1!==t.indexOf("://")||0===t.indexOf("//"))},render:function(){this.isValid()?this.$control().addClass("-valid"):this.$control().removeClass("-valid")},onkeyup:function(t,e){this.render()}});acf.registerFieldType(t)}(jQuery),function(){var t=acf.Field.extend({type:"wysiwyg",wait:"load",events:{"mousedown .acf-editor-wrap.delay":"onMousedown",unmountField:"disableEditor",remountField:"enableEditor",removeField:"disableEditor"},$control:function(){return this.$(".acf-editor-wrap")},$input:function(){return this.$("textarea")},getMode:function(){return this.$control().hasClass("tmce-active")?"visual":"text"},initialize:function(){this.$control().hasClass("delay")||this.initializeEditor()},initializeEditor:function(){var t=this.$control(),e=this.$input(),i={tinymce:!0,quicktags:!0,toolbar:this.get("toolbar"),mode:this.getMode(),field:this},n=e.attr("id"),a=acf.uniqueId("acf-editor-"),s=e.data(),e=e.val();acf.rename({target:t,search:n,replace:a,destructive:!0}),this.set("id",a,!0),this.$input().data(s).val(e),acf.tinymce.initialize(a,i)},onMousedown:function(t){t.preventDefault();t=this.$control();t.removeClass("delay"),t.find(".acf-editor-toolbar").remove(),this.initializeEditor()},enableEditor:function(){"visual"==this.getMode()&&acf.tinymce.enable(this.get("id"))},disableEditor:function(){acf.tinymce.destroy(this.get("id"))}});acf.registerFieldType(t)}(jQuery),function(e){var s=[];acf.Condition=acf.Model.extend({type:"",operator:"==",label:"",choiceType:"input",fieldTypes:[],data:{conditions:!1,field:!1,rule:{}},events:{change:"change",keyup:"change",enableField:"change",disableField:"change"},setup:function(t){e.extend(this.data,t)},getEventTarget:function(t,e){return t||this.get("field").$el},change:function(t,e){this.get("conditions").change(t)},match:function(t,e){return!1},calculate:function(){return this.match(this.get("rule"),this.get("field"))},choices:function(t){return''}}),acf.newCondition=function(t,e){var i=e.get("field"),n=i.getField(t.field);if(!i||!n)return!1;e={rule:t,target:i,conditions:e,field:n},n=n.get("type"),t=t.operator;return new(acf.getConditionTypes({fieldType:n,operator:t})[0]||acf.Condition)(e)};function n(t){return acf.strPascalCase(t||"")+"Condition"}acf.registerConditionType=function(t){var e=t.prototype.type,i=n(e);acf.models[i]=t,s.push(e)},acf.getConditionType=function(t){t=n(t);return acf.models[t]||!1},acf.registerConditionForFieldType=function(t,e){t=acf.getConditionType(t);t&&t.prototype.fieldTypes.push(e)},acf.getConditionTypes=function(n){n=acf.parseArgs(n,{fieldType:"",operator:""});var a=[];return s.map(function(t){var e=acf.getConditionType(t),i=e.prototype.fieldTypes,t=e.prototype.operator;n.fieldType&&-1===i.indexOf(n.fieldType)||n.operator&&t!==n.operator||a.push(e)}),a}}(jQuery),function(){function a(t,e){var i=acf.getFields({key:e,sibling:t.$el,suppressFilters:!0});return!!(i=!i.length?acf.getFields({key:e,parent:t.$el.parent(),suppressFilters:!0}):i).length&&i[0]}var t="conditional_logic";new acf.Model({id:"conditionsManager",priority:20,actions:{new_field:"onNewField"},onNewField:function(t){t.has("conditions")&&t.getConditions().render()}});acf.Field.prototype.getField=function(t){var e=a(this,t);if(e)return e;for(var i=this.parents(),n=0;n'}});acf.registerConditionType(i);var t=i.extend({type:"hasNoValue",operator:"==empty",label:s("Has no value"),match:function(t,e){return!i.prototype.match.apply(this,arguments)}});acf.registerConditionType(t);var o=acf.Condition.extend({type:"equalTo",operator:"==",label:s("Value is equal to"),fieldTypes:["text","textarea","number","range","email","url","password"],match:function(t,e){return acf.isNumeric(t.value)?(i=t.value,n=e.val(),parseFloat(i)===parseFloat(n)):a(t.value,e.val());var i,n},choices:function(t){return''}});acf.registerConditionType(o);var e=o.extend({type:"notEqualTo",operator:"!=",label:s("Value is not equal to"),match:function(t,e){return!o.prototype.match.apply(this,arguments)}});acf.registerConditionType(e);t=acf.Condition.extend({type:"patternMatch",operator:"==pattern",label:s("Value matches pattern"),fieldTypes:["text","textarea","email","url","password","wysiwyg"],match:function(t,e){return function(t,e){e=new RegExp(n(e),"gi");return n(t).match(e)}(e.val(),t.value)},choices:function(t){return''}});acf.registerConditionType(t);t=acf.Condition.extend({type:"contains",operator:"==contains",label:s("Value contains"),fieldTypes:["text","textarea","number","email","url","password","wysiwyg","oembed","select"],match:function(t,e){return e=e.val(),t=t.value,-1'}});acf.registerConditionType(t);t=o.extend({type:"trueFalseEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:s("Checked")}]}});acf.registerConditionType(t);t=e.extend({type:"trueFalseNotEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:s("Checked")}]}});acf.registerConditionType(t);var r=acf.Condition.extend({type:"selectEqualTo",operator:"==",label:s("Value is equal to"),fieldTypes:["select","checkbox","radio","button_group"],match:function(t,e){var i=e.val();return i instanceof Array?(e=t.value,-1",label:s("Value is greater than"),fieldTypes:["number","range"],match:function(t,e){e=e.val();return e instanceof Array&&(e=e.length),e=e,t=t.value,parseFloat(e)>parseFloat(t)},choices:function(t){return''}});acf.registerConditionType(t);e=t.extend({type:"lessThan",operator:"<",label:s("Value is less than"),match:function(t,e){e=e.val();return e instanceof Array&&(e=e.length),e=e,t=t.value,parseFloat(e)'}});acf.registerConditionType(e);t=t.extend({type:"selectionGreaterThan",label:s("Selection is greater than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType(t);e=e.extend({type:"selectionLessThan",label:s("Selection is less than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType(e)}(jQuery),function(t){acf.unload=new acf.Model({wait:"load",active:!0,changed:!1,actions:{validation_failure:"startListening",validation_success:"stopListening"},events:{"change form .acf-field":"startListening","submit form":"stopListening"},enable:function(){this.active=!0},disable:function(){this.active=!1},reset:function(){this.stopListening()},startListening:function(){!this.changed&&this.active&&(this.changed=!0,t(window).on("beforeunload",this.onUnload))},stopListening:function(){this.changed=!1,t(window).off("beforeunload",this.onUnload)},onUnload:function(){return acf.__("The changes you made will be lost if you navigate away from this page")}})}(jQuery),function(e){new acf.Model({wait:"prepare",priority:1,initialize:function(){(acf.get("postboxes")||[]).map(acf.newPostbox)}});acf.getPostbox=function(t){return"string"==typeof arguments[0]&&(t=e("#"+arguments[0])),acf.getInstance(t)},acf.getPostboxes=function(){return acf.getInstances(e(".acf-postbox"))},acf.newPostbox=function(t){return new acf.models.Postbox(t)},acf.models.Postbox=acf.Model.extend({data:{id:"",key:"",style:"default",label:"top",edit:""},setup:function(t){t.editLink&&(t.edit=t.editLink),e.extend(this.data,t),this.$el=this.$postbox()},$postbox:function(){return e("#"+this.get("id"))},$hide:function(){return e("#"+this.get("id")+"-hide")},$hideLabel:function(){return this.$hide().parent()},$hndle:function(){return this.$("> .hndle")},$handleActions:function(){return this.$("> .postbox-header .handle-actions")},$inside:function(){return this.$("> .inside")},isVisible:function(){return this.$el.hasClass("acf-hidden")},initialize:function(){this.$el.addClass("acf-postbox"),this.$el.removeClass("hide-if-js"),"block"===acf.get("editor")||"default"!==(t=this.get("style"))&&this.$el.addClass(t),this.$inside().addClass("acf-fields").addClass("-"+this.get("label"));var t,e=this.get("edit");e&&(t='',(e=this.$handleActions()).length?e.prepend(t):this.$hndle().append(t)),this.show()},show:function(){this.$hideLabel().show(),this.$hide().prop("checked",!0),this.$el.show().removeClass("acf-hidden"),acf.doAction("show_postbox",this)},enable:function(){acf.enable(this.$el,"postbox")},showEnable:function(){this.enable(),this.show()},hide:function(){this.$hideLabel().hide(),this.$el.hide().addClass("acf-hidden"),acf.doAction("hide_postbox",this)},disable:function(){acf.disable(this.$el,"postbox")},hideDisable:function(){this.disable(),this.hide()},html:function(t){this.$inside().html(t),acf.doAction("append",this.$el)}})}(jQuery),function(a){acf.newMediaPopup=function(t){var e=null,e=new("edit"==(t=acf.parseArgs(t,{mode:"select",title:"",button:"",type:"",field:!1,allowedTypes:"",library:"all",multiple:!1,attachment:0,autoOpen:!0,open:function(){},select:function(){},close:function(){}})).mode?acf.models.EditMediaPopup:acf.models.SelectMediaPopup)(t);return t.autoOpen&&setTimeout(function(){e.open()},1),acf.doAction("new_media_popup",e),e};function e(){var t=acf.get("post_id");return acf.isNumeric(t)?t:0}acf.getMimeTypes=function(){return this.get("mimeTypes")},acf.getMimeType=function(t){var e,i=acf.getMimeTypes();if(void 0!==i[t])return i[t];for(e in i)if(-1!==e.indexOf(t))return i[e];return!1};var n=acf.Model.extend({id:"MediaPopup",data:{},defaults:{},frame:!1,setup:function(t){a.extend(this.data,t)},initialize:function(){var t=this.getFrameOptions();this.addFrameStates(t);var e=wp.media(t);(e.acf=this).addFrameEvents(e,t),this.frame=e},open:function(){this.frame.open()},close:function(){this.frame.close()},remove:function(){this.frame.detach(),this.frame.remove()},getFrameOptions:function(){var t={title:this.get("title"),multiple:this.get("multiple"),library:{},states:[]};return this.get("type")&&(t.library.type=this.get("type")),"uploadedTo"===this.get("library")&&(t.library.uploadedTo=e()),this.get("attachment")&&(t.library.post__in=[this.get("attachment")]),this.get("button")&&(t.button={text:this.get("button")}),t},addFrameStates:function(t){var e=wp.media.query(t.library);this.get("field")&&acf.isset(e,"mirroring","args")&&(e.mirroring.args._acfuploader=this.get("field")),t.states.push(new wp.media.controller.Library({library:e,multiple:this.get("multiple"),title:this.get("title"),priority:20,filterable:"all",editable:!0,allowLocalEdits:!0})),acf.isset(wp,"media","controller","EditImage")&&t.states.push(new wp.media.controller.EditImage)},addFrameEvents:function(i,t){i.on("open",function(){this.$el.closest(".media-modal").addClass("acf-media-modal -"+this.acf.get("mode"))},i),i.on("content:render:edit-image",function(){var t=this.state().get("image"),t=new wp.media.view.EditImage({model:t,controller:this}).render();this.content.set(t),t.loadEditor()},i),i.on("select",function(){var t=i.state().get("selection");t&&t.each(function(t,e){i.acf.get("select").apply(i.acf,[t,e])})}),i.on("close",function(){setTimeout(function(){i.acf.get("close").apply(i.acf),i.acf.remove()},1)})}});acf.models.SelectMediaPopup=n.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Select","verb")),n.prototype.setup.apply(this,arguments)},addFrameEvents:function(e,t){acf.isset(_wpPluploadSettings,"defaults","multipart_params")&&(_wpPluploadSettings.defaults.multipart_params._acfuploader=this.get("field"),e.on("open",function(){delete _wpPluploadSettings.defaults.multipart_params._acfuploader})),e.on("content:activate:browse",function(){var t=!1;try{t=e.content.get().toolbar}catch(t){return void console.log(t)}e.acf.customizeFilters.apply(e.acf,[t])}),n.prototype.addFrameEvents.apply(this,arguments)},customizeFilters:function(t){var i,e=t.get("filters");"image"==this.get("type")&&(e.filters.all.text=acf.__("All images"),delete e.filters.audio,delete e.filters.video,delete e.filters.image,a.each(e.filters,function(t,e){e.props.type=e.props.type||"image"})),this.get("allowedTypes")&&this.get("allowedTypes").split(" ").join("").split(".").join("").split(",").map(function(t){t=acf.getMimeType(t);t&&(e.filters[t]={text:t,props:{status:null,type:t,uploadedTo:null,orderby:"date",order:"DESC"},priority:20})}),"uploadedTo"===this.get("library")&&(i=this.frame.options.library.uploadedTo,delete e.filters.unattached,delete e.filters.uploaded,a.each(e.filters,function(t,e){e.text+=" ("+acf.__("Uploaded to this post")+")",e.props.uploadedTo=i}));var n=this.get("field");a.each(e.filters,function(t,e){e.props._acfuploader=n}),t.get("search").model.attributes._acfuploader=n,e.renderFilters&&e.renderFilters()}}),acf.models.EditMediaPopup=n.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Update","verb")),n.prototype.setup.apply(this,arguments)},addFrameEvents:function(i,t){i.on("open",function(){this.$el.closest(".media-modal").addClass("acf-expanded"),"browse"!=this.content.mode()&&this.content.mode("browse");var t=this.state().get("selection"),e=wp.media.attachment(i.acf.get("attachment"));t.add(e)},i),n.prototype.addFrameEvents.apply(this,arguments)}});new acf.Model({id:"customizePrototypes",wait:"ready",initialize:function(){var t;acf.isset(window,"wp","media","view")&&((t=e())&&acf.isset(wp,"media","view","settings","post")&&(wp.media.view.settings.post.id=t),this.customizeAttachmentsButton(),this.customizeAttachmentsRouter(),this.customizeAttachmentFilters(),this.customizeAttachmentCompat(),this.customizeAttachmentLibrary())},customizeAttachmentsButton:function(){var t;acf.isset(wp,"media","view","Button")&&(t=wp.media.view.Button,wp.media.view.Button=t.extend({initialize:function(){var t=_.defaults(this.options,this.defaults);this.model=new Backbone.Model(t),this.listenTo(this.model,"change",this.render)}}))},customizeAttachmentsRouter:function(){var t;acf.isset(wp,"media","view","Router")&&(t=wp.media.view.Router,wp.media.view.Router=t.extend({addExpand:function(){var t=a(['',''+acf.__("Expand Details")+"",''+acf.__("Collapse Details")+"",""].join(""));t.on("click",function(t){t.preventDefault();t=a(this).closest(".media-modal");t.hasClass("acf-expanded")?t.removeClass("acf-expanded"):t.addClass("acf-expanded")}),this.$el.append(t)},initialize:function(){return t.prototype.initialize.apply(this,arguments),this.addExpand(),this}}))},customizeAttachmentFilters:function(){acf.isset(wp,"media","view","AttachmentFilters","All")&&(wp.media.view.AttachmentFilters.All.prototype.renderFilters=function(){this.$el.html(_.chain(this.filters).map(function(t,e){return{el:a("").val(e).html(t.text)[0],priority:t.priority||50}},this).sortBy("priority").pluck("el").value())})},customizeAttachmentCompat:function(){var t,e;acf.isset(wp,"media","view","AttachmentCompat")&&(t=wp.media.view.AttachmentCompat,e=!1,wp.media.view.AttachmentCompat=t.extend({render:function(){return this.rendered?this:(t.prototype.render.apply(this,arguments),this.$("#acf-form-data").length&&(clearTimeout(e),e=setTimeout(a.proxy(function(){this.rendered=!0,acf.doAction("append",this.$el)},this),50)),this)},save:function(t){var e;t&&t.preventDefault(),e=acf.serializeForAjax(this.$el),this.controller.trigger("attachment:compat:waiting",["waiting"]),this.model.saveCompat(e).always(_.bind(this.postSave,this))}}))},customizeAttachmentLibrary:function(){var o;acf.isset(wp,"media","view","Attachment","Library")&&(o=wp.media.view.Attachment.Library,wp.media.view.Attachment.Library=o.extend({render:function(){var t=acf.isget(this,"controller","acf"),e=acf.isget(this,"model","attributes");return t&&e&&(e.acf_errors&&this.$el.addClass("acf-disabled"),(t=t.get("selected"))&&-1',''+acf.__("Restricted")+"",''+n+"",''+a+"","
        "].join("")),e.reset(),void e.single(i)}return o.prototype.toggleSelection.apply(this,arguments)}}))}})}(jQuery),function(u){acf.screen=new acf.Model({active:!0,xhr:!1,timeout:!1,wait:"load",events:{"change #page_template":"onChange","change #parent_id":"onChange","change #post-formats-select":"onChange","change .categorychecklist":"onChange","change .tagsdiv":"onChange",'change .acf-taxonomy-field[data-save="1"]':"onChange","change #product-type":"onChange"},isPost:function(){return"post"===acf.get("screen")},isUser:function(){return"user"===acf.get("screen")},isTaxonomy:function(){return"taxonomy"===acf.get("screen")},isAttachment:function(){return"attachment"===acf.get("screen")},isNavMenu:function(){return"nav_menu"===acf.get("screen")},isWidget:function(){return"widget"===acf.get("screen")},isComment:function(){return"comment"===acf.get("screen")},getPageTemplate:function(){var t=u("#page_template");return t.length?t.val():null},getPageParent:function(t,e){return(e=u("#parent_id")).length?e.val():null},getPageType:function(t,e){return this.getPageParent()?"child":"parent"},getPostType:function(){return u("#post_type").val()},getPostFormat:function(t,e){if((e=u("#post-formats-select input:checked")).length){e=e.val();return"0"==e?"standard":e}return null},getPostCoreTerms:function(){var t,e={},i=acf.serialize(u(".categorydiv, .tagsdiv"));for(t in i.tax_input&&(e=i.tax_input),i.post_category&&(e.category=i.post_category),e)acf.isArray(e[t])||(e[t]=e[t].split(/,[\s]?/));return e},getPostTerms:function(){var t,i=this.getPostCoreTerms();for(t in acf.getFields({type:"taxonomy"}).map(function(t){var e;t.get("save")&&(e=t.val(),t=t.get("taxonomy"),e&&(i[t]=i[t]||[],e=acf.isArray(e)?e:[e],i[t]=i[t].concat(e)))}),null!==(productType=this.getProductType())&&(i.product_type=[productType]),i)i[t]=acf.uniqueArray(i[t]);return i},getProductType:function(){var t=u("#product-type");return t.length?t.val():null},check:function(){var e;"post"===acf.get("screen")&&(this.xhr&&this.xhr.abort(),e=acf.parseArgs(this.data,{action:"acf/ajax/check_screen",screen:acf.get("screen"),exists:[]}),this.isPost()&&(e.post_id=acf.get("post_id")),null!==(postType=this.getPostType())&&(e.post_type=postType),null!==(pageTemplate=this.getPageTemplate())&&(e.page_template=pageTemplate),null!==(pageParent=this.getPageParent())&&(e.page_parent=pageParent),null!==(pageType=this.getPageType())&&(e.page_type=pageType),null!==(postFormat=this.getPostFormat())&&(e.post_format=postFormat),null!==(postTerms=this.getPostTerms())&&(e.post_terms=postTerms),acf.getPostboxes().map(function(t){e.exists.push(t.get("key"))}),e=acf.applyFilters("check_screen_args",e),this.xhr=u.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"json",context:this,success:function(t){"post"==acf.get("screen")?this.renderPostScreen(t):"user"==acf.get("screen")&&this.renderUserScreen(t),acf.doAction("check_screen_complete",t,e)}}))},onChange:function(t,e){this.setTimeout(this.check,1)},renderPostScreen:function(c){function l(t,e){var i,n=u._data(t[0]).events;for(i in n)for(var a=0;a','

        ',""+acf.escHtml(e.title)+"","

        ",'
        ','","
        ",""]:['",'

        ',""+acf.escHtml(e.title)+"","

        "]).join("");var n,a,s=u(['
        ',a,'
        ',e.html,"
        ","
        "].join(""));u("#adv-settings").length&&(n=u("#adv-settings .metabox-prefs"),a=u(['"].join("")),l(n.find("input").first(),a.find("input")),n.append(a)),u(".postbox").length&&(l(u(".postbox .handlediv").first(),s.children(".handlediv")),l(u(".postbox .hndle").first(),s.children(".hndle"))),"side"===e.position?u("#"+e.position+"-sortables").append(s):u("#"+e.position+"-sortables").prepend(s);var o=[];if(c.results.map(function(t){e.position===t.position&&u("#"+e.position+"-sortables #"+t.id).length&&o.push(t.id)}),d(e.id,o),c.sorted)for(var r in c.sorted){o=c.sorted[r].split(",");if(d(e.id,o))break}i=acf.newPostbox(e),acf.doAction("append",s),acf.doAction("append_postbox",i)}return i.showEnable(),c.visible.push(e.id),e}),acf.getPostboxes().map(function(t){-1===c.visible.indexOf(t.get("id"))&&(t.hideDisable(),c.hidden.push(t.get("id")))}),u("#acf-style").html(c.style),acf.doAction("refresh_post_screen",c)},renderUserScreen:function(t){}});new acf.Model({postEdits:{},wait:"prepare",initialize:function(){acf.isGutenberg()&&(wp.data.subscribe(acf.debounce(this.onChange).bind(this)),acf.screen.getPageTemplate=this.getPageTemplate,acf.screen.getPageParent=this.getPageParent,acf.screen.getPostType=this.getPostType,acf.screen.getPostFormat=this.getPostFormat,acf.screen.getPostCoreTerms=this.getPostCoreTerms,acf.unload.disable(),5.3<=parseFloat(acf.get("wp_version"))&&this.addAction("refresh_post_screen",this.onRefreshPostScreen),wp.domReady(acf.refresh))},onChange:function(){var e=["template","parent","format"];(wp.data.select("core").getTaxonomies()||[]).map(function(t){e.push(t.rest_base)});var i=wp.data.select("core/editor").getPostEdits(),n={};e.map(function(t){void 0!==i[t]&&(n[t]=i[t])}),JSON.stringify(n)!==JSON.stringify(this.postEdits)&&(this.postEdits=n,acf.screen.check())},getPageTemplate:function(){return wp.data.select("core/editor").getEditedPostAttribute("template")},getPageParent:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("parent")},getPostType:function(){return wp.data.select("core/editor").getEditedPostAttribute("type")},getPostFormat:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("format")},getPostCoreTerms:function(){var i={};return(wp.data.select("core").getTaxonomies()||[]).map(function(t){var e=wp.data.select("core/editor").getEditedPostAttribute(t.rest_base);e&&(i[t.slug]=e)}),i},onRefreshPostScreen:function(e){var i=wp.data.select("core/edit-post"),t=wp.data.dispatch("core/edit-post"),n={};i.getActiveMetaBoxLocations().map(function(t){n[t]=i.getMetaBoxesPerLocation(t)});var a,s=[];for(a in n)n[a].map(function(t){s.push(t.id)});for(a in e.results.filter(function(t){return-1===s.indexOf(t.id)}).map(function(t,e){var i=t.position;n[i]=n[i]||[],n[i].push({id:t.id,title:t.title})}),n)n[a]=n[a].filter(function(t){return-1===e.hidden.indexOf(t.id)});t.setAvailableMetaBoxesPerLocation(n)}})}(jQuery),function(l){function n(){return acf.isset(window,"jQuery","fn","select2","amd")?4:!!acf.isset(window,"Select2")&&3}acf.newSelect2=function(t,e){return e=acf.parseArgs(e,{allowNull:!1,placeholder:"",multiple:!1,field:!1,ajax:!1,ajaxAction:"",ajaxData:function(t){return t},ajaxResults:function(t){return t}}),e=new(4==n()?a:s)(t,e),acf.doAction("new_select2",e),e};var i=acf.Model.extend({setup:function(t,e){l.extend(this.data,e),this.$el=t},initialize:function(){},selectOption:function(t){t=this.getOption(t);t.prop("selected")||t.prop("selected",!0).trigger("change")},unselectOption:function(t){t=this.getOption(t);t.prop("selected")&&t.prop("selected",!1).trigger("change")},getOption:function(t){return this.$('option[value="'+t+'"]')},addOption:function(t){t=acf.parseArgs(t,{id:"",text:"",selected:!1});var e=this.getOption(t.id);return e.length||((e=l("")).html(t.text),e.attr("value",t.id),e.prop("selected",t.selected),this.$el.append(e)),e},getValue:function(){var e=[],t=this.$el.find("option:selected");return t.exists()&&(t=t.sort(function(t,e){return+t.getAttribute("data-i")-+e.getAttribute("data-i")})).each(function(){var t=l(this);e.push({$el:t,id:t.attr("value"),text:t.text()})}),e},mergeOptions:function(){},getChoices:function(){var i=function(t){var e=[];return t.children().each(function(){var t=l(this);t.is("optgroup")?e.push({text:t.attr("label"),children:i(t)}):e.push({id:t.attr("value"),text:t.text()})}),e};return i(this.$el)},getAjaxData:function(t){var e={action:this.get("ajaxAction"),s:t.term||"",paged:t.page||1},i=this.get("field");i&&(e.field_key=i.get("key"));var n=this.get("ajaxData");return n&&(e=n.apply(this,[e,t])),e=acf.applyFilters("select2_ajax_data",e,this.data,this.$el,i||!1,this),acf.prepareForAjax(e)},getAjaxResults:function(t,e){t=acf.parseArgs(t,{results:!1,more:!1});var i=this.get("ajaxResults");return i&&(t=i.apply(this,[t,e])),t=acf.applyFilters("select2_ajax_results",t,e,this)},processAjaxResults:function(t,e){return(t=this.getAjaxResults(t,e)).more&&(t.pagination={more:!0}),setTimeout(l.proxy(this.mergeOptions,this),1),t},destroy:function(){this.$el.data("select2")&&this.$el.select2("destroy"),this.$el.siblings(".select2-container").remove()}}),a=i.extend({initialize:function(){var e=this.$el;(n={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),multiple:this.get("multiple"),data:[],escapeMarkup:function(t){return acf.escHtml(t)}}).multiple&&this.getValue().map(function(t){t.$el.detach().appendTo(e)});var t=e.attr("data-ajax");void 0!==t&&(e.removeData("ajax"),e.removeAttr("data-ajax")),this.get("ajax")&&(n.ajax={url:acf.get("ajaxurl"),delay:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),processResults:l.proxy(this.processAjaxResults,this)});var i=this.get("field"),n=acf.applyFilters("select2_args",n,e,this.data,i||!1,this);e.select2(n);var a,s=e.next(".select2-container");n.multiple&&((a=s.find("ul")).sortable({stop:function(t){a.find(".select2-selection__choice").each(function(){l(l(this).data("data").element).detach().appendTo(e)}),e.trigger("change")}}),e.on("select2:select",this.proxy(function(t){this.getOption(t.params.data.id).detach().appendTo(this.$el)}))),s.addClass("-acf"),void 0!==t&&e.attr("data-ajax",t),acf.doAction("select2_init",e,n,this.data,i||!1,this)},mergeOptions:function(){var i=!1,n=!1;l('.select2-results__option[role="group"]').each(function(){var t=l(this).children("ul"),e=l(this).children("strong");if(n&&n.text()===e.text())return i.append(t.children()),void l(this).remove();i=t,n=e})}}),s=i.extend({initialize:function(){var i=this.$el,n=this.getValue(),a=this.get("multiple"),t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),separator:"||",multiple:this.get("multiple"),data:this.getChoices(),escapeMarkup:function(t){return acf.escHtml(t)},dropdownCss:{"z-index":"999999999"},initSelection:function(t,e){e(a?n:n.shift())}},e=i.siblings("input");e.length||(e=l(''),i.before(e)),inputValue=n.map(function(t){return t.id}).join("||"),e.val(inputValue),t.multiple&&n.map(function(t){t.$el.detach().appendTo(i)}),t.allowClear&&(t.data=t.data.filter(function(t){return""!==t.id})),i.removeData("ajax"),i.removeAttr("data-ajax"),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),quietMillis:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),results:l.proxy(this.processAjaxResults,this)});var s=this.get("field"),t=acf.applyFilters("select2_args",t,i,this.data,s||!1,this);e.select2(t);var o,r=e.select2("container"),c=l.proxy(this.getOption,this);t.multiple&&(o=r.find("ul")).sortable({stop:function(){o.find(".select2-search-choice").each(function(){var t=l(this).data("select2Data");c(t.id).detach().appendTo(i)}),i.trigger("change")}}),e.on("select2-selecting",function(t){var e=t.choice,t=c(e.id);(t=!t.length?l('"):t).detach().appendTo(i)}),r.addClass("-acf"),acf.doAction("select2_init",i,t,this.data,s||!1,this),e.on("change",function(){var t=e.val();t.indexOf("||")&&(t=t.split("||")),i.val(t).trigger("change")}),i.hide()},mergeOptions:function(){var i=!1;l("#select2-drop .select2-result-with-children").each(function(){var t=l(this).children("ul"),e=l(this).children(".select2-result-label");if(i&&i.text()===e.text())return i.append(t.children()),void l(this).remove();i=e})},getAjaxData:function(t,e){return i.prototype.getAjaxData.apply(this,[{term:t,page:e}])}});new acf.Model({priority:5,wait:"prepare",actions:{duplicate:"onDuplicate"},initialize:function(){var t=acf.get("locale"),e=(acf.get("rtl"),acf.get("select2L10n")),i=n();return!!e&&(0!==t.indexOf("en")&&void(4==i?this.addTranslations4():3==i&&this.addTranslations3()))},addTranslations4:function(){var e=acf.get("select2L10n"),t=(t=acf.get("locale")).replace("_","-"),i={errorLoading:function(){return e.load_fail},inputTooLong:function(t){t=t.input.length-t.maximum;return 1'),t.addClass("acf-sortable-tr-helper"),t.children().each(function(){c(this).width(c(this).width())}),e.height(t.height()+"px"),t.removeClass("acf-sortable-tr-helper"))}}),new acf.Model({actions:{after_duplicate:"onAfterDuplicate"},onAfterDuplicate:function(t,e){var i=[];t.find("select").each(function(t){i.push(c(this).val())}),e.find("select").each(function(t){c(this).val(i[t])})}}),new acf.Model({id:"tableHelper",priority:20,actions:{refresh:"renderTables"},renderTables:function(t){var e=this;c(".acf-table:visible").each(function(){e.renderTable(c(this))})},renderTable:function(t){var e=t.find("> thead > tr:visible > th[data-key]"),a=t.find("> tbody > tr:visible > td[data-key]");if(!e.length||!a.length)return!1;e.each(function(t){var e=c(this),i=e.data("key"),n=a.filter('[data-key="'+i+'"]'),i=n.filter(".acf-hidden");n.removeClass("acf-empty"),n.length===i.length?acf.hide(e):(acf.show(e),i.addClass("acf-empty"))}),e.css("width","auto");var e=e.not(".acf-hidden"),i=100;e.length;e.filter("[data-width]").each(function(){var t=c(this).data("width");c(this).css("width",t+"%"),i-=t});var n=e.not("[data-width]");n.length&&(t=i/n.length,n.css("width",t+"%"),i=0),0'),e=c('
        '),o=c('
          '),r=c(""),t.append(n.html()),o.append(r),e.append(o),a.append(t),a.append(e),n.remove(),s.remove(),a.attr("colspan",2),n=t,a=e,s=r),i.addClass("acf-accordion"),n.addClass("acf-accordion-title"),a.addClass("acf-accordion-content"),l++,this.get("multi_expand")&&i.attr("multi-expand",1);var r=acf.getPreference("this.accordions")||[];void 0!==r[l-1]&&this.set("open",r[l-1]),this.get("open")&&(i.addClass("-open"),a.css("display","block")),n.prepend(d.iconHtml({open:this.get("open")}));n=i.parent();s.addClass(n.hasClass("-left")?"-left":""),s.addClass(n.hasClass("-clear")?"-clear":""),s.append(i.nextUntil(".acf-field-accordion",".acf-field")),s.removeAttr("data-open data-multi_expand data-endpoint")}}});acf.registerFieldType(t);var d=new acf.Model({actions:{unload:"onUnload"},events:{"click .acf-accordion-title":"onClick","invalidField .acf-accordion":"onInvalidField"},isOpen:function(t){return t.hasClass("-open")},toggle:function(t){this.isOpen(t)?this.close(t):this.open(t)},iconHtml:function(t){return acf.isGutenberg()?t.open?'':'':t.open?'':''},open:function(t){var e=acf.isGutenberg()?0:300;t.find(".acf-accordion-content:first").slideDown(e).css("display","block"),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!0})),t.addClass("-open"),acf.doAction("show",t),t.attr("multi-expand")||t.siblings(".acf-accordion.-open").each(function(){d.close(c(this))})},close:function(t){var e=acf.isGutenberg()?0:300;t.find(".acf-accordion-content:first").slideUp(e),t.find(".acf-accordion-icon:first").replaceWith(this.iconHtml({open:!1})),t.removeClass("-open"),acf.doAction("hide",t)},onClick:function(t,e){t.preventDefault(),this.toggle(e.parent())},onInvalidField:function(t,e){this.busy||(this.busy=!0,this.setTimeout(function(){this.busy=!1},1e3),this.open(e))},onUnload:function(t){var e=[];c(".acf-accordion").each(function(){var t=c(this).hasClass("-open")?1:0;e.push(t)}),e.length&&acf.setPreference("this.accordions",e)}})}(jQuery),function(){var t=acf.Field.extend({type:"button_group",events:{'click input[type="radio"]':"onClick"},$control:function(){return this.$(".acf-button-group")},$input:function(){return this.$("input:checked")},setValue:function(t){this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClick:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(t)}(jQuery),function(e){var t=acf.Field.extend({type:"checkbox",events:{"change input":"onChange","click .acf-add-checkbox":"onClickAdd","click .acf-checkbox-toggle":"onClickToggle","click .acf-checkbox-custom":"onClickCustom"},$control:function(){return this.$(".acf-checkbox-list")},$toggle:function(){return this.$(".acf-checkbox-toggle")},$input:function(){return this.$('input[type="hidden"]')},$inputs:function(){return this.$('input[type="checkbox"]').not(".acf-checkbox-toggle")},getValue:function(){var t=[];return this.$(":checked").each(function(){t.push(e(this).val())}),!!t.length&&t},onChange:function(t,e){var i=e.prop("checked"),n=e.parent("label"),e=this.$toggle();i?n.addClass("selected"):n.removeClass("selected"),e.length&&(0==this.$inputs().not(":checked").length?e.prop("checked",!0):e.prop("checked",!1))},onClickAdd:function(t,e){var i='
        • ';e.parent("li").before(i)},onClickToggle:function(t,e){var i=e.prop("checked"),n=this.$('input[type="checkbox"]'),e=this.$("label");n.prop("checked",i),i?e.addClass("selected"):e.removeClass("selected")},onClickCustom:function(t,e){var i=e.prop("checked"),n=e.next('input[type="text"]');i?n.prop("disabled",!1):(n.prop("disabled",!0),""==n.val()&&e.parent("li").remove())}});acf.registerFieldType(t)}(jQuery),function(){var t=acf.Field.extend({type:"color_picker",wait:"load",events:{duplicateField:"onDuplicate"},$control:function(){return this.$(".acf-color-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},setValue:function(t){acf.val(this.$input(),t),this.$inputText().iris("color",t)},initialize:function(){var e=this.$input(),i=this.$inputText(),t=function(t){setTimeout(function(){acf.val(e,i.val())},1)},t={defaultColor:!1,palettes:!0,hide:!0,change:t,clear:t},t=acf.applyFilters("color_picker_args",t,this);i.wpColorPicker(t)},onDuplicate:function(t,e,i){$colorPicker=i.find(".wp-picker-container"),$inputText=i.find('input[type="text"]'),$colorPicker.replaceWith($inputText)}});acf.registerFieldType(t)}(jQuery),function(n){var t=acf.Field.extend({type:"date_picker",events:{'blur input[type="text"]':"onBlur",duplicateField:"onDuplicate"},$control:function(){return this.$(".acf-date-picker")},$input:function(){return this.$('input[type="hidden"]')},$inputText:function(){return this.$('input[type="text"]')},initialize:function(){if(this.has("save_format"))return this.initializeCompatibility();var t=this.$input(),e=this.$inputText(),t={dateFormat:this.get("date_format"),altField:t,altFormat:"yymmdd",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")},t=acf.applyFilters("date_picker_args",t,this);acf.newDatePicker(e,t),acf.doAction("date_picker_init",e,t,this)},initializeCompatibility:function(){var t=this.$input(),e=this.$inputText();e.val(t.val());var i={dateFormat:this.get("date_format"),altField:t,altFormat:this.get("save_format"),changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day")},t=(i=acf.applyFilters("date_picker_args",i,this)).dateFormat;i.dateFormat=this.get("save_format"),acf.newDatePicker(e,i),e.datepicker("option","dateFormat",t),acf.doAction("date_picker_init",e,i,this)},onBlur:function(){this.$inputText().val()||acf.val(this.$input(),"")},onDuplicate:function(t,e,i){i.find('input[type="text"]').removeClass("hasDatepicker").removeAttr("id")}});acf.registerFieldType(t);new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("datePickerL10n");return!!i&&(void 0!==n.datepicker&&(i.isRTL=e,n.datepicker.regional[t]=i,void n.datepicker.setDefaults(i)))}});acf.newDatePicker=function(t,e){if(void 0===n.datepicker)return!1;t.datepicker(e=e||{}),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
          ')}}(jQuery),function(n){var t=acf.models.DatePickerField.extend({type:"date_time_picker",$control:function(){return this.$(".acf-date-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),t={dateFormat:this.get("date_format"),timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altFormat:"yy-mm-dd",altTimeFormat:"HH:mm:ss",changeYear:!0,yearRange:"-100:+100",changeMonth:!0,showButtonPanel:!0,firstDay:this.get("first_day"),controlType:"select",oneLine:!0},t=acf.applyFilters("date_time_picker_args",t,this);acf.newDateTimePicker(e,t),acf.doAction("date_time_picker_init",e,t,this)}});acf.registerFieldType(t);new acf.Model({priority:5,wait:"ready",initialize:function(){var t=acf.get("locale"),e=acf.get("rtl"),i=acf.get("dateTimePickerL10n");return!!i&&(void 0!==n.timepicker&&(i.isRTL=e,n.timepicker.regional[t]=i,void n.timepicker.setDefaults(i)))}});acf.newDateTimePicker=function(t,e){if(void 0===n.timepicker)return!1;t.datetimepicker(e=e||{}),n("body > #ui-datepicker-div").exists()&&n("body > #ui-datepicker-div").wrap('
          ')}}(jQuery),function(e){var t=acf.Field.extend({type:"google_map",map:!1,wait:"load",events:{'click a[data-name="clear"]':"onClickClear",'click a[data-name="locate"]':"onClickLocate",'click a[data-name="search"]':"onClickSearch","keydown .search":"onKeydownSearch","keyup .search":"onKeyupSearch","focus .search":"onFocusSearch","blur .search":"onBlurSearch",showField:"onShow"},$control:function(){return this.$(".acf-google-map")},$search:function(){return this.$(".search")},$canvas:function(){return this.$(".canvas")},setState:function(t){this.$control().removeClass("-value -loading -searching"),(t="default"===t?this.val()?"value":"":t)&&this.$control().addClass("-"+t)},getValue:function(){var t=this.$input().val();return!!t&&JSON.parse(t)},setValue:function(t,e){var i="";t&&(i=JSON.stringify(t)),acf.val(this.$input(),i),e||(this.renderVal(t),acf.doAction("google_map_change",t,this.map,this))},renderVal:function(t){t?(this.setState("value"),this.$search().val(t.address),this.setPosition(t.lat,t.lng)):(this.setState(""),this.$search().val(""),this.map.marker.setVisible(!1))},newLatLng:function(t,e){return new google.maps.LatLng(parseFloat(t),parseFloat(e))},setPosition:function(t,e){this.map.marker.setPosition({lat:parseFloat(t),lng:parseFloat(e)}),this.map.marker.setVisible(!0),this.center()},center:function(){var t,e=this.map.marker.getPosition();e=e?(t=e.lat(),e.lng()):(t=this.get("lat"),this.get("lng")),this.map.setCenter({lat:parseFloat(t),lng:parseFloat(e)})},initialize:function(){!function(t){if(a)return t();if(acf.isset(window,"google","maps","Geocoder"))return a=new google.maps.Geocoder,t();acf.addAction("google_map_api_loaded",t),i||(t=acf.get("google_map_api"))&&(i=!0,e.ajax({url:t,dataType:"script",cache:!0,success:function(){a=new google.maps.Geocoder,acf.doAction("google_map_api_loaded")}}))}(this.initializeMap.bind(this))},initializeMap:function(){var t=this.getValue(),e=acf.parseArgs(t,{zoom:this.get("zoom"),lat:this.get("lat"),lng:this.get("lng")}),i={scrollwheel:!1,zoom:parseInt(e.zoom),center:{lat:parseFloat(e.lat),lng:parseFloat(e.lng)},mapTypeId:google.maps.MapTypeId.ROADMAP,marker:{draggable:!0,raiseOnDrag:!0},autocomplete:{}},i=acf.applyFilters("google_map_args",i,this),n=new google.maps.Map(this.$canvas()[0],i),a=acf.parseArgs(i.marker,{draggable:!0,raiseOnDrag:!0,map:n}),a=acf.applyFilters("google_map_marker_args",a,this),e=new google.maps.Marker(a),a=!1;acf.isset(google,"maps","places","Autocomplete")&&(i=i.autocomplete||{},i=acf.applyFilters("google_map_autocomplete_args",i,this),(a=new google.maps.places.Autocomplete(this.$search()[0],i)).bindTo("bounds",n)),this.addMapEvents(this,n,e,a),n.acf=this,n.marker=e,n.autocomplete=a,this.map=n,t&&this.setPosition(t.lat,t.lng),acf.doAction("google_map_init",n,e,this)},addMapEvents:function(i,e,t,n){google.maps.event.addListener(e,"click",function(t){var e=t.latLng.lat(),t=t.latLng.lng();i.searchPosition(e,t)}),google.maps.event.addListener(t,"dragend",function(){var t=this.getPosition().lat(),e=this.getPosition().lng();i.searchPosition(t,e)}),n&&google.maps.event.addListener(n,"place_changed",function(){var t=this.getPlace();i.searchPlace(t)}),google.maps.event.addListener(e,"zoom_changed",function(){var t=i.val();t&&(t.zoom=e.getZoom(),i.setValue(t,!0))})},searchPosition:function(i,n){this.setState("loading"),a.geocode({location:{lat:i,lng:n}},function(t,e){this.setState(""),"OK"!==e?this.showNotice({text:acf.__("Location not found: %s").replace("%s",e),type:"warning"}):((t=this.parseResult(t[0])).lat=i,t.lng=n,this.val(t))}.bind(this))},searchPlace:function(t){var e;t&&(t.geometry?(t.formatted_address=this.$search().val(),e=this.parseResult(t),this.val(e)):t.name&&this.searchAddress(t.name))},searchAddress:function(i){if(i){var t=i.split(",");if(2==t.length){var e=parseFloat(t[0]),t=parseFloat(t[1]);if(e&&t)return this.searchPosition(e,t)}this.setState("loading"),a.geocode({address:i},function(t,e){this.setState(""),"OK"!==e?this.showNotice({text:acf.__("Location not found: %s").replace("%s",e),type:"warning"}):((t=this.parseResult(t[0])).address=i,this.val(t))}.bind(this))}},searchLocation:function(){if(!navigator.geolocation)return alert(acf.__("Sorry, this browser does not support geolocation"));this.setState("loading"),navigator.geolocation.getCurrentPosition(function(t){this.setState("");var e=t.coords.latitude,t=t.coords.longitude;this.searchPosition(e,t)}.bind(this),function(t){this.setState("")}.bind(this))},parseResult:function(t){var e={address:t.formatted_address,lat:t.geometry.location.lat(),lng:t.geometry.location.lng()};e.zoom=this.map.getZoom(),t.place_id&&(e.place_id=t.place_id),t.name&&(e.name=t.name);var i,n={street_number:["street_number"],street_name:["street_address","route"],city:["locality"],state:["administrative_area_level_1","administrative_area_level_2","administrative_area_level_3","administrative_area_level_4","administrative_area_level_5"],post_code:["postal_code"],country:["country"]};for(i in n)for(var a=n[i],s=0;s
          '):this.$el=n('
            '),i.before(this.$el),this.set("index",a,!0),a++},initializeTabs:function(){var t=this.getVisible().shift(),e=(acf.getPreference("this.tabs")||[])[this.get("index")];(t=this.tabs[e]&&this.tabs[e].isVisible()?this.tabs[e]:t)?this.selectTab(t):this.closeTabs(),this.set("initialized",!0)},getVisible:function(){return this.tabs.filter(function(t){return t.isVisible()})},getActive:function(){return this.active},setActive:function(t){return this.active=t},hasActive:function(){return!1!==this.active},isActive:function(t){var e=this.getActive();return e&&e.cid===t.cid},closeActive:function(){this.hasActive()&&this.closeTab(this.getActive())},openTab:function(t){this.closeActive(),t.open(),this.setActive(t)},closeTab:function(t){t.close(),this.setActive(!1)},closeTabs:function(){this.tabs.map(this.closeTab,this)},selectTab:function(e){this.tabs.map(function(t){e.cid!==t.cid&&this.closeTab(t)},this),this.openTab(e)},addTab:function(t,e){t=n("
          • "+t.outerHTML()+"
          • ");this.$("ul").append(t);e=new i({$el:t,field:e,group:this});return this.tabs.push(e),e},reset:function(){return this.closeActive(),this.refresh()},refresh:function(){if(this.hasActive())return!1;var t=this.getVisible().shift();return t&&this.openTab(t),t},onRefresh:function(){var t,e,i;"left"===this.get("placement")&&(t=this.$el.parent(),i=this.$el.children("ul"),e=t.is("td")?"height":"min-height",i=i.position().top+i.outerHeight(!0)-1,t.css(e,i))}}),i=acf.Model.extend({group:!1,field:!1,events:{"click a":"onClick"},index:function(){return this.$el.index()},isVisible:function(){return acf.isVisible(this.$el)},isActive:function(){return this.$el.hasClass("active")},open:function(){this.$el.addClass("active"),this.field.showFields()},close:function(){this.$el.removeClass("active"),this.field.hideFields()},onClick:function(t,e){t.preventDefault(),this.toggle()},toggle:function(){this.isActive()||this.group.openTab(this)}});new acf.Model({priority:50,actions:{prepare:"render",append:"render",unload:"onUnload",invalid_field:"onInvalidField"},findTabs:function(){return n(".acf-tab-wrap")},getTabs:function(){return acf.getInstances(this.findTabs())},render:function(t){this.getTabs().map(function(t){t.get("initialized")||t.initializeTabs()})},onInvalidField:function(t){this.busy||t.hiddenByTab&&(t.hiddenByTab.toggle(),this.busy=!0,this.setTimeout(function(){this.busy=!1},100))},onUnload:function(){var e=[];this.getTabs().map(function(t){t=t.hasActive()?t.getActive().index():0;e.push(t)}),e.length&&acf.setPreference("this.tabs",e)}})}(jQuery),function(){var t=acf.models.SelectField.extend({type:"post_object"});acf.registerFieldType(t)}(jQuery),function(){var t=acf.models.SelectField.extend({type:"page_link"});acf.registerFieldType(t)}(jQuery),function(){var t=acf.models.SelectField.extend({type:"user"});acf.registerFieldType(t)}(jQuery),function(p){var t=acf.Field.extend({type:"taxonomy",data:{ftype:"select"},select2:!1,wait:"load",events:{'click a[data-name="add"]':"onClickAdd",'click input[type="radio"]':"onClickRadio",removeField:"onRemove"},$control:function(){return this.$(".acf-taxonomy-field")},$input:function(){return this.getRelatedPrototype().$input.apply(this,arguments)},getRelatedType:function(){var t=this.get("ftype");return t="multi_select"==t?"select":t},getRelatedPrototype:function(){return acf.getFieldType(this.getRelatedType()).prototype},getValue:function(){return this.getRelatedPrototype().getValue.apply(this,arguments)},setValue:function(){return this.getRelatedPrototype().setValue.apply(this,arguments)},initialize:function(){this.getRelatedPrototype().initialize.apply(this,arguments)},onRemove:function(){var t=this.getRelatedPrototype();t.onRemove&&t.onRemove.apply(this,arguments)},onClickAdd:function(t,e){var i=this,n=!1,a=!1,s=!1,o=!1,r=!1,c=!1,l=function(t){n.loading(!1),n.content(t),a=n.$("form"),s=n.$('input[name="term_name"]'),o=n.$('select[name="term_parent"]'),r=n.$(".acf-submit-button"),s.trigger("focus"),n.on("submit","form",d)},d=function(t,e){if(t.preventDefault(),t.stopImmediatePropagation(),""===s.val())return s.trigger("focus"),!1;acf.startButtonLoading(r);t={action:"acf/fields/taxonomy/add_term",field_key:i.get("key"),term_name:s.val(),term_parent:o.length?o.val():0};p.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(t),type:"post",dataType:"json",success:u})},u=function(t){acf.stopButtonLoading(r),c&&c.remove(),c=acf.isAjaxSuccess(t)?(s.val(""),f(t.data),acf.newNotice({type:"success",text:acf.getAjaxMessage(t),target:a,timeout:2e3,dismiss:!1})):acf.newNotice({type:"error",text:acf.getAjaxError(t),target:a,timeout:2e3,dismiss:!1}),s.trigger("focus")},f=function(e){var t=p('");e.term_parent?o.children('option[value="'+e.term_parent+'"]').after(t):o.append(t),acf.getFields({type:"taxonomy"}).map(function(t){t.get("taxonomy")==i.get("taxonomy")&&t.appendTerm(e)}),i.selectTerm(e.term_id)};!function(){n=acf.newPopup({title:e.attr("title"),loading:!0,width:"300px"});var t={action:"acf/fields/taxonomy/add_term",field_key:i.get("key")};p.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(t),type:"post",dataType:"html",success:l})}()},appendTerm:function(t){"select"==this.getRelatedType()?this.appendTermSelect(t):this.appendTermCheckbox(t)},appendTermSelect:function(t){this.select2.addOption({id:t.term_id,text:t.term_label})},appendTermCheckbox:function(t){var e=this.$("[name]:first").attr("name"),i=this.$("ul:first");"checkbox"==this.getRelatedType()&&(e+="[]");e=p(['
          • ',"","
          • "].join(""));t.term_parent&&((i=(t=i.find('li[data-id="'+t.term_parent+'"]')).children("ul")).exists()||(i=p('
              '),t.append(i))),i.append(e)},selectTerm:function(t){"select"==this.getRelatedType()?this.select2.selectOption(t):this.$('input[value="'+t+'"]').prop("checked",!0).trigger("change")},onClickRadio:function(t,e){var i=e.parent("label"),n=i.hasClass("selected");this.$(".selected").removeClass("selected"),i.addClass("selected"),this.get("allow_null")&&n&&(i.removeClass("selected"),e.prop("checked",!1).trigger("change"))}});acf.registerFieldType(t)}(jQuery),function(i){var t=acf.models.DatePickerField.extend({type:"time_picker",$control:function(){return this.$(".acf-time-picker")},initialize:function(){var t=this.$input(),e=this.$inputText(),t={timeFormat:this.get("time_format"),altField:t,altFieldTimeOnly:!1,altTimeFormat:"HH:mm:ss",showButtonPanel:!0,controlType:"select",oneLine:!0,closeText:acf.get("dateTimePickerL10n").selectText,timeOnly:!0,onClose:function(t,e,i){e=e.dpDiv.find(".ui-datepicker-close");!t&&e.is(":hover")&&i._updateDateTime()}},t=acf.applyFilters("time_picker_args",t,this);acf.newTimePicker(e,t),acf.doAction("time_picker_init",e,t,this)}});acf.registerFieldType(t),acf.newTimePicker=function(t,e){if(void 0===i.timepicker)return!1;t.timepicker(e=e||{}),i("body > #ui-datepicker-div").exists()&&i("body > #ui-datepicker-div").wrap('
              ')}}(jQuery),function(){var t=acf.Field.extend({type:"true_false",events:{"change .acf-switch-input":"onChange","focus .acf-switch-input":"onFocus","blur .acf-switch-input":"onBlur","keypress .acf-switch-input":"onKeypress"},$input:function(){return this.$('input[type="checkbox"]')},$switch:function(){return this.$(".acf-switch")},getValue:function(){return this.$input().prop("checked")?1:0},initialize:function(){this.render()},render:function(){var t,e,i=this.$switch();i.length&&(t=i.children(".acf-switch-on"),e=i.children(".acf-switch-off"),(i=Math.max(t.width(),e.width()))&&(t.css("min-width",i),e.css("min-width",i)))},switchOn:function(){this.$input().prop("checked",!0),this.$switch().addClass("-on")},switchOff:function(){this.$input().prop("checked",!1),this.$switch().removeClass("-on")},onChange:function(t,e){e.prop("checked")?this.switchOn():this.switchOff()},onFocus:function(t,e){this.$switch().addClass("-focus")},onBlur:function(t,e){this.$switch().removeClass("-focus")},onKeypress:function(t,e){return 37===t.keyCode?this.switchOff():39===t.keyCode?this.switchOn():void 0}});acf.registerFieldType(t)}(jQuery),function(){var t=acf.Field.extend({type:"url",events:{'keyup input[type="url"]':"onkeyup"},$control:function(){return this.$(".acf-input-wrap")},$input:function(){return this.$('input[type="url"]')},initialize:function(){this.render()},isValid:function(){var t=this.val();return!!t&&(-1!==t.indexOf("://")||0===t.indexOf("//"))},render:function(){this.isValid()?this.$control().addClass("-valid"):this.$control().removeClass("-valid")},onkeyup:function(t,e){this.render()}});acf.registerFieldType(t)}(jQuery),function(){var t=acf.Field.extend({type:"wysiwyg",wait:"load",events:{"mousedown .acf-editor-wrap.delay":"onMousedown",unmountField:"disableEditor",remountField:"enableEditor",removeField:"disableEditor"},$control:function(){return this.$(".acf-editor-wrap")},$input:function(){return this.$("textarea")},getMode:function(){return this.$control().hasClass("tmce-active")?"visual":"text"},initialize:function(){this.$control().hasClass("delay")||this.initializeEditor()},initializeEditor:function(){var t=this.$control(),e=this.$input(),i={tinymce:!0,quicktags:!0,toolbar:this.get("toolbar"),mode:this.getMode(),field:this},n=e.attr("id"),a=acf.uniqueId("acf-editor-"),s=e.data(),e=e.val();acf.rename({target:t,search:n,replace:a,destructive:!0}),this.set("id",a,!0),this.$input().data(s).val(e),acf.tinymce.initialize(a,i)},onMousedown:function(t){t.preventDefault();t=this.$control();t.removeClass("delay"),t.find(".acf-editor-toolbar").remove(),this.initializeEditor()},enableEditor:function(){"visual"==this.getMode()&&acf.tinymce.enable(this.get("id"))},disableEditor:function(){acf.tinymce.destroy(this.get("id"))}});acf.registerFieldType(t)}(jQuery),function(e){var s=[];acf.Condition=acf.Model.extend({type:"",operator:"==",label:"",choiceType:"input",fieldTypes:[],data:{conditions:!1,field:!1,rule:{}},events:{change:"change",keyup:"change",enableField:"change",disableField:"change"},setup:function(t){e.extend(this.data,t)},getEventTarget:function(t,e){return t||this.get("field").$el},change:function(t,e){this.get("conditions").change(t)},match:function(t,e){return!1},calculate:function(){return this.match(this.get("rule"),this.get("field"))},choices:function(t){return''}}),acf.newCondition=function(t,e){var i=e.get("field"),n=i.getField(t.field);if(!i||!n)return!1;e={rule:t,target:i,conditions:e,field:n},n=n.get("type"),t=t.operator;return new(acf.getConditionTypes({fieldType:n,operator:t})[0]||acf.Condition)(e)};function n(t){return acf.strPascalCase(t||"")+"Condition"}acf.registerConditionType=function(t){var e=t.prototype.type,i=n(e);acf.models[i]=t,s.push(e)},acf.getConditionType=function(t){t=n(t);return acf.models[t]||!1},acf.registerConditionForFieldType=function(t,e){t=acf.getConditionType(t);t&&t.prototype.fieldTypes.push(e)},acf.getConditionTypes=function(n){n=acf.parseArgs(n,{fieldType:"",operator:""});var a=[];return s.map(function(t){var e=acf.getConditionType(t),i=e.prototype.fieldTypes,t=e.prototype.operator;n.fieldType&&-1===i.indexOf(n.fieldType)||n.operator&&t!==n.operator||a.push(e)}),a}}(jQuery),function(){function a(t,e){var i=acf.getFields({key:e,sibling:t.$el,suppressFilters:!0});return!!(i=!i.length?acf.getFields({key:e,parent:t.$el.parent(),suppressFilters:!0}):i).length&&i[0]}var t="conditional_logic";new acf.Model({id:"conditionsManager",priority:20,actions:{new_field:"onNewField"},onNewField:function(t){t.has("conditions")&&t.getConditions().render()}});acf.Field.prototype.getField=function(t){var e=a(this,t);if(e)return e;for(var i=this.parents(),n=0;n'}});acf.registerConditionType(i);var t=i.extend({type:"hasNoValue",operator:"==empty",label:s("Has no value"),match:function(t,e){return!i.prototype.match.apply(this,arguments)}});acf.registerConditionType(t);var o=acf.Condition.extend({type:"equalTo",operator:"==",label:s("Value is equal to"),fieldTypes:["text","textarea","number","range","email","url","password"],match:function(t,e){return acf.isNumeric(t.value)?(i=t.value,n=e.val(),parseFloat(i)===parseFloat(n)):a(t.value,e.val());var i,n},choices:function(t){return''}});acf.registerConditionType(o);var e=o.extend({type:"notEqualTo",operator:"!=",label:s("Value is not equal to"),match:function(t,e){return!o.prototype.match.apply(this,arguments)}});acf.registerConditionType(e);t=acf.Condition.extend({type:"patternMatch",operator:"==pattern",label:s("Value matches pattern"),fieldTypes:["text","textarea","email","url","password","wysiwyg"],match:function(t,e){return function(t,e){e=new RegExp(n(e),"gi");return n(t).match(e)}(e.val(),t.value)},choices:function(t){return''}});acf.registerConditionType(t);t=acf.Condition.extend({type:"contains",operator:"==contains",label:s("Value contains"),fieldTypes:["text","textarea","number","email","url","password","wysiwyg","oembed","select"],match:function(t,e){return e=e.val(),t=t.value,-1'}});acf.registerConditionType(t);t=o.extend({type:"trueFalseEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:s("Checked")}]}});acf.registerConditionType(t);t=e.extend({type:"trueFalseNotEqualTo",choiceType:"select",fieldTypes:["true_false"],choices:function(t){return[{id:1,text:s("Checked")}]}});acf.registerConditionType(t);var r=acf.Condition.extend({type:"selectEqualTo",operator:"==",label:s("Value is equal to"),fieldTypes:["select","checkbox","radio","button_group"],match:function(t,e){var i=e.val();return i instanceof Array?(e=t.value,-1",label:s("Value is greater than"),fieldTypes:["number","range"],match:function(t,e){e=e.val();return e instanceof Array&&(e=e.length),e=e,t=t.value,parseFloat(e)>parseFloat(t)},choices:function(t){return''}});acf.registerConditionType(t);e=t.extend({type:"lessThan",operator:"<",label:s("Value is less than"),match:function(t,e){e=e.val();return e instanceof Array&&(e=e.length),e=e,t=t.value,parseFloat(e)'}});acf.registerConditionType(e);t=t.extend({type:"selectionGreaterThan",label:s("Selection is greater than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType(t);e=e.extend({type:"selectionLessThan",label:s("Selection is less than"),fieldTypes:["checkbox","select","post_object","page_link","relationship","taxonomy","user"]});acf.registerConditionType(e)}(jQuery),function(t){acf.unload=new acf.Model({wait:"load",active:!0,changed:!1,actions:{validation_failure:"startListening",validation_success:"stopListening"},events:{"change form .acf-field":"startListening","submit form":"stopListening"},enable:function(){this.active=!0},disable:function(){this.active=!1},reset:function(){this.stopListening()},startListening:function(){!this.changed&&this.active&&(this.changed=!0,t(window).on("beforeunload",this.onUnload))},stopListening:function(){this.changed=!1,t(window).off("beforeunload",this.onUnload)},onUnload:function(){return acf.__("The changes you made will be lost if you navigate away from this page")}})}(jQuery),function(e){new acf.Model({wait:"prepare",priority:1,initialize:function(){(acf.get("postboxes")||[]).map(acf.newPostbox)}});acf.getPostbox=function(t){return"string"==typeof arguments[0]&&(t=e("#"+arguments[0])),acf.getInstance(t)},acf.getPostboxes=function(){return acf.getInstances(e(".acf-postbox"))},acf.newPostbox=function(t){return new acf.models.Postbox(t)},acf.models.Postbox=acf.Model.extend({data:{id:"",key:"",style:"default",label:"top",edit:""},setup:function(t){t.editLink&&(t.edit=t.editLink),e.extend(this.data,t),this.$el=this.$postbox()},$postbox:function(){return e("#"+this.get("id"))},$hide:function(){return e("#"+this.get("id")+"-hide")},$hideLabel:function(){return this.$hide().parent()},$hndle:function(){return this.$("> .hndle")},$handleActions:function(){return this.$("> .postbox-header .handle-actions")},$inside:function(){return this.$("> .inside")},isVisible:function(){return this.$el.hasClass("acf-hidden")},initialize:function(){this.$el.addClass("acf-postbox"),this.$el.removeClass("hide-if-js"),"block"===acf.get("editor")||"default"!==(t=this.get("style"))&&this.$el.addClass(t),this.$inside().addClass("acf-fields").addClass("-"+this.get("label"));var t,e=this.get("edit");e&&(t='',(e=this.$handleActions()).length?e.prepend(t):this.$hndle().append(t)),this.show()},show:function(){this.$hideLabel().show(),this.$hide().prop("checked",!0),this.$el.show().removeClass("acf-hidden"),acf.doAction("show_postbox",this)},enable:function(){acf.enable(this.$el,"postbox")},showEnable:function(){this.enable(),this.show()},hide:function(){this.$hideLabel().hide(),this.$el.hide().addClass("acf-hidden"),acf.doAction("hide_postbox",this)},disable:function(){acf.disable(this.$el,"postbox")},hideDisable:function(){this.disable(),this.hide()},html:function(t){this.$inside().html(t),acf.doAction("append",this.$el)}})}(jQuery),function(a){acf.newMediaPopup=function(t){var e=null,e=new("edit"==(t=acf.parseArgs(t,{mode:"select",title:"",button:"",type:"",field:!1,allowedTypes:"",library:"all",multiple:!1,attachment:0,autoOpen:!0,open:function(){},select:function(){},close:function(){}})).mode?acf.models.EditMediaPopup:acf.models.SelectMediaPopup)(t);return t.autoOpen&&setTimeout(function(){e.open()},1),acf.doAction("new_media_popup",e),e};function e(){var t=acf.get("post_id");return acf.isNumeric(t)?t:0}acf.getMimeTypes=function(){return this.get("mimeTypes")},acf.getMimeType=function(t){var e,i=acf.getMimeTypes();if(void 0!==i[t])return i[t];for(e in i)if(-1!==e.indexOf(t))return i[e];return!1};var n=acf.Model.extend({id:"MediaPopup",data:{},defaults:{},frame:!1,setup:function(t){a.extend(this.data,t)},initialize:function(){var t=this.getFrameOptions();this.addFrameStates(t);var e=wp.media(t);(e.acf=this).addFrameEvents(e,t),this.frame=e},open:function(){this.frame.open()},close:function(){this.frame.close()},remove:function(){this.frame.detach(),this.frame.remove()},getFrameOptions:function(){var t={title:this.get("title"),multiple:this.get("multiple"),library:{},states:[]};return this.get("type")&&(t.library.type=this.get("type")),"uploadedTo"===this.get("library")&&(t.library.uploadedTo=e()),this.get("attachment")&&(t.library.post__in=[this.get("attachment")]),this.get("button")&&(t.button={text:this.get("button")}),t},addFrameStates:function(t){var e=wp.media.query(t.library);this.get("field")&&acf.isset(e,"mirroring","args")&&(e.mirroring.args._acfuploader=this.get("field")),t.states.push(new wp.media.controller.Library({library:e,multiple:this.get("multiple"),title:this.get("title"),priority:20,filterable:"all",editable:!0,allowLocalEdits:!0})),acf.isset(wp,"media","controller","EditImage")&&t.states.push(new wp.media.controller.EditImage)},addFrameEvents:function(i,t){i.on("open",function(){this.$el.closest(".media-modal").addClass("acf-media-modal -"+this.acf.get("mode"))},i),i.on("content:render:edit-image",function(){var t=this.state().get("image"),t=new wp.media.view.EditImage({model:t,controller:this}).render();this.content.set(t),t.loadEditor()},i),i.on("select",function(){var t=i.state().get("selection");t&&t.each(function(t,e){i.acf.get("select").apply(i.acf,[t,e])})}),i.on("close",function(){setTimeout(function(){i.acf.get("close").apply(i.acf),i.acf.remove()},1)})}});acf.models.SelectMediaPopup=n.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Select","verb")),n.prototype.setup.apply(this,arguments)},addFrameEvents:function(e,t){acf.isset(_wpPluploadSettings,"defaults","multipart_params")&&(_wpPluploadSettings.defaults.multipart_params._acfuploader=this.get("field"),e.on("open",function(){delete _wpPluploadSettings.defaults.multipart_params._acfuploader})),e.on("content:activate:browse",function(){var t=!1;try{t=e.content.get().toolbar}catch(t){return void console.log(t)}e.acf.customizeFilters.apply(e.acf,[t])}),n.prototype.addFrameEvents.apply(this,arguments)},customizeFilters:function(t){var i,e=t.get("filters");"image"==this.get("type")&&(e.filters.all.text=acf.__("All images"),delete e.filters.audio,delete e.filters.video,delete e.filters.image,a.each(e.filters,function(t,e){e.props.type=e.props.type||"image"})),this.get("allowedTypes")&&this.get("allowedTypes").split(" ").join("").split(".").join("").split(",").map(function(t){t=acf.getMimeType(t);t&&(e.filters[t]={text:t,props:{status:null,type:t,uploadedTo:null,orderby:"date",order:"DESC"},priority:20})}),"uploadedTo"===this.get("library")&&(i=this.frame.options.library.uploadedTo,delete e.filters.unattached,delete e.filters.uploaded,a.each(e.filters,function(t,e){e.text+=" ("+acf.__("Uploaded to this post")+")",e.props.uploadedTo=i}));var n=this.get("field");a.each(e.filters,function(t,e){e.props._acfuploader=n}),t.get("search").model.attributes._acfuploader=n,e.renderFilters&&e.renderFilters()}}),acf.models.EditMediaPopup=n.extend({id:"SelectMediaPopup",setup:function(t){t.button||(t.button=acf._x("Update","verb")),n.prototype.setup.apply(this,arguments)},addFrameEvents:function(i,t){i.on("open",function(){this.$el.closest(".media-modal").addClass("acf-expanded"),"browse"!=this.content.mode()&&this.content.mode("browse");var t=this.state().get("selection"),e=wp.media.attachment(i.acf.get("attachment"));t.add(e)},i),n.prototype.addFrameEvents.apply(this,arguments)}});new acf.Model({id:"customizePrototypes",wait:"ready",initialize:function(){var t;acf.isset(window,"wp","media","view")&&((t=e())&&acf.isset(wp,"media","view","settings","post")&&(wp.media.view.settings.post.id=t),this.customizeAttachmentsButton(),this.customizeAttachmentsRouter(),this.customizeAttachmentFilters(),this.customizeAttachmentCompat(),this.customizeAttachmentLibrary())},customizeAttachmentsButton:function(){var t;acf.isset(wp,"media","view","Button")&&(t=wp.media.view.Button,wp.media.view.Button=t.extend({initialize:function(){var t=_.defaults(this.options,this.defaults);this.model=new Backbone.Model(t),this.listenTo(this.model,"change",this.render)}}))},customizeAttachmentsRouter:function(){var t;acf.isset(wp,"media","view","Router")&&(t=wp.media.view.Router,wp.media.view.Router=t.extend({addExpand:function(){var t=a(['',''+acf.__("Expand Details")+"",''+acf.__("Collapse Details")+"",""].join(""));t.on("click",function(t){t.preventDefault();t=a(this).closest(".media-modal");t.hasClass("acf-expanded")?t.removeClass("acf-expanded"):t.addClass("acf-expanded")}),this.$el.append(t)},initialize:function(){return t.prototype.initialize.apply(this,arguments),this.addExpand(),this}}))},customizeAttachmentFilters:function(){acf.isset(wp,"media","view","AttachmentFilters","All")&&(wp.media.view.AttachmentFilters.All.prototype.renderFilters=function(){this.$el.html(_.chain(this.filters).map(function(t,e){return{el:a("").val(e).html(t.text)[0],priority:t.priority||50}},this).sortBy("priority").pluck("el").value())})},customizeAttachmentCompat:function(){var t,e;acf.isset(wp,"media","view","AttachmentCompat")&&(t=wp.media.view.AttachmentCompat,e=!1,wp.media.view.AttachmentCompat=t.extend({render:function(){return this.rendered?this:(t.prototype.render.apply(this,arguments),this.$("#acf-form-data").length&&(clearTimeout(e),e=setTimeout(a.proxy(function(){this.rendered=!0,acf.doAction("append",this.$el)},this),50)),this)},save:function(t){var e;t&&t.preventDefault(),e=acf.serializeForAjax(this.$el),this.controller.trigger("attachment:compat:waiting",["waiting"]),this.model.saveCompat(e).always(_.bind(this.postSave,this))}}))},customizeAttachmentLibrary:function(){var o;acf.isset(wp,"media","view","Attachment","Library")&&(o=wp.media.view.Attachment.Library,wp.media.view.Attachment.Library=o.extend({render:function(){var t=acf.isget(this,"controller","acf"),e=acf.isget(this,"model","attributes");return t&&e&&(e.acf_errors&&this.$el.addClass("acf-disabled"),(t=t.get("selected"))&&-1',''+acf.__("Restricted")+"",''+n+"",''+a+"","
              "].join("")),e.reset(),void e.single(i)}return o.prototype.toggleSelection.apply(this,arguments)}}))}})}(jQuery),function(u){acf.screen=new acf.Model({active:!0,xhr:!1,timeout:!1,wait:"load",events:{"change #page_template":"onChange","change #parent_id":"onChange","change #post-formats-select":"onChange","change .categorychecklist":"onChange","change .tagsdiv":"onChange",'change .acf-taxonomy-field[data-save="1"]':"onChange","change #product-type":"onChange"},isPost:function(){return"post"===acf.get("screen")},isUser:function(){return"user"===acf.get("screen")},isTaxonomy:function(){return"taxonomy"===acf.get("screen")},isAttachment:function(){return"attachment"===acf.get("screen")},isNavMenu:function(){return"nav_menu"===acf.get("screen")},isWidget:function(){return"widget"===acf.get("screen")},isComment:function(){return"comment"===acf.get("screen")},getPageTemplate:function(){var t=u("#page_template");return t.length?t.val():null},getPageParent:function(t,e){return(e=u("#parent_id")).length?e.val():null},getPageType:function(t,e){return this.getPageParent()?"child":"parent"},getPostType:function(){return u("#post_type").val()},getPostFormat:function(t,e){if((e=u("#post-formats-select input:checked")).length){e=e.val();return"0"==e?"standard":e}return null},getPostCoreTerms:function(){var t,e={},i=acf.serialize(u(".categorydiv, .tagsdiv"));for(t in i.tax_input&&(e=i.tax_input),i.post_category&&(e.category=i.post_category),e)acf.isArray(e[t])||(e[t]=e[t].split(/,[\s]?/));return e},getPostTerms:function(){var t,i=this.getPostCoreTerms();for(t in acf.getFields({type:"taxonomy"}).map(function(t){var e;t.get("save")&&(e=t.val(),t=t.get("taxonomy"),e&&(i[t]=i[t]||[],e=acf.isArray(e)?e:[e],i[t]=i[t].concat(e)))}),null!==(productType=this.getProductType())&&(i.product_type=[productType]),i)i[t]=acf.uniqueArray(i[t]);return i},getProductType:function(){var t=u("#product-type");return t.length?t.val():null},check:function(){var e;"post"===acf.get("screen")&&(this.xhr&&this.xhr.abort(),e=acf.parseArgs(this.data,{action:"acf/ajax/check_screen",screen:acf.get("screen"),exists:[]}),this.isPost()&&(e.post_id=acf.get("post_id")),null!==(postType=this.getPostType())&&(e.post_type=postType),null!==(pageTemplate=this.getPageTemplate())&&(e.page_template=pageTemplate),null!==(pageParent=this.getPageParent())&&(e.page_parent=pageParent),null!==(pageType=this.getPageType())&&(e.page_type=pageType),null!==(postFormat=this.getPostFormat())&&(e.post_format=postFormat),null!==(postTerms=this.getPostTerms())&&(e.post_terms=postTerms),acf.getPostboxes().map(function(t){e.exists.push(t.get("key"))}),e=acf.applyFilters("check_screen_args",e),this.xhr=u.ajax({url:acf.get("ajaxurl"),data:acf.prepareForAjax(e),type:"post",dataType:"json",context:this,success:function(t){"post"==acf.get("screen")?this.renderPostScreen(t):"user"==acf.get("screen")&&this.renderUserScreen(t),acf.doAction("check_screen_complete",t,e)}}))},onChange:function(t,e){this.setTimeout(this.check,1)},renderPostScreen:function(c){function l(t,e){var i,n=u._data(t[0]).events;for(i in n)for(var a=0;a','

              ',""+acf.escHtml(e.title)+"","

              ",'
              ','","
              ",""]:['",'

              ',""+acf.escHtml(e.title)+"","

              "]).join("");var n,a,s=u(['
              ',a,'
              ',e.html,"
              ","
              "].join(""));u("#adv-settings").length&&(n=u("#adv-settings .metabox-prefs"),a=u(['"].join("")),l(n.find("input").first(),a.find("input")),n.append(a)),u(".postbox").length&&(l(u(".postbox .handlediv").first(),s.children(".handlediv")),l(u(".postbox .hndle").first(),s.children(".hndle"))),"side"===e.position?u("#"+e.position+"-sortables").append(s):u("#"+e.position+"-sortables").prepend(s);var o=[];if(c.results.map(function(t){e.position===t.position&&u("#"+e.position+"-sortables #"+t.id).length&&o.push(t.id)}),d(e.id,o),c.sorted)for(var r in c.sorted){o=c.sorted[r].split(",");if(d(e.id,o))break}i=acf.newPostbox(e),acf.doAction("append",s),acf.doAction("append_postbox",i)}return i.showEnable(),c.visible.push(e.id),e}),acf.getPostboxes().map(function(t){-1===c.visible.indexOf(t.get("id"))&&(t.hideDisable(),c.hidden.push(t.get("id")))}),u("#acf-style").html(c.style),acf.doAction("refresh_post_screen",c)},renderUserScreen:function(t){}});new acf.Model({postEdits:{},wait:"prepare",initialize:function(){acf.isGutenberg()&&(wp.data.subscribe(acf.debounce(this.onChange).bind(this)),acf.screen.getPageTemplate=this.getPageTemplate,acf.screen.getPageParent=this.getPageParent,acf.screen.getPostType=this.getPostType,acf.screen.getPostFormat=this.getPostFormat,acf.screen.getPostCoreTerms=this.getPostCoreTerms,acf.unload.disable(),5.3<=parseFloat(acf.get("wp_version"))&&this.addAction("refresh_post_screen",this.onRefreshPostScreen),wp.domReady(acf.refresh))},onChange:function(){var e=["template","parent","format"];(wp.data.select("core").getTaxonomies()||[]).map(function(t){e.push(t.rest_base)});var i=wp.data.select("core/editor").getPostEdits(),n={};e.map(function(t){void 0!==i[t]&&(n[t]=i[t])}),JSON.stringify(n)!==JSON.stringify(this.postEdits)&&(this.postEdits=n,acf.screen.check())},getPageTemplate:function(){return wp.data.select("core/editor").getEditedPostAttribute("template")},getPageParent:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("parent")},getPostType:function(){return wp.data.select("core/editor").getEditedPostAttribute("type")},getPostFormat:function(t,e){return wp.data.select("core/editor").getEditedPostAttribute("format")},getPostCoreTerms:function(){var i={};return(wp.data.select("core").getTaxonomies()||[]).map(function(t){var e=wp.data.select("core/editor").getEditedPostAttribute(t.rest_base);e&&(i[t.slug]=e)}),i},onRefreshPostScreen:function(e){var i=wp.data.select("core/edit-post"),t=wp.data.dispatch("core/edit-post"),n={};i.getActiveMetaBoxLocations().map(function(t){n[t]=i.getMetaBoxesPerLocation(t)});var a,s=[];for(a in n)n[a].map(function(t){s.push(t.id)});for(a in e.results.filter(function(t){return-1===s.indexOf(t.id)}).map(function(t,e){var i=t.position;n[i]=n[i]||[],n[i].push({id:t.id,title:t.title})}),n)n[a]=n[a].filter(function(t){return-1===e.hidden.indexOf(t.id)});t.setAvailableMetaBoxesPerLocation(n)}})}(jQuery),function(l){function n(){return acf.isset(window,"jQuery","fn","select2","amd")?4:!!acf.isset(window,"Select2")&&3}acf.newSelect2=function(t,e){return e=acf.parseArgs(e,{allowNull:!1,placeholder:"",multiple:!1,field:!1,ajax:!1,ajaxAction:"",ajaxData:function(t){return t},ajaxResults:function(t){return t}}),e=new(4==n()?a:s)(t,e),acf.doAction("new_select2",e),e};var i=acf.Model.extend({setup:function(t,e){l.extend(this.data,e),this.$el=t},initialize:function(){},selectOption:function(t){t=this.getOption(t);t.prop("selected")||t.prop("selected",!0).trigger("change")},unselectOption:function(t){t=this.getOption(t);t.prop("selected")&&t.prop("selected",!1).trigger("change")},getOption:function(t){return this.$('option[value="'+t+'"]')},addOption:function(t){t=acf.parseArgs(t,{id:"",text:"",selected:!1});var e=this.getOption(t.id);return e.length||((e=l("")).html(t.text),e.attr("value",t.id),e.prop("selected",t.selected),this.$el.append(e)),e},getValue:function(){var e=[],t=this.$el.find("option:selected");return t.exists()&&(t=t.sort(function(t,e){return+t.getAttribute("data-i")-+e.getAttribute("data-i")})).each(function(){var t=l(this);e.push({$el:t,id:t.attr("value"),text:t.text()})}),e},mergeOptions:function(){},getChoices:function(){var i=function(t){var e=[];return t.children().each(function(){var t=l(this);t.is("optgroup")?e.push({text:t.attr("label"),children:i(t)}):e.push({id:t.attr("value"),text:t.text()})}),e};return i(this.$el)},getAjaxData:function(t){var e={action:this.get("ajaxAction"),s:t.term||"",paged:t.page||1},i=this.get("field");i&&(e.field_key=i.get("key"));var n=this.get("ajaxData");return n&&(e=n.apply(this,[e,t])),e=acf.applyFilters("select2_ajax_data",e,this.data,this.$el,i||!1,this),acf.prepareForAjax(e)},getAjaxResults:function(t,e){t=acf.parseArgs(t,{results:!1,more:!1});var i=this.get("ajaxResults");return i&&(t=i.apply(this,[t,e])),t=acf.applyFilters("select2_ajax_results",t,e,this)},processAjaxResults:function(t,e){return(t=this.getAjaxResults(t,e)).more&&(t.pagination={more:!0}),setTimeout(l.proxy(this.mergeOptions,this),1),t},destroy:function(){this.$el.data("select2")&&this.$el.select2("destroy"),this.$el.siblings(".select2-container").remove()}}),a=i.extend({initialize:function(){var e=this.$el,t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),multiple:this.get("multiple"),data:[],escapeMarkup:function(t){return"string"!=typeof t?t:acf.escHtml(t)}};acf.isset(window,"jQuery","fn","selectWoo")||(t.templateSelection=function(t){var e=l('');return e.html(acf.escHtml(t.text)),e.data("element",t.element),e}),t.multiple&&this.getValue().map(function(t){t.$el.detach().appendTo(e)});var i=e.attr("data-ajax");void 0!==i&&(e.removeData("ajax"),e.removeAttr("data-ajax")),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),delay:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),processResults:l.proxy(this.processAjaxResults,this)});var n=this.get("field"),t=acf.applyFilters("select2_args",t,e,this.data,n||!1,this);e.select2(t);var a,s=e.next(".select2-container");t.multiple&&((a=s.find("ul")).sortable({stop:function(t){a.find(".select2-selection__choice").each(function(){(l(this).data("data")?l(l(this).data("data").element):l(l(this).children("span.acf-selection").data("element"))).detach().appendTo(e)}),e.trigger("change")}}),e.on("select2:select",this.proxy(function(t){this.getOption(t.params.data.id).detach().appendTo(this.$el)}))),s.addClass("-acf"),void 0!==i&&e.attr("data-ajax",i),acf.doAction("select2_init",e,t,this.data,n||!1,this)},mergeOptions:function(){var i=!1,n=!1;l('.select2-results__option[role="group"]').each(function(){var t=l(this).children("ul"),e=l(this).children("strong");if(n&&n.text()===e.text())return i.append(t.children()),void l(this).remove();i=t,n=e})}}),s=i.extend({initialize:function(){var i=this.$el,n=this.getValue(),a=this.get("multiple"),t={width:"100%",allowClear:this.get("allowNull"),placeholder:this.get("placeholder"),separator:"||",multiple:this.get("multiple"),data:this.getChoices(),escapeMarkup:function(t){return acf.escHtml(t)},dropdownCss:{"z-index":"999999999"},initSelection:function(t,e){e(a?n:n.shift())}},e=i.siblings("input");e.length||(e=l(''),i.before(e)),inputValue=n.map(function(t){return t.id}).join("||"),e.val(inputValue),t.multiple&&n.map(function(t){t.$el.detach().appendTo(i)}),t.allowClear&&(t.data=t.data.filter(function(t){return""!==t.id})),i.removeData("ajax"),i.removeAttr("data-ajax"),this.get("ajax")&&(t.ajax={url:acf.get("ajaxurl"),quietMillis:250,dataType:"json",type:"post",cache:!1,data:l.proxy(this.getAjaxData,this),results:l.proxy(this.processAjaxResults,this)});var s=this.get("field"),t=acf.applyFilters("select2_args",t,i,this.data,s||!1,this);e.select2(t);var o,r=e.select2("container"),c=l.proxy(this.getOption,this);t.multiple&&(o=r.find("ul")).sortable({stop:function(){o.find(".select2-search-choice").each(function(){var t=l(this).data("select2Data");c(t.id).detach().appendTo(i)}),i.trigger("change")}}),e.on("select2-selecting",function(t){var e=t.choice,t=c(e.id);(t=!t.length?l('"):t).detach().appendTo(i)}),r.addClass("-acf"),acf.doAction("select2_init",i,t,this.data,s||!1,this),e.on("change",function(){var t=e.val();t.indexOf("||")&&(t=t.split("||")),i.val(t).trigger("change")}),i.hide()},mergeOptions:function(){var i=!1;l("#select2-drop .select2-result-with-children").each(function(){var t=l(this).children("ul"),e=l(this).children(".select2-result-label");if(i&&i.text()===e.text())return i.append(t.children()),void l(this).remove();i=e})},getAjaxData:function(t,e){return i.prototype.getAjaxData.apply(this,[{term:t,page:e}])}});new acf.Model({priority:5,wait:"prepare",actions:{duplicate:"onDuplicate"},initialize:function(){var t=acf.get("locale"),e=(acf.get("rtl"),acf.get("select2L10n")),i=n();return!!e&&(0!==t.indexOf("en")&&void(4==i?this.addTranslations4():3==i&&this.addTranslations3()))},addTranslations4:function(){var e=acf.get("select2L10n"),t=(t=acf.get("locale")).replace("_","-"),i={errorLoading:function(){return e.load_fail},inputTooLong:function(t){t=t.input.length-t.maximum;return 1'),t.addClass("acf-sortable-tr-helper"),t.children().each(function(){c(this).width(c(this).width())}),e.height(t.height()+"px"),t.removeClass("acf-sortable-tr-helper"))}}),new acf.Model({actions:{after_duplicate:"onAfterDuplicate"},onAfterDuplicate:function(t,e){var i=[];t.find("select").each(function(t){i.push(c(this).val())}),e.find("select").each(function(t){c(this).val(i[t])})}}),new acf.Model({id:"tableHelper",priority:20,actions:{refresh:"renderTables"},renderTables:function(t){var e=this;c(".acf-table:visible").each(function(){e.renderTable(c(this))})},renderTable:function(t){var e=t.find("> thead > tr:visible > th[data-key]"),a=t.find("> tbody > tr:visible > td[data-key]");if(!e.length||!a.length)return!1;e.each(function(t){var e=c(this),i=e.data("key"),n=a.filter('[data-key="'+i+'"]'),i=n.filter(".acf-hidden");n.removeClass("acf-empty"),n.length===i.length?acf.hide(e):(acf.show(e),i.addClass("acf-empty"))}),e.css("width","auto");var e=e.not(".acf-hidden"),i=100;e.length;e.filter("[data-width]").each(function(){var t=c(this).data("width");c(this).css("width",t+"%"),i-=t});var n=e.not("[data-width]");n.length&&(t=i/n.length,n.css("width",t+"%"),i=0),0 arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + +function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + +function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +(function ($, undefined) { + acf.jsxNameReplacements = { + "accent-height": "accentHeight", + "accentheight": "accentHeight", + "accept-charset": "acceptCharset", + "acceptcharset": "acceptCharset", + "accesskey": "accessKey", + "alignment-baseline": "alignmentBaseline", + "alignmentbaseline": "alignmentBaseline", + "allowedblocks": "allowedBlocks", + "allowfullscreen": "allowFullScreen", + "allowreorder": "allowReorder", + "arabic-form": "arabicForm", + "arabicform": "arabicForm", + "attributename": "attributeName", + "attributetype": "attributeType", + "autocapitalize": "autoCapitalize", + "autocomplete": "autoComplete", + "autocorrect": "autoCorrect", + "autofocus": "autoFocus", + "autoplay": "autoPlay", + "autoreverse": "autoReverse", + "autosave": "autoSave", + "basefrequency": "baseFrequency", + "baseline-shift": "baselineShift", + "baselineshift": "baselineShift", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "cap-height": "capHeight", + "capheight": "capHeight", + "cellpadding": "cellPadding", + "cellspacing": "cellSpacing", + "charset": "charSet", + "class": "className", + "classid": "classID", + "classname": "className", + "clip-path": "clipPath", + "clip-rule": "clipRule", + "clippath": "clipPath", + "clippathunits": "clipPathUnits", + "cliprule": "clipRule", + "color-interpolation": "colorInterpolation", + "color-interpolation-filters": "colorInterpolationFilters", + "color-profile": "colorProfile", + "color-rendering": "colorRendering", + "colorinterpolation": "colorInterpolation", + "colorinterpolationfilters": "colorInterpolationFilters", + "colorprofile": "colorProfile", + "colorrendering": "colorRendering", + "colspan": "colSpan", + "contenteditable": "contentEditable", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "contextmenu": "contextMenu", + "controlslist": "controlsList", + "crossorigin": "crossOrigin", + "dangerouslysetinnerhtml": "dangerouslySetInnerHTML", + "datetime": "dateTime", + "defaultchecked": "defaultChecked", + "defaultvalue": "defaultValue", + "diffuseconstant": "diffuseConstant", + "disablepictureinpicture": "disablePictureInPicture", + "disableremoteplayback": "disableRemotePlayback", + "dominant-baseline": "dominantBaseline", + "dominantbaseline": "dominantBaseline", + "edgemode": "edgeMode", + "enable-background": "enableBackground", + "enablebackground": "enableBackground", + "enctype": "encType", + "enterkeyhint": "enterKeyHint", + "externalresourcesrequired": "externalResourcesRequired", + "fill-opacity": "fillOpacity", + "fill-rule": "fillRule", + "fillopacity": "fillOpacity", + "fillrule": "fillRule", + "filterres": "filterRes", + "filterunits": "filterUnits", + "flood-color": "floodColor", + "flood-opacity": "floodOpacity", + "floodcolor": "floodColor", + "floodopacity": "floodOpacity", + "font-family": "fontFamily", + "font-size": "fontSize", + "font-size-adjust": "fontSizeAdjust", + "font-stretch": "fontStretch", + "font-style": "fontStyle", + "font-variant": "fontVariant", + "font-weight": "fontWeight", + "fontfamily": "fontFamily", + "fontsize": "fontSize", + "fontsizeadjust": "fontSizeAdjust", + "fontstretch": "fontStretch", + "fontstyle": "fontStyle", + "fontvariant": "fontVariant", + "fontweight": "fontWeight", + "for": "htmlFor", + "formaction": "formAction", + "formenctype": "formEncType", + "formmethod": "formMethod", + "formnovalidate": "formNoValidate", + "formtarget": "formTarget", + "frameborder": "frameBorder", + "glyph-name": "glyphName", + "glyph-orientation-horizontal": "glyphOrientationHorizontal", + "glyph-orientation-vertical": "glyphOrientationVertical", + "glyphname": "glyphName", + "glyphorientationhorizontal": "glyphOrientationHorizontal", + "glyphorientationvertical": "glyphOrientationVertical", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "horiz-adv-x": "horizAdvX", + "horiz-origin-x": "horizOriginX", + "horizadvx": "horizAdvX", + "horizoriginx": "horizOriginX", + "hreflang": "hrefLang", + "htmlfor": "htmlFor", + "http-equiv": "httpEquiv", + "httpequiv": "httpEquiv", + "image-rendering": "imageRendering", + "imagerendering": "imageRendering", + "innerhtml": "innerHTML", + "inputmode": "inputMode", + "itemid": "itemID", + "itemprop": "itemProp", + "itemref": "itemRef", + "itemscope": "itemScope", + "itemtype": "itemType", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keyparams": "keyParams", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "keytype": "keyType", + "lengthadjust": "lengthAdjust", + "letter-spacing": "letterSpacing", + "letterspacing": "letterSpacing", + "lighting-color": "lightingColor", + "lightingcolor": "lightingColor", + "limitingconeangle": "limitingConeAngle", + "marginheight": "marginHeight", + "marginwidth": "marginWidth", + "marker-end": "markerEnd", + "marker-mid": "markerMid", + "marker-start": "markerStart", + "markerend": "markerEnd", + "markerheight": "markerHeight", + "markermid": "markerMid", + "markerstart": "markerStart", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "maxlength": "maxLength", + "mediagroup": "mediaGroup", + "minlength": "minLength", + "nomodule": "noModule", + "novalidate": "noValidate", + "numoctaves": "numOctaves", + "overline-position": "overlinePosition", + "overline-thickness": "overlineThickness", + "overlineposition": "overlinePosition", + "overlinethickness": "overlineThickness", + "paint-order": "paintOrder", + "paintorder": "paintOrder", + "panose-1": "panose1", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "playsinline": "playsInline", + "pointer-events": "pointerEvents", + "pointerevents": "pointerEvents", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "radiogroup": "radioGroup", + "readonly": "readOnly", + "referrerpolicy": "referrerPolicy", + "refx": "refX", + "refy": "refY", + "rendering-intent": "renderingIntent", + "renderingintent": "renderingIntent", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "rowspan": "rowSpan", + "shape-rendering": "shapeRendering", + "shaperendering": "shapeRendering", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spellcheck": "spellCheck", + "spreadmethod": "spreadMethod", + "srcdoc": "srcDoc", + "srclang": "srcLang", + "srcset": "srcSet", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "stop-color": "stopColor", + "stop-opacity": "stopOpacity", + "stopcolor": "stopColor", + "stopopacity": "stopOpacity", + "strikethrough-position": "strikethroughPosition", + "strikethrough-thickness": "strikethroughThickness", + "strikethroughposition": "strikethroughPosition", + "strikethroughthickness": "strikethroughThickness", + "stroke-dasharray": "strokeDasharray", + "stroke-dashoffset": "strokeDashoffset", + "stroke-linecap": "strokeLinecap", + "stroke-linejoin": "strokeLinejoin", + "stroke-miterlimit": "strokeMiterlimit", + "stroke-opacity": "strokeOpacity", + "stroke-width": "strokeWidth", + "strokedasharray": "strokeDasharray", + "strokedashoffset": "strokeDashoffset", + "strokelinecap": "strokeLinecap", + "strokelinejoin": "strokeLinejoin", + "strokemiterlimit": "strokeMiterlimit", + "strokeopacity": "strokeOpacity", + "strokewidth": "strokeWidth", + "suppresscontenteditablewarning": "suppressContentEditableWarning", + "suppresshydrationwarning": "suppressHydrationWarning", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tabindex": "tabIndex", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "templatelock": "templateLock", + "text-anchor": "textAnchor", + "text-decoration": "textDecoration", + "text-rendering": "textRendering", + "textanchor": "textAnchor", + "textdecoration": "textDecoration", + "textlength": "textLength", + "textrendering": "textRendering", + "underline-position": "underlinePosition", + "underline-thickness": "underlineThickness", + "underlineposition": "underlinePosition", + "underlinethickness": "underlineThickness", + "unicode-bidi": "unicodeBidi", + "unicode-range": "unicodeRange", + "unicodebidi": "unicodeBidi", + "unicoderange": "unicodeRange", + "units-per-em": "unitsPerEm", + "unitsperem": "unitsPerEm", + "usemap": "useMap", + "v-alphabetic": "vAlphabetic", + "v-hanging": "vHanging", + "v-ideographic": "vIdeographic", + "v-mathematical": "vMathematical", + "valphabetic": "vAlphabetic", + "vector-effect": "vectorEffect", + "vectoreffect": "vectorEffect", + "vert-adv-y": "vertAdvY", + "vert-origin-x": "vertOriginX", + "vert-origin-y": "vertOriginY", + "vertadvy": "vertAdvY", + "vertoriginx": "vertOriginX", + "vertoriginy": "vertOriginY", + "vhanging": "vHanging", + "videographic": "vIdeographic", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "vmathematical": "vMathematical", + "word-spacing": "wordSpacing", + "wordspacing": "wordSpacing", + "writing-mode": "writingMode", + "writingmode": "writingMode", + "x-height": "xHeight", + "xchannelselector": "xChannelSelector", + "xheight": "xHeight", + "xlink:actuate": "xlinkActuate", + "xlink:arcrole": "xlinkArcrole", + "xlink:href": "xlinkHref", + "xlink:role": "xlinkRole", + "xlink:show": "xlinkShow", + "xlink:title": "xlinkTitle", + "xlink:type": "xlinkType", + "xlinkactuate": "xlinkActuate", + "xlinkarcrole": "xlinkArcrole", + "xlinkhref": "xlinkHref", + "xlinkrole": "xlinkRole", + "xlinkshow": "xlinkShow", + "xlinktitle": "xlinkTitle", + "xlinktype": "xlinkType", + "xml:base": "xmlBase", + "xml:lang": "xmlLang", + "xml:space": "xmlSpace", + "xmlbase": "xmlBase", + "xmllang": "xmlLang", + "xmlns:xlink": "xmlnsXlink", + "xmlnsxlink": "xmlnsXlink", + "xmlspace": "xmlSpace", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" + }; +})(jQuery); + +(function ($, undefined) { + // Dependencies. + var _wp$blockEditor = wp.blockEditor, + BlockControls = _wp$blockEditor.BlockControls, + InspectorControls = _wp$blockEditor.InspectorControls, + InnerBlocks = _wp$blockEditor.InnerBlocks; + var _wp$components = wp.components, + Toolbar = _wp$components.Toolbar, + IconButton = _wp$components.IconButton, + Placeholder = _wp$components.Placeholder, + Spinner = _wp$components.Spinner; + var Fragment = wp.element.Fragment; + var _React = React, + Component = _React.Component; + var withSelect = wp.data.withSelect; + var createHigherOrderComponent = wp.compose.createHigherOrderComponent; + /** + * Storage for registered block types. + * + * @since 5.8.0 + * @var object + */ + + var blockTypes = {}; + /** + * Returns a block type for the given name. + * + * @date 20/2/19 + * @since 5.8.0 + * + * @param string name The block name. + * @return (object|false) + */ + + function getBlockType(name) { + return blockTypes[name] || false; + } + /** + * Returns true if a block exists for the given name. + * + * @date 20/2/19 + * @since 5.8.0 + * + * @param string name The block name. + * @return bool + */ + + + function isBlockType(name) { + return !!blockTypes[name]; + } + /** + * Returns true if the provided block is new. + * + * @date 31/07/2020 + * @since 5.9.0 + * + * @param object props The block props. + * @return bool + */ + + + function isNewBlock(props) { + return !props.attributes.id; + } + /** + * Returns true if the provided block is a duplicate: + * True when there are is another block with the same "id", but a different "clientId". + * + * @date 31/07/2020 + * @since 5.9.0 + * + * @param object props The block props. + * @return bool + */ + + + function isDuplicateBlock(props) { + return getBlocks().filter(function (block) { + return block.attributes.id === props.attributes.id; + }).filter(function (block) { + return block.clientId !== props.clientId; + }).length; + } + /** + * Registers a block type. + * + * @date 19/2/19 + * @since 5.8.0 + * + * @param object blockType The block type settings localized from PHP. + * @return object The result from wp.blocks.registerBlockType(). + */ + + + function registerBlockType(blockType) { + // Bail ealry if is excluded post_type. + var allowedTypes = blockType.post_types || []; + + if (allowedTypes.length) { + // Always allow block to appear on "Edit reusable Block" screen. + allowedTypes.push('wp_block'); // Check post type. + + var postType = acf.get('postType'); + + if (allowedTypes.indexOf(postType) === -1) { + return false; + } + } // Handle svg HTML. + + + if (typeof blockType.icon === 'string' && blockType.icon.substr(0, 4) === 'value pairs used to filter results. + * @return array. + */ + + + function getBlocks(args) { + // Get all blocks (avoid deprecated warning). + var blocks = select('core/block-editor').getBlocks(); // Append innerBlocks. + + var i = 0; + + while (i < blocks.length) { + blocks = blocks.concat(blocks[i].innerBlocks); + i++; + } // Loop over args and filter. + + + for (var k in args) { + blocks = blocks.filter(function (block) { + return block.attributes[k] === args[k]; + }); + } // Return results. + + + return blocks; + } // Data storage for AJAX requests. + + + var ajaxQueue = {}; + /** + * Fetches a JSON result from the AJAX API. + * + * @date 28/2/19 + * @since 5.7.13 + * + * @param object block The block props. + * @query object The query args used in AJAX callback. + * @return object The AJAX promise. + */ + + function fetchBlock(args) { + var _args$attributes = args.attributes, + attributes = _args$attributes === void 0 ? {} : _args$attributes, + _args$query = args.query, + query = _args$query === void 0 ? {} : _args$query, + _args$delay = args.delay, + delay = _args$delay === void 0 ? 0 : _args$delay; // Use storage or default data. + + var id = attributes.id; + var data = ajaxQueue[id] || { + query: {}, + timeout: false, + promise: $.Deferred() + }; // Append query args to storage. + + data.query = _objectSpread(_objectSpread({}, data.query), query); // Set fresh timeout. + + clearTimeout(data.timeout); + data.timeout = setTimeout(function () { + $.ajax({ + url: acf.get('ajaxurl'), + dataType: 'json', + type: 'post', + cache: false, + data: acf.prepareForAjax({ + action: 'acf/ajax/fetch-block', + block: JSON.stringify(attributes), + query: data.query + }) + }).always(function () { + // Clean up queue after AJAX request is complete. + ajaxQueue[id] = null; + }).done(function () { + data.promise.resolve.apply(this, arguments); + }).fail(function () { + data.promise.reject.apply(this, arguments); + }); + }, delay); // Update storage. + + ajaxQueue[id] = data; // Return promise. + + return data.promise; + } + /** + * Returns true if both object are the same. + * + * @date 19/05/2020 + * @since 5.9.0 + * + * @param object obj1 + * @param object obj2 + * @return bool + */ + + + function compareObjects(obj1, obj2) { + return JSON.stringify(obj1) === JSON.stringify(obj2); + } + /** + * Converts HTML into a React element. + * + * @date 19/05/2020 + * @since 5.9.0 + * + * @param string html The HTML to convert. + * @return object Result of React.createElement(). + */ + + + acf.parseJSX = function (html) { + return parseNode($(html)[0]); + }; + /** + * Converts a DOM node into a React element. + * + * @date 19/05/2020 + * @since 5.9.0 + * + * @param DOM node The DOM node. + * @return object Result of React.createElement(). + */ + + + function parseNode(node) { + // Get node name. + var nodeName = parseNodeName(node.nodeName.toLowerCase()); + + if (!nodeName) { + return null; + } // Get node attributes in React friendly format. + + + var nodeAttrs = {}; + acf.arrayArgs(node.attributes).map(parseNodeAttr).forEach(function (attr) { + nodeAttrs[attr.name] = attr.value; + }); // Define args for React.createElement(). + + var args = [nodeName, nodeAttrs]; + acf.arrayArgs(node.childNodes).forEach(function (child) { + if (child instanceof Text) { + var text = child.textContent; + + if (text) { + args.push(text); + } + } else { + args.push(parseNode(child)); + } + }); // Return element. + + return React.createElement.apply(this, args); + } + + ; + /** + * Converts a node or attribute name into it's JSX compliant name + * + * @date 05/07/2021 + * @since 5.9.8 + * + * @param string name The node or attribute name. + * @returns string + */ + + function getJSXName(name) { + var replacement = acf.isget(acf, 'jsxNameReplacements', name); + if (replacement) return replacement; + return name; + } + /** + * Converts the given name into a React friendly name or component. + * + * @date 19/05/2020 + * @since 5.9.0 + * + * @param string name The node name in lowercase. + * @return mixed + */ + + + function parseNodeName(name) { + switch (name) { + case 'innerblocks': + return InnerBlocks; + + case 'script': + return Script; + + case '#comment': + return null; + + default: + // Replace names for JSX counterparts. + name = getJSXName(name); + } + + return name; + } + /** + * Converts the given attribute into a React friendly name and value object. + * + * @date 19/05/2020 + * @since 5.9.0 + * + * @param obj nodeAttr The node attribute. + * @return obj + */ + + + function parseNodeAttr(nodeAttr) { + var name = nodeAttr.name; + var value = nodeAttr.value; + + switch (name) { + // Class. + case 'class': + name = 'className'; + break; + // Style. + + case 'style': + var css = {}; + value.split(';').forEach(function (s) { + var pos = s.indexOf(':'); + + if (pos > 0) { + var ruleName = s.substr(0, pos).trim(); + var ruleValue = s.substr(pos + 1).trim(); // Rename core properties, but not CSS variables. + + if (ruleName.charAt(0) !== '-') { + ruleName = acf.strCamelCase(ruleName); + } + + css[ruleName] = ruleValue; + } + }); + value = css; + break; + // Default. + + default: + // No formatting needed for "data-x" attributes. + if (name.indexOf('data-') === 0) { + break; + } // Replace names for JSX counterparts. + + + name = getJSXName(name); // Convert JSON values. + + var c1 = value.charAt(0); + + if (c1 === '[' || c1 === '{') { + value = JSON.parse(value); + } // Convert bool values. + + + if (value === 'true' || value === 'false') { + value = value === 'true'; + } + + break; + } + + return { + name: name, + value: value + }; + } + /** + * Higher Order Component used to set default block attribute values. + * + * By modifying block attributes directly, instead of defining defaults in registerBlockType(), + * WordPress will include them always within the saved block serialized JSON. + * + * @date 31/07/2020 + * @since 5.9.0 + * + * @param Component BlockListBlock The BlockListBlock Component. + * @return Component + */ + + + var withDefaultAttributes = createHigherOrderComponent(function (BlockListBlock) { + return /*#__PURE__*/function (_Component) { + _inherits(WrappedBlockEdit, _Component); + + var _super = _createSuper(WrappedBlockEdit); + + function WrappedBlockEdit(props) { + var _this; + + _classCallCheck(this, WrappedBlockEdit); + + _this = _super.call(this, props); // Extract vars. + + var _this$props = _this.props, + name = _this$props.name, + attributes = _this$props.attributes; // Only run on ACF Blocks. + + var blockType = getBlockType(name); + + if (!blockType) { + return _possibleConstructorReturn(_this); + } // Set unique ID and default attributes for newly added blocks. + + + if (isNewBlock(props)) { + attributes.id = acf.uniqid('block_'); + + for (var attribute in blockType.attributes) { + if (attributes[attribute] === undefined && blockType[attribute] !== undefined) { + attributes[attribute] = blockType[attribute]; + } + } + + return _possibleConstructorReturn(_this); + } // Generate new ID for duplicated blocks. + + + if (isDuplicateBlock(props)) { + attributes.id = acf.uniqid('block_'); + return _possibleConstructorReturn(_this); + } + + return _this; + } + + _createClass(WrappedBlockEdit, [{ + key: "render", + value: function render() { + return /*#__PURE__*/React.createElement(BlockListBlock, this.props); + } + }]); + + return WrappedBlockEdit; + }(Component); + }, 'withDefaultAttributes'); + wp.hooks.addFilter('editor.BlockListBlock', 'acf/with-default-attributes', withDefaultAttributes); + /** + * The BlockSave functional component. + * + * @date 08/07/2020 + * @since 5.9.0 + */ + + function BlockSave() { + return /*#__PURE__*/React.createElement(InnerBlocks.Content, null); + } + /** + * The BlockEdit component. + * + * @date 19/2/19 + * @since 5.7.12 + */ + + + var BlockEdit = /*#__PURE__*/function (_Component2) { + _inherits(BlockEdit, _Component2); + + var _super2 = _createSuper(BlockEdit); + + function BlockEdit(props) { + var _this2; + + _classCallCheck(this, BlockEdit); + + _this2 = _super2.call(this, props); + + _this2.setup(); + + return _this2; + } + + _createClass(BlockEdit, [{ + key: "setup", + value: function setup() { + var _this$props2 = this.props, + name = _this$props2.name, + attributes = _this$props2.attributes; + var blockType = getBlockType(name); // Restrict current mode. + + function restrictMode(modes) { + if (modes.indexOf(attributes.mode) === -1) { + attributes.mode = modes[0]; + } + } + + switch (blockType.mode) { + case 'edit': + restrictMode(['edit', 'preview']); + break; + + case 'preview': + restrictMode(['preview', 'edit']); + break; + + default: + restrictMode(['auto']); + break; + } + } + }, { + key: "render", + value: function render() { + var _this$props3 = this.props, + name = _this$props3.name, + attributes = _this$props3.attributes, + setAttributes = _this$props3.setAttributes; + var mode = attributes.mode; + var blockType = getBlockType(name); // Show toggle only for edit/preview modes. + + var showToggle = blockType.supports.mode; + + if (mode === 'auto') { + showToggle = false; + } // Configure toggle variables. + + + var toggleText = mode === 'preview' ? acf.__('Switch to Edit') : acf.__('Switch to Preview'); + var toggleIcon = mode === 'preview' ? 'edit' : 'welcome-view-site'; + + function toggleMode() { + setAttributes({ + mode: mode === 'preview' ? 'edit' : 'preview' + }); + } // Return template. + + + return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(BlockControls, null, showToggle && /*#__PURE__*/React.createElement(Toolbar, null, /*#__PURE__*/React.createElement(IconButton, { + className: "components-icon-button components-toolbar__control", + label: toggleText, + icon: toggleIcon, + onClick: toggleMode + }))), /*#__PURE__*/React.createElement(InspectorControls, null, mode === 'preview' && /*#__PURE__*/React.createElement("div", { + className: "acf-block-component acf-block-panel" + }, /*#__PURE__*/React.createElement(BlockForm, this.props))), /*#__PURE__*/React.createElement(BlockBody, this.props)); + } + }]); + + return BlockEdit; + }(Component); + /** + * The BlockBody component. + * + * @date 19/2/19 + * @since 5.7.12 + */ + + + var _BlockBody = /*#__PURE__*/function (_Component3) { + _inherits(_BlockBody, _Component3); + + var _super3 = _createSuper(_BlockBody); + + function _BlockBody() { + _classCallCheck(this, _BlockBody); + + return _super3.apply(this, arguments); + } + + _createClass(_BlockBody, [{ + key: "render", + value: function render() { + var _this$props4 = this.props, + attributes = _this$props4.attributes, + isSelected = _this$props4.isSelected; + var mode = attributes.mode; + return /*#__PURE__*/React.createElement("div", { + className: "acf-block-component acf-block-body" + }, mode === 'auto' && isSelected ? /*#__PURE__*/React.createElement(BlockForm, this.props) : mode === 'auto' && !isSelected ? /*#__PURE__*/React.createElement(BlockPreview, this.props) : mode === 'preview' ? /*#__PURE__*/React.createElement(BlockPreview, this.props) : /*#__PURE__*/React.createElement(BlockForm, this.props)); + } + }]); + + return _BlockBody; + }(Component); // Append blockIndex to component props. + + + var BlockBody = withSelect(function (select, ownProps) { + var clientId = ownProps.clientId; // Use optional rootClientId to allow discoverability of child blocks. + + var rootClientId = select('core/block-editor').getBlockRootClientId(clientId); + var index = select('core/block-editor').getBlockIndex(clientId, rootClientId); + return { + index: index + }; + })(_BlockBody); + /** + * A react component to append HTMl. + * + * @date 19/2/19 + * @since 5.7.12 + * + * @param string children The html to insert. + * @return void + */ + + var Div = /*#__PURE__*/function (_Component4) { + _inherits(Div, _Component4); + + var _super4 = _createSuper(Div); + + function Div() { + _classCallCheck(this, Div); + + return _super4.apply(this, arguments); + } + + _createClass(Div, [{ + key: "render", + value: function render() { + return /*#__PURE__*/React.createElement("div", { + dangerouslySetInnerHTML: { + __html: this.props.children + } + }); + } + }]); + + return Div; + }(Component); + /** + * A react Component for inline scripts. + * + * This Component uses a combination of React references and jQuery to append the + * inline ")); + } + }, { + key: "componentDidUpdate", + value: function componentDidUpdate() { + this.setHTML(this.props.children); + } + }, { + key: "componentDidMount", + value: function componentDidMount() { + this.setHTML(this.props.children); + } + }]); + + return Script; + }(Component); // Data storage for DynamicHTML components. + + + var store = {}; + /** + * DynamicHTML Class. + * + * A react componenet to load and insert dynamic HTML. + * + * @date 19/2/19 + * @since 5.7.12 + * + * @param void + * @return void + */ + + var DynamicHTML = /*#__PURE__*/function (_Component6) { + _inherits(DynamicHTML, _Component6); + + var _super6 = _createSuper(DynamicHTML); + + function DynamicHTML(props) { + var _this4; + + _classCallCheck(this, DynamicHTML); + + _this4 = _super6.call(this, props); // Bind callbacks. + + _this4.setRef = _this4.setRef.bind(_assertThisInitialized(_this4)); // Define default props and call setup(). + + _this4.id = ''; + _this4.el = false; + _this4.subscribed = true; + _this4.renderMethod = 'jQuery'; + + _this4.setup(props); // Load state. + + + _this4.loadState(); + + return _this4; + } + + _createClass(DynamicHTML, [{ + key: "setup", + value: function setup(props) {// Do nothing. + } + }, { + key: "fetch", + value: function fetch() {// Do nothing. + } + }, { + key: "maybePreload", + value: function maybePreload(blockId) { + if (this.state.html === undefined) { + var preloadedBlocks = acf.get('preloadedBlocks'); + + if (preloadedBlocks && preloadedBlocks[blockId]) { + // Set HTML to the preloaded version. + this.setHtml(preloadedBlocks[blockId]); // Delete the preloaded HTML so we don't try to load it again. + + delete preloadedBlocks[blockId]; + acf.set('preloadedBlocks', preloadedBlocks); + return true; + } + } + + return false; + } + }, { + key: "loadState", + value: function loadState() { + this.state = store[this.id] || {}; + } + }, { + key: "setState", + value: function setState(state) { + store[this.id] = _objectSpread(_objectSpread({}, this.state), state); // Update component state if subscribed. + // - Allows AJAX callback to update store without modifying state of an unmounted component. + + if (this.subscribed) { + _get(_getPrototypeOf(DynamicHTML.prototype), "setState", this).call(this, state); + } + } + }, { + key: "setHtml", + value: function setHtml(html) { + html = html ? html.trim() : ''; // Bail early if html has not changed. + + if (html === this.state.html) { + return; + } // Update state. + + + var state = { + html: html + }; + + if (this.renderMethod === 'jsx') { + state.jsx = acf.parseJSX(html); + state.$el = $(this.el); + } else { + state.$el = $(html); + } + + this.setState(state); + } + }, { + key: "setRef", + value: function setRef(el) { + this.el = el; + } + }, { + key: "render", + value: function render() { + // Render JSX. + if (this.state.jsx) { + return /*#__PURE__*/React.createElement("div", { + ref: this.setRef + }, this.state.jsx); + } // Return HTML. + + + return /*#__PURE__*/React.createElement("div", { + ref: this.setRef + }, /*#__PURE__*/React.createElement(Placeholder, null, /*#__PURE__*/React.createElement(Spinner, null))); + } + }, { + key: "shouldComponentUpdate", + value: function shouldComponentUpdate(nextProps, nextState) { + if (nextProps.index !== this.props.index) { + this.componentWillMove(); + } + + return nextState.html !== this.state.html; + } + }, { + key: "display", + value: function display(context) { + // This method is called after setting new HTML and the Component render. + // The jQuery render method simply needs to move $el into place. + if (this.renderMethod === 'jQuery') { + var $el = this.state.$el; + var $prevParent = $el.parent(); + var $thisParent = $(this.el); // Move $el into place. + + $thisParent.html($el); // Special case for reusable blocks. + // Multiple instances of the same reusable block share the same block id. + // This causes all instances to share the same state (cool), which unfortunately + // pulls $el back and forth between the last rendered reusable block. + // This simple fix leaves a "clone" behind :) + + if ($prevParent.length && $prevParent[0] !== $thisParent[0]) { + $prevParent.html($el.clone()); + } + } // Call context specific method. + + + switch (context) { + case 'append': + this.componentDidAppend(); + break; + + case 'remount': + this.componentDidRemount(); + break; + } + } + }, { + key: "componentDidMount", + value: function componentDidMount() { + // Fetch on first load. + if (this.state.html === undefined) { + //console.log('componentDidMount', this.id); + this.fetch(); // Or remount existing HTML. + } else { + this.display('remount'); + } + } + }, { + key: "componentDidUpdate", + value: function componentDidUpdate(prevProps, prevState) { + // HTML has changed. + this.display('append'); + } + }, { + key: "componentDidAppend", + value: function componentDidAppend() { + acf.doAction('append', this.state.$el); + } + }, { + key: "componentWillUnmount", + value: function componentWillUnmount() { + acf.doAction('unmount', this.state.$el); // Unsubscribe this component from state. + + this.subscribed = false; + } + }, { + key: "componentDidRemount", + value: function componentDidRemount() { + var _this5 = this; + + this.subscribed = true; // Use setTimeout to avoid incorrect timing of events. + // React will unmount and mount components in DOM order. + // This means a new component can be mounted before an old one is unmounted. + // ACF shares $el across new/old components which is un-React-like. + // This timout ensures that unmounting occurs before remounting. + + setTimeout(function () { + acf.doAction('remount', _this5.state.$el); + }); + } + }, { + key: "componentWillMove", + value: function componentWillMove() { + var _this6 = this; + + acf.doAction('unmount', this.state.$el); + setTimeout(function () { + acf.doAction('remount', _this6.state.$el); + }); + } + }]); + + return DynamicHTML; + }(Component); + /** + * BlockForm Class. + * + * A react componenet to handle the block form. + * + * @date 19/2/19 + * @since 5.7.12 + * + * @param string id the block id. + * @return void + */ + + + var BlockForm = /*#__PURE__*/function (_DynamicHTML) { + _inherits(BlockForm, _DynamicHTML); + + var _super7 = _createSuper(BlockForm); + + function BlockForm() { + _classCallCheck(this, BlockForm); + + return _super7.apply(this, arguments); + } + + _createClass(BlockForm, [{ + key: "setup", + value: function setup(props) { + this.id = "BlockForm-".concat(props.attributes.id); + } + }, { + key: "fetch", + value: function fetch() { + var _this7 = this; + + // Extract props. + var attributes = this.props.attributes; // Try preloaded data first. + + var preloaded = this.maybePreload(attributes.id); + + if (preloaded) { + return; + } // Request AJAX and update HTML on complete. + + + fetchBlock({ + attributes: attributes, + query: { + form: true + } + }).done(function (json) { + _this7.setHtml(json.data.form); + }); + } + }, { + key: "componentDidAppend", + value: function componentDidAppend() { + _get(_getPrototypeOf(BlockForm.prototype), "componentDidAppend", this).call(this); // Extract props. + + + var _this$props5 = this.props, + attributes = _this$props5.attributes, + setAttributes = _this$props5.setAttributes; + var $el = this.state.$el; // Callback for updating block data. + + function serializeData() { + var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var data = acf.serialize($el, "acf-".concat(attributes.id)); + + if (silent) { + attributes.data = data; + } else { + setAttributes({ + data: data + }); + } + } // Add events. + + + var timeout = false; + $el.on('change keyup', function () { + clearTimeout(timeout); + timeout = setTimeout(serializeData, 300); + }); // Ensure newly added block is saved with data. + // Do it silently to avoid triggering a preview render. + + if (!attributes.data) { + serializeData(true); + } + } + }]); + + return BlockForm; + }(DynamicHTML); + /** + * BlockPreview Class. + * + * A react componenet to handle the block preview. + * + * @date 19/2/19 + * @since 5.7.12 + * + * @param string id the block id. + * @return void + */ + + + var BlockPreview = /*#__PURE__*/function (_DynamicHTML2) { + _inherits(BlockPreview, _DynamicHTML2); + + var _super8 = _createSuper(BlockPreview); + + function BlockPreview() { + _classCallCheck(this, BlockPreview); + + return _super8.apply(this, arguments); + } + + _createClass(BlockPreview, [{ + key: "setup", + value: function setup(props) { + this.id = "BlockPreview-".concat(props.attributes.id); + var blockType = getBlockType(props.name); + + if (blockType.supports.jsx) { + this.renderMethod = 'jsx'; + } //console.log('setup', this.id); + + } + }, { + key: "fetch", + value: function fetch() { + var _this8 = this; + + var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var _args$attributes2 = args.attributes, + attributes = _args$attributes2 === void 0 ? this.props.attributes : _args$attributes2, + _args$delay2 = args.delay, + delay = _args$delay2 === void 0 ? 0 : _args$delay2; // Remember attributes used to fetch HTML. + + this.setState({ + prevAttributes: attributes + }); // Try preloaded data first. + + var preloaded = this.maybePreload(attributes.id); + + if (preloaded) { + return; + } // Request AJAX and update HTML on complete. + + + fetchBlock({ + attributes: attributes, + query: { + preview: true + }, + delay: delay + }).done(function (json) { + _this8.setHtml(json.data.preview); + }); + } + }, { + key: "componentDidAppend", + value: function componentDidAppend() { + _get(_getPrototypeOf(BlockPreview.prototype), "componentDidAppend", this).call(this); // Extract props. + + + var attributes = this.props.attributes; + var $el = this.state.$el; // Generate action friendly type. + + var type = attributes.name.replace('acf/', ''); // Do action. + + acf.doAction('render_block_preview', $el, attributes); + acf.doAction("render_block_preview/type=".concat(type), $el, attributes); + } + }, { + key: "shouldComponentUpdate", + value: function shouldComponentUpdate(nextProps, nextState) { + var nextAttributes = nextProps.attributes; + var thisAttributes = this.props.attributes; // Update preview if block data has changed. + + if (!compareObjects(nextAttributes, thisAttributes)) { + var delay = 0; // Delay fetch when editing className or anchor to simulate conscistent logic to custom fields. + + if (nextAttributes.className !== thisAttributes.className) { + delay = 300; + } + + if (nextAttributes.anchor !== thisAttributes.anchor) { + delay = 300; + } + + this.fetch({ + attributes: nextAttributes, + delay: delay + }); + } + + return _get(_getPrototypeOf(BlockPreview.prototype), "shouldComponentUpdate", this).call(this, nextProps, nextState); + } + }, { + key: "componentDidRemount", + value: function componentDidRemount() { + _get(_getPrototypeOf(BlockPreview.prototype), "componentDidRemount", this).call(this); // Update preview if data has changed since last render (changing from "edit" to "preview"). + + + if (!compareObjects(this.state.prevAttributes, this.props.attributes)) { + //console.log('componentDidRemount', this.id); + this.fetch(); + } + } + }]); + + return BlockPreview; + }(DynamicHTML); + /** + * Initializes ACF Blocks logic and registration. + * + * @since 5.9.0 + */ + + + function initialize() { + // Add support for WordPress versions before 5.2. + if (!wp.blockEditor) { + wp.blockEditor = wp.editor; + } // Register block types. + + + var blockTypes = acf.get('blockTypes'); + + if (blockTypes) { + blockTypes.map(registerBlockType); + } + } // Run the initialize callback during the "prepare" action. + // This ensures that all localized data is available and that blocks are registered before the WP editor has been instantiated. + + + acf.addAction('prepare', initialize); + /** + * Returns a valid vertical alignment. + * + * @date 07/08/2020 + * @since 5.9.0 + * + * @param string align A vertical alignment. + * @return string + */ + + function validateVerticalAlignment(align) { + var ALIGNMENTS = ['top', 'center', 'bottom']; + var DEFAULT = 'top'; + return ALIGNMENTS.includes(align) ? align : DEFAULT; + } + /** + * Returns a valid horizontal alignment. + * + * @date 07/08/2020 + * @since 5.9.0 + * + * @param string align A horizontal alignment. + * @return string + */ + + + function validateHorizontalAlignment(align) { + var ALIGNMENTS = ['left', 'center', 'right']; + var DEFAULT = acf.get('rtl') ? 'right' : 'left'; + return ALIGNMENTS.includes(align) ? align : DEFAULT; + } + /** + * Returns a valid matrix alignment. + * + * Written for "upgrade-path" compatibility from vertical alignment to matrix alignment. + * + * @date 07/08/2020 + * @since 5.9.0 + * + * @param string align A matrix alignment. + * @return string + */ + + + function validateMatrixAlignment(align) { + var DEFAULT = 'center center'; + + if (align) { + var _align$split = align.split(' '), + _align$split2 = _slicedToArray(_align$split, 2), + y = _align$split2[0], + x = _align$split2[1]; + + return validateVerticalAlignment(y) + ' ' + validateHorizontalAlignment(x); + } + + return DEFAULT; + } // Dependencies. + + + var _wp$blockEditor2 = wp.blockEditor, + AlignmentToolbar = _wp$blockEditor2.AlignmentToolbar, + BlockVerticalAlignmentToolbar = _wp$blockEditor2.BlockVerticalAlignmentToolbar; + var BlockAlignmentMatrixToolbar = wp.blockEditor.__experimentalBlockAlignmentMatrixToolbar || wp.blockEditor.BlockAlignmentMatrixToolbar; // Gutenberg v10.x begins transition from Toolbar components to Control components. + + var BlockAlignmentMatrixControl = wp.blockEditor.__experimentalBlockAlignmentMatrixControl || wp.blockEditor.BlockAlignmentMatrixControl; + /** + * Appends extra attributes for block types that support align_content. + * + * @date 08/07/2020 + * @since 5.9.0 + * + * @param object attributes The block type attributes. + * @return object + */ + + function withAlignContentAttributes(attributes) { + attributes.align_content = { + type: 'string' + }; + return attributes; + } + /** + * A higher order component adding align_content editing functionality. + * + * @date 08/07/2020 + * @since 5.9.0 + * + * @param component OriginalBlockEdit The original BlockEdit component. + * @param object blockType The block type settings. + * @return component + */ + + + function withAlignContentComponent(OriginalBlockEdit, blockType) { + // Determine alignment vars + var type = blockType.supports.align_content; + var AlignmentComponent, validateAlignment; + + switch (type) { + case 'matrix': + AlignmentComponent = BlockAlignmentMatrixControl || BlockAlignmentMatrixToolbar; + validateAlignment = validateMatrixAlignment; + break; + + default: + AlignmentComponent = BlockVerticalAlignmentToolbar; + validateAlignment = validateVerticalAlignment; + break; + } // Ensure alignment component exists. + + + if (AlignmentComponent === undefined) { + console.warn("The \"".concat(type, "\" alignment component was not found.")); + return OriginalBlockEdit; + } // Ensure correct block attribute data is sent in intial preview AJAX request. + + + blockType.align_content = validateAlignment(blockType.align_content); // Return wrapped component. + + return /*#__PURE__*/function (_Component7) { + _inherits(WrappedBlockEdit, _Component7); + + var _super9 = _createSuper(WrappedBlockEdit); + + function WrappedBlockEdit() { + _classCallCheck(this, WrappedBlockEdit); + + return _super9.apply(this, arguments); + } + + _createClass(WrappedBlockEdit, [{ + key: "render", + value: function render() { + var _this$props6 = this.props, + attributes = _this$props6.attributes, + setAttributes = _this$props6.setAttributes; + var align_content = attributes.align_content; + + function onChangeAlignContent(align_content) { + setAttributes({ + align_content: validateAlignment(align_content) + }); + } + + return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(BlockControls, { + group: "block" + }, /*#__PURE__*/React.createElement(AlignmentComponent, { + label: acf.__('Change content alignment'), + value: validateAlignment(align_content), + onChange: onChangeAlignContent + })), /*#__PURE__*/React.createElement(OriginalBlockEdit, this.props)); + } + }]); + + return WrappedBlockEdit; + }(Component); + } + /** + * Appends extra attributes for block types that support align_text. + * + * @date 08/07/2020 + * @since 5.9.0 + * + * @param object attributes The block type attributes. + * @return object + */ + + + function withAlignTextAttributes(attributes) { + attributes.align_text = { + type: 'string' + }; + return attributes; + } + /** + * A higher order component adding align_text editing functionality. + * + * @date 08/07/2020 + * @since 5.9.0 + * + * @param component OriginalBlockEdit The original BlockEdit component. + * @param object blockType The block type settings. + * @return component + */ + + + function withAlignTextComponent(OriginalBlockEdit, blockType) { + var validateAlignment = validateHorizontalAlignment; // Ensure correct block attribute data is sent in intial preview AJAX request. + + blockType.align_text = validateAlignment(blockType.align_text); // Return wrapped component. + + return /*#__PURE__*/function (_Component8) { + _inherits(WrappedBlockEdit, _Component8); + + var _super10 = _createSuper(WrappedBlockEdit); + + function WrappedBlockEdit() { + _classCallCheck(this, WrappedBlockEdit); + + return _super10.apply(this, arguments); + } + + _createClass(WrappedBlockEdit, [{ + key: "render", + value: function render() { + var _this$props7 = this.props, + attributes = _this$props7.attributes, + setAttributes = _this$props7.setAttributes; + var align_text = attributes.align_text; + + function onChangeAlignText(align_text) { + setAttributes({ + align_text: validateAlignment(align_text) + }); + } + + return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(BlockControls, null, /*#__PURE__*/React.createElement(AlignmentToolbar, { + value: validateAlignment(align_text), + onChange: onChangeAlignText + })), /*#__PURE__*/React.createElement(OriginalBlockEdit, this.props)); + } + }]); + + return WrappedBlockEdit; + }(Component); + } +})(jQuery); \ No newline at end of file diff --git a/assets/build/js/pro/acf-pro-blocks-legacy.min.js b/assets/build/js/pro/acf-pro-blocks-legacy.min.js new file mode 100755 index 0000000..eeb569d --- /dev/null +++ b/assets/build/js/pro/acf-pro-blocks-legacy.min.js @@ -0,0 +1 @@ +"use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _slicedToArray(e,t){return _arrayWithHoles(e)||_iterableToArrayLimit(e,t)||_unsupportedIterableToArray(e,t)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(r="Object"===r&&e.constructor?e.constructor.name:r)||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r".concat(e,"<\/script>"))}},{key:"componentDidUpdate",value:function(){this.setHTML(this.props.children)}},{key:"componentDidMount",value:function(){this.setHTML(this.props.children)}}]),t}(),A={},P=function(){_inherits(n,h);var r=_createSuper(n);function n(e){var t;return _classCallCheck(this,n),(t=r.call(this,e)).setRef=t.setRef.bind(_assertThisInitialized(t)),t.id="",t.el=!1,t.subscribed=!0,t.renderMethod="jQuery",t.setup(e),t.loadState(),t}return _createClass(n,[{key:"setup",value:function(e){}},{key:"fetch",value:function(){}},{key:"maybePreload",value:function(e){if(this.state.html===s){var t=acf.get("preloadedBlocks");if(t&&t[e])return this.setHtml(t[e]),delete t[e],acf.set("preloadedBlocks",t),!0}return!1}},{key:"loadState",value:function(){this.state=A[this.id]||{}}},{key:"setState",value:function(e){A[this.id]=_objectSpread(_objectSpread({},this.state),e),this.subscribed&&_get(_getPrototypeOf(n.prototype),"setState",this).call(this,e)}},{key:"setHtml",value:function(e){var t;(e=e?e.trim():"")!==this.state.html&&(t={html:e},"jsx"===this.renderMethod?(t.jsx=acf.parseJSX(e),t.$el=o(this.el)):t.$el=o(e),this.setState(t))}},{key:"setRef",value:function(e){this.el=e}},{key:"render",value:function(){return this.state.jsx?React.createElement("div",{ref:this.setRef},this.state.jsx):React.createElement("div",{ref:this.setRef},React.createElement(i,null,React.createElement(p,null)))}},{key:"shouldComponentUpdate",value:function(e,t){return e.index!==this.props.index&&this.componentWillMove(),t.html!==this.state.html}},{key:"display",value:function(e){var t,r,n;switch("jQuery"===this.renderMethod&&(r=(t=this.state.$el).parent(),(n=o(this.el)).html(t),r.length&&r[0]!==n[0]&&r.html(t.clone())),e){case"append":this.componentDidAppend();break;case"remount":this.componentDidRemount()}}},{key:"componentDidMount",value:function(){this.state.html===s?this.fetch():this.display("remount")}},{key:"componentDidUpdate",value:function(e,t){this.display("append")}},{key:"componentDidAppend",value:function(){acf.doAction("append",this.state.$el)}},{key:"componentWillUnmount",value:function(){acf.doAction("unmount",this.state.$el),this.subscribed=!1}},{key:"componentDidRemount",value:function(){var e=this;this.subscribed=!0,setTimeout(function(){acf.doAction("remount",e.state.$el)})}},{key:"componentWillMove",value:function(){var e=this;acf.doAction("unmount",this.state.$el),setTimeout(function(){acf.doAction("remount",e.state.$el)})}}]),n}(),E=function(){_inherits(a,P);var e=_createSuper(a);function a(){return _classCallCheck(this,a),e.apply(this,arguments)}return _createClass(a,[{key:"setup",value:function(e){this.id="BlockForm-".concat(e.attributes.id)}},{key:"fetch",value:function(){var t=this,e=this.props.attributes;this.maybePreload(e.id)||k({attributes:e,query:{form:!0}}).done(function(e){t.setHtml(e.data.form)})}},{key:"componentDidAppend",value:function(){_get(_getPrototypeOf(a.prototype),"componentDidAppend",this).call(this);var e=this.props,r=e.attributes,n=e.setAttributes,i=this.state.$el;function t(){var e=0 0) { var ruleName = s.substr(0, pos).trim(); var ruleValue = s.substr(pos + 1).trim(); // Rename core properties, but not CSS variables. - if (ruleName.charAt(0) !== '-') { + if (ruleName.charAt(0) !== "-") { ruleName = acf.strCamelCase(ruleName); } @@ -824,7 +839,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope default: // No formatting needed for "data-x" attributes. - if (name.indexOf('data-') === 0) { + if (name.indexOf("data-") === 0) { break; } // Replace names for JSX counterparts. @@ -833,13 +848,13 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope var c1 = value.charAt(0); - if (c1 === '[' || c1 === '{') { + if (c1 === "[" || c1 === "{") { value = JSON.parse(value); } // Convert bool values. - if (value === 'true' || value === 'false') { - value = value === 'true'; + if (value === "true" || value === "false") { + value = value === "true"; } break; @@ -852,8 +867,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope } /** * Higher Order Component used to set default block attribute values. - * - * By modifying block attributes directly, instead of defining defaults in registerBlockType(), + * + * By modifying block attributes directly, instead of defining defaults in registerBlockType(), * WordPress will include them always within the saved block serialized JSON. * * @date 31/07/2020 @@ -889,7 +904,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope if (isNewBlock(props)) { - attributes.id = acf.uniqid('block_'); + attributes.id = acf.uniqid("block_"); for (var attribute in blockType.attributes) { if (attributes[attribute] === undefined && blockType[attribute] !== undefined) { @@ -902,7 +917,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope if (isDuplicateBlock(props)) { - attributes.id = acf.uniqid('block_'); + attributes.id = acf.uniqid("block_"); return _possibleConstructorReturn(_this); } @@ -918,8 +933,8 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope return WrappedBlockEdit; }(Component); - }, 'withDefaultAttributes'); - wp.hooks.addFilter('editor.BlockListBlock', 'acf/with-default-attributes', withDefaultAttributes); + }, "withDefaultAttributes"); + wp.hooks.addFilter("editor.BlockListBlock", "acf/with-default-attributes", withDefaultAttributes); /** * The BlockSave functional component. * @@ -964,22 +979,22 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope var blockType = getBlockType(name); // Restrict current mode. function restrictMode(modes) { - if (modes.indexOf(attributes.mode) === -1) { + if (!modes.includes(attributes.mode)) { attributes.mode = modes[0]; } } switch (blockType.mode) { - case 'edit': - restrictMode(['edit', 'preview']); + case "edit": + restrictMode(["edit", "preview"]); break; - case 'preview': - restrictMode(['preview', 'edit']); + case "preview": + restrictMode(["preview", "edit"]); break; default: - restrictMode(['auto']); + restrictMode(["auto"]); break; } } @@ -995,27 +1010,27 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope var showToggle = blockType.supports.mode; - if (mode === 'auto') { + if (mode === "auto") { showToggle = false; } // Configure toggle variables. - var toggleText = mode === 'preview' ? acf.__('Switch to Edit') : acf.__('Switch to Preview'); - var toggleIcon = mode === 'preview' ? 'edit' : 'welcome-view-site'; + var toggleText = mode === "preview" ? acf.__("Switch to Edit") : acf.__("Switch to Preview"); + var toggleIcon = mode === "preview" ? "edit" : "welcome-view-site"; function toggleMode() { setAttributes({ - mode: mode === 'preview' ? 'edit' : 'preview' + mode: mode === "preview" ? "edit" : "preview" }); } // Return template. - return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(BlockControls, null, showToggle && /*#__PURE__*/React.createElement(Toolbar, null, /*#__PURE__*/React.createElement(IconButton, { + return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement(BlockControls, null, showToggle && /*#__PURE__*/React.createElement(ToolbarGroup, null, /*#__PURE__*/React.createElement(ToolbarButton, { className: "components-icon-button components-toolbar__control", label: toggleText, icon: toggleIcon, onClick: toggleMode - }))), /*#__PURE__*/React.createElement(InspectorControls, null, mode === 'preview' && /*#__PURE__*/React.createElement("div", { + }))), /*#__PURE__*/React.createElement(InspectorControls, null, mode === "preview" && /*#__PURE__*/React.createElement("div", { className: "acf-block-component acf-block-panel" }, /*#__PURE__*/React.createElement(BlockForm, this.props))), /*#__PURE__*/React.createElement(BlockBody, this.props)); } @@ -1024,46 +1039,29 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope return BlockEdit; }(Component); /** - * The BlockBody component. + * The BlockBody functional component. * * @date 19/2/19 * @since 5.7.12 */ - var _BlockBody = /*#__PURE__*/function (_Component3) { - _inherits(_BlockBody, _Component3); - - var _super3 = _createSuper(_BlockBody); - - function _BlockBody() { - _classCallCheck(this, _BlockBody); - - return _super3.apply(this, arguments); - } - - _createClass(_BlockBody, [{ - key: "render", - value: function render() { - var _this$props4 = this.props, - attributes = _this$props4.attributes, - isSelected = _this$props4.isSelected; - var mode = attributes.mode; - return /*#__PURE__*/React.createElement("div", { - className: "acf-block-component acf-block-body" - }, mode === 'auto' && isSelected ? /*#__PURE__*/React.createElement(BlockForm, this.props) : mode === 'auto' && !isSelected ? /*#__PURE__*/React.createElement(BlockPreview, this.props) : mode === 'preview' ? /*#__PURE__*/React.createElement(BlockPreview, this.props) : /*#__PURE__*/React.createElement(BlockForm, this.props)); - } - }]); - - return _BlockBody; - }(Component); // Append blockIndex to component props. + function _BlockBody(props) { + var wpProps = useBlockProps(); + var attributes = props.attributes, + isSelected = props.isSelected; + var mode = attributes.mode; + return /*#__PURE__*/React.createElement("div", wpProps, /*#__PURE__*/React.createElement("div", { + className: "acf-block-component acf-block-body" + }, mode === "auto" && isSelected ? /*#__PURE__*/React.createElement(BlockForm, props) : mode === "auto" && !isSelected ? /*#__PURE__*/React.createElement(BlockPreview, props) : mode === "preview" ? /*#__PURE__*/React.createElement(BlockPreview, props) : /*#__PURE__*/React.createElement(BlockForm, props))); + } // Append blockIndex to component props. var BlockBody = withSelect(function (select, ownProps) { var clientId = ownProps.clientId; // Use optional rootClientId to allow discoverability of child blocks. - var rootClientId = select('core/block-editor').getBlockRootClientId(clientId); - var index = select('core/block-editor').getBlockIndex(clientId, rootClientId); + var rootClientId = select("core/block-editor").getBlockRootClientId(clientId); + var index = select("core/block-editor").getBlockIndex(clientId, rootClientId); return { index: index }; @@ -1078,15 +1076,15 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope * @return void */ - var Div = /*#__PURE__*/function (_Component4) { - _inherits(Div, _Component4); + var Div = /*#__PURE__*/function (_Component3) { + _inherits(Div, _Component3); - var _super4 = _createSuper(Div); + var _super3 = _createSuper(Div); function Div() { _classCallCheck(this, Div); - return _super4.apply(this, arguments); + return _super3.apply(this, arguments); } _createClass(Div, [{ @@ -1104,7 +1102,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope }(Component); /** * A react Component for inline scripts. - * + * * This Component uses a combination of React references and jQuery to append the * inline - post_type !== 'acf-field-group' ) { - return $post_id; - } - - // only save once! WordPress save's a revision as well. - if( wp_is_post_revision($post_id) ) { - return $post_id; - } - - // verify nonce - if( !acf_verify_nonce('field_group') ) { - return $post_id; - } - - // Bail early if request came from an unauthorised user. - if( !current_user_can(acf_get_setting('capability')) ) { - return $post_id; - } - - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - // save fields - if( !empty($_POST['acf_fields']) ) { - - // loop - foreach( $_POST['acf_fields'] as $field ) { - - // vars - $specific = false; - $save = acf_extract_var( $field, 'save' ); - - - // only saved field if has changed - if( $save == 'meta' ) { - $specific = array( - 'menu_order', - 'post_parent', - ); - } - - // set parent - if( !$field['parent'] ) { - $field['parent'] = $post_id; - } - - // save field - acf_update_field( $field, $specific ); - + + + /* + * save_post + * + * This function will save all the field group data + * + * @type function + * @date 23/06/12 + * @since 1.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function save_post( $post_id, $post ) { + + // do not save if this is an auto save routine + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return $post_id; } - } - - - // delete fields - if( $_POST['_acf_delete_fields'] ) { - - // clean - $ids = explode('|', $_POST['_acf_delete_fields']); - $ids = array_map( 'intval', $ids ); - - - // loop - foreach( $ids as $id ) { - - // bai early if no id - if( !$id ) continue; - - - // delete - acf_delete_field( $id ); - + + // bail early if not acf-field-group + if ( $post->post_type !== 'acf-field-group' ) { + return $post_id; } - - } - - - // add args - $_POST['acf_field_group']['ID'] = $post_id; - $_POST['acf_field_group']['title'] = $_POST['post_title']; - - - // save field group - acf_update_field_group( $_POST['acf_field_group'] ); - - - // return - return $post_id; - } - - - /* - * mb_fields - * - * This function will render the HTML for the medtabox 'acf-field-group-fields' - * - * @type function - * @date 28/09/13 - * @since 5.0.0 - * - * @param N/A - * @return N/A - */ - - function mb_fields() { - - // global - global $field_group; - - - // get fields - $view = array( - 'fields' => acf_get_fields( $field_group ), - 'parent' => 0 - ); - - - // load view - acf_get_view('field-group-fields', $view); - - } - - - /* - * mb_options - * - * This function will render the HTML for the medtabox 'acf-field-group-options' - * - * @type function - * @date 28/09/13 - * @since 5.0.0 - * - * @param N/A - * @return N/A - */ - - function mb_options() { - - // global - global $field_group; - - - // field key (leave in for compatibility) - if( !acf_is_field_group_key( $field_group['key']) ) { - - $field_group['key'] = uniqid('group_'); - + + // only save once! WordPress save's a revision as well. + if ( wp_is_post_revision( $post_id ) ) { + return $post_id; + } + + // verify nonce + if ( ! acf_verify_nonce( 'field_group' ) ) { + return $post_id; + } + + // Bail early if request came from an unauthorised user. + if ( ! current_user_can( acf_get_setting( 'capability' ) ) ) { + return $post_id; + } + + // disable filters to ensure ACF loads raw data from DB + acf_disable_filters(); + + // save fields + if ( ! empty( $_POST['acf_fields'] ) ) { + + // loop + foreach ( $_POST['acf_fields'] as $field ) { + + // vars + $specific = false; + $save = acf_extract_var( $field, 'save' ); + + // only saved field if has changed + if ( $save == 'meta' ) { + $specific = array( + 'menu_order', + 'post_parent', + ); + } + + // set parent + if ( ! $field['parent'] ) { + $field['parent'] = $post_id; + } + + // save field + acf_update_field( $field, $specific ); + + } + } + + // delete fields + if ( $_POST['_acf_delete_fields'] ) { + + // clean + $ids = explode( '|', $_POST['_acf_delete_fields'] ); + $ids = array_map( 'intval', $ids ); + + // loop + foreach ( $ids as $id ) { + + // bai early if no id + if ( ! $id ) { + continue; + } + + // delete + acf_delete_field( $id ); + + } + } + + // add args + $_POST['acf_field_group']['ID'] = $post_id; + $_POST['acf_field_group']['title'] = $_POST['post_title']; + + // save field group + acf_update_field_group( $_POST['acf_field_group'] ); + + // return + return $post_id; } - - - // view - acf_get_view('field-group-options'); - - } - - - /* - * mb_locations - * - * This function will render the HTML for the medtabox 'acf-field-group-locations' - * - * @type function - * @date 28/09/13 - * @since 5.0.0 - * - * @param N/A - * @return N/A - */ - - function mb_locations() { - - // global - global $field_group; - - - // UI needs at lease 1 location rule - if( empty($field_group['location']) ) { - - $field_group['location'] = array( - - // group 0 - array( - - // rule 0 - array( - 'param' => 'post_type', - 'operator' => '==', - 'value' => 'post', - ) - ) - + + + /* + * mb_fields + * + * This function will render the HTML for the medtabox 'acf-field-group-fields' + * + * @type function + * @date 28/09/13 + * @since 5.0.0 + * + * @param N/A + * @return N/A + */ + + function mb_fields() { + + // global + global $field_group; + + // get fields + $view = array( + 'fields' => acf_get_fields( $field_group ), + 'parent' => 0, ); + + // load view + acf_get_view( 'field-group-fields', $view ); + } - - - // view - acf_get_view('field-group-locations'); - - } - - - /* - * ajax_render_location_rule - * - * This function can be accessed via an AJAX action and will return the result from the render_location_value function - * - * @type function (ajax) - * @date 30/09/13 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function ajax_render_location_rule() { - - // validate - if( !acf_verify_ajax() ) die(); - - // validate rule - $rule = acf_validate_location_rule($_POST['rule']); - - // view - acf_get_view( 'html-location-rule', array( - 'rule' => $rule - )); - - // die - die(); - } - - - /* - * ajax_render_field_settings - * - * This function will return HTML containing the field's settings based on it's new type - * - * @type function (ajax) - * @date 30/09/13 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function ajax_render_field_settings() { - - // validate - if( !acf_verify_ajax() ) die(); - - // vars - $field = acf_maybe_get_POST('field'); - - // check - if( !$field ) die(); - - // set prefix - $field['prefix'] = acf_maybe_get_POST('prefix'); - - // validate - $field = acf_get_valid_field( $field ); - - // render - do_action("acf/render_field_settings/type={$field['type']}", $field); - - // return - die(); - - } - - /* - * ajax_move_field - * - * description - * - * @type function - * @date 20/01/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_move_field() { - - // disable filters to ensure ACF loads raw data from DB - acf_disable_filters(); - - - $args = acf_parse_args($_POST, array( - 'nonce' => '', - 'post_id' => 0, - 'field_id' => 0, - 'field_group_id' => 0 - )); - - - // verify nonce - if( !wp_verify_nonce($args['nonce'], 'acf_nonce') ) die(); - - - // confirm? - if( $args['field_id'] && $args['field_group_id'] ) { - - // vars - $field = acf_get_field($args['field_id']); - $field_group = acf_get_field_group($args['field_group_id']); - - - // update parent - $field['parent'] = $field_group['ID']; - - - // remove conditional logic - $field['conditional_logic'] = 0; - - - // update field - acf_update_field($field); - - - // Output HTML. - $link = '' . esc_html( $field_group['title'] ) . ''; - - echo '' . - '

              ' . __( 'Move Complete.', 'acf' ) . '

              ' . - '

              ' . sprintf( - acf_punctify( __( 'The %s field can now be found in the %s field group', 'acf' ) ), - esc_html( $field['label'] ), - $link - ). '

              ' . - '' . __( 'Close Window', 'acf' ) . ''; + + + /* + * mb_options + * + * This function will render the HTML for the medtabox 'acf-field-group-options' + * + * @type function + * @date 28/09/13 + * @since 5.0.0 + * + * @param N/A + * @return N/A + */ + + function mb_options() { + + // global + global $field_group; + + // field key (leave in for compatibility) + if ( ! acf_is_field_group_key( $field_group['key'] ) ) { + + $field_group['key'] = uniqid( 'group_' ); + + } + + // view + acf_get_view( 'field-group-options' ); + + } + + + /* + * mb_locations + * + * This function will render the HTML for the medtabox 'acf-field-group-locations' + * + * @type function + * @date 28/09/13 + * @since 5.0.0 + * + * @param N/A + * @return N/A + */ + + function mb_locations() { + + // global + global $field_group; + + // UI needs at lease 1 location rule + if ( empty( $field_group['location'] ) ) { + + $field_group['location'] = array( + + // group 0 + array( + + // rule 0 + array( + 'param' => 'post_type', + 'operator' => '==', + 'value' => 'post', + ), + ), + + ); + } + + // view + acf_get_view( 'field-group-locations' ); + + } + + + /* + * ajax_render_location_rule + * + * This function can be accessed via an AJAX action and will return the result from the render_location_value function + * + * @type function (ajax) + * @date 30/09/13 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function ajax_render_location_rule() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // verify user capability + if ( ! acf_current_user_can_admin() ) { + die(); + } + + // validate rule + $rule = acf_validate_location_rule( $_POST['rule'] ); + + // view + acf_get_view( + 'html-location-rule', + array( + 'rule' => $rule, + ) + ); + + // die die(); } - - - // get all field groups - $field_groups = acf_get_field_groups(); - $choices = array(); - - - // check - if( !empty($field_groups) ) { - - // loop - foreach( $field_groups as $field_group ) { - - // bail early if no ID - if( !$field_group['ID'] ) continue; - - - // bail ealry if is current - if( $field_group['ID'] == $args['post_id'] ) continue; - - - // append - $choices[ $field_group['ID'] ] = $field_group['title']; - - } - - } - - - // render options - $field = acf_get_valid_field(array( - 'type' => 'select', - 'name' => 'acf_field_group', - 'choices' => $choices - )); - - - echo '

              ' . __('Please select the destination for this field', 'acf') . '

              '; - - echo '
              '; - - // render - acf_render_field_wrap( $field ); - - echo ''; - - echo ''; - - - // die - die(); - - } - -} -// initialize -new acf_admin_field_group(); + + /* + * ajax_render_field_settings + * + * This function will return HTML containing the field's settings based on it's new type + * + * @type function (ajax) + * @date 30/09/13 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function ajax_render_field_settings() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // verify user capability + if ( ! acf_current_user_can_admin() ) { + die(); + } + + // vars + $field = acf_maybe_get_POST( 'field' ); + + // check + if ( ! $field ) { + die(); + } + + // set prefix + $field['prefix'] = acf_maybe_get_POST( 'prefix' ); + + // validate + $field = acf_get_valid_field( $field ); + + // render + do_action( "acf/render_field_settings/type={$field['type']}", $field ); + + // return + die(); + + } + + /* + * ajax_move_field + * + * description + * + * @type function + * @date 20/01/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_move_field() { + + // disable filters to ensure ACF loads raw data from DB + acf_disable_filters(); + + $args = acf_parse_args( + $_POST, + array( + 'nonce' => '', + 'post_id' => 0, + 'field_id' => 0, + 'field_group_id' => 0, + ) + ); + + // verify nonce + if ( ! wp_verify_nonce( $args['nonce'], 'acf_nonce' ) ) { + die(); + } + + // verify user capability + if ( ! acf_current_user_can_admin() ) { + die(); + } + + // confirm? + if ( $args['field_id'] && $args['field_group_id'] ) { + + // vars + $field = acf_get_field( $args['field_id'] ); + $field_group = acf_get_field_group( $args['field_group_id'] ); + + // update parent + $field['parent'] = $field_group['ID']; + + // remove conditional logic + $field['conditional_logic'] = 0; + + // update field + acf_update_field( $field ); + + // Output HTML. + $link = '' . esc_html( $field_group['title'] ) . ''; + + echo '' . + '

              ' . __( 'Move Complete.', 'acf' ) . '

              ' . + '

              ' . sprintf( + acf_punctify( __( 'The %1$s field can now be found in the %2$s field group', 'acf' ) ), + esc_html( $field['label'] ), + $link + ) . '

              ' . + '' . __( 'Close Window', 'acf' ) . ''; + die(); + } + + // get all field groups + $field_groups = acf_get_field_groups(); + $choices = array(); + + // check + if ( ! empty( $field_groups ) ) { + + // loop + foreach ( $field_groups as $field_group ) { + + // bail early if no ID + if ( ! $field_group['ID'] ) { + continue; + } + + // bail ealry if is current + if ( $field_group['ID'] == $args['post_id'] ) { + continue; + } + + // append + $choices[ $field_group['ID'] ] = $field_group['title']; + + } + } + + // render options + $field = acf_get_valid_field( + array( + 'type' => 'select', + 'name' => 'acf_field_group', + 'choices' => $choices, + ) + ); + + echo '

              ' . __( 'Please select the destination for this field', 'acf' ) . '

              '; + + echo '
              '; + + // render + acf_render_field_wrap( $field ); + + echo ''; + + echo ''; + + // die + die(); + + } + + } + + // initialize + new acf_admin_field_group(); endif; -?> \ No newline at end of file +?> diff --git a/includes/admin/admin-field-groups.php b/includes/admin/admin-field-groups.php index 89a51d0..a8b5575 100644 --- a/includes/admin/admin-field-groups.php +++ b/includes/admin/admin-field-groups.php @@ -1,713 +1,719 @@ -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 (%s)', 'Active (%s)', '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 ); + /** + * 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' ) ); } - // Add hooks for "sync" view. - if( $this->view === 'sync' ) { - add_action( 'admin_footer', array( $this, 'admin_footer__sync' ), 1 ); + /** + * 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}" ); } - } - - /** - * 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; + + /** + * 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 (%s)', 'Active (%s)', '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}"; + + /** + * 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' ), + ) + ); } - 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 ' ' . _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(); + + /** + * 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; } - 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'); + + /** + * 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 ' ' . _x( 'Disabled', 'post status', '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 ); + + /** + * 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; } - } - - /** - * 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 '' . acf_esc_html( $field_group['description'] ) . ''; - } - 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; + + /** + * 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; } - } - - /** - * 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 ); + + /** + * 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 '' . acf_esc_html( $field_group['description'] ) . ''; } - $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); + 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 ); - } 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; + $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 .= ' '; - - // Labels. - $labels = array_column( $objects, 'label' ); - $labels = array_slice( $labels, 0, 3 ); - $html .= implode(', ', $labels ); - - // More. - if( $total > $limit ) { - $html .= ', ...'; - } - } else { - $html = ' ' . __( '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 '' . __( 'Sync available', 'acf' ) . ''; - if( $field_group['ID'] ) { - echo ''; - } else { - echo ''; + + // Reset keys. + $objects = array_values( $objects ); + + // Display. + $html = ''; + if ( $objects ) { + $limit = 3; + $total = count( $objects ); + + // Icon. + $html .= ' '; + + // Labels. + $labels = array_column( $objects, 'label' ); + $labels = array_slice( $labels, 0, 3 ); + $html .= implode( ', ', $labels ); + + // More. + if ( $total > $limit ) { + $html .= ', ...'; } } else { - echo __( 'Saved', 'acf' ); + $html = ' ' . __( 'Various', 'acf' ); } - } else { - echo '' . __( 'Awaiting save', 'acf' ) . ''; - } - } - - /** - * 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' ] = '' . __( 'Duplicate', 'acf' ) . ''; - - // 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' ); + // Filter. + echo acf_esc_html( $html ); } - - // Add "Sync" action. - if( $this->sync ) { - if( $this->view === 'sync' ) { - $actions = array(); + + /** + * 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 ); } - $actions[ 'acfsync' ] = __( 'Sync changes', 'acf' ); + return $located; } - 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[] = '' . get_the_title( $id ) . ''; - } - $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[] = '' . get_the_title( $id ) . ''; - } - $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. + + /** + * 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 '' . __( 'Sync available', 'acf' ) . ''; + if ( $field_group['ID'] ) { + echo ''; + } else { + echo ''; + } } else { - // Ignore. - continue; + echo __( 'Saved', 'acf' ); } - $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']; + } else { + echo '' . __( 'Awaiting save', 'acf' ) . ''; } - - // 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( - '%s (%s)', - ( $this->view === 'sync' ? 'class="current"' : '' ), - esc_url( $this->get_admin_url( '&post_status=sync' ) ), - esc_html( __('Sync available', 'acf') ), - $count - ); + + /** + * 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'] = '' . __( 'Duplicate', 'acf' ) . ''; + + // Return actions in custom order. + $order = array( 'edit', 'acfduplicate', 'trash' ); + return array_merge( array_flip( $order ), $actions ); } - - // 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. + + /** + * 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; } - return $views; - } - - /** - * Prints scripts into the admin footer. - * - * @date 20/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - function admin_footer() { - ?> + + /** + * 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[] = '' . get_the_title( $id ) . ''; + } + $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[] = '' . get_the_title( $id ) . ''; + } + $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( + '%s (%s)', + ( $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() { + ?> - get_columns(); - $hidden = get_hidden_columns( $wp_list_table->screen ); - ?> + get_columns(); + $hidden = get_hidden_columns( $wp_list_table->screen ); + ?>
                - sync as $k => $field_group ) { - echo ''; - 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 ''; - echo ''; - break; - - // Title. - case 'title': - $post_state = ''; - if( !$field_group['active'] ) { - $post_state = ' — ' . $this->get_disabled_post_state() . ''; + sync as $k => $field_group ) { + echo ''; + 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"; } - echo '' . esc_html( $field_group['title']) . '' . $post_state . ''; - echo '
                ' . $this->get_human_readable_file_location( $field_group['local_file'] ) . '
                '; - echo ''; - break; - - // All other columns. - default: - $this->render_admin_table_column( $column_name, $field_group ); - break; + if ( in_array( $column_name, $hidden, true ) ) { + $classes .= ' hidden'; + } + echo "<$el class=\"$classes\" data-colname=\"$column_label\">"; + switch ( $column_name ) { + + // Checkbox. + case 'cb': + echo ''; + echo ''; + break; + + // Title. + case 'title': + $post_state = ''; + if ( ! $field_group['active'] ) { + $post_state = ' — ' . $this->get_disabled_post_state() . ''; + } + echo '' . esc_html( $field_group['title'] ) . '' . $post_state . ''; + echo '
                ' . $this->get_human_readable_file_location( $field_group['local_file'] ) . '
                '; + echo ''; + break; + + // All other columns. + default: + $this->render_admin_table_column( $column_name, $field_group ); + break; + } + echo ""; + } + echo ''; } - echo ""; - } - echo ''; - } - ?> + ?>
                @@ -824,56 +830,56 @@ class ACF_Admin_Field_Groups { $('#the-list').html( $('#acf-the-list').children() ); })(jQuery); - '', - - /** @type string The type of notice (warning, error, success, info). */ - 'type' => 'info', - - /** @type bool If the notice can be dismissed. */ - 'dismissible' => true, - ); - - /** - * render - * - * Renders the notice HTML. - * - * @date 27/12/18 - * @since 5.8.0 - * - * @param void - * @return void - */ - function render() { - $notice_text = $this->get('text'); - $notice_type = $this->get('type'); - $is_dismissible = $this->get('dismissible'); - - printf('
                %s
                ', - esc_attr( $notice_type ), - $is_dismissible ? 'is-dismissible' : '', - acf_esc_html( wpautop( acf_punctify( $notice_text ) ) ) + class ACF_Admin_Notice extends ACF_Data { + + /** @var array Storage for data. */ + var $data = array( + + /** @type string Text displayed in notice. */ + 'text' => '', + + /** @type string The type of notice (warning, error, success, info). */ + 'type' => 'info', + + /** @type bool If the notice can be dismissed. */ + 'dismissible' => true, ); + + /** + * render + * + * Renders the notice HTML. + * + * @date 27/12/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + function render() { + $notice_text = $this->get( 'text' ); + $notice_type = $this->get( 'type' ); + $is_dismissible = $this->get( 'dismissible' ); + + printf( + '
                %s
                ', + esc_attr( $notice_type ), + $is_dismissible ? 'is-dismissible' : '', + acf_esc_html( wpautop( acf_punctify( $notice_text ) ) ) + ); + } } -} endif; // class_exists check /** -* acf_new_admin_notice -* -* Instantiates and returns a new model. -* -* @date 23/12/18 -* @since 5.8.0 -* -* @param array $data Optional data to set. -* @return ACF_Admin_Notice -*/ + * acf_new_admin_notice + * + * Instantiates and returns a new model. + * + * @date 23/12/18 + * @since 5.8.0 + * + * @param array $data Optional data to set. + * @return ACF_Admin_Notice + */ function acf_new_admin_notice( $data = false ) { - + // Create notice. $instance = new ACF_Admin_Notice( $data ); - + // Register notice. acf_get_store( 'notices' )->set( $instance->cid, $instance ); - + // Return notice. return $instance; } @@ -93,40 +96,45 @@ function acf_new_admin_notice( $data = false ) { * * Renders all admin notices HTML. * - * @date 10/1/19 - * @since 5.7.10 + * @date 10/1/19 + * @since 5.7.10 * - * @param void - * @return void + * @param void + * @return void */ function acf_render_admin_notices() { - + // Get notices. $notices = acf_get_store( 'notices' )->get_data(); - + // Loop over notices and render. - if( $notices ) { - foreach( $notices as $notice ) { + if ( $notices ) { + foreach ( $notices as $notice ) { $notice->render(); } } } // Render notices during admin action. -add_action('admin_notices', 'acf_render_admin_notices', 99); +add_action( 'admin_notices', 'acf_render_admin_notices', 99 ); /** * acf_add_admin_notice * * Creates and returns a new notice. * - * @date 17/10/13 - * @since 5.0.0 + * @date 17/10/13 + * @since 5.0.0 * - * @param string $text The admin notice text. - * @param string $class The type of notice (warning, error, success, info). - * @return ACF_Admin_Notice + * @param string $text The admin notice text. + * @param string $class The type of notice (warning, error, success, info). + * @return ACF_Admin_Notice */ function acf_add_admin_notice( $text = '', $type = 'info' ) { - return acf_new_admin_notice( array( 'text' => $text, 'type' => $type ) ); -} \ No newline at end of file + return acf_new_admin_notice( + array( + 'text' => $text, + 'type' => $type, + ) + ); +} diff --git a/includes/admin/admin-tools.php b/includes/admin/admin-tools.php index 5462b89..2fe04ba 100644 --- a/includes/admin/admin-tools.php +++ b/includes/admin/admin-tools.php @@ -1,291 +1,285 @@ -tools[ $instance->name ] = $instance; - - } - - - /** - * get_tool - * - * This function will return a tool tool class - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param string $name - * @return n/a - */ - - function get_tool( $name ) { - - return isset( $this->tools[$name] ) ? $this->tools[$name] : null; - - } - - - /** - * get_tools - * - * This function will return an array of all tools - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return array - */ - - function get_tools() { - - return $this->tools; - - } - - - /* - * admin_menu - * - * This function will add the ACF menu item to the WP admin - * - * @type action (admin_menu) - * @date 28/09/13 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function admin_menu() { - - // bail early if no show_admin - if( !acf_get_setting('show_admin') ) return; - - - // add page - $page = add_submenu_page('edit.php?post_type=acf-field-group', __('Tools','acf'), __('Tools','acf'), acf_get_setting('capability'), 'acf-tools', array($this, 'html')); - - - // actions - add_action('load-' . $page, array($this, 'load')); - - } - - - /** - * load - * - * description - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function load() { - - // disable filters (default to raw data) - acf_disable_filters(); - - - // include tools - $this->include_tools(); - - - // check submit - $this->check_submit(); - - - // load acf scripts - acf_enqueue_scripts(); - - } - - - /** - * include_tools - * - * description - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function include_tools() { - - // include - acf_include('includes/admin/tools/class-acf-admin-tool.php'); - acf_include('includes/admin/tools/class-acf-admin-tool-export.php'); - acf_include('includes/admin/tools/class-acf-admin-tool-import.php'); - - - // action - do_action('acf/include_admin_tools'); - - } - - - /** - * check_submit - * - * description - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function check_submit() { - - // loop - foreach( $this->get_tools() as $tool ) { - - // load - $tool->load(); - - - // submit - if( acf_verify_nonce($tool->name) ) { - $tool->submit(); + class acf_admin_tools { + + + /** @var array Contains an array of admin tool instances */ + var $tools = array(); + + + /** @var string The active tool */ + var $active = ''; + + + /** + * __construct + * + * This function will setup the class functionality + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // actions + add_action( 'admin_menu', array( $this, 'admin_menu' ) ); + + } + + + /** + * register_tool + * + * This function will store a tool tool class + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param string $class + * @return n/a + */ + + function register_tool( $class ) { + + $instance = new $class(); + $this->tools[ $instance->name ] = $instance; + + } + + + /** + * get_tool + * + * This function will return a tool tool class + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param string $name + * @return n/a + */ + + function get_tool( $name ) { + + return isset( $this->tools[ $name ] ) ? $this->tools[ $name ] : null; + + } + + + /** + * get_tools + * + * This function will return an array of all tools + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return array + */ + + function get_tools() { + + return $this->tools; + + } + + + /* + * admin_menu + * + * This function will add the ACF menu item to the WP admin + * + * @type action (admin_menu) + * @date 28/09/13 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function admin_menu() { + + // bail early if no show_admin + if ( ! acf_get_setting( 'show_admin' ) ) { + return; } - + + // add page + $page = add_submenu_page( 'edit.php?post_type=acf-field-group', __( 'Tools', 'acf' ), __( 'Tools', 'acf' ), acf_get_setting( 'capability' ), 'acf-tools', array( $this, 'html' ) ); + + // actions + add_action( 'load-' . $page, array( $this, 'load' ) ); + } - - } - - - /** - * html - * - * description - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function html() { - - // vars - $screen = get_current_screen(); - $active = acf_maybe_get_GET('tool'); - - - // view - $view = array( - 'screen_id' => $screen->id, - 'active' => $active - ); - - - // register metaboxes - foreach( $this->get_tools() as $tool ) { - - // check active - if( $active && $active !== $tool->name ) continue; - - // add metabox - add_meta_box( 'acf-admin-tool-' . $tool->name, acf_esc_html( $tool->title ), array($this, 'metabox_html'), $screen->id, 'normal', 'default', array('tool' => $tool->name) ); - + + + /** + * load + * + * description + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function load() { + + // disable filters (default to raw data) + acf_disable_filters(); + + // include tools + $this->include_tools(); + + // check submit + $this->check_submit(); + + // load acf scripts + acf_enqueue_scripts(); + } - - - // view - acf_get_view( 'html-admin-tools', $view ); - - } - - - /** - * meta_box_html - * - * description - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function metabox_html( $post, $metabox ) { - - // vars - $tool = $this->get_tool($metabox['args']['tool']); - - - ?> + + + /** + * include_tools + * + * description + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function include_tools() { + + // include + acf_include( 'includes/admin/tools/class-acf-admin-tool.php' ); + acf_include( 'includes/admin/tools/class-acf-admin-tool-export.php' ); + acf_include( 'includes/admin/tools/class-acf-admin-tool-import.php' ); + + // action + do_action( 'acf/include_admin_tools' ); + + } + + + /** + * check_submit + * + * description + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function check_submit() { + + // loop + foreach ( $this->get_tools() as $tool ) { + + // load + $tool->load(); + + // submit + if ( acf_verify_nonce( $tool->name ) ) { + $tool->submit(); + } + } + + } + + + /** + * html + * + * description + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html() { + + // vars + $screen = get_current_screen(); + $active = acf_maybe_get_GET( 'tool' ); + + // view + $view = array( + 'screen_id' => $screen->id, + 'active' => $active, + ); + + // register metaboxes + foreach ( $this->get_tools() as $tool ) { + + // check active + if ( $active && $active !== $tool->name ) { + continue; + } + + // add metabox + add_meta_box( 'acf-admin-tool-' . $tool->name, acf_esc_html( $tool->title ), array( $this, 'metabox_html' ), $screen->id, 'normal', 'default', array( 'tool' => $tool->name ) ); + + } + + // view + acf_get_view( 'html-admin-tools', $view ); + + } + + + /** + * meta_box_html + * + * description + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function metabox_html( $post, $metabox ) { + + // vars + $tool = $this->get_tool( $metabox['args']['tool'] ); + + ?>
                html(); ?> name ); ?>
                - admin_tools = new acf_admin_tools(); + } + + } + + // initialize + acf()->admin_tools = new acf_admin_tools(); endif; // class_exists check @@ -295,18 +289,18 @@ endif; // class_exists check * * alias of acf()->admin_tools->register_tool() * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_register_admin_tool( $class ) { - + return acf()->admin_tools->register_tool( $class ); - + } @@ -315,18 +309,18 @@ function acf_register_admin_tool( $class ) { * * This function will return the admin URL to the tools page * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_get_admin_tools_url() { - - return admin_url('edit.php?post_type=acf-field-group&page=acf-tools'); - + + return admin_url( 'edit.php?post_type=acf-field-group&page=acf-tools' ); + } @@ -335,19 +329,19 @@ function acf_get_admin_tools_url() { * * This function will return the admin URL to the tools page * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_get_admin_tool_url( $tool = '' ) { - - return acf_get_admin_tools_url() . '&tool='.$tool; - + + return acf_get_admin_tools_url() . '&tool=' . $tool; + } -?> \ No newline at end of file +?> diff --git a/includes/admin/admin-upgrade.php b/includes/admin/admin-upgrade.php index e3275cb..fde6349 100644 --- a/includes/admin/admin-upgrade.php +++ b/includes/admin/admin-upgrade.php @@ -1,244 +1,246 @@ - 0 ) ); - if( $sites ) { - - // Unhook action to avoid memory issue (as seen in wp-includes/ms-site.php). - remove_action( 'switch_blog', 'wp_switch_roles_and_user', 1 ); - foreach( $sites as $site ) { - - // Switch site. - switch_to_blog( $site->blog_id ); - - // Check for upgrade. - $site_upgrade = acf_has_upgrade(); - - // Restore site. - // Ideally, we would switch back to the original site at after looping, however, - // the restore_current_blog() is needed to modify global vars. - restore_current_blog(); - - // Check if upgrade was found. - if( $site_upgrade ) { - $upgrade = true; - break; - } - } - add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 ); - } - - // Bail early if no upgrade is needed. - if( !$upgrade ) { - return; - } - - // Add notice. - add_action('network_admin_notices', array($this, 'network_admin_notices')); - - // Add page. - $page = add_submenu_page( - 'index.php', - __('Upgrade Database','acf'), - __('Upgrade Database','acf'), - acf_get_setting('capability'), - 'acf-upgrade-network', - array( $this,'network_admin_html' ) - ); - add_action( "load-$page", array( $this, 'network_admin_load' ) ); - } - - /** - * admin_load - * - * Runs during the loading of the admin page. - * - * @date 24/8/18 - * @since 5.7.4 - * - * @param type $var Description. Default. - * @return type Description. - */ - function admin_load() { - - // remove prompt - remove_action('admin_notices', array($this, 'admin_notices')); - - // Enqueue core script. - acf_enqueue_script( 'acf' ); - } - - /** - * network_admin_load - * - * Runs during the loading of the network admin page. - * - * @date 24/8/18 - * @since 5.7.4 - * - * @param type $var Description. Default. - * @return type Description. - */ - function network_admin_load() { - - // remove prompt - remove_action('network_admin_notices', array($this, 'network_admin_notices')); - - // Enqueue core script. - acf_enqueue_script( 'acf' ); - } - - /** - * admin_notices - * - * Displays the DB Upgrade prompt. - * - * @date 23/8/18 - * @since 5.7.3 - * - * @param void - * @return void - */ - function admin_notices() { - - // vars - $view = array( - 'button_text' => __("Upgrade Database", 'acf'), - 'button_url' => admin_url('index.php?page=acf-upgrade'), - 'confirm' => true - ); - - // view - acf_get_view('html-notice-upgrade', $view); - } - - /** - * network_admin_notices - * - * Displays the DB Upgrade prompt on a multi site. - * - * @date 23/8/18 - * @since 5.7.3 - * - * @param void - * @return void - */ - function network_admin_notices() { - - // vars - $view = array( - 'button_text' => __("Review sites & upgrade", 'acf'), - 'button_url' => network_admin_url('index.php?page=acf-upgrade-network'), - 'confirm' => false - ); - - // view - acf_get_view('html-notice-upgrade', $view); - } - - /** - * admin_html - * - * Displays the HTML for the admin page. - * - * @date 24/8/18 - * @since 5.7.4 - * - * @param void - * @return void - */ - function admin_html() { - acf_get_view('html-admin-page-upgrade'); - } - - /** - * network_admin_html - * - * Displays the HTML for the network upgrade admin page. - * - * @date 24/8/18 - * @since 5.7.4 - * - * @param void - * @return void - */ - function network_admin_html() { - acf_get_view('html-admin-page-upgrade-network'); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// instantiate -acf_new_instance('ACF_Admin_Upgrade'); +if ( ! class_exists( 'ACF_Admin_Upgrade' ) ) : + + class ACF_Admin_Upgrade { + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param void + * @return void + */ + function __construct() { + + // actions + add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 ); + if ( is_multisite() ) { + add_action( 'network_admin_menu', array( $this, 'network_admin_menu' ), 20 ); + } + } + + /** + * admin_menu + * + * Setus up logic if DB Upgrade is needed on a single site. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ + function admin_menu() { + + // check if upgrade is avaialble + if ( acf_has_upgrade() ) { + + // add notice + add_action( 'admin_notices', array( $this, 'admin_notices' ) ); + + // add page + $page = add_submenu_page( 'index.php', __( 'Upgrade Database', 'acf' ), __( 'Upgrade Database', 'acf' ), acf_get_setting( 'capability' ), 'acf-upgrade', array( $this, 'admin_html' ) ); + + // actions + add_action( 'load-' . $page, array( $this, 'admin_load' ) ); + } + } + + /** + * network_admin_menu + * + * Sets up admin logic if DB Upgrade is required on a multi site. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ + function network_admin_menu() { + + // Vars. + $upgrade = false; + + // Loop over sites and check for upgrades. + $sites = get_sites( array( 'number' => 0 ) ); + if ( $sites ) { + + // Unhook action to avoid memory issue (as seen in wp-includes/ms-site.php). + remove_action( 'switch_blog', 'wp_switch_roles_and_user', 1 ); + foreach ( $sites as $site ) { + + // Switch site. + switch_to_blog( $site->blog_id ); + + // Check for upgrade. + $site_upgrade = acf_has_upgrade(); + + // Restore site. + // Ideally, we would switch back to the original site at after looping, however, + // the restore_current_blog() is needed to modify global vars. + restore_current_blog(); + + // Check if upgrade was found. + if ( $site_upgrade ) { + $upgrade = true; + break; + } + } + add_action( 'switch_blog', 'wp_switch_roles_and_user', 1, 2 ); + } + + // Bail early if no upgrade is needed. + if ( ! $upgrade ) { + return; + } + + // Add notice. + add_action( 'network_admin_notices', array( $this, 'network_admin_notices' ) ); + + // Add page. + $page = add_submenu_page( + 'index.php', + __( 'Upgrade Database', 'acf' ), + __( 'Upgrade Database', 'acf' ), + acf_get_setting( 'capability' ), + 'acf-upgrade-network', + array( $this, 'network_admin_html' ) + ); + add_action( "load-$page", array( $this, 'network_admin_load' ) ); + } + + /** + * admin_load + * + * Runs during the loading of the admin page. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param type $var Description. Default. + * @return type Description. + */ + function admin_load() { + + // remove prompt + remove_action( 'admin_notices', array( $this, 'admin_notices' ) ); + + // Enqueue core script. + acf_enqueue_script( 'acf' ); + } + + /** + * network_admin_load + * + * Runs during the loading of the network admin page. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param type $var Description. Default. + * @return type Description. + */ + function network_admin_load() { + + // remove prompt + remove_action( 'network_admin_notices', array( $this, 'network_admin_notices' ) ); + + // Enqueue core script. + acf_enqueue_script( 'acf' ); + } + + /** + * admin_notices + * + * Displays the DB Upgrade prompt. + * + * @date 23/8/18 + * @since 5.7.3 + * + * @param void + * @return void + */ + function admin_notices() { + + // vars + $view = array( + 'button_text' => __( 'Upgrade Database', 'acf' ), + 'button_url' => admin_url( 'index.php?page=acf-upgrade' ), + 'confirm' => true, + ); + + // view + acf_get_view( 'html-notice-upgrade', $view ); + } + + /** + * network_admin_notices + * + * Displays the DB Upgrade prompt on a multi site. + * + * @date 23/8/18 + * @since 5.7.3 + * + * @param void + * @return void + */ + function network_admin_notices() { + + // vars + $view = array( + 'button_text' => __( 'Review sites & upgrade', 'acf' ), + 'button_url' => network_admin_url( 'index.php?page=acf-upgrade-network' ), + 'confirm' => false, + ); + + // view + acf_get_view( 'html-notice-upgrade', $view ); + } + + /** + * admin_html + * + * Displays the HTML for the admin page. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ + function admin_html() { + acf_get_view( 'html-admin-page-upgrade' ); + } + + /** + * network_admin_html + * + * Displays the HTML for the network upgrade admin page. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ + function network_admin_html() { + acf_get_view( 'html-admin-page-upgrade-network' ); + } + } + + // instantiate + acf_new_instance( 'ACF_Admin_Upgrade' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/admin/admin.php b/includes/admin/admin.php index d27d175..8af062b 100644 --- a/includes/admin/admin.php +++ b/includes/admin/admin.php @@ -1,207 +1,209 @@ -= 5.3 ) { - $classes .= ' acf-admin-5-3'; - } else { - $classes .= ' acf-admin-3-8'; - } - - // Add browser for specific CSS. - $classes .= ' acf-browser-' . acf_get_browser(); - - // Return classes. - return $classes; - } - - /** - * Adds custom functionality to "ACF" admin pages. - * - * @date 7/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - function current_screen( $screen ) { - - // Determine if the current page being viewed is "ACF" related. - if( isset( $screen->post_type ) && $screen->post_type === 'acf-field-group' ) { - add_action( 'in_admin_header', array( $this, 'in_admin_header' ) ); - add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ) ); - $this->setup_help_tab(); - } - } - - /** - * Sets up the admin help tab. - * - * @date 20/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - public function setup_help_tab() { - $screen = get_current_screen(); - - // Overview tab. - $screen->add_help_tab( - array( - 'id' => 'overview', - 'title' => __( 'Overview', 'acf' ), - 'content' => - '

                ' . __( 'Overview', 'acf' ) . '

                ' . - '

                ' . __( 'The Advanced Custom Fields plugin provides a visual form builder to customize WordPress edit screens with extra fields, and an intuitive API to display custom field values in any theme template file.', 'acf' ) . '

                ' . - '

                ' . sprintf( - __( 'Before creating your first Field Group, we recommend first reading our Getting started guide to familiarize yourself with the plugin\'s philosophy and best practises.', 'acf' ), - 'https://www.advancedcustomfields.com/resources/getting-started-with-acf/' - ) . '

                ' . - '

                ' . __( 'Please use the Help & Support tab to get in touch should you find yourself requiring assistance.', 'acf' ) . '

                ' . - '' - ) - ); - - // Help tab. - $screen->add_help_tab( - array( - 'id' => 'help', - 'title' => __( 'Help & Support', 'acf' ), - 'content' => - '

                ' . __( 'Help & Support', 'acf' ) . '

                ' . - '

                ' . __( 'We are fanatical about support, and want you to get the best out of your website with ACF. If you run into any difficulties, there are several places you can find help:', 'acf' ) . '

                ' . - '
                  ' . - '
                • ' . sprintf( - __( 'Documentation. Our extensive documentation contains references and guides for most situations you may encounter.', 'acf' ), - 'https://www.advancedcustomfields.com/resources/' - ) . '
                • ' . - '
                • ' . sprintf( - __( 'Discussions. We have an active and friendly community on our Community Forums who may be able to help you figure out the ‘how-tos’ of the ACF world.', 'acf' ), - 'https://support.advancedcustomfields.com/' - ) . '
                • ' . - '
                • ' . sprintf( - __( 'Help Desk. The support professionals on our Help Desk will assist with your more in depth, technical challenges.', 'acf' ), - 'https://www.advancedcustomfields.com/support/' - ) . '
                • ' . - '
                ' - ) - ); - - // Sidebar. - $screen->set_help_sidebar( - '

                ' . __( 'Information', 'acf' ) . '

                ' . - '

                ' . sprintf( __( 'Version %s', 'acf' ), ACF_VERSION ) . '

                ' . - '

                ' . __( 'View details', 'acf' ) . '

                ' . - '

                ' . __( 'Visit website', 'acf' ) . '

                ' . - '' - ); - } - - /** - * Renders the admin navigation element. - * - * @date 27/3/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - function in_admin_header() { - acf_get_view( 'html-admin-navigation' ); - } - - /** - * Modifies the admin footer text. - * - * @date 7/4/20 - * @since 5.9.0 - * - * @param string $text The admin footer text. - * @return string - */ - function admin_footer_text( $text ) { - // Use RegExp to append "ACF" after the element allowing translations to read correctly. - return preg_replace( '/()/', '$1 ' . __('and', 'acf') . ' ACF', $text, 1 ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Instantiate. -acf_new_instance('ACF_Admin'); +if ( ! class_exists( 'ACF_Admin' ) ) : + + class ACF_Admin { + + /** + * Constructor. + * + * @date 23/06/12 + * @since 5.0.0 + * + * @param void + * @return void + */ + function __construct() { + + // Add actions. + add_action( 'admin_menu', array( $this, 'admin_menu' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'admin_body_class', array( $this, 'admin_body_class' ) ); + add_action( 'current_screen', array( $this, 'current_screen' ) ); + } + + /** + * Adds the ACF menu item. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + function admin_menu() { + + // Bail early if ACF is hidden. + if ( ! acf_get_setting( 'show_admin' ) ) { + return; + } + + // Vars. + $slug = 'edit.php?post_type=acf-field-group'; + $cap = acf_get_setting( 'capability' ); + + // Add menu items. + add_menu_page( __( 'Custom Fields', 'acf' ), __( 'Custom Fields', 'acf' ), $cap, $slug, false, 'dashicons-welcome-widgets-menus', 80 ); + add_submenu_page( $slug, __( 'Field Groups', 'acf' ), __( 'Field Groups', 'acf' ), $cap, $slug ); + add_submenu_page( $slug, __( 'Add New', 'acf' ), __( 'Add New', 'acf' ), $cap, 'post-new.php?post_type=acf-field-group' ); + } + + /** + * Enqueues global admin styling. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + function admin_enqueue_scripts() { + wp_enqueue_style( 'acf-global' ); + } + + /** + * Appends custom admin body classes. + * + * @date 5/11/19 + * @since 5.8.7 + * + * @param string $classes Space-separated list of CSS classes. + * @return string + */ + function admin_body_class( $classes ) { + global $wp_version; + + // Determine body class version. + $wp_minor_version = floatval( $wp_version ); + if ( $wp_minor_version >= 5.3 ) { + $classes .= ' acf-admin-5-3'; + } else { + $classes .= ' acf-admin-3-8'; + } + + // Add browser for specific CSS. + $classes .= ' acf-browser-' . acf_get_browser(); + + // Return classes. + return $classes; + } + + /** + * Adds custom functionality to "ACF" admin pages. + * + * @date 7/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + function current_screen( $screen ) { + + // Determine if the current page being viewed is "ACF" related. + if ( isset( $screen->post_type ) && $screen->post_type === 'acf-field-group' ) { + add_action( 'in_admin_header', array( $this, 'in_admin_header' ) ); + add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ) ); + $this->setup_help_tab(); + } + } + + /** + * Sets up the admin help tab. + * + * @date 20/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + public function setup_help_tab() { + $screen = get_current_screen(); + + // Overview tab. + $screen->add_help_tab( + array( + 'id' => 'overview', + 'title' => __( 'Overview', 'acf' ), + 'content' => + '

                ' . __( 'Overview', 'acf' ) . '

                ' . + '

                ' . __( 'The Advanced Custom Fields plugin provides a visual form builder to customize WordPress edit screens with extra fields, and an intuitive API to display custom field values in any theme template file.', 'acf' ) . '

                ' . + '

                ' . sprintf( + __( 'Before creating your first Field Group, we recommend first reading our Getting started guide to familiarize yourself with the plugin\'s philosophy and best practises.', 'acf' ), + 'https://www.advancedcustomfields.com/resources/getting-started-with-acf/' + ) . '

                ' . + '

                ' . __( 'Please use the Help & Support tab to get in touch should you find yourself requiring assistance.', 'acf' ) . '

                ' . + '', + ) + ); + + // Help tab. + $screen->add_help_tab( + array( + 'id' => 'help', + 'title' => __( 'Help & Support', 'acf' ), + 'content' => + '

                ' . __( 'Help & Support', 'acf' ) . '

                ' . + '

                ' . __( 'We are fanatical about support, and want you to get the best out of your website with ACF. If you run into any difficulties, there are several places you can find help:', 'acf' ) . '

                ' . + '
                  ' . + '
                • ' . sprintf( + __( 'Documentation. Our extensive documentation contains references and guides for most situations you may encounter.', 'acf' ), + 'https://www.advancedcustomfields.com/resources/' + ) . '
                • ' . + '
                • ' . sprintf( + __( 'Discussions. We have an active and friendly community on our Community Forums who may be able to help you figure out the ‘how-tos’ of the ACF world.', 'acf' ), + 'https://support.advancedcustomfields.com/' + ) . '
                • ' . + '
                • ' . sprintf( + __( 'Help Desk. The support professionals on our Help Desk will assist with your more in depth, technical challenges.', 'acf' ), + 'https://www.advancedcustomfields.com/support/' + ) . '
                • ' . + '
                ', + ) + ); + + // Sidebar. + $screen->set_help_sidebar( + '

                ' . __( 'Information', 'acf' ) . '

                ' . + '

                ' . sprintf( __( 'Version %s', 'acf' ), ACF_VERSION ) . '

                ' . + '

                ' . __( 'View details', 'acf' ) . '

                ' . + '

                ' . __( 'Visit website', 'acf' ) . '

                ' . + '' + ); + } + + /** + * Renders the admin navigation element. + * + * @date 27/3/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + function in_admin_header() { + acf_get_view( 'html-admin-navigation' ); + } + + /** + * Modifies the admin footer text. + * + * @date 7/4/20 + * @since 5.9.0 + * + * @param string $text The admin footer text. + * @return string + */ + function admin_footer_text( $text ) { + // Use RegExp to append "ACF" after the element allowing translations to read correctly. + return preg_replace( '/()/', '$1 ' . __( 'and', 'acf' ) . ' ACF', $text, 1 ); + } + } + + // Instantiate. + acf_new_instance( 'ACF_Admin' ); endif; // class_exists check diff --git a/includes/admin/tools/class-acf-admin-tool-export.php b/includes/admin/tools/class-acf-admin-tool-export.php index f506dc6..42df051 100644 --- a/includes/admin/tools/class-acf-admin-tool-export.php +++ b/includes/admin/tools/class-acf-admin-tool-export.php @@ -1,366 +1,359 @@ -name = 'export'; + $this->title = __( 'Export Field Groups', 'acf' ); + + // active + if ( $this->is_active() ) { + $this->title .= ' - ' . __( 'Generate PHP', 'acf' ); + } -class ACF_Admin_Tool_Export extends ACF_Admin_Tool { - - /** @var string View context */ - var $view = ''; - - - /** @var array Export data */ - var $json = ''; - - - /** - * initialize - * - * This function will initialize the admin tool - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'export'; - $this->title = __("Export Field Groups", 'acf'); - - - // active - if( $this->is_active() ) { - $this->title .= ' - ' . __('Generate PHP', 'acf'); - } - - } - - - /** - * submit - * - * This function will run when the tool's form has been submit - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function submit() { - - // vars - $action = acf_maybe_get_POST('action'); - - - // download - if( $action === 'download' ) { - - $this->submit_download(); - - // generate - } elseif( $action === 'generate' ) { - - $this->submit_generate(); - - } - - } - - - /** - * submit_download - * - * description - * - * @date 17/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function submit_download() { - - // vars - $json = $this->get_selected(); - - - // validate - if( $json === false ) { - return acf_add_admin_notice( __("No field groups selected", 'acf'), 'warning' ); - } - - - // headers - $file_name = 'acf-export-' . date('Y-m-d') . '.json'; - header( "Content-Description: File Transfer" ); - header( "Content-Disposition: attachment; filename={$file_name}" ); - header( "Content-Type: application/json; charset=utf-8" ); - - - // return - echo acf_json_encode( $json ); - die; - - } - - - /** - * submit_generate - * - * description - * - * @date 17/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function submit_generate() { - - // vars - $keys = $this->get_selected_keys(); - - - // validate - if( !$keys ) { - return acf_add_admin_notice( __("No field groups selected", 'acf'), 'warning' ); - } - - - // url - $url = add_query_arg( 'keys', implode('+', $keys), $this->get_url() ); - - - // redirect - wp_redirect( $url ); - exit; - - } - - - /** - * load - * - * description - * - * @date 21/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function load() { - - // active - if( $this->is_active() ) { - - // get selected keys - $selected = $this->get_selected_keys(); - - - // add notice - if( $selected ) { - $count = count($selected); - $text = sprintf( _n( 'Exported 1 field group.', 'Exported %s field groups.', $count, 'acf' ), $count ); - acf_add_admin_notice( $text, 'success' ); - } } - } - - - /** - * html - * - * This function will output the metabox HTML - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function html() { - - // single (generate PHP) - if( $this->is_active() ) { - - $this->html_single(); - - // archive - } else { - - $this->html_archive(); - + + /** + * submit + * + * This function will run when the tool's form has been submit + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function submit() { + + // vars + $action = acf_maybe_get_POST( 'action' ); + + // download + if ( $action === 'download' ) { + + $this->submit_download(); + + // generate + } elseif ( $action === 'generate' ) { + + $this->submit_generate(); + + } + } - - } - - - /** - * html_field_selection - * - * description - * - * @date 24/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function html_field_selection() { - - // vars - $choices = array(); - $selected = $this->get_selected_keys(); - $field_groups = acf_get_field_groups(); - - - // loop - if( $field_groups ) { - foreach( $field_groups as $field_group ) { - $choices[ $field_group['key'] ] = esc_html( $field_group['title'] ); - } + + + /** + * submit_download + * + * description + * + * @date 17/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function submit_download() { + + // vars + $json = $this->get_selected(); + + // validate + if ( $json === false ) { + return acf_add_admin_notice( __( 'No field groups selected', 'acf' ), 'warning' ); + } + + // headers + $file_name = 'acf-export-' . date( 'Y-m-d' ) . '.json'; + header( 'Content-Description: File Transfer' ); + header( "Content-Disposition: attachment; filename={$file_name}" ); + header( 'Content-Type: application/json; charset=utf-8' ); + + // return + echo acf_json_encode( $json ); + die; + } - - - // render - acf_render_field_wrap(array( - 'label' => __('Select Field Groups', 'acf'), - 'type' => 'checkbox', - 'name' => 'keys', - 'prefix' => false, - 'value' => $selected, - 'toggle' => true, - 'choices' => $choices, - )); - - } - - - /** - * html_panel_selection - * - * description - * - * @date 21/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function html_panel_selection() { - - ?> + + + /** + * submit_generate + * + * description + * + * @date 17/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function submit_generate() { + + // vars + $keys = $this->get_selected_keys(); + + // validate + if ( ! $keys ) { + return acf_add_admin_notice( __( 'No field groups selected', 'acf' ), 'warning' ); + } + + // url + $url = add_query_arg( 'keys', implode( '+', $keys ), $this->get_url() ); + + // redirect + wp_redirect( $url ); + exit; + + } + + + /** + * load + * + * description + * + * @date 21/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function load() { + + // active + if ( $this->is_active() ) { + + // get selected keys + $selected = $this->get_selected_keys(); + + // add notice + if ( $selected ) { + $count = count( $selected ); + $text = sprintf( _n( 'Exported 1 field group.', 'Exported %s field groups.', $count, 'acf' ), $count ); + acf_add_admin_notice( $text, 'success' ); + } + } + + } + + + /** + * html + * + * This function will output the metabox HTML + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html() { + + // single (generate PHP) + if ( $this->is_active() ) { + + $this->html_single(); + + // archive + } else { + + $this->html_archive(); + + } + + } + + + /** + * html_field_selection + * + * description + * + * @date 24/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html_field_selection() { + + // vars + $choices = array(); + $selected = $this->get_selected_keys(); + $field_groups = acf_get_field_groups(); + + // loop + if ( $field_groups ) { + foreach ( $field_groups as $field_group ) { + $choices[ $field_group['key'] ] = esc_html( $field_group['title'] ); + } + } + + // render + acf_render_field_wrap( + array( + 'label' => __( 'Select Field Groups', 'acf' ), + 'type' => 'checkbox', + 'name' => 'keys', + 'prefix' => false, + 'value' => $selected, + 'toggle' => true, + 'choices' => $choices, + ) + ); + + } + + + /** + * html_panel_selection + * + * description + * + * @date 21/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html_panel_selection() { + + ?>
                -

                +

                html_field_selection(); ?>
                - +
                -

                +

                - __('Empty settings', 'acf'), - 'type' => 'select', - 'name' => 'minimal', - 'prefix' => false, - 'value' => '', - 'choices' => array( - 'all' => __('Include all settings', 'acf'), - 'minimal' => __('Ignore empty settings', 'acf'), + 'label' => __('Empty settings', 'acf'), + 'type' => 'select', + 'name' => 'minimal', + 'prefix' => false, + 'value' => '', + 'choices' => array( + 'all' => __('Include all settings', 'acf'), + 'minimal' => __('Ignore empty settings', 'acf'), ) )); -*/ - + */ + ?>
                - -

                + +

                html_field_selection(); ?>

                - - + +

                - +
                html_generate(); ?> @@ -368,80 +361,76 @@ class ACF_Admin_Tool_Export extends ACF_Admin_Tool {
                html_panel_selection(); ?>

                - +

                - get_selected(); - $str_replace = array( - " " => "\t", - "'!!__(!!\'" => "__('", - "!!\', !!\'" => "', '", - "!!\')!!'" => "')", - "array (" => "array(" - ); - $preg_replace = array( - '/([\t\r\n]+?)array/' => 'array', - '/[0-9]+ => array/' => 'array' - ); + -

                - + + + /** + * html_generate + * + * description + * + * @date 17/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html_generate() { + + // prevent default translation and fake __() within string + acf_update_setting( 'l10n_var_export', true ); + + // vars + $json = $this->get_selected(); + $str_replace = array( + ' ' => "\t", + "'!!__(!!\'" => "__('", + "!!\', !!\'" => "', '", + "!!\')!!'" => "')", + 'array (' => 'array(', + ); + $preg_replace = array( + '/([\t\r\n]+?)array/' => 'array', + '/[0-9]+ => array/' => 'array', + ); + + ?> +

                +

                @@ -480,7 +469,7 @@ class ACF_Admin_Tool_Export extends ACF_Admin_Tool { // tooltip acf.newTooltip({ - text: "", + text: "", timeout: 250, target: $(this), }); @@ -495,102 +484,97 @@ class ACF_Admin_Tool_Export extends ACF_Admin_Tool { })(jQuery); - get_selected_keys(); - $json = array(); - - - // bail early if no keys - if( !$selected ) return false; - - - // construct JSON - foreach( $selected as $key ) { - - // load field group - $field_group = acf_get_field_group( $key ); - - - // validate field group - if( empty($field_group) ) continue; - - - // load fields - $field_group['fields'] = acf_get_fields( $field_group ); - - - // prepare for export - $field_group = acf_prepare_field_group_for_export( $field_group ); - - - // add to json array - $json[] = $field_group; - - } - - - // return - return $json; - - } -} + get_selected_keys(); + $json = array(); + + // bail early if no keys + if ( ! $selected ) { + return false; + } + + // construct JSON + foreach ( $selected as $key ) { + + // load field group + $field_group = acf_get_field_group( $key ); + + // validate field group + if ( empty( $field_group ) ) { + continue; + } + + // load fields + $field_group['fields'] = acf_get_fields( $field_group ); + + // prepare for export + $field_group = acf_prepare_field_group_for_export( $field_group ); + + // add to json array + $json[] = $field_group; + + } + + // return + return $json; + + } + } + + // initialize + acf_register_admin_tool( 'ACF_Admin_Tool_Export' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/admin/tools/class-acf-admin-tool-import.php b/includes/admin/tools/class-acf-admin-tool-import.php index 1faaccd..cb85391 100644 --- a/includes/admin/tools/class-acf-admin-tool-import.php +++ b/includes/admin/tools/class-acf-admin-tool-import.php @@ -1,157 +1,161 @@ -name = 'import'; - $this->title = __("Import Field Groups", 'acf'); - $this->icon = 'dashicons-upload'; - - } - - - /** - * html - * - * This function will output the metabox HTML - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function html() { - - ?> -

                + class ACF_Admin_Tool_Import extends ACF_Admin_Tool { + + + /** + * initialize + * + * This function will initialize the admin tool + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'import'; + $this->title = __( 'Import Field Groups', 'acf' ); + $this->icon = 'dashicons-upload'; + + } + + + /** + * html + * + * This function will output the metabox HTML + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html() { + + ?> +

                - __('Select File', 'acf'), - 'type' => 'file', - 'name' => 'acf_import_file', - 'value' => false, - 'uploader' => 'basic', - )); - + __( 'Select File', 'acf' ), + 'type' => 'file', + 'name' => 'acf_import_file', + 'value' => false, + 'uploader' => 'basic', + ) + ); + ?>

                - +

                - ID; - } - - // Import field group. - $field_group = acf_import_field_group( $field_group ); - - // append message - $ids[] = $field_group['ID']; - } - - // Count number of imported field groups. - $total = count($ids); - - // Generate text. - $text = sprintf( _n( 'Imported 1 field group', 'Imported %s field groups', $total, 'acf' ), $total ); - - // Add links to text. - $links = array(); - foreach( $ids as $id ) { - $links[] = '' . get_the_title( $id ) . ''; - } - $text .= ' ' . implode( ', ', $links ); - - // Add notice - acf_add_admin_notice( $text, 'success' ); - } -} + ID; + } + + // Import field group. + $field_group = acf_import_field_group( $field_group ); + + // append message + $ids[] = $field_group['ID']; + } + + // Count number of imported field groups. + $total = count( $ids ); + + // Generate text. + $text = sprintf( _n( 'Imported 1 field group', 'Imported %s field groups', $total, 'acf' ), $total ); + + // Add links to text. + $links = array(); + foreach ( $ids as $id ) { + $links[] = '' . get_the_title( $id ) . ''; + } + $text .= ' ' . implode( ', ', $links ); + + // Add notice + acf_add_admin_notice( $text, 'success' ); + } + } + + // initialize + acf_register_admin_tool( 'ACF_Admin_Tool_Import' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/admin/tools/class-acf-admin-tool.php b/includes/admin/tools/class-acf-admin-tool.php index 9f4c683..757298c 100644 --- a/includes/admin/tools/class-acf-admin-tool.php +++ b/includes/admin/tools/class-acf-admin-tool.php @@ -1,195 +1,194 @@ -name; - } - - - /** - * get_title - * - * This function will return the Tool's title - * - * @date 19/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function get_title() { - return $this->title; - } - - - /** - * get_url - * - * This function will return the Tool's title - * - * @date 19/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function get_url() { - return acf_get_admin_tool_url( $this->name ); - } - - - /** - * is_active - * - * This function will return true if the tool is active - * - * @date 19/10/17 - * @since 5.6.3 - * - * @param n/a - * @return bool - */ - - function is_active() { - return acf_maybe_get_GET('tool') === $this->name; - } - - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 27/6/17 - * @since 5.6.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // initialize - $this->initialize(); - - } - - - /** - * initialize - * - * This function will initialize the admin tool - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - /* do nothing */ - - } - - - - /** - * load - * - * This function is called during the admin page load - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function load() { - - /* do nothing */ - - } - - - /** - * html - * - * This function will output the metabox HTML - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function html() { - - - - } - - - /** - * submit - * - * This function will run when the tool's form has been submit - * - * @date 10/10/17 - * @since 5.6.3 - * - * @param n/a - * @return n/a - */ - - function submit() { - - - } - - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Admin_Tool' ) ) : + + class ACF_Admin_Tool { + + + /** @var string Tool name */ + var $name = ''; + + + /** @var string Tool title */ + var $title = ''; + + + /** @var string Dashicon slug */ + // var $icon = ''; + + + /** @var boolean Redirect form to single */ + // var $redirect = false; + + + /** + * get_name + * + * This function will return the Tool's name + * + * @date 19/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function get_name() { + return $this->name; + } + + + /** + * get_title + * + * This function will return the Tool's title + * + * @date 19/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function get_title() { + return $this->title; + } + + + /** + * get_url + * + * This function will return the Tool's title + * + * @date 19/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function get_url() { + return acf_get_admin_tool_url( $this->name ); + } + + + /** + * is_active + * + * This function will return true if the tool is active + * + * @date 19/10/17 + * @since 5.6.3 + * + * @param n/a + * @return bool + */ + + function is_active() { + return acf_maybe_get_GET( 'tool' ) === $this->name; + } + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 27/6/17 + * @since 5.6.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // initialize + $this->initialize(); + + } + + + /** + * initialize + * + * This function will initialize the admin tool + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + /* do nothing */ + + } + + + + /** + * load + * + * This function is called during the admin page load + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function load() { + + /* do nothing */ + + } + + + /** + * html + * + * This function will output the metabox HTML + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function html() { + + } + + + /** + * submit + * + * This function will run when the tool's form has been submit + * + * @date 10/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function submit() { + + } + + + } + endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/admin/views/field-group-field-conditional-logic.php b/includes/admin/views/field-group-field-conditional-logic.php index a49f761..06d3565 100644 --- a/includes/admin/views/field-group-field-conditional-logic.php +++ b/includes/admin/views/field-group-field-conditional-logic.php @@ -1,55 +1,64 @@ - - + - 'true_false', - 'name' => 'conditional_logic', - 'prefix' => $field['prefix'], - 'value' => $disabled ? 0 : 1, - 'ui' => 1, - 'class' => 'conditions-toggle', - )); - + 'true_false', + 'name' => 'conditional_logic', + 'prefix' => $field['prefix'], + 'value' => $disabled ? 0 : 1, + 'ui' => 1, + 'class' => 'conditions-toggle', + ) + ); + ?> -
                style="display:none;"> +
                + style="display:none;"> - $group ): - + $group ) : + // validate - if( empty($group) ) continue; - - + if ( empty( $group ) ) { + continue; + } + + // vars // $group_id must be completely different to $rule_id to avoid JS issues $group_id = "group_{$group_id}"; - $h4 = ($group_id == "group_0") ? __("Show this field if",'acf') : __("or",'acf'); - + $h4 = ( $group_id == 'group_0' ) ? __( 'Show this field if', 'acf' ) : __( 'or', 'acf' ); + ?>
                @@ -57,85 +66,95 @@ if( empty($field['conditional_logic']) ) { - $rule ): - + $rule ) : + // valid rule - $rule = wp_parse_args( $rule, array( - 'field' => '', - 'operator' => '', - 'value' => '', - )); - - - // vars + $rule = wp_parse_args( + $rule, + array( + 'field' => '', + 'operator' => '', + 'value' => '', + ) + ); + + + // vars // $group_id must be completely different to $rule_id to avoid JS issues $rule_id = "rule_{$rule_id}"; - $prefix = "{$field['prefix']}[conditional_logic][{$group_id}][{$rule_id}]"; - + $prefix = "{$field['prefix']}[conditional_logic][{$group_id}][{$rule_id}]"; + // data attributes $attributes = array( - 'data-id' => $rule_id, - 'data-field' => $rule['field'], - 'data-operator' => $rule['operator'], - 'data-value' => $rule['value'] + 'data-id' => $rule_id, + 'data-field' => $rule['field'], + 'data-operator' => $rule['operator'], + 'data-value' => $rule['value'], ); - + ?> - > + > - \ No newline at end of file + diff --git a/includes/admin/views/field-group-field.php b/includes/admin/views/field-group-field.php index 453edb2..131b9b2 100644 --- a/includes/admin/views/field-group-field.php +++ b/includes/admin/views/field-group-field.php @@ -1,55 +1,62 @@ - 'acf-field-object acf-field-object-' . acf_slugify( $field['type'] ), - 'data-id' => $field['ID'], - 'data-key' => $field['key'], - 'data-type' => $field['type'], + 'class' => 'acf-field-object acf-field-object-' . acf_slugify( $field['type'] ), + 'data-id' => $field['ID'], + 'data-key' => $field['key'], + 'data-type' => $field['type'], ); // Misc template vars. -$field_label = acf_get_field_label( $field, 'admin' ); +$field_label = acf_get_field_label( $field, 'admin' ); $field_type_label = acf_get_field_type_label( $field['type'] ); ?>
                >
                - $field['ID'], - 'key' => $field['key'], - 'parent' => $field['parent'], - 'menu_order' => $i, - 'save' => '' + 'ID' => $field['ID'], + 'key' => $field['key'], + 'parent' => $field['parent'], + 'menu_order' => $i, + 'save' => '', ); - foreach( $meta_inputs as $k => $v ): - acf_hidden_input(array( 'name' => $input_prefix . '[' . $k . ']', 'value' => $v, 'id' => $input_id . '-' . $k )); - endforeach; ?> + foreach ( $meta_inputs as $k => $v ) : + acf_hidden_input( + array( + 'name' => $input_prefix . '[' . $k . ']', + 'value' => $v, + 'id' => $input_id . '-' . $k, + ) + ); + endforeach; + ?>
                - 'select', - 'prefix' => $prefix, - 'name' => 'field', - 'class' => 'condition-rule-field', - 'disabled' => $disabled, - 'value' => $rule['field'], - 'choices' => array( - $rule['field'] => $rule['field'] + 'select', + 'prefix' => $prefix, + 'name' => 'field', + 'class' => 'condition-rule-field', + 'disabled' => $disabled, + 'value' => $rule['field'], + 'choices' => array( + $rule['field'] => $rule['field'], + ), ) - )); - + ); + ?> - 'select', - 'prefix' => $prefix, - 'name' => 'operator', - 'class' => 'condition-rule-operator', - 'disabled' => $disabled, - 'value' => $rule['operator'], - 'choices' => array( - $rule['operator'] => $rule['operator'] + 'select', + 'prefix' => $prefix, + 'name' => 'operator', + 'class' => 'condition-rule-operator', + 'disabled' => $disabled, + 'value' => $rule['operator'], + 'choices' => array( + $rule['operator'] => $rule['operator'], + ), ) - )); - + ); + ?> - 'select', - 'prefix' => $prefix, - 'name' => 'value', - 'class' => 'condition-rule-value', - 'disabled' => $disabled, - 'value' => $rule['value'], - 'choices' => array( - $rule['value'] => $rule['value'] + acf_render_field( + array( + 'type' => 'select', + 'prefix' => $prefix, + 'name' => 'value', + 'class' => 'condition-rule-value', + 'disabled' => $disabled, + 'value' => $rule['value'], + 'choices' => array( + $rule['value'] => $rule['value'], + ), ) - )); - + ); + ?> - + @@ -148,11 +167,11 @@ if( empty($field['conditional_logic']) ) { -

                +

                - +
                - __('Field Label','acf'), - 'instructions' => __('This is the name which will appear on the EDIT page','acf'), - 'name' => 'label', - 'type' => 'text', - 'class' => 'field-label' - ), true); - - + acf_render_field_setting( + $field, + array( + 'label' => __( 'Field Label', 'acf' ), + 'instructions' => __( 'This is the name which will appear on the EDIT page', 'acf' ), + 'name' => 'label', + 'type' => 'text', + 'class' => 'field-label', + ), + true + ); + + // name - acf_render_field_setting($field, array( - 'label' => __('Field Name','acf'), - 'instructions' => __('Single word, no spaces. Underscores and dashes allowed','acf'), - 'name' => 'name', - 'type' => 'text', - 'class' => 'field-name' - ), true); - - + acf_render_field_setting( + $field, + array( + 'label' => __( 'Field Name', 'acf' ), + 'instructions' => __( 'Single word, no spaces. Underscores and dashes allowed', 'acf' ), + 'name' => 'name', + 'type' => 'text', + 'class' => 'field-name', + ), + true + ); + + // type - acf_render_field_setting($field, array( - 'label' => __('Field Type','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'type', - 'choices' => acf_get_grouped_field_types(), - 'class' => 'field-type' - ), true); - - + acf_render_field_setting( + $field, + array( + 'label' => __( 'Field Type', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'type', + 'choices' => acf_get_grouped_field_types(), + 'class' => 'field-type', + ), + true + ); + + // instructions - acf_render_field_setting($field, array( - 'label' => __('Instructions','acf'), - 'instructions' => __('Instructions for authors. Shown when submitting data','acf'), - 'type' => 'textarea', - 'name' => 'instructions', - 'rows' => 5 - ), true); - - + acf_render_field_setting( + $field, + array( + 'label' => __( 'Instructions', 'acf' ), + 'instructions' => __( 'Instructions for authors. Shown when submitting data', 'acf' ), + 'type' => 'textarea', + 'name' => 'instructions', + 'rows' => 5, + ), + true + ); + + // required - acf_render_field_setting($field, array( - 'label' => __('Required?','acf'), - 'instructions' => '', - 'type' => 'true_false', - 'name' => 'required', - 'ui' => 1, - 'class' => 'field-required' - ), true); - - + acf_render_field_setting( + $field, + array( + 'label' => __( 'Required?', 'acf' ), + 'instructions' => '', + 'type' => 'true_false', + 'name' => 'required', + 'ui' => 1, + 'class' => 'field-required', + ), + true + ); + + // 3rd party settings - do_action('acf/render_field_settings', $field); - - + do_action( 'acf/render_field_settings', $field ); + + // type specific settings - do_action("acf/render_field_settings/type={$field['type']}", $field); - - + do_action( "acf/render_field_settings/type={$field['type']}", $field ); + + // conditional logic - acf_get_view('field-group-field-conditional-logic', array( 'field' => $field )); - - + acf_get_view( 'field-group-field-conditional-logic', array( 'field' => $field ) ); + + // wrapper - acf_render_field_wrap(array( - 'label' => __('Wrapper Attributes','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'width', - 'prefix' => $field['prefix'] . '[wrapper]', - 'value' => $field['wrapper']['width'], - 'prepend' => __('width', 'acf'), - 'append' => '%', - 'wrapper' => array( - 'data-name' => 'wrapper', - 'class' => 'acf-field-setting-wrapper' - ) - ), 'tr'); - - acf_render_field_wrap(array( - 'label' => '', - 'instructions' => '', - 'type' => 'text', - 'name' => 'class', - 'prefix' => $field['prefix'] . '[wrapper]', - 'value' => $field['wrapper']['class'], - 'prepend' => __('class', 'acf'), - 'wrapper' => array( - 'data-append' => 'wrapper' - ) - ), 'tr'); - - acf_render_field_wrap(array( - 'label' => '', - 'instructions' => '', - 'type' => 'text', - 'name' => 'id', - 'prefix' => $field['prefix'] . '[wrapper]', - 'value' => $field['wrapper']['id'], - 'prepend' => __('id', 'acf'), - 'wrapper' => array( - 'data-append' => 'wrapper' - ) - ), 'tr'); - + acf_render_field_wrap( + array( + 'label' => __( 'Wrapper Attributes', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'width', + 'prefix' => $field['prefix'] . '[wrapper]', + 'value' => $field['wrapper']['width'], + 'prepend' => __( 'width', 'acf' ), + 'append' => '%', + 'wrapper' => array( + 'data-name' => 'wrapper', + 'class' => 'acf-field-setting-wrapper', + ), + ), + 'tr' + ); + + acf_render_field_wrap( + array( + 'label' => '', + 'instructions' => '', + 'type' => 'text', + 'name' => 'class', + 'prefix' => $field['prefix'] . '[wrapper]', + 'value' => $field['wrapper']['class'], + 'prepend' => __( 'class', 'acf' ), + 'wrapper' => array( + 'data-append' => 'wrapper', + ), + ), + 'tr' + ); + + acf_render_field_wrap( + array( + 'label' => '', + 'instructions' => '', + 'type' => 'text', + 'name' => 'id', + 'prefix' => $field['prefix'] . '[wrapper]', + 'value' => $field['wrapper']['id'], + 'prepend' => __( 'id', 'acf' ), + 'wrapper' => array( + 'data-append' => 'wrapper', + ), + ), + 'tr' + ); + ?> @@ -185,4 +221,4 @@ $field_type_label = acf_get_field_type_label( $field['type'] );
                -
                \ No newline at end of file +
                diff --git a/includes/admin/views/field-group-fields.php b/includes/admin/views/field-group-fields.php index e4a9e50..72b2246 100644 --- a/includes/admin/views/field-group-fields.php +++ b/includes/admin/views/field-group-fields.php @@ -1,52 +1,76 @@
                  -
                • -
                • -
                • -
                • -
                • +
                • +
                • +
                • +
                • +
                -
                +
                - + Add Field button to create your first field.",'acf'); ?> + + Add Field button to create your first field.', 'acf' ); ?>
                - $field ): - - acf_get_view('field-group-field', array( 'field' => $field, 'i' => $i )); - + $field ) : + + acf_get_view( + 'field-group-field', + array( + 'field' => $field, + 'i' => $i, + ) + ); + endforeach; - - endif; ?> + + endif; + ?>
                • - +
                - 'acfcloneindex', - 'key' => 'acfcloneindex', - 'label' => __('New Field','acf'), - 'name' => 'new_field', - 'type' => 'text' - )); - + $clone = acf_get_valid_field( + array( + 'ID' => 'acfcloneindex', + 'key' => 'acfcloneindex', + 'label' => __( 'New Field', 'acf' ), + 'name' => 'new_field', + 'type' => 'text', + ) + ); + ?> - + -
                \ No newline at end of file +
                diff --git a/includes/admin/views/field-group-locations.php b/includes/admin/views/field-group-locations.php index 12c76a8..9b0a9bb 100644 --- a/includes/admin/views/field-group-locations.php +++ b/includes/admin/views/field-group-locations.php @@ -6,29 +6,36 @@ global $field_group; ?>
                - -

                + +

                - $group ): - + $group ) : + // bail ealry if no group - if( empty($group) ) return; - - + if ( empty( $group ) ) { + return; + } + + // view - acf_get_view('html-location-group', array( - 'group' => $group, - 'group_id' => "group_{$i}" - )); + acf_get_view( + 'html-location-group', + array( + 'group' => $group, + 'group_id' => "group_{$i}", + ) + ); + + endforeach; + ?> - endforeach; ?> +

                -

                - - +
                @@ -42,4 +49,4 @@ if( typeof acf !== 'undefined' ) { }); } - \ No newline at end of file + diff --git a/includes/admin/views/field-group-options.php b/includes/admin/views/field-group-options.php index e72cd08..64cba73 100644 --- a/includes/admin/views/field-group-options.php +++ b/includes/admin/views/field-group-options.php @@ -2,143 +2,159 @@ // global global $field_group; - - + + // active -acf_render_field_wrap(array( - 'label' => __('Active','acf'), - 'instructions' => '', - 'type' => 'true_false', - 'name' => 'active', - 'prefix' => 'acf_field_group', - 'value' => $field_group['active'], - 'ui' => 1, - //'ui_on_text' => __('Active', 'acf'), - //'ui_off_text' => __('Inactive', 'acf'), -)); +acf_render_field_wrap( + array( + 'label' => __( 'Active', 'acf' ), + 'instructions' => '', + 'type' => 'true_false', + 'name' => 'active', + 'prefix' => 'acf_field_group', + 'value' => $field_group['active'], + 'ui' => 1, + // 'ui_on_text' => __('Active', 'acf'), + // 'ui_off_text' => __('Inactive', 'acf'), + ) +); // style -acf_render_field_wrap(array( - 'label' => __('Style','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'style', - 'prefix' => 'acf_field_group', - 'value' => $field_group['style'], - 'choices' => array( - 'default' => __("Standard (WP metabox)",'acf'), - 'seamless' => __("Seamless (no metabox)",'acf'), +acf_render_field_wrap( + array( + 'label' => __( 'Style', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'style', + 'prefix' => 'acf_field_group', + 'value' => $field_group['style'], + 'choices' => array( + 'default' => __( 'Standard (WP metabox)', 'acf' ), + 'seamless' => __( 'Seamless (no metabox)', 'acf' ), + ), ) -)); +); // position -acf_render_field_wrap(array( - 'label' => __('Position','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'position', - 'prefix' => 'acf_field_group', - 'value' => $field_group['position'], - 'choices' => array( - 'acf_after_title' => __("High (after title)",'acf'), - 'normal' => __("Normal (after content)",'acf'), - 'side' => __("Side",'acf'), - ), - 'default_value' => 'normal' -)); +acf_render_field_wrap( + array( + 'label' => __( 'Position', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'position', + 'prefix' => 'acf_field_group', + 'value' => $field_group['position'], + 'choices' => array( + 'acf_after_title' => __( 'High (after title)', 'acf' ), + 'normal' => __( 'Normal (after content)', 'acf' ), + 'side' => __( 'Side', 'acf' ), + ), + 'default_value' => 'normal', + ) +); // label_placement -acf_render_field_wrap(array( - 'label' => __('Label placement','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'label_placement', - 'prefix' => 'acf_field_group', - 'value' => $field_group['label_placement'], - 'choices' => array( - 'top' => __("Top aligned",'acf'), - 'left' => __("Left aligned",'acf'), +acf_render_field_wrap( + array( + 'label' => __( 'Label placement', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'label_placement', + 'prefix' => 'acf_field_group', + 'value' => $field_group['label_placement'], + 'choices' => array( + 'top' => __( 'Top aligned', 'acf' ), + 'left' => __( 'Left aligned', 'acf' ), + ), ) -)); +); // instruction_placement -acf_render_field_wrap(array( - 'label' => __('Instruction placement','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'instruction_placement', - 'prefix' => 'acf_field_group', - 'value' => $field_group['instruction_placement'], - 'choices' => array( - 'label' => __("Below labels",'acf'), - 'field' => __("Below fields",'acf'), +acf_render_field_wrap( + array( + 'label' => __( 'Instruction placement', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'instruction_placement', + 'prefix' => 'acf_field_group', + 'value' => $field_group['instruction_placement'], + 'choices' => array( + 'label' => __( 'Below labels', 'acf' ), + 'field' => __( 'Below fields', 'acf' ), + ), ) -)); +); // menu_order -acf_render_field_wrap(array( - 'label' => __('Order No.','acf'), - 'instructions' => __('Field groups with a lower order will appear first','acf'), - 'type' => 'number', - 'name' => 'menu_order', - 'prefix' => 'acf_field_group', - 'value' => $field_group['menu_order'], -)); +acf_render_field_wrap( + array( + 'label' => __( 'Order No.', 'acf' ), + 'instructions' => __( 'Field groups with a lower order will appear first', 'acf' ), + 'type' => 'number', + 'name' => 'menu_order', + 'prefix' => 'acf_field_group', + 'value' => $field_group['menu_order'], + ) +); // description -acf_render_field_wrap(array( - 'label' => __('Description','acf'), - 'instructions' => __('Shown in field group list','acf'), - 'type' => 'text', - 'name' => 'description', - 'prefix' => 'acf_field_group', - 'value' => $field_group['description'], -)); +acf_render_field_wrap( + array( + 'label' => __( 'Description', 'acf' ), + 'instructions' => __( 'Shown in field group list', 'acf' ), + 'type' => 'text', + 'name' => 'description', + 'prefix' => 'acf_field_group', + 'value' => $field_group['description'], + ) +); // hide on screen $choices = array( - 'permalink' => __("Permalink", 'acf'), - 'the_content' => __("Content Editor",'acf'), - 'excerpt' => __("Excerpt", 'acf'), - 'custom_fields' => __("Custom Fields", 'acf'), - 'discussion' => __("Discussion", 'acf'), - 'comments' => __("Comments", 'acf'), - 'revisions' => __("Revisions", 'acf'), - 'slug' => __("Slug", 'acf'), - 'author' => __("Author", 'acf'), - 'format' => __("Format", 'acf'), - 'page_attributes' => __("Page Attributes", 'acf'), - 'featured_image' => __("Featured Image", 'acf'), - 'categories' => __("Categories", 'acf'), - 'tags' => __("Tags", 'acf'), - 'send-trackbacks' => __("Send Trackbacks", 'acf'), + 'permalink' => __( 'Permalink', 'acf' ), + 'the_content' => __( 'Content Editor', 'acf' ), + 'excerpt' => __( 'Excerpt', 'acf' ), + 'custom_fields' => __( 'Custom Fields', 'acf' ), + 'discussion' => __( 'Discussion', 'acf' ), + 'comments' => __( 'Comments', 'acf' ), + 'revisions' => __( 'Revisions', 'acf' ), + 'slug' => __( 'Slug', 'acf' ), + 'author' => __( 'Author', 'acf' ), + 'format' => __( 'Format', 'acf' ), + 'page_attributes' => __( 'Page Attributes', 'acf' ), + 'featured_image' => __( 'Featured Image', 'acf' ), + 'categories' => __( 'Categories', 'acf' ), + 'tags' => __( 'Tags', 'acf' ), + 'send-trackbacks' => __( 'Send Trackbacks', 'acf' ), ); -if( acf_get_setting('remove_wp_meta_box') ) { - unset( $choices['custom_fields'] ); +if ( acf_get_setting( 'remove_wp_meta_box' ) ) { + unset( $choices['custom_fields'] ); } -acf_render_field_wrap(array( - 'label' => __('Hide on screen','acf'), - 'instructions' => __('Select items to hide them from the edit screen.','acf') . '

                ' . __("If multiple field groups appear on an edit screen, the first field group's options will be used (the one with the lowest order number)",'acf'), - 'type' => 'checkbox', - 'name' => 'hide_on_screen', - 'prefix' => 'acf_field_group', - 'value' => $field_group['hide_on_screen'], - 'toggle' => true, - 'choices' => $choices -)); +acf_render_field_wrap( + array( + 'label' => __( 'Hide on screen', 'acf' ), + 'instructions' => __( 'Select items to hide them from the edit screen.', 'acf' ) . '

                ' . __( "If multiple field groups appear on an edit screen, the first field group's options will be used (the one with the lowest order number)", 'acf' ), + 'type' => 'checkbox', + 'name' => 'hide_on_screen', + 'prefix' => 'acf_field_group', + 'value' => $field_group['hide_on_screen'], + 'toggle' => true, + 'choices' => $choices, + ) +); // 3rd party settings -do_action('acf/render_field_group_settings', $field_group); - +do_action( 'acf/render_field_group_settings', $field_group ); + ?>
                @@ -152,4 +168,4 @@ if( typeof acf !== 'undefined' ) { }); } - \ No newline at end of file + diff --git a/includes/admin/views/html-admin-navigation.php b/includes/admin/views/html-admin-navigation.php index ecf145f..d3e6e9e 100644 --- a/includes/admin/views/html-admin-navigation.php +++ b/includes/admin/views/html-admin-navigation.php @@ -1,12 +1,14 @@ - $sub_item ) { - +if ( isset( $submenu[ $parent_slug ] ) ) { + foreach ( $submenu[ $parent_slug ] as $i => $sub_item ) { + // Check user can access page. - if ( !current_user_can( $sub_item[1] ) ) { + if ( ! current_user_can( $sub_item[1] ) ) { continue; } - + // Ignore "Add New". - if( $i === 1 ) { + if ( $i === 1 ) { continue; } - + // Define tab. $tab = array( - 'text' => $sub_item[0], - 'url' => $sub_item[2] + 'text' => $sub_item[0], + 'url' => $sub_item[2], ); - + // Convert submenu slug "test" to "$parent_slug&page=test". - if( !strpos($sub_item[2], '.php') ) { + if ( ! strpos( $sub_item[2], '.php' ) ) { $tab['url'] = add_query_arg( array( 'page' => $sub_item[2] ), $parent_slug ); } - + // Detect active state. - if( $submenu_file === $sub_item[2] || $plugin_page === $sub_item[2] ) { + if ( $submenu_file === $sub_item[2] || $plugin_page === $sub_item[2] ) { $tab['is_active'] = true; } - + // Special case for "Add New" page. - if( $i === 0 && $submenu_file === 'post-new.php?post_type=acf-field-group' ) { + if ( $i === 0 && $submenu_file === 'post-new.php?post_type=acf-field-group' ) { $tab['is_active'] = true; } $tabs[] = $tab; @@ -55,35 +57,37 @@ if( isset($submenu[ $parent_slug ]) ) { /** * Filters the admin navigation tabs. * - * @date 27/3/20 - * @since 5.9.0 + * @date 27/3/20 + * @since 5.9.0 * - * @param array $tabs The array of navigation tabs. + * @param array $tabs The array of navigation tabs. */ $tabs = apply_filters( 'acf/admin/toolbar', $tabs ); // Bail early if set to false. -if( $tabs === false ) { +if ( $tabs === false ) { return; } ?>
                -

                - + %s', - !empty( $tab['is_active'] ) ? ' is-active' : '', + ! empty( $tab['is_active'] ) ? ' is-active' : '', esc_url( $tab['url'] ), acf_esc_html( $tab['text'] ) ); - } ?> + } + ?> - - - -

                -
                - + + + +

                +
                + -
                \ No newline at end of file +
                diff --git a/includes/admin/views/html-admin-page-upgrade-network.php b/includes/admin/views/html-admin-page-upgrade-network.php index 903733e..9ee2a5b 100644 --- a/includes/admin/views/html-admin-page-upgrade-network.php +++ b/includes/admin/views/html-admin-page-upgrade-network.php @@ -1,14 +1,14 @@
                -

                +

                -

                -

                +

                +

                @@ -33,9 +33,9 @@ - + @@ -44,53 +44,57 @@ - + $site ): - - // switch blog - switch_to_blog( $site['blog_id'] ); - - ?> - class="alternate"> + if ( $sites ) : + foreach ( $sites as $i => $site ) : + + // switch blog + switch_to_blog( $site['blog_id'] ); + + ?> + + class="alternate"> -
                - +
                - +
                - + -
                +
                - - - - + + + +
                -

                -

                Return to network dashboard', 'acf'), network_admin_url() ); ?>

                +

                +

                Return to network dashboard', 'acf' ), network_admin_url() ); ?>

                -
                \ No newline at end of file +
                diff --git a/includes/admin/views/html-admin-page-upgrade.php b/includes/admin/views/html-admin-page-upgrade.php index 3c0f9aa..a3ab091 100644 --- a/includes/admin/views/html-admin-page-upgrade.php +++ b/includes/admin/views/html-admin-page-upgrade.php @@ -1,14 +1,14 @@
                -

                +

                - + -

                -

                +

                +

                -

                See what\'s new', 'acf' ), admin_url('edit.php?post_type=acf-field-group') ); ?>

                +

                See what\'s new', 'acf' ), admin_url( 'edit.php?post_type=acf-field-group' ) ); ?>

                - + -

                +

                -
                \ No newline at end of file +
                diff --git a/includes/admin/views/html-admin-tools.php b/includes/admin/views/html-admin-tools.php index 145ac6c..6e87aaa 100644 --- a/includes/admin/views/html-admin-tools.php +++ b/includes/admin/views/html-admin-tools.php @@ -1,27 +1,30 @@ -
                -

                +

                +

                -
                \ No newline at end of file + diff --git a/includes/admin/views/html-location-group.php b/includes/admin/views/html-location-group.php index 14dc961..804f9fe 100644 --- a/includes/admin/views/html-location-group.php +++ b/includes/admin/views/html-location-group.php @@ -1,25 +1,30 @@
                -

                +

                - $rule ): - + $rule ) : + // validate rule - $rule = acf_validate_location_rule($rule); - + $rule = acf_validate_location_rule( $rule ); + // append id and group - $rule['id'] = "rule_{$i}"; + $rule['id'] = "rule_{$i}"; $rule['group'] = $group_id; - + // view - acf_get_view('html-location-rule', array( - 'rule' => $rule - )); - - endforeach; ?> + acf_get_view( + 'html-location-rule', + array( + 'rule' => $rule, + ) + ); + + endforeach; + ?>
                -
                \ No newline at end of file + diff --git a/includes/admin/views/html-location-rule.php b/includes/admin/views/html-location-rule.php index 1171133..2e99bc8 100644 --- a/includes/admin/views/html-location-rule.php +++ b/includes/admin/views/html-location-rule.php @@ -1,91 +1,97 @@ - - 'select', - 'name' => 'param', - 'prefix' => $prefix, - 'value' => $rule['param'], - 'choices' => $choices, - 'class' => 'refresh-location-rule' - )); - + if ( is_array( $choices ) ) { + + acf_render_field( + array( + 'type' => 'select', + 'name' => 'param', + 'prefix' => $prefix, + 'value' => $rule['param'], + 'choices' => $choices, + 'class' => 'refresh-location-rule', + ) + ); + } - + ?> - 'select', - 'name' => 'operator', - 'prefix' => $prefix, - 'value' => $rule['operator'], - 'choices' => $choices - )); - - // custom + if ( is_array( $choices ) ) { + + acf_render_field( + array( + 'type' => 'select', + 'name' => 'operator', + 'prefix' => $prefix, + 'value' => $rule['operator'], + 'choices' => $choices, + ) + ); + + // custom } else { - + echo $choices; - + } - + ?> 'select', - 'name' => 'value', - 'prefix' => $prefix, - 'value' => $rule['value'], - 'choices' => $choices - )); - - // custom + if ( is_array( $choices ) ) { + + acf_render_field( + array( + 'type' => 'select', + 'name' => 'value', + 'prefix' => $prefix, + 'value' => $rule['value'], + 'choices' => $choices, + ) + ); + + // custom } else { - + echo $choices; - + } - + ?> - + - \ No newline at end of file + diff --git a/includes/admin/views/html-notice-upgrade.php b/includes/admin/views/html-notice-upgrade.php index 11f40fd..6676f1b 100644 --- a/includes/admin/views/html-notice-upgrade.php +++ b/includes/admin/views/html-notice-upgrade.php @@ -1,15 +1,22 @@ - @@ -17,11 +24,11 @@ if( !acf_get_setting('pro') ) {
                - -

                -


                - -

                + +

                +


                + +

                @@ -30,7 +37,7 @@ if( !acf_get_setting('pro') ) { - + - \ No newline at end of file + diff --git a/includes/ajax/class-acf-ajax-check-screen.php b/includes/ajax/class-acf-ajax-check-screen.php index c56eb56..5438bd8 100644 --- a/includes/ajax/class-acf-ajax-check-screen.php +++ b/includes/ajax/class-acf-ajax-check-screen.php @@ -1,98 +1,103 @@ request, array( - 'screen' => '', - 'post_id' => 0, - 'ajax' => true, - 'exists' => array() - )); - - // vars - $response = array( - 'results' => array(), - 'style' => '' - ); - - // get field groups - $field_groups = acf_get_field_groups( $args ); - - // loop through field groups - if( $field_groups ) { - foreach( $field_groups as $i => $field_group ) { - - // vars - $item = array( - 'id' => 'acf-' . $field_group['key'], - 'key' => $field_group['key'], - 'title' => $field_group['title'], - 'position' => $field_group['position'], - 'style' => $field_group['style'], - 'label' => $field_group['label_placement'], - 'edit' => acf_get_field_group_edit_link( $field_group['ID'] ), - 'html' => '' - ); - - // append html if doesnt already exist on page - if( !in_array($field_group['key'], $args['exists']) ) { - - // load fields - $fields = acf_get_fields( $field_group ); - - // get field HTML - ob_start(); - - // render - acf_render_fields( $fields, $args['post_id'], 'div', $field_group['instruction_placement'] ); - - $item['html'] = ob_get_clean(); - } - - // append - $response['results'][] = $item; - } - - // Get style from first field group. - $response['style'] = acf_get_field_group_style( $field_groups[0] ); - } - - // Custom metabox order. - if( $this->get('screen') == 'post' ) { - $response['sorted'] = get_user_option('meta-box-order_' . $this->get('post_type')); - } - - // return - return $response; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -acf_new_instance('ACF_Ajax_Check_Screen'); +if ( ! class_exists( 'ACF_Ajax_Check_Screen' ) ) : + + class ACF_Ajax_Check_Screen extends ACF_Ajax { + + /** @var string The AJAX action name. */ + var $action = 'acf/ajax/check_screen'; + + /** @var bool Prevents access for non-logged in users. */ + var $public = false; + + /** + * get_response + * + * Returns the response data to sent back. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return mixed The response data or WP_Error. + */ + function get_response( $request ) { + + // vars + $args = wp_parse_args( + $this->request, + array( + 'screen' => '', + 'post_id' => 0, + 'ajax' => true, + 'exists' => array(), + ) + ); + + // vars + $response = array( + 'results' => array(), + 'style' => '', + ); + + // get field groups + $field_groups = acf_get_field_groups( $args ); + + // loop through field groups + if ( $field_groups ) { + foreach ( $field_groups as $i => $field_group ) { + + // vars + $item = array( + 'id' => 'acf-' . $field_group['key'], + 'key' => $field_group['key'], + 'title' => $field_group['title'], + 'position' => $field_group['position'], + 'style' => $field_group['style'], + 'label' => $field_group['label_placement'], + 'edit' => acf_get_field_group_edit_link( $field_group['ID'] ), + 'html' => '', + ); + + // append html if doesnt already exist on page + if ( ! in_array( $field_group['key'], $args['exists'] ) ) { + + // load fields + $fields = acf_get_fields( $field_group ); + + // get field HTML + ob_start(); + + // render + acf_render_fields( $fields, $args['post_id'], 'div', $field_group['instruction_placement'] ); + + $item['html'] = ob_get_clean(); + } + + // append + $response['results'][] = $item; + } + + // Get style from first field group. + $response['style'] = acf_get_field_group_style( $field_groups[0] ); + } + + // Custom metabox order. + if ( $this->get( 'screen' ) == 'post' ) { + $response['sorted'] = get_user_option( 'meta-box-order_' . $this->get( 'post_type' ) ); + } + + // return + return $response; + } + } + + acf_new_instance( 'ACF_Ajax_Check_Screen' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/ajax/class-acf-ajax-local-json-diff.php b/includes/ajax/class-acf-ajax-local-json-diff.php index a3ca7bb..7a370db 100644 --- a/includes/ajax/class-acf-ajax-local-json-diff.php +++ b/includes/ajax/class-acf-ajax-local-json-diff.php @@ -1,69 +1,71 @@ 404 ) ); - } - - // Disable filters and load field group directly from database. - acf_disable_filters(); - $field_group = acf_get_field_group( $id ); - if( !$field_group ) { - return new WP_Error( 'acf_invalid_id', __( 'Invalid field group ID.', 'acf' ), array( 'status' => 404 ) ); - } - $field_group['fields'] = acf_get_fields( $field_group ); - $field_group['modified'] = get_post_modified_time( 'U', true, $field_group['ID'] ); - $field_group = acf_prepare_field_group_for_export( $field_group ); - - // Load local field group file. - $files = acf_get_local_json_files(); - $key = $field_group['key']; - if( !isset( $files[ $key ] ) ) { - return new WP_Error( 'acf_cannot_compare', __( 'Sorry, this field group is unavailable for diff comparison.', 'acf' ), array( 'status' => 404 ) ); - } - $local_field_group = json_decode( file_get_contents( $files[ $key ] ), true ); - - // Render diff HTML. - $date_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); - $date_template = __( 'Last updated: %s', 'acf' ); - $json['html'] = ' + class ACF_Ajax_Local_JSON_Diff extends ACF_Ajax { + + /** @var string The AJAX action name. */ + var $action = 'acf/ajax/local_json_diff'; + + /** @var bool Prevents access for non-logged in users. */ + var $public = false; + + /** + * get_response + * + * Returns the response data to sent back. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return mixed The response data or WP_Error. + */ + function get_response( $request ) { + $json = array(); + + // Extract props. + $id = isset( $request['id'] ) ? intval( $request['id'] ) : 0; + + // Bail ealry if missing props. + if ( ! $id ) { + return new WP_Error( 'acf_invalid_param', __( 'Invalid field group parameter(s).', 'acf' ), array( 'status' => 404 ) ); + } + + // Disable filters and load field group directly from database. + acf_disable_filters(); + $field_group = acf_get_field_group( $id ); + if ( ! $field_group ) { + return new WP_Error( 'acf_invalid_id', __( 'Invalid field group ID.', 'acf' ), array( 'status' => 404 ) ); + } + $field_group['fields'] = acf_get_fields( $field_group ); + $field_group['modified'] = get_post_modified_time( 'U', true, $field_group['ID'] ); + $field_group = acf_prepare_field_group_for_export( $field_group ); + + // Load local field group file. + $files = acf_get_local_json_files(); + $key = $field_group['key']; + if ( ! isset( $files[ $key ] ) ) { + return new WP_Error( 'acf_cannot_compare', __( 'Sorry, this field group is unavailable for diff comparison.', 'acf' ), array( 'status' => 404 ) ); + } + $local_field_group = json_decode( file_get_contents( $files[ $key ] ), true ); + + // Render diff HTML. + $date_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' ); + $date_template = __( 'Last updated: %s', 'acf' ); + $json['html'] = '
                - ' . __( 'Original field group', 'acf' ) . ' + ' . __( 'Original field group', 'acf' ) . ' ' . sprintf( $date_template, wp_date( $date_format, $field_group['modified'] ) ) . '
                - ' . __( 'JSON field group (newer)', 'acf' ) . ' + ' . __( 'JSON field group (newer)', 'acf' ) . ' ' . sprintf( $date_template, wp_date( $date_format, $local_field_group['modified'] ) ) . '
                @@ -71,10 +73,10 @@ class ACF_Ajax_Local_JSON_Diff extends ACF_Ajax { ' . wp_text_diff( acf_json_encode( $field_group ), acf_json_encode( $local_field_group ) ) . '
                '; - return $json; + return $json; + } } -} -acf_new_instance('ACF_Ajax_Local_JSON_Diff'); + acf_new_instance( 'ACF_Ajax_Local_JSON_Diff' ); endif; // class_exists check diff --git a/includes/ajax/class-acf-ajax-query-users.php b/includes/ajax/class-acf-ajax-query-users.php index 7173b62..8f674c9 100644 --- a/includes/ajax/class-acf-ajax-query-users.php +++ b/includes/ajax/class-acf-ajax-query-users.php @@ -1,273 +1,275 @@ per_page; - $args['paged'] = $this->page; - if( $this->is_search ) { - $args['search'] = "*{$this->search}*"; - } - - /** - * Filters the query args. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param array $args The query args. - * @param array $request The query request. - * @param ACF_Ajax_Query $query The query object. - */ - return apply_filters( "acf/ajax/query_users/args", $args, $request, $this ); - } - - /** - * Prepares args for the get_results() method. - * - * @date 23/3/20 - * @since 5.8.9 - * - * @param array args The query args. - * @return array - */ - function prepare_args( $args ) { - - // Parse pagination args that may have been modified. - if( isset($args['users_per_page']) ) { - $this->per_page = intval($args['users_per_page']); - unset( $args['users_per_page'] ); - - } elseif( isset($args['number']) ) { - $this->per_page = intval($args['number']); - } - - if( isset($args['paged']) ) { - $this->page = intval($args['paged']); - unset( $args['paged'] ); - } - - // Set pagination args for fine control. - $args['number'] = $this->per_page; - $args['offset'] = $this->per_page * ($this->page - 1); - $args['count_total'] = true; - return $args; - } - - /** - * get_results - * - * Returns an array of results for the given args. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param array args The query args. - * @return array - */ - function get_results( $args ) { - $results = array(); - - // Prepare args for quey. - $args = $this->prepare_args( $args ); - - // Get result groups. - if( !empty( $args['role__in']) ) { - $roles = acf_get_user_role_labels( $args['role__in'] ); - } else { - $roles = acf_get_user_role_labels(); - } - - // Return a flat array of results when searching or when queriying one group only. - if( $this->is_search || count($roles) === 1 ) { - - // Query users and append to results. - $wp_user_query = new WP_User_Query( $args ); - $users = (array) $wp_user_query->get_results(); - $total_users = $wp_user_query->get_total(); - foreach( $users as $user ) { - $results[] = $this->get_result( $user ); - } - - // Determine if more results exist. - // As this query does not return grouped results, the calculation can be exact (">"). - $this->more = ( $total_users > count($users) + $args['offset'] ); - - // Otherwise, group results via role. - } else { - - // Unset args that will interfer with query results. - unset( $args['role__in'], $args['role__not_in'] ); - - // Loop over each role. - foreach( $roles as $role => $role_label ) { - - // Query users (for this role only). - $args['role'] = $role; - $wp_user_query = new WP_User_Query( $args ); - $users = (array) $wp_user_query->get_results(); - $total_users = $wp_user_query->get_total(); - - //acf_log( $args ); - //acf_log( '- ', count($users) ); - //acf_log( '- ', $total_users ); - - // If users were found for this query... - if( $users ) { - - // Append optgroup of results. - $role_results = array(); - foreach( $users as $user ) { - $role_results[] = $this->get_result( $user ); - } - $results[] = array( - 'text' => $role_label, - 'children' => $role_results - ); - - // End loop when enough results have been found. - if( count($users) === $args['number'] ) { - - // Determine if more results exist. - // As this query does return grouped results, the calculation is best left fuzzy to avoid querying the next group (">="). - $this->more = ( $total_users >= count($users) + $args['offset'] ); - break; - - // Otherwise, modify the args so that the next query can continue on correctly. - } else { - $args['offset'] = 0; - $args['number'] -= count($users); - } - - // If no users were found (for the current pagination args), but there were users found for previous pages... - // Modify the args so that the next query is offset slightly less (the number of total users) and can continue on correctly. - } elseif( $total_users ) { - $args['offset'] -= $total_users; - continue; - - // Ignore roles that will never return a result. - } else { - continue; - } - } - } - - /** - * Filters the query results. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param array $results The query results. - * @param array $args The query args. - * @param ACF_Ajax_Query $query The query object. - */ - return apply_filters( "acf/ajax/query_users/results", $results, $args, $this ); - } - - /** - * get_result - * - * Returns a single result for the given item object. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param mixed $item A single item from the queried results. - * @return string - */ - function get_result( $user ) { - $item = acf_get_user_result( $user ); - - /** - * Filters the result item. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param array $item The choice id and text. - * @param ACF_User $user The user object. - * @param ACF_Ajax_Query $query The query object. - */ - return apply_filters( "acf/ajax/query_users/result", $item, $user, $this ); - } - - /** - * Filters the WP_User_Query search columns. - * - * @date 9/3/20 - * @since 5.8.8 - * - * @param array $columns An array of column names to be searched. - * @param string $search The search term. - * @param WP_User_Query $WP_User_Query The WP_User_Query instance. - * @return array - */ - function filter_search_columns( $columns, $search, $WP_User_Query ) { - - /** - * Filters the column names to be searched. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param array $columns An array of column names to be searched. - * @param string $search The search term. - * @param WP_User_Query $WP_User_Query The WP_User_Query instance. - * @param ACF_Ajax_Query $query The query object. - */ - return apply_filters( "acf/ajax/query_users/search_columns", $columns, $search, $WP_User_Query, $this ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -acf_new_instance('ACF_Ajax_Query_Users'); +if ( ! class_exists( 'ACF_Ajax_Query_Users' ) ) : + + class ACF_Ajax_Query_Users extends ACF_Ajax_Query { + + /** @var string The AJAX action name. */ + var $action = 'acf/ajax/query_users'; + + /** + * init_request + * + * Called at the beginning of a request to setup properties. + * + * @date 23/5/19 + * @since 5.8.1 + * + * @param array $request The request args. + * @return void + */ + function init_request( $request ) { + parent::init_request( $request ); + + // Customize query. + add_filter( 'user_search_columns', array( $this, 'filter_search_columns' ), 10, 3 ); + + /** + * Fires when a request is made. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $request The query request. + * @param ACF_Ajax_Query $query The query object. + */ + do_action( 'acf/ajax/query_users/init', $request, $this ); + } + + /** + * get_args + * + * Returns an array of args for this query. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return array + */ + function get_args( $request ) { + $args = parent::get_args( $request ); + $args['number'] = $this->per_page; + $args['paged'] = $this->page; + if ( $this->is_search ) { + $args['search'] = "*{$this->search}*"; + } + + /** + * Filters the query args. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $args The query args. + * @param array $request The query request. + * @param ACF_Ajax_Query $query The query object. + */ + return apply_filters( 'acf/ajax/query_users/args', $args, $request, $this ); + } + + /** + * Prepares args for the get_results() method. + * + * @date 23/3/20 + * @since 5.8.9 + * + * @param array args The query args. + * @return array + */ + function prepare_args( $args ) { + + // Parse pagination args that may have been modified. + if ( isset( $args['users_per_page'] ) ) { + $this->per_page = intval( $args['users_per_page'] ); + unset( $args['users_per_page'] ); + + } elseif ( isset( $args['number'] ) ) { + $this->per_page = intval( $args['number'] ); + } + + if ( isset( $args['paged'] ) ) { + $this->page = intval( $args['paged'] ); + unset( $args['paged'] ); + } + + // Set pagination args for fine control. + $args['number'] = $this->per_page; + $args['offset'] = $this->per_page * ( $this->page - 1 ); + $args['count_total'] = true; + return $args; + } + + /** + * get_results + * + * Returns an array of results for the given args. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array args The query args. + * @return array + */ + function get_results( $args ) { + $results = array(); + + // Prepare args for quey. + $args = $this->prepare_args( $args ); + + // Get result groups. + if ( ! empty( $args['role__in'] ) ) { + $roles = acf_get_user_role_labels( $args['role__in'] ); + } else { + $roles = acf_get_user_role_labels(); + } + + // Return a flat array of results when searching or when queriying one group only. + if ( $this->is_search || count( $roles ) === 1 ) { + + // Query users and append to results. + $wp_user_query = new WP_User_Query( $args ); + $users = (array) $wp_user_query->get_results(); + $total_users = $wp_user_query->get_total(); + foreach ( $users as $user ) { + $results[] = $this->get_result( $user ); + } + + // Determine if more results exist. + // As this query does not return grouped results, the calculation can be exact (">"). + $this->more = ( $total_users > count( $users ) + $args['offset'] ); + + // Otherwise, group results via role. + } else { + + // Unset args that will interfer with query results. + unset( $args['role__in'], $args['role__not_in'] ); + + // Loop over each role. + foreach ( $roles as $role => $role_label ) { + + // Query users (for this role only). + $args['role'] = $role; + $wp_user_query = new WP_User_Query( $args ); + $users = (array) $wp_user_query->get_results(); + $total_users = $wp_user_query->get_total(); + + // acf_log( $args ); + // acf_log( '- ', count($users) ); + // acf_log( '- ', $total_users ); + + // If users were found for this query... + if ( $users ) { + + // Append optgroup of results. + $role_results = array(); + foreach ( $users as $user ) { + $role_results[] = $this->get_result( $user ); + } + $results[] = array( + 'text' => $role_label, + 'children' => $role_results, + ); + + // End loop when enough results have been found. + if ( count( $users ) === $args['number'] ) { + + // Determine if more results exist. + // As this query does return grouped results, the calculation is best left fuzzy to avoid querying the next group (">="). + $this->more = ( $total_users >= count( $users ) + $args['offset'] ); + break; + + // Otherwise, modify the args so that the next query can continue on correctly. + } else { + $args['offset'] = 0; + $args['number'] -= count( $users ); + } + + // If no users were found (for the current pagination args), but there were users found for previous pages... + // Modify the args so that the next query is offset slightly less (the number of total users) and can continue on correctly. + } elseif ( $total_users ) { + $args['offset'] -= $total_users; + continue; + + // Ignore roles that will never return a result. + } else { + continue; + } + } + } + + /** + * Filters the query results. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $results The query results. + * @param array $args The query args. + * @param ACF_Ajax_Query $query The query object. + */ + return apply_filters( 'acf/ajax/query_users/results', $results, $args, $this ); + } + + /** + * get_result + * + * Returns a single result for the given item object. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param mixed $item A single item from the queried results. + * @return string + */ + function get_result( $user ) { + $item = acf_get_user_result( $user ); + + /** + * Filters the result item. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $item The choice id and text. + * @param ACF_User $user The user object. + * @param ACF_Ajax_Query $query The query object. + */ + return apply_filters( 'acf/ajax/query_users/result', $item, $user, $this ); + } + + /** + * Filters the WP_User_Query search columns. + * + * @date 9/3/20 + * @since 5.8.8 + * + * @param array $columns An array of column names to be searched. + * @param string $search The search term. + * @param WP_User_Query $WP_User_Query The WP_User_Query instance. + * @return array + */ + function filter_search_columns( $columns, $search, $WP_User_Query ) { + + /** + * Filters the column names to be searched. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $columns An array of column names to be searched. + * @param string $search The search term. + * @param WP_User_Query $WP_User_Query The WP_User_Query instance. + * @param ACF_Ajax_Query $query The query object. + */ + return apply_filters( 'acf/ajax/query_users/search_columns', $columns, $search, $WP_User_Query, $this ); + } + } + + acf_new_instance( 'ACF_Ajax_Query_Users' ); endif; // class_exists check diff --git a/includes/ajax/class-acf-ajax-query.php b/includes/ajax/class-acf-ajax-query.php index 026b05a..dd1bfe6 100644 --- a/includes/ajax/class-acf-ajax-query.php +++ b/includes/ajax/class-acf-ajax-query.php @@ -1,150 +1,152 @@ init_request( $request ); - - // Get query args. - $args = $this->get_args( $request ); - - // Get query results. - $results = $this->get_results( $args ); - if( is_wp_error($results) ) { - return $results; - } - - // Return response. - return array( - 'results' => $results, - 'more' => $this->more - ); - } - - /** - * init_request - * - * Called at the beginning of a request to setup properties. - * - * @date 23/5/19 - * @since 5.8.1 - * - * @param array $request The request args. - * @return void - */ - function init_request( $request ) { - - // Get field for this query. - if( isset($request['field_key']) ) { - $this->field = acf_get_field( $request['field_key'] ); - } - - // Update query properties. - if( isset($request['page']) ) { - $this->page = intval($request['page']); - } - if( isset($request['per_page']) ) { - $this->per_page = intval($request['per_page']); - } - if( isset($request['search']) && acf_not_empty($request['search']) ) { - $this->search = sanitize_text_field($request['search']); - $this->is_search = true; - } - if( isset($request['post_id']) ) { - $this->post_id = $request['post_id']; - } - } - - /** - * get_args - * - * Returns an array of args for this query. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param array $request The request args. - * @return array - */ - function get_args( $request ) { - - // Allow for custom "query" arg. - if( isset($request['query']) ) { - return (array) $request['query']; - } - return array(); - } - - /** - * get_items - * - * Returns an array of results for the given args. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param array args The query args. - * @return array - */ - function get_results( $args ) { - return array(); - } - - /** - * get_item - * - * Returns a single result for the given item object. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param mixed $item A single item from the queried results. - * @return array An array containing "id" and "text". - */ - function get_result( $item ) { - return false; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Ajax_Query' ) ) : + + class ACF_Ajax_Query extends ACF_Ajax { + + /** @var bool Prevents access for non-logged in users. */ + var $public = true; + + /** @var int The page of results to return. */ + var $page = 1; + + /** @var int The number of results per page. */ + var $per_page = 20; + + /** @var bool Signifies whether or not this AJAX query has more pages to load. */ + var $more = false; + + /** @var string The searched term. */ + var $search = ''; + + /** @var bool Signifies whether the current query is a search. */ + var $is_search = false; + + /** @var (int|string) The post_id being edited. */ + var $post_id = 0; + + /** @var array The ACF field related to this query. */ + var $field = false; + + /** + * get_response + * + * Returns the response data to sent back. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return (array|WP_Error) The response data or WP_Error. + */ + function get_response( $request ) { + + // Init request. + $this->init_request( $request ); + + // Get query args. + $args = $this->get_args( $request ); + + // Get query results. + $results = $this->get_results( $args ); + if ( is_wp_error( $results ) ) { + return $results; + } + + // Return response. + return array( + 'results' => $results, + 'more' => $this->more, + ); + } + + /** + * init_request + * + * Called at the beginning of a request to setup properties. + * + * @date 23/5/19 + * @since 5.8.1 + * + * @param array $request The request args. + * @return void + */ + function init_request( $request ) { + + // Get field for this query. + if ( isset( $request['field_key'] ) ) { + $this->field = acf_get_field( $request['field_key'] ); + } + + // Update query properties. + if ( isset( $request['page'] ) ) { + $this->page = intval( $request['page'] ); + } + if ( isset( $request['per_page'] ) ) { + $this->per_page = intval( $request['per_page'] ); + } + if ( isset( $request['search'] ) && acf_not_empty( $request['search'] ) ) { + $this->search = sanitize_text_field( $request['search'] ); + $this->is_search = true; + } + if ( isset( $request['post_id'] ) ) { + $this->post_id = $request['post_id']; + } + } + + /** + * get_args + * + * Returns an array of args for this query. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return array + */ + function get_args( $request ) { + + // Allow for custom "query" arg. + if ( isset( $request['query'] ) ) { + return (array) $request['query']; + } + return array(); + } + + /** + * get_items + * + * Returns an array of results for the given args. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array args The query args. + * @return array + */ + function get_results( $args ) { + return array(); + } + + /** + * get_item + * + * Returns a single result for the given item object. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param mixed $item A single item from the queried results. + * @return array An array containing "id" and "text". + */ + function get_result( $item ) { + return false; + } + } + endif; // class_exists check diff --git a/includes/ajax/class-acf-ajax-upgrade.php b/includes/ajax/class-acf-ajax-upgrade.php index 2f08e53..b01452b 100644 --- a/includes/ajax/class-acf-ajax-upgrade.php +++ b/includes/ajax/class-acf-ajax-upgrade.php @@ -1,54 +1,56 @@ has('value') ) { - return acf_update_user_setting( $this->get('name'), $this->get('value') ); - - // get - } else { - return acf_get_user_setting( $this->get('name') ); - } - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -acf_new_instance('ACF_Ajax_User_Setting'); +if ( ! class_exists( 'ACF_Ajax_User_Setting' ) ) : + + class ACF_Ajax_User_Setting extends ACF_Ajax { + + /** @var string The AJAX action name. */ + var $action = 'acf/ajax/user_setting'; + + /** @var bool Prevents access for non-logged in users. */ + var $public = true; + + /** + * get_response + * + * Returns the response data to sent back. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return mixed The response data or WP_Error. + */ + function get_response( $request ) { + + // update + if ( $this->has( 'value' ) ) { + return acf_update_user_setting( $this->get( 'name' ), $this->get( 'value' ) ); + + // get + } else { + return acf_get_user_setting( $this->get( 'name' ) ); + } + } + } + + acf_new_instance( 'ACF_Ajax_User_Setting' ); endif; // class_exists check diff --git a/includes/ajax/class-acf-ajax.php b/includes/ajax/class-acf-ajax.php index ed09791..9894bb7 100644 --- a/includes/ajax/class-acf-ajax.php +++ b/includes/ajax/class-acf-ajax.php @@ -1,227 +1,232 @@ initialize(); - $this->add_actions(); - } - - /** - * has - * - * Returns true if the request has data for the given key. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param string $key The data key. - * @return boolean - */ - function has( $key = '' ) { - return isset($this->request[$key]); - } - - /** - * get - * - * Returns request data for the given key. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param string $key The data key. - * @return mixed - */ - function get( $key = '' ) { - return isset($this->request[$key]) ? $this->request[$key] : null; - } - - /** - * Sets request data for the given key. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param string $key The data key. - * @param mixed $value The data value. - * @return ACF_Ajax - */ - function set( $key = '', $value = null ) { - $this->request[$key] = $value; - return $this; - } - - /** - * initialize - * - * Allows easy access to modifying properties without changing constructor. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param void - * @return void - */ - function initialize() { - /* do nothing */ - } - - /** - * add_actions - * - * Adds the ajax actions for this response. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param void - * @return void - */ - function add_actions() { - - // add action for logged-in users - add_action( "wp_ajax_{$this->action}", array($this, 'request') ); - - // add action for non logged-in users - if( $this->public ) { - add_action( "wp_ajax_nopriv_{$this->action}", array($this, 'request') ); - } - } - - /** - * request - * - * Callback for ajax action. Sets up properties and calls the get_response() function. - * - * @date 1/8/18 - * @since 5.7.2 - * - * @param void - * @return void - */ - function request() { - - // Store data for has() and get() functions. - $this->request = wp_unslash($_REQUEST); - - // Verify request and handle error. - $error = $this->verify_request( $this->request ); - if( is_wp_error( $error ) ) { - $this->send( $error ); - } - - // Send response. - $this->send( $this->get_response( $this->request ) ); - } - - /** - * Verifies the request. - * - * @date 9/3/20 - * @since 5.8.8 - * - * @param array $request The request args. - * @return (bool|WP_Error) True on success, WP_Error on fail. - */ - function verify_request( $request ) { - - // Verify nonce. - if( !acf_verify_ajax() ) { - return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'acf' ), array( 'status' => 404 ) ); - } - return true; - } - - /** - * get_response - * - * Returns the response data to sent back. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param array $request The request args. - * @return mixed The response data or WP_Error. - */ - function get_response( $request ) { - return true; - } - - /** - * send - * - * Sends back JSON based on the $response as either success or failure. - * - * @date 31/7/18 - * @since 5.7.2 - * - * @param mixed $response The response to send back. - * @return void - */ - function send( $response ) { - - // Return error. - if( is_wp_error($response) ) { - $this->send_error( $response ); - - // Return success. - } else { - wp_send_json( $response ); - } - } - - /** - * Sends a JSON response for the given WP_Error object. - * - * @date 8/3/20 - * @since 5.8.8 - * - * @param WP_Error error The error object. - * @return void - */ - function send_error( $error ) { - - // Get error status - $error_data = $error->get_error_data(); - if( is_array($error_data) && isset($error_data['status']) ) { - $status_code = $error_data['status']; - } else { - $status_code = 500; - } - - wp_send_json(array( - 'code' => $error->get_error_code(), - 'message' => $error->get_error_message(), - 'data' => $error->get_error_data() - ), $status_code); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Ajax' ) ) : + + class ACF_Ajax { + + /** @var string The AJAX action name. */ + var $action = ''; + + /** @var array The $_REQUEST data. */ + var $request; + + /** @var bool Prevents access for non-logged in users. */ + var $public = false; + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param void + * @return void + */ + function __construct() { + $this->initialize(); + $this->add_actions(); + } + + /** + * has + * + * Returns true if the request has data for the given key. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param string $key The data key. + * @return boolean + */ + function has( $key = '' ) { + return isset( $this->request[ $key ] ); + } + + /** + * get + * + * Returns request data for the given key. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param string $key The data key. + * @return mixed + */ + function get( $key = '' ) { + return isset( $this->request[ $key ] ) ? $this->request[ $key ] : null; + } + + /** + * Sets request data for the given key. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param string $key The data key. + * @param mixed $value The data value. + * @return ACF_Ajax + */ + function set( $key = '', $value = null ) { + $this->request[ $key ] = $value; + return $this; + } + + /** + * initialize + * + * Allows easy access to modifying properties without changing constructor. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param void + * @return void + */ + function initialize() { + /* do nothing */ + } + + /** + * add_actions + * + * Adds the ajax actions for this response. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param void + * @return void + */ + function add_actions() { + + // add action for logged-in users + add_action( "wp_ajax_{$this->action}", array( $this, 'request' ) ); + + // add action for non logged-in users + if ( $this->public ) { + add_action( "wp_ajax_nopriv_{$this->action}", array( $this, 'request' ) ); + } + } + + /** + * request + * + * Callback for ajax action. Sets up properties and calls the get_response() function. + * + * @date 1/8/18 + * @since 5.7.2 + * + * @param void + * @return void + */ + function request() { + + // Store data for has() and get() functions. + $this->request = wp_unslash( $_REQUEST ); + + // Verify request and handle error. + $error = $this->verify_request( $this->request ); + if ( is_wp_error( $error ) ) { + $this->send( $error ); + } + + // Send response. + $this->send( $this->get_response( $this->request ) ); + } + + /** + * Verifies the request. + * + * @date 9/3/20 + * @since 5.8.8 + * + * @param array $request The request args. + * @return (bool|WP_Error) True on success, WP_Error on fail. + */ + function verify_request( $request ) { + + // Verify nonce. + if ( ! acf_verify_ajax() ) { + return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'acf' ), array( 'status' => 404 ) ); + } + return true; + } + + /** + * get_response + * + * Returns the response data to sent back. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param array $request The request args. + * @return mixed The response data or WP_Error. + */ + function get_response( $request ) { + return true; + } + + /** + * send + * + * Sends back JSON based on the $response as either success or failure. + * + * @date 31/7/18 + * @since 5.7.2 + * + * @param mixed $response The response to send back. + * @return void + */ + function send( $response ) { + + // Return error. + if ( is_wp_error( $response ) ) { + $this->send_error( $response ); + + // Return success. + } else { + wp_send_json( $response ); + } + } + + /** + * Sends a JSON response for the given WP_Error object. + * + * @date 8/3/20 + * @since 5.8.8 + * + * @param WP_Error error The error object. + * @return void + */ + function send_error( $error ) { + + // Get error status + $error_data = $error->get_error_data(); + if ( is_array( $error_data ) && isset( $error_data['status'] ) ) { + $status_code = $error_data['status']; + } else { + $status_code = 500; + } + + wp_send_json( + array( + 'code' => $error->get_error_code(), + 'message' => $error->get_error_message(), + 'data' => $error->get_error_data(), + ), + $status_code + ); + } + } + endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/api/api-helpers.php b/includes/api/api-helpers.php index 1ef5cd8..ae9884e 100644 --- a/includes/api/api-helpers.php +++ b/includes/api/api-helpers.php @@ -1,35 +1,35 @@ -has_setting() -* -* @date 2/2/18 -* @since 5.6.5 -* -* @param n/a -* @return n/a -*/ + * acf_has_setting + * + * alias of acf()->has_setting() + * + * @date 2/2/18 + * @since 5.6.5 + * + * @param n/a + * @return n/a + */ function acf_has_setting( $name = '' ) { return acf()->has_setting( $name ); @@ -37,16 +37,16 @@ function acf_has_setting( $name = '' ) { /** -* acf_raw_setting -* -* alias of acf()->get_setting() -* -* @date 2/2/18 -* @since 5.6.5 -* -* @param n/a -* @return n/a -*/ + * acf_raw_setting + * + * alias of acf()->get_setting() + * + * @date 2/2/18 + * @since 5.6.5 + * + * @param n/a + * @return n/a + */ function acf_raw_setting( $name = '' ) { return acf()->get_setting( $name ); @@ -58,39 +58,39 @@ function acf_raw_setting( $name = '' ) { * * alias of acf()->update_setting() * -* @type function -* @date 28/09/13 -* @since 5.0.0 +* @type function +* @date 28/09/13 +* @since 5.0.0 * -* @param $name (string) -* @param $value (mixed) -* @return n/a +* @param $name (string) +* @param $value (mixed) +* @return n/a */ function acf_update_setting( $name, $value ) { - + // validate name $name = acf_validate_setting( $name ); - + // update return acf()->update_setting( $name, $value ); } /** -* acf_validate_setting -* -* Returns the changed setting name if available. -* -* @date 2/2/18 -* @since 5.6.5 -* -* @param n/a -* @return n/a -*/ + * acf_validate_setting + * + * Returns the changed setting name if available. + * + * @date 2/2/18 + * @since 5.6.5 + * + * @param n/a + * @return n/a + */ function acf_validate_setting( $name = '' ) { - return apply_filters( "acf/validate_setting", $name ); + return apply_filters( 'acf/validate_setting', $name ); } @@ -99,27 +99,27 @@ function acf_validate_setting( $name = '' ) { * * alias of acf()->get_setting() * -* @type function -* @date 28/09/13 -* @since 5.0.0 +* @type function +* @date 28/09/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_get_setting( $name, $value = null ) { - + // validate name $name = acf_validate_setting( $name ); - + // check settings - if( acf_has_setting($name) ) { + if ( acf_has_setting( $name ) ) { $value = acf_raw_setting( $name ); } - + // filter $value = apply_filters( "acf/settings/{$name}", $value ); - + // return return $value; } @@ -130,44 +130,44 @@ function acf_get_setting( $name, $value = null ) { * * This function will add a value into the settings array found in the acf object * -* @type function -* @date 28/09/13 -* @since 5.0.0 +* @type function +* @date 28/09/13 +* @since 5.0.0 * -* @param $name (string) -* @param $value (mixed) -* @return n/a +* @param $name (string) +* @param $value (mixed) +* @return n/a */ function acf_append_setting( $name, $value ) { - + // vars $setting = acf_raw_setting( $name ); - + // bail ealry if not array - if( !is_array($setting) ) { + if ( ! is_array( $setting ) ) { $setting = array(); } - + // append $setting[] = $value; - + // update return acf_update_setting( $name, $setting ); } /** -* acf_get_data -* -* Returns data. -* -* @date 28/09/13 -* @since 5.0.0 -* -* @param string $name -* @return mixed -*/ + * acf_get_data + * + * Returns data. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $name + * @return mixed + */ function acf_get_data( $name ) { return acf()->get_data( $name ); @@ -175,17 +175,17 @@ function acf_get_data( $name ) { /** -* acf_set_data -* -* Sets data. -* -* @date 28/09/13 -* @since 5.0.0 -* -* @param string $name -* @param mixed $value -* @return n/a -*/ + * acf_set_data + * + * Sets data. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param string $name + * @param mixed $value + * @return n/a + */ function acf_set_data( $name, $value ) { return acf()->set_data( $name, $value ); @@ -194,15 +194,15 @@ function acf_set_data( $name, $value ) { /** * Appends data to an existing key. * - * @date 11/06/2020 - * @since 5.9.0 + * @date 11/06/2020 + * @since 5.9.0 * - * @param string $name The data name. - * @return array $data The data array. + * @param string $name The data name. + * @return array $data The data array. */ function acf_append_data( $name, $data ) { $prev_data = acf()->get_data( $name ); - if( is_array($prev_data) ) { + if ( is_array( $prev_data ) ) { $data = array_merge( $prev_data, $data ); } acf()->set_data( $name, $data ); @@ -213,18 +213,18 @@ function acf_append_data( $name, $data ) { * * alias of acf()->init() * -* @type function -* @date 28/09/13 -* @since 5.0.0 +* @type function +* @date 28/09/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_init() { - + acf()->init(); - + } @@ -233,23 +233,23 @@ function acf_init() { * * This function will return true if this action has already been done * -* @type function -* @date 16/12/2015 -* @since 5.3.2 +* @type function +* @date 16/12/2015 +* @since 5.3.2 * -* @param $name (string) -* @return (boolean) +* @param $name (string) +* @return (boolean) */ function acf_has_done( $name ) { - + // return true if already done - if( acf_raw_setting("has_done_{$name}") ) { + if ( acf_raw_setting( "has_done_{$name}" ) ) { return true; } - + // update setting and return - acf_update_setting("has_done_{$name}", true); + acf_update_setting( "has_done_{$name}", true ); return false; } @@ -261,19 +261,19 @@ function acf_has_done( $name ) { * * This function will return the path to a file within an external folder * -* @type function -* @date 22/2/17 -* @since 5.5.8 +* @type function +* @date 22/2/17 +* @since 5.5.8 * -* @param $file (string) -* @param $path (string) -* @return (string) +* @param $file (string) +* @param $path (string) +* @return (string) */ function acf_get_external_path( $file, $path = '' ) { - - return plugin_dir_path( $file ) . $path; - + + return plugin_dir_path( $file ) . $path; + } @@ -282,64 +282,62 @@ function acf_get_external_path( $file, $path = '' ) { * * This function will return the url to a file within an external folder * -* @type function -* @date 22/2/17 -* @since 5.5.8 +* @type function +* @date 22/2/17 +* @since 5.5.8 * -* @param $file (string) -* @param $path (string) -* @return (string) +* @param $file (string) +* @param $path (string) +* @return (string) */ function acf_get_external_dir( $file, $path = '' ) { - - return acf_plugin_dir_url( $file ) . $path; - + + return acf_plugin_dir_url( $file ) . $path; + } /** -* acf_plugin_dir_url -* -* This function will calculate the url to a plugin folder. -* Different to the WP plugin_dir_url(), this function can calculate for urls outside of the plugins folder (theme include). -* -* @date 13/12/17 -* @since 5.6.8 -* -* @param type $var Description. Default. -* @return type Description. -*/ + * acf_plugin_dir_url + * + * This function will calculate the url to a plugin folder. + * Different to the WP plugin_dir_url(), this function can calculate for urls outside of the plugins folder (theme include). + * + * @date 13/12/17 + * @since 5.6.8 + * + * @param type $var Description. Default. + * @return type Description. + */ function acf_plugin_dir_url( $file ) { - + // vars $path = plugin_dir_path( $file ); $path = wp_normalize_path( $path ); - - + // check plugins - $check_path = wp_normalize_path( realpath(WP_PLUGIN_DIR) ); - if( strpos($path, $check_path) === 0 ) { + $check_path = wp_normalize_path( realpath( WP_PLUGIN_DIR ) ); + if ( strpos( $path, $check_path ) === 0 ) { return str_replace( $check_path, plugins_url(), $path ); } - + // check wp-content - $check_path = wp_normalize_path( realpath(WP_CONTENT_DIR) ); - if( strpos($path, $check_path) === 0 ) { + $check_path = wp_normalize_path( realpath( WP_CONTENT_DIR ) ); + if ( strpos( $path, $check_path ) === 0 ) { return str_replace( $check_path, content_url(), $path ); } - + // check root - $check_path = wp_normalize_path( realpath(ABSPATH) ); - if( strpos($path, $check_path) === 0 ) { - return str_replace( $check_path, site_url('/'), $path ); + $check_path = wp_normalize_path( realpath( ABSPATH ) ); + if ( strpos( $path, $check_path ) === 0 ) { + return str_replace( $check_path, site_url( '/' ), $path ); } - - - // return - return plugin_dir_url( $file ); - + + // return + return plugin_dir_url( $file ); + } @@ -348,28 +346,26 @@ function acf_plugin_dir_url( $file ) { * * This function will merge together 2 arrays and also convert any numeric values to ints * -* @type function -* @date 18/10/13 -* @since 5.0.0 +* @type function +* @date 18/10/13 +* @since 5.0.0 * -* @param $args (array) -* @param $defaults (array) -* @return $args (array) +* @param $args (array) +* @param $defaults (array) +* @return $args (array) */ function acf_parse_args( $args, $defaults = array() ) { - + // parse args $args = wp_parse_args( $args, $defaults ); - - + // parse types $args = acf_parse_types( $args ); - - + // return return $args; - + } @@ -378,12 +374,12 @@ function acf_parse_args( $args, $defaults = array() ) { * * This function will convert any numeric values to int and trim strings * -* @type function -* @date 18/10/13 -* @since 5.0.0 +* @type function +* @date 18/10/13 +* @since 5.0.0 * -* @param $var (mixed) -* @return $var (mixed) +* @param $var (mixed) +* @return $var (mixed) */ function acf_parse_types( $array ) { @@ -396,28 +392,28 @@ function acf_parse_types( $array ) { * * description * -* @type function -* @date 11/11/2014 -* @since 5.0.9 +* @type function +* @date 11/11/2014 +* @since 5.0.9 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_parse_type( $v ) { - + // Check if is string. - if( is_string($v) ) { - + if ( is_string( $v ) ) { + // Trim ("Word " = "Word"). $v = trim( $v ); - + // Convert int strings to int ("123" = 123). - if( is_numeric($v) && strval(intval($v)) === $v ) { + if ( is_numeric( $v ) && strval( intval( $v ) ) === $v ) { $v = intval( $v ); } } - + // return. return $v; } @@ -428,33 +424,32 @@ function acf_parse_type( $v ) { * * This function will load in a file from the 'admin/views' folder and allow variables to be passed through * -* @type function -* @date 28/09/13 -* @since 5.0.0 +* @type function +* @date 28/09/13 +* @since 5.0.0 * -* @param $view_name (string) -* @param $args (array) -* @return n/a +* @param $view_name (string) +* @param $args (array) +* @return n/a */ function acf_get_view( $path = '', $args = array() ) { - + // allow view file name shortcut - if( substr($path, -4) !== '.php' ) { - - $path = acf_get_path("includes/admin/views/{$path}.php"); - + if ( substr( $path, -4 ) !== '.php' ) { + + $path = acf_get_path( "includes/admin/views/{$path}.php" ); + } - - + // include - if( file_exists($path) ) { - + if ( file_exists( $path ) ) { + extract( $args ); - include( $path ); - + include $path; + } - + } @@ -463,46 +458,44 @@ function acf_get_view( $path = '', $args = array() ) { * * description * -* @type function -* @date 2/11/2014 -* @since 5.0.9 +* @type function +* @date 2/11/2014 +* @since 5.0.9 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_merge_atts( $atts, $extra = array() ) { - + // bail ealry if no $extra - if( empty($extra) ) return $atts; - - - // trim - $extra = array_map('trim', $extra); - $extra = array_filter($extra); - - - // merge in new atts - foreach( $extra as $k => $v ) { - - // append - if( $k == 'class' || $k == 'style' ) { - - $atts[ $k ] .= ' ' . $v; - - // merge - } else { - - $atts[ $k ] = $v; - - } - + if ( empty( $extra ) ) { + return $atts; } - - + + // trim + $extra = array_map( 'trim', $extra ); + $extra = array_filter( $extra ); + + // merge in new atts + foreach ( $extra as $k => $v ) { + + // append + if ( $k == 'class' || $k == 'style' ) { + + $atts[ $k ] .= ' ' . $v; + + // merge + } else { + + $atts[ $k ] = $v; + + } + } + // return return $atts; - + } @@ -511,18 +504,18 @@ function acf_merge_atts( $atts, $extra = array() ) { * * This function will create a basic nonce input * -* @type function -* @date 24/5/17 -* @since 5.6.0 +* @type function +* @date 24/5/17 +* @since 5.6.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_nonce_input( $nonce = '' ) { - + echo ''; - + } @@ -531,35 +524,32 @@ function acf_nonce_input( $nonce = '' ) { * * This function will remove the var from the array, and return the var * -* @type function -* @date 2/10/13 -* @since 5.0.0 +* @type function +* @date 2/10/13 +* @since 5.0.0 * -* @param $array (array) -* @param $key (string) -* @return (mixed) +* @param $array (array) +* @param $key (string) +* @return (mixed) */ function acf_extract_var( &$array, $key, $default = null ) { - + // check if exists // - uses array_key_exists to extract NULL values (isset will fail) - if( is_array($array) && array_key_exists($key, $array) ) { - + if ( is_array( $array ) && array_key_exists( $key, $array ) ) { + // store value $v = $array[ $key ]; - - + // unset unset( $array[ $key ] ); - - + // return return $v; - + } - - + // return return $default; } @@ -570,24 +560,24 @@ function acf_extract_var( &$array, $key, $default = null ) { * * This function will remove the vars from the array, and return the vars * -* @type function -* @date 8/10/13 -* @since 5.0.0 +* @type function +* @date 8/10/13 +* @since 5.0.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_extract_vars( &$array, $keys ) { - + $r = array(); - - foreach( $keys as $key ) { - + + foreach ( $keys as $key ) { + $r[ $key ] = acf_extract_var( $array, $key ); - + } - + return $r; } @@ -597,129 +587,127 @@ function acf_extract_vars( &$array, $keys ) { * * This function will return a sub array of data * -* @type function -* @date 15/03/2016 -* @since 5.3.2 +* @type function +* @date 15/03/2016 +* @since 5.3.2 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_get_sub_array( $array, $keys ) { - + $r = array(); - - foreach( $keys as $key ) { - + + foreach ( $keys as $key ) { + $r[ $key ] = $array[ $key ]; - + } - + return $r; - + } /** -* acf_get_post_types -* -* Returns an array of post type names. -* -* @date 7/10/13 -* @since 5.0.0 -* -* @param array $args Optional. An array of key => value arguments to match against the post type objects. Default empty array. -* @return array A list of post type names. -*/ + * acf_get_post_types + * + * Returns an array of post type names. + * + * @date 7/10/13 + * @since 5.0.0 + * + * @param array $args Optional. An array of key => value arguments to match against the post type objects. Default empty array. + * @return array A list of post type names. + */ function acf_get_post_types( $args = array() ) { - + // vars $post_types = array(); - + // extract special arg - $exclude = acf_extract_var( $args, 'exclude', array() ); + $exclude = acf_extract_var( $args, 'exclude', array() ); $exclude[] = 'acf-field'; $exclude[] = 'acf-field-group'; - + // get post type objects $objects = get_post_types( $args, 'objects' ); - + // loop - foreach( $objects as $i => $object ) { - + foreach ( $objects as $i => $object ) { + // bail early if is exclude - if( in_array($i, $exclude) ) continue; - + if ( in_array( $i, $exclude ) ) { + continue; + } + // bail early if is builtin (WP) private post type // - nav_menu_item, revision, customize_changeset, etc - if( $object->_builtin && !$object->public ) continue; - + if ( $object->_builtin && ! $object->public ) { + continue; + } + // append $post_types[] = $i; } - + // filter - $post_types = apply_filters('acf/get_post_types', $post_types, $args); - + $post_types = apply_filters( 'acf/get_post_types', $post_types, $args ); + // return return $post_types; } function acf_get_pretty_post_types( $post_types = array() ) { - + // get post types - if( empty($post_types) ) { - + if ( empty( $post_types ) ) { + // get all custom post types $post_types = acf_get_post_types(); - + } - - + // get labels $ref = array(); - $r = array(); - - foreach( $post_types as $post_type ) { - + $r = array(); + + foreach ( $post_types as $post_type ) { + // vars - $label = acf_get_post_type_label($post_type); - - + $label = acf_get_post_type_label( $post_type ); + // append to r $r[ $post_type ] = $label; - - + // increase counter - if( !isset($ref[ $label ]) ) { - + if ( ! isset( $ref[ $label ] ) ) { + $ref[ $label ] = 0; - + } - + $ref[ $label ]++; } - - + // get slugs - foreach( array_keys($r) as $i ) { - + foreach ( array_keys( $r ) as $i ) { + // vars $post_type = $r[ $i ]; - - if( $ref[ $post_type ] > 1 ) { - + + if ( $ref[ $post_type ] > 1 ) { + $r[ $i ] .= ' (' . $i . ')'; - + } - } - - + // return return $r; - + } @@ -729,33 +717,31 @@ function acf_get_pretty_post_types( $post_types = array() ) { * * This function will return a pretty label for a specific post_type * -* @type function -* @date 5/07/2016 -* @since 5.4.0 +* @type function +* @date 5/07/2016 +* @since 5.4.0 * -* @param $post_type (string) -* @return (string) +* @param $post_type (string) +* @return (string) */ function acf_get_post_type_label( $post_type ) { - + // vars $label = $post_type; - - + // check that object exists // - case exists when importing field group from another install and post type does not exist - if( post_type_exists($post_type) ) { - - $obj = get_post_type_object($post_type); + if ( post_type_exists( $post_type ) ) { + + $obj = get_post_type_object( $post_type ); $label = $obj->labels->singular_name; - + } - - + // return return $label; - + } @@ -764,31 +750,30 @@ function acf_get_post_type_label( $post_type ) { * * This function will look at the $_POST['_acf_nonce'] value and return true or false * -* @type function -* @date 15/10/13 -* @since 5.0.0 +* @type function +* @date 15/10/13 +* @since 5.0.0 * -* @param $nonce (string) -* @return (boolean) +* @param $nonce (string) +* @return (boolean) */ -function acf_verify_nonce( $value) { - +function acf_verify_nonce( $value ) { + // vars - $nonce = acf_maybe_get_POST('_acf_nonce'); - - + $nonce = acf_maybe_get_POST( '_acf_nonce' ); + // bail early nonce does not match (post|user|comment|term) - if( !$nonce || !wp_verify_nonce($nonce, $value) ) return false; - - + if ( ! $nonce || ! wp_verify_nonce( $nonce, $value ) ) { + return false; + } + // reset nonce (only allow 1 save) $_POST['_acf_nonce'] = false; - - + // return return true; - + } @@ -798,27 +783,27 @@ function acf_verify_nonce( $value) { * This function will return true if the current AJAX request is valid * It's action will also allow WPML to set the lang and avoid AJAX get_posts issues * -* @type function -* @date 7/08/2015 -* @since 5.2.3 +* @type function +* @date 7/08/2015 +* @since 5.2.3 * -* @param n/a -* @return (boolean) +* @param n/a +* @return (boolean) */ function acf_verify_ajax() { - + // vars - $nonce = isset($_REQUEST['nonce']) ? $_REQUEST['nonce'] : ''; - + $nonce = isset( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : ''; + // bail early if not acf nonce - if( !$nonce || !wp_verify_nonce($nonce, 'acf_nonce') ) { + if ( ! $nonce || ! wp_verify_nonce( $nonce, 'acf_nonce' ) ) { return false; } - + // action for 3rd party customization - do_action('acf/verify_ajax'); - + do_action( 'acf/verify_ajax' ); + // return return true; } @@ -829,101 +814,88 @@ function acf_verify_ajax() { * * This function will return an array of available image sizes * -* @type function -* @date 23/10/13 -* @since 5.0.0 +* @type function +* @date 23/10/13 +* @since 5.0.0 * -* @param n/a -* @return (array) +* @param n/a +* @return (array) */ function acf_get_image_sizes() { - + // vars $sizes = array( - 'thumbnail' => __("Thumbnail",'acf'), - 'medium' => __("Medium",'acf'), - 'large' => __("Large",'acf') + 'thumbnail' => __( 'Thumbnail', 'acf' ), + 'medium' => __( 'Medium', 'acf' ), + 'large' => __( 'Large', 'acf' ), ); - - + // find all sizes $all_sizes = get_intermediate_image_sizes(); - - + // add extra registered sizes - if( !empty($all_sizes) ) { - - foreach( $all_sizes as $size ) { - + if ( ! empty( $all_sizes ) ) { + + foreach ( $all_sizes as $size ) { + // bail early if already in array - if( isset($sizes[ $size ]) ) { - + if ( isset( $sizes[ $size ] ) ) { + continue; - + } - - + // append to array - $label = str_replace('-', ' ', $size); - $label = ucwords( $label ); + $label = str_replace( '-', ' ', $size ); + $label = ucwords( $label ); $sizes[ $size ] = $label; - + } - } - - + // add sizes - foreach( array_keys($sizes) as $s ) { - + foreach ( array_keys( $sizes ) as $s ) { + // vars - $data = acf_get_image_size($s); - - + $data = acf_get_image_size( $s ); + // append - if( $data['width'] && $data['height'] ) { - + if ( $data['width'] && $data['height'] ) { + $sizes[ $s ] .= ' (' . $data['width'] . ' x ' . $data['height'] . ')'; - + } - } - - + // add full end - $sizes['full'] = __("Full Size",'acf'); - - + $sizes['full'] = __( 'Full Size', 'acf' ); + // filter for 3rd party customization $sizes = apply_filters( 'acf/get_image_sizes', $sizes ); - - + // return return $sizes; - + } function acf_get_image_size( $s = '' ) { - + // global global $_wp_additional_image_sizes; - - + // rename for nicer code $_sizes = $_wp_additional_image_sizes; - - + // vars $data = array( - 'width' => isset($_sizes[$s]['width']) ? $_sizes[$s]['width'] : get_option("{$s}_size_w"), - 'height' => isset($_sizes[$s]['height']) ? $_sizes[$s]['height'] : get_option("{$s}_size_h") + 'width' => isset( $_sizes[ $s ]['width'] ) ? $_sizes[ $s ]['width'] : get_option( "{$s}_size_w" ), + 'height' => isset( $_sizes[ $s ]['height'] ) ? $_sizes[ $s ]['height'] : get_option( "{$s}_size_h" ), ); - - + // return return $data; - + } /** @@ -931,22 +903,22 @@ function acf_get_image_size( $s = '' ) { * * Similar to the version_compare() function but with extra functionality. * - * @date 21/11/16 - * @since 5.5.0 + * @date 21/11/16 + * @since 5.5.0 * - * @param string $left The left version number. - * @param string $compare The compare operator. - * @param string $right The right version number. - * @return bool + * @param string $left The left version number. + * @param string $compare The compare operator. + * @param string $right The right version number. + * @return bool */ function acf_version_compare( $left = '', $compare = '>', $right = '' ) { - + // Detect 'wp' placeholder. - if( $left === 'wp' ) { + if ( $left === 'wp' ) { global $wp_version; $left = $wp_version; } - + // Return result. return version_compare( $left, $right, $compare ); } @@ -957,27 +929,26 @@ function acf_version_compare( $left = '', $compare = '>', $right = '' ) { * * This function will remove any '-beta1' or '-RC1' strings from a version * -* @type function -* @date 24/11/16 -* @since 5.5.0 +* @type function +* @date 24/11/16 +* @since 5.5.0 * -* @param $version (string) -* @return (string) +* @param $version (string) +* @return (string) */ function acf_get_full_version( $version = '1' ) { - + // remove '-beta1' or '-RC1' - if( $pos = strpos($version, '-') ) { - - $version = substr($version, 0, $pos); - + if ( $pos = strpos( $version, '-' ) ) { + + $version = substr( $version, 0, $pos ); + } - - + // return return $version; - + } @@ -986,28 +957,31 @@ function acf_get_full_version( $version = '1' ) { * * This function is a wrapper for the get_terms() function * -* @type function -* @date 28/09/2016 -* @since 5.4.0 +* @type function +* @date 28/09/2016 +* @since 5.4.0 * -* @param $args (array) -* @return (array) +* @param $args (array) +* @return (array) */ function acf_get_terms( $args ) { - + // defaults - $args = wp_parse_args($args, array( - 'taxonomy' => null, - 'hide_empty' => false, - 'update_term_meta_cache' => false, - )); - + $args = wp_parse_args( + $args, + array( + 'taxonomy' => null, + 'hide_empty' => false, + 'update_term_meta_cache' => false, + ) + ); + // parameters changed in version 4.5 - if( acf_version_compare('wp', '<', '4.5') ) { + if ( acf_version_compare( 'wp', '<', '4.5' ) ) { return get_terms( $args['taxonomy'], $args ); } - + // return return get_terms( $args ); } @@ -1018,70 +992,65 @@ function acf_get_terms( $args ) { * * This function will return an array of available taxonomy terms * -* @type function -* @date 7/10/13 -* @since 5.0.0 +* @type function +* @date 7/10/13 +* @since 5.0.0 * -* @param $taxonomies (array) -* @return (array) +* @param $taxonomies (array) +* @return (array) */ function acf_get_taxonomy_terms( $taxonomies = array() ) { - + // force array $taxonomies = acf_get_array( $taxonomies ); - - + // get pretty taxonomy names $taxonomies = acf_get_pretty_taxonomies( $taxonomies ); - - + // vars $r = array(); - - + // populate $r - foreach( array_keys($taxonomies) as $taxonomy ) { - + foreach ( array_keys( $taxonomies ) as $taxonomy ) { + // vars - $label = $taxonomies[ $taxonomy ]; + $label = $taxonomies[ $taxonomy ]; $is_hierarchical = is_taxonomy_hierarchical( $taxonomy ); - $terms = acf_get_terms(array( - 'taxonomy' => $taxonomy, - 'hide_empty' => false - )); - - + $terms = acf_get_terms( + array( + 'taxonomy' => $taxonomy, + 'hide_empty' => false, + ) + ); + // bail early i no terms - if( empty($terms) ) continue; - - + if ( empty( $terms ) ) { + continue; + } + // sort into hierachial order! - if( $is_hierarchical ) { - + if ( $is_hierarchical ) { + $terms = _get_term_children( 0, $terms, $taxonomy ); - + } - - - // add placeholder + + // add placeholder $r[ $label ] = array(); - - + // add choices - foreach( $terms as $term ) { - - $k = "{$taxonomy}:{$term->slug}"; + foreach ( $terms as $term ) { + + $k = "{$taxonomy}:{$term->slug}"; $r[ $label ][ $k ] = acf_get_term_title( $term ); - + } - } - - + // return return $r; - + } @@ -1090,50 +1059,47 @@ function acf_get_taxonomy_terms( $taxonomies = array() ) { * * This function decodes the $taxonomy:$term strings into a nested array * -* @type function -* @date 27/02/2014 -* @since 5.0.0 +* @type function +* @date 27/02/2014 +* @since 5.0.0 * -* @param $terms (array) -* @return (array) +* @param $terms (array) +* @return (array) */ function acf_decode_taxonomy_terms( $strings = false ) { - + // bail early if no terms - if( empty($strings) ) return false; - - + if ( empty( $strings ) ) { + return false; + } + // vars $terms = array(); - - + // loop - foreach( $strings as $string ) { - + foreach ( $strings as $string ) { + // vars - $data = acf_decode_taxonomy_term( $string ); + $data = acf_decode_taxonomy_term( $string ); $taxonomy = $data['taxonomy']; - $term = $data['term']; - - + $term = $data['term']; + // create empty array - if( !isset($terms[ $taxonomy ]) ) { - + if ( ! isset( $terms[ $taxonomy ] ) ) { + $terms[ $taxonomy ] = array(); - + } - - + // append $terms[ $taxonomy ][] = $term; - + } - - + // return return $terms; - + } @@ -1142,80 +1108,76 @@ function acf_decode_taxonomy_terms( $strings = false ) { * * This function will return the taxonomy and term slug for a given value * -* @type function -* @date 31/03/2014 -* @since 5.0.0 +* @type function +* @date 31/03/2014 +* @since 5.0.0 * -* @param $string (string) -* @return (array) +* @param $string (string) +* @return (array) */ function acf_decode_taxonomy_term( $value ) { - + // vars $data = array( - 'taxonomy' => '', - 'term' => '' + 'taxonomy' => '', + 'term' => '', ); - - + // int - if( is_numeric($value) ) { - + if ( is_numeric( $value ) ) { + $data['term'] = $value; - - // string - } elseif( is_string($value) ) { - - $value = explode(':', $value); - $data['taxonomy'] = isset($value[0]) ? $value[0] : ''; - $data['term'] = isset($value[1]) ? $value[1] : ''; - - // error + + // string + } elseif ( is_string( $value ) ) { + + $value = explode( ':', $value ); + $data['taxonomy'] = isset( $value[0] ) ? $value[0] : ''; + $data['term'] = isset( $value[1] ) ? $value[1] : ''; + + // error } else { - + return false; - + } - - + // allow for term_id (Used by ACF v4) - if( is_numeric($data['term']) ) { - + if ( is_numeric( $data['term'] ) ) { + // global global $wpdb; - - + // find taxonomy - if( !$data['taxonomy'] ) { - - $data['taxonomy'] = $wpdb->get_var( $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $data['term']) ); - + if ( ! $data['taxonomy'] ) { + + $data['taxonomy'] = $wpdb->get_var( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $data['term'] ) ); + } - - + // find term (may have numeric slug '123') $term = get_term_by( 'slug', $data['term'], $data['taxonomy'] ); - - + // attempt get term via ID (ACF4 uses ID) - if( !$term ) $term = get_term( $data['term'], $data['taxonomy'] ); - - + if ( ! $term ) { + $term = get_term( $data['term'], $data['taxonomy'] ); + } + // bail early if no term - if( !$term ) return false; - - + if ( ! $term ) { + return false; + } + // update $data['taxonomy'] = $term->taxonomy; - $data['term'] = $term->slug; - + $data['term'] = $term->slug; + } - - + // return return $data; - + } /** @@ -1223,11 +1185,11 @@ function acf_decode_taxonomy_term( $value ) { * * Casts the value into an array. * - * @date 9/1/19 - * @since 5.7.10 + * @date 9/1/19 + * @since 5.7.10 * - * @param mixed $val The value to cast. - * @return array + * @param mixed $val The value to cast. + * @return array */ function acf_array( $val = array() ) { return (array) $val; @@ -1236,14 +1198,14 @@ function acf_array( $val = array() ) { /** * Returns a non-array value. * - * @date 11/05/2020 - * @since 5.8.10 + * @date 11/05/2020 + * @since 5.8.10 * - * @param mixed $val The value to review. - * @return mixed + * @param mixed $val The value to review. + * @return mixed */ function acf_unarray( $val ) { - if( is_array( $val ) ) { + if ( is_array( $val ) ) { return reset( $val ); } return $val; @@ -1254,37 +1216,34 @@ function acf_unarray( $val ) { * * This function will force a variable to become an array * -* @type function -* @date 4/02/2014 -* @since 5.0.0 +* @type function +* @date 4/02/2014 +* @since 5.0.0 * -* @param $var (mixed) -* @return (array) +* @param $var (mixed) +* @return (array) */ function acf_get_array( $var = false, $delimiter = '' ) { - + // array - if( is_array($var) ) { + if ( is_array( $var ) ) { return $var; } - - + // bail early if empty - if( acf_is_empty($var) ) { + if ( acf_is_empty( $var ) ) { return array(); } - - - // string - if( is_string($var) && $delimiter ) { - return explode($delimiter, $var); + + // string + if ( is_string( $var ) && $delimiter ) { + return explode( $delimiter, $var ); } - - + // place in array return (array) $var; - + } @@ -1293,40 +1252,41 @@ function acf_get_array( $var = false, $delimiter = '' ) { * * This function will return numeric values * -* @type function -* @date 15/07/2016 -* @since 5.4.0 +* @type function +* @date 15/07/2016 +* @since 5.4.0 * -* @param $value (mixed) -* @return (mixed) +* @param $value (mixed) +* @return (mixed) */ function acf_get_numeric( $value = '' ) { - + // vars - $numbers = array(); - $is_array = is_array($value); - - + $numbers = array(); + $is_array = is_array( $value ); + // loop - foreach( (array) $value as $v ) { - - if( is_numeric($v) ) $numbers[] = (int) $v; - + foreach ( (array) $value as $v ) { + + if ( is_numeric( $v ) ) { + $numbers[] = (int) $v; + } } - - + // bail early if is empty - if( empty($numbers) ) return false; - - + if ( empty( $numbers ) ) { + return false; + } + // convert array - if( !$is_array ) $numbers = $numbers[0]; - - + if ( ! $is_array ) { + $numbers = $numbers[0]; + } + // return return $numbers; - + } @@ -1335,53 +1295,56 @@ function acf_get_numeric( $value = '' ) { * * Similar to the get_posts() function but with extra functionality. * - * @date 3/03/15 - * @since 5.1.5 + * @date 3/03/15 + * @since 5.1.5 * - * @param array $args The query args. - * @return array + * @param array $args The query args. + * @return array */ function acf_get_posts( $args = array() ) { - + // Vars. $posts = array(); - + // Apply default args. - $args = wp_parse_args($args, array( - 'posts_per_page' => -1, - 'post_type' => '', - 'post_status' => 'any', - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false - )); - + $args = wp_parse_args( + $args, + array( + 'posts_per_page' => -1, + 'post_type' => '', + 'post_status' => 'any', + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + ) + ); + // Avoid default 'post' post_type by providing all public types. - if( !$args['post_type'] ) { + if ( ! $args['post_type'] ) { $args['post_type'] = acf_get_post_types(); } - + // Check if specifc post ID's have been provided. - if( $args['post__in'] ) { - + if ( $args['post__in'] ) { + // Clean value into an array of IDs. - $args['post__in'] = array_map('intval', acf_array($args['post__in'])); + $args['post__in'] = array_map( 'intval', acf_array( $args['post__in'] ) ); } - + // Query posts. $posts = get_posts( $args ); - + // Remove any potential empty results. $posts = array_filter( $posts ); - + // Manually order results. - if( $posts && $args['post__in'] ) { + if ( $posts && $args['post__in'] ) { $order = array(); - foreach( $posts as $i => $post ) { + foreach ( $posts as $i => $post ) { $order[ $i ] = array_search( $post->ID, $args['post__in'] ); } - array_multisort($order, $posts); + array_multisort( $order, $posts ); } - + // Return posts. return $posts; } @@ -1393,52 +1356,46 @@ function acf_get_posts( $args = array() ) { * This function will remove the 'wp_posts.post_type' WHERE clause completely * When using 'post__in', this clause is unneccessary and slow. * -* @type function -* @date 4/03/2015 -* @since 5.1.5 +* @type function +* @date 4/03/2015 +* @since 5.1.5 * -* @param $sql (string) -* @return $sql +* @param $sql (string) +* @return $sql */ function _acf_query_remove_post_type( $sql ) { - + // global global $wpdb; - - + // bail ealry if no 'wp_posts.ID IN' - if( strpos($sql, "$wpdb->posts.ID IN") === false ) { - + if ( strpos( $sql, "$wpdb->posts.ID IN" ) === false ) { + return $sql; - + } - - - // get bits + + // get bits $glue = 'AND'; - $bits = explode($glue, $sql); - - + $bits = explode( $glue, $sql ); + // loop through $where and remove any post_type queries - foreach( $bits as $i => $bit ) { - - if( strpos($bit, "$wpdb->posts.post_type") !== false ) { - + foreach ( $bits as $i => $bit ) { + + if ( strpos( $bit, "$wpdb->posts.post_type" ) !== false ) { + unset( $bits[ $i ] ); - + } - } - - + // join $where back together - $sql = implode($glue, $bits); - - - // return - return $sql; - + $sql = implode( $glue, $bits ); + + // return + return $sql; + } @@ -1448,303 +1405,277 @@ function _acf_query_remove_post_type( $sql ) { * This function will return all posts grouped by post_type * This is handy for select settings * -* @type function -* @date 27/02/2014 -* @since 5.0.0 +* @type function +* @date 27/02/2014 +* @since 5.0.0 * -* @param $args (array) -* @return (array) +* @param $args (array) +* @return (array) */ function acf_get_grouped_posts( $args ) { - + // vars $data = array(); - - - // defaults - $args = wp_parse_args( $args, array( - 'posts_per_page' => -1, - 'paged' => 0, - 'post_type' => 'post', - 'orderby' => 'menu_order title', - 'order' => 'ASC', - 'post_status' => 'any', - 'suppress_filters' => false, - 'update_post_meta_cache' => false, - )); - + // defaults + $args = wp_parse_args( + $args, + array( + 'posts_per_page' => -1, + 'paged' => 0, + 'post_type' => 'post', + 'orderby' => 'menu_order title', + 'order' => 'ASC', + 'post_status' => 'any', + 'suppress_filters' => false, + 'update_post_meta_cache' => false, + ) + ); + // find array of post_type - $post_types = acf_get_array( $args['post_type'] ); - $post_types_labels = acf_get_pretty_post_types($post_types); - $is_single_post_type = ( count($post_types) == 1 ); - - + $post_types = acf_get_array( $args['post_type'] ); + $post_types_labels = acf_get_pretty_post_types( $post_types ); + $is_single_post_type = ( count( $post_types ) == 1 ); + // attachment doesn't work if it is the only item in an array - if( $is_single_post_type ) { - $args['post_type'] = reset($post_types); + if ( $is_single_post_type ) { + $args['post_type'] = reset( $post_types ); } - - + // add filter to orderby post type - if( !$is_single_post_type ) { - add_filter('posts_orderby', '_acf_orderby_post_type', 10, 2); + if ( ! $is_single_post_type ) { + add_filter( 'posts_orderby', '_acf_orderby_post_type', 10, 2 ); } - - + // get posts $posts = get_posts( $args ); - - + // remove this filter (only once) - if( !$is_single_post_type ) { - remove_filter('posts_orderby', '_acf_orderby_post_type', 10, 2); + if ( ! $is_single_post_type ) { + remove_filter( 'posts_orderby', '_acf_orderby_post_type', 10, 2 ); } - - + // loop - foreach( $post_types as $post_type ) { - + foreach ( $post_types as $post_type ) { + // vars $this_posts = array(); $this_group = array(); - - + // populate $this_posts - foreach( $posts as $post ) { - if( $post->post_type == $post_type ) { + foreach ( $posts as $post ) { + if ( $post->post_type == $post_type ) { $this_posts[] = $post; } } - - + // bail early if no posts for this post type - if( empty($this_posts) ) continue; - - + if ( empty( $this_posts ) ) { + continue; + } + // sort into hierachial order! // this will fail if a search has taken place because parents wont exist - if( is_post_type_hierarchical($post_type) && empty($args['s'])) { - + if ( is_post_type_hierarchical( $post_type ) && empty( $args['s'] ) ) { + // vars - $post_id = $this_posts[0]->ID; - $parent_id = acf_maybe_get($args, 'post_parent', 0); - $offset = 0; - $length = count($this_posts); - - + $post_id = $this_posts[0]->ID; + $parent_id = acf_maybe_get( $args, 'post_parent', 0 ); + $offset = 0; + $length = count( $this_posts ); + // get all posts from this post type - $all_posts = get_posts(array_merge($args, array( - 'posts_per_page' => -1, - 'paged' => 0, - 'post_type' => $post_type - ))); - - + $all_posts = get_posts( + array_merge( + $args, + array( + 'posts_per_page' => -1, + 'paged' => 0, + 'post_type' => $post_type, + ) + ) + ); + // find starting point (offset) - foreach( $all_posts as $i => $post ) { - if( $post->ID == $post_id ) { + foreach ( $all_posts as $i => $post ) { + if ( $post->ID == $post_id ) { $offset = $i; break; } } - - + // order posts - $ordered_posts = get_page_children($parent_id, $all_posts); - - + $ordered_posts = get_page_children( $parent_id, $all_posts ); + // compare aray lengths // if $ordered_posts is smaller than $all_posts, WP has lost posts during the get_page_children() function - // this is possible when get_post( $args ) filter out parents (via taxonomy, meta and other search parameters) - if( count($ordered_posts) == count($all_posts) ) { - $this_posts = array_slice($ordered_posts, $offset, $length); + // this is possible when get_post( $args ) filter out parents (via taxonomy, meta and other search parameters) + if ( count( $ordered_posts ) == count( $all_posts ) ) { + $this_posts = array_slice( $ordered_posts, $offset, $length ); } - } - - + // populate $this_posts - foreach( $this_posts as $post ) { + foreach ( $this_posts as $post ) { $this_group[ $post->ID ] = $post; } - - + // group by post type - $label = $post_types_labels[ $post_type ]; + $label = $post_types_labels[ $post_type ]; $data[ $label ] = $this_group; - + } - - + // return return $data; - + } function _acf_orderby_post_type( $ordeby, $wp_query ) { - + // global global $wpdb; - - + // get post types - $post_types = $wp_query->get('post_type'); - + $post_types = $wp_query->get( 'post_type' ); // prepend SQL - if( is_array($post_types) ) { - - $post_types = implode("','", $post_types); - $ordeby = "FIELD({$wpdb->posts}.post_type,'$post_types')," . $ordeby; - + if ( is_array( $post_types ) ) { + + $post_types = implode( "','", $post_types ); + $ordeby = "FIELD({$wpdb->posts}.post_type,'$post_types')," . $ordeby; + } - - + // return return $ordeby; - + } function acf_get_post_title( $post = 0, $is_search = false ) { - + // vars - $post = get_post($post); - $title = ''; + $post = get_post( $post ); + $title = ''; $prepend = ''; - $append = ''; - - + $append = ''; + // bail early if no post - if( !$post ) return ''; - - + if ( ! $post ) { + return ''; + } + // title $title = get_the_title( $post->ID ); - - + // empty - if( $title === '' ) { - - $title = __('(no title)', 'acf'); - + if ( $title === '' ) { + + $title = __( '(no title)', 'acf' ); + } - - + // status - if( get_post_status( $post->ID ) != "publish" ) { - + if ( get_post_status( $post->ID ) != 'publish' ) { + $append .= ' (' . get_post_status( $post->ID ) . ')'; - + } - - + // ancestors - if( $post->post_type !== 'attachment' ) { - + if ( $post->post_type !== 'attachment' ) { + // get ancestors $ancestors = get_ancestors( $post->ID, $post->post_type ); - $prepend .= str_repeat('- ', count($ancestors)); - - + $prepend .= str_repeat( '- ', count( $ancestors ) ); + // add parent -/* + /* removed in 5.6.5 as not used by the UI if( $is_search && !empty($ancestors) ) { - + // reverse $ancestors = array_reverse($ancestors); - - + + // convert id's into titles foreach( $ancestors as $i => $id ) { - + $ancestors[ $i ] = get_the_title( $id ); - + } - - + + // append $append .= ' | ' . __('Parent', 'acf') . ': ' . implode(' / ', $ancestors); - + } -*/ - + */ + } - - + // merge $title = $prepend . $title . $append; - - + // return return $title; - + } function acf_order_by_search( $array, $search ) { - + // vars $weights = array(); - $needle = strtolower( $search ); - - - // add key prefix - foreach( array_keys($array) as $k ) { - - $array[ '_' . $k ] = acf_extract_var( $array, $k ); - - } + $needle = strtolower( $search ); + // add key prefix + foreach ( array_keys( $array ) as $k ) { + + $array[ '_' . $k ] = acf_extract_var( $array, $k ); + + } // add search weight - foreach( $array as $k => $v ) { - + foreach ( $array as $k => $v ) { + // vars - $weight = 0; + $weight = 0; $haystack = strtolower( $v ); - $strpos = strpos( $haystack, $needle ); - - + $strpos = strpos( $haystack, $needle ); + // detect search match - if( $strpos !== false ) { - + if ( $strpos !== false ) { + // set eright to length of match $weight = strlen( $search ); - - + // increase weight if match starts at begining of string - if( $strpos == 0 ) { - + if ( $strpos == 0 ) { + $weight++; - + } - } - - + // append to wights $weights[ $k ] = $weight; - + } - - + // sort the array with menu_order ascending array_multisort( $weights, SORT_DESC, $array ); - - + // remove key prefix - foreach( array_keys($array) as $k ) { - - $array[ substr($k,1) ] = acf_extract_var( $array, $k ); - + foreach ( array_keys( $array ) as $k ) { + + $array[ substr( $k, 1 ) ] = acf_extract_var( $array, $k ); + } - - + // return return $array; } @@ -1755,38 +1686,37 @@ function acf_order_by_search( $array, $search ) { * * description * -* @type function -* @date 23/02/2016 -* @since 5.3.2 +* @type function +* @date 23/02/2016 +* @since 5.3.2 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_get_pretty_user_roles( $allowed = false ) { - + // vars $editable_roles = get_editable_roles(); - $allowed = acf_get_array($allowed); - $roles = array(); - - + $allowed = acf_get_array( $allowed ); + $roles = array(); + // loop - foreach( $editable_roles as $role_name => $role_details ) { - + foreach ( $editable_roles as $role_name => $role_details ) { + // bail early if not allowed - if( !empty($allowed) && !in_array($role_name, $allowed) ) continue; - - + if ( ! empty( $allowed ) && ! in_array( $role_name, $allowed ) ) { + continue; + } + // append $roles[ $role_name ] = translate_user_role( $role_details['name'] ); - + } - - + // return return $roles; - + } @@ -1796,153 +1726,142 @@ function acf_get_pretty_user_roles( $allowed = false ) { * This function will return all users grouped by role * This is handy for select settings * -* @type function -* @date 27/02/2014 -* @since 5.0.0 +* @type function +* @date 27/02/2014 +* @since 5.0.0 * -* @param $args (array) -* @return (array) +* @param $args (array) +* @return (array) */ function acf_get_grouped_users( $args = array() ) { - + // vars $r = array(); - - + // defaults - $args = wp_parse_args( $args, array( - 'users_per_page' => -1, - 'paged' => 0, - 'role' => '', - 'orderby' => 'login', - 'order' => 'ASC', - )); - - + $args = wp_parse_args( + $args, + array( + 'users_per_page' => -1, + 'paged' => 0, + 'role' => '', + 'orderby' => 'login', + 'order' => 'ASC', + ) + ); + // offset - $i = 0; - $min = 0; - $max = 0; - $users_per_page = acf_extract_var($args, 'users_per_page'); - $paged = acf_extract_var($args, 'paged'); - - if( $users_per_page > 0 ) { - + $i = 0; + $min = 0; + $max = 0; + $users_per_page = acf_extract_var( $args, 'users_per_page' ); + $paged = acf_extract_var( $args, 'paged' ); + + if ( $users_per_page > 0 ) { + // prevent paged from being -1 - $paged = max(0, $paged); - - + $paged = max( 0, $paged ); + // set min / max - $min = (($paged-1) * $users_per_page) + 1; // 1, 11 - $max = ($paged * $users_per_page); // 10, 20 - + $min = ( ( $paged - 1 ) * $users_per_page ) + 1; // 1, 11 + $max = ( $paged * $users_per_page ); // 10, 20 + } - - + // find array of post_type - $user_roles = acf_get_pretty_user_roles($args['role']); - - + $user_roles = acf_get_pretty_user_roles( $args['role'] ); + // fix role - if( is_array($args['role']) ) { - + if ( is_array( $args['role'] ) ) { + // global - global $wp_version, $wpdb; - - + global $wp_version, $wpdb; + // vars - $roles = acf_extract_var($args, 'role'); - - + $roles = acf_extract_var( $args, 'role' ); + // new WP has role__in - if( version_compare($wp_version, '4.4', '>=' ) ) { - + if ( version_compare( $wp_version, '4.4', '>=' ) ) { + $args['role__in'] = $roles; - - // old WP doesn't have role__in + + // old WP doesn't have role__in } else { - + // vars - $blog_id = get_current_blog_id(); + $blog_id = get_current_blog_id(); $meta_query = array( 'relation' => 'OR' ); - - + // loop - foreach( $roles as $role ) { - + foreach ( $roles as $role ) { + $meta_query[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $role . '"', 'compare' => 'LIKE', ); - + } - - + // append $args['meta_query'] = $meta_query; - + } - } - - + // get posts $users = get_users( $args ); - - + // loop - foreach( $user_roles as $user_role_name => $user_role_label ) { - + foreach ( $user_roles as $user_role_name => $user_role_label ) { + // vars $this_users = array(); $this_group = array(); - - + // populate $this_posts - foreach( array_keys($users) as $key ) { - + foreach ( array_keys( $users ) as $key ) { + // bail ealry if not correct role - if( !in_array($user_role_name, $users[ $key ]->roles) ) continue; - - + if ( ! in_array( $user_role_name, $users[ $key ]->roles ) ) { + continue; + } + // extract user $user = acf_extract_var( $users, $key ); - - + // increase $i++; - - + // bail ealry if too low - if( $min && $i < $min ) continue; - - + if ( $min && $i < $min ) { + continue; + } + // bail early if too high (don't bother looking at any more users) - if( $max && $i > $max ) break; - - + if ( $max && $i > $max ) { + break; + } + // group by post type $this_users[ $user->ID ] = $user; - - + } - - + // bail early if no posts for this post type - if( empty($this_users) ) continue; - - + if ( empty( $this_users ) ) { + continue; + } + // append $r[ $user_role_label ] = $this_users; - + } - - + // return return $r; - + } /** @@ -1950,14 +1869,14 @@ function acf_get_grouped_users( $args = array() ) { * * Returns json_encode() ready for file / database use. * - * @date 29/4/19 - * @since 5.0.0 + * @date 29/4/19 + * @since 5.0.0 * - * @param array $json The array of data to encode. - * @return string + * @param array $json The array of data to encode. + * @return string */ function acf_json_encode( $json ) { - return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + return json_encode( $json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE ); } @@ -1966,25 +1885,24 @@ function acf_json_encode( $json ) { * * This function will return true if a sub string is found * -* @type function -* @date 1/05/2014 -* @since 5.0.0 +* @type function +* @date 1/05/2014 +* @since 5.0.0 * -* @param $needle (string) -* @param $haystack (string) -* @return (boolean) +* @param $needle (string) +* @param $haystack (string) +* @return (boolean) */ function acf_str_exists( $needle, $haystack ) { - + // return true if $haystack contains the $needle - if( is_string($haystack) && strpos($haystack, $needle) !== false ) { - + if ( is_string( $haystack ) && strpos( $haystack, $needle ) !== false ) { + return true; - + } - - + // return return false; } @@ -1995,75 +1913,72 @@ function acf_str_exists( $needle, $haystack ) { * * description * -* @type function -* @date 2/05/2014 -* @since 5.0.0 +* @type function +* @date 2/05/2014 +* @since 5.0.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_debug() { - + // vars $args = func_get_args(); - $s = array_shift($args); - $o = ''; - $nl = "\r\n"; - - + $s = array_shift( $args ); + $o = ''; + $nl = "\r\n"; + // start script $o .= '' . $nl; - - + // echo echo $o; } function acf_debug_start() { - - acf_update_setting( 'debug_start', memory_get_usage()); - + + acf_update_setting( 'debug_start', memory_get_usage() ); + } function acf_debug_end() { - + $start = acf_get_setting( 'debug_start' ); - $end = memory_get_usage(); - + $end = memory_get_usage(); + return $end - $start; - + } @@ -2072,124 +1987,116 @@ function acf_debug_end() { * * description * -* @type function -* @date 4/06/2014 -* @since 5.0.0 +* @type function +* @date 4/06/2014 +* @since 5.0.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_encode_choices( $array = array(), $show_keys = true ) { - + // bail early if not array (maybe a single string) - if( !is_array($array) ) return $array; - - + if ( ! is_array( $array ) ) { + return $array; + } + // bail early if empty array - if( empty($array) ) return ''; - - + if ( empty( $array ) ) { + return ''; + } + // vars $string = ''; - - + // if allowed to show keys (good for choices, not for default values) - if( $show_keys ) { - + if ( $show_keys ) { + // loop - foreach( $array as $k => $v ) { - + foreach ( $array as $k => $v ) { + // ignore if key and value are the same - if( strval($k) == strval($v) ) continue; - - + if ( strval( $k ) == strval( $v ) ) { + continue; + } + // show key in the value $array[ $k ] = $k . ' : ' . $v; - - } - - } - - - // implode - $string = implode("\n", $array); - + } + } + + // implode + $string = implode( "\n", $array ); + // return return $string; - + } function acf_decode_choices( $string = '', $array_keys = false ) { - + // bail early if already array - if( is_array($string) ) { - + if ( is_array( $string ) ) { + return $string; - - // allow numeric values (same as string) - } elseif( is_numeric($string) ) { - + + // allow numeric values (same as string) + } elseif ( is_numeric( $string ) ) { + // do nothing - - // bail early if not a string - } elseif( !is_string($string) ) { - + + // bail early if not a string + } elseif ( ! is_string( $string ) ) { + return array(); - - // bail early if is empty string - } elseif( $string === '' ) { - + + // bail early if is empty string + } elseif ( $string === '' ) { + return array(); - + } - - + // vars $array = array(); - - + // explode - $lines = explode("\n", $string); - - + $lines = explode( "\n", $string ); + // key => value - foreach( $lines as $line ) { - + foreach ( $lines as $line ) { + // vars - $k = trim($line); - $v = trim($line); - - + $k = trim( $line ); + $v = trim( $line ); + // look for ' : ' - if( acf_str_exists(' : ', $line) ) { - - $line = explode(' : ', $line); - - $k = trim($line[0]); - $v = trim($line[1]); - + if ( acf_str_exists( ' : ', $line ) ) { + + $line = explode( ' : ', $line ); + + $k = trim( $line[0] ); + $v = trim( $line[1] ); + } - - + // append $array[ $k ] = $v; - + } - - + // return only array keys? (good for checkbox default_value) - if( $array_keys ) { - - return array_keys($array); - + if ( $array_keys ) { + + return array_keys( $array ); + } - - + // return return $array; - + } @@ -2200,48 +2107,46 @@ function acf_decode_choices( $string = '', $array_keys = false ) { * The difference is the extra logic to avoid replacing a string that has alread been replaced * This is very useful for replacing date characters as they overlap with eachother * -* @type function -* @date 21/06/2016 -* @since 5.3.8 +* @type function +* @date 21/06/2016 +* @since 5.3.8 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_str_replace( $string = '', $search_replace = array() ) { - + // vars $ignore = array(); - - + // remove potential empty search to avoid PHP error - unset($search_replace['']); - - + unset( $search_replace[''] ); + // loop over conversions - foreach( $search_replace as $search => $replace ) { - + foreach ( $search_replace as $search => $replace ) { + // ignore this search, it was a previous replace - if( in_array($search, $ignore) ) continue; - - + if ( in_array( $search, $ignore ) ) { + continue; + } + // bail early if subsctring not found - if( strpos($string, $search) === false ) continue; - - + if ( strpos( $string, $search ) === false ) { + continue; + } + // replace - $string = str_replace($search, $replace, $string); - - + $string = str_replace( $search, $replace, $string ); + // append to ignore $ignore[] = $replace; - + } - - + // return return $string; - + } @@ -2250,52 +2155,58 @@ function acf_str_replace( $string = '', $search_replace = array() ) { * * These settings contain an association of format strings from PHP => JS * -* @type function -* @date 21/06/2016 -* @since 5.3.8 +* @type function +* @date 21/06/2016 +* @since 5.3.8 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ -acf_update_setting('php_to_js_date_formats', array( +acf_update_setting( + 'php_to_js_date_formats', + array( + + // Year + 'Y' => 'yy', // Numeric, 4 digits 1999, 2003 + 'y' => 'y', // Numeric, 2 digits 99, 03 + - // Year - 'Y' => 'yy', // Numeric, 4 digits 1999, 2003 - 'y' => 'y', // Numeric, 2 digits 99, 03 - - // Month - 'm' => 'mm', // Numeric, with leading zeros 01–12 - 'n' => 'm', // Numeric, without leading zeros 1–12 - 'F' => 'MM', // Textual full January – December - 'M' => 'M', // Textual three letters Jan - Dec - - - // Weekday - 'l' => 'DD', // Full name (lowercase 'L') Sunday – Saturday - 'D' => 'D', // Three letter name Mon – Sun - - - // Day of Month - 'd' => 'dd', // Numeric, with leading zeros 01–31 - 'j' => 'd', // Numeric, without leading zeros 1–31 - 'S' => '', // The English suffix for the day of the month st, nd or th in the 1st, 2nd or 15th. - -)); + 'm' => 'mm', // Numeric, with leading zeros 01–12 + 'n' => 'm', // Numeric, without leading zeros 1–12 + 'F' => 'MM', // Textual full January – December + 'M' => 'M', // Textual three letters Jan - Dec -acf_update_setting('php_to_js_time_formats', array( - - 'a' => 'tt', // Lowercase Ante meridiem and Post meridiem am or pm - 'A' => 'TT', // Uppercase Ante meridiem and Post meridiem AM or PM - 'h' => 'hh', // 12-hour format of an hour with leading zeros 01 through 12 - 'g' => 'h', // 12-hour format of an hour without leading zeros 1 through 12 - 'H' => 'HH', // 24-hour format of an hour with leading zeros 00 through 23 - 'G' => 'H', // 24-hour format of an hour without leading zeros 0 through 23 - 'i' => 'mm', // Minutes with leading zeros 00 to 59 - 's' => 'ss', // Seconds, with leading zeros 00 through 59 - -)); + + // Weekday + 'l' => 'DD', // Full name (lowercase 'L') Sunday – Saturday + 'D' => 'D', // Three letter name Mon – Sun + + + // Day of Month + 'd' => 'dd', // Numeric, with leading zeros 01–31 + 'j' => 'd', // Numeric, without leading zeros 1–31 + 'S' => '', // The English suffix for the day of the month st, nd or th in the 1st, 2nd or 15th. + + ) +); + +acf_update_setting( + 'php_to_js_time_formats', + array( + + 'a' => 'tt', // Lowercase Ante meridiem and Post meridiem am or pm + 'A' => 'TT', // Uppercase Ante meridiem and Post meridiem AM or PM + 'h' => 'hh', // 12-hour format of an hour with leading zeros 01 through 12 + 'g' => 'h', // 12-hour format of an hour without leading zeros 1 through 12 + 'H' => 'HH', // 24-hour format of an hour with leading zeros 00 through 23 + 'G' => 'H', // 24-hour format of an hour without leading zeros 0 through 23 + 'i' => 'mm', // Minutes with leading zeros 00 to 59 + 's' => 'ss', // Seconds, with leading zeros 00 through 59 + + ) +); /* @@ -2303,60 +2214,55 @@ acf_update_setting('php_to_js_time_formats', array( * * This function will split a format string into seperate date and time * -* @type function -* @date 26/05/2016 -* @since 5.3.8 +* @type function +* @date 26/05/2016 +* @since 5.3.8 * -* @param $date_time (string) -* @return $formats (array) +* @param $date_time (string) +* @return $formats (array) */ function acf_split_date_time( $date_time = '' ) { - + // vars - $php_date = acf_get_setting('php_to_js_date_formats'); - $php_time = acf_get_setting('php_to_js_time_formats'); - $chars = str_split($date_time); - $type = 'date'; - - + $php_date = acf_get_setting( 'php_to_js_date_formats' ); + $php_time = acf_get_setting( 'php_to_js_time_formats' ); + $chars = str_split( $date_time ); + $type = 'date'; + // default $data = array( 'date' => '', - 'time' => '' + 'time' => '', ); - - + // loop - foreach( $chars as $i => $c ) { - + foreach ( $chars as $i => $c ) { + // find type // - allow misc characters to append to previous type - if( isset($php_date[ $c ]) ) { - + if ( isset( $php_date[ $c ] ) ) { + $type = 'date'; - - } elseif( isset($php_time[ $c ]) ) { - + + } elseif ( isset( $php_time[ $c ] ) ) { + $type = 'time'; - + } - - + // append char $data[ $type ] .= $c; - + } - - + // trim - $data['date'] = trim($data['date']); - $data['time'] = trim($data['time']); - - + $data['date'] = trim( $data['date'] ); + $data['time'] = trim( $data['time'] ); + // return - return $data; - + return $data; + } @@ -2365,24 +2271,23 @@ function acf_split_date_time( $date_time = '' ) { * * This fucntion converts a date format string from JS to PHP * -* @type function -* @date 20/06/2014 -* @since 5.0.0 +* @type function +* @date 20/06/2014 +* @since 5.0.0 * -* @param $date (string) -* @return (string) +* @param $date (string) +* @return (string) */ function acf_convert_date_to_php( $date = '' ) { - + // vars - $php_to_js = acf_get_setting('php_to_js_date_formats'); - $js_to_php = array_flip($php_to_js); - - + $php_to_js = acf_get_setting( 'php_to_js_date_formats' ); + $js_to_php = array_flip( $php_to_js ); + // return return acf_str_replace( $date, $js_to_php ); - + } /* @@ -2390,23 +2295,22 @@ function acf_convert_date_to_php( $date = '' ) { * * This fucntion converts a date format string from PHP to JS * -* @type function -* @date 20/06/2014 -* @since 5.0.0 +* @type function +* @date 20/06/2014 +* @since 5.0.0 * -* @param $date (string) -* @return (string) +* @param $date (string) +* @return (string) */ function acf_convert_date_to_js( $date = '' ) { - + // vars - $php_to_js = acf_get_setting('php_to_js_date_formats'); - - + $php_to_js = acf_get_setting( 'php_to_js_date_formats' ); + // return return acf_str_replace( $date, $php_to_js ); - + } @@ -2415,24 +2319,23 @@ function acf_convert_date_to_js( $date = '' ) { * * This fucntion converts a time format string from JS to PHP * -* @type function -* @date 20/06/2014 -* @since 5.0.0 +* @type function +* @date 20/06/2014 +* @since 5.0.0 * -* @param $time (string) -* @return (string) +* @param $time (string) +* @return (string) */ function acf_convert_time_to_php( $time = '' ) { - + // vars - $php_to_js = acf_get_setting('php_to_js_time_formats'); - $js_to_php = array_flip($php_to_js); - - + $php_to_js = acf_get_setting( 'php_to_js_time_formats' ); + $js_to_php = array_flip( $php_to_js ); + // return return acf_str_replace( $time, $js_to_php ); - + } @@ -2441,23 +2344,22 @@ function acf_convert_time_to_php( $time = '' ) { * * This fucntion converts a date format string from PHP to JS * -* @type function -* @date 20/06/2014 -* @since 5.0.0 +* @type function +* @date 20/06/2014 +* @since 5.0.0 * -* @param $time (string) -* @return (string) +* @param $time (string) +* @return (string) */ function acf_convert_time_to_js( $time = '' ) { - + // vars - $php_to_js = acf_get_setting('php_to_js_time_formats'); - - + $php_to_js = acf_get_setting( 'php_to_js_time_formats' ); + // return return acf_str_replace( $time, $php_to_js ); - + } @@ -2466,44 +2368,40 @@ function acf_convert_time_to_js( $time = '' ) { * * description * -* @type function -* @date 15/07/2014 -* @since 5.0.0 +* @type function +* @date 15/07/2014 +* @since 5.0.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_update_user_setting( $name, $value ) { - + // get current user id $user_id = get_current_user_id(); - - + // get user settings $settings = get_user_meta( $user_id, 'acf_user_settings', true ); - - + // ensure array - $settings = acf_get_array($settings); - - + $settings = acf_get_array( $settings ); + // delete setting (allow 0 to save) - if( acf_is_empty($value) ) { - - unset($settings[ $name ]); - - // append setting + if ( acf_is_empty( $value ) ) { + + unset( $settings[ $name ] ); + + // append setting } else { - + $settings[ $name ] = $value; - + } - - + // update user data - return update_metadata('user', $user_id, 'acf_user_settings', $settings); - + return update_metadata( 'user', $user_id, 'acf_user_settings', $settings ); + } @@ -2512,35 +2410,33 @@ function acf_update_user_setting( $name, $value ) { * * description * -* @type function -* @date 15/07/2014 -* @since 5.0.0 +* @type function +* @date 15/07/2014 +* @since 5.0.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_get_user_setting( $name = '', $default = false ) { - + // get current user id $user_id = get_current_user_id(); - - + // get user settings $settings = get_user_meta( $user_id, 'acf_user_settings', true ); - - + // ensure array - $settings = acf_get_array($settings); - - + $settings = acf_get_array( $settings ); + // bail arly if no settings - if( !isset($settings[$name]) ) return $default; - - + if ( ! isset( $settings[ $name ] ) ) { + return $default; + } + // return - return $settings[$name]; - + return $settings[ $name ]; + } @@ -2549,23 +2445,24 @@ function acf_get_user_setting( $name = '', $default = false ) { * * description * -* @type function -* @date 22/07/2014 -* @since 5.0.0 +* @type function +* @date 22/07/2014 +* @since 5.0.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_in_array( $value = '', $array = false ) { - + // bail early if not array - if( !is_array($array) ) return false; - - + if ( ! is_array( $array ) ) { + return false; + } + // find value in array - return in_array($value, $array); - + return in_array( $value, $array ); + } @@ -2574,108 +2471,97 @@ function acf_in_array( $value = '', $array = false ) { * * This function will return a valid post_id based on the current screen / parameter * -* @type function -* @date 8/12/2013 -* @since 5.0.0 +* @type function +* @date 8/12/2013 +* @since 5.0.0 * -* @param $post_id (mixed) -* @return $post_id (mixed) +* @param $post_id (mixed) +* @return $post_id (mixed) */ function acf_get_valid_post_id( $post_id = 0 ) { - + // allow filter to short-circuit load_value logic - $preload = apply_filters( "acf/pre_load_post_id", null, $post_id ); - if( $preload !== null ) { - return $preload; - } - + $preload = apply_filters( 'acf/pre_load_post_id', null, $post_id ); + if ( $preload !== null ) { + return $preload; + } + // vars $_post_id = $post_id; - - + // if not $post_id, load queried object - if( !$post_id ) { - + if ( ! $post_id ) { + // try for global post (needed for setup_postdata) $post_id = (int) get_the_ID(); - - + // try for current screen - if( !$post_id ) { - + if ( ! $post_id ) { + $post_id = get_queried_object(); - + } - } - - + // $post_id may be an object. // todo: Compare class types instead. - if( is_object($post_id) ) { - + if ( is_object( $post_id ) ) { + // post - if( isset($post_id->post_type, $post_id->ID) ) { - + if ( isset( $post_id->post_type, $post_id->ID ) ) { + $post_id = $post_id->ID; - - // user - } elseif( isset($post_id->roles, $post_id->ID) ) { - + + // user + } elseif ( isset( $post_id->roles, $post_id->ID ) ) { + $post_id = 'user_' . $post_id->ID; - - // term - } elseif( isset($post_id->taxonomy, $post_id->term_id) ) { - + + // term + } elseif ( isset( $post_id->taxonomy, $post_id->term_id ) ) { + $post_id = 'term_' . $post_id->term_id; - - // comment - } elseif( isset($post_id->comment_ID) ) { - + + // comment + } elseif ( isset( $post_id->comment_ID ) ) { + $post_id = 'comment_' . $post_id->comment_ID; - - // default + + // default } else { - + $post_id = 0; - + } - } - - + // allow for option == options - if( $post_id === 'option' ) { - + if ( $post_id === 'option' ) { + $post_id = 'options'; - + } - - + // append language code - if( $post_id == 'options' ) { - - $dl = acf_get_setting('default_language'); - $cl = acf_get_setting('current_language'); - - if( $cl && $cl !== $dl ) { - + if ( $post_id == 'options' ) { + + $dl = acf_get_setting( 'default_language' ); + $cl = acf_get_setting( 'current_language' ); + + if ( $cl && $cl !== $dl ) { + $post_id .= '_' . $cl; - + } - } - - - + // filter for 3rd party - $post_id = apply_filters('acf/validate_post_id', $post_id, $_post_id); - - + $post_id = apply_filters( 'acf/validate_post_id', $post_id, $_post_id ); + // return return $post_id; - + } @@ -2685,86 +2571,82 @@ function acf_get_valid_post_id( $post_id = 0 ) { * * This function will return the type and id for a given $post_id string * -* @type function -* @date 2/07/2016 -* @since 5.4.0 +* @type function +* @date 2/07/2016 +* @since 5.4.0 * -* @param $post_id (mixed) -* @return $info (array) +* @param $post_id (mixed) +* @return $info (array) */ function acf_get_post_id_info( $post_id = 0 ) { - + // vars $info = array( - 'type' => 'post', - 'id' => 0 + 'type' => 'post', + 'id' => 0, ); - + // bail early if no $post_id - if( !$post_id ) return $info; - - + if ( ! $post_id ) { + return $info; + } + // check cache // - this function will most likely be called multiple times (saving loading fields from post) - //$cache_key = "get_post_id_info/post_id={$post_id}"; - - //if( acf_isset_cache($cache_key) ) return acf_get_cache($cache_key); - - + // $cache_key = "get_post_id_info/post_id={$post_id}"; + + // if( acf_isset_cache($cache_key) ) return acf_get_cache($cache_key); + // numeric - if( is_numeric($post_id) ) { - + if ( is_numeric( $post_id ) ) { + $info['id'] = (int) $post_id; - - // string - } elseif( is_string($post_id) ) { - + + // string + } elseif ( is_string( $post_id ) ) { + // vars $glue = '_'; - $type = explode($glue, $post_id); - $id = array_pop($type); - $type = implode($glue, $type); - $meta = array('post', 'user', 'comment', 'term'); - - + $type = explode( $glue, $post_id ); + $id = array_pop( $type ); + $type = implode( $glue, $type ); + $meta = array( 'post', 'user', 'comment', 'term' ); + // check if is taxonomy (ACF < 5.5) // - avoid scenario where taxonomy exists with name of meta type - if( !in_array($type, $meta) && acf_isset_termmeta($type) ) $type = 'term'; - - - // meta - if( is_numeric($id) && in_array($type, $meta) ) { - - $info['type'] = $type; - $info['id'] = (int) $id; - - // option - } else { - - $info['type'] = 'option'; - $info['id'] = $post_id; - + if ( ! in_array( $type, $meta ) && acf_isset_termmeta( $type ) ) { + $type = 'term'; + } + + // meta + if ( is_numeric( $id ) && in_array( $type, $meta ) ) { + + $info['type'] = $type; + $info['id'] = (int) $id; + + // option + } else { + + $info['type'] = 'option'; + $info['id'] = $post_id; + } - } - - + // update cache - //acf_set_cache($cache_key, $info); - - + // acf_set_cache($cache_key, $info); + // filter - $info = apply_filters("acf/get_post_id_info", $info, $post_id); - + $info = apply_filters( 'acf/get_post_id_info', $info, $post_id ); + // return return $info; - + } /* - acf_log( acf_get_post_id_info(4) ); acf_log( acf_get_post_id_info('post_4') ); @@ -2792,27 +2674,29 @@ acf_log( acf_get_post_id_info('options') ); * This function will return true if the termmeta table exists * https://developer.wordpress.org/reference/functions/get_term_meta/ * -* @type function -* @date 3/09/2016 -* @since 5.4.0 +* @type function +* @date 3/09/2016 +* @since 5.4.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_isset_termmeta( $taxonomy = '' ) { - + // bail ealry if no table - if( get_option('db_version') < 34370 ) return false; - - + if ( get_option( 'db_version' ) < 34370 ) { + return false; + } + // check taxonomy - if( $taxonomy && !taxonomy_exists($taxonomy) ) return false; - - + if ( $taxonomy && ! taxonomy_exists( $taxonomy ) ) { + return false; + } + // return return true; - + } @@ -2821,86 +2705,77 @@ function acf_isset_termmeta( $taxonomy = '' ) { * * This function will walk througfh the $_FILES data and upload each found * -* @type function -* @date 25/10/2014 -* @since 5.0.9 +* @type function +* @date 25/10/2014 +* @since 5.0.9 * -* @param $ancestors (array) an internal parameter, not required -* @return n/a +* @param $ancestors (array) an internal parameter, not required +* @return n/a */ - + function acf_upload_files( $ancestors = array() ) { - + // vars $file = array( - 'name' => '', - 'type' => '', - 'tmp_name' => '', - 'error' => '', - 'size' => '' + 'name' => '', + 'type' => '', + 'tmp_name' => '', + 'error' => '', + 'size' => '', ); - - + // populate with $_FILES data - foreach( array_keys($file) as $k ) { - + foreach ( array_keys( $file ) as $k ) { + $file[ $k ] = $_FILES['acf'][ $k ]; - + } - - + // walk through ancestors - if( !empty($ancestors) ) { - - foreach( $ancestors as $a ) { - - foreach( array_keys($file) as $k ) { - + if ( ! empty( $ancestors ) ) { + + foreach ( $ancestors as $a ) { + + foreach ( array_keys( $file ) as $k ) { + $file[ $k ] = $file[ $k ][ $a ]; - + } - } - } - - + // is array? - if( is_array($file['name']) ) { - - foreach( array_keys($file['name']) as $k ) { - - $_ancestors = array_merge($ancestors, array($k)); - + if ( is_array( $file['name'] ) ) { + + foreach ( array_keys( $file['name'] ) as $k ) { + + $_ancestors = array_merge( $ancestors, array( $k ) ); + acf_upload_files( $_ancestors ); - + } - + return; - + } - - + // bail ealry if file has error (no file uploaded) - if( $file['error'] ) { - + if ( $file['error'] ) { + return; - + } - - + // assign global _acfuploader for media validation - $_POST['_acfuploader'] = end($ancestors); - - + $_POST['_acfuploader'] = end( $ancestors ); + // file found! $attachment_id = acf_upload_file( $file ); - - + // update $_POST - array_unshift($ancestors, 'acf'); + array_unshift( $ancestors, 'acf' ); acf_update_nested_array( $_POST, $ancestors, $attachment_id ); - + } @@ -2909,65 +2784,60 @@ function acf_upload_files( $ancestors = array() ) { * * This function will uploade a $_FILE * -* @type function -* @date 27/10/2014 -* @since 5.0.9 +* @type function +* @date 27/10/2014 +* @since 5.0.9 * -* @param $uploaded_file (array) array found from $_FILE data -* @return $id (int) new attachment ID +* @param $uploaded_file (array) array found from $_FILE data +* @return $id (int) new attachment ID */ function acf_upload_file( $uploaded_file ) { - + // required - //require_once( ABSPATH . "/wp-load.php" ); // WP should already be loaded - require_once( ABSPATH . "/wp-admin/includes/media.php" ); // video functions - require_once( ABSPATH . "/wp-admin/includes/file.php" ); - require_once( ABSPATH . "/wp-admin/includes/image.php" ); - - + // require_once( ABSPATH . "/wp-load.php" ); // WP should already be loaded + require_once ABSPATH . '/wp-admin/includes/media.php'; // video functions + require_once ABSPATH . '/wp-admin/includes/file.php'; + require_once ABSPATH . '/wp-admin/includes/image.php'; + // required for wp_handle_upload() to upload the file $upload_overrides = array( 'test_form' => false ); - - + // upload $file = wp_handle_upload( $uploaded_file, $upload_overrides ); - - + // bail ealry if upload failed - if( isset($file['error']) ) { - + if ( isset( $file['error'] ) ) { + return $file['error']; - + } - - + // vars - $url = $file['url']; - $type = $file['type']; - $file = $file['file']; - $filename = basename($file); - + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $filename = basename( $file ); // Construct the object array $object = array( - 'post_title' => $filename, + 'post_title' => $filename, 'post_mime_type' => $type, - 'guid' => $url + 'guid' => $url, ); // Save the data - $id = wp_insert_attachment($object, $file); + $id = wp_insert_attachment( $object, $file ); // Add the meta-data wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); - + /** This action is documented in wp-admin/custom-header.php */ do_action( 'wp_create_file_in_uploads', $file, $id ); // For replication - + // return new ID return $id; - + } @@ -2976,42 +2846,39 @@ function acf_upload_file( $uploaded_file ) { * * This function will update a nested array value. Useful for modifying the $_POST array * -* @type function -* @date 27/10/2014 -* @since 5.0.9 +* @type function +* @date 27/10/2014 +* @since 5.0.9 * -* @param $array (array) target array to be updated -* @param $ancestors (array) array of keys to navigate through to find the child -* @param $value (mixed) The new value -* @return (boolean) +* @param $array (array) target array to be updated +* @param $ancestors (array) array of keys to navigate through to find the child +* @param $value (mixed) The new value +* @return (boolean) */ function acf_update_nested_array( &$array, $ancestors, $value ) { - + // if no more ancestors, update the current var - if( empty($ancestors) ) { - + if ( empty( $ancestors ) ) { + $array = $value; - + // return return true; - + } - - + // shift the next ancestor from the array $k = array_shift( $ancestors ); - - + // if exists - if( isset($array[ $k ]) ) { - + if ( isset( $array[ $k ] ) ) { + return acf_update_nested_array( $array[ $k ], $ancestors, $value ); - + } - - - // return + + // return return false; } @@ -3021,35 +2888,35 @@ function acf_update_nested_array( &$array, $ancestors, $value ) { * * This function will return true if all args are matched for the current screen * -* @type function -* @date 9/12/2014 -* @since 5.1.5 +* @type function +* @date 9/12/2014 +* @since 5.1.5 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_is_screen( $id = '' ) { - + // bail early if not defined - if( !function_exists('get_current_screen') ) { + if ( ! function_exists( 'get_current_screen' ) ) { return false; } - + // vars $current_screen = get_current_screen(); - + // no screen - if( !$current_screen ) { + if ( ! $current_screen ) { return false; - - // array - } elseif( is_array($id) ) { - return in_array($current_screen->id, $id); - - // string + + // array + } elseif ( is_array( $id ) ) { + return in_array( $current_screen->id, $id ); + + // string } else { - return ($id === $current_screen->id); + return ( $id === $current_screen->id ); } } @@ -3059,65 +2926,65 @@ function acf_is_screen( $id = '' ) { * * This function will return a var if it exists in an array * -* @type function -* @date 9/12/2014 -* @since 5.1.5 +* @type function +* @date 9/12/2014 +* @since 5.1.5 * -* @param $array (array) the array to look within -* @param $key (key) the array key to look for. Nested values may be found using '/' -* @param $default (mixed) the value returned if not found -* @return $post_id (int) +* @param $array (array) the array to look within +* @param $key (key) the array key to look for. Nested values may be found using '/' +* @param $default (mixed) the value returned if not found +* @return $post_id (int) */ function acf_maybe_get( $array = array(), $key = 0, $default = null ) { - - return isset( $array[$key] ) ? $array[$key] : $default; - + + return isset( $array[ $key ] ) ? $array[ $key ] : $default; + } function acf_maybe_get_POST( $key = '', $default = null ) { - - return isset( $_POST[$key] ) ? $_POST[$key] : $default; - + + return isset( $_POST[ $key ] ) ? $_POST[ $key ] : $default; + } function acf_maybe_get_GET( $key = '', $default = null ) { - - return isset( $_GET[$key] ) ? $_GET[$key] : $default; - + + return isset( $_GET[ $key ] ) ? $_GET[ $key ] : $default; + } /** * Returns an array of attachment data. * - * @date 05/01/2015 - * @since 5.1.5 + * @date 05/01/2015 + * @since 5.1.5 * - * @param int|WP_Post The attachment ID or object. - * @return array|false + * @param int|WP_Post The attachment ID or object. + * @return array|false */ function acf_get_attachment( $attachment ) { - + // Allow filter to short-circuit load attachment logic. - // Alternatively, this filter may be used to switch blogs for multisite media functionality. - $response = apply_filters( "acf/pre_load_attachment", null, $attachment ); - if( $response !== null ) { + // Alternatively, this filter may be used to switch blogs for multisite media functionality. + $response = apply_filters( 'acf/pre_load_attachment', null, $attachment ); + if ( $response !== null ) { return $response; } // Get the attachment post object. $attachment = get_post( $attachment ); - if( !$attachment ) { + if ( ! $attachment ) { return false; } - if( $attachment->post_type !== 'attachment' ) { + if ( $attachment->post_type !== 'attachment' ) { return false; } - + // Load various attachment details. - $meta = wp_get_attachment_metadata( $attachment->ID ); + $meta = wp_get_attachment_metadata( $attachment->ID ); $attached_file = get_attached_file( $attachment->ID ); - if( strpos( $attachment->post_mime_type, '/' ) !== false ) { + if ( strpos( $attachment->post_mime_type, '/' ) !== false ) { list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); } else { list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); @@ -3125,90 +2992,90 @@ function acf_get_attachment( $attachment ) { // Generate response. $response = array( - 'ID' => $attachment->ID, - 'id' => $attachment->ID, - 'title' => $attachment->post_title, - 'filename' => wp_basename( $attached_file ), - 'filesize' => 0, - 'url' => wp_get_attachment_url( $attachment->ID ), - 'link' => get_attachment_link( $attachment->ID ), - 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), - 'author' => $attachment->post_author, - 'description' => $attachment->post_content, - 'caption' => $attachment->post_excerpt, - 'name' => $attachment->post_name, - 'status' => $attachment->post_status, - 'uploaded_to' => $attachment->post_parent, - 'date' => $attachment->post_date_gmt, - 'modified' => $attachment->post_modified_gmt, - 'menu_order' => $attachment->menu_order, - 'mime_type' => $attachment->post_mime_type, - 'type' => $type, - 'subtype' => $subtype, - 'icon' => wp_mime_type_icon( $attachment->ID ) + 'ID' => $attachment->ID, + 'id' => $attachment->ID, + 'title' => $attachment->post_title, + 'filename' => wp_basename( $attached_file ), + 'filesize' => 0, + 'url' => wp_get_attachment_url( $attachment->ID ), + 'link' => get_attachment_link( $attachment->ID ), + 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), + 'author' => $attachment->post_author, + 'description' => $attachment->post_content, + 'caption' => $attachment->post_excerpt, + 'name' => $attachment->post_name, + 'status' => $attachment->post_status, + 'uploaded_to' => $attachment->post_parent, + 'date' => $attachment->post_date_gmt, + 'modified' => $attachment->post_modified_gmt, + 'menu_order' => $attachment->menu_order, + 'mime_type' => $attachment->post_mime_type, + 'type' => $type, + 'subtype' => $subtype, + 'icon' => wp_mime_type_icon( $attachment->ID ), ); - + // Append filesize data. - if( isset($meta['filesize']) ) { + if ( isset( $meta['filesize'] ) ) { $response['filesize'] = $meta['filesize']; - } elseif( file_exists($attached_file) ) { + } elseif ( file_exists( $attached_file ) ) { $response['filesize'] = filesize( $attached_file ); } - + // Restrict the loading of image "sizes". $sizes_id = 0; // Type specific logic. - switch( $type ) { + switch ( $type ) { case 'image': $sizes_id = $attachment->ID; - $src = wp_get_attachment_image_src( $attachment->ID, 'full' ); + $src = wp_get_attachment_image_src( $attachment->ID, 'full' ); if ( $src ) { - $response['url'] = $src[0]; - $response['width'] = $src[1]; + $response['url'] = $src[0]; + $response['width'] = $src[1]; $response['height'] = $src[2]; } break; case 'video': - $response['width'] = acf_maybe_get( $meta, 'width', 0 ); + $response['width'] = acf_maybe_get( $meta, 'width', 0 ); $response['height'] = acf_maybe_get( $meta, 'height', 0 ); - if( $featured_id = get_post_thumbnail_id( $attachment->ID ) ) { + if ( $featured_id = get_post_thumbnail_id( $attachment->ID ) ) { $sizes_id = $featured_id; } break; case 'audio': - if( $featured_id = get_post_thumbnail_id( $attachment->ID ) ) { + if ( $featured_id = get_post_thumbnail_id( $attachment->ID ) ) { $sizes_id = $featured_id; - } + } break; } // Load array of image sizes. - if( $sizes_id ) { - $sizes = get_intermediate_image_sizes(); + if ( $sizes_id ) { + $sizes = get_intermediate_image_sizes(); $sizes_data = array(); - foreach( $sizes as $size ) { + foreach ( $sizes as $size ) { $src = wp_get_attachment_image_src( $sizes_id, $size ); if ( $src ) { - $sizes_data[ $size ] = $src[0]; - $sizes_data[ $size . '-width' ] = $src[1]; + $sizes_data[ $size ] = $src[0]; + $sizes_data[ $size . '-width' ] = $src[1]; $sizes_data[ $size . '-height' ] = $src[2]; } } $response['sizes'] = $sizes_data; } - + /** * Filters the attachment $response after it has been loaded. * - * @date 16/06/2020 - * @since 5.9.0 + * @date 16/06/2020 + * @since 5.9.0 * - * @param array $response Array of loaded attachment data. - * @param WP_Post $attachment Attachment object. - * @param array|false $meta Array of attachment meta data, or false if there is none. + * @param array $response Array of loaded attachment data. + * @param WP_Post $attachment Attachment object. + * @param array|false $meta Array of attachment meta data, or false if there is none. */ - return apply_filters( "acf/load_attachment", $response, $attachment, $meta ); + return apply_filters( 'acf/load_attachment', $response, $attachment, $meta ); } @@ -3217,37 +3084,34 @@ function acf_get_attachment( $attachment ) { * * This function will truncate and return a string * -* @type function -* @date 8/08/2014 -* @since 5.0.0 +* @type function +* @date 8/08/2014 +* @since 5.0.0 * -* @param $text (string) -* @param $length (int) -* @return (string) +* @param $text (string) +* @param $length (int) +* @return (string) */ function acf_get_truncated( $text, $length = 64 ) { - + // vars - $text = trim($text); + $text = trim( $text ); $the_length = strlen( $text ); - - + // cut - $return = substr( $text, 0, ($length - 3) ); - - + $return = substr( $text, 0, ( $length - 3 ) ); + // ... - if( $the_length > ($length - 3) ) { - + if ( $the_length > ( $length - 3 ) ) { + $return .= '...'; - + } - - + // return return $return; - + } /* @@ -3255,26 +3119,25 @@ function acf_get_truncated( $text, $length = 64 ) { * * This function will return true if the current user can administrate the ACF field groups * -* @type function -* @date 9/02/2015 -* @since 5.1.5 +* @type function +* @date 9/02/2015 +* @since 5.1.5 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_current_user_can_admin() { - - if( acf_get_setting('show_admin') && current_user_can(acf_get_setting('capability')) ) { - + + if ( acf_get_setting( 'show_admin' ) && current_user_can( acf_get_setting( 'capability' ) ) ) { + return true; - + } - - + // return return false; - + } @@ -3283,53 +3146,48 @@ function acf_current_user_can_admin() { * * This function will return a numeric value of bytes for a given filesize string * -* @type function -* @date 18/02/2015 -* @since 5.1.5 +* @type function +* @date 18/02/2015 +* @since 5.1.5 * -* @param $size (mixed) -* @return (int) +* @param $size (mixed) +* @return (int) */ function acf_get_filesize( $size = 1 ) { - + // vars - $unit = 'MB'; + $unit = 'MB'; $units = array( 'TB' => 4, 'GB' => 3, 'MB' => 2, 'KB' => 1, ); - - + // look for $unit within the $size parameter (123 KB) - if( is_string($size) ) { - + if ( is_string( $size ) ) { + // vars - $custom = strtoupper( substr($size, -2) ); - - foreach( $units as $k => $v ) { - - if( $custom === $k ) { - + $custom = strtoupper( substr( $size, -2 ) ); + + foreach ( $units as $k => $v ) { + + if ( $custom === $k ) { + $unit = $k; - $size = substr($size, 0, -2); - + $size = substr( $size, 0, -2 ); + } - } - } - - + // calc bytes - $bytes = floatval($size) * pow(1024, $units[$unit]); - - + $bytes = floatval( $size ) * pow( 1024, $units[ $unit ] ); + // return return $bytes; - + } @@ -3338,20 +3196,19 @@ function acf_get_filesize( $size = 1 ) { * * This function will return a formatted string containing the filesize and unit * -* @type function -* @date 18/02/2015 -* @since 5.1.5 +* @type function +* @date 18/02/2015 +* @since 5.1.5 * -* @param $size (mixed) -* @return (int) +* @param $size (mixed) +* @return (int) */ function acf_format_filesize( $size = 1 ) { - + // convert $bytes = acf_get_filesize( $size ); - - + // vars $units = array( 'TB' => 4, @@ -3359,25 +3216,22 @@ function acf_format_filesize( $size = 1 ) { 'MB' => 2, 'KB' => 1, ); - - + // loop through units - foreach( $units as $k => $v ) { - - $result = $bytes / pow(1024, $v); - - if( $result >= 1 ) { - + foreach ( $units as $k => $v ) { + + $result = $bytes / pow( 1024, $v ); + + if ( $result >= 1 ) { + return $result . ' ' . $k; - + } - } - - + // return return $bytes . ' B'; - + } @@ -3386,50 +3240,45 @@ function acf_format_filesize( $size = 1 ) { * * This function will replace old terms with new split term ids * -* @type function -* @date 27/02/2015 -* @since 5.1.5 +* @type function +* @date 27/02/2015 +* @since 5.1.5 * -* @param $terms (int|array) -* @param $taxonomy (string) -* @return $terms +* @param $terms (int|array) +* @param $taxonomy (string) +* @return $terms */ function acf_get_valid_terms( $terms = false, $taxonomy = 'category' ) { - + // force into array - $terms = acf_get_array($terms); - - + $terms = acf_get_array( $terms ); + // force ints - $terms = array_map('intval', $terms); - - + $terms = array_map( 'intval', $terms ); + // bail early if function does not yet exist or - if( !function_exists('wp_get_split_term') || empty($terms) ) { - + if ( ! function_exists( 'wp_get_split_term' ) || empty( $terms ) ) { + return $terms; - + } - - + // attempt to find new terms - foreach( $terms as $i => $term_id ) { - - $new_term_id = wp_get_split_term($term_id, $taxonomy); - - if( $new_term_id ) { - + foreach ( $terms as $i => $term_id ) { + + $new_term_id = wp_get_split_term( $term_id, $taxonomy ); + + if ( $new_term_id ) { + $terms[ $i ] = $new_term_id; - + } - } - - + // return return $terms; - + } @@ -3438,185 +3287,172 @@ function acf_get_valid_terms( $terms = false, $taxonomy = 'category' ) { * * This function will validate an attachment based on a field's restrictions and return an array of errors * -* @type function -* @date 3/07/2015 -* @since 5.2.3 +* @type function +* @date 3/07/2015 +* @since 5.2.3 * -* @param $attachment (array) attachment data. Changes based on context -* @param $field (array) field settings containing restrictions -* @param $context (string) $file is different when uploading / preparing -* @return $errors (array) +* @param $attachment (array) attachment data. Changes based on context +* @param $field (array) field settings containing restrictions +* @param $context (string) $file is different when uploading / preparing +* @return $errors (array) */ function acf_validate_attachment( $attachment, $field, $context = 'prepare' ) { - + // vars $errors = array(); - $file = array( - 'type' => '', - 'width' => 0, - 'height' => 0, - 'size' => 0 + $file = array( + 'type' => '', + 'width' => 0, + 'height' => 0, + 'size' => 0, ); - - + // upload - if( $context == 'upload' ) { - + if ( $context == 'upload' ) { + // vars - $file['type'] = pathinfo($attachment['name'], PATHINFO_EXTENSION); - $file['size'] = filesize($attachment['tmp_name']); - - if( strpos($attachment['type'], 'image') !== false ) { - - $size = getimagesize($attachment['tmp_name']); - $file['width'] = acf_maybe_get($size, 0); - $file['height'] = acf_maybe_get($size, 1); - + $file['type'] = pathinfo( $attachment['name'], PATHINFO_EXTENSION ); + $file['size'] = filesize( $attachment['tmp_name'] ); + + if ( strpos( $attachment['type'], 'image' ) !== false ) { + + $size = getimagesize( $attachment['tmp_name'] ); + $file['width'] = acf_maybe_get( $size, 0 ); + $file['height'] = acf_maybe_get( $size, 1 ); + } - - // prepare - } elseif( $context == 'prepare' ) { - - $use_path = isset($attachment['filename']) ? $attachment['filename'] : $attachment['url']; - $file['type'] = pathinfo($use_path, PATHINFO_EXTENSION); - $file['size'] = acf_maybe_get($attachment, 'filesizeInBytes', 0); - $file['width'] = acf_maybe_get($attachment, 'width', 0); - $file['height'] = acf_maybe_get($attachment, 'height', 0); - - // custom + + // prepare + } elseif ( $context == 'prepare' ) { + + $use_path = isset( $attachment['filename'] ) ? $attachment['filename'] : $attachment['url']; + $file['type'] = pathinfo( $use_path, PATHINFO_EXTENSION ); + $file['size'] = acf_maybe_get( $attachment, 'filesizeInBytes', 0 ); + $file['width'] = acf_maybe_get( $attachment, 'width', 0 ); + $file['height'] = acf_maybe_get( $attachment, 'height', 0 ); + + // custom } else { - - $file = array_merge($file, $attachment); - $use_path = isset($attachment['filename']) ? $attachment['filename'] : $attachment['url']; - $file['type'] = pathinfo($use_path, PATHINFO_EXTENSION); - + + $file = array_merge( $file, $attachment ); + $use_path = isset( $attachment['filename'] ) ? $attachment['filename'] : $attachment['url']; + $file['type'] = pathinfo( $use_path, PATHINFO_EXTENSION ); + } - - + // image - if( $file['width'] || $file['height'] ) { - + if ( $file['width'] || $file['height'] ) { + // width - $min_width = (int) acf_maybe_get($field, 'min_width', 0); - $max_width = (int) acf_maybe_get($field, 'max_width', 0); - - if( $file['width'] ) { - - if( $min_width && $file['width'] < $min_width ) { - + $min_width = (int) acf_maybe_get( $field, 'min_width', 0 ); + $max_width = (int) acf_maybe_get( $field, 'max_width', 0 ); + + if ( $file['width'] ) { + + if ( $min_width && $file['width'] < $min_width ) { + // min width - $errors['min_width'] = sprintf(__('Image width must be at least %dpx.', 'acf'), $min_width ); - - } elseif( $max_width && $file['width'] > $max_width ) { - + $errors['min_width'] = sprintf( __( 'Image width must be at least %dpx.', 'acf' ), $min_width ); + + } elseif ( $max_width && $file['width'] > $max_width ) { + // min width - $errors['max_width'] = sprintf(__('Image width must not exceed %dpx.', 'acf'), $max_width ); - + $errors['max_width'] = sprintf( __( 'Image width must not exceed %dpx.', 'acf' ), $max_width ); + } - } - - + // height - $min_height = (int) acf_maybe_get($field, 'min_height', 0); - $max_height = (int) acf_maybe_get($field, 'max_height', 0); - - if( $file['height'] ) { - - if( $min_height && $file['height'] < $min_height ) { - + $min_height = (int) acf_maybe_get( $field, 'min_height', 0 ); + $max_height = (int) acf_maybe_get( $field, 'max_height', 0 ); + + if ( $file['height'] ) { + + if ( $min_height && $file['height'] < $min_height ) { + // min height - $errors['min_height'] = sprintf(__('Image height must be at least %dpx.', 'acf'), $min_height ); - - } elseif( $max_height && $file['height'] > $max_height ) { - + $errors['min_height'] = sprintf( __( 'Image height must be at least %dpx.', 'acf' ), $min_height ); + + } elseif ( $max_height && $file['height'] > $max_height ) { + // min height - $errors['max_height'] = sprintf(__('Image height must not exceed %dpx.', 'acf'), $max_height ); - + $errors['max_height'] = sprintf( __( 'Image height must not exceed %dpx.', 'acf' ), $max_height ); + } - } - } - - + // file size - if( $file['size'] ) { - - $min_size = acf_maybe_get($field, 'min_size', 0); - $max_size = acf_maybe_get($field, 'max_size', 0); - - if( $min_size && $file['size'] < acf_get_filesize($min_size) ) { - + if ( $file['size'] ) { + + $min_size = acf_maybe_get( $field, 'min_size', 0 ); + $max_size = acf_maybe_get( $field, 'max_size', 0 ); + + if ( $min_size && $file['size'] < acf_get_filesize( $min_size ) ) { + // min width - $errors['min_size'] = sprintf(__('File size must be at least %s.', 'acf'), acf_format_filesize($min_size) ); - - } elseif( $max_size && $file['size'] > acf_get_filesize($max_size) ) { - + $errors['min_size'] = sprintf( __( 'File size must be at least %s.', 'acf' ), acf_format_filesize( $min_size ) ); + + } elseif ( $max_size && $file['size'] > acf_get_filesize( $max_size ) ) { + // min width - $errors['max_size'] = sprintf(__('File size must not exceed %s.', 'acf'), acf_format_filesize($max_size) ); - + $errors['max_size'] = sprintf( __( 'File size must not exceed %s.', 'acf' ), acf_format_filesize( $max_size ) ); + } - } - - + // file type - if( $file['type'] ) { - - $mime_types = acf_maybe_get($field, 'mime_types', ''); - + if ( $file['type'] ) { + + $mime_types = acf_maybe_get( $field, 'mime_types', '' ); + // lower case - $file['type'] = strtolower($file['type']); - $mime_types = strtolower($mime_types); - - + $file['type'] = strtolower( $file['type'] ); + $mime_types = strtolower( $mime_types ); + // explode - $mime_types = str_replace(array(' ', '.'), '', $mime_types); - $mime_types = explode(',', $mime_types); // split pieces - $mime_types = array_filter($mime_types); // remove empty pieces - - if( !empty($mime_types) && !in_array($file['type'], $mime_types) ) { - + $mime_types = str_replace( array( ' ', '.' ), '', $mime_types ); + $mime_types = explode( ',', $mime_types ); // split pieces + $mime_types = array_filter( $mime_types ); // remove empty pieces + + if ( ! empty( $mime_types ) && ! in_array( $file['type'], $mime_types ) ) { + // glue together last 2 types - if( count($mime_types) > 1 ) { - - $last1 = array_pop($mime_types); - $last2 = array_pop($mime_types); - - $mime_types[] = $last2 . ' ' . __('or', 'acf') . ' ' . $last1; - + if ( count( $mime_types ) > 1 ) { + + $last1 = array_pop( $mime_types ); + $last2 = array_pop( $mime_types ); + + $mime_types[] = $last2 . ' ' . __( 'or', 'acf' ) . ' ' . $last1; + } - - $errors['mime_types'] = sprintf(__('File type must be %s.', 'acf'), implode(', ', $mime_types) ); - + + $errors['mime_types'] = sprintf( __( 'File type must be %s.', 'acf' ), implode( ', ', $mime_types ) ); + } - } - - + /** * Filters the errors for a file before it is uploaded or displayed in the media modal. * - * @date 3/07/2015 - * @since 5.2.3 + * @date 3/07/2015 + * @since 5.2.3 * - * @param array $errors An array of errors. - * @param array $file An array of data for a single file. - * @param array $attachment An array of attachment data which differs based on the context. - * @param array $field The field array. - * @param string $context The curent context (uploading, preparing) + * @param array $errors An array of errors. + * @param array $file An array of data for a single file. + * @param array $attachment An array of attachment data which differs based on the context. + * @param array $field The field array. + * @param string $context The curent context (uploading, preparing) */ - $errors = apply_filters( "acf/validate_attachment/type={$field['type']}", $errors, $file, $attachment, $field, $context ); - $errors = apply_filters( "acf/validate_attachment/name={$field['_name']}", $errors, $file, $attachment, $field, $context ); - $errors = apply_filters( "acf/validate_attachment/key={$field['key']}", $errors, $file, $attachment, $field, $context ); - $errors = apply_filters( "acf/validate_attachment", $errors, $file, $attachment, $field, $context ); - - + $errors = apply_filters( "acf/validate_attachment/type={$field['type']}", $errors, $file, $attachment, $field, $context ); + $errors = apply_filters( "acf/validate_attachment/name={$field['_name']}", $errors, $file, $attachment, $field, $context ); + $errors = apply_filters( "acf/validate_attachment/key={$field['key']}", $errors, $file, $attachment, $field, $context ); + $errors = apply_filters( 'acf/validate_attachment', $errors, $file, $attachment, $field, $context ); + // return return $errors; - + } @@ -3625,26 +3461,25 @@ function acf_validate_attachment( $attachment, $field, $context = 'prepare' ) { * * Dynamic logic for uploader setting * -* @type function -* @date 7/05/2015 -* @since 5.2.3 +* @type function +* @date 7/05/2015 +* @since 5.2.3 * -* @param $uploader (string) -* @return $uploader +* @param $uploader (string) +* @return $uploader */ -add_filter('acf/settings/uploader', '_acf_settings_uploader'); +add_filter( 'acf/settings/uploader', '_acf_settings_uploader' ); function _acf_settings_uploader( $uploader ) { - + // if can't upload files - if( !current_user_can('upload_files') ) { - + if ( ! current_user_can( 'upload_files' ) ) { + $uploader = 'basic'; - + } - - + // return return $uploader; } @@ -3655,37 +3490,37 @@ function _acf_settings_uploader( $uploader ) { * * description * -* @type function -* @date 7/12/2015 -* @since 5.3.2 +* @type function +* @date 7/12/2015 +* @since 5.3.2 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ /* function acf_translate_keys( $array, $keys ) { - + // bail early if no keys if( empty($keys) ) return $array; - - + + // translate foreach( $keys as $k ) { - + // bail ealry if not exists if( !isset($array[ $k ]) ) continue; - - + + // translate $array[ $k ] = acf_translate( $array[ $k ] ); - + } - - + + // return return $array; - + } */ @@ -3696,61 +3531,63 @@ function acf_translate_keys( $array, $keys ) { * This function will translate a string using the new 'l10n_textdomain' setting * Also works for arrays which is great for fields - select -> choices * -* @type function -* @date 4/12/2015 -* @since 5.3.2 +* @type function +* @date 4/12/2015 +* @since 5.3.2 * -* @param $string (mixed) string or array containins strings to be translated -* @return $string +* @param $string (mixed) string or array containins strings to be translated +* @return $string */ function acf_translate( $string ) { - + // vars - $l10n = acf_get_setting('l10n'); - $textdomain = acf_get_setting('l10n_textdomain'); - - + $l10n = acf_get_setting( 'l10n' ); + $textdomain = acf_get_setting( 'l10n_textdomain' ); + // bail early if not enabled - if( !$l10n ) return $string; - - + if ( ! $l10n ) { + return $string; + } + // bail early if no textdomain - if( !$textdomain ) return $string; - - + if ( ! $textdomain ) { + return $string; + } + // is array - if( is_array($string) ) { - - return array_map('acf_translate', $string); - + if ( is_array( $string ) ) { + + return array_map( 'acf_translate', $string ); + } - - + // bail early if not string - if( !is_string($string) ) return $string; - - - // bail early if empty - if( $string === '' ) return $string; - - - // allow for var_export export - if( acf_get_setting('l10n_var_export') ){ - - // bail early if already translated - if( substr($string, 0, 7) === '!!__(!!' ) return $string; - - - // return - return "!!__(!!'" . $string . "!!', !!'" . $textdomain . "!!')!!"; - + if ( ! is_string( $string ) ) { + return $string; } - - + + // bail early if empty + if ( $string === '' ) { + return $string; + } + + // allow for var_export export + if ( acf_get_setting( 'l10n_var_export' ) ) { + + // bail early if already translated + if ( substr( $string, 0, 7 ) === '!!__(!!' ) { + return $string; + } + + // return + return "!!__(!!'" . $string . "!!', !!'" . $textdomain . "!!')!!"; + + } + // vars return __( $string, $textdomain ); - + } @@ -3759,29 +3596,29 @@ function acf_translate( $string ) { * * This function will determine if the action has already run before adding / calling the function * -* @type function -* @date 13/01/2016 -* @since 5.3.2 +* @type function +* @date 13/01/2016 +* @since 5.3.2 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_maybe_add_action( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) { - + // if action has already run, execute it // - if currently doing action, allow $tag to be added as per usual to allow $priority ordering needed for 3rd party asset compatibility - if( did_action($tag) && !doing_action($tag) ) { - + if ( did_action( $tag ) && ! doing_action( $tag ) ) { + call_user_func( $function_to_add ); - - // if action has not yet run, add it + + // if action has not yet run, add it } else { - + add_action( $tag, $function_to_add, $priority, $accepted_args ); - + } - + } @@ -3790,41 +3627,37 @@ function acf_maybe_add_action( $tag, $function_to_add, $priority = 10, $accepted * * This function will return true if the field's row is collapsed * -* @type function -* @date 2/03/2016 -* @since 5.3.2 +* @type function +* @date 2/03/2016 +* @since 5.3.2 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_is_row_collapsed( $field_key = '', $row_index = 0 ) { - + // collapsed - $collapsed = acf_get_user_setting('collapsed_' . $field_key, ''); - - + $collapsed = acf_get_user_setting( 'collapsed_' . $field_key, '' ); + // cookie fallback ( version < 5.3.2 ) - if( $collapsed === '' ) { - - $collapsed = acf_extract_var($_COOKIE, "acf_collapsed_{$field_key}", ''); - $collapsed = str_replace('|', ',', $collapsed); - - + if ( $collapsed === '' ) { + + $collapsed = acf_extract_var( $_COOKIE, "acf_collapsed_{$field_key}", '' ); + $collapsed = str_replace( '|', ',', $collapsed ); + // update acf_update_user_setting( 'collapsed_' . $field_key, $collapsed ); - + } - - + // explode - $collapsed = explode(',', $collapsed); - $collapsed = array_filter($collapsed, 'is_numeric'); - - + $collapsed = explode( ',', $collapsed ); + $collapsed = array_filter( $collapsed, 'is_numeric' ); + // collapsed class - return in_array($row_index, $collapsed); - + return in_array( $row_index, $collapsed ); + } @@ -3833,28 +3666,28 @@ function acf_is_row_collapsed( $field_key = '', $row_index = 0 ) { * * description * -* @type function -* @date 24/10/16 -* @since 5.5.0 +* @type function +* @date 24/10/16 +* @since 5.5.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_get_attachment_image( $attachment_id = 0, $size = 'thumbnail' ) { - + // vars - $url = wp_get_attachment_image_src($attachment_id, 'thumbnail'); - $alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true); - - + $url = wp_get_attachment_image_src( $attachment_id, 'thumbnail' ); + $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); + // bail early if no url - if( !$url ) return ''; - - + if ( ! $url ) { + return ''; + } + // return $value = '' . $alt . ''; - + } @@ -3863,77 +3696,71 @@ function acf_get_attachment_image( $attachment_id = 0, $size = 'thumbnail' ) { * * This function will return a thumbail image url for a given post * -* @type function -* @date 3/05/2016 -* @since 5.3.8 +* @type function +* @date 3/05/2016 +* @since 5.3.8 * -* @param $post (obj) -* @param $size (mixed) -* @return (string) +* @param $post (obj) +* @param $size (mixed) +* @return (string) */ function acf_get_post_thumbnail( $post = null, $size = 'thumbnail' ) { - + // vars $data = array( - 'url' => '', - 'type' => '', - 'html' => '' + 'url' => '', + 'type' => '', + 'html' => '', ); - - + // post - $post = get_post($post); - - + $post = get_post( $post ); + // bail early if no post - if( !$post ) return $data; - - + if ( ! $post ) { + return $data; + } + // vars - $thumb_id = $post->ID; - $mime_type = acf_maybe_get(explode('/', $post->post_mime_type), 0); - - + $thumb_id = $post->ID; + $mime_type = acf_maybe_get( explode( '/', $post->post_mime_type ), 0 ); + // attachment - if( $post->post_type === 'attachment' ) { - + if ( $post->post_type === 'attachment' ) { + // change $thumb_id - if( $mime_type === 'audio' || $mime_type === 'video' ) { - - $thumb_id = get_post_thumbnail_id($post->ID); - + if ( $mime_type === 'audio' || $mime_type === 'video' ) { + + $thumb_id = get_post_thumbnail_id( $post->ID ); + } - - // post + + // post } else { - - $thumb_id = get_post_thumbnail_id($post->ID); - + + $thumb_id = get_post_thumbnail_id( $post->ID ); + } - - + // try url - $data['url'] = wp_get_attachment_image_src($thumb_id, $size); - $data['url'] = acf_maybe_get($data['url'], 0); - - + $data['url'] = wp_get_attachment_image_src( $thumb_id, $size ); + $data['url'] = acf_maybe_get( $data['url'], 0 ); + // default icon - if( !$data['url'] && $post->post_type === 'attachment' ) { - - $data['url'] = wp_mime_type_icon($post->ID); + if ( ! $data['url'] && $post->post_type === 'attachment' ) { + + $data['url'] = wp_mime_type_icon( $post->ID ); $data['type'] = 'icon'; - + } - - + // html $data['html'] = ''; - - + // return return $data; - + } /** @@ -3941,34 +3768,34 @@ function acf_get_post_thumbnail( $post = null, $size = 'thumbnail' ) { * * Returns the name of the current browser. * - * @date 17/01/2014 - * @since 5.0.0 + * @date 17/01/2014 + * @since 5.0.0 * - * @param void - * @return string + * @param void + * @return string */ function acf_get_browser() { - + // Check server var. - if( isset($_SERVER['HTTP_USER_AGENT']) ) { + if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) { $agent = $_SERVER['HTTP_USER_AGENT']; - + // Loop over search terms. $browsers = array( - 'Firefox' => 'firefox', - 'Trident' => 'msie', - 'MSIE' => 'msie', - 'Edge' => 'edge', - 'Chrome' => 'chrome', - 'Safari' => 'safari', + 'Firefox' => 'firefox', + 'Trident' => 'msie', + 'MSIE' => 'msie', + 'Edge' => 'edge', + 'Chrome' => 'chrome', + 'Safari' => 'safari', ); - foreach( $browsers as $k => $v ) { - if( strpos($agent, $k) !== false ) { + foreach ( $browsers as $k => $v ) { + if ( strpos( $agent, $k ) !== false ) { return $v; } } } - + // Return default. return ''; } @@ -3979,39 +3806,36 @@ function acf_get_browser() { * * This function will reutrn true if performing a wp ajax call * -* @type function -* @date 7/06/2016 -* @since 5.3.8 +* @type function +* @date 7/06/2016 +* @since 5.3.8 * -* @param n/a -* @return (boolean) +* @param n/a +* @return (boolean) */ function acf_is_ajax( $action = '' ) { - + // vars $is_ajax = false; - - + // check if is doing ajax - if( defined('DOING_AJAX') && DOING_AJAX ) { - + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + $is_ajax = true; - + } - - + // check $action - if( $action && acf_maybe_get($_POST, 'action') !== $action ) { - + if ( $action && acf_maybe_get( $_POST, 'action' ) !== $action ) { + $is_ajax = false; - + } - - + // return return $is_ajax; - + } @@ -4022,39 +3846,38 @@ function acf_is_ajax( $action = '' ) { * * This function will accept a date value and return it in a formatted string * -* @type function -* @date 16/06/2016 -* @since 5.3.8 +* @type function +* @date 16/06/2016 +* @since 5.3.8 * -* @param $value (string) -* @return $format (string) +* @param $value (string) +* @return $format (string) */ function acf_format_date( $value, $format ) { - + // bail early if no value - if( !$value ) return $value; - - + if ( ! $value ) { + return $value; + } + // vars $unixtimestamp = 0; - - + // numeric (either unix or YYYYMMDD) - if( is_numeric($value) && strlen($value) !== 8 ) { - + if ( is_numeric( $value ) && strlen( $value ) !== 8 ) { + $unixtimestamp = $value; - + } else { - - $unixtimestamp = strtotime($value); - + + $unixtimestamp = strtotime( $value ); + } - - + // return - return date_i18n($format, $unixtimestamp); - + return date_i18n( $format, $unixtimestamp ); + } /** @@ -4062,11 +3885,11 @@ function acf_format_date( $value, $format ) { * * Deletes the debug.log file. * - * @date 21/1/19 - * @since 5.7.10 + * @date 21/1/19 + * @since 5.7.10 * - * @param type $var Description. Default. - * @return type Description. + * @param type $var Description. Default. + * @return type Description. */ function acf_clear_log() { unlink( WP_CONTENT_DIR . '/debug.log' ); @@ -4077,53 +3900,53 @@ function acf_clear_log() { * * description * -* @type function -* @date 24/06/2016 -* @since 5.3.8 +* @type function +* @date 24/06/2016 +* @since 5.3.8 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_log() { - + // vars $args = func_get_args(); - + // loop - foreach( $args as $i => $arg ) { - + foreach ( $args as $i => $arg ) { + // array | object - if( is_array($arg) || is_object($arg) ) { - $arg = print_r($arg, true); - - // bool - } elseif( is_bool($arg) ) { + if ( is_array( $arg ) || is_object( $arg ) ) { + $arg = print_r( $arg, true ); + + // bool + } elseif ( is_bool( $arg ) ) { $arg = 'bool(' . ( $arg ? 'true' : 'false' ) . ')'; } - + // update $args[ $i ] = $arg; } - + // log - error_log( implode(' ', $args) ); + error_log( implode( ' ', $args ) ); } /** -* acf_dev_log -* -* Used to log variables only if ACF_DEV is defined -* -* @date 25/8/18 -* @since 5.7.4 -* -* @param mixed -* @return void -*/ + * acf_dev_log + * + * Used to log variables only if ACF_DEV is defined + * + * @date 25/8/18 + * @since 5.7.4 + * + * @param mixed + * @return void + */ function acf_dev_log() { - if( defined('ACF_DEV') && ACF_DEV ) { - call_user_func_array('acf_log', func_get_args()); + if ( defined( 'ACF_DEV' ) && ACF_DEV ) { + call_user_func_array( 'acf_log', func_get_args() ); } } @@ -4132,20 +3955,20 @@ function acf_dev_log() { * * This function will tell ACF what task it is doing * -* @type function -* @date 28/06/2016 -* @since 5.3.8 +* @type function +* @date 28/06/2016 +* @since 5.3.8 * -* @param $event (string) -* @param context (string) -* @return n/a +* @param $event (string) +* @param context (string) +* @return n/a */ function acf_doing( $event = '', $context = '' ) { - + acf_update_setting( 'doing', $event ); acf_update_setting( 'doing_context', $context ); - + } @@ -4154,40 +3977,37 @@ function acf_doing( $event = '', $context = '' ) { * * This function can be used to state what ACF is doing, or to check * -* @type function -* @date 28/06/2016 -* @since 5.3.8 +* @type function +* @date 28/06/2016 +* @since 5.3.8 * -* @param $event (string) -* @param context (string) -* @return (boolean) +* @param $event (string) +* @param context (string) +* @return (boolean) */ function acf_is_doing( $event = '', $context = '' ) { - + // vars $doing = false; - - + // task - if( acf_get_setting('doing') === $event ) { - + if ( acf_get_setting( 'doing' ) === $event ) { + $doing = true; - + } - - + // context - if( $context && acf_get_setting('doing_context') !== $context ) { - + if ( $context && acf_get_setting( 'doing_context' ) !== $context ) { + $doing = false; - + } - - + // return return $doing; - + } @@ -4197,32 +4017,30 @@ function acf_is_doing( $event = '', $context = '' ) { * This function will return true if the ACF plugin is active * - May be included within a theme or other plugin * -* @type function -* @date 13/07/2016 -* @since 5.4.0 +* @type function +* @date 13/07/2016 +* @since 5.4.0 * -* @param $basename (int) -* @return $post_id (int) +* @param $basename (int) +* @return $post_id (int) */ function acf_is_plugin_active() { - + // vars - $basename = acf_get_setting('basename'); - - + $basename = acf_get_setting( 'basename' ); + // ensure is_plugin_active() exists (not on frontend) - if( !function_exists('is_plugin_active') ) { - - include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); - + if ( ! function_exists( 'is_plugin_active' ) ) { + + include_once ABSPATH . 'wp-admin/includes/plugin.php'; + } - - + // return - return is_plugin_active($basename); - + return is_plugin_active( $basename ); + } /* @@ -4230,59 +4048,56 @@ function acf_is_plugin_active() { * * This function will print JSON data for a Select2 AJAX query * -* @type function -* @date 19/07/2016 -* @since 5.4.0 +* @type function +* @date 19/07/2016 +* @since 5.4.0 * -* @param $response (array) -* @return n/a +* @param $response (array) +* @return n/a */ function acf_send_ajax_results( $response ) { - + // validate - $response = wp_parse_args($response, array( - 'results' => array(), - 'more' => false, - 'limit' => 0 - )); - - + $response = wp_parse_args( + $response, + array( + 'results' => array(), + 'more' => false, + 'limit' => 0, + ) + ); + // limit - if( $response['limit'] && $response['results']) { - + if ( $response['limit'] && $response['results'] ) { + // vars $total = 0; - - foreach( $response['results'] as $result ) { - + + foreach ( $response['results'] as $result ) { + // parent $total++; - - + // children - if( !empty($result['children']) ) { - + if ( ! empty( $result['children'] ) ) { + $total += count( $result['children'] ); - + } - } - - + // calc - if( $total >= $response['limit'] ) { - + if ( $total >= $response['limit'] ) { + $response['more'] = true; - + } - } - - + // return wp_send_json( $response ); - + } @@ -4291,33 +4106,34 @@ function acf_send_ajax_results( $response ) { * * This function will return true if the array contains only numeric keys * -* @source http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential -* @type function -* @date 9/09/2016 -* @since 5.4.0 +* @source http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential +* @type function +* @date 9/09/2016 +* @since 5.4.0 * -* @param $array (array) -* @return (boolean) +* @param $array (array) +* @return (boolean) */ function acf_is_sequential_array( $array ) { - + // bail ealry if not array - if( !is_array($array) ) return false; - - - // loop - foreach( $array as $key => $value ) { - - // bail ealry if is string - if( is_string($key) ) return false; - + if ( ! is_array( $array ) ) { + return false; } - - + + // loop + foreach ( $array as $key => $value ) { + + // bail ealry if is string + if ( is_string( $key ) ) { + return false; + } + } + // return return true; - + } @@ -4326,33 +4142,34 @@ function acf_is_sequential_array( $array ) { * * This function will return true if the array contains one or more string keys * -* @source http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential -* @type function -* @date 9/09/2016 -* @since 5.4.0 +* @source http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential +* @type function +* @date 9/09/2016 +* @since 5.4.0 * -* @param $array (array) -* @return (boolean) +* @param $array (array) +* @return (boolean) */ function acf_is_associative_array( $array ) { - + // bail ealry if not array - if( !is_array($array) ) return false; - - - // loop - foreach( $array as $key => $value ) { - - // bail ealry if is string - if( is_string($key) ) return true; - + if ( ! is_array( $array ) ) { + return false; } - - + + // loop + foreach ( $array as $key => $value ) { + + // bail ealry if is string + if ( is_string( $key ) ) { + return true; + } + } + // return return false; - + } @@ -4362,33 +4179,31 @@ function acf_is_associative_array( $array ) { * This function will add a prefix to all array keys * Useful to preserve numeric keys when performing array_multisort * -* @type function -* @date 15/09/2016 -* @since 5.4.0 +* @type function +* @date 15/09/2016 +* @since 5.4.0 * -* @param $array (array) -* @param $prefix (string) -* @return (array) +* @param $array (array) +* @param $prefix (string) +* @return (array) */ function acf_add_array_key_prefix( $array, $prefix ) { - + // vars $array2 = array(); - - + // loop - foreach( $array as $k => $v ) { - - $k2 = $prefix . $k; - $array2[ $k2 ] = $v; - + foreach ( $array as $k => $v ) { + + $k2 = $prefix . $k; + $array2[ $k2 ] = $v; + } - - + // return return $array2; - + } @@ -4398,56 +4213,54 @@ function acf_add_array_key_prefix( $array, $prefix ) { * This function will remove a prefix to all array keys * Useful to preserve numeric keys when performing array_multisort * -* @type function -* @date 15/09/2016 -* @since 5.4.0 +* @type function +* @date 15/09/2016 +* @since 5.4.0 * -* @param $array (array) -* @param $prefix (string) -* @return (array) +* @param $array (array) +* @param $prefix (string) +* @return (array) */ function acf_remove_array_key_prefix( $array, $prefix ) { - + // vars $array2 = array(); - $l = strlen($prefix); - - + $l = strlen( $prefix ); + // loop - foreach( $array as $k => $v ) { - - $k2 = (substr($k, 0, $l) === $prefix) ? substr($k, $l) : $k; - $array2[ $k2 ] = $v; - + foreach ( $array as $k => $v ) { + + $k2 = ( substr( $k, 0, $l ) === $prefix ) ? substr( $k, $l ) : $k; + $array2[ $k2 ] = $v; + } - - + // return return $array2; - + } /* * acf_strip_protocol * -* This function will remove the proticol from a url -* Used to allow licences to remain active if a site is switched to https +* This function will remove the proticol from a url +* Used to allow licences to remain active if a site is switched to https * -* @type function -* @date 10/01/2017 -* @since 5.5.4 -* @author Aaron +* @type function +* @date 10/01/2017 +* @since 5.5.4 +* @author Aaron * -* @param $url (string) -* @return (string) +* @param $url (string) +* @return (string) */ function acf_strip_protocol( $url ) { - - // strip the protical - return str_replace(array('http://','https://'), '', $url); + + // strip the protical + return str_replace( array( 'http://', 'https://' ), '', $url ); } @@ -4455,57 +4268,62 @@ function acf_strip_protocol( $url ) { /* * acf_connect_attachment_to_post * -* This function will connect an attacment (image etc) to the post +* This function will connect an attacment (image etc) to the post * Used to connect attachements uploaded directly to media that have not been attaced to a post * -* @type function -* @date 11/01/2017 -* @since 5.8.0 Added filter to prevent connection. -* @since 5.5.4 +* @type function +* @date 11/01/2017 +* @since 5.8.0 Added filter to prevent connection. +* @since 5.5.4 * -* @param int $attachment_id The attachment ID. -* @param int $post_id The post ID. -* @return bool True if attachment was connected. +* @param int $attachment_id The attachment ID. +* @param int $post_id The post ID. +* @return bool True if attachment was connected. */ function acf_connect_attachment_to_post( $attachment_id = 0, $post_id = 0 ) { - + // Bail ealry if $attachment_id is not valid. - if( !$attachment_id || !is_numeric($attachment_id) ) { + if ( ! $attachment_id || ! is_numeric( $attachment_id ) ) { return false; } - + // Bail ealry if $post_id is not valid. - if( !$post_id || !is_numeric($post_id) ) { + if ( ! $post_id || ! is_numeric( $post_id ) ) { return false; } - + /** * Filters whether or not to connect the attachment. * - * @date 8/11/18 - * @since 5.8.0 + * @date 8/11/18 + * @since 5.8.0 * - * @param bool $bool Returning false will prevent the connection. Default true. - * @param int $attachment_id The attachment ID. - * @param int $post_id The post ID. + * @param bool $bool Returning false will prevent the connection. Default true. + * @param int $attachment_id The attachment ID. + * @param int $post_id The post ID. */ - if( !apply_filters('acf/connect_attachment_to_post', true, $attachment_id, $post_id) ) { + if ( ! apply_filters( 'acf/connect_attachment_to_post', true, $attachment_id, $post_id ) ) { return false; } - - // vars + + // vars $post = get_post( $attachment_id ); - + // Check if is valid post. - if( $post && $post->post_type == 'attachment' && $post->post_parent == 0 ) { - + if ( $post && $post->post_type == 'attachment' && $post->post_parent == 0 ) { + // update - wp_update_post( array('ID' => $post->ID, 'post_parent' => $post_id) ); - + wp_update_post( + array( + 'ID' => $post->ID, + 'post_parent' => $post_id, + ) + ); + // return return true; } - + // return return true; } @@ -4517,36 +4335,34 @@ function acf_connect_attachment_to_post( $attachment_id = 0, $post_id = 0 ) { * This function will encrypt a string using PHP * https://bhoover.com/using-php-openssl_encrypt-openssl_decrypt-encrypt-decrypt-data/ * -* @type function -* @date 27/2/17 -* @since 5.5.8 +* @type function +* @date 27/2/17 +* @since 5.5.8 * -* @param $data (string) -* @return (string) +* @param $data (string) +* @return (string) */ function acf_encrypt( $data = '' ) { - + // bail ealry if no encrypt function - if( !function_exists('openssl_encrypt') ) return base64_encode($data); - - + if ( ! function_exists( 'openssl_encrypt' ) ) { + return base64_encode( $data ); + } + // generate a key - $key = wp_hash('acf_encrypt'); - - - // Generate an initialization vector - $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); - - - // Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector. - $encrypted_data = openssl_encrypt($data, 'aes-256-cbc', $key, 0, $iv); - - - // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::) - return base64_encode($encrypted_data . '::' . $iv); - + $key = wp_hash( 'acf_encrypt' ); + + // Generate an initialization vector + $iv = openssl_random_pseudo_bytes( openssl_cipher_iv_length( 'aes-256-cbc' ) ); + + // Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector. + $encrypted_data = openssl_encrypt( $data, 'aes-256-cbc', $key, 0, $iv ); + + // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::) + return base64_encode( $encrypted_data . '::' . $iv ); + } @@ -4556,209 +4372,208 @@ function acf_encrypt( $data = '' ) { * This function will decrypt an encrypted string using PHP * https://bhoover.com/using-php-openssl_encrypt-openssl_decrypt-encrypt-decrypt-data/ * -* @type function -* @date 27/2/17 -* @since 5.5.8 +* @type function +* @date 27/2/17 +* @since 5.5.8 * -* @param $data (string) -* @return (string) +* @param $data (string) +* @return (string) */ function acf_decrypt( $data = '' ) { - + // bail ealry if no decrypt function - if( !function_exists('openssl_decrypt') ) return base64_decode($data); - - + if ( ! function_exists( 'openssl_decrypt' ) ) { + return base64_decode( $data ); + } + // generate a key - $key = wp_hash('acf_encrypt'); - - - // To decrypt, split the encrypted data from our IV - our unique separator used was "::" - list($encrypted_data, $iv) = explode('::', base64_decode($data), 2); - - - // decrypt - return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv); - + $key = wp_hash( 'acf_encrypt' ); + + // To decrypt, split the encrypted data from our IV - our unique separator used was "::" + list($encrypted_data, $iv) = explode( '::', base64_decode( $data ), 2 ); + + // decrypt + return openssl_decrypt( $encrypted_data, 'aes-256-cbc', $key, 0, $iv ); + } /** -* acf_parse_markdown -* -* A very basic regex-based Markdown parser function based off [slimdown](https://gist.github.com/jbroadway/2836900). -* -* @date 6/8/18 -* @since 5.7.2 -* -* @param string $text The string to parse. -* @return string -*/ + * acf_parse_markdown + * + * A very basic regex-based Markdown parser function based off [slimdown](https://gist.github.com/jbroadway/2836900). + * + * @date 6/8/18 + * @since 5.7.2 + * + * @param string $text The string to parse. + * @return string + */ function acf_parse_markdown( $text = '' ) { - + // trim - $text = trim($text); - + $text = trim( $text ); + // rules - $rules = array ( - '/=== (.+?) ===/' => '

                $1

                ', // headings - '/== (.+?) ==/' => '

                $1

                ', // headings - '/= (.+?) =/' => '

                $1

                ', // headings - '/\[([^\[]+)\]\(([^\)]+)\)/' => '$1', // links - '/(\*\*)(.*?)\1/' => '$2', // bold - '/(\*)(.*?)\1/' => '$2', // intalic - '/`(.*?)`/' => '$1', // inline code - '/\n\*(.*)/' => "\n
                  \n\t
                • $1
                • \n
                ", // ul lists - '/\n[0-9]+\.(.*)/' => "\n
                  \n\t
                1. $1
                2. \n
                ", // ol lists - '/<\/ul>\s?
                  /' => '', // fix extra ul - '/<\/ol>\s?
                    /' => '', // fix extra ol + $rules = array( + '/=== (.+?) ===/' => '

                    $1

                    ', // headings + '/== (.+?) ==/' => '

                    $1

                    ', // headings + '/= (.+?) =/' => '

                    $1

                    ', // headings + '/\[([^\[]+)\]\(([^\)]+)\)/' => '$1', // links + '/(\*\*)(.*?)\1/' => '$2', // bold + '/(\*)(.*?)\1/' => '$2', // intalic + '/`(.*?)`/' => '$1', // inline code + '/\n\*(.*)/' => "\n
                      \n\t
                    • $1
                    • \n
                    ", // ul lists + '/\n[0-9]+\.(.*)/' => "\n
                      \n\t
                    1. $1
                    2. \n
                    ", // ol lists + '/<\/ul>\s?
                      /' => '', // fix extra ul + '/<\/ol>\s?
                        /' => '', // fix extra ol ); - foreach( $rules as $k => $v ) { - $text = preg_replace($k, $v, $text); + foreach ( $rules as $k => $v ) { + $text = preg_replace( $k, $v, $text ); } - + // autop - $text = wpautop($text); - + $text = wpautop( $text ); + // return return $text; } /** -* acf_get_sites -* -* Returns an array of sites for a network. -* -* @date 29/08/2016 -* @since 5.4.0 -* -* @param void -* @return array -*/ + * acf_get_sites + * + * Returns an array of sites for a network. + * + * @date 29/08/2016 + * @since 5.4.0 + * + * @param void + * @return array + */ function acf_get_sites() { $results = array(); - $sites = get_sites( array( 'number' => 0 ) ); - if( $sites ) { - foreach( $sites as $site ) { - $results[] = get_site( $site )->to_array(); - } + $sites = get_sites( array( 'number' => 0 ) ); + if ( $sites ) { + foreach ( $sites as $site ) { + $results[] = get_site( $site )->to_array(); + } } return $results; } /** -* acf_convert_rules_to_groups -* -* Converts an array of rules from ACF4 to an array of groups for ACF5 -* -* @date 25/8/18 -* @since 5.7.4 -* -* @param array $rules An array of rules. -* @param string $anyorall The anyorall setting used in ACF4. Defaults to 'any'. -* @return array -*/ + * acf_convert_rules_to_groups + * + * Converts an array of rules from ACF4 to an array of groups for ACF5 + * + * @date 25/8/18 + * @since 5.7.4 + * + * @param array $rules An array of rules. + * @param string $anyorall The anyorall setting used in ACF4. Defaults to 'any'. + * @return array + */ function acf_convert_rules_to_groups( $rules, $anyorall = 'any' ) { - + // vars $groups = array(); - $index = 0; - + $index = 0; + // loop - foreach( $rules as $rule ) { - + foreach ( $rules as $rule ) { + // extract vars $group = acf_extract_var( $rule, 'group_no' ); $order = acf_extract_var( $rule, 'order_no' ); - + // calculate group if not defined - if( $group === null ) { + if ( $group === null ) { $group = $index; - + // use $anyorall to determine if a new group is needed - if( $anyorall == 'any' ) { + if ( $anyorall == 'any' ) { $index++; } } - + // calculate order if not defined - if( $order === null ) { - $order = isset($groups[ $group ]) ? count($groups[ $group ]) : 0; + if ( $order === null ) { + $order = isset( $groups[ $group ] ) ? count( $groups[ $group ] ) : 0; } - + // append to group $groups[ $group ][ $order ] = $rule; - + // sort groups ksort( $groups[ $group ] ); } - + // sort groups ksort( $groups ); - + // return return $groups; } /** -* acf_register_ajax -* -* Regsiters an ajax callback. -* -* @date 5/10/18 -* @since 5.7.7 -* -* @param string $name The ajax action name. -* @param array $callback The callback function or array. -* @param bool $public Whether to allow access to non logged in users. -* @return void -*/ + * acf_register_ajax + * + * Regsiters an ajax callback. + * + * @date 5/10/18 + * @since 5.7.7 + * + * @param string $name The ajax action name. + * @param array $callback The callback function or array. + * @param bool $public Whether to allow access to non logged in users. + * @return void + */ function acf_register_ajax( $name = '', $callback = false, $public = false ) { - + // vars $action = "acf/ajax/$name"; - + // add action for logged-in users add_action( "wp_ajax_$action", $callback ); - + // add action for non logged-in users - if( $public ) { + if ( $public ) { add_action( "wp_ajax_nopriv_$action", $callback ); } } /** -* acf_str_camel_case -* -* Converts a string into camelCase. -* Thanks to https://stackoverflow.com/questions/31274782/convert-array-keys-from-underscore-case-to-camelcase-recursively -* -* @date 24/10/18 -* @since 5.8.0 -* -* @param string $string The string ot convert. -* @return string -*/ + * acf_str_camel_case + * + * Converts a string into camelCase. + * Thanks to https://stackoverflow.com/questions/31274782/convert-array-keys-from-underscore-case-to-camelcase-recursively + * + * @date 24/10/18 + * @since 5.8.0 + * + * @param string $string The string ot convert. + * @return string + */ function acf_str_camel_case( $string = '' ) { - return lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $string)))); + return lcfirst( str_replace( ' ', '', ucwords( str_replace( '_', ' ', $string ) ) ) ); } /** -* acf_array_camel_case -* -* Converts all aray keys to camelCase. -* -* @date 24/10/18 -* @since 5.8.0 -* -* @param array $array The array to convert. -* @return array -*/ + * acf_array_camel_case + * + * Converts all aray keys to camelCase. + * + * @date 24/10/18 + * @since 5.8.0 + * + * @param array $array The array to convert. + * @return array + */ function acf_array_camel_case( $array = array() ) { $array2 = array(); - foreach( $array as $k => $v ) { - $array2[ acf_str_camel_case($k) ] = $v; + foreach ( $array as $k => $v ) { + $array2[ acf_str_camel_case( $k ) ] = $v; } return $array2; } @@ -4774,7 +4589,7 @@ function acf_array_camel_case( $array = array() ) { function acf_is_block_editor() { if ( function_exists( 'get_current_screen' ) ) { $screen = get_current_screen(); - if( $screen && method_exists( $screen, 'is_block_editor' ) ) { + if ( $screen && method_exists( $screen, 'is_block_editor' ) ) { return $screen->is_block_editor(); } } diff --git a/includes/api/api-template.php b/includes/api/api-template.php index ad99e8a..01f4f94 100644 --- a/includes/api/api-template.php +++ b/includes/api/api-template.php @@ -1,64 +1,60 @@ - $selector, - 'key' => '', - 'type' => '', - )); - - + if ( ! $field ) { + + $field = acf_get_valid_field( + array( + 'name' => $selector, + 'key' => '', + 'type' => '', + ) + ); + // prevent formatting $format_value = false; - + } - - + // get value for field $value = acf_get_value( $post_id, $field ); - - + // format value - if( $format_value ) { - + if ( $format_value ) { + // get value for field $value = acf_format_value( $value, $post_id, $field ); - + } - - + // return return $value; - + } @@ -67,27 +63,27 @@ function get_field( $selector, $post_id = false, $format_value = true ) { * * This function is the same as echo get_field(). * -* @type function -* @since 1.0.3 -* @date 29/01/13 +* @type function +* @since 1.0.3 +* @date 29/01/13 * -* @param $selector (string) the field name or key -* @param $post_id (mixed) the post_id of which the value is saved against -* @return n/a +* @param $selector (string) the field name or key +* @param $post_id (mixed) the post_id of which the value is saved against +* @return n/a */ function the_field( $selector, $post_id = false, $format_value = true ) { - - $value = get_field($selector, $post_id, $format_value); - - if( is_array($value) ) { - + + $value = get_field( $selector, $post_id, $format_value ); + + if ( is_array( $value ) ) { + $value = @implode( ', ', $value ); - + } - + echo $value; - + } @@ -96,55 +92,53 @@ function the_field( $selector, $post_id = false, $format_value = true ) { * * This function will return an array containing all the field data for a given field_name * -* @type function -* @since 3.6 -* @date 3/02/13 +* @type function +* @since 3.6 +* @date 3/02/13 * -* @param $selector (string) the field name or key -* @param $post_id (mixed) the post_id of which the value is saved against -* @param $format_value (boolean) whether or not to format the field value -* @param $load_value (boolean) whether or not to load the field value -* @return $field (array) +* @param $selector (string) the field name or key +* @param $post_id (mixed) the post_id of which the value is saved against +* @param $format_value (boolean) whether or not to format the field value +* @param $load_value (boolean) whether or not to load the field value +* @return $field (array) */ function get_field_object( $selector, $post_id = false, $format_value = true, $load_value = true ) { - + // compatibilty - if( is_array($format_value) ) extract( $format_value ); - - + if ( is_array( $format_value ) ) { + extract( $format_value ); + } + // get valid post_id $post_id = acf_get_valid_post_id( $post_id ); - - + // get field key $field = acf_maybe_get_field( $selector, $post_id ); - - + // bail early if no field found - if( !$field ) return false; - - - // load value - if( $load_value ) { - - $field['value'] = acf_get_value( $post_id, $field ); - + if ( ! $field ) { + return false; } - - + + // load value + if ( $load_value ) { + + $field['value'] = acf_get_value( $post_id, $field ); + + } + // format value - if( $format_value ) { - + if ( $format_value ) { + // get value for field $field['value'] = acf_format_value( $field['value'], $post_id, $field ); - + } - - + // return return $field; - + } /* @@ -153,37 +147,37 @@ function get_field_object( $selector, $post_id = false, $format_value = true, $l * This function will return a field for the given selector. * It will also review the field_reference to ensure the correct field is returned which makes it useful for the template API * -* @type function -* @date 4/08/2015 -* @since 5.2.3 +* @type function +* @date 4/08/2015 +* @since 5.2.3 * -* @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object -* @param $post_id (mixed) the post_id of which the value is saved against -* @param $strict (boolean) if true, return a field only when a field key is found. -* @return $field (array) +* @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object +* @param $post_id (mixed) the post_id of which the value is saved against +* @param $strict (boolean) if true, return a field only when a field key is found. +* @return $field (array) */ function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) { - + // init acf_init(); - + // Check if field key was given. - if( acf_is_field_key($selector) ) { + if ( acf_is_field_key( $selector ) ) { return acf_get_field( $selector ); } - + // Lookup field via reference. $post_id = acf_get_valid_post_id( $post_id ); - $field = acf_get_meta_field( $selector, $post_id ); - if( $field ) { + $field = acf_get_meta_field( $selector, $post_id ); + if ( $field ) { return $field; } - + // Lookup field loosely via name. - if( !$strict ) { - return acf_get_field( $selector ); + if ( ! $strict ) { + return acf_get_field( $selector ); } - + // Return no result. return false; } @@ -193,57 +187,55 @@ function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) { * * This function will attempt to find a sub field * -* @type function -* @date 3/10/2016 -* @since 5.4.0 +* @type function +* @date 3/10/2016 +* @since 5.4.0 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_maybe_get_sub_field( $selectors, $post_id = false, $strict = true ) { - + // bail ealry if not enough selectors - if( !is_array($selectors) || count($selectors) < 3 ) return false; - - + if ( ! is_array( $selectors ) || count( $selectors ) < 3 ) { + return false; + } + // vars - $offset = acf_get_setting('row_index_offset'); - $selector = acf_extract_var( $selectors, 0 ); + $offset = acf_get_setting( 'row_index_offset' ); + $selector = acf_extract_var( $selectors, 0 ); $selectors = array_values( $selectors ); // reset keys - - + // attempt get field $field = acf_maybe_get_field( $selector, $post_id, $strict ); - - + // bail early if no field - if( !$field ) return false; - - + if ( ! $field ) { + return false; + } + // loop - for( $j = 0; $j < count($selectors); $j+=2 ) { - + for ( $j = 0; $j < count( $selectors ); $j += 2 ) { + // vars - $sub_i = $selectors[ $j ]; - $sub_s = $selectors[ $j+1 ]; + $sub_i = $selectors[ $j ]; + $sub_s = $selectors[ $j + 1 ]; $field_name = $field['name']; - - + // find sub field $field = acf_get_sub_field( $sub_s, $field ); - - + // bail early if no sub field - if( !$field ) return false; - - + if ( ! $field ) { + return false; + } + // add to name - $field['name'] = $field_name . '_' . ($sub_i-$offset) . '_' . $field['name']; - + $field['name'] = $field_name . '_' . ( $sub_i - $offset ) . '_' . $field['name']; + } - - + // return return $field; } @@ -254,37 +246,36 @@ function acf_maybe_get_sub_field( $selectors, $post_id = false, $strict = true ) * This function will return an array containing all the custom field values for a specific post_id. * The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the values. * -* @type function -* @since 3.6 -* @date 29/01/13 +* @type function +* @since 3.6 +* @date 29/01/13 * -* @param $post_id (mixed) the post_id of which the value is saved against -* @param $format_value (boolean) whether or not to format the field value -* @return (array) associative array where field name => field value +* @param $post_id (mixed) the post_id of which the value is saved against +* @param $format_value (boolean) whether or not to format the field value +* @return (array) associative array where field name => field value */ function get_fields( $post_id = false, $format_value = true ) { - + // vars $fields = get_field_objects( $post_id, $format_value ); - $meta = array(); - - + $meta = array(); + // bail early - if( !$fields ) return false; - - - // populate - foreach( $fields as $k => $field ) { - - $meta[ $k ] = $field['value']; - + if ( ! $fields ) { + return false; } - - + + // populate + foreach ( $fields as $k => $field ) { + + $meta[ $k ] = $field['value']; + + } + // return - return $meta; - + return $meta; + } @@ -294,61 +285,69 @@ function get_fields( $post_id = false, $format_value = true ) { * This function will return an array containing all the custom field objects for a specific post_id. * The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the fields / values. * -* @type function -* @since 3.6 -* @date 29/01/13 +* @type function +* @since 3.6 +* @date 29/01/13 * -* @param $post_id (mixed) the post_id of which the value is saved against -* @param $format_value (boolean) whether or not to format the field value -* @param $load_value (boolean) whether or not to load the field value -* @return (array) associative array where field name => field +* @param $post_id (mixed) the post_id of which the value is saved against +* @param $format_value (boolean) whether or not to format the field value +* @param $load_value (boolean) whether or not to load the field value +* @return (array) associative array where field name => field */ function get_field_objects( $post_id = false, $format_value = true, $load_value = true ) { - + // init acf_init(); - + // validate post_id $post_id = acf_get_valid_post_id( $post_id ); - + // get meta $meta = acf_get_meta( $post_id ); - + // bail early if no meta - if( empty($meta) ) return false; - + if ( empty( $meta ) ) { + return false; + } + // populate vars $fields = array(); - foreach( $meta as $key => $value ) { - + foreach ( $meta as $key => $value ) { + // bail if reference key does not exist - if( !isset($meta["_$key"]) ) continue; - + if ( ! isset( $meta[ "_$key" ] ) ) { + continue; + } + // get field - $field = acf_get_field($meta["_$key"]); - + $field = acf_get_field( $meta[ "_$key" ] ); + // bail early if no field, or if the field's name is different to $key // - solves problem where sub fields (and clone fields) are incorrectly allowed - if( !$field || $field['name'] !== $key ) continue; - + if ( ! $field || $field['name'] !== $key ) { + continue; + } + // load value - if( $load_value ) { + if ( $load_value ) { $field['value'] = acf_get_value( $post_id, $field ); } - + // format value - if( $format_value ) { + if ( $format_value ) { $field['value'] = acf_format_value( $field['value'], $post_id, $field ); } - + // append to $value $fields[ $key ] = $field; } - + // no value - if( empty($fields) ) return false; - + if ( empty( $fields ) ) { + return false; + } + // return return $fields; } @@ -360,133 +359,133 @@ function get_field_objects( $post_id = false, $format_value = true, $load_value * Checks if a field (such as Repeater or Flexible Content) has any rows of data to loop over. * This function is intended to be used in conjunction with the_row() to step through available values. * - * @date 2/09/13 - * @since 4.3.0 + * @date 2/09/13 + * @since 4.3.0 * - * @param string $selector The field name or field key. - * @param mixed $post_id The post ID where the value is saved. Defaults to the current post. - * @return bool + * @param string $selector The field name or field key. + * @param mixed $post_id The post ID where the value is saved. Defaults to the current post. + * @return bool */ function have_rows( $selector, $post_id = false ) { - + // Validate and backup $post_id. $_post_id = $post_id; - $post_id = acf_get_valid_post_id( $post_id ); - + $post_id = acf_get_valid_post_id( $post_id ); + // Vars. - $key = "selector={$selector}/post_id={$post_id}"; - $active_loop = acf_get_loop('active'); - $prev_loop = acf_get_loop('previous'); - $new_loop = false; - $sub_field = false; - + $key = "selector={$selector}/post_id={$post_id}"; + $active_loop = acf_get_loop( 'active' ); + $prev_loop = acf_get_loop( 'previous' ); + $new_loop = false; + $sub_field = false; + // Check if no active loop. - if( !$active_loop ) { + if ( ! $active_loop ) { $new_loop = 'parent'; - - // Detect "change" compared to the active loop. - } elseif( $key !== $active_loop['key'] ) { - + + // Detect "change" compared to the active loop. + } elseif ( $key !== $active_loop['key'] ) { + // Find sub field and check if a sub value exists. $sub_field_exists = false; - $sub_field = acf_get_sub_field($selector, $active_loop['field']); - if( $sub_field ) { + $sub_field = acf_get_sub_field( $selector, $active_loop['field'] ); + if ( $sub_field ) { $sub_field_exists = isset( $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ] ); } - + // Detect change in post_id. - if( $post_id != $active_loop['post_id'] ) { - + if ( $post_id != $active_loop['post_id'] ) { + // Case: Change in $post_id was due to this being a nested loop and not specifying the $post_id. // Action: Move down one level into a new loop. - if( empty($_post_id) && $sub_field_exists ) { + if ( empty( $_post_id ) && $sub_field_exists ) { $new_loop = 'child'; - - // Case: Change in $post_id was due to a nested loop ending. - // Action: move up one level through the loops. - } elseif( $prev_loop && $prev_loop['post_id'] == $post_id ) { - acf_remove_loop('active'); + + // Case: Change in $post_id was due to a nested loop ending. + // Action: move up one level through the loops. + } elseif ( $prev_loop && $prev_loop['post_id'] == $post_id ) { + acf_remove_loop( 'active' ); $active_loop = $prev_loop; - - // Case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects. - // Action: leave this current loop alone and create a new parent loop. + + // Case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects. + // Action: leave this current loop alone and create a new parent loop. } else { $new_loop = 'parent'; } - - // Detect change in selector. - } elseif( $selector != $active_loop['selector'] ) { - + + // Detect change in selector. + } elseif ( $selector != $active_loop['selector'] ) { + // Case: Change in $field_name was due to this being a nested loop. // Action: move down one level into a new loop. - if( $sub_field_exists ) { + if ( $sub_field_exists ) { $new_loop = 'child'; - - // Case: Change in $field_name was due to a nested loop ending. - // Action: move up one level through the loops. - } elseif( $prev_loop && $prev_loop['selector'] == $selector && $prev_loop['post_id'] == $post_id ) { - acf_remove_loop('active'); + + // Case: Change in $field_name was due to a nested loop ending. + // Action: move up one level through the loops. + } elseif ( $prev_loop && $prev_loop['selector'] == $selector && $prev_loop['post_id'] == $post_id ) { + acf_remove_loop( 'active' ); $active_loop = $prev_loop; - - // Case: Change in $field_name is the most obvious, this is a new loop for a different field within the $post. - // Action: leave this current loop alone and create a new parent loop. + + // Case: Change in $field_name is the most obvious, this is a new loop for a different field within the $post. + // Action: leave this current loop alone and create a new parent loop. } else { $new_loop = 'parent'; } } } - + // Add loop if required. - if( $new_loop ) { + if ( $new_loop ) { $args = array( - 'key' => $key, - 'selector' => $selector, - 'post_id' => $post_id, - 'name' => null, - 'value' => null, - 'field' => null, - 'i' => -1, + 'key' => $key, + 'selector' => $selector, + 'post_id' => $post_id, + 'name' => null, + 'value' => null, + 'field' => null, + 'i' => -1, ); - + // Case: Parent loop. - if( $new_loop === 'parent' ) { + if ( $new_loop === 'parent' ) { $field = get_field_object( $selector, $post_id, false ); - if( $field ) { + if ( $field ) { $args['field'] = $field; $args['value'] = $field['value']; - $args['name'] = $field['name']; + $args['name'] = $field['name']; unset( $args['field']['value'] ); } - - // Case: Child loop ($sub_field must exist). + + // Case: Child loop ($sub_field must exist). } else { - $args['field'] = $sub_field; - $args['value'] = $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ]; - $args['name'] = "{$active_loop['name']}_{$active_loop['i']}_{$sub_field['name']}"; + $args['field'] = $sub_field; + $args['value'] = $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ]; + $args['name'] = "{$active_loop['name']}_{$active_loop['i']}_{$sub_field['name']}"; $args['post_id'] = $active_loop['post_id']; } - + // Bail early if value is either empty or a non array. - if( !$args['value'] || !is_array($args['value']) ) { + if ( ! $args['value'] || ! is_array( $args['value'] ) ) { return false; } - + // Allow for non repeatable data for Group and Clone fields. - if( acf_get_field_type_prop($args['field']['type'], 'have_rows') === 'single' ) { + if ( acf_get_field_type_prop( $args['field']['type'], 'have_rows' ) === 'single' ) { $args['value'] = array( $args['value'] ); } - + // Add loop. - $active_loop = acf_add_loop($args); + $active_loop = acf_add_loop( $args ); } - + // Return true if next row exists. - if( $active_loop && isset($active_loop['value'][ $active_loop['i']+1 ]) ) { + if ( $active_loop && isset( $active_loop['value'][ $active_loop['i'] + 1 ] ) ) { return true; - } - + } + // Return false if no next row. - acf_remove_loop('active'); + acf_remove_loop( 'active' ); return false; } @@ -496,100 +495,93 @@ function have_rows( $selector, $post_id = false ) { * * This function will progress the global repeater or flexible content value 1 row * -* @type function -* @date 2/09/13 -* @since 4.3.0 +* @type function +* @date 2/09/13 +* @since 4.3.0 * -* @param N/A -* @return (array) the current row data +* @param N/A +* @return (array) the current row data */ function the_row( $format = false ) { - + // vars - $i = acf_get_loop('active', 'i'); - - + $i = acf_get_loop( 'active', 'i' ); + // increase $i++; - - + // update - acf_update_loop('active', 'i', $i); - - + acf_update_loop( 'active', 'i', $i ); + // return return get_row( $format ); - + } function get_row( $format = false ) { - + // vars - $loop = acf_get_loop('active'); - - + $loop = acf_get_loop( 'active' ); + // bail early if no loop - if( !$loop ) return false; - - + if ( ! $loop ) { + return false; + } + // get value $value = acf_maybe_get( $loop['value'], $loop['i'] ); - - + // bail early if no current value // possible if get_row_layout() is called before the_row() - if( !$value ) return false; - - + if ( ! $value ) { + return false; + } + // format - if( $format ) { - + if ( $format ) { + // vars $field = $loop['field']; - - + // single row - if( acf_get_field_type_prop($field['type'], 'have_rows') === 'single' ) { - + if ( acf_get_field_type_prop( $field['type'], 'have_rows' ) === 'single' ) { + // format value $value = acf_format_value( $value, $loop['post_id'], $field ); - - // multiple rows + + // multiple rows } else { - + // format entire value // - solves problem where cached value is incomplete // - no performance issues here thanks to cache $value = acf_format_value( $loop['value'], $loop['post_id'], $field ); $value = acf_maybe_get( $value, $loop['i'] ); - + } - } - - + // return return $value; - + } function get_row_index() { - + // vars - $i = acf_get_loop('active', 'i'); - $offset = acf_get_setting('row_index_offset'); - - + $i = acf_get_loop( 'active', 'i' ); + $offset = acf_get_setting( 'row_index_offset' ); + // return return $offset + $i; - + } function the_row_index() { - + echo get_row_index(); - + } @@ -598,39 +590,38 @@ function the_row_index() { * * This function is used inside a 'has_sub_field' while loop to return a sub field object * -* @type function -* @date 16/05/2016 -* @since 5.3.8 +* @type function +* @date 16/05/2016 +* @since 5.3.8 * -* @param $selector (string) -* @return (array) +* @param $selector (string) +* @return (array) */ function get_row_sub_field( $selector ) { - + // vars - $row = acf_get_loop('active'); - - + $row = acf_get_loop( 'active' ); + // bail early if no row - if( !$row ) return false; - - + if ( ! $row ) { + return false; + } + // attempt to find sub field - $sub_field = acf_get_sub_field($selector, $row['field']); - - + $sub_field = acf_get_sub_field( $selector, $row['field'] ); + // bail early if no field - if( !$sub_field ) return false; - - + if ( ! $sub_field ) { + return false; + } + // update field's name based on row data $sub_field['name'] = "{$row['name']}_{$row['i']}_{$sub_field['name']}"; - - + // return return $sub_field; - + } @@ -639,35 +630,34 @@ function get_row_sub_field( $selector ) { * * This function is used inside a 'has_sub_field' while loop to return a sub field value * -* @type function -* @date 16/05/2016 -* @since 5.3.8 +* @type function +* @date 16/05/2016 +* @since 5.3.8 * -* @param $selector (string) -* @return (mixed) +* @param $selector (string) +* @return (mixed) */ function get_row_sub_value( $selector ) { - + // vars - $row = acf_get_loop('active'); - - + $row = acf_get_loop( 'active' ); + // bail early if no row - if( !$row ) return null; - - - // return value - if( isset($row['value'][ $row['i'] ][ $selector ]) ) { - - return $row['value'][ $row['i'] ][ $selector ]; - + if ( ! $row ) { + return null; } - - + + // return value + if ( isset( $row['value'][ $row['i'] ][ $selector ] ) ) { + + return $row['value'][ $row['i'] ][ $selector ]; + + } + // return return null; - + } @@ -677,23 +667,22 @@ function get_row_sub_value( $selector ) { * This function will find the current loop and unset it from the global array. * To bo used when loop finishes or a break is used * -* @type function -* @date 26/10/13 -* @since 5.0.0 +* @type function +* @date 26/10/13 +* @since 5.0.0 * -* @param $hard_reset (boolean) completely wipe the global variable, or just unset the active row -* @return (boolean) +* @param $hard_reset (boolean) completely wipe the global variable, or just unset the active row +* @return (boolean) */ function reset_rows() { - + // remove last loop - acf_remove_loop('active'); - - + acf_remove_loop( 'active' ); + // return return true; - + } @@ -701,41 +690,39 @@ function reset_rows() { * has_sub_field() * * This function is used inside a while loop to return either true or false (loop again or stop). -* When using a repeater or flexible content field, it will loop through the rows until +* When using a repeater or flexible content field, it will loop through the rows until * there are none left or a break is detected * -* @type function -* @since 1.0.3 -* @date 29/01/13 +* @type function +* @since 1.0.3 +* @date 29/01/13 * -* @param $field_name (string) the field name -* @param $post_id (mixed) the post_id of which the value is saved against -* @return (boolean) +* @param $field_name (string) the field name +* @param $post_id (mixed) the post_id of which the value is saved against +* @return (boolean) */ function has_sub_field( $field_name, $post_id = false ) { - + // vars $r = have_rows( $field_name, $post_id ); - - + // if has rows, progress through 1 row for the while loop to work - if( $r ) { - + if ( $r ) { + the_row(); - + } - - + // return return $r; - + } function has_sub_fields( $field_name, $post_id = false ) { - + return has_sub_field( $field_name, $post_id ); - + } @@ -744,27 +731,27 @@ function has_sub_fields( $field_name, $post_id = false ) { * * This function is used inside a 'has_sub_field' while loop to return a sub field value * -* @type function -* @since 1.0.3 -* @date 29/01/13 +* @type function +* @since 1.0.3 +* @date 29/01/13 * -* @param $field_name (string) the field name -* @return (mixed) +* @param $field_name (string) the field name +* @return (mixed) */ function get_sub_field( $selector = '', $format_value = true ) { - + // get sub field $sub_field = get_sub_field_object( $selector, $format_value ); - - + // bail early if no sub field - if( !$sub_field ) return false; - - - // return + if ( ! $sub_field ) { + return false; + } + + // return return $sub_field['value']; - + } @@ -773,24 +760,24 @@ function get_sub_field( $selector = '', $format_value = true ) { * * This function is the same as echo get_sub_field * -* @type function -* @since 1.0.3 -* @date 29/01/13 +* @type function +* @since 1.0.3 +* @date 29/01/13 * -* @param $field_name (string) the field name -* @return n/a +* @param $field_name (string) the field name +* @return n/a */ function the_sub_field( $field_name, $format_value = true ) { - + $value = get_sub_field( $field_name, $format_value ); - - if( is_array($value) ) { - - $value = implode(', ',$value); - + + if ( is_array( $value ) ) { + + $value = implode( ', ', $value ); + } - + echo $value; } @@ -800,52 +787,50 @@ function the_sub_field( $field_name, $format_value = true ) { * * This function is used inside a 'has_sub_field' while loop to return a sub field object * -* @type function -* @since 3.5.8.1 -* @date 29/01/13 +* @type function +* @since 3.5.8.1 +* @date 29/01/13 * -* @param $child_name (string) the field name -* @return (array) +* @param $child_name (string) the field name +* @return (array) */ function get_sub_field_object( $selector, $format_value = true, $load_value = true ) { - + // vars - $row = acf_get_loop('active'); - - + $row = acf_get_loop( 'active' ); + // bail early if no row - if( !$row ) return false; - - - // attempt to find sub field - $sub_field = get_row_sub_field($selector); - - - // bail early if no sub field - if( !$sub_field ) return false; - - - // load value - if( $load_value ) { - - $sub_field['value'] = get_row_sub_value( $sub_field['key'] ); - + if ( ! $row ) { + return false; } - - + + // attempt to find sub field + $sub_field = get_row_sub_field( $selector ); + + // bail early if no sub field + if ( ! $sub_field ) { + return false; + } + + // load value + if ( $load_value ) { + + $sub_field['value'] = get_row_sub_value( $sub_field['key'] ); + + } + // format value - if( $format_value ) { - + if ( $format_value ) { + // get value for field $sub_field['value'] = acf_format_value( $sub_field['value'], $row['post_id'], $sub_field ); - + } - - + // return return $sub_field; - + } @@ -854,31 +839,29 @@ function get_sub_field_object( $selector, $format_value = true, $load_value = tr * * This function will return a string representation of the current row layout within a 'have_rows' loop * -* @type function -* @since 3.0.6 -* @date 29/01/13 +* @type function +* @since 3.0.6 +* @date 29/01/13 * -* @param n/a -* @return (string) +* @param n/a +* @return (string) */ function get_row_layout() { - + // vars $row = get_row(); - - + // return - if( isset($row['acf_fc_layout']) ) { - + if ( isset( $row['acf_fc_layout'] ) ) { + return $row['acf_fc_layout']; - + } - - + // return return false; - + } @@ -888,44 +871,50 @@ function get_row_layout() { * This function is used to add basic shortcode support for the ACF plugin * eg. [acf field="heading" post_id="123" format_value="1"] * -* @type function -* @since 1.1.1 -* @date 29/01/13 +* @type function +* @since 1.1.1 +* @date 29/01/13 * -* @param $field (string) the field name or key -* @param $post_id (mixed) the post_id of which the value is saved against -* @param $format_value (boolean) whether or not to format the field value -* @return (string) +* @param $field (string) the field name or key +* @param $post_id (mixed) the post_id of which the value is saved against +* @param $format_value (boolean) whether or not to format the field value +* @return (string) */ function acf_shortcode( $atts ) { - + // Mitigate issue where some AJAX requests can return ACF field data. + if ( wp_doing_ajax() && ! current_user_can( 'edit_posts' ) ) { + return; + } + // extract attributs - extract( shortcode_atts( array( - 'field' => '', - 'post_id' => false, - 'format_value' => true - ), $atts ) ); - - + extract( + shortcode_atts( + array( + 'field' => '', + 'post_id' => false, + 'format_value' => true, + ), + $atts + ) + ); + // get value and return it $value = get_field( $field, $post_id, $format_value ); - - + // array - if( is_array($value) ) { - + if ( is_array( $value ) ) { + $value = @implode( ', ', $value ); - + } - - + // return return $value; - + } -add_shortcode('acf', 'acf_shortcode'); +add_shortcode( 'acf', 'acf_shortcode' ); /* @@ -933,41 +922,40 @@ add_shortcode('acf', 'acf_shortcode'); * * This function will update a value in the database * -* @type function -* @since 3.1.9 -* @date 29/01/13 +* @type function +* @since 3.1.9 +* @date 29/01/13 * -* @param $selector (string) the field name or key -* @param $value (mixed) the value to save in the database -* @param $post_id (mixed) the post_id of which the value is saved against -* @return (boolean) +* @param $selector (string) the field name or key +* @param $value (mixed) the value to save in the database +* @param $post_id (mixed) the post_id of which the value is saved against +* @return (boolean) */ function update_field( $selector, $value, $post_id = false ) { - + // filter post_id $post_id = acf_get_valid_post_id( $post_id ); - - + // get field $field = acf_maybe_get_field( $selector, $post_id, false ); - - + // create dummy field - if( !$field ) { - - $field = acf_get_valid_field(array( - 'name' => $selector, - 'key' => '', - 'type' => '', - )); - + if ( ! $field ) { + + $field = acf_get_valid_field( + array( + 'name' => $selector, + 'key' => '', + 'type' => '', + ) + ); + } - - + // save return acf_update_value( $value, $post_id, $field ); - + } @@ -976,43 +964,42 @@ function update_field( $selector, $value, $post_id = false ) { * * This function will update a value of a sub field in the database * -* @type function -* @date 2/04/2014 -* @since 5.0.0 +* @type function +* @date 2/04/2014 +* @since 5.0.0 * -* @param $selector (mixed) the sub field name or key, or an array of ancestors -* @param $value (mixed) the value to save in the database -* @param $post_id (mixed) the post_id of which the value is saved against -* @return (boolean) +* @param $selector (mixed) the sub field name or key, or an array of ancestors +* @param $value (mixed) the value to save in the database +* @param $post_id (mixed) the post_id of which the value is saved against +* @return (boolean) */ function update_sub_field( $selector, $value, $post_id = false ) { - + // vars $sub_field = false; - - - // get sub field - if( is_array($selector) ) { - - $post_id = acf_get_valid_post_id( $post_id ); - $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false ); - - } else { - - $post_id = acf_get_loop('active', 'post_id'); - $sub_field = get_row_sub_field( $selector ); - - } - - - // bail early if no sub field - if( !$sub_field ) return false; + // get sub field + if ( is_array( $selector ) ) { + + $post_id = acf_get_valid_post_id( $post_id ); + $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false ); + + } else { + + $post_id = acf_get_loop( 'active', 'post_id' ); + $sub_field = get_row_sub_field( $selector ); + + } + + // bail early if no sub field + if ( ! $sub_field ) { + return false; + } // update return acf_update_value( $value, $post_id, $sub_field ); - + } @@ -1021,28 +1008,26 @@ function update_sub_field( $selector, $value, $post_id = false ) { * * This function will remove a value from the database * -* @type function -* @since 3.1.9 -* @date 29/01/13 +* @type function +* @since 3.1.9 +* @date 29/01/13 * -* @param $selector (string) the field name or key -* @param $post_id (mixed) the post_id of which the value is saved against -* @return (boolean) +* @param $selector (string) the field name or key +* @param $post_id (mixed) the post_id of which the value is saved against +* @return (boolean) */ function delete_field( $selector, $post_id = false ) { - + // filter post_id $post_id = acf_get_valid_post_id( $post_id ); - - + // get field $field = acf_maybe_get_field( $selector, $post_id ); - - + // delete return $field ? acf_delete_value( $post_id, $field ) : false; - + } @@ -1051,20 +1036,20 @@ function delete_field( $selector, $post_id = false ) { * * This function will delete a value of a sub field in the database * -* @type function -* @date 2/04/2014 -* @since 5.0.0 +* @type function +* @date 2/04/2014 +* @since 5.0.0 * -* @param $selector (mixed) the sub field name or key, or an array of ancestors -* @param $value (mixed) the value to save in the database -* @param $post_id (mixed) the post_id of which the value is saved against -* @return (boolean) +* @param $selector (mixed) the sub field name or key, or an array of ancestors +* @param $value (mixed) the value to save in the database +* @param $post_id (mixed) the post_id of which the value is saved against +* @return (boolean) */ function delete_sub_field( $selector, $post_id = false ) { - + return update_sub_field( $selector, null, $post_id ); - + } @@ -1073,49 +1058,44 @@ function delete_sub_field( $selector, $post_id = false ) { * * This function will add a row of data to a field * -* @type function -* @date 16/10/2015 -* @since 5.2.3 +* @type function +* @date 16/10/2015 +* @since 5.2.3 * -* @param $selector (string) -* @param $row (array) -* @param $post_id (mixed) -* @return (boolean) +* @param $selector (string) +* @param $row (array) +* @param $post_id (mixed) +* @return (boolean) */ function add_row( $selector, $row = false, $post_id = false ) { - + // filter post_id $post_id = acf_get_valid_post_id( $post_id ); - - + // get field $field = acf_maybe_get_field( $selector, $post_id, false ); - - + // bail early if no field - if( !$field ) return false; - - + if ( ! $field ) { + return false; + } + // get raw value $value = acf_get_value( $post_id, $field ); - - + // ensure array - $value = acf_get_array($value); - - + $value = acf_get_array( $value ); + // append $value[] = $row; - - + // update value acf_update_value( $value, $post_id, $field ); - - + // return - return count($value); - + return count( $value ); + } @@ -1124,59 +1104,54 @@ function add_row( $selector, $row = false, $post_id = false ) { * * This function will add a row of data to a field * -* @type function -* @date 16/10/2015 -* @since 5.2.3 +* @type function +* @date 16/10/2015 +* @since 5.2.3 * -* @param $selector (string) -* @param $row (array) -* @param $post_id (mixed) -* @return (boolean) +* @param $selector (string) +* @param $row (array) +* @param $post_id (mixed) +* @return (boolean) */ function add_sub_row( $selector, $row = false, $post_id = false ) { - + // vars $sub_field = false; - - + // get sub field - if( is_array($selector) ) { - - $post_id = acf_get_valid_post_id( $post_id ); + if ( is_array( $selector ) ) { + + $post_id = acf_get_valid_post_id( $post_id ); $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false ); - + } else { - - $post_id = acf_get_loop('active', 'post_id'); + + $post_id = acf_get_loop( 'active', 'post_id' ); $sub_field = get_row_sub_field( $selector ); - + } - - + // bail early if no sub field - if( !$sub_field ) return false; - - + if ( ! $sub_field ) { + return false; + } + // get raw value $value = acf_get_value( $post_id, $sub_field ); - - + // ensure array $value = acf_get_array( $value ); - - + // append $value[] = $row; - // update acf_update_value( $value, $post_id, $sub_field ); - - + // return - return count($value); - + return count( $value ); + } @@ -1185,55 +1160,49 @@ function add_sub_row( $selector, $row = false, $post_id = false ) { * * This function will update a row of data to a field * -* @type function -* @date 19/10/2015 -* @since 5.2.3 +* @type function +* @date 19/10/2015 +* @since 5.2.3 * -* @param $selector (string) -* @param $i (int) -* @param $row (array) -* @param $post_id (mixed) -* @return (boolean) +* @param $selector (string) +* @param $i (int) +* @param $row (array) +* @param $post_id (mixed) +* @return (boolean) */ function update_row( $selector, $i = 1, $row = false, $post_id = false ) { - + // vars - $offset = acf_get_setting('row_index_offset'); - $i = $i - $offset; - - + $offset = acf_get_setting( 'row_index_offset' ); + $i = $i - $offset; + // filter post_id $post_id = acf_get_valid_post_id( $post_id ); - - + // get field $field = acf_maybe_get_field( $selector, $post_id, false ); - - + // bail early if no field - if( !$field ) return false; - - + if ( ! $field ) { + return false; + } + // get raw value $value = acf_get_value( $post_id, $field ); - - + // ensure array - $value = acf_get_array($value); - - + $value = acf_get_array( $value ); + // update $value[ $i ] = $row; - - + // update value acf_update_value( $value, $post_id, $field ); - - + // return return true; - + } @@ -1242,61 +1211,56 @@ function update_row( $selector, $i = 1, $row = false, $post_id = false ) { * * This function will add a row of data to a field * -* @type function -* @date 16/10/2015 -* @since 5.2.3 +* @type function +* @date 16/10/2015 +* @since 5.2.3 * -* @param $selector (string) -* @param $row (array) -* @param $post_id (mixed) -* @return (boolean) +* @param $selector (string) +* @param $row (array) +* @param $post_id (mixed) +* @return (boolean) */ function update_sub_row( $selector, $i = 1, $row = false, $post_id = false ) { - + // vars $sub_field = false; - $offset = acf_get_setting('row_index_offset'); - $i = $i - $offset; - - + $offset = acf_get_setting( 'row_index_offset' ); + $i = $i - $offset; + // get sub field - if( is_array($selector) ) { - - $post_id = acf_get_valid_post_id( $post_id ); + if ( is_array( $selector ) ) { + + $post_id = acf_get_valid_post_id( $post_id ); $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false ); - + } else { - - $post_id = acf_get_loop('active', 'post_id'); + + $post_id = acf_get_loop( 'active', 'post_id' ); $sub_field = get_row_sub_field( $selector ); - + } - - + // bail early if no sub field - if( !$sub_field ) return false; - - + if ( ! $sub_field ) { + return false; + } + // get raw value $value = acf_get_value( $post_id, $sub_field ); - - + // ensure array $value = acf_get_array( $value ); - - + // append $value[ $i ] = $row; - // update acf_update_value( $value, $post_id, $sub_field ); - - + // return return true; - + } @@ -1305,58 +1269,53 @@ function update_sub_row( $selector, $i = 1, $row = false, $post_id = false ) { * * This function will delete a row of data from a field * -* @type function -* @date 19/10/2015 -* @since 5.2.3 +* @type function +* @date 19/10/2015 +* @since 5.2.3 * -* @param $selector (string) -* @param $i (int) -* @param $post_id (mixed) -* @return (boolean) +* @param $selector (string) +* @param $i (int) +* @param $post_id (mixed) +* @return (boolean) */ function delete_row( $selector, $i = 1, $post_id = false ) { - + // vars - $offset = acf_get_setting('row_index_offset'); - $i = $i - $offset; - - + $offset = acf_get_setting( 'row_index_offset' ); + $i = $i - $offset; + // filter post_id $post_id = acf_get_valid_post_id( $post_id ); - - + // get field $field = acf_maybe_get_field( $selector, $post_id ); - - + // bail early if no field - if( !$field ) return false; - - + if ( ! $field ) { + return false; + } + // get value $value = acf_get_value( $post_id, $field ); - - + // ensure array - $value = acf_get_array($value); - - + $value = acf_get_array( $value ); + // bail early if index doesn't exist - if( !isset($value[ $i ]) ) return false; - - + if ( ! isset( $value[ $i ] ) ) { + return false; + } + // unset unset( $value[ $i ] ); - - + // update acf_update_value( $value, $post_id, $field ); - - + // return return true; - + } @@ -1365,65 +1324,61 @@ function delete_row( $selector, $i = 1, $post_id = false ) { * * This function will add a row of data to a field * -* @type function -* @date 16/10/2015 -* @since 5.2.3 +* @type function +* @date 16/10/2015 +* @since 5.2.3 * -* @param $selector (string) -* @param $row (array) -* @param $post_id (mixed) -* @return (boolean) +* @param $selector (string) +* @param $row (array) +* @param $post_id (mixed) +* @return (boolean) */ function delete_sub_row( $selector, $i = 1, $post_id = false ) { - + // vars $sub_field = false; - $offset = acf_get_setting('row_index_offset'); - $i = $i - $offset; - - + $offset = acf_get_setting( 'row_index_offset' ); + $i = $i - $offset; + // get sub field - if( is_array($selector) ) { - - $post_id = acf_get_valid_post_id( $post_id ); + if ( is_array( $selector ) ) { + + $post_id = acf_get_valid_post_id( $post_id ); $sub_field = acf_maybe_get_sub_field( $selector, $post_id, false ); - + } else { - - $post_id = acf_get_loop('active', 'post_id'); + + $post_id = acf_get_loop( 'active', 'post_id' ); $sub_field = get_row_sub_field( $selector ); - + } - - + // bail early if no sub field - if( !$sub_field ) return false; - - + if ( ! $sub_field ) { + return false; + } + // get raw value $value = acf_get_value( $post_id, $sub_field ); - - + // ensure array $value = acf_get_array( $value ); - - + // bail early if index doesn't exist - if( !isset($value[ $i ]) ) return false; - - + if ( ! isset( $value[ $i ] ) ) { + return false; + } + // append unset( $value[ $i ] ); - // update acf_update_value( $value, $post_id, $sub_field ); - - + // return return true; - + } @@ -1432,48 +1387,48 @@ function delete_sub_row( $selector, $i = 1, $post_id = false ) { * * These functions are outdated * -* @type function -* @date 4/03/2014 -* @since 1.0.0 +* @type function +* @date 4/03/2014 +* @since 1.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function create_field( $field ) { acf_render_field( $field ); - + } function render_field( $field ) { acf_render_field( $field ); - + } function reset_the_repeater_field() { - + return reset_rows(); - + } function the_repeater_field( $field_name, $post_id = false ) { - + return has_sub_field( $field_name, $post_id ); - + } function the_flexible_field( $field_name, $post_id = false ) { - + return has_sub_field( $field_name, $post_id ); - + } function acf_filter_post_id( $post_id ) { - + return acf_get_valid_post_id( $post_id ); - + } -?> + diff --git a/includes/api/api-term.php b/includes/api/api-term.php index 6376b44..5cde29e 100644 --- a/includes/api/api-term.php +++ b/includes/api/api-term.php @@ -5,71 +5,73 @@ * * Returns an array of taxonomy names. * -* @date 7/10/13 -* @since 5.0.0 +* @date 7/10/13 +* @since 5.0.0 * -* @param array $args An array of args used in the get_taxonomies() function. -* @return array An array of taxonomy names. +* @param array $args An array of args used in the get_taxonomies() function. +* @return array An array of taxonomy names. */ function acf_get_taxonomies( $args = array() ) { // vars $taxonomies = array(); - + // get taxonomy objects $objects = get_taxonomies( $args, 'objects' ); - + // loop - foreach( $objects as $i => $object ) { - + foreach ( $objects as $i => $object ) { + // bail early if is builtin (WP) private post type // - nav_menu_item, revision, customize_changeset, etc - if( $object->_builtin && !$object->public ) continue; - + if ( $object->_builtin && ! $object->public ) { + continue; + } + // append $taxonomies[] = $i; } - + // custom post_type arg which does not yet exist in core - if( isset($args['post_type']) ) { - $taxonomies = acf_get_taxonomies_for_post_type($args['post_type']); + if ( isset( $args['post_type'] ) ) { + $taxonomies = acf_get_taxonomies_for_post_type( $args['post_type'] ); } - + // filter - $taxonomies = apply_filters('acf/get_taxonomies', $taxonomies, $args); - + $taxonomies = apply_filters( 'acf/get_taxonomies', $taxonomies, $args ); + // return return $taxonomies; } /** -* acf_get_taxonomies_for_post_type -* -* Returns an array of taxonomies for a given post type(s) -* -* @date 7/9/18 -* @since 5.7.5 -* -* @param string|array $post_types The post types to compare against. -* @return array -*/ + * acf_get_taxonomies_for_post_type + * + * Returns an array of taxonomies for a given post type(s) + * + * @date 7/9/18 + * @since 5.7.5 + * + * @param string|array $post_types The post types to compare against. + * @return array + */ function acf_get_taxonomies_for_post_type( $post_types = 'post' ) { - + // vars $taxonomies = array(); - + // loop - foreach( (array) $post_types as $post_type ) { + foreach ( (array) $post_types as $post_type ) { $object_taxonomies = get_object_taxonomies( $post_type ); - foreach( (array) $object_taxonomies as $taxonomy ) { - $taxonomies[] = $taxonomy; + foreach ( (array) $object_taxonomies as $taxonomy ) { + $taxonomies[] = $taxonomy; } } - + // remove duplicates - $taxonomies = array_unique($taxonomies); - + $taxonomies = array_unique( $taxonomies ); + // return return $taxonomies; } @@ -79,414 +81,426 @@ function acf_get_taxonomies_for_post_type( $post_types = 'post' ) { * * Returns an array of taxonomies in the format "name => label" for use in a select field. * -* @date 3/8/18 -* @since 5.7.2 +* @date 3/8/18 +* @since 5.7.2 * -* @param array $taxonomies Optional. An array of specific taxonomies to return. -* @return array +* @param array $taxonomies Optional. An array of specific taxonomies to return. +* @return array */ function acf_get_taxonomy_labels( $taxonomies = array() ) { - + // default - if( empty($taxonomies) ) { + if ( empty( $taxonomies ) ) { $taxonomies = acf_get_taxonomies(); } - + // vars - $ref = array(); + $ref = array(); $data = array(); - + // loop - foreach( $taxonomies as $taxonomy ) { - + foreach ( $taxonomies as $taxonomy ) { + // vars $object = get_taxonomy( $taxonomy ); - $label = $object->labels->singular_name; - + $label = $object->labels->singular_name; + // append $data[ $taxonomy ] = $label; - + // increase counter - if( !isset($ref[ $label ]) ) { + if ( ! isset( $ref[ $label ] ) ) { $ref[ $label ] = 0; } $ref[ $label ]++; } - + // show taxonomy name next to label for shared labels - foreach( $data as $taxonomy => $label ) { - if( $ref[$label] > 1 ) { + foreach ( $data as $taxonomy => $label ) { + if ( $ref[ $label ] > 1 ) { $data[ $taxonomy ] .= ' (' . $taxonomy . ')'; } } - + // return return $data; } /** -* acf_get_term_title -* -* Returns the title for this term object. -* -* @date 10/9/18 -* @since 5.0.0 -* -* @param object $term The WP_Term object. -* @return string -*/ + * acf_get_term_title + * + * Returns the title for this term object. + * + * @date 10/9/18 + * @since 5.0.0 + * + * @param object $term The WP_Term object. + * @return string + */ function acf_get_term_title( $term ) { $title = $term->name; - + // Allow for empty name. - if( $title === '' ) { - $title = __('(no title)', 'acf'); + if ( $title === '' ) { + $title = __( '(no title)', 'acf' ); } - + // Prepend ancestors indentation. - if( is_taxonomy_hierarchical($term->taxonomy) ) { + if ( is_taxonomy_hierarchical( $term->taxonomy ) ) { $ancestors = get_ancestors( $term->term_id, $term->taxonomy ); - $title = str_repeat('- ', count($ancestors)) . $title; + $title = str_repeat( '- ', count( $ancestors ) ) . $title; } - + return $title; } /** -* acf_get_grouped_terms -* -* Returns an array of terms for the given query $args and groups by taxonomy name. -* -* @date 2/8/18 -* @since 5.7.2 -* -* @param array $args An array of args used in the get_terms() function. -* @return array -*/ + * acf_get_grouped_terms + * + * Returns an array of terms for the given query $args and groups by taxonomy name. + * + * @date 2/8/18 + * @since 5.7.2 + * + * @param array $args An array of args used in the get_terms() function. + * @return array + */ function acf_get_grouped_terms( $args ) { - + // vars $data = array(); - + // defaults - $args = wp_parse_args($args, array( - 'taxonomy' => null, - 'hide_empty' => false, - 'update_term_meta_cache' => false, - )); - + $args = wp_parse_args( + $args, + array( + 'taxonomy' => null, + 'hide_empty' => false, + 'update_term_meta_cache' => false, + ) + ); + // vars - $taxonomies = acf_get_taxonomy_labels( acf_get_array($args['taxonomy']) ); - $is_single = (count($taxonomies) == 1); - + $taxonomies = acf_get_taxonomy_labels( acf_get_array( $args['taxonomy'] ) ); + $is_single = ( count( $taxonomies ) == 1 ); + // specify exact taxonomies required for _acf_terms_clauses() to work. - $args['taxonomy'] = array_keys($taxonomies); - + $args['taxonomy'] = array_keys( $taxonomies ); + // add filter to group results by taxonomy - if( !$is_single ) { - add_filter('terms_clauses', '_acf_terms_clauses', 10, 3); + if ( ! $is_single ) { + add_filter( 'terms_clauses', '_acf_terms_clauses', 10, 3 ); } - + // get terms $terms = get_terms( $args ); - + // remove this filter (only once) - if( !$is_single ) { - remove_filter('terms_clauses', '_acf_terms_clauses', 10, 3); + if ( ! $is_single ) { + remove_filter( 'terms_clauses', '_acf_terms_clauses', 10, 3 ); } - + // loop - foreach( $taxonomies as $taxonomy => $label ) { - + foreach ( $taxonomies as $taxonomy => $label ) { + // vars $this_terms = array(); - + // populate $this_terms - foreach( $terms as $term ) { - if( $term->taxonomy == $taxonomy ) { + foreach ( $terms as $term ) { + if ( $term->taxonomy == $taxonomy ) { $this_terms[] = $term; } } - + // bail early if no $items - if( empty($this_terms) ) continue; - + if ( empty( $this_terms ) ) { + continue; + } + // sort into hierachial order // this will fail if a search has taken place because parents wont exist - if( is_taxonomy_hierarchical($taxonomy) && empty($args['s'])) { - + if ( is_taxonomy_hierarchical( $taxonomy ) && empty( $args['s'] ) ) { + // get all terms from this taxonomy - $all_terms = get_terms(array_merge($args, array( - 'number' => 0, - 'offset' => 0, - 'taxonomy' => $taxonomy - ))); - + $all_terms = get_terms( + array_merge( + $args, + array( + 'number' => 0, + 'offset' => 0, + 'taxonomy' => $taxonomy, + ) + ) + ); + // vars - $length = count($this_terms); + $length = count( $this_terms ); $offset = 0; - + // find starting point (offset) - foreach( $all_terms as $i => $term ) { - if( $term->term_id == $this_terms[0]->term_id ) { + foreach ( $all_terms as $i => $term ) { + if ( $term->term_id == $this_terms[0]->term_id ) { $offset = $i; break; } } - + // order terms - $parent = acf_maybe_get( $args, 'parent', 0 ); - $parent = acf_maybe_get( $args, 'child_of', $parent ); + $parent = acf_maybe_get( $args, 'parent', 0 ); + $parent = acf_maybe_get( $args, 'child_of', $parent ); $ordered_terms = _get_term_children( $parent, $all_terms, $taxonomy ); - + // compare aray lengths // if $ordered_posts is smaller than $all_posts, WP has lost posts during the get_page_children() function // this is possible when get_post( $args ) filter out parents (via taxonomy, meta and other search parameters) - if( count($ordered_terms) == count($all_terms) ) { - $this_terms = array_slice($ordered_terms, $offset, $length); + if ( count( $ordered_terms ) == count( $all_terms ) ) { + $this_terms = array_slice( $ordered_terms, $offset, $length ); } } - + // populate group $data[ $label ] = array(); - foreach( $this_terms as $term ) { + foreach ( $this_terms as $term ) { $data[ $label ][ $term->term_id ] = $term; - } + } } - + // return return $data; } /** -* _acf_terms_clauses -* -* Used in the 'terms_clauses' filter to order terms by taxonomy name. -* -* @date 2/8/18 -* @since 5.7.2 -* -* @param array $pieces Terms query SQL clauses. -* @param array $taxonomies An array of taxonomies. -* @param array $args An array of terms query arguments. -* @return array $pieces -*/ + * _acf_terms_clauses + * + * Used in the 'terms_clauses' filter to order terms by taxonomy name. + * + * @date 2/8/18 + * @since 5.7.2 + * + * @param array $pieces Terms query SQL clauses. + * @param array $taxonomies An array of taxonomies. + * @param array $args An array of terms query arguments. + * @return array $pieces + */ function _acf_terms_clauses( $pieces, $taxonomies, $args ) { - + // prepend taxonomy to 'orderby' SQL - if( is_array($taxonomies) ) { - $sql = "FIELD(tt.taxonomy,'" . implode("', '", array_map('esc_sql', $taxonomies)) . "')"; - $pieces['orderby'] = str_replace("ORDER BY", "ORDER BY $sql,", $pieces['orderby']); + if ( is_array( $taxonomies ) ) { + $sql = "FIELD(tt.taxonomy,'" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "')"; + $pieces['orderby'] = str_replace( 'ORDER BY', "ORDER BY $sql,", $pieces['orderby'] ); } - - // return + + // return return $pieces; } /** -* acf_get_pretty_taxonomies -* -* Deprecated in favor of acf_get_taxonomy_labels() function. -* -* @date 7/10/13 -* @since 5.0.0 -* @deprecated 5.7.2 -*/ + * acf_get_pretty_taxonomies + * + * Deprecated in favor of acf_get_taxonomy_labels() function. + * + * @date 7/10/13 + * @since 5.0.0 + * @deprecated 5.7.2 + */ function acf_get_pretty_taxonomies( $taxonomies = array() ) { return acf_get_taxonomy_labels( $taxonomies ); } /** -* acf_get_term -* -* Similar to get_term() but with some extra functionality. -* -* @date 19/8/18 -* @since 5.7.3 -* -* @param mixed $term_id The term ID or a string of "taxonomy:slug". -* @param string $taxonomy The taxonomyname. -* @return WP_Term -*/ + * acf_get_term + * + * Similar to get_term() but with some extra functionality. + * + * @date 19/8/18 + * @since 5.7.3 + * + * @param mixed $term_id The term ID or a string of "taxonomy:slug". + * @param string $taxonomy The taxonomyname. + * @return WP_Term + */ function acf_get_term( $term_id, $taxonomy = '' ) { - + // allow $term_id parameter to be a string of "taxonomy:slug" or "taxonomy:id" - if( is_string($term_id) && strpos($term_id, ':') ) { - list( $taxonomy, $term_id ) = explode(':', $term_id); - $term = get_term_by( 'slug', $term_id, $taxonomy ); - if( $term ) return $term; + if ( is_string( $term_id ) && strpos( $term_id, ':' ) ) { + list( $taxonomy, $term_id ) = explode( ':', $term_id ); + $term = get_term_by( 'slug', $term_id, $taxonomy ); + if ( $term ) { + return $term; + } } - + // return return get_term( $term_id, $taxonomy ); } /** -* acf_encode_term -* -* Returns a "taxonomy:slug" string for a given WP_Term. -* -* @date 27/8/18 -* @since 5.7.4 -* -* @param WP_Term $term The term object. -* @return string -*/ + * acf_encode_term + * + * Returns a "taxonomy:slug" string for a given WP_Term. + * + * @date 27/8/18 + * @since 5.7.4 + * + * @param WP_Term $term The term object. + * @return string + */ function acf_encode_term( $term ) { return "{$term->taxonomy}:{$term->slug}"; } /** -* acf_decode_term -* -* Decodes a "taxonomy:slug" string into an array of taxonomy and slug. -* -* @date 27/8/18 -* @since 5.7.4 -* -* @param WP_Term $term The term object. -* @return string -*/ + * acf_decode_term + * + * Decodes a "taxonomy:slug" string into an array of taxonomy and slug. + * + * @date 27/8/18 + * @since 5.7.4 + * + * @param WP_Term $term The term object. + * @return string + */ function acf_decode_term( $string ) { - if( is_string($string) && strpos($string, ':') ) { - list( $taxonomy, $slug ) = explode(':', $string); + if ( is_string( $string ) && strpos( $string, ':' ) ) { + list( $taxonomy, $slug ) = explode( ':', $string ); return compact( 'taxonomy', 'slug' ); } return false; } /** -* acf_get_encoded_terms -* -* Returns an array of WP_Term objects from an array of encoded strings -* -* @date 9/9/18 -* @since 5.7.5 -* -* @param array $values The array of encoded strings. -* @return array -*/ + * acf_get_encoded_terms + * + * Returns an array of WP_Term objects from an array of encoded strings + * + * @date 9/9/18 + * @since 5.7.5 + * + * @param array $values The array of encoded strings. + * @return array + */ function acf_get_encoded_terms( $values ) { - + // vars $terms = array(); - + // loop over values - foreach( (array) $values as $value ) { - + foreach ( (array) $values as $value ) { + // find term from string $term = acf_get_term( $value ); - + // append - if( $term instanceof WP_Term ) { + if ( $term instanceof WP_Term ) { $terms[] = $term; } } - + // return return $terms; } /** -* acf_get_choices_from_terms -* -* Returns an array of choices from the terms provided. -* -* @date 8/9/18 -* @since 5.7.5 -* -* @param array $values and array of WP_Terms objects or encoded strings. -* @param string $format The value format (term_id, slug). -* @return array -*/ + * acf_get_choices_from_terms + * + * Returns an array of choices from the terms provided. + * + * @date 8/9/18 + * @since 5.7.5 + * + * @param array $values and array of WP_Terms objects or encoded strings. + * @param string $format The value format (term_id, slug). + * @return array + */ function acf_get_choices_from_terms( $terms, $format = 'term_id' ) { - + // vars $groups = array(); - + // get taxonomy lables $labels = acf_get_taxonomy_labels(); - + // convert array of encoded strings to terms - $term = reset($terms); - if( !$term instanceof WP_Term ) { + $term = reset( $terms ); + if ( ! $term instanceof WP_Term ) { $terms = acf_get_encoded_terms( $terms ); } - + // loop over terms - foreach( $terms as $term ) { - $group = $labels[ $term->taxonomy ]; - $choice = acf_get_choice_from_term( $term, $format ); + foreach ( $terms as $term ) { + $group = $labels[ $term->taxonomy ]; + $choice = acf_get_choice_from_term( $term, $format ); $groups[ $group ][ $choice['id'] ] = $choice['text']; } - + // return return $groups; } /** -* acf_get_choices_from_grouped_terms -* -* Returns an array of choices from the grouped terms provided. -* -* @date 8/9/18 -* @since 5.7.5 -* -* @param array $value A grouped array of WP_Terms objects. -* @param string $format The value format (term_id, slug). -* @return array -*/ + * acf_get_choices_from_grouped_terms + * + * Returns an array of choices from the grouped terms provided. + * + * @date 8/9/18 + * @since 5.7.5 + * + * @param array $value A grouped array of WP_Terms objects. + * @param string $format The value format (term_id, slug). + * @return array + */ function acf_get_choices_from_grouped_terms( $value, $format = 'term_id' ) { - + // vars $groups = array(); - + // loop over values - foreach( $value as $group => $terms ) { + foreach ( $value as $group => $terms ) { $groups[ $group ] = array(); - foreach( $terms as $term_id => $term ) { - $choice = acf_get_choice_from_term( $term, $format ); + foreach ( $terms as $term_id => $term ) { + $choice = acf_get_choice_from_term( $term, $format ); $groups[ $group ][ $choice['id'] ] = $choice['text']; } } - + // return return $groups; } /** -* acf_get_choice_from_term -* -* Returns an array containing the id and text for this item. -* -* @date 10/9/18 -* @since 5.7.6 -* -* @param object $item The item object such as WP_Post or WP_Term. -* @param string $format The value format (term_id, slug) -* @return array -*/ + * acf_get_choice_from_term + * + * Returns an array containing the id and text for this item. + * + * @date 10/9/18 + * @since 5.7.6 + * + * @param object $item The item object such as WP_Post or WP_Term. + * @param string $format The value format (term_id, slug) + * @return array + */ function acf_get_choice_from_term( $term, $format = 'term_id' ) { - + // vars - $id = $term->term_id; + $id = $term->term_id; $text = acf_get_term_title( $term ); - + // return format - if( $format == 'slug' ) { - $id = acf_encode_term($term); + if ( $format == 'slug' ) { + $id = acf_encode_term( $term ); } - + // return return array( - 'id' => $id, - 'text' => $text + 'id' => $id, + 'text' => $text, ); } @@ -494,15 +508,15 @@ function acf_get_choice_from_term( $term, $format = 'term_id' ) { * Returns a valid post_id string for a given term and taxonomy. * No longer needed since WP introduced the termmeta table in WP 4.4. * - * @date 6/2/17 - * @since 5.5.6 + * @date 6/2/17 + * @since 5.5.6 * @deprecated 5.9.2 * - * @param $taxonomy (string) The taxonomy type. - * @param $term_id (int) The term ID. - * @return (string) + * @param $taxonomy (string) The taxonomy type. + * @param $term_id (int) The term ID. + * @return (string) */ function acf_get_term_post_id( $taxonomy, $term_id ) { _deprecated_function( __FUNCTION__, '5.9.2', 'string format term_%d' ); return 'term_' . $term_id; -} \ No newline at end of file +} diff --git a/includes/assets.php b/includes/assets.php index 3e28d59..a1199d1 100644 --- a/includes/assets.php +++ b/includes/assets.php @@ -1,603 +1,614 @@ - $v ) { - $this->text[ $k ] = $v; - } - } - - /** - * Appends an array of l10n data. - * - * @date 13/4/18 - * @since 5.6.9 - * - * @param array $data An array of data for l10n. - * @return void - */ - public function add_data( $data ) { - foreach( (array) $data as $k => $v ) { - $this->data[ $k ] = $v; - } - } - - /** - * Registers the ACF scripts and styles. - * - * @date 10/4/18 - * @since 5.6.9 - * - * @param void - * @return void - */ - public function register_scripts() { - // Extract vars. - $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - $version = acf_get_setting('version'); - - // Register scripts. - wp_register_script( 'acf', acf_get_url( 'assets/build/js/acf' . $suffix . '.js' ), array( 'jquery' ), $version ); - wp_register_script( 'acf-input', acf_get_url( 'assets/build/js/acf-input' . $suffix . '.js' ), array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-resizable', 'acf' ), $version ); - wp_register_script( 'acf-field-group', acf_get_url( 'assets/build/js/acf-field-group' . $suffix . '.js' ), array( 'acf-input' ), $version ); - - // Register styles. - wp_register_style( 'acf-global', acf_get_url( 'assets/build/css/acf-global.css' ), array( 'dashicons' ), $version ); - wp_register_style( 'acf-input', acf_get_url( 'assets/build/css/acf-input.css' ), array( 'acf-global' ), $version ); - wp_register_style( 'acf-field-group', acf_get_url( 'assets/build/css/acf-field-group.css' ), array( 'acf-input' ), $version ); - /** - * Fires after core scripts and styles have been registered. + * Storage for i18n data. * - * @since 5.6.9 - * - * @param string $version The ACF version. - * @param string $suffix The potential ".min" filename suffix. + * @since 5.6.9 + * @var array */ - do_action( 'acf/register_scripts', $version, $suffix ); - } + public $text = array(); - /** - * Enqueues a script and sets up actions for priting supplemental scripts. - * - * @date 27/4/20 - * @since 5.9.0 - * - * @param string $name The script name. - * @return void - */ - public function enqueue_script( $name ) { - wp_enqueue_script( $name ); - $this->add_actions(); - } + /** + * Storage for l10n data. + * + * @since 5.6.9 + * @var array + */ + public $data = array(); - /** - * Enqueues a style. - * - * @date 27/4/20 - * @since 5.9.0 - * - * @param string $name The style name. - * @return void - */ - public function enqueue_style( $name ) { - wp_enqueue_style( $name ); - } - - /** - * Adds the actions needed to print supporting inline scripts. - * - * @date 27/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - private function add_actions() { - - // Only run once. - if( acf_has_done('ACF_Assets::add_actions') ) { - return; + /** + * List of enqueue flags. + * + * @since 5.9.0 + * @var bool + */ + private $enqueue = array(); + + /** + * Constructor. + * + * @date 10/4/18 + * @since 5.6.9 + * + * @param void + * @return void + */ + public function __construct() { + add_action( 'init', array( $this, 'register_scripts' ) ); } - - // Add actions. - $this->add_action( 'admin_enqueue_scripts', 'enqueue_scripts' , 20 ); - $this->add_action( 'admin_print_scripts', 'print_scripts', 20 ); - $this->add_action( 'admin_print_footer_scripts', 'print_footer_scripts', 20 ); - } - - /** - * Extends the add_action() function with two additional features: - * 1. Renames $action depending on the current page (customizer, login, front-end). - * 2. Alters the priotiry or calls the method directly if the action has already passed. - * - * @date 28/4/20 - * @since 5.9.0 - * - * @param string $action The action name. - * @param string $method The method name. - * @param int $priority See add_action(). - * @param int $accepted_args See add_action(). - * @return void - */ - public function add_action( $action, $method, $priority = 10, $accepted_args = 1 ) { - - // Generate an array of action replacements. - $replacements = array( - 'customizer' => array( - 'admin_enqueue_scripts' => 'admin_enqueue_scripts', - 'admin_print_scripts' => 'customize_controls_print_scripts', - 'admin_head' => 'customize_controls_print_scripts', - 'admin_footer' => 'customize_controls_print_footer_scripts', - 'admin_print_footer_scripts' => 'customize_controls_print_footer_scripts' - ), - 'login' => array( - 'admin_enqueue_scripts' => 'login_enqueue_scripts', - 'admin_print_scripts' => 'login_head', - 'admin_head' => 'login_head', - 'admin_footer' => 'login_footer', - 'admin_print_footer_scripts' => 'login_footer' - ), - 'wp' => array( - 'admin_enqueue_scripts' => 'wp_enqueue_scripts', - 'admin_print_scripts' => 'wp_print_scripts', - 'admin_head' => 'wp_head', - 'admin_footer' => 'wp_footer', - 'admin_print_footer_scripts' => 'wp_print_footer_scripts' - ) - ); - - // Determine the current context. - if( did_action('customize_controls_init') ) { - $context = 'customizer'; - } elseif( did_action('login_form_register') ) { - $context = 'login'; - } elseif( is_admin() ) { - $context = 'admin'; - } else { - $context = 'wp'; - } - - // Replace action if possible. - if( isset( $replacements[ $context ][ $action ] ) ) { - $action = $replacements[ $context ][ $action ]; - } - - // Check if action is currently being or has already been run. - if( did_action($action) ) { - $doing = acf_doing_action( $action ); - if( $doing && $doing < $priority ) { - // Allow action to be added as per usual. - } else { - // Call method directly. - return call_user_func( array( $this, $method ) ); + + /** + * Magic __call method for backwards compatibility. + * + * @date 10/4/20 + * @since 5.9.0 + * + * @param string $name The method name. + * @param array $arguments The array of arguments. + * @return mixed + */ + public function __call( $name, $arguments ) { + switch ( $name ) { + case 'admin_enqueue_scripts': + case 'admin_print_scripts': + case 'admin_head': + case 'admin_footer': + case 'admin_print_footer_scripts': + _doing_it_wrong( __FUNCTION__, 'The ACF_Assets class should not be accessed directly.', '5.9.0' ); } } - - // Add action. - add_action( $action, array( $this, $method ), $priority, $accepted_args ); - } - - /** - * Generic controller for enqueuing scripts and styles. - * - * @date 28/4/20 - * @since 5.9.0 - * - * @param array $args { - * @type bool $uploader Whether or not to enqueue uploader scripts. - * } - * @return void - */ - public function enqueue( $args = array() ) { - - // Apply defaults. - $args = wp_parse_args($args, array( - 'input' => true, - 'uploader' => false - )); - - // Set enqueue flags and add actions. - if( $args['input'] ) { - $this->enqueue[] = 'input'; - } - if( $args['uploader'] ) { - $this->enqueue[] = 'uploader'; - } - $this->add_actions(); - } - - /** - * Enqueues the scripts and styles needed for the WP media uploader. - * - * @date 27/10/2014 - * @since 5.0.9 - * - * @param void - * @return void - */ - public function enqueue_uploader() { - - // Only run once. - if( acf_has_done('ACF_Assets::enqueue_uploader') ) { - return; - } - - // Enqueue media assets. - if( current_user_can('upload_files') ) { - wp_enqueue_media(); - } - - // Add actions. - $this->add_action( 'admin_footer', 'print_uploader_scripts', 1 ); /** - * Fires when enqueuing the uploader. + * Appends an array of i18n data. * - * @since 5.6.9 + * @date 13/4/18 + * @since 5.6.9 * - * @param void + * @param array $text An array of text for i18n. + * @return void */ - do_action( 'acf/enqueue_uploader' ); - } - - /** - * Enqueues and localizes scripts. - * - * @date 27/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - public function enqueue_scripts() { - - // Enqueue input scripts. - if( in_array('input', $this->enqueue) ) { - wp_enqueue_script( 'acf-input' ); - wp_enqueue_style( 'acf-input' ); + public function add_text( $text ) { + foreach ( (array) $text as $k => $v ) { + $this->text[ $k ] = $v; + } } - // Enqueue media scripts. - if( in_array('uploader', $this->enqueue) ) { - $this->enqueue_uploader(); + /** + * Appends an array of l10n data. + * + * @date 13/4/18 + * @since 5.6.9 + * + * @param array $data An array of data for l10n. + * @return void + */ + public function add_data( $data ) { + foreach ( (array) $data as $k => $v ) { + $this->data[ $k ] = $v; + } } - // Localize text. - acf_localize_text(array( - - // Tooltip - 'Are you sure?' => __('Are you sure?','acf'), - 'Yes' => __('Yes','acf'), - 'No' => __('No','acf'), - 'Remove' => __('Remove','acf'), - 'Cancel' => __('Cancel','acf'), - )); - - // Localize "input" text. - if( wp_script_is('acf-input') ) { - acf_localize_text(array( - - // Unload - 'The changes you made will be lost if you navigate away from this page' => __('The changes you made will be lost if you navigate away from this page', 'acf'), - - // Validation - 'Validation successful' => __('Validation successful', 'acf'), - 'Validation failed' => __('Validation failed', 'acf'), - '1 field requires attention' => __('1 field requires attention', 'acf'), - '%d fields require attention' => __('%d fields require attention', 'acf'), - - // Other - 'Edit field group' => __('Edit field group', 'acf'), - )); - + /** + * Registers the ACF scripts and styles. + * + * @date 10/4/18 + * @since 5.6.9 + * + * @param void + * @return void + */ + public function register_scripts() { + // Extract vars. + $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + $version = acf_get_setting( 'version' ); + + // Register scripts. + wp_register_script( 'acf', acf_get_url( 'assets/build/js/acf' . $suffix . '.js' ), array( 'jquery' ), $version ); + wp_register_script( 'acf-input', acf_get_url( 'assets/build/js/acf-input' . $suffix . '.js' ), array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-resizable', 'acf' ), $version ); + wp_register_script( 'acf-field-group', acf_get_url( 'assets/build/js/acf-field-group' . $suffix . '.js' ), array( 'acf-input' ), $version ); + + // Register styles. + wp_register_style( 'acf-global', acf_get_url( 'assets/build/css/acf-global.css' ), array( 'dashicons' ), $version ); + wp_register_style( 'acf-input', acf_get_url( 'assets/build/css/acf-input.css' ), array( 'acf-global' ), $version ); + wp_register_style( 'acf-field-group', acf_get_url( 'assets/build/css/acf-field-group.css' ), array( 'acf-input' ), $version ); + + /** + * Fires after core scripts and styles have been registered. + * + * @since 5.6.9 + * + * @param string $version The ACF version. + * @param string $suffix The potential ".min" filename suffix. + */ + do_action( 'acf/register_scripts', $version, $suffix ); + } + + /** + * Enqueues a script and sets up actions for priting supplemental scripts. + * + * @date 27/4/20 + * @since 5.9.0 + * + * @param string $name The script name. + * @return void + */ + public function enqueue_script( $name ) { + wp_enqueue_script( $name ); + $this->add_actions(); + } + + /** + * Enqueues a style. + * + * @date 27/4/20 + * @since 5.9.0 + * + * @param string $name The style name. + * @return void + */ + public function enqueue_style( $name ) { + wp_enqueue_style( $name ); + } + + /** + * Adds the actions needed to print supporting inline scripts. + * + * @date 27/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + private function add_actions() { + + // Only run once. + if ( acf_has_done( 'ACF_Assets::add_actions' ) ) { + return; + } + + // Add actions. + $this->add_action( 'admin_enqueue_scripts', 'enqueue_scripts', 20 ); + $this->add_action( 'admin_print_scripts', 'print_scripts', 20 ); + $this->add_action( 'admin_print_footer_scripts', 'print_footer_scripts', 20 ); + } + + /** + * Extends the add_action() function with two additional features: + * 1. Renames $action depending on the current page (customizer, login, front-end). + * 2. Alters the priotiry or calls the method directly if the action has already passed. + * + * @date 28/4/20 + * @since 5.9.0 + * + * @param string $action The action name. + * @param string $method The method name. + * @param int $priority See add_action(). + * @param int $accepted_args See add_action(). + * @return void + */ + public function add_action( $action, $method, $priority = 10, $accepted_args = 1 ) { + + // Generate an array of action replacements. + $replacements = array( + 'customizer' => array( + 'admin_enqueue_scripts' => 'admin_enqueue_scripts', + 'admin_print_scripts' => 'customize_controls_print_scripts', + 'admin_head' => 'customize_controls_print_scripts', + 'admin_footer' => 'customize_controls_print_footer_scripts', + 'admin_print_footer_scripts' => 'customize_controls_print_footer_scripts', + ), + 'login' => array( + 'admin_enqueue_scripts' => 'login_enqueue_scripts', + 'admin_print_scripts' => 'login_head', + 'admin_head' => 'login_head', + 'admin_footer' => 'login_footer', + 'admin_print_footer_scripts' => 'login_footer', + ), + 'wp' => array( + 'admin_enqueue_scripts' => 'wp_enqueue_scripts', + 'admin_print_scripts' => 'wp_print_scripts', + 'admin_head' => 'wp_head', + 'admin_footer' => 'wp_footer', + 'admin_print_footer_scripts' => 'wp_print_footer_scripts', + ), + ); + + // Determine the current context. + if ( did_action( 'customize_controls_init' ) ) { + $context = 'customizer'; + } elseif ( did_action( 'login_form_register' ) ) { + $context = 'login'; + } elseif ( is_admin() ) { + $context = 'admin'; + } else { + $context = 'wp'; + } + + // Replace action if possible. + if ( isset( $replacements[ $context ][ $action ] ) ) { + $action = $replacements[ $context ][ $action ]; + } + + // Check if action is currently being or has already been run. + if ( did_action( $action ) ) { + $doing = acf_doing_action( $action ); + if ( $doing && $doing < $priority ) { + // Allow action to be added as per usual. + } else { + // Call method directly. + return call_user_func( array( $this, $method ) ); + } + } + + // Add action. + add_action( $action, array( $this, $method ), $priority, $accepted_args ); + } + + /** + * Generic controller for enqueuing scripts and styles. + * + * @date 28/4/20 + * @since 5.9.0 + * + * @param array $args { + * @type bool $uploader Whether or not to enqueue uploader scripts. + * } + * @return void + */ + public function enqueue( $args = array() ) { + + // Apply defaults. + $args = wp_parse_args( + $args, + array( + 'input' => true, + 'uploader' => false, + ) + ); + + // Set enqueue flags and add actions. + if ( $args['input'] ) { + $this->enqueue[] = 'input'; + } + if ( $args['uploader'] ) { + $this->enqueue[] = 'uploader'; + } + $this->add_actions(); + } + + /** + * Enqueues the scripts and styles needed for the WP media uploader. + * + * @date 27/10/2014 + * @since 5.0.9 + * + * @param void + * @return void + */ + public function enqueue_uploader() { + + // Only run once. + if ( acf_has_done( 'ACF_Assets::enqueue_uploader' ) ) { + return; + } + + // Enqueue media assets. + if ( current_user_can( 'upload_files' ) ) { + wp_enqueue_media(); + } + + // Add actions. + $this->add_action( 'admin_footer', 'print_uploader_scripts', 1 ); + + /** + * Fires when enqueuing the uploader. + * + * @since 5.6.9 + * + * @param void + */ + do_action( 'acf/enqueue_uploader' ); + } + + /** + * Enqueues and localizes scripts. + * + * @date 27/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + public function enqueue_scripts() { + + // Enqueue input scripts. + if ( in_array( 'input', $this->enqueue ) ) { + wp_enqueue_script( 'acf-input' ); + wp_enqueue_style( 'acf-input' ); + } + + // Enqueue media scripts. + if ( in_array( 'uploader', $this->enqueue ) ) { + $this->enqueue_uploader(); + } + + // Localize text. + acf_localize_text( + array( + + // Tooltip + 'Are you sure?' => __( 'Are you sure?', 'acf' ), + 'Yes' => __( 'Yes', 'acf' ), + 'No' => __( 'No', 'acf' ), + 'Remove' => __( 'Remove', 'acf' ), + 'Cancel' => __( 'Cancel', 'acf' ), + ) + ); + + // Localize "input" text. + if ( wp_script_is( 'acf-input' ) ) { + acf_localize_text( + array( + + // Unload + 'The changes you made will be lost if you navigate away from this page' => __( 'The changes you made will be lost if you navigate away from this page', 'acf' ), + + // Validation + 'Validation successful' => __( 'Validation successful', 'acf' ), + 'Validation failed' => __( 'Validation failed', 'acf' ), + '1 field requires attention' => __( '1 field requires attention', 'acf' ), + '%d fields require attention' => __( '%d fields require attention', 'acf' ), + + // Other + 'Edit field group' => __( 'Edit field group', 'acf' ), + ) + ); + + /** + * Fires during "admin_enqueue_scripts" when ACF scripts are enqueued. + * + * @since 5.6.9 + * + * @param void + */ + do_action( 'acf/input/admin_enqueue_scripts' ); + } + /** * Fires during "admin_enqueue_scripts" when ACF scripts are enqueued. * - * @since 5.6.9 + * @since 5.6.9 * - * @param void + * @param void */ - do_action( 'acf/input/admin_enqueue_scripts' ); - } - - /** - * Fires during "admin_enqueue_scripts" when ACF scripts are enqueued. - * - * @since 5.6.9 - * - * @param void - */ - do_action( 'acf/admin_enqueue_scripts' ); - do_action( 'acf/enqueue_scripts' ); + do_action( 'acf/admin_enqueue_scripts' ); + do_action( 'acf/enqueue_scripts' ); - // Filter i18n translations that differ from English and localize script. - $text = array(); - foreach( $this->text as $k => $v ) { - if( str_replace('.verb', '', $k) !== $v ) { - $text[ $k ] = $v; + // Filter i18n translations that differ from English and localize script. + $text = array(); + foreach ( $this->text as $k => $v ) { + if ( str_replace( '.verb', '', $k ) !== $v ) { + $text[ $k ] = $v; + } + } + if ( $text ) { + wp_localize_script( 'acf', 'acfL10n', $text ); } } - if( $text ) { - wp_localize_script( 'acf', 'acfL10n', $text ); - } - } - - /** - * Prints scripts in head. - * - * @date 27/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - public function print_scripts() { - if( wp_script_is('acf-input') ) { - + + /** + * Prints scripts in head. + * + * @date 27/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + public function print_scripts() { + if ( wp_script_is( 'acf-input' ) ) { + + /** + * Fires during "admin_head" when ACF scripts are enqueued. + * + * @since 5.6.9 + * + * @param void + */ + do_action( 'acf/input/admin_head' ); + do_action( 'acf/input/admin_print_scripts' ); + } + /** * Fires during "admin_head" when ACF scripts are enqueued. * - * @since 5.6.9 + * @since 5.6.9 * - * @param void + * @param void */ - do_action( 'acf/input/admin_head' ); - do_action( 'acf/input/admin_print_scripts' ); + do_action( 'acf/admin_head' ); + do_action( 'acf/admin_print_scripts' ); } /** - * Fires during "admin_head" when ACF scripts are enqueued. + * Prints scripts in footer. * - * @since 5.6.9 + * @date 27/4/20 + * @since 5.9.0 * - * @param void + * @param void + * @return void */ - do_action( 'acf/admin_head' ); - do_action( 'acf/admin_print_scripts' ); - } - - /** - * Prints scripts in footer. - * - * @date 27/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - public function print_footer_scripts() { - global $wp_version; - - // Bail early if 'acf' script was never enqueued (fixes Elementor enqueue reset conflict). - if( !wp_script_is('acf') ) { - return; - } - - // Localize data. - acf_localize_data(array( - 'admin_url' => admin_url(), - 'ajaxurl' => admin_url( 'admin-ajax.php' ), - 'nonce' => wp_create_nonce( 'acf_nonce' ), - 'acf_version' => acf_get_setting('version'), - 'wp_version' => $wp_version, - 'browser' => acf_get_browser(), - 'locale' => acf_get_locale(), - 'rtl' => is_rtl(), - 'screen' => acf_get_form_data('screen'), - 'post_id' => acf_get_form_data('post_id'), - 'validation' => acf_get_form_data('validation'), - 'editor' => acf_is_block_editor() ? 'block' : 'classic' - )); - - // Print inline script. - printf( "\n", 'acf.data = ' . wp_json_encode( $this->data ) . ';' ); - - if( wp_script_is('acf-input') ) { - - /** - * Filters an empty array for compat l10n data. - * - * @since 5.0.0 - * - * @param array $data An array of data to append to. - */ - $compat_l10n = apply_filters( 'acf/input/admin_l10n', array() ); - if( $compat_l10n ) { - printf( "\n", 'acf.l10n = ' . wp_json_encode( $compat_l10n ) . ';' ); + public function print_footer_scripts() { + global $wp_version; + + // Bail early if 'acf' script was never enqueued (fixes Elementor enqueue reset conflict). + if ( ! wp_script_is( 'acf' ) ) { + return; } - + + // Localize data. + acf_localize_data( + array( + 'admin_url' => admin_url(), + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'acf_nonce' ), + 'acf_version' => acf_get_setting( 'version' ), + 'wp_version' => $wp_version, + 'browser' => acf_get_browser(), + 'locale' => acf_get_locale(), + 'rtl' => is_rtl(), + 'screen' => acf_get_form_data( 'screen' ), + 'post_id' => acf_get_form_data( 'post_id' ), + 'validation' => acf_get_form_data( 'validation' ), + 'editor' => acf_is_block_editor() ? 'block' : 'classic', + ) + ); + + // Print inline script. + printf( "\n", 'acf.data = ' . wp_json_encode( $this->data ) . ';' ); + + if ( wp_script_is( 'acf-input' ) ) { + + /** + * Filters an empty array for compat l10n data. + * + * @since 5.0.0 + * + * @param array $data An array of data to append to. + */ + $compat_l10n = apply_filters( 'acf/input/admin_l10n', array() ); + if ( $compat_l10n ) { + printf( "\n", 'acf.l10n = ' . wp_json_encode( $compat_l10n ) . ';' ); + } + + /** + * Fires during "admin_footer" when ACF scripts are enqueued. + * + * @since 5.6.9 + * + * @param void + */ + do_action( 'acf/input/admin_footer' ); + do_action( 'acf/input/admin_print_footer_scripts' ); + } + /** * Fires during "admin_footer" when ACF scripts are enqueued. * - * @since 5.6.9 + * @since 5.6.9 * - * @param void + * @param void */ - do_action( 'acf/input/admin_footer' ); - do_action( 'acf/input/admin_print_footer_scripts' ); + do_action( 'acf/admin_footer' ); + do_action( 'acf/admin_print_footer_scripts' ); + + // Once all data is localized, trigger acf.prepare() to execute functionality before DOM ready. + printf( "\n", "acf.doAction( 'prepare' );" ); } - + /** - * Fires during "admin_footer" when ACF scripts are enqueued. + * Prints uploader scripts in footer. * - * @since 5.6.9 + * @date 11/06/2020 + * @since 5.9.0 * - * @param void + * @param void + * @return void */ - do_action( 'acf/admin_footer' ); - do_action( 'acf/admin_print_footer_scripts' ); - - // Once all data is localized, trigger acf.prepare() to execute functionality before DOM ready. - printf( "\n", "acf.doAction( 'prepare' );" ); - } - - /** - * Prints uploader scripts in footer. - * - * @date 11/06/2020 - * @since 5.9.0 - * - * @param void - * @return void - */ - public function print_uploader_scripts() { - // Todo: investigate output-buffer to hide HTML. - ?> + public function print_uploader_scripts() { + // Todo: investigate output-buffer to hide HTML. + ?> - add_text( $text ); + return acf_get_instance( 'ACF_Assets' )->add_text( $text ); } /** * Appends an array of l10n data for localization. * - * @date 13/4/18 - * @since 5.6.9 + * @date 13/4/18 + * @since 5.6.9 * - * @param array $data An array of data for l10n. - * @return void + * @param array $data An array of data for l10n. + * @return void */ function acf_localize_data( $data ) { - return acf_get_instance('ACF_Assets')->add_data( $data ); + return acf_get_instance( 'ACF_Assets' )->add_data( $data ); } /** * Enqueues a script with support for supplemental inline scripts. * - * @date 27/4/20 - * @since 5.9.0 + * @date 27/4/20 + * @since 5.9.0 * - * @param string $name The script name. - * @return void + * @param string $name The script name. + * @return void */ function acf_enqueue_script( $name ) { - return acf_get_instance('ACF_Assets')->enqueue_script( $name ); + return acf_get_instance( 'ACF_Assets' )->enqueue_script( $name ); } /** * Enqueues the input scripts required for fields. * - * @date 13/4/18 - * @since 5.6.9 + * @date 13/4/18 + * @since 5.6.9 * - * @param array $args See ACF_Assets::enqueue_scripts() for a list of args. - * @return void + * @param array $args See ACF_Assets::enqueue_scripts() for a list of args. + * @return void */ function acf_enqueue_scripts( $args = array() ) { - return acf_get_instance('ACF_Assets')->enqueue( $args ); + return acf_get_instance( 'ACF_Assets' )->enqueue( $args ); } /** * Enqueues the WP media uploader scripts and styles. * - * @date 27/10/2014 - * @since 5.0.9 + * @date 27/10/2014 + * @since 5.0.9 * - * @param void - * @return void + * @param void + * @return void */ function acf_enqueue_uploader() { - return acf_get_instance('ACF_Assets')->enqueue_uploader(); + return acf_get_instance( 'ACF_Assets' )->enqueue_uploader(); } diff --git a/includes/class-acf-data.php b/includes/class-acf-data.php index 455410b..68170f0 100644 --- a/includes/class-acf-data.php +++ b/includes/class-acf-data.php @@ -1,354 +1,356 @@ -cid = acf_uniqid(); - - // Set data. - if( $data ) { - $this->set( $data ); - } - - // Initialize. - $this->initialize(); - } - - /** - * initialize - * - * Called during constructor to setup class functionality. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param void - * @return void - */ - function initialize() { - // Do nothing. - } - - /** - * prop - * - * Sets a property for the given name and returns $this for chaining. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param (string|array) $name The data name or an array of data. - * @param mixed $value The data value. - * @return ACF_Data - */ - function prop( $name = '', $value = null ) { - - // Update property. - $this->{$name} = $value; - - // Return this for chaining. - return $this; - } - - /** - * _key - * - * Returns a key for the given name allowing aliasses to work. - * - * @date 18/1/19 - * @since 5.7.10 - * - * @param type $var Description. Default. - * @return type Description. - */ - function _key( $name = '' ) { - return isset($this->aliases[ $name ]) ? $this->aliases[ $name ] : $name; - } - - /** - * has - * - * Returns true if this has data for the given name. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param string $name The data name. - * @return boolean - */ - function has( $name = '' ) { - $key = $this->_key($name); - return isset($this->data[ $key ]); - } - - /** - * is - * - * Similar to has() but does not check aliases. - * - * @date 7/2/19 - * @since 5.7.11 - * - * @param type $var Description. Default. - * @return type Description. - */ - function is( $key = '' ) { - return isset($this->data[ $key ]); - } - - /** - * get - * - * Returns data for the given name of null if doesn't exist. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param string $name The data name. - * @return mixed - */ - function get( $name = false ) { - - // Get all. - if( $name === false ) { - return $this->data; - - // Get specific. - } else { - $key = $this->_key($name); - return isset($this->data[ $key ]) ? $this->data[ $key ] : null; - } - } - - /** - * get_data - * - * Returns an array of all data. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param void - * @return array - */ - function get_data() { - return $this->data; - } - - /** - * set - * - * Sets data for the given name and returns $this for chaining. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param (string|array) $name The data name or an array of data. - * @param mixed $value The data value. - * @return ACF_Data - */ - function set( $name = '', $value = null ) { - - // Set multiple. - if( is_array($name) ) { - $this->data = array_merge($this->data, $name); - - // Set single. - } else { - $this->data[ $name ] = $value; - } - - // Return this for chaining. - return $this; - } - - /** - * append - * - * Appends data for the given name and returns $this for chaining. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param mixed $value The data value. - * @return ACF_Data - */ - function append( $value = null ) { - - // Append. - $this->data[] = $value; - - // Return this for chaining. - return $this; - } - - /** - * remove - * - * Removes data for the given name. - * - * @date 9/1/19 - * @since 5.7.10 - * - * @param string $name The data name. - * @return ACF_Data - */ - function remove( $name = '' ) { - - // Remove data. - unset( $this->data[ $name ] ); - - // Return this for chaining. - return $this; - } - - /** - * reset - * - * Resets the data. - * - * @date 22/1/19 - * @since 5.7.10 - * - * @param void - * @return void - */ - function reset() { - $this->data = array(); - $this->aliases = array(); - } - - /** - * count - * - * Returns the data count. - * - * @date 23/1/19 - * @since 5.7.10 - * - * @param void - * @return int - */ - function count() { - return count( $this->data ); - } - - /** - * query - * - * Returns a filtered array of data based on the set of key => value arguments. - * - * @date 23/1/19 - * @since 5.7.10 - * - * @param void - * @return int - */ - function query( $args, $operator = 'AND' ) { - return wp_list_filter( $this->data, $args, $operator ); - } - - /** - * alias - * - * Sets an alias for the given name allowing data to be found via multiple identifiers. - * - * @date 18/1/19 - * @since 5.7.10 - * - * @param type $var Description. Default. - * @return type Description. - */ - function alias( $name = '' /*, $alias, $alias2, etc */ ) { - - // Get all aliases. - $args = func_get_args(); - array_shift( $args ); - - // Loop over aliases and add to data. - foreach( $args as $alias ) { - $this->aliases[ $alias ] = $name; - } - - // Return this for chaining. - return $this; - } - - /** - * switch_site - * - * Triggered when switching between sites on a multisite installation. - * - * @date 13/2/19 - * @since 5.7.11 - * - * @param int $site_id New blog ID. - * @param int prev_blog_id Prev blog ID. - * @return void - */ - function switch_site( $site_id, $prev_site_id ) { - - // Bail early if not multisite compatible. - if( !$this->multisite ) { - return; - } - - // Bail early if no change in blog ID. - if( $site_id === $prev_site_id ) { - return; - } - - // Create storage. - if( !isset($this->site_data) ) { - $this->site_data = array(); - $this->site_aliases = array(); - } - - // Save state. - $this->site_data[ $prev_site_id ] = $this->data; - $this->site_aliases[ $prev_site_id ] = $this->aliases; - - // Reset state. - $this->data = array(); - $this->aliases = array(); - - // Load state. - if( isset($this->site_data[ $site_id ]) ) { - $this->data = $this->site_data[ $site_id ]; - $this->aliases = $this->site_aliases[ $site_id ]; - unset( $this->site_data[ $site_id ] ); - unset( $this->site_aliases[ $site_id ] ); - } - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. } +if ( ! class_exists( 'ACF_Data' ) ) : + + class ACF_Data { + + /** @var string Unique identifier. */ + var $cid = ''; + + /** @var array Storage for data. */ + var $data = array(); + + /** @var array Storage for data aliases. */ + var $aliases = array(); + + /** @var bool Enables unique data per site. */ + var $multisite = false; + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param array $data Optional data to set. + * @return void + */ + function __construct( $data = false ) { + + // Set cid. + $this->cid = acf_uniqid(); + + // Set data. + if ( $data ) { + $this->set( $data ); + } + + // Initialize. + $this->initialize(); + } + + /** + * initialize + * + * Called during constructor to setup class functionality. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param void + * @return void + */ + function initialize() { + // Do nothing. + } + + /** + * prop + * + * Sets a property for the given name and returns $this for chaining. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param (string|array) $name The data name or an array of data. + * @param mixed $value The data value. + * @return ACF_Data + */ + function prop( $name = '', $value = null ) { + + // Update property. + $this->{$name} = $value; + + // Return this for chaining. + return $this; + } + + /** + * _key + * + * Returns a key for the given name allowing aliasses to work. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param type $var Description. Default. + * @return type Description. + */ + function _key( $name = '' ) { + return isset( $this->aliases[ $name ] ) ? $this->aliases[ $name ] : $name; + } + + /** + * has + * + * Returns true if this has data for the given name. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param string $name The data name. + * @return boolean + */ + function has( $name = '' ) { + $key = $this->_key( $name ); + return isset( $this->data[ $key ] ); + } + + /** + * is + * + * Similar to has() but does not check aliases. + * + * @date 7/2/19 + * @since 5.7.11 + * + * @param type $var Description. Default. + * @return type Description. + */ + function is( $key = '' ) { + return isset( $this->data[ $key ] ); + } + + /** + * get + * + * Returns data for the given name of null if doesn't exist. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param string $name The data name. + * @return mixed + */ + function get( $name = false ) { + + // Get all. + if ( $name === false ) { + return $this->data; + + // Get specific. + } else { + $key = $this->_key( $name ); + return isset( $this->data[ $key ] ) ? $this->data[ $key ] : null; + } + } + + /** + * get_data + * + * Returns an array of all data. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param void + * @return array + */ + function get_data() { + return $this->data; + } + + /** + * set + * + * Sets data for the given name and returns $this for chaining. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param (string|array) $name The data name or an array of data. + * @param mixed $value The data value. + * @return ACF_Data + */ + function set( $name = '', $value = null ) { + + // Set multiple. + if ( is_array( $name ) ) { + $this->data = array_merge( $this->data, $name ); + + // Set single. + } else { + $this->data[ $name ] = $value; + } + + // Return this for chaining. + return $this; + } + + /** + * append + * + * Appends data for the given name and returns $this for chaining. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param mixed $value The data value. + * @return ACF_Data + */ + function append( $value = null ) { + + // Append. + $this->data[] = $value; + + // Return this for chaining. + return $this; + } + + /** + * remove + * + * Removes data for the given name. + * + * @date 9/1/19 + * @since 5.7.10 + * + * @param string $name The data name. + * @return ACF_Data + */ + function remove( $name = '' ) { + + // Remove data. + unset( $this->data[ $name ] ); + + // Return this for chaining. + return $this; + } + + /** + * reset + * + * Resets the data. + * + * @date 22/1/19 + * @since 5.7.10 + * + * @param void + * @return void + */ + function reset() { + $this->data = array(); + $this->aliases = array(); + } + + /** + * count + * + * Returns the data count. + * + * @date 23/1/19 + * @since 5.7.10 + * + * @param void + * @return int + */ + function count() { + return count( $this->data ); + } + + /** + * query + * + * Returns a filtered array of data based on the set of key => value arguments. + * + * @date 23/1/19 + * @since 5.7.10 + * + * @param void + * @return int + */ + function query( $args, $operator = 'AND' ) { + return wp_list_filter( $this->data, $args, $operator ); + } + + /** + * alias + * + * Sets an alias for the given name allowing data to be found via multiple identifiers. + * + * @date 18/1/19 + * @since 5.7.10 + * + * @param type $var Description. Default. + * @return type Description. + */ + function alias( $name = '' /*, $alias, $alias2, etc */ ) { + + // Get all aliases. + $args = func_get_args(); + array_shift( $args ); + + // Loop over aliases and add to data. + foreach ( $args as $alias ) { + $this->aliases[ $alias ] = $name; + } + + // Return this for chaining. + return $this; + } + + /** + * switch_site + * + * Triggered when switching between sites on a multisite installation. + * + * @date 13/2/19 + * @since 5.7.11 + * + * @param int $site_id New blog ID. + * @param int prev_blog_id Prev blog ID. + * @return void + */ + function switch_site( $site_id, $prev_site_id ) { + + // Bail early if not multisite compatible. + if ( ! $this->multisite ) { + return; + } + + // Bail early if no change in blog ID. + if ( $site_id === $prev_site_id ) { + return; + } + + // Create storage. + if ( ! isset( $this->site_data ) ) { + $this->site_data = array(); + $this->site_aliases = array(); + } + + // Save state. + $this->site_data[ $prev_site_id ] = $this->data; + $this->site_aliases[ $prev_site_id ] = $this->aliases; + + // Reset state. + $this->data = array(); + $this->aliases = array(); + + // Load state. + if ( isset( $this->site_data[ $site_id ] ) ) { + $this->data = $this->site_data[ $site_id ]; + $this->aliases = $this->site_aliases[ $site_id ]; + unset( $this->site_data[ $site_id ] ); + unset( $this->site_aliases[ $site_id ] ); + } + } + } + endif; // class_exists check diff --git a/includes/compatibility.php b/includes/compatibility.php index 8078133..d6edd1c 100644 --- a/includes/compatibility.php +++ b/includes/compatibility.php @@ -1,470 +1,474 @@ 'post_taxonomy', - 'ef_media' => 'attachment', - 'ef_taxonomy' => 'taxonomy', - 'ef_user' => 'user_role', - 'user_type' => 'current_user_role' // 5.2.0 - ); - - // only replace 'taxonomy' rule if is an ACF4 field group - if( $version > 4 ) { - unset($replace['taxonomy']); - } - - // loop over location groups - if( $field_group['location'] ) { - foreach( $field_group['location'] as $i => $group ) { - - // loop over group rules - if( $group ) { - foreach( $group as $j => $rule ) { - - // migrate param - if( isset($replace[ $rule['param'] ]) ) { - $field_group['location'][ $i ][ $j ]['param'] = $replace[ $rule['param'] ]; - } - }} - }} - - // change layout to style (v5.0.0) - if( isset($field_group['layout']) ) { - $field_group['style'] = acf_extract_var($field_group, 'layout'); - } - - // change no_box to seamless (v5.0.0) - if( $field_group['style'] === 'no_box' ) { - $field_group['style'] = 'seamless'; - } - - //return - return $field_group; - } - - /** - * validate_post_taxonomy_location_rule - * - * description - * - * @date 27/8/18 - * @since 5.7.4 - * - * @param type $var Description. Default. - * @return type Description. - */ - function validate_post_taxonomy_location_rule( $rule ) { - - // previous versions of ACF (v4.4.12) saved value as term_id - // convert term_id into "taxonomy:slug" string - if( is_numeric($rule['value']) ) { - $term = acf_get_term( $rule['value'] ); - if( $term ) { - $rule['value'] = acf_encode_term($term); - } - } - - // return - return $rule; - } - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -acf_new_instance('ACF_Compatibility'); +if ( ! class_exists( 'ACF_Compatibility' ) ) : + + class ACF_Compatibility { + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 30/04/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function __construct() { + + // actions + add_filter( 'acf/validate_field', array( $this, 'validate_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=textarea', array( $this, 'validate_textarea_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=relationship', array( $this, 'validate_relationship_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=post_object', array( $this, 'validate_relationship_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=page_link', array( $this, 'validate_relationship_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=image', array( $this, 'validate_image_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=file', array( $this, 'validate_image_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=wysiwyg', array( $this, 'validate_wysiwyg_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=date_picker', array( $this, 'validate_date_picker_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=taxonomy', array( $this, 'validate_taxonomy_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=date_time_picker', array( $this, 'validate_date_time_picker_field' ), 20, 1 ); + add_filter( 'acf/validate_field/type=user', array( $this, 'validate_user_field' ), 20, 1 ); + add_filter( 'acf/validate_field_group', array( $this, 'validate_field_group' ), 20, 1 ); + + // Modify field wrapper attributes + add_filter( 'acf/field_wrapper_attributes', array( $this, 'field_wrapper_attributes' ), 20, 2 ); + + // location + add_filter( 'acf/location/validate_rule/type=post_taxonomy', array( $this, 'validate_post_taxonomy_location_rule' ), 20, 1 ); + add_filter( 'acf/location/validate_rule/type=post_category', array( $this, 'validate_post_taxonomy_location_rule' ), 20, 1 ); + + // Update settings + add_action( 'acf/init', array( $this, 'init' ) ); + } + + /** + * init + * + * Adds compatibility for deprecated settings. + * + * @date 10/6/19 + * @since 5.8.1 + * + * @param void + * @return void + */ + function init() { + + // Update "show_admin" setting based on defined constant. + if ( defined( 'ACF_LITE' ) && ACF_LITE ) { + acf_update_setting( 'show_admin', false ); + } + } + + /** + * field_wrapper_attributes + * + * Adds compatibility with deprecated field wrap attributes. + * + * @date 21/1/19 + * @since 5.7.10 + * + * @param array $wrapper The wrapper attributes array. + * @param array $field The field array. + */ + function field_wrapper_attributes( $wrapper, $field ) { + + // Check compatibility setting. + if ( acf_get_compatibility( 'field_wrapper_class' ) ) { + $wrapper['class'] .= " field_type-{$field['type']}"; + if ( $field['key'] ) { + $wrapper['class'] .= " field_key-{$field['key']}"; + } + } + + // Return wrapper. + return $wrapper; + } + + /** + * validate_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array $field + */ + function validate_field( $field ) { + + // conditional logic data structure changed to groups in version 5.0.0 + // convert previous data (status, rules, allorany) into groups + if ( isset( $field['conditional_logic']['status'] ) ) { + + // check status + if ( $field['conditional_logic']['status'] ) { + $field['conditional_logic'] = acf_convert_rules_to_groups( $field['conditional_logic']['rules'], $field['conditional_logic']['allorany'] ); + } else { + $field['conditional_logic'] = 0; + } + } + + // return + return $field; + } + + /** + * validate_textarea_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array $field + */ + function validate_textarea_field( $field ) { + + // formatting has been removed + $formatting = acf_extract_var( $field, 'formatting' ); + if ( $formatting === 'br' ) { + $field['new_lines'] = 'br'; + } + + // return + return $field; + } + + /** + * validate_relationship_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array $field + */ + function validate_relationship_field( $field ) { + + // remove 'all' from post_type + if ( acf_in_array( 'all', $field['post_type'] ) ) { + $field['post_type'] = array(); + } + + // remove 'all' from taxonomy + if ( acf_in_array( 'all', $field['taxonomy'] ) ) { + $field['taxonomy'] = array(); + } + + // result_elements is now elements + if ( isset( $field['result_elements'] ) ) { + $field['elements'] = acf_extract_var( $field, 'result_elements' ); + } + + // return + return $field; + } + + /** + * validate_image_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array $field + */ + function validate_image_field( $field ) { + + // save_format is now return_format + if ( isset( $field['save_format'] ) ) { + $field['return_format'] = acf_extract_var( $field, 'save_format' ); + } + + // object is now array + if ( $field['return_format'] == 'object' ) { + $field['return_format'] = 'array'; + } + + // return + return $field; + } + + /** + * validate_wysiwyg_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array $field + */ + function validate_wysiwyg_field( $field ) { + + // media_upload is now numeric + if ( $field['media_upload'] === 'yes' ) { + $field['media_upload'] = 1; + } elseif ( $field['media_upload'] === 'no' ) { + $field['media_upload'] = 0; + } + + // return + return $field; + } + + /** + * validate_date_picker_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.0.0 + * + * @param array $field The field array. + * @return array $field + */ + function validate_date_picker_field( $field ) { + + // date_format has changed to display_format + if ( isset( $field['date_format'] ) ) { + + // extract vars + $date_format = $field['date_format']; + $display_format = $field['display_format']; + + // convert from js to php + $display_format = acf_convert_date_to_php( $display_format ); + + // append settings + $field['display_format'] = $display_format; + $field['save_format'] = $date_format; + + // clean up + unset( $field['date_format'] ); + } + + // return + return $field; + } + + /** + * validate_taxonomy_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.2.7 + * + * @param array $field The field array. + * @return array $field + */ + function validate_taxonomy_field( $field ) { + + // load_save_terms deprecated in favour of separate save_terms + if ( isset( $field['load_save_terms'] ) ) { + $field['save_terms'] = acf_extract_var( $field, 'load_save_terms' ); + } + + // return + return $field; + } + + /** + * validate_date_time_picker_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.2.7 + * + * @param array $field The field array. + * @return array $field + */ + function validate_date_time_picker_field( $field ) { + + // 3rd party date time picker + // https://github.com/soderlind/acf-field-date-time-picker + if ( ! empty( $field['time_format'] ) ) { + + // extract vars + $time_format = acf_extract_var( $field, 'time_format' ); + $date_format = acf_extract_var( $field, 'date_format' ); + $get_as_timestamp = acf_extract_var( $field, 'get_as_timestamp' ); + + // convert from js to php + $time_format = acf_convert_time_to_php( $time_format ); + $date_format = acf_convert_date_to_php( $date_format ); + + // append settings + $field['return_format'] = $date_format . ' ' . $time_format; + $field['display_format'] = $date_format . ' ' . $time_format; + + // timestamp + if ( $get_as_timestamp === 'true' ) { + $field['return_format'] = 'U'; + } + } + + // return + return $field; + } + + /** + * validate_user_field + * + * Adds compatibility with deprecated settings + * + * @date 23/04/2014 + * @since 5.2.7 + * + * @param array $field The field array. + * @return array $field + */ + function validate_user_field( $field ) { + + // remove 'all' from roles + if ( acf_in_array( 'all', $field['role'] ) ) { + $field['role'] = ''; + } + + // field_type removed in favour of multiple + if ( isset( $field['field_type'] ) ) { + + // extract vars + $field_type = acf_extract_var( $field, 'field_type' ); + + // multiple + if ( $field_type === 'multi_select' ) { + $field['multiple'] = true; + } + } + + // return + return $field; + } + + /* + * validate_field_group + * + * This function will provide compatibility with ACF4 field groups + * + * @type function + * @date 23/04/2014 + * @since 5.0.0 + * + * @param $field_group (array) + * @return $field_group + */ + function validate_field_group( $field_group ) { + + // vars + $version = 5; + + // field group key was added in version 5.0.0 + // detect ACF4 data and generate key + if ( ! $field_group['key'] ) { + $version = 4; + $field_group['key'] = isset( $field_group['id'] ) ? "group_{$field_group['id']}" : uniqid( 'group_' ); + } + + // prior to version 5.0.0, settings were saved in an 'options' array + // extract and merge options into the field group + if ( isset( $field_group['options'] ) ) { + $options = acf_extract_var( $field_group, 'options' ); + $field_group = array_merge( $field_group, $options ); + } + + // location data structure changed to groups in version 4.1.0 + // convert previous data (rules, allorany) into groups + if ( isset( $field_group['location']['rules'] ) ) { + $field_group['location'] = acf_convert_rules_to_groups( $field_group['location']['rules'], $field_group['location']['allorany'] ); + } + + // some location rule names have changed in version 5.0.0 + // loop over location data and modify rules + $replace = array( + 'taxonomy' => 'post_taxonomy', + 'ef_media' => 'attachment', + 'ef_taxonomy' => 'taxonomy', + 'ef_user' => 'user_role', + 'user_type' => 'current_user_role', // 5.2.0 + ); + + // only replace 'taxonomy' rule if is an ACF4 field group + if ( $version > 4 ) { + unset( $replace['taxonomy'] ); + } + + // loop over location groups + if ( $field_group['location'] ) { + foreach ( $field_group['location'] as $i => $group ) { + + // loop over group rules + if ( $group ) { + foreach ( $group as $j => $rule ) { + + // migrate param + if ( isset( $replace[ $rule['param'] ] ) ) { + $field_group['location'][ $i ][ $j ]['param'] = $replace[ $rule['param'] ]; + } + } + } + } + } + + // change layout to style (v5.0.0) + if ( isset( $field_group['layout'] ) ) { + $field_group['style'] = acf_extract_var( $field_group, 'layout' ); + } + + // change no_box to seamless (v5.0.0) + if ( $field_group['style'] === 'no_box' ) { + $field_group['style'] = 'seamless'; + } + + // return + return $field_group; + } + + /** + * validate_post_taxonomy_location_rule + * + * description + * + * @date 27/8/18 + * @since 5.7.4 + * + * @param type $var Description. Default. + * @return type Description. + */ + function validate_post_taxonomy_location_rule( $rule ) { + + // previous versions of ACF (v4.4.12) saved value as term_id + // convert term_id into "taxonomy:slug" string + if ( is_numeric( $rule['value'] ) ) { + $term = acf_get_term( $rule['value'] ); + if ( $term ) { + $rule['value'] = acf_encode_term( $term ); + } + } + + // return + return $rule; + } + + } + + acf_new_instance( 'ACF_Compatibility' ); endif; // class_exists check @@ -473,12 +477,12 @@ endif; // class_exists check * * Returns true if compatibility is enabled for the given component. * - * @date 20/1/15 - * @since 5.1.5 + * @date 20/1/15 + * @since 5.1.5 * - * @param string $name The name of the component to check. - * @return bool + * @param string $name The name of the component to check. + * @return bool */ function acf_get_compatibility( $name ) { return apply_filters( "acf/compatibility/{$name}", false ); -} \ No newline at end of file +} diff --git a/includes/deprecated.php b/includes/deprecated.php index 8137580..ca73619 100644 --- a/includes/deprecated.php +++ b/includes/deprecated.php @@ -1,38 +1,38 @@ - $parent_id, 'key' => "group_$parent_id" )); + return acf_get_fields( + array( + 'ID' => $parent_id, + 'key' => "group_$parent_id", + ) + ); } /** @@ -84,23 +89,23 @@ function acf_get_fields_by_id( $parent_id = 0 ) { * * A wrapper for the WP update_option but provides logic for a 'no' autoload * - * @date 4/01/2014 - * @since 5.0.0 - * @deprecated 5.7.11 + * @date 4/01/2014 + * @since 5.0.0 + * @deprecated 5.7.11 * - * @param string $option The option name. - * @param string $value The option value. - * @param string $autoload An optional autoload value. - * @return bool + * @param string $option The option name. + * @param string $value The option value. + * @param string $autoload An optional autoload value. + * @return bool */ function acf_update_option( $option = '', $value = '', $autoload = null ) { - + // Warning. _deprecated_function( __FUNCTION__, '5.7.11', 'update_option()' ); - + // Update. - if( $autoload === null ) { - $autoload = (bool) acf_get_setting('autoload'); + if ( $autoload === null ) { + $autoload = (bool) acf_get_setting( 'autoload' ); } return update_option( $option, $value, $autoload ); } @@ -110,19 +115,19 @@ function acf_update_option( $option = '', $value = '', $autoload = null ) { * * Finds the field key for a given field name and post_id. * - * @date 26/1/18 - * @since 5.6.5 - * @deprecated 5.6.8 + * @date 26/1/18 + * @since 5.6.5 + * @deprecated 5.6.8 * - * @param string $field_name The name of the field. eg 'sub_heading' - * @param mixed $post_id The post_id of which the value is saved against - * @return string $reference The field key + * @param string $field_name The name of the field. eg 'sub_heading' + * @param mixed $post_id The post_id of which the value is saved against + * @return string $reference The field key */ function acf_get_field_reference( $field_name, $post_id ) { - + // Warning. _deprecated_function( __FUNCTION__, '5.6.8', 'acf_get_reference()' ); - + // Return reference. return acf_get_reference( $field_name, $post_id ); } @@ -132,18 +137,18 @@ function acf_get_field_reference( $field_name, $post_id ) { * * Returns the plugin url to a specified file. * - * @date 28/09/13 - * @since 5.0.0 - * @deprecated 5.6.8 + * @date 28/09/13 + * @since 5.0.0 + * @deprecated 5.6.8 * - * @param string $filename The specified file. - * @return string + * @param string $filename The specified file. + * @return string */ function acf_get_dir( $filename = '' ) { - + // Warning. _deprecated_function( __FUNCTION__, '5.6.8', 'acf_get_url()' ); - + // Return. return acf_get_url( $filename ); } diff --git a/includes/fields.php b/includes/fields.php old mode 100644 new mode 100755 index 2aa9424..f8da506 --- a/includes/fields.php +++ b/includes/fields.php @@ -1,139 +1,141 @@ -types[ $class->name ] = $class; - - // allow class name - } else { - $instance = new $class(); - $this->types[ $instance->name ] = $instance; - } - } - - - /* - * get_field_type - * - * This function will return a field type instance - * - * @type function - * @date 6/07/2016 - * @since 5.4.0 - * - * @param $name (string) - * @return (mixed) - */ - - function get_field_type( $name ) { - return isset( $this->types[$name] ) ? $this->types[$name] : null; - } - - - /* - * is_field_type - * - * This function will return true if a field type exists - * - * @type function - * @date 6/07/2016 - * @since 5.4.0 - * - * @param $name (string) - * @return (mixed) - */ - - function is_field_type( $name ) { - return isset( $this->types[$name] ); - } - - - /* - * register_field_type_info - * - * This function will store a basic array of info about the field type - * to later be overriden by the above register_field_type function - * - * @type function - * @date 29/5/17 - * @since 5.6.0 - * - * @param $info (array) - * @return n/a - */ - - function register_field_type_info( $info ) { - - // convert to object - $instance = (object) $info; - $this->types[ $instance->name ] = $instance; - } - - - /* - * get_field_types - * - * This function will return an array of all field types - * - * @type function - * @date 6/07/2016 - * @since 5.4.0 - * - * @param $name (string) - * @return (mixed) - */ - - function get_field_types() { - return $this->types; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'acf_fields' ) ) : -// initialize -acf()->fields = new acf_fields(); + class acf_fields { + + /** @var array Contains an array of field type instances */ + var $types = array(); + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.4.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + /* do nothing */ + } + + + /* + * register_field_type + * + * This function will register a field type instance + * + * @type function + * @date 6/07/2016 + * @since 5.4.0 + * + * @param $class (string) + * @return n/a + */ + + function register_field_type( $class ) { + + // allow instance + if ( $class instanceof acf_field ) { + $this->types[ $class->name ] = $class; + + // allow class name + } else { + $instance = new $class(); + $this->types[ $instance->name ] = $instance; + } + } + + + /* + * get_field_type + * + * This function will return a field type instance + * + * @type function + * @date 6/07/2016 + * @since 5.4.0 + * + * @param $name (string) + * @return (mixed) + */ + + function get_field_type( $name ) { + return isset( $this->types[ $name ] ) ? $this->types[ $name ] : null; + } + + + /* + * is_field_type + * + * This function will return true if a field type exists + * + * @type function + * @date 6/07/2016 + * @since 5.4.0 + * + * @param $name (string) + * @return (mixed) + */ + + function is_field_type( $name ) { + return isset( $this->types[ $name ] ); + } + + + /* + * register_field_type_info + * + * This function will store a basic array of info about the field type + * to later be overriden by the above register_field_type function + * + * @type function + * @date 29/5/17 + * @since 5.6.0 + * + * @param $info (array) + * @return n/a + */ + + function register_field_type_info( $info ) { + + // convert to object + $instance = (object) $info; + $this->types[ $instance->name ] = $instance; + } + + + /* + * get_field_types + * + * This function will return an array of all field types + * + * @type function + * @date 6/07/2016 + * @since 5.4.0 + * + * @param $name (string) + * @return (mixed) + */ + + function get_field_types() { + return $this->types; + } + } + + + // initialize + acf()->fields = new acf_fields(); endif; // class_exists check @@ -143,12 +145,12 @@ endif; // class_exists check * * alias of acf()->fields->register_field_type() * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_register_field_type( $class ) { @@ -161,12 +163,12 @@ function acf_register_field_type( $class ) { * * alias of acf()->fields->register_field_type_info() * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_register_field_type_info( $info ) { @@ -179,12 +181,12 @@ function acf_register_field_type_info( $info ) { * * alias of acf()->fields->get_field_type() * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_get_field_type( $name ) { @@ -197,57 +199,60 @@ function acf_get_field_type( $name ) { * * alias of acf()->fields->get_field_types() * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_get_field_types( $args = array() ) { - + // default - $args = wp_parse_args($args, array( - 'public' => true, // true, false - )); - + $args = wp_parse_args( + $args, + array( + 'public' => true, // true, false + ) + ); + // get field types $field_types = acf()->fields->get_field_types(); - + // filter - return wp_filter_object_list( $field_types, $args ); + return wp_filter_object_list( $field_types, $args ); } /** -* acf_get_field_types_info -* -* Returns an array containing information about each field type -* -* @date 18/6/18 -* @since 5.6.9 -* -* @param type $var Description. Default. -* @return type Description. -*/ + * acf_get_field_types_info + * + * Returns an array containing information about each field type + * + * @date 18/6/18 + * @since 5.6.9 + * + * @param type $var Description. Default. + * @return type Description. + */ function acf_get_field_types_info( $args = array() ) { - + // vars - $data = array(); + $data = array(); $field_types = acf_get_field_types(); - + // loop - foreach( $field_types as $type ) { + foreach ( $field_types as $type ) { $data[ $type->name ] = array( - 'label' => $type->label, - 'name' => $type->name, - 'category' => $type->category, - 'public' => $type->public + 'label' => $type->label, + 'name' => $type->name, + 'category' => $type->category, + 'public' => $type->public, ); } - + // return return $data; } @@ -258,12 +263,12 @@ function acf_get_field_types_info( $args = array() ) { * * alias of acf()->fields->is_field_type() * -* @type function -* @date 31/5/17 -* @since 5.6.0 +* @type function +* @date 31/5/17 +* @since 5.6.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_is_field_type( $name = '' ) { @@ -276,17 +281,17 @@ function acf_is_field_type( $name = '' ) { * * This function will return a field type's property * -* @type function -* @date 1/10/13 -* @since 5.0.0 +* @type function +* @date 1/10/13 +* @since 5.0.0 * -* @param n/a -* @return (array) +* @param n/a +* @return (array) */ function acf_get_field_type_prop( $name = '', $prop = '' ) { $type = acf_get_field_type( $name ); - return ($type && isset($type->$prop)) ? $type->$prop : null; + return ( $type && isset( $type->$prop ) ) ? $type->$prop : null; } @@ -295,17 +300,17 @@ function acf_get_field_type_prop( $name = '', $prop = '' ) { * * This function will return the label of a field type * -* @type function -* @date 1/10/13 -* @since 5.0.0 +* @type function +* @date 1/10/13 +* @since 5.0.0 * -* @param n/a -* @return (array) +* @param n/a +* @return (array) */ function acf_get_field_type_label( $name = '' ) { $label = acf_get_field_type_prop( $name, 'label' ); - return $label ? $label : ''.__('Unknown', 'acf').''; + return $label ? $label : '' . __( 'Unknown', 'acf' ) . ''; } @@ -314,12 +319,12 @@ function acf_get_field_type_label( $name = '' ) { * * deprecated in favour of acf_is_field_type() * -* @type function -* @date 1/10/13 -* @since 5.0.0 +* @type function +* @date 1/10/13 +* @since 5.0.0 * -* @param $type (string) -* @return (boolean) +* @param $type (string) +* @return (boolean) */ function acf_field_type_exists( $type = '' ) { @@ -332,47 +337,44 @@ function acf_field_type_exists( $type = '' ) { * * Returns an multi-dimentional array of field types "name => label" grouped by category * -* @type function -* @date 1/10/13 -* @since 5.0.0 +* @type function +* @date 1/10/13 +* @since 5.0.0 * -* @param n/a -* @return (array) +* @param n/a +* @return (array) */ function acf_get_grouped_field_types() { - + // vars - $types = acf_get_field_types(); + $types = acf_get_field_types(); $groups = array(); - $l10n = array( - 'basic' => __('Basic', 'acf'), - 'content' => __('Content', 'acf'), - 'choice' => __('Choice', 'acf'), - 'relational' => __('Relational', 'acf'), - 'jquery' => __('jQuery', 'acf'), - 'layout' => __('Layout', 'acf'), + $l10n = array( + 'basic' => __( 'Basic', 'acf' ), + 'content' => __( 'Content', 'acf' ), + 'choice' => __( 'Choice', 'acf' ), + 'relational' => __( 'Relational', 'acf' ), + 'jquery' => __( 'jQuery', 'acf' ), + 'layout' => __( 'Layout', 'acf' ), ); - - + // loop - foreach( $types as $type ) { - + foreach ( $types as $type ) { + // translate $cat = $type->category; - $cat = isset( $l10n[$cat] ) ? $l10n[$cat] : $cat; - + $cat = isset( $l10n[ $cat ] ) ? $l10n[ $cat ] : $cat; + // append $groups[ $cat ][ $type->name ] = $type->label; } - - + // filter - $groups = apply_filters('acf/get_field_types', $groups); - - + $groups = apply_filters( 'acf/get_field_types', $groups ); + // return return $groups; } -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-accordion.php b/includes/fields/class-acf-field-accordion.php index e149e04..b877d8e 100644 --- a/includes/fields/class-acf-field-accordion.php +++ b/includes/fields/class-acf-field-accordion.php @@ -1,167 +1,174 @@ name = 'accordion'; - $this->label = __("Accordion",'acf'); - $this->category = 'layout'; - $this->defaults = array( - 'open' => 0, - 'multi_expand' => 0, - 'endpoint' => 0 - ); - - } - - - /** - * render_field - * - * Create the HTML interface for your field - * - * @date 30/10/17 - * @since 5.6.3 - * - * @param array $field - * @return n/a - */ - - function render_field( $field ) { - - // vars - $atts = array( - 'class' => 'acf-fields', - 'data-open' => $field['open'], - 'data-multi_expand' => $field['multi_expand'], - 'data-endpoint' => $field['endpoint'] - ); - - ?> -
                        >
                        - ' . __( 'Accordions help you organize fields into panels that open and close.', 'acf') . '

                        '; - $message .= '

                        ' . __( 'All fields following this accordion (or until another accordion is defined) will be grouped together.','acf') . '

                        '; - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Instructions','acf'), - 'instructions' => '', - 'name' => 'notes', - 'type' => 'message', - 'message' => $message, - )); -*/ - - // active - acf_render_field_setting( $field, array( - 'label' => __('Open','acf'), - 'instructions' => __('Display this accordion as open on page load.','acf'), - 'name' => 'open', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // multi_expand - acf_render_field_setting( $field, array( - 'label' => __('Multi-expand','acf'), - 'instructions' => __('Allow this accordion to open without closing others.','acf'), - 'name' => 'multi_expand', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // endpoint - acf_render_field_setting( $field, array( - 'label' => __('Endpoint','acf'), - 'instructions' => __('Define an endpoint for the previous accordion to stop. This accordion will not be visible.','acf'), - 'name' => 'endpoint', - 'type' => 'true_false', - 'ui' => 1, - )); - - } - - - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - - function load_field( $field ) { - - // remove name to avoid caching issue - $field['name'] = ''; - - // remove required to avoid JS issues - $field['required'] = 0; - - // set value other than 'null' to avoid ACF loading / caching issue - $field['value'] = false; - - // return - return $field; - - } - -} + class acf_field__accordion extends acf_field { -// initialize -acf_register_field_type( 'acf_field__accordion' ); + /** + * initialize + * + * This function will setup the field type data + * + * @date 30/10/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'accordion'; + $this->label = __( 'Accordion', 'acf' ); + $this->category = 'layout'; + $this->defaults = array( + 'open' => 0, + 'multi_expand' => 0, + 'endpoint' => 0, + ); + + } + + + /** + * render_field + * + * Create the HTML interface for your field + * + * @date 30/10/17 + * @since 5.6.3 + * + * @param array $field + * @return n/a + */ + + function render_field( $field ) { + + // vars + $atts = array( + 'class' => 'acf-fields', + 'data-open' => $field['open'], + 'data-multi_expand' => $field['multi_expand'], + 'data-endpoint' => $field['endpoint'], + ); + + ?> +
                        >
                        + ' . __( 'Accordions help you organize fields into panels that open and close.', 'acf') . '

                        '; + $message .= '

                        ' . __( 'All fields following this accordion (or until another accordion is defined) will be grouped together.','acf') . '

                        '; + + + // default_value + acf_render_field_setting( $field, array( + 'label' => __('Instructions','acf'), + 'instructions' => '', + 'name' => 'notes', + 'type' => 'message', + 'message' => $message, + )); + */ + + // active + acf_render_field_setting( + $field, + array( + 'label' => __( 'Open', 'acf' ), + 'instructions' => __( 'Display this accordion as open on page load.', 'acf' ), + 'name' => 'open', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // multi_expand + acf_render_field_setting( + $field, + array( + 'label' => __( 'Multi-expand', 'acf' ), + 'instructions' => __( 'Allow this accordion to open without closing others.', 'acf' ), + 'name' => 'multi_expand', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // endpoint + acf_render_field_setting( + $field, + array( + 'label' => __( 'Endpoint', 'acf' ), + 'instructions' => __( 'Define an endpoint for the previous accordion to stop. This accordion will not be visible.', 'acf' ), + 'name' => 'endpoint', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + + function load_field( $field ) { + + // remove name to avoid caching issue + $field['name'] = ''; + + // remove required to avoid JS issues + $field['required'] = 0; + + // set value other than 'null' to avoid ACF loading / caching issue + $field['value'] = false; + + // return + return $field; + + } + + } + + + // initialize + acf_register_field_type( 'acf_field__accordion' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-button-group.php b/includes/fields/class-acf-field-button-group.php index db1dd95..1c08337 100644 --- a/includes/fields/class-acf-field-button-group.php +++ b/includes/fields/class-acf-field-button-group.php @@ -1,292 +1,299 @@ name = 'button_group'; - $this->label = __("Button Group",'acf'); - $this->category = 'choice'; - $this->defaults = array( - 'choices' => array(), - 'default_value' => '', - 'allow_null' => 0, - 'return_format' => 'value', - 'layout' => 'horizontal', - ); - - } - - - /** - * render_field() - * - * Creates the field's input HTML - * - * @date 18/9/17 - * @since 5.6.3 - * - * @param array $field The field settings array - * @return n/a - */ - - function render_field( $field ) { - - // vars - $html = ''; - $selected = null; - $buttons = array(); - $value = esc_attr( $field['value'] ); - - - // bail ealrly if no choices - if( empty($field['choices']) ) return; - - - // buttons - foreach( $field['choices'] as $_value => $_label ) { - - // checked - $checked = ( $value === esc_attr($_value) ); - if( $checked ) $selected = true; - - - // append - $buttons[] = array( - 'name' => $field['name'], - 'value' => $_value, - 'label' => $_label, - 'checked' => $checked + class acf_field_button_group extends acf_field { + + + /** + * initialize() + * + * This function will setup the field type data + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'button_group'; + $this->label = __( 'Button Group', 'acf' ); + $this->category = 'choice'; + $this->defaults = array( + 'choices' => array(), + 'default_value' => '', + 'allow_null' => 0, + 'return_format' => 'value', + 'layout' => 'horizontal', ); - + } - - - // maybe select initial value - if( !$field['allow_null'] && $selected === null ) { - $buttons[0]['checked'] = true; - } - - - // div - $div = array( 'class' => 'acf-button-group' ); - - if( $field['layout'] == 'vertical' ) { $div['class'] .= ' -vertical'; } - if( $field['class'] ) { $div['class'] .= ' ' . $field['class']; } - if( $field['allow_null'] ) { $div['data-allow_null'] = 1; } - - - // hdden input - $html .= acf_get_hidden_input( array('name' => $field['name']) ); - - - // open - $html .= '
                        '; - - // loop - foreach( $buttons as $button ) { - + + + /** + * render_field() + * + * Creates the field's input HTML + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param array $field The field settings array + * @return n/a + */ + + function render_field( $field ) { + + // vars + $html = ''; + $selected = null; + $buttons = array(); + $value = esc_attr( $field['value'] ); + + // bail ealrly if no choices + if ( empty( $field['choices'] ) ) { + return; + } + + // buttons + foreach ( $field['choices'] as $_value => $_label ) { + // checked - if( $button['checked'] ) { + $checked = ( $value === esc_attr( $_value ) ); + if ( $checked ) { + $selected = true; + } + + // append + $buttons[] = array( + 'name' => $field['name'], + 'value' => $_value, + 'label' => $_label, + 'checked' => $checked, + ); + + } + + // maybe select initial value + if ( ! $field['allow_null'] && $selected === null ) { + $buttons[0]['checked'] = true; + } + + // div + $div = array( 'class' => 'acf-button-group' ); + + if ( $field['layout'] == 'vertical' ) { + $div['class'] .= ' -vertical'; } + if ( $field['class'] ) { + $div['class'] .= ' ' . $field['class']; } + if ( $field['allow_null'] ) { + $div['data-allow_null'] = 1; } + + // hdden input + $html .= acf_get_hidden_input( array( 'name' => $field['name'] ) ); + + // open + $html .= '
                        '; + + // loop + foreach ( $buttons as $button ) { + + // checked + if ( $button['checked'] ) { $button['checked'] = 'checked'; } else { - unset($button['checked']); + unset( $button['checked'] ); } - - + // append $html .= acf_get_radio_input( $button ); - + } - - - // close - $html .= '
                        '; - - - // return - echo $html; - - } - - - /** - * render_field_settings() - * - * Creates the field's settings HTML - * - * @date 18/9/17 - * @since 5.6.3 - * - * @param array $field The field settings array - * @return n/a - */ - - function render_field_settings( $field ) { - - // encode choices (convert from array) - $field['choices'] = acf_encode_choices($field['choices']); - - - // choices - acf_render_field_setting( $field, array( - 'label' => __('Choices','acf'), - 'instructions' => __('Enter each choice on a new line.','acf') . '

                        ' . __('For more control, you may specify both a value and label like this:','acf'). '

                        ' . __('red : Red','acf'), - 'type' => 'textarea', - 'name' => 'choices', - )); - - - // allow_null - acf_render_field_setting( $field, array( - 'label' => __('Allow Null?','acf'), - 'instructions' => '', - 'name' => 'allow_null', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'text', - 'name' => 'default_value', - )); - - - // layout - acf_render_field_setting( $field, array( - 'label' => __('Layout','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'layout', - 'layout' => 'horizontal', - 'choices' => array( - 'horizontal' => __("Horizontal",'acf'), - 'vertical' => __("Vertical",'acf'), - ) - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Value','acf'), - 'instructions' => __('Specify the returned value on front end','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'layout' => 'horizontal', - 'choices' => array( - 'value' => __('Value','acf'), - 'label' => __('Label','acf'), - 'array' => __('Both (Array)','acf') - ) - )); - - } - - - /* - * update_field() - * - * This filter is appied to the $field before it is saved to the database - * - * @date 18/9/17 - * @since 5.6.3 - * - * @param array $field The field array holding all the field options - * @return $field - */ - function update_field( $field ) { - - return acf_get_field_type('radio')->update_field( $field ); - } - - - /* - * load_value() - * - * This filter is appied to the $value after it is loaded from the db - * - * @date 18/9/17 - * @since 5.6.3 - * - * @param mixed $value The value found in the database - * @param mixed $post_id The post ID from which the value was loaded from - * @param array $field The field array holding all the field options - * @return $value - */ - - function load_value( $value, $post_id, $field ) { - - return acf_get_field_type('radio')->load_value( $value, $post_id, $field ); - - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @date 18/9/17 - * @since 5.6.3 - * - * @param array $field The field array holding all the field options - * @return $field - */ - - function translate_field( $field ) { - - return acf_get_field_type('radio')->translate_field( $field ); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @date 18/9/17 - * @since 5.6.3 - * - * @param mixed $value The value found in the database - * @param mixed $post_id The post ID from which the value was loaded from - * @param array $field The field array holding all the field options - * @return $value - */ - - function format_value( $value, $post_id, $field ) { - - return acf_get_field_type('radio')->format_value( $value, $post_id, $field ); - - } - -} + // close + $html .= '
                        '; + + // return + echo $html; + + } -// initialize -acf_register_field_type( 'acf_field_button_group' ); + /** + * render_field_settings() + * + * Creates the field's settings HTML + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param array $field The field settings array + * @return n/a + */ + + function render_field_settings( $field ) { + + // encode choices (convert from array) + $field['choices'] = acf_encode_choices( $field['choices'] ); + + // choices + acf_render_field_setting( + $field, + array( + 'label' => __( 'Choices', 'acf' ), + 'instructions' => __( 'Enter each choice on a new line.', 'acf' ) . '

                        ' . __( 'For more control, you may specify both a value and label like this:', 'acf' ) . '

                        ' . __( 'red : Red', 'acf' ), + 'type' => 'textarea', + 'name' => 'choices', + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'text', + 'name' => 'default_value', + ) + ); + + // layout + acf_render_field_setting( + $field, + array( + 'label' => __( 'Layout', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'layout', + 'layout' => 'horizontal', + 'choices' => array( + 'horizontal' => __( 'Horizontal', 'acf' ), + 'vertical' => __( 'Vertical', 'acf' ), + ), + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Value', 'acf' ), + 'instructions' => __( 'Specify the returned value on front end', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'value' => __( 'Value', 'acf' ), + 'label' => __( 'Label', 'acf' ), + 'array' => __( 'Both (Array)', 'acf' ), + ), + ) + ); + + } + + + /* + * update_field() + * + * This filter is appied to the $field before it is saved to the database + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param array $field The field array holding all the field options + * @return $field + */ + + function update_field( $field ) { + + return acf_get_field_type( 'radio' )->update_field( $field ); + } + + + /* + * load_value() + * + * This filter is appied to the $value after it is loaded from the db + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param mixed $value The value found in the database + * @param mixed $post_id The post ID from which the value was loaded from + * @param array $field The field array holding all the field options + * @return $value + */ + + function load_value( $value, $post_id, $field ) { + + return acf_get_field_type( 'radio' )->load_value( $value, $post_id, $field ); + + } + + + /* + * translate_field + * + * This function will translate field settings + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param array $field The field array holding all the field options + * @return $field + */ + + function translate_field( $field ) { + + return acf_get_field_type( 'radio' )->translate_field( $field ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @date 18/9/17 + * @since 5.6.3 + * + * @param mixed $value The value found in the database + * @param mixed $post_id The post ID from which the value was loaded from + * @param array $field The field array holding all the field options + * @return $value + */ + + function format_value( $value, $post_id, $field ) { + + return acf_get_field_type( 'radio' )->format_value( $value, $post_id, $field ); + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_button_group' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-checkbox.php b/includes/fields/class-acf-field-checkbox.php index b47b889..a167244 100644 --- a/includes/fields/class-acf-field-checkbox.php +++ b/includes/fields/class-acf-field-checkbox.php @@ -1,585 +1,575 @@ name = 'checkbox'; - $this->label = __("Checkbox",'acf'); - $this->category = 'choice'; - $this->defaults = array( - 'layout' => 'vertical', - 'choices' => array(), - 'default_value' => '', - 'allow_custom' => 0, - 'save_custom' => 0, - 'toggle' => 0, - 'return_format' => 'value' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field (array) the $field being rendered - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field (array) the $field being edited - * @return n/a - */ - - function render_field( $field ) { - - // reset vars - $this->_values = array(); - $this->_all_checked = true; - - - // ensure array - $field['value'] = acf_get_array($field['value']); - $field['choices'] = acf_get_array($field['choices']); - - - // hiden input - acf_hidden_input( array('name' => $field['name']) ); - - - // vars - $li = ''; - $ul = array( - 'class' => 'acf-checkbox-list', - ); - - - // append to class - $ul['class'] .= ' ' . ($field['layout'] == 'horizontal' ? 'acf-hl' : 'acf-bl'); - $ul['class'] .= ' ' . $field['class']; - - - // checkbox saves an array - $field['name'] .= '[]'; - - - // choices - if( !empty($field['choices']) ) { - - // choices - $li .= $this->render_field_choices( $field ); - - - // toggle - if( $field['toggle'] ) { - $li = $this->render_field_toggle( $field ) . $li; - } - - } - - - // custom - if( $field['allow_custom'] ) { - $li .= $this->render_field_custom( $field ); - } - - - // return - echo '
                          ' . "\n" . $li . '
                        ' . "\n"; - - } - - - /* - * render_field_choices - * - * description - * - * @type function - * @date 15/7/17 - * @since 5.6.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_choices( $field ) { - - // walk - return $this->walk( $field['choices'], $field ); - - } - - - /* - * render_field_toggle - * - * description - * - * @type function - * @date 15/7/17 - * @since 5.6.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_toggle( $field ) { - - // vars - $atts = array( - 'type' => 'checkbox', - 'class' => 'acf-checkbox-toggle', - 'label' => __("Toggle All", 'acf') - ); - - - // custom label - if( is_string($field['toggle']) ) { - $atts['label'] = $field['toggle']; - } - - - // checked - if( $this->_all_checked ) { - $atts['checked'] = 'checked'; - } - - - // return - return '
                      1. ' . acf_get_checkbox_input($atts) . '
                      2. ' . "\n"; - - } - - - /* - * render_field_custom - * - * description - * - * @type function - * @date 15/7/17 - * @since 5.6.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_custom( $field ) { - - // vars - $html = ''; - - - // loop - foreach( $field['value'] as $value ) { - - // ignore if already eixsts - if( isset($field['choices'][ $value ]) ) continue; - - // vars - $esc_value = esc_attr($value); - $text_input = array( - 'name' => $field['name'], - 'value' => $value, + $this->name = 'checkbox'; + $this->label = __( 'Checkbox', 'acf' ); + $this->category = 'choice'; + $this->defaults = array( + 'layout' => 'vertical', + 'choices' => array(), + 'default_value' => '', + 'allow_custom' => 0, + 'save_custom' => 0, + 'toggle' => 0, + 'return_format' => 'value', ); - - - // bail ealry if choice already exists - if( in_array( $esc_value, $this->_values ) ) continue; - - - // append - $html .= '
                      3. ' . acf_get_text_input($text_input) . '
                      4. ' . "\n"; - - } - - - // append button - $html .= '
                      5. ' . esc_attr__('Add new choice', 'acf') . '
                      6. ' . "\n"; - - - // return - return $html; - - } - - - function walk( $choices = array(), $args = array(), $depth = 0 ) { - - // bail ealry if no choices - if( empty($choices) ) return ''; - - - // defaults - $args = wp_parse_args($args, array( - 'id' => '', - 'type' => 'checkbox', - 'name' => '', - 'value' => array(), - 'disabled' => array(), - )); - - - // vars - $html = ''; - - - // sanitize values for 'selected' matching - if( $depth == 0 ) { - $args['value'] = array_map('esc_attr', $args['value']); - $args['disabled'] = array_map('esc_attr', $args['disabled']); - } - - - // loop - foreach( $choices as $value => $label ) { - - // open - $html .= '
                      7. '; - - - // optgroup - if( is_array($label) ){ - - $html .= '
                          ' . "\n"; - $html .= $this->walk( $label, $args, $depth+1 ); - $html .= '
                        '; - - // option - } else { - - // vars - $esc_value = esc_attr($value); - $atts = array( - 'id' => $args['id'] . '-' . str_replace(' ', '-', $value), - 'type' => $args['type'], - 'name' => $args['name'], - 'value' => $value, - 'label' => $label, - ); - - - // selected - if( in_array( $esc_value, $args['value'] ) ) { - $atts['checked'] = 'checked'; - } else { - $this->_all_checked = false; - } - - - // disabled - if( in_array( $esc_value, $args['disabled'] ) ) { - $atts['disabled'] = 'disabled'; - } - - - // store value added - $this->_values[] = $esc_value; - - - // append - $html .= acf_get_checkbox_input($atts); - - } - - - // close - $html .= '
                      8. ' . "\n"; - - } - - - // return - return $html; - - } - - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // encode choices (convert from array) - $field['choices'] = acf_encode_choices($field['choices']); - $field['default_value'] = acf_encode_choices($field['default_value'], false); - - - // choices - acf_render_field_setting( $field, array( - 'label' => __('Choices','acf'), - 'instructions' => __('Enter each choice on a new line.','acf') . '

                        ' . __('For more control, you may specify both a value and label like this:','acf'). '

                        ' . __('red : Red','acf'), - 'type' => 'textarea', - 'name' => 'choices', - )); - - - // other_choice - acf_render_field_setting( $field, array( - 'label' => __('Allow Custom','acf'), - 'instructions' => '', - 'name' => 'allow_custom', - 'type' => 'true_false', - 'ui' => 1, - 'message' => __("Allow 'custom' values to be added", 'acf'), - )); - - - // save_other_choice - acf_render_field_setting( $field, array( - 'label' => __('Save Custom','acf'), - 'instructions' => '', - 'name' => 'save_custom', - 'type' => 'true_false', - 'ui' => 1, - 'message' => __("Save 'custom' values to the field's choices", 'acf'), - 'conditions' => array( - 'field' => 'allow_custom', - 'operator' => '==', - 'value' => 1 - ) - )); - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Enter each default value on a new line','acf'), - 'type' => 'textarea', - 'name' => 'default_value', - )); - - - // layout - acf_render_field_setting( $field, array( - 'label' => __('Layout','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'layout', - 'layout' => 'horizontal', - 'choices' => array( - 'vertical' => __("Vertical",'acf'), - 'horizontal' => __("Horizontal",'acf') - ) - )); - - - // layout - acf_render_field_setting( $field, array( - 'label' => __('Toggle','acf'), - 'instructions' => __('Prepend an extra checkbox to toggle all choices','acf'), - 'name' => 'toggle', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Value','acf'), - 'instructions' => __('Specify the returned value on front end','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'layout' => 'horizontal', - 'choices' => array( - 'value' => __('Value','acf'), - 'label' => __('Label','acf'), - 'array' => __('Both (Array)','acf') - ) - )); - - } - - - /* - * update_field() - * - * This filter is appied to the $field before it is saved to the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * @param $post_id - the field group ID (post_type = acf) - * - * @return $field - the modified field - */ - function update_field( $field ) { - - // Decode choices (convert to array). - $field['choices'] = acf_decode_choices( $field['choices'] ); - $field['default_value'] = acf_decode_choices( $field['default_value'], true ); - return $field; - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // bail early if is empty - if( empty($value) ) return $value; - - - // select -> update_value() - $value = acf_get_field_type('select')->update_value( $value, $post_id, $field ); - - - // save_other_choice - if( $field['save_custom'] ) { - - // get raw $field (may have been changed via repeater field) - // if field is local, it won't have an ID - $selector = $field['ID'] ? $field['ID'] : $field['key']; - $field = acf_get_field( $selector ); - if( !$field ) { - return false; + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field (array) the $field being rendered + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field (array) the $field being edited + * @return n/a + */ + + function render_field( $field ) { + + // reset vars + $this->_values = array(); + $this->_all_checked = true; + + // ensure array + $field['value'] = acf_get_array( $field['value'] ); + $field['choices'] = acf_get_array( $field['choices'] ); + + // hiden input + acf_hidden_input( array( 'name' => $field['name'] ) ); + + // vars + $li = ''; + $ul = array( + 'class' => 'acf-checkbox-list', + ); + + // append to class + $ul['class'] .= ' ' . ( $field['layout'] == 'horizontal' ? 'acf-hl' : 'acf-bl' ); + $ul['class'] .= ' ' . $field['class']; + + // checkbox saves an array + $field['name'] .= '[]'; + + // choices + if ( ! empty( $field['choices'] ) ) { + + // choices + $li .= $this->render_field_choices( $field ); + + // toggle + if ( $field['toggle'] ) { + $li = $this->render_field_toggle( $field ) . $li; + } } - - - // bail early if no ID (JSON only) - if( !$field['ID'] ) return $value; - - + + // custom + if ( $field['allow_custom'] ) { + $li .= $this->render_field_custom( $field ); + } + + // return + echo '
                          ' . "\n" . $li . '
                        ' . "\n"; + + } + + + /* + * render_field_choices + * + * description + * + * @type function + * @date 15/7/17 + * @since 5.6.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_choices( $field ) { + + // walk + return $this->walk( $field['choices'], $field ); + + } + + + /* + * render_field_toggle + * + * description + * + * @type function + * @date 15/7/17 + * @since 5.6.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_toggle( $field ) { + + // vars + $atts = array( + 'type' => 'checkbox', + 'class' => 'acf-checkbox-toggle', + 'label' => __( 'Toggle All', 'acf' ), + ); + + // custom label + if ( is_string( $field['toggle'] ) ) { + $atts['label'] = $field['toggle']; + } + + // checked + if ( $this->_all_checked ) { + $atts['checked'] = 'checked'; + } + + // return + return '
                      9. ' . acf_get_checkbox_input( $atts ) . '
                      10. ' . "\n"; + + } + + + /* + * render_field_custom + * + * description + * + * @type function + * @date 15/7/17 + * @since 5.6.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_custom( $field ) { + + // vars + $html = ''; + // loop - foreach( $value as $v ) { - + foreach ( $field['value'] as $value ) { + // ignore if already eixsts - if( isset($field['choices'][ $v ]) ) continue; - - - // unslash (fixes serialize single quote issue) - $v = wp_unslash($v); - - - // sanitize (remove tags) - $v = sanitize_text_field($v); - - + if ( isset( $field['choices'][ $value ] ) ) { + continue; + } + + // vars + $esc_value = esc_attr( $value ); + $text_input = array( + 'name' => $field['name'], + 'value' => $value, + ); + + // bail ealry if choice already exists + if ( in_array( $esc_value, $this->_values ) ) { + continue; + } + // append - $field['choices'][ $v ] = $v; - + $html .= '
                      11. ' . acf_get_text_input( $text_input ) . '
                      12. ' . "\n"; + } - - - // save - acf_update_field( $field ); - - } - - - // return - return $value; - - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @type function - * @date 8/03/2016 - * @since 5.3.2 - * - * @param $field (array) - * @return $field - */ - - function translate_field( $field ) { - - return acf_get_field_type('select')->translate_field( $field ); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // Bail early if is empty. - if( acf_is_empty($value) ) { - return array(); + + // append button + $html .= '
                      13. ' . esc_attr__( 'Add new choice', 'acf' ) . '
                      14. ' . "\n"; + + // return + return $html; + } - - // Always convert to array of items. - $value = acf_array($value); - - // Return. - return acf_get_field_type('select')->format_value( $value, $post_id, $field ); + + + function walk( $choices = array(), $args = array(), $depth = 0 ) { + + // bail ealry if no choices + if ( empty( $choices ) ) { + return ''; + } + + // defaults + $args = wp_parse_args( + $args, + array( + 'id' => '', + 'type' => 'checkbox', + 'name' => '', + 'value' => array(), + 'disabled' => array(), + ) + ); + + // vars + $html = ''; + + // sanitize values for 'selected' matching + if ( $depth == 0 ) { + $args['value'] = array_map( 'esc_attr', $args['value'] ); + $args['disabled'] = array_map( 'esc_attr', $args['disabled'] ); + } + + // loop + foreach ( $choices as $value => $label ) { + + // open + $html .= '
                      15. '; + + // optgroup + if ( is_array( $label ) ) { + + $html .= '
                          ' . "\n"; + $html .= $this->walk( $label, $args, $depth + 1 ); + $html .= '
                        '; + + // option + } else { + + // vars + $esc_value = esc_attr( $value ); + $atts = array( + 'id' => $args['id'] . '-' . str_replace( ' ', '-', $value ), + 'type' => $args['type'], + 'name' => $args['name'], + 'value' => $value, + 'label' => $label, + ); + + // selected + if ( in_array( $esc_value, $args['value'] ) ) { + $atts['checked'] = 'checked'; + } else { + $this->_all_checked = false; + } + + // disabled + if ( in_array( $esc_value, $args['disabled'] ) ) { + $atts['disabled'] = 'disabled'; + } + + // store value added + $this->_values[] = $esc_value; + + // append + $html .= acf_get_checkbox_input( $atts ); + + } + + // close + $html .= '
                      16. ' . "\n"; + + } + + // return + return $html; + + } + + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // encode choices (convert from array) + $field['choices'] = acf_encode_choices( $field['choices'] ); + $field['default_value'] = acf_encode_choices( $field['default_value'], false ); + + // choices + acf_render_field_setting( + $field, + array( + 'label' => __( 'Choices', 'acf' ), + 'instructions' => __( 'Enter each choice on a new line.', 'acf' ) . '

                        ' . __( 'For more control, you may specify both a value and label like this:', 'acf' ) . '

                        ' . __( 'red : Red', 'acf' ), + 'type' => 'textarea', + 'name' => 'choices', + ) + ); + + // other_choice + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Custom', 'acf' ), + 'instructions' => '', + 'name' => 'allow_custom', + 'type' => 'true_false', + 'ui' => 1, + 'message' => __( "Allow 'custom' values to be added", 'acf' ), + ) + ); + + // save_other_choice + acf_render_field_setting( + $field, + array( + 'label' => __( 'Save Custom', 'acf' ), + 'instructions' => '', + 'name' => 'save_custom', + 'type' => 'true_false', + 'ui' => 1, + 'message' => __( "Save 'custom' values to the field's choices", 'acf' ), + 'conditions' => array( + 'field' => 'allow_custom', + 'operator' => '==', + 'value' => 1, + ), + ) + ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Enter each default value on a new line', 'acf' ), + 'type' => 'textarea', + 'name' => 'default_value', + ) + ); + + // layout + acf_render_field_setting( + $field, + array( + 'label' => __( 'Layout', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'layout', + 'layout' => 'horizontal', + 'choices' => array( + 'vertical' => __( 'Vertical', 'acf' ), + 'horizontal' => __( 'Horizontal', 'acf' ), + ), + ) + ); + + // layout + acf_render_field_setting( + $field, + array( + 'label' => __( 'Toggle', 'acf' ), + 'instructions' => __( 'Prepend an extra checkbox to toggle all choices', 'acf' ), + 'name' => 'toggle', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Value', 'acf' ), + 'instructions' => __( 'Specify the returned value on front end', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'value' => __( 'Value', 'acf' ), + 'label' => __( 'Label', 'acf' ), + 'array' => __( 'Both (Array)', 'acf' ), + ), + ) + ); + + } + + + /* + * update_field() + * + * This filter is appied to the $field before it is saved to the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * @param $post_id - the field group ID (post_type = acf) + * + * @return $field - the modified field + */ + + function update_field( $field ) { + + // Decode choices (convert to array). + $field['choices'] = acf_decode_choices( $field['choices'] ); + $field['default_value'] = acf_decode_choices( $field['default_value'], true ); + return $field; + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // bail early if is empty + if ( empty( $value ) ) { + return $value; + } + + // select -> update_value() + $value = acf_get_field_type( 'select' )->update_value( $value, $post_id, $field ); + + // save_other_choice + if ( $field['save_custom'] ) { + + // get raw $field (may have been changed via repeater field) + // if field is local, it won't have an ID + $selector = $field['ID'] ? $field['ID'] : $field['key']; + $field = acf_get_field( $selector ); + if ( ! $field ) { + return false; + } + + // bail early if no ID (JSON only) + if ( ! $field['ID'] ) { + return $value; + } + + // loop + foreach ( $value as $v ) { + + // ignore if already eixsts + if ( isset( $field['choices'][ $v ] ) ) { + continue; + } + + // unslash (fixes serialize single quote issue) + $v = wp_unslash( $v ); + + // sanitize (remove tags) + $v = sanitize_text_field( $v ); + + // append + $field['choices'][ $v ] = $v; + + } + + // save + acf_update_field( $field ); + + } + + // return + return $value; + + } + + + /* + * translate_field + * + * This function will translate field settings + * + * @type function + * @date 8/03/2016 + * @since 5.3.2 + * + * @param $field (array) + * @return $field + */ + + function translate_field( $field ) { + + return acf_get_field_type( 'select' )->translate_field( $field ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // Bail early if is empty. + if ( acf_is_empty( $value ) ) { + return array(); + } + + // Always convert to array of items. + $value = acf_array( $value ); + + // Return. + return acf_get_field_type( 'select' )->format_value( $value, $post_id, $field ); + } + } - -} -// initialize -acf_register_field_type( 'acf_field_checkbox' ); + // initialize + acf_register_field_type( 'acf_field_checkbox' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-color_picker.php b/includes/fields/class-acf-field-color_picker.php index 9b4fcc6..4ffa555 100644 --- a/includes/fields/class-acf-field-color_picker.php +++ b/includes/fields/class-acf-field-color_picker.php @@ -1,144 +1,296 @@ name = 'color_picker'; - $this->label = __("Color Picker",'acf'); - $this->category = 'jquery'; - $this->defaults = array( - 'default_value' => '', - ); - - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { + class acf_field_color_picker extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'color_picker'; + $this->label = __( 'Color Picker', 'acf' ); + $this->category = 'jquery'; + $this->defaults = array( + 'default_value' => '', + 'enable_opacity' => false, + 'return_format' => 'string', // 'string'|'array' + ); - // Register scripts for non-admin. - // Applies logic from wp_default_scripts() function defined in "wp-includes/script-loader.php". - if( !is_admin() ) { - $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - $scripts = wp_scripts(); - $scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.0.7', 1 ); - $scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 ); - - // Handle localisation across multiple WP versions. - // WP 5.0+ - if( method_exists($scripts, 'set_translations') ) { - $scripts->set_translations( 'wp-color-picker' ); - // WP 4.9 - } else { - $scripts->localize( 'wp-color-picker', 'wpColorPickerL10n', array( - 'clear' => __( 'Clear' ), - 'clearAriaLabel' => __( 'Clear color' ), - 'defaultString' => __( 'Default' ), - 'defaultAriaLabel' => __( 'Select default color' ), - 'pick' => __( 'Select Color' ), - 'defaultLabel' => __( 'Color value' ), - )); - } - } - - // Enqueue. - wp_enqueue_style( 'wp-color-picker' ); - wp_enqueue_script( 'wp-color-picker' ); - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $text_input = acf_get_sub_array( $field, array('id', 'class', 'name', 'value') ); - $hidden_input = acf_get_sub_array( $field, array('name', 'value') ); - - - // html - ?> + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // Register scripts for non-admin. + // Applies logic from wp_default_scripts() function defined in "wp-includes/script-loader.php". + if ( ! is_admin() ) { + $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + $scripts = wp_scripts(); + $scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.0.7', 1 ); + $scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 ); + + // Handle localisation across multiple WP versions. + // WP 5.0+ + if ( method_exists( $scripts, 'set_translations' ) ) { + $scripts->set_translations( 'wp-color-picker' ); + // WP 4.9 + } else { + $scripts->localize( + 'wp-color-picker', + 'wpColorPickerL10n', + array( + 'clear' => __( 'Clear' ), + 'clearAriaLabel' => __( 'Clear color' ), + 'defaultString' => __( 'Default' ), + 'defaultAriaLabel' => __( 'Select default color' ), + 'pick' => __( 'Select Color' ), + 'defaultLabel' => __( 'Color value' ), + ) + ); + } + } + + // Enqueue alpha color picker assets. + wp_enqueue_script( + 'acf-color-picker-alpha', + acf_get_url( 'assets/inc/color-picker-alpha/wp-color-picker-alpha.js' ), + array( 'jquery', 'wp-color-picker' ), + '3.0.0' + ); + + // Enqueue. + wp_enqueue_style( 'wp-color-picker' ); + wp_enqueue_script( 'wp-color-picker' ); + + acf_localize_data( + array( + 'colorPickerL10n' => array( + 'hex_string' => __( 'Hex String', 'acf' ), + 'rgba_string' => __( 'RGBA String', 'acf' ), + ), + ) + ); + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $text_input = acf_get_sub_array( $field, array( 'id', 'class', 'name', 'value' ) ); + $hidden_input = acf_get_sub_array( $field, array( 'name', 'value' ) ); + + // Color picker alpha library requires a specific data attribute to exist. + if ( $field['enable_opacity'] ) { + $text_input['data-alpha-enabled'] = true; + } + + // html + ?>
                        - __('Default Value','acf'), - 'instructions' => '', - 'type' => 'text', - 'name' => 'default_value', - 'placeholder' => '#FFFFFF' - )); - - } - -} + __( 'Default Value', 'acf' ), + 'instructions' => '', + 'type' => 'text', + 'name' => 'default_value', + 'placeholder' => '#FFFFFF', + ) + ); + + // Toggle opacity control. + acf_render_field_setting( + $field, + array( + 'label' => __( 'Enable Transparency', 'acf' ), + 'instructions' => '', + 'type' => 'true_false', + 'name' => 'enable_opacity', + 'ui' => 1, + ) + ); + + // Return format control. + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'string' => __( 'Hex String', 'acf' ), + 'array' => __( 'RGBA Array', 'acf' ), + ), + ) + ); + + } + + /** + * Format the value for use in templates. At this stage, the value has been loaded from the + * database and is being returned by an API function such as get_field(), the_field(), etc. + * + * @since 5.10 + * @date 15/12/20 + * + * @param mixed $value + * @param int $post_id + * @param array $field + * + * @return string|array + */ + public function format_value( $value, $post_id, $field ) { + if ( isset( $field['return_format'] ) && $field['return_format'] === 'array' ) { + $value = $this->string_to_array( $value ); + } + + return $value; + } + + /** + * Convert either a Hexadecimal or RGBA string to an RGBA array. + * + * @since 5.10 + * @date 15/12/20 + * + * @param string $value + * @return array + */ + private function string_to_array( $value ) { + // Trim Value + $value = trim( $value ); + + // Match and collect r,g,b values from 6 digit hex code. If there are 4 + // match-results, we have the values we need to build an r,g,b,a array. + preg_match( '/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i', $value, $matches ); + if ( count( $matches ) === 4 ) { + return array( + 'red' => hexdec( $matches[1] ), + 'green' => hexdec( $matches[2] ), + 'blue' => hexdec( $matches[3] ), + 'alpha' => (float) 1, + ); + } + + // Match and collect r,g,b values from 3 digit hex code. If there are 4 + // match-results, we have the values we need to build an r,g,b,a array. + // We have to duplicate the matched hex digit for 3 digit hex codes. + preg_match( '/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i', $value, $matches ); + if ( count( $matches ) === 4 ) { + return array( + 'red' => hexdec( $matches[1] . $matches[1] ), + 'green' => hexdec( $matches[2] . $matches[2] ), + 'blue' => hexdec( $matches[3] . $matches[3] ), + 'alpha' => (float) 1, + ); + } + + // Attempt to match an rgba(…) or rgb(…) string (case-insensitive), capturing the decimals + // as a string. If there are two match results, we have the RGBA decimal values as a + // comma-separated string. Break it apart and, depending on the number of values, return + // our formatted r,g,b,a array. + preg_match( '/^rgba?\(([0-9,.]+)\)/i', $value, $matches ); + if ( count( $matches ) === 2 ) { + $decimals = explode( ',', $matches[1] ); + + // Handle rgba() format. + if ( count( $decimals ) === 4 ) { + return array( + 'red' => (int) $decimals[0], + 'green' => (int) $decimals[1], + 'blue' => (int) $decimals[2], + 'alpha' => (float) $decimals[3], + ); + } + + // Handle rgb() format. + if ( count( $decimals ) === 3 ) { + return array( + 'red' => (int) $decimals[0], + 'green' => (int) $decimals[1], + 'blue' => (int) $decimals[2], + 'alpha' => (float) 1, + ); + } + } + + return array( + 'red' => 0, + 'green' => 0, + 'blue' => 0, + 'alpha' => (float) 0, + ); + } + + } + + // initialize + acf_register_field_type( 'acf_field_color_picker' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-date_picker.php b/includes/fields/class-acf-field-date_picker.php index a8feaf6..66be9e4 100644 --- a/includes/fields/class-acf-field-date_picker.php +++ b/includes/fields/class-acf-field-date_picker.php @@ -1,277 +1,286 @@ name = 'date_picker'; - $this->label = __("Date Picker",'acf'); - $this->category = 'jquery'; - $this->defaults = array( - 'display_format' => 'd/m/Y', - 'return_format' => 'd/m/Y', - 'first_day' => 1 - ); - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // bail ealry if no enqueue - if( !acf_get_setting('enqueue_datepicker') ) { - return; - } - - // localize - global $wp_locale; - acf_localize_data(array( - 'datePickerL10n' => array( - 'closeText' => _x('Done', 'Date Picker JS closeText', 'acf'), - 'currentText' => _x('Today', 'Date Picker JS currentText', 'acf'), - 'nextText' => _x('Next', 'Date Picker JS nextText', 'acf'), - 'prevText' => _x('Prev', 'Date Picker JS prevText', 'acf'), - 'weekHeader' => _x('Wk', 'Date Picker JS weekHeader', 'acf'), - 'monthNames' => array_values( $wp_locale->month ), - 'monthNamesShort' => array_values( $wp_locale->month_abbrev ), - 'dayNames' => array_values( $wp_locale->weekday ), - 'dayNamesMin' => array_values( $wp_locale->weekday_initial ), - 'dayNamesShort' => array_values( $wp_locale->weekday_abbrev ) - ) - )); - - // script - wp_enqueue_script('jquery-ui-datepicker'); - - // style - wp_enqueue_style('acf-datepicker', acf_get_url('assets/inc/datepicker/jquery-ui.min.css'), array(), '1.11.4' ); - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $hidden_value = ''; - $display_value = ''; - - // format value - if( $field['value'] ) { - $hidden_value = acf_format_date( $field['value'], 'Ymd' ); - $display_value = acf_format_date( $field['value'], $field['display_format'] ); + class acf_field_date_picker extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'date_picker'; + $this->label = __( 'Date Picker', 'acf' ); + $this->category = 'jquery'; + $this->defaults = array( + 'display_format' => 'd/m/Y', + 'return_format' => 'd/m/Y', + 'first_day' => 1, + ); } - - // elements - $div = array( - 'class' => 'acf-date-picker acf-input-wrap', - 'data-date_format' => acf_convert_date_to_js($field['display_format']), - 'data-first_day' => $field['first_day'], - ); - $hidden_input = array( - 'id' => $field['id'], - 'name' => $field['name'], - 'value' => $hidden_value, - ); - $text_input = array( - 'class' => 'input', - 'value' => $display_value, - ); - - // special attributes - foreach( array( 'readonly', 'disabled' ) as $k ) { - if( !empty($field[ $k ]) ) { - $hidden_input[ $k ] = $k; - $text_input[ $k ] = $k; + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // bail ealry if no enqueue + if ( ! acf_get_setting( 'enqueue_datepicker' ) ) { + return; } + + // localize + global $wp_locale; + acf_localize_data( + array( + 'datePickerL10n' => array( + 'closeText' => _x( 'Done', 'Date Picker JS closeText', 'acf' ), + 'currentText' => _x( 'Today', 'Date Picker JS currentText', 'acf' ), + 'nextText' => _x( 'Next', 'Date Picker JS nextText', 'acf' ), + 'prevText' => _x( 'Prev', 'Date Picker JS prevText', 'acf' ), + 'weekHeader' => _x( 'Wk', 'Date Picker JS weekHeader', 'acf' ), + 'monthNames' => array_values( $wp_locale->month ), + 'monthNamesShort' => array_values( $wp_locale->month_abbrev ), + 'dayNames' => array_values( $wp_locale->weekday ), + 'dayNamesMin' => array_values( $wp_locale->weekday_initial ), + 'dayNamesShort' => array_values( $wp_locale->weekday_abbrev ), + ), + ) + ); + + // script + wp_enqueue_script( 'jquery-ui-datepicker' ); + + // style + wp_enqueue_style( 'acf-datepicker', acf_get_url( 'assets/inc/datepicker/jquery-ui.min.css' ), array(), '1.11.4' ); } - - // save_format - compatibility with ACF < 5.0.0 - if( !empty($field['save_format']) ) { - - // add custom JS save format - $div['data-save_format'] = $field['save_format']; - - // revert hidden input value to raw DB value - $hidden_input['value'] = $field['value']; - - // remove formatted value (will do this via JS) - $text_input['value'] = ''; - } - - // html - ?> + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $hidden_value = ''; + $display_value = ''; + + // format value + if ( $field['value'] ) { + $hidden_value = acf_format_date( $field['value'], 'Ymd' ); + $display_value = acf_format_date( $field['value'], $field['display_format'] ); + } + + // elements + $div = array( + 'class' => 'acf-date-picker acf-input-wrap', + 'data-date_format' => acf_convert_date_to_js( $field['display_format'] ), + 'data-first_day' => $field['first_day'], + ); + $hidden_input = array( + 'id' => $field['id'], + 'name' => $field['name'], + 'value' => $hidden_value, + ); + $text_input = array( + 'class' => 'input', + 'value' => $display_value, + ); + + // special attributes + foreach ( array( 'readonly', 'disabled' ) as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $hidden_input[ $k ] = $k; + $text_input[ $k ] = $k; + } + } + + // save_format - compatibility with ACF < 5.0.0 + if ( ! empty( $field['save_format'] ) ) { + + // add custom JS save format + $div['data-save_format'] = $field['save_format']; + + // revert hidden input value to raw DB value + $hidden_input['value'] = $field['value']; + + // remove formatted value (will do this via JS) + $text_input['value'] = ''; + } + + // html + ?>
                        >
                        - __('Display Format','acf'), - 'instructions' => __('The format displayed when editing a post','acf'), - 'type' => 'radio', - 'name' => 'display_format', - 'other_choice' => 1, - 'choices' => array( - 'd/m/Y' => '' . $d_m_Y . 'd/m/Y', - 'm/d/Y' => '' . $m_d_Y . 'm/d/Y', - 'F j, Y' => '' . $F_j_Y . 'F j, Y', - 'other' => '' . __('Custom:','acf') . '' - ) - )); - - - // save_format - compatibility with ACF < 5.0.0 - if( !empty($field['save_format']) ) { - - // save_format - acf_render_field_setting( $field, array( - 'label' => __('Save Format','acf'), - 'instructions' => __('The format used when saving a value','acf'), - 'type' => 'text', - 'name' => 'save_format', - //'readonly' => 1 // this setting was not readonly in v4 - )); - - } else { - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => __('The format returned via template functions','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'other_choice' => 1, - 'choices' => array( - 'd/m/Y' => '' . $d_m_Y . 'd/m/Y', - 'm/d/Y' => '' . $m_d_Y . 'm/d/Y', - 'F j, Y' => '' . $F_j_Y . 'F j, Y', - 'Ymd' => '' . $Ymd . 'Ymd', - 'other' => '' . __('Custom:','acf') . '' + __( 'Display Format', 'acf' ), + 'instructions' => __( 'The format displayed when editing a post', 'acf' ), + 'type' => 'radio', + 'name' => 'display_format', + 'other_choice' => 1, + 'choices' => array( + 'd/m/Y' => '' . $d_m_Y . 'd/m/Y', + 'm/d/Y' => '' . $m_d_Y . 'm/d/Y', + 'F j, Y' => '' . $F_j_Y . 'F j, Y', + 'other' => '' . __( 'Custom:', 'acf' ) . '', + ), ) - )); - + ); + + // save_format - compatibility with ACF < 5.0.0 + if ( ! empty( $field['save_format'] ) ) { + + // save_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Save Format', 'acf' ), + 'instructions' => __( 'The format used when saving a value', 'acf' ), + 'type' => 'text', + 'name' => 'save_format', + // 'readonly' => 1 // this setting was not readonly in v4 + ) + ); + + } else { + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => __( 'The format returned via template functions', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'other_choice' => 1, + 'choices' => array( + 'd/m/Y' => '' . $d_m_Y . 'd/m/Y', + 'm/d/Y' => '' . $m_d_Y . 'm/d/Y', + 'F j, Y' => '' . $F_j_Y . 'F j, Y', + 'Ymd' => '' . $Ymd . 'Ymd', + 'other' => '' . __( 'Custom:', 'acf' ) . '', + ), + ) + ); + + } + + // first_day + acf_render_field_setting( + $field, + array( + 'label' => __( 'Week Starts On', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'first_day', + 'choices' => array_values( $wp_locale->weekday ), + ) + ); + } - - - // first_day - acf_render_field_setting( $field, array( - 'label' => __('Week Starts On','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'first_day', - 'choices' => array_values( $wp_locale->weekday ) - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // save_format - compatibility with ACF < 5.0.0 - if( !empty($field['save_format']) ) { - - return $value; - - } - - - // return - return acf_format_date( $value, $field['return_format'] ); - - } - -} -// initialize -acf_register_field_type( 'acf_field_date_picker' ); + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // save_format - compatibility with ACF < 5.0.0 + if ( ! empty( $field['save_format'] ) ) { + + return $value; + + } + + // return + return acf_format_date( $value, $field['return_format'] ); + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_date_picker' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-date_time_picker.php b/includes/fields/class-acf-field-date_time_picker.php index 4113955..33801b7 100644 --- a/includes/fields/class-acf-field-date_time_picker.php +++ b/includes/fields/class-acf-field-date_time_picker.php @@ -1,255 +1,261 @@ name = 'date_time_picker'; - $this->label = __("Date Time Picker",'acf'); - $this->category = 'jquery'; - $this->defaults = array( - 'display_format' => 'd/m/Y g:i a', - 'return_format' => 'd/m/Y g:i a', - 'first_day' => 1 - ); - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // bail ealry if no enqueue - if( !acf_get_setting('enqueue_datetimepicker') ) return; - - - // vars - $version = '1.6.1'; - - - // script - wp_enqueue_script('acf-timepicker', acf_get_url('assets/inc/timepicker/jquery-ui-timepicker-addon.min.js'), array('jquery-ui-datepicker'), $version); - - - // style - wp_enqueue_style('acf-timepicker', acf_get_url('assets/inc/timepicker/jquery-ui-timepicker-addon.min.css'), '', $version); - - // localize - acf_localize_data(array( - 'dateTimePickerL10n' => array( - 'timeOnlyTitle' => _x('Choose Time', 'Date Time Picker JS timeOnlyTitle', 'acf'), - 'timeText' => _x('Time', 'Date Time Picker JS timeText', 'acf'), - 'hourText' => _x('Hour', 'Date Time Picker JS hourText', 'acf'), - 'minuteText' => _x('Minute', 'Date Time Picker JS minuteText', 'acf'), - 'secondText' => _x('Second', 'Date Time Picker JS secondText', 'acf'), - 'millisecText' => _x('Millisecond', 'Date Time Picker JS millisecText', 'acf'), - 'microsecText' => _x('Microsecond', 'Date Time Picker JS microsecText', 'acf'), - 'timezoneText' => _x('Time Zone', 'Date Time Picker JS timezoneText', 'acf'), - 'currentText' => _x('Now', 'Date Time Picker JS currentText', 'acf'), - 'closeText' => _x('Done', 'Date Time Picker JS closeText', 'acf'), - 'selectText' => _x('Select', 'Date Time Picker JS selectText', 'acf'), - 'amNames' => array( - _x('AM', 'Date Time Picker JS amText', 'acf'), - _x('A', 'Date Time Picker JS amTextShort', 'acf'), - ), - 'pmNames' => array( - _x('PM', 'Date Time Picker JS pmText', 'acf'), - _x('P', 'Date Time Picker JS pmTextShort', 'acf'), - ) - ) - )); - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // Set value. - $hidden_value = ''; - $display_value = ''; - - if( $field['value'] ) { - $hidden_value = acf_format_date( $field['value'], 'Y-m-d H:i:s' ); - $display_value = acf_format_date( $field['value'], $field['display_format'] ); + class acf_field_date_and_time_picker extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'date_time_picker'; + $this->label = __( 'Date Time Picker', 'acf' ); + $this->category = 'jquery'; + $this->defaults = array( + 'display_format' => 'd/m/Y g:i a', + 'return_format' => 'd/m/Y g:i a', + 'first_day' => 1, + ); } - - // Convert "display_format" setting to individual date and time formats. - $formats = acf_split_date_time( $field['display_format'] ); - - // Elements. - $div = array( - 'class' => 'acf-date-time-picker acf-input-wrap', - 'data-date_format' => acf_convert_date_to_js($formats['date']), - 'data-time_format' => acf_convert_time_to_js($formats['time']), - 'data-first_day' => $field['first_day'], - ); - $hidden_input = array( - 'id' => $field['id'], - 'class' => 'input-alt', - 'name' => $field['name'], - 'value' => $hidden_value, - ); - $text_input = array( - 'class' => 'input', - 'value' => $display_value, - ); - foreach( array( 'readonly', 'disabled' ) as $k ) { - if( !empty($field[ $k ]) ) { - $hidden_input[ $k ] = $k; - $text_input[ $k ] = $k; + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // bail ealry if no enqueue + if ( ! acf_get_setting( 'enqueue_datetimepicker' ) ) { + return; } + + // vars + $version = '1.6.1'; + + // script + wp_enqueue_script( 'acf-timepicker', acf_get_url( 'assets/inc/timepicker/jquery-ui-timepicker-addon.min.js' ), array( 'jquery-ui-datepicker' ), $version ); + + // style + wp_enqueue_style( 'acf-timepicker', acf_get_url( 'assets/inc/timepicker/jquery-ui-timepicker-addon.min.css' ), '', $version ); + + // localize + acf_localize_data( + array( + 'dateTimePickerL10n' => array( + 'timeOnlyTitle' => _x( 'Choose Time', 'Date Time Picker JS timeOnlyTitle', 'acf' ), + 'timeText' => _x( 'Time', 'Date Time Picker JS timeText', 'acf' ), + 'hourText' => _x( 'Hour', 'Date Time Picker JS hourText', 'acf' ), + 'minuteText' => _x( 'Minute', 'Date Time Picker JS minuteText', 'acf' ), + 'secondText' => _x( 'Second', 'Date Time Picker JS secondText', 'acf' ), + 'millisecText' => _x( 'Millisecond', 'Date Time Picker JS millisecText', 'acf' ), + 'microsecText' => _x( 'Microsecond', 'Date Time Picker JS microsecText', 'acf' ), + 'timezoneText' => _x( 'Time Zone', 'Date Time Picker JS timezoneText', 'acf' ), + 'currentText' => _x( 'Now', 'Date Time Picker JS currentText', 'acf' ), + 'closeText' => _x( 'Done', 'Date Time Picker JS closeText', 'acf' ), + 'selectText' => _x( 'Select', 'Date Time Picker JS selectText', 'acf' ), + 'amNames' => array( + _x( 'AM', 'Date Time Picker JS amText', 'acf' ), + _x( 'A', 'Date Time Picker JS amTextShort', 'acf' ), + ), + 'pmNames' => array( + _x( 'PM', 'Date Time Picker JS pmText', 'acf' ), + _x( 'P', 'Date Time Picker JS pmTextShort', 'acf' ), + ), + ), + ) + ); } - - // Output. - ?> + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // Set value. + $hidden_value = ''; + $display_value = ''; + + if ( $field['value'] ) { + $hidden_value = acf_format_date( $field['value'], 'Y-m-d H:i:s' ); + $display_value = acf_format_date( $field['value'], $field['display_format'] ); + } + + // Convert "display_format" setting to individual date and time formats. + $formats = acf_split_date_time( $field['display_format'] ); + + // Elements. + $div = array( + 'class' => 'acf-date-time-picker acf-input-wrap', + 'data-date_format' => acf_convert_date_to_js( $formats['date'] ), + 'data-time_format' => acf_convert_time_to_js( $formats['time'] ), + 'data-first_day' => $field['first_day'], + ); + $hidden_input = array( + 'id' => $field['id'], + 'class' => 'input-alt', + 'name' => $field['name'], + 'value' => $hidden_value, + ); + $text_input = array( + 'class' => 'input', + 'value' => $display_value, + ); + foreach ( array( 'readonly', 'disabled' ) as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $hidden_input[ $k ] = $k; + $text_input[ $k ] = $k; + } + } + + // Output. + ?>
                        >
                        - __('Display Format','acf'), - 'instructions' => __('The format displayed when editing a post','acf'), - 'type' => 'radio', - 'name' => 'display_format', - 'other_choice' => 1, - 'choices' => array( - 'd/m/Y g:i a' => '' . $d_m_Y . 'd/m/Y g:i a', - 'm/d/Y g:i a' => '' . $m_d_Y . 'm/d/Y g:i a', - 'F j, Y g:i a' => '' . $F_j_Y . 'F j, Y g:i a', - 'Y-m-d H:i:s' => '' . $Ymd . 'Y-m-d H:i:s', - 'other' => '' . __('Custom:','acf') . '' - ) - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => __('The format returned via template functions','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'other_choice' => 1, - 'choices' => array( - 'd/m/Y g:i a' => '' . $d_m_Y . 'd/m/Y g:i a', - 'm/d/Y g:i a' => '' . $m_d_Y . 'm/d/Y g:i a', - 'F j, Y g:i a' => '' . $F_j_Y . 'F j, Y g:i a', - 'Y-m-d H:i:s' => '' . $Ymd . 'Y-m-d H:i:s', - 'other' => '' . __('Custom:','acf') . '' - ) - )); - - - // first_day - acf_render_field_setting( $field, array( - 'label' => __('Week Starts On','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'first_day', - 'choices' => array_values( $wp_locale->weekday ) - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - return acf_format_date( $value, $field['return_format'] ); - - } - -} + __( 'Display Format', 'acf' ), + 'instructions' => __( 'The format displayed when editing a post', 'acf' ), + 'type' => 'radio', + 'name' => 'display_format', + 'other_choice' => 1, + 'choices' => array( + 'd/m/Y g:i a' => '' . $d_m_Y . 'd/m/Y g:i a', + 'm/d/Y g:i a' => '' . $m_d_Y . 'm/d/Y g:i a', + 'F j, Y g:i a' => '' . $F_j_Y . 'F j, Y g:i a', + 'Y-m-d H:i:s' => '' . $Ymd . 'Y-m-d H:i:s', + 'other' => '' . __( 'Custom:', 'acf' ) . '', + ), + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => __( 'The format returned via template functions', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'other_choice' => 1, + 'choices' => array( + 'd/m/Y g:i a' => '' . $d_m_Y . 'd/m/Y g:i a', + 'm/d/Y g:i a' => '' . $m_d_Y . 'm/d/Y g:i a', + 'F j, Y g:i a' => '' . $F_j_Y . 'F j, Y g:i a', + 'Y-m-d H:i:s' => '' . $Ymd . 'Y-m-d H:i:s', + 'other' => '' . __( 'Custom:', 'acf' ) . '', + ), + ) + ); + + // first_day + acf_render_field_setting( + $field, + array( + 'label' => __( 'Week Starts On', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'first_day', + 'choices' => array_values( $wp_locale->weekday ), + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + return acf_format_date( $value, $field['return_format'] ); + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_date_and_time_picker' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-email.php b/includes/fields/class-acf-field-email.php index cce93a0..0fe4b65 100644 --- a/includes/fields/class-acf-field-email.php +++ b/includes/fields/class-acf-field-email.php @@ -1,183 +1,189 @@ name = 'email'; + $this->label = __( 'Email', 'acf' ); + $this->defaults = array( + 'default_value' => '', + 'placeholder' => '', + 'prepend' => '', + 'append' => '', + ); -class acf_field_email extends acf_field { - - - /* - * initialize - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'email'; - $this->label = __("Email",'acf'); - $this->defaults = array( - 'default_value' => '', - 'placeholder' => '', - 'prepend' => '', - 'append' => '' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $atts = array(); - $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' ); - $keys2 = array( 'readonly', 'disabled', 'required', 'multiple' ); - $html = ''; - - - // prepend - if( $field['prepend'] !== '' ) { - - $field['class'] .= ' acf-is-prepended'; - $html .= '
                        ' . acf_esc_html($field['prepend']) . '
                        '; - } - - - // append - if( $field['append'] !== '' ) { - - $field['class'] .= ' acf-is-appended'; - $html .= '
                        ' . acf_esc_html($field['append']) . '
                        '; - + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $atts = array(); + $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' ); + $keys2 = array( 'readonly', 'disabled', 'required', 'multiple' ); + $html = ''; + + // prepend + if ( $field['prepend'] !== '' ) { + + $field['class'] .= ' acf-is-prepended'; + $html .= '
                        ' . acf_esc_html( $field['prepend'] ) . '
                        '; + + } + + // append + if ( $field['append'] !== '' ) { + + $field['class'] .= ' acf-is-appended'; + $html .= '
                        ' . acf_esc_html( $field['append'] ) . '
                        '; + + } + + // atts (value="123") + foreach ( $keys as $k ) { + if ( isset( $field[ $k ] ) ) { + $atts[ $k ] = $field[ $k ]; + } + } + + // atts2 (disabled="disabled") + foreach ( $keys2 as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $atts[ $k ] = $k; + } + } + + // remove empty atts + $atts = acf_clean_atts( $atts ); + + // render + $html .= '
                        ' . acf_get_text_input( $atts ) . '
                        '; + + // return + echo $html; + } - - - // atts (value="123") - foreach( $keys as $k ) { - if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ]; + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'text', + 'name' => 'default_value', + ) + ); + + // placeholder + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placeholder Text', 'acf' ), + 'instructions' => __( 'Appears within the input', 'acf' ), + 'type' => 'text', + 'name' => 'placeholder', + ) + ); + + // prepend + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prepend', 'acf' ), + 'instructions' => __( 'Appears before the input', 'acf' ), + 'type' => 'text', + 'name' => 'prepend', + ) + ); + + // append + acf_render_field_setting( + $field, + array( + 'label' => __( 'Append', 'acf' ), + 'instructions' => __( 'Appears after the input', 'acf' ), + 'type' => 'text', + 'name' => 'append', + ) + ); + } - - - // atts2 (disabled="disabled") - foreach( $keys2 as $k ) { - if( !empty($field[ $k ]) ) $atts[ $k ] = $k; + + /** + * Validate the email value. If this method returns TRUE, the input value is valid. If + * FALSE or a string is returned, the input value is invalid and the user is shown a + * notice. If a string is returned, the string is show as the message text. + * + * @param bool $valid Whether the value is valid. + * @param mixed $value The field value. + * @param array $field The field array. + * @param string $input The request variable name for the inbound field. + * + * @return bool|string + */ + public function validate_value( $valid, $value, $field, $input ) { + $flags = defined( 'FILTER_FLAG_EMAIL_UNICODE' ) ? FILTER_FLAG_EMAIL_UNICODE : 0; + + if ( $value && filter_var( wp_unslash( $value ), FILTER_VALIDATE_EMAIL, $flags ) === false ) { + return sprintf( __( "'%s' is not a valid email address", 'acf' ), esc_html( $value ) ); + } + + return $valid; } - - - // remove empty atts - $atts = acf_clean_atts( $atts ); - - - // render - $html .= '
                        ' . acf_get_text_input( $atts ) . '
                        '; - - - // return - echo $html; - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'text', - 'name' => 'default_value', - )); - - - // placeholder - acf_render_field_setting( $field, array( - 'label' => __('Placeholder Text','acf'), - 'instructions' => __('Appears within the input','acf'), - 'type' => 'text', - 'name' => 'placeholder', - )); - - - // prepend - acf_render_field_setting( $field, array( - 'label' => __('Prepend','acf'), - 'instructions' => __('Appears before the input','acf'), - 'type' => 'text', - 'name' => 'prepend', - )); - - - // append - acf_render_field_setting( $field, array( - 'label' => __('Append','acf'), - 'instructions' => __('Appears after the input','acf'), - 'type' => 'text', - 'name' => 'append', - )); } - /** - * Validate the email value. If this method returns TRUE, the input value is valid. If - * FALSE or a string is returned, the input value is invalid and the user is shown a - * notice. If a string is returned, the string is show as the message text. - * - * @param bool $valid Whether the value is valid. - * @param mixed $value The field value. - * @param array $field The field array. - * @param string $input The request variable name for the inbound field. - * - * @return bool|string - */ - public function validate_value( $valid, $value, $field, $input ) { - $flags = defined( 'FILTER_FLAG_EMAIL_UNICODE' ) ? FILTER_FLAG_EMAIL_UNICODE : 0; - if ( $value && filter_var( wp_unslash($value), FILTER_VALIDATE_EMAIL, $flags ) === false ) { - return sprintf( __( "'%s' is not a valid email address", 'acf' ), esc_html( $value ) ); - } - - return $valid; - } - -} - - -// initialize -acf_register_field_type( 'acf_field_email' ); + // initialize + acf_register_field_type( 'acf_field_email' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-file.php b/includes/fields/class-acf-field-file.php index bee1a06..311081d 100644 --- a/includes/fields/class-acf-field-file.php +++ b/includes/fields/class-acf-field-file.php @@ -1,437 +1,460 @@ name = 'file'; - $this->label = __("File",'acf'); - $this->category = 'content'; - $this->defaults = array( - 'return_format' => 'array', - 'library' => 'all', - 'min_size' => 0, - 'max_size' => 0, - 'mime_types' => '' - ); - - // filters - add_filter('get_media_item_args', array($this, 'get_media_item_args')); - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // localize - acf_localize_text(array( - 'Select File' => __('Select File', 'acf'), - 'Edit File' => __('Edit File', 'acf'), - 'Update File' => __('Update File', 'acf'), - )); - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $uploader = acf_get_setting('uploader'); - - - // allow custom uploader - $uploader = acf_maybe_get($field, 'uploader', $uploader); - - - // enqueue - if( $uploader == 'wp' ) { - acf_enqueue_uploader(); + class acf_field_file extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'file'; + $this->label = __( 'File', 'acf' ); + $this->category = 'content'; + $this->defaults = array( + 'return_format' => 'array', + 'library' => 'all', + 'min_size' => 0, + 'max_size' => 0, + 'mime_types' => '', + ); + + // filters + add_filter( 'get_media_item_args', array( $this, 'get_media_item_args' ) ); } - - - // vars - $o = array( - 'icon' => '', - 'title' => '', - 'url' => '', - 'filename' => '', - 'filesize' => '' - ); - - $div = array( - 'class' => 'acf-file-uploader', - 'data-library' => $field['library'], - 'data-mime_types' => $field['mime_types'], - 'data-uploader' => $uploader - ); - - - // has value? - if( $field['value'] ) { - - $attachment = acf_get_attachment($field['value']); - if( $attachment ) { - - // has value - $div['class'] .= ' has-value'; - - // update - $o['icon'] = $attachment['icon']; - $o['title'] = $attachment['title']; - $o['url'] = $attachment['url']; - $o['filename'] = $attachment['filename']; - if( $attachment['filesize'] ) { - $o['filesize'] = size_format($attachment['filesize']); + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // localize + acf_localize_text( + array( + 'Select File' => __( 'Select File', 'acf' ), + 'Edit File' => __( 'Edit File', 'acf' ), + 'Update File' => __( 'Update File', 'acf' ), + ) + ); + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $uploader = acf_get_setting( 'uploader' ); + + // allow custom uploader + $uploader = acf_maybe_get( $field, 'uploader', $uploader ); + + // enqueue + if ( $uploader == 'wp' ) { + acf_enqueue_uploader(); + } + + // vars + $o = array( + 'icon' => '', + 'title' => '', + 'url' => '', + 'filename' => '', + 'filesize' => '', + ); + + $div = array( + 'class' => 'acf-file-uploader', + 'data-library' => $field['library'], + 'data-mime_types' => $field['mime_types'], + 'data-uploader' => $uploader, + ); + + // has value? + if ( $field['value'] ) { + + $attachment = acf_get_attachment( $field['value'] ); + if ( $attachment ) { + + // has value + $div['class'] .= ' has-value'; + + // update + $o['icon'] = $attachment['icon']; + $o['title'] = $attachment['title']; + $o['url'] = $attachment['url']; + $o['filename'] = $attachment['filename']; + if ( $attachment['filesize'] ) { + $o['filesize'] = size_format( $attachment['filesize'] ); + } } - } - } - -?> + } + + ?>
                        > - $field['name'], 'value' => $field['value'], 'data-name' => 'id' )); ?> + $field['name'], + 'value' => $field['value'], + 'data-name' => 'id', + ) + ); + ?>
                        - +

                        - +

                        - : - + : +

                        - : - + : +

                        - - + + - +
                        - + - -

                        + +

                        - + -

                        +

                        - __( 'Return Value', 'acf' ), + 'instructions' => __( 'Specify the returned value on front end', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'array' => __( 'File Array', 'acf' ), + 'url' => __( 'File URL', 'acf' ), + 'id' => __( 'File ID', 'acf' ), + ), + ) + ); + + // library + acf_render_field_setting( + $field, + array( + 'label' => __( 'Library', 'acf' ), + 'instructions' => __( 'Limit the media library choice', 'acf' ), + 'type' => 'radio', + 'name' => 'library', + 'layout' => 'horizontal', + 'choices' => array( + 'all' => __( 'All', 'acf' ), + 'uploadedTo' => __( 'Uploaded to post', 'acf' ), + ), + ) + ); + + // min + acf_render_field_setting( + $field, + array( + 'label' => __( 'Minimum', 'acf' ), + 'instructions' => __( 'Restrict which files can be uploaded', 'acf' ), + 'type' => 'text', + 'name' => 'min_size', + 'prepend' => __( 'File size', 'acf' ), + 'append' => 'MB', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Maximum', 'acf' ), + 'instructions' => __( 'Restrict which files can be uploaded', 'acf' ), + 'type' => 'text', + 'name' => 'max_size', + 'prepend' => __( 'File size', 'acf' ), + 'append' => 'MB', + ) + ); + + // allowed type + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allowed file types', 'acf' ), + 'instructions' => __( 'Comma separated list. Leave blank for all types', 'acf' ), + 'type' => 'text', + 'name' => 'mime_types', + ) + ); + } - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Value','acf'), - 'instructions' => __('Specify the returned value on front end','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'layout' => 'horizontal', - 'choices' => array( - 'array' => __("File Array",'acf'), - 'url' => __("File URL",'acf'), - 'id' => __("File ID",'acf') - ) - )); - - - // library - acf_render_field_setting( $field, array( - 'label' => __('Library','acf'), - 'instructions' => __('Limit the media library choice','acf'), - 'type' => 'radio', - 'name' => 'library', - 'layout' => 'horizontal', - 'choices' => array( - 'all' => __('All', 'acf'), - 'uploadedTo' => __('Uploaded to post', 'acf') - ) - )); - - - // min - acf_render_field_setting( $field, array( - 'label' => __('Minimum','acf'), - 'instructions' => __('Restrict which files can be uploaded','acf'), - 'type' => 'text', - 'name' => 'min_size', - 'prepend' => __('File size', 'acf'), - 'append' => 'MB', - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Maximum','acf'), - 'instructions' => __('Restrict which files can be uploaded','acf'), - 'type' => 'text', - 'name' => 'max_size', - 'prepend' => __('File size', 'acf'), - 'append' => 'MB', - )); - - - // allowed type - acf_render_field_setting( $field, array( - 'label' => __('Allowed file types','acf'), - 'instructions' => __('Comma separated list. Leave blank for all types','acf'), - 'type' => 'text', - 'name' => 'mime_types', - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return false; - - - // bail early if not numeric (error message) - if( !is_numeric($value) ) return false; - - - // convert to int - $value = intval($value); - - - // format - if( $field['return_format'] == 'url' ) { - - return wp_get_attachment_url($value); - - } elseif( $field['return_format'] == 'array' ) { - - return acf_get_attachment( $value ); - } - - - // return - return $value; - } - - - /* - * get_media_item_args - * - * description - * - * @type function - * @date 27/01/13 - * @since 3.6.0 - * - * @param $vars (array) - * @return $vars - */ - - function get_media_item_args( $vars ) { - - $vars['send'] = true; - return($vars); - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( empty($value) ) { + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // bail early if not numeric (error message) + if ( ! is_numeric( $value ) ) { + return false; + } + + // convert to int + $value = intval( $value ); + + // format + if ( $field['return_format'] == 'url' ) { + + return wp_get_attachment_url( $value ); + + } elseif ( $field['return_format'] == 'array' ) { + + return acf_get_attachment( $value ); + } + + // return return $value; } - - // Parse value for id. - $attachment_id = acf_idval( $value ); - - // Connect attacment to post. - acf_connect_attachment_to_post( $attachment_id, $post_id ); - - // Return id. - return $attachment_id; - } - - - - /* - * validate_value - * - * This function will validate a basic file input - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // bail early if empty - if( empty($value) ) return $valid; - - - // bail ealry if is numeric - if( is_numeric($value) ) return $valid; - - - // bail ealry if not basic string - if( !is_string($value) ) return $valid; - - - // decode value - $file = null; - parse_str($value, $file); - - - // bail early if no attachment - if( empty($file) ) return $valid; - - - // get errors - $errors = acf_validate_attachment( $file, $field, 'basic_upload' ); - - - // append error - if( !empty($errors) ) { - - $valid = implode("\n", $errors); - + + + /* + * get_media_item_args + * + * description + * + * @type function + * @date 27/01/13 + * @since 3.6.0 + * + * @param $vars (array) + * @return $vars + */ + + function get_media_item_args( $vars ) { + + $vars['send'] = true; + return( $vars ); + } - - - // return - return $valid; - + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( empty( $value ) ) { + return $value; + } + + // Parse value for id. + $attachment_id = acf_idval( $value ); + + // Connect attacment to post. + acf_connect_attachment_to_post( $attachment_id, $post_id ); + + // Return id. + return $attachment_id; + } + + + + /* + * validate_value + * + * This function will validate a basic file input + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // bail early if empty + if ( empty( $value ) ) { + return $valid; + } + + // bail ealry if is numeric + if ( is_numeric( $value ) ) { + return $valid; + } + + // bail ealry if not basic string + if ( ! is_string( $value ) ) { + return $valid; + } + + // decode value + $file = null; + parse_str( $value, $file ); + + // bail early if no attachment + if ( empty( $file ) ) { + return $valid; + } + + // get errors + $errors = acf_validate_attachment( $file, $field, 'basic_upload' ); + + // append error + if ( ! empty( $errors ) ) { + + $valid = implode( "\n", $errors ); + + } + + // return + return $valid; + + } + } - -} -// initialize -acf_register_field_type( 'acf_field_file' ); + // initialize + acf_register_field_type( 'acf_field_file' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-google-map.php b/includes/fields/class-acf-field-google-map.php index 3cb2599..3697ece 100644 --- a/includes/fields/class-acf-field-google-map.php +++ b/includes/fields/class-acf-field-google-map.php @@ -1,291 +1,312 @@ name = 'google_map'; - $this->label = __("Google Map",'acf'); - $this->category = 'jquery'; - $this->defaults = array( - 'height' => '', - 'center_lat' => '', - 'center_lng' => '', - 'zoom' => '' - ); - $this->default_values = array( - 'height' => '400', - 'center_lat' => '-37.81411', - 'center_lng' => '144.96328', - 'zoom' => '14' - ); - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // localize - acf_localize_text(array( - 'Sorry, this browser does not support geolocation' => __('Sorry, this browser does not support geolocation', 'acf'), - )); - - - // bail ealry if no enqueue - if( !acf_get_setting('enqueue_google_maps') ) { - return; - } - - - // vars - $api = array( - 'key' => acf_get_setting('google_api_key'), - 'client' => acf_get_setting('google_api_client'), - 'libraries' => 'places', - 'ver' => 3, - 'callback' => '', - 'language' => acf_get_locale() - ); - - - // filter - $api = apply_filters('acf/fields/google_map/api', $api); - - - // remove empty - if( empty($api['key']) ) unset($api['key']); - if( empty($api['client']) ) unset($api['client']); - - - // construct url - $url = add_query_arg($api, 'https://maps.googleapis.com/maps/api/js'); - - - // localize - acf_localize_data(array( - 'google_map_api' => $url - )); - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // Apply defaults. - foreach( $this->default_values as $k => $v ) { - if( !$field[ $k ] ) { - $field[ $k ] = $v; - } + class acf_field_google_map extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'google_map'; + $this->label = __( 'Google Map', 'acf' ); + $this->category = 'jquery'; + $this->defaults = array( + 'height' => '', + 'center_lat' => '', + 'center_lng' => '', + 'zoom' => '', + ); + $this->default_values = array( + 'height' => '400', + 'center_lat' => '-37.81411', + 'center_lng' => '144.96328', + 'zoom' => '14', + ); } - - // Attrs. - $attrs = array( - 'id' => $field['id'], - 'class' => "acf-google-map {$field['class']}", - 'data-lat' => $field['center_lat'], - 'data-lng' => $field['center_lng'], - 'data-zoom' => $field['zoom'], - ); - - $search = ''; - if( $field['value'] ) { - $attrs['class'] .= ' -value'; - $search = $field['value']['address']; - } else { - $field['value'] = ''; + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // localize + acf_localize_text( + array( + 'Sorry, this browser does not support geolocation' => __( 'Sorry, this browser does not support geolocation', 'acf' ), + ) + ); + + // bail ealry if no enqueue + if ( ! acf_get_setting( 'enqueue_google_maps' ) ) { + return; + } + + // vars + $api = array( + 'key' => acf_get_setting( 'google_api_key' ), + 'client' => acf_get_setting( 'google_api_client' ), + 'libraries' => 'places', + 'ver' => 3, + 'callback' => '', + 'language' => acf_get_locale(), + ); + + // filter + $api = apply_filters( 'acf/fields/google_map/api', $api ); + + // remove empty + if ( empty( $api['key'] ) ) { + unset( $api['key'] ); + } + if ( empty( $api['client'] ) ) { + unset( $api['client'] ); + } + + // construct url + $url = add_query_arg( $api, 'https://maps.googleapis.com/maps/api/js' ); + + // localize + acf_localize_data( + array( + 'google_map_api' => $url, + ) + ); } - -?> -
                        > + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // Apply defaults. + foreach ( $this->default_values as $k => $v ) { + if ( ! $field[ $k ] ) { + $field[ $k ] = $v; + } + } + + // Attrs. + $attrs = array( + 'id' => $field['id'], + 'class' => "acf-google-map {$field['class']}", + 'data-lat' => $field['center_lat'], + 'data-lng' => $field['center_lng'], + 'data-zoom' => $field['zoom'], + ); + + $search = ''; + if ( $field['value'] ) { + $attrs['class'] .= ' -value'; + $search = $field['value']['address']; + } else { + $field['value'] = ''; + } + + ?> +
                        > - $field['name'], 'value' => $field['value']) ); ?> + $field['name'], + 'value' => $field['value'], + ) + ); + ?>
                        - "> - "> - "> + + +
                        - " value="" /> +
                        -
                        +
                        - __('Center','acf'), - 'instructions' => __('Center the initial map','acf'), - 'type' => 'text', - 'name' => 'center_lat', - 'prepend' => 'lat', - 'placeholder' => $this->default_values['center_lat'] - )); - - - // center_lng - acf_render_field_setting( $field, array( - 'label' => __('Center','acf'), - 'instructions' => __('Center the initial map','acf'), - 'type' => 'text', - 'name' => 'center_lng', - 'prepend' => 'lng', - 'placeholder' => $this->default_values['center_lng'], - '_append' => 'center_lat' - )); - - - // zoom - acf_render_field_setting( $field, array( - 'label' => __('Zoom','acf'), - 'instructions' => __('Set the initial zoom level','acf'), - 'type' => 'text', - 'name' => 'zoom', - 'placeholder' => $this->default_values['zoom'] - )); - - - // allow_null - acf_render_field_setting( $field, array( - 'label' => __('Height','acf'), - 'instructions' => __('Customize the map height','acf'), - 'type' => 'text', - 'name' => 'height', - 'append' => 'px', - 'placeholder' => $this->default_values['height'] - )); - - } - - /** - * load_value - * - * Filters the value loaded from the database. - * - * @date 16/10/19 - * @since 5.8.1 - * - * @param mixed $value The value loaded from the database. - * @param mixed $post_id The post ID where the value is saved. - * @param array $field The field settings array. - * @return (array|false) - */ - function load_value( $value, $post_id, $field ) { - - // Ensure value is an array. - if( $value ) { - return wp_parse_args($value, array( - 'address' => '', - 'lat' => 0, - 'lng' => 0 - )); + __( 'Center', 'acf' ), + 'instructions' => __( 'Center the initial map', 'acf' ), + 'type' => 'text', + 'name' => 'center_lat', + 'prepend' => 'lat', + 'placeholder' => $this->default_values['center_lat'], + ) + ); + + // center_lng + acf_render_field_setting( + $field, + array( + 'label' => __( 'Center', 'acf' ), + 'instructions' => __( 'Center the initial map', 'acf' ), + 'type' => 'text', + 'name' => 'center_lng', + 'prepend' => 'lng', + 'placeholder' => $this->default_values['center_lng'], + '_append' => 'center_lat', + ) + ); + + // zoom + acf_render_field_setting( + $field, + array( + 'label' => __( 'Zoom', 'acf' ), + 'instructions' => __( 'Set the initial zoom level', 'acf' ), + 'type' => 'text', + 'name' => 'zoom', + 'placeholder' => $this->default_values['zoom'], + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Height', 'acf' ), + 'instructions' => __( 'Customize the map height', 'acf' ), + 'type' => 'text', + 'name' => 'height', + 'append' => 'px', + 'placeholder' => $this->default_values['height'], + ) + ); + + } + + /** + * load_value + * + * Filters the value loaded from the database. + * + * @date 16/10/19 + * @since 5.8.1 + * + * @param mixed $value The value loaded from the database. + * @param mixed $post_id The post ID where the value is saved. + * @param array $field The field settings array. + * @return (array|false) + */ + function load_value( $value, $post_id, $field ) { + + // Ensure value is an array. + if ( $value ) { + return wp_parse_args( + $value, + array( + 'address' => '', + 'lat' => 0, + 'lng' => 0, + ) + ); + } + + // Return default. + return false; + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + function update_value( $value, $post_id, $field ) { + + // decode JSON string. + if ( is_string( $value ) ) { + $value = json_decode( wp_unslash( $value ), true ); + } + + // Ensure value is an array. + if ( $value ) { + return (array) $value; + } + + // Return default. + return false; + } + } + + + // initialize + acf_register_field_type( 'acf_field_google_map' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-group.php b/includes/fields/class-acf-field-group.php index 13c7f04..c0e5a8d 100644 --- a/includes/fields/class-acf-field-group.php +++ b/includes/fields/class-acf-field-group.php @@ -1,682 +1,670 @@ name = 'group'; - $this->label = __("Group",'acf'); - $this->category = 'layout'; - $this->defaults = array( - 'sub_fields' => array(), - 'layout' => 'block' - ); - $this->have_rows = 'single'; - - - // field filters - $this->add_field_filter('acf/prepare_field_for_export', array($this, 'prepare_field_for_export')); - $this->add_field_filter('acf/prepare_field_for_import', array($this, 'prepare_field_for_import')); - - } - - - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - - function load_field( $field ) { - - // vars - $sub_fields = acf_get_fields( $field ); - - - // append - if( $sub_fields ) { - - $field['sub_fields'] = $sub_fields; - - } - - - // return - return $field; - - } - - - /* - * load_value() - * - * This filter is applied to the $value after it is loaded from the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value found in the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * @return $value - */ - - function load_value( $value, $post_id, $field ) { - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $value; - - - // modify names - $field = $this->prepare_field_for_db( $field ); - - - // load sub fields - $value = array(); - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - - // load - $value[ $sub_field['key'] ] = acf_get_value( $post_id, $sub_field ); - - } - - - // return - return $value; - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return false; - - - // modify names - $field = $this->prepare_field_for_db( $field ); - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - - // extract value - $sub_value = acf_extract_var( $value, $sub_field['key'] ); - - - // format value - $sub_value = acf_format_value( $sub_value, $post_id, $sub_field ); - - - // append to $row - $value[ $sub_field['_name'] ] = $sub_value; - - } - - - // return - return $value; - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $field - the field array holding all the field options - * @param $post_id - the $post_id of which the value will be saved - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // bail early if no value - if( !acf_is_array($value) ) return null; - - - // bail ealry if no sub fields - if( empty($field['sub_fields']) ) return null; - - - // modify names - $field = $this->prepare_field_for_db( $field ); - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - // vars - $v = false; - - - // key (backend) - if( isset($value[ $sub_field['key'] ]) ) { - - $v = $value[ $sub_field['key'] ]; - - // name (frontend) - } elseif( isset($value[ $sub_field['_name'] ]) ) { - - $v = $value[ $sub_field['_name'] ]; - - // empty - } else { - - // input is not set (hidden by conditioanl logic) - continue; - - } - - - // update value - acf_update_value( $v, $post_id, $sub_field ); - - } - - - // return - return ''; - - } - - - /* - * prepare_field_for_db - * - * This function will modify sub fields ready for update / load - * - * @type function - * @date 4/11/16 - * @since 5.5.0 - * - * @param $field (array) - * @return $field - */ - - function prepare_field_for_db( $field ) { - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $field; - - - // loop - foreach( $field['sub_fields'] as &$sub_field ) { - - // prefix name - $sub_field['name'] = $field['name'] . '_' . $sub_field['_name']; - - } - - - // return - return $field; + $this->name = 'group'; + $this->label = __( 'Group', 'acf' ); + $this->category = 'layout'; + $this->defaults = array( + 'sub_fields' => array(), + 'layout' => 'block', + ); + $this->have_rows = 'single'; + + // field filters + $this->add_field_filter( 'acf/prepare_field_for_export', array( $this, 'prepare_field_for_export' ) ); + $this->add_field_filter( 'acf/prepare_field_for_import', array( $this, 'prepare_field_for_import' ) ); + + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + + function load_field( $field ) { + + // vars + $sub_fields = acf_get_fields( $field ); + + // append + if ( $sub_fields ) { + + $field['sub_fields'] = $sub_fields; - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return; - - - // load values - foreach( $field['sub_fields'] as &$sub_field ) { - - // add value - if( isset($field['value'][ $sub_field['key'] ]) ) { - - // this is a normal value - $sub_field['value'] = $field['value'][ $sub_field['key'] ]; - - } elseif( isset($sub_field['default_value']) ) { - - // no value, but this sub field has a default value - $sub_field['value'] = $sub_field['default_value']; - } - - - // update prefix to allow for nested values - $sub_field['prefix'] = $field['name']; - - - // restore required - if( $field['required'] ) $sub_field['required'] = 0; - + + // return + return $field; + } - - - // render - if( $field['layout'] == 'table' ) { - - $this->render_field_table( $field ); - - } else { - - $this->render_field_block( $field ); - + + + /* + * load_value() + * + * This filter is applied to the $value after it is loaded from the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value found in the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * @return $value + */ + + function load_value( $value, $post_id, $field ) { + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $value; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // load sub fields + $value = array(); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // load + $value[ $sub_field['key'] ] = acf_get_value( $post_id, $sub_field ); + + } + + // return + return $value; + } - - } - - - /* - * render_field_block - * - * description - * - * @type function - * @date 12/07/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_block( $field ) { - - // vars - $label_placement = ($field['layout'] == 'block') ? 'top' : 'left'; - - - // html - echo '
                        '; - - foreach( $field['sub_fields'] as $sub_field ) { - - acf_render_field_wrap( $sub_field ); - + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // extract value + $sub_value = acf_extract_var( $value, $sub_field['key'] ); + + // format value + $sub_value = acf_format_value( $sub_value, $post_id, $sub_field ); + + // append to $row + $value[ $sub_field['_name'] ] = $sub_value; + + } + + // return + return $value; + } - - echo '
                        '; - - } - - - /* - * render_field_table - * - * description - * - * @type function - * @date 12/07/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_table( $field ) { - -?> + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $field - the field array holding all the field options + * @param $post_id - the $post_id of which the value will be saved + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // bail early if no value + if ( ! acf_is_array( $value ) ) { + return null; + } + + // bail ealry if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return null; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // vars + $v = false; + + // key (backend) + if ( isset( $value[ $sub_field['key'] ] ) ) { + + $v = $value[ $sub_field['key'] ]; + + // name (frontend) + } elseif ( isset( $value[ $sub_field['_name'] ] ) ) { + + $v = $value[ $sub_field['_name'] ]; + + // empty + } else { + + // input is not set (hidden by conditioanl logic) + continue; + + } + + // update value + acf_update_value( $v, $post_id, $sub_field ); + + } + + // return + return ''; + + } + + + /* + * prepare_field_for_db + * + * This function will modify sub fields ready for update / load + * + * @type function + * @date 4/11/16 + * @since 5.5.0 + * + * @param $field (array) + * @return $field + */ + + function prepare_field_for_db( $field ) { + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $field; + } + + // loop + foreach ( $field['sub_fields'] as &$sub_field ) { + + // prefix name + $sub_field['name'] = $field['name'] . '_' . $sub_field['_name']; + + } + + // return + return $field; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return; + } + + // load values + foreach ( $field['sub_fields'] as &$sub_field ) { + + // add value + if ( isset( $field['value'][ $sub_field['key'] ] ) ) { + + // this is a normal value + $sub_field['value'] = $field['value'][ $sub_field['key'] ]; + + } elseif ( isset( $sub_field['default_value'] ) ) { + + // no value, but this sub field has a default value + $sub_field['value'] = $sub_field['default_value']; + + } + + // update prefix to allow for nested values + $sub_field['prefix'] = $field['name']; + + // restore required + if ( $field['required'] ) { + $sub_field['required'] = 0; + } + } + + // render + if ( $field['layout'] == 'table' ) { + + $this->render_field_table( $field ); + + } else { + + $this->render_field_block( $field ); + + } + + } + + + /* + * render_field_block + * + * description + * + * @type function + * @date 12/07/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_block( $field ) { + + // vars + $label_placement = ( $field['layout'] == 'block' ) ? 'top' : 'left'; + + // html + echo '
                        '; + + foreach ( $field['sub_fields'] as $sub_field ) { + + acf_render_field_wrap( $sub_field ); + + } + + echo '
                        '; + + } + + + /* + * render_field_table + * + * description + * + * @type function + * @date 12/07/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_table( $field ) { + + ?> - + - + - +
                        >
                        - $field['sub_fields'], - 'parent' => $field['ID'] - ); - - - ?> + $field['sub_fields'], + 'parent' => $field['ID'], + ); + + ?> + - + - - __('Layout','acf'), - 'instructions' => __('Specify the style used to render the selected fields', 'acf'), - 'type' => 'radio', - 'name' => 'layout', - 'layout' => 'horizontal', - 'choices' => array( - 'block' => __('Block','acf'), - 'table' => __('Table','acf'), - 'row' => __('Row','acf') - ) - )); - - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // bail early if no $value - if( empty($value) ) return $valid; - - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $valid; - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - - // get sub field - $k = $sub_field['key']; - - - // bail early if value not set (conditional logic?) - if( !isset($value[ $k ]) ) continue; - - - // required - if( $field['required'] ) { - $sub_field['required'] = 1; - } - - - // validate - acf_validate_value( $value[ $k ], $sub_field, "{$input}[{$k}]" ); - - } - - - // return - return $valid; - - } - - - /* - * duplicate_field() - * - * This filter is appied to the $field before it is duplicated and saved to the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the modified field - */ + __( 'Layout', 'acf' ), + 'instructions' => __( 'Specify the style used to render the selected fields', 'acf' ), + 'type' => 'radio', + 'name' => 'layout', + 'layout' => 'horizontal', + 'choices' => array( + 'block' => __( 'Block', 'acf' ), + 'table' => __( 'Table', 'acf' ), + 'row' => __( 'Row', 'acf' ), + ), + ) + ); - function duplicate_field( $field ) { - - // get sub fields - $sub_fields = acf_extract_var( $field, 'sub_fields' ); - - - // save field to get ID - $field = acf_update_field( $field ); - - - // duplicate sub fields - acf_duplicate_fields( $sub_fields, $field['ID'] ); - - - // return - return $field; - - } - - /** - * prepare_field_for_export - * - * Prepares the field for export. - * - * @date 11/03/2014 - * @since 5.0.0 - * - * @param array $field The field settings. - * @return array - */ - function prepare_field_for_export( $field ) { - - // Check for sub fields. - if( !empty($field['sub_fields']) ) { - $field['sub_fields'] = acf_prepare_fields_for_export( $field['sub_fields'] ); } - return $field; - } - - /** - * prepare_field_for_import - * - * Returns a flat array of fields containing all sub fields ready for import. - * - * @date 11/03/2014 - * @since 5.0.0 - * - * @param array $field The field settings. - * @return array - */ - function prepare_field_for_import( $field ) { - - // Check for sub fields. - if( !empty($field['sub_fields']) ) { + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // bail early if no $value + if ( empty( $value ) ) { + return $valid; + } + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $valid; + } + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // get sub field + $k = $sub_field['key']; + + // bail early if value not set (conditional logic?) + if ( ! isset( $value[ $k ] ) ) { + continue; + } + + // required + if ( $field['required'] ) { + $sub_field['required'] = 1; + } + + // validate + acf_validate_value( $value[ $k ], $sub_field, "{$input}[{$k}]" ); + + } + + // return + return $valid; + + } + + + /* + * duplicate_field() + * + * This filter is appied to the $field before it is duplicated and saved to the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the modified field + */ + + function duplicate_field( $field ) { + + // get sub fields $sub_fields = acf_extract_var( $field, 'sub_fields' ); - - // Modify sub fields. - foreach( $sub_fields as $i => $sub_field ) { - $sub_fields[ $i ]['parent'] = $field['key']; - $sub_fields[ $i ]['menu_order'] = $i; + + // save field to get ID + $field = acf_update_field( $field ); + + // duplicate sub fields + acf_duplicate_fields( $sub_fields, $field['ID'] ); + + // return + return $field; + + } + + /** + * prepare_field_for_export + * + * Prepares the field for export. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $field The field settings. + * @return array + */ + function prepare_field_for_export( $field ) { + + // Check for sub fields. + if ( ! empty( $field['sub_fields'] ) ) { + $field['sub_fields'] = acf_prepare_fields_for_export( $field['sub_fields'] ); } - - // Return array of [field, sub_1, sub_2, ...]. - return array_merge( array($field), $sub_fields ); - + return $field; } - return $field; - } - - - /* - * delete_value - * - * Called when deleting this field's value. - * - * @date 1/07/2015 - * @since 5.2.3 - * - * @param mixed $post_id The post ID being saved - * @param string $meta_key The field name as seen by the DB - * @param array $field The field settings - * @return void - */ - - function delete_value( $post_id, $meta_key, $field ) { - - // bail ealry if no sub fields - if( empty($field['sub_fields']) ) return null; - - // modify names - $field = $this->prepare_field_for_db( $field ); - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - acf_delete_value( $post_id, $sub_field ); - } - } - - /** - * delete_field - * - * Called when deleting a field of this type. - * - * @date 8/11/18 - * @since 5.8.0 - * - * @param arra $field The field settings. - * @return void - */ - function delete_field( $field ) { - - // loop over sub fields and delete them - if( $field['sub_fields'] ) { - foreach( $field['sub_fields'] as $sub_field ) { - acf_delete_field( $sub_field['ID'] ); + + /** + * prepare_field_for_import + * + * Returns a flat array of fields containing all sub fields ready for import. + * + * @date 11/03/2014 + * @since 5.0.0 + * + * @param array $field The field settings. + * @return array + */ + function prepare_field_for_import( $field ) { + + // Check for sub fields. + if ( ! empty( $field['sub_fields'] ) ) { + $sub_fields = acf_extract_var( $field, 'sub_fields' ); + + // Modify sub fields. + foreach ( $sub_fields as $i => $sub_field ) { + $sub_fields[ $i ]['parent'] = $field['key']; + $sub_fields[ $i ]['menu_order'] = $i; + } + + // Return array of [field, sub_1, sub_2, ...]. + return array_merge( array( $field ), $sub_fields ); + } + return $field; } - } - -} -// initialize -acf_register_field_type( 'acf_field__group' ); + /* + * delete_value + * + * Called when deleting this field's value. + * + * @date 1/07/2015 + * @since 5.2.3 + * + * @param mixed $post_id The post ID being saved + * @param string $meta_key The field name as seen by the DB + * @param array $field The field settings + * @return void + */ + + function delete_value( $post_id, $meta_key, $field ) { + + // bail ealry if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return null; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + acf_delete_value( $post_id, $sub_field ); + } + } + + /** + * delete_field + * + * Called when deleting a field of this type. + * + * @date 8/11/18 + * @since 5.8.0 + * + * @param arra $field The field settings. + * @return void + */ + function delete_field( $field ) { + + // loop over sub fields and delete them + if ( $field['sub_fields'] ) { + foreach ( $field['sub_fields'] as $sub_field ) { + acf_delete_field( $sub_field['ID'] ); + } + } + } + + } + + + // initialize + acf_register_field_type( 'acf_field__group' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-image.php b/includes/fields/class-acf-field-image.php index 5bc93c0..c0ecd06 100644 --- a/includes/fields/class-acf-field-image.php +++ b/includes/fields/class-acf-field-image.php @@ -1,419 +1,452 @@ name = 'image'; + $this->label = __( 'Image', 'acf' ); + $this->category = 'content'; + $this->defaults = array( + 'return_format' => 'array', + 'preview_size' => 'medium', + 'library' => 'all', + 'min_width' => 0, + 'min_height' => 0, + 'min_size' => 0, + 'max_width' => 0, + 'max_height' => 0, + 'max_size' => 0, + 'mime_types' => '', + ); + + // filters + add_filter( 'get_media_item_args', array( $this, 'get_media_item_args' ) ); -class acf_field_image extends acf_field { - - - /* - * __construct - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'image'; - $this->label = __("Image",'acf'); - $this->category = 'content'; - $this->defaults = array( - 'return_format' => 'array', - 'preview_size' => 'medium', - 'library' => 'all', - 'min_width' => 0, - 'min_height' => 0, - 'min_size' => 0, - 'max_width' => 0, - 'max_height' => 0, - 'max_size' => 0, - 'mime_types' => '' - ); - - // filters - add_filter('get_media_item_args', array($this, 'get_media_item_args')); - - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // localize - acf_localize_text(array( - 'Select Image' => __('Select Image', 'acf'), - 'Edit Image' => __('Edit Image', 'acf'), - 'Update Image' => __('Update Image', 'acf'), - 'All images' => __('All images', 'acf'), - )); - } - - /** - * Renders the field HTML. - * - * @date 23/01/13 - * @since 3.6.0 - * - * @param array $field The field settings. - * @return void - */ - function render_field( $field ) { - $uploader = acf_get_setting('uploader'); - - // Enqueue uploader scripts - if( $uploader === 'wp' ) { - acf_enqueue_uploader(); } - // Elements and attributes. - $value = ''; - $div_attrs = array( - 'class' => 'acf-image-uploader', - 'data-preview_size' => $field['preview_size'], - 'data-library' => $field['library'], - 'data-mime_types' => $field['mime_types'], - 'data-uploader' => $uploader - ); - $img_attrs = array( - 'src' => '', - 'alt' => '', - 'data-name' => 'image' - ); - - // Detect value. - if( $field['value'] && is_numeric($field['value']) ) { - $image = wp_get_attachment_image_src( $field['value'], $field['preview_size'] ); - if( $image ) { - $value = $field['value']; - $img_attrs['src'] = $image[0]; - $img_attrs['alt'] = get_post_meta( $field['value'], '_wp_attachment_image_alt', true ); - $div_attrs['class'] .= ' has-value'; - } - } - - // Add "preview size" max width and height style. - // Apply max-width to wrap, and max-height to img for max compatibility with field widths. - $size = acf_get_image_size( $field['preview_size'] ); - $size_w = $size['width'] ? $size['width'] . 'px' : '100%'; - $size_h = $size['height'] ? $size['height'] . 'px' : '100%'; - $img_attrs['style'] = sprintf( 'max-height: %s;', $size_h ); - // Render HTML. - ?> + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // localize + acf_localize_text( + array( + 'Select Image' => __( 'Select Image', 'acf' ), + 'Edit Image' => __( 'Edit Image', 'acf' ), + 'Update Image' => __( 'Update Image', 'acf' ), + 'All images' => __( 'All images', 'acf' ), + ) + ); + } + + /** + * Renders the field HTML. + * + * @date 23/01/13 + * @since 3.6.0 + * + * @param array $field The field settings. + * @return void + */ + function render_field( $field ) { + $uploader = acf_get_setting( 'uploader' ); + + // Enqueue uploader scripts + if ( $uploader === 'wp' ) { + acf_enqueue_uploader(); + } + + // Elements and attributes. + $value = ''; + $div_attrs = array( + 'class' => 'acf-image-uploader', + 'data-preview_size' => $field['preview_size'], + 'data-library' => $field['library'], + 'data-mime_types' => $field['mime_types'], + 'data-uploader' => $uploader, + ); + $img_attrs = array( + 'src' => '', + 'alt' => '', + 'data-name' => 'image', + ); + + // Detect value. + if ( $field['value'] && is_numeric( $field['value'] ) ) { + $image = wp_get_attachment_image_src( $field['value'], $field['preview_size'] ); + if ( $image ) { + $value = $field['value']; + $img_attrs['src'] = $image[0]; + $img_attrs['alt'] = get_post_meta( $field['value'], '_wp_attachment_image_alt', true ); + $div_attrs['class'] .= ' has-value'; + } + } + + // Add "preview size" max width and height style. + // Apply max-width to wrap, and max-height to img for max compatibility with field widths. + $size = acf_get_image_size( $field['preview_size'] ); + $size_w = $size['width'] ? $size['width'] . 'px' : '100%'; + $size_h = $size['height'] ? $size['height'] . 'px' : '100%'; + $img_attrs['style'] = sprintf( 'max-height: %s;', $size_h ); + + // Render HTML. + ?>
                        > - $field['name'], - 'value' => $value - )); ?> + $field['name'], + 'value' => $value, + ) + ); + ?>
                        />
                        - +
                        - - + +

                        - +

                        - __( 'Return Format', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'array' => __( 'Image Array', 'acf' ), + 'url' => __( 'Image URL', 'acf' ), + 'id' => __( 'Image ID', 'acf' ), + ), + ) + ); + + // preview_size + acf_render_field_setting( + $field, + array( + 'label' => __( 'Preview Size', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'preview_size', + 'choices' => acf_get_image_sizes(), + ) + ); + + // library + acf_render_field_setting( + $field, + array( + 'label' => __( 'Library', 'acf' ), + 'instructions' => __( 'Limit the media library choice', 'acf' ), + 'type' => 'radio', + 'name' => 'library', + 'layout' => 'horizontal', + 'choices' => array( + 'all' => __( 'All', 'acf' ), + 'uploadedTo' => __( 'Uploaded to post', 'acf' ), + ), + ) + ); + + // min + acf_render_field_setting( + $field, + array( + 'label' => __( 'Minimum', 'acf' ), + 'instructions' => __( 'Restrict which images can be uploaded', 'acf' ), + 'type' => 'text', + 'name' => 'min_width', + 'prepend' => __( 'Width', 'acf' ), + 'append' => 'px', + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => '', + 'type' => 'text', + 'name' => 'min_height', + 'prepend' => __( 'Height', 'acf' ), + 'append' => 'px', + '_append' => 'min_width', + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => '', + 'type' => 'text', + 'name' => 'min_size', + 'prepend' => __( 'File size', 'acf' ), + 'append' => 'MB', + '_append' => 'min_width', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Maximum', 'acf' ), + 'instructions' => __( 'Restrict which images can be uploaded', 'acf' ), + 'type' => 'text', + 'name' => 'max_width', + 'prepend' => __( 'Width', 'acf' ), + 'append' => 'px', + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => '', + 'type' => 'text', + 'name' => 'max_height', + 'prepend' => __( 'Height', 'acf' ), + 'append' => 'px', + '_append' => 'max_width', + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => '', + 'type' => 'text', + 'name' => 'max_size', + 'prepend' => __( 'File size', 'acf' ), + 'append' => 'MB', + '_append' => 'max_width', + ) + ); + + // allowed type + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allowed file types', 'acf' ), + 'instructions' => __( 'Comma separated list. Leave blank for all types', 'acf' ), + 'type' => 'text', + 'name' => 'mime_types', + ) + ); + } - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'return_format', - 'layout' => 'horizontal', - 'choices' => array( - 'array' => __("Image Array",'acf'), - 'url' => __("Image URL",'acf'), - 'id' => __("Image ID",'acf') - ) - )); - - - // preview_size - acf_render_field_setting( $field, array( - 'label' => __('Preview Size','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'preview_size', - 'choices' => acf_get_image_sizes() - )); - - - // library - acf_render_field_setting( $field, array( - 'label' => __('Library','acf'), - 'instructions' => __('Limit the media library choice','acf'), - 'type' => 'radio', - 'name' => 'library', - 'layout' => 'horizontal', - 'choices' => array( - 'all' => __('All', 'acf'), - 'uploadedTo' => __('Uploaded to post', 'acf') - ) - )); - - - // min - acf_render_field_setting( $field, array( - 'label' => __('Minimum','acf'), - 'instructions' => __('Restrict which images can be uploaded','acf'), - 'type' => 'text', - 'name' => 'min_width', - 'prepend' => __('Width', 'acf'), - 'append' => 'px', - )); - - acf_render_field_setting( $field, array( - 'label' => '', - 'type' => 'text', - 'name' => 'min_height', - 'prepend' => __('Height', 'acf'), - 'append' => 'px', - '_append' => 'min_width' - )); - - acf_render_field_setting( $field, array( - 'label' => '', - 'type' => 'text', - 'name' => 'min_size', - 'prepend' => __('File size', 'acf'), - 'append' => 'MB', - '_append' => 'min_width' - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Maximum','acf'), - 'instructions' => __('Restrict which images can be uploaded','acf'), - 'type' => 'text', - 'name' => 'max_width', - 'prepend' => __('Width', 'acf'), - 'append' => 'px', - )); - - acf_render_field_setting( $field, array( - 'label' => '', - 'type' => 'text', - 'name' => 'max_height', - 'prepend' => __('Height', 'acf'), - 'append' => 'px', - '_append' => 'max_width' - )); - - acf_render_field_setting( $field, array( - 'label' => '', - 'type' => 'text', - 'name' => 'max_size', - 'prepend' => __('File size', 'acf'), - 'append' => 'MB', - '_append' => 'max_width' - )); - - - // allowed type - acf_render_field_setting( $field, array( - 'label' => __('Allowed file types','acf'), - 'instructions' => __('Comma separated list. Leave blank for all types','acf'), - 'type' => 'text', - 'name' => 'mime_types', - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return false; - - - // bail early if not numeric (error message) - if( !is_numeric($value) ) return false; - - - // convert to int - $value = intval($value); - - - // format - if( $field['return_format'] == 'url' ) { - - return wp_get_attachment_url( $value ); - - } elseif( $field['return_format'] == 'array' ) { - - return acf_get_attachment( $value ); - - } - - - // return - return $value; - - } - - - /* - * get_media_item_args - * - * description - * - * @type function - * @date 27/01/13 - * @since 3.6.0 - * - * @param $vars (array) - * @return $vars - */ - - function get_media_item_args( $vars ) { - - $vars['send'] = true; - return($vars); - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - return acf_get_field_type('file')->update_value( $value, $post_id, $field ); - - } - - - /* - * validate_value - * - * This function will validate a basic file input - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - return acf_get_field_type('file')->validate_value( $valid, $value, $field, $input ); - - } - -} -// initialize -acf_register_field_type( 'acf_field_image' ); + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // bail early if not numeric (error message) + if ( ! is_numeric( $value ) ) { + return false; + } + + // convert to int + $value = intval( $value ); + + // format + if ( $field['return_format'] == 'url' ) { + + return wp_get_attachment_url( $value ); + + } elseif ( $field['return_format'] == 'array' ) { + + return acf_get_attachment( $value ); + + } + + // return + return $value; + + } + + + /* + * get_media_item_args + * + * description + * + * @type function + * @date 27/01/13 + * @since 3.6.0 + * + * @param $vars (array) + * @return $vars + */ + + function get_media_item_args( $vars ) { + + $vars['send'] = true; + return( $vars ); + + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + return acf_get_field_type( 'file' )->update_value( $value, $post_id, $field ); + + } + + + /* + * validate_value + * + * This function will validate a basic file input + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + return acf_get_field_type( 'file' )->validate_value( $valid, $value, $field, $input ); + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_image' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-link.php b/includes/fields/class-acf-field-link.php index d5bfb55..4c78de5 100644 --- a/includes/fields/class-acf-field-link.php +++ b/includes/fields/class-acf-field-link.php @@ -1,287 +1,291 @@ name = 'link'; - $this->label = __("Link",'acf'); - $this->category = 'relational'; - $this->defaults = array( - 'return_format' => 'array', - ); - - } - - - /* - * get_link - * - * description - * - * @type function - * @date 16/5/17 - * @since 5.5.13 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function get_link( $value = '' ) { - - // vars - $link = array( - 'title' => '', - 'url' => '', - 'target' => '' - ); - - - // array (ACF 5.6.0) - if( is_array($value) ) { - - $link = array_merge($link, $value); - - // post id (ACF < 5.6.0) - } elseif( is_numeric($value) ) { - - $link['title'] = get_the_title( $value ); - $link['url'] = get_permalink( $value ); - - // string (ACF < 5.6.0) - } elseif( is_string($value) ) { - - $link['url'] = $value; - - } - - - // return - return $link; - - } - + class acf_field_link extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'link'; + $this->label = __( 'Link', 'acf' ); + $this->category = 'relational'; + $this->defaults = array( + 'return_format' => 'array', + ); - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ){ - - // vars - $div = array( - 'id' => $field['id'], - 'class' => $field['class'] . ' acf-link', - ); - - - // render scripts/styles - acf_enqueue_uploader(); - - - // get link - $link = $this->get_link( $field['value'] ); - - - // classes - if( $link['url'] ) { - $div['class'] .= ' -value'; } - - if( $link['target'] === '_blank' ) { - $div['class'] .= ' -external'; + + + /* + * get_link + * + * description + * + * @type function + * @date 16/5/17 + * @since 5.5.13 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function get_link( $value = '' ) { + + // vars + $link = array( + 'title' => '', + 'url' => '', + 'target' => '', + ); + + // array (ACF 5.6.0) + if ( is_array( $value ) ) { + + $link = array_merge( $link, $value ); + + // post id (ACF < 5.6.0) + } elseif ( is_numeric( $value ) ) { + + $link['title'] = get_the_title( $value ); + $link['url'] = get_permalink( $value ); + + // string (ACF < 5.6.0) + } elseif ( is_string( $value ) ) { + + $link['url'] = $value; + + } + + // return + return $link; + } - - /**/ -?> -
                        > + ?>*/ + ?> +
                        >
                        - - $v ): ?> - "input-$k", 'name' => $field['name'] . "[$k]", 'value' => $v )); ?> + + $v ) : ?> + "input-$k", + 'name' => $field['name'] . "[$k]", + 'value' => $v, + ) + ); + ?>
                        - +
                        - __('Return Value','acf'), - 'instructions' => __('Specify the returned value on front end','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'layout' => 'horizontal', - 'choices' => array( - 'array' => __("Link Array",'acf'), - 'url' => __("Link URL",'acf'), - ) - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return $value; - - - // get link - $link = $this->get_link( $value ); - - - // format value - if( $field['return_format'] == 'url' ) { - - return $link['url']; - + __( 'Return Value', 'acf' ), + 'instructions' => __( 'Specify the returned value on front end', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'array' => __( 'Link Array', 'acf' ), + 'url' => __( 'Link URL', 'acf' ), + ), + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return $value; + } + + // get link + $link = $this->get_link( $value ); + + // format value + if ( $field['return_format'] == 'url' ) { + + return $link['url']; + + } + + // return link + return $link; + + } + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // bail early if not required + if ( ! $field['required'] ) { + return $valid; + } + + // URL is required + if ( empty( $value ) || empty( $value['url'] ) ) { + + return false; + + } + + // return + return $valid; + + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // Check if value is an empty array and convert to empty string. + if ( empty( $value ) || empty( $value['url'] ) ) { + $value = ''; + } + + // return + return $value; + } + } + + + // initialize + acf_register_field_type( 'acf_field_link' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-message.php b/includes/fields/class-acf-field-message.php index 3fd2118..f47d308 100644 --- a/includes/fields/class-acf-field-message.php +++ b/includes/fields/class-acf-field-message.php @@ -1,198 +1,200 @@ name = 'message'; + $this->label = __( 'Message', 'acf' ); + $this->category = 'layout'; + $this->defaults = array( + 'message' => '', + 'esc_html' => 0, + 'new_lines' => 'wpautop', + ); -class acf_field_message extends acf_field { - - - /* - * __construct - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'message'; - $this->label = __("Message",'acf'); - $this->category = 'layout'; - $this->defaults = array( - 'message' => '', - 'esc_html' => 0, - 'new_lines' => 'wpautop', - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $m = $field['message']; - - - // wptexturize (improves "quotes") - $m = wptexturize( $m ); - - - // esc_html - if( $field['esc_html'] ) { - - $m = esc_html( $m ); - } - - - // new lines - if( $field['new_lines'] == 'wpautop' ) { - - $m = wpautop($m); - - } elseif( $field['new_lines'] == 'br' ) { - - $m = nl2br($m); - + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $m = $field['message']; + + // wptexturize (improves "quotes") + $m = wptexturize( $m ); + + // esc_html + if ( $field['esc_html'] ) { + + $m = esc_html( $m ); + + } + + // new lines + if ( $field['new_lines'] == 'wpautop' ) { + + $m = wpautop( $m ); + + } elseif ( $field['new_lines'] == 'br' ) { + + $m = nl2br( $m ); + + } + + // return + echo acf_esc_html( $m ); + } - - - // return - echo acf_esc_html( $m ); - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Message','acf'), - 'instructions' => '', - 'type' => 'textarea', - 'name' => 'message', - )); - - - // formatting - acf_render_field_setting( $field, array( - 'label' => __('New Lines','acf'), - 'instructions' => __('Controls how new lines are rendered','acf'), - 'type' => 'select', - 'name' => 'new_lines', - 'choices' => array( - 'wpautop' => __("Automatically add paragraphs",'acf'), - 'br' => __("Automatically add <br>",'acf'), - '' => __("No Formatting",'acf') - ) - )); - - - // HTML - acf_render_field_setting( $field, array( - 'label' => __('Escape HTML','acf'), - 'instructions' => __('Allow HTML markup to display as visible text instead of rendering','acf'), - 'name' => 'esc_html', - 'type' => 'true_false', - 'ui' => 1, - )); - - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @type function - * @date 8/03/2016 - * @since 5.3.2 - * - * @param $field (array) - * @return $field - */ - - function translate_field( $field ) { - - // translate - $field['message'] = acf_translate( $field['message'] ); - - - // return - return $field; - - } - - - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - function load_field( $field ) { - - // remove name to avoid caching issue - $field['name'] = ''; - - // remove instructions - $field['instructions'] = ''; - - // remove required to avoid JS issues - $field['required'] = 0; - - // set value other than 'null' to avoid ACF loading / caching issue - $field['value'] = false; - - // return - return $field; - } - -} -// initialize -acf_register_field_type( 'acf_field_message' ); + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Message', 'acf' ), + 'instructions' => '', + 'type' => 'textarea', + 'name' => 'message', + ) + ); + + // formatting + acf_render_field_setting( + $field, + array( + 'label' => __( 'New Lines', 'acf' ), + 'instructions' => __( 'Controls how new lines are rendered', 'acf' ), + 'type' => 'select', + 'name' => 'new_lines', + 'choices' => array( + 'wpautop' => __( 'Automatically add paragraphs', 'acf' ), + 'br' => __( 'Automatically add <br>', 'acf' ), + '' => __( 'No Formatting', 'acf' ), + ), + ) + ); + + // HTML + acf_render_field_setting( + $field, + array( + 'label' => __( 'Escape HTML', 'acf' ), + 'instructions' => __( 'Allow HTML markup to display as visible text instead of rendering', 'acf' ), + 'name' => 'esc_html', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + } + + + /* + * translate_field + * + * This function will translate field settings + * + * @type function + * @date 8/03/2016 + * @since 5.3.2 + * + * @param $field (array) + * @return $field + */ + + function translate_field( $field ) { + + // translate + $field['message'] = acf_translate( $field['message'] ); + + // return + return $field; + + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + function load_field( $field ) { + + // remove name to avoid caching issue + $field['name'] = ''; + + // remove instructions + $field['instructions'] = ''; + + // remove required to avoid JS issues + $field['required'] = 0; + + // set value other than 'null' to avoid ACF loading / caching issue + $field['value'] = false; + + // return + return $field; + } + + } + + + // initialize + acf_register_field_type( 'acf_field_message' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-number.php b/includes/fields/class-acf-field-number.php index 0395471..c24d547 100644 --- a/includes/fields/class-acf-field-number.php +++ b/includes/fields/class-acf-field-number.php @@ -1,304 +1,307 @@ name = 'number'; + $this->label = __( 'Number', 'acf' ); + $this->defaults = array( + 'default_value' => '', + 'min' => '', + 'max' => '', + 'step' => '', + 'placeholder' => '', + 'prepend' => '', + 'append' => '', + ); -class acf_field_number extends acf_field { - - - /* - * initialize - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'number'; - $this->label = __("Number",'acf'); - $this->defaults = array( - 'default_value' => '', - 'min' => '', - 'max' => '', - 'step' => '', - 'placeholder' => '', - 'prepend' => '', - 'append' => '' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $atts = array(); - $keys = array( 'type', 'id', 'class', 'name', 'value', 'min', 'max', 'step', 'placeholder', 'pattern' ); - $keys2 = array( 'readonly', 'disabled', 'required' ); - $html = ''; - - - // step - if( !$field['step'] ) { - $field['step'] = 'any'; } - - - // prepend - if( $field['prepend'] !== '' ) { - - $field['class'] .= ' acf-is-prepended'; - $html .= '
                        ' . acf_esc_html($field['prepend']) . '
                        '; - - } - - - // append - if( $field['append'] !== '' ) { - - $field['class'] .= ' acf-is-appended'; - $html .= '
                        ' . acf_esc_html($field['append']) . '
                        '; - - } - - - // atts (value="123") - foreach( $keys as $k ) { - if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ]; - } - - - // atts2 (disabled="disabled") - foreach( $keys2 as $k ) { - if( !empty($field[ $k ]) ) $atts[ $k ] = $k; - } - - - // remove empty atts - $atts = acf_clean_atts( $atts ); - - - // render - $html .= '
                        ' . acf_get_text_input( $atts ) . '
                        '; - - - // return - echo $html; - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'text', - 'name' => 'default_value', - )); - - - // placeholder - acf_render_field_setting( $field, array( - 'label' => __('Placeholder Text','acf'), - 'instructions' => __('Appears within the input','acf'), - 'type' => 'text', - 'name' => 'placeholder', - )); - - - // prepend - acf_render_field_setting( $field, array( - 'label' => __('Prepend','acf'), - 'instructions' => __('Appears before the input','acf'), - 'type' => 'text', - 'name' => 'prepend', - )); - - - // append - acf_render_field_setting( $field, array( - 'label' => __('Append','acf'), - 'instructions' => __('Appears after the input','acf'), - 'type' => 'text', - 'name' => 'append', - )); - - - // min - acf_render_field_setting( $field, array( - 'label' => __('Minimum Value','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'min', - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Maximum Value','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'max', - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Step Size','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'step', - )); - - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // remove ',' - if( acf_str_exists(',', $value) ) { - - $value = str_replace(',', '', $value); - - } - - - // if value is not numeric... - if( !is_numeric($value) ) { - - // allow blank to be saved - if( !empty($value) ) { - - $valid = __('Value must be a number', 'acf'); - + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $atts = array(); + $keys = array( 'type', 'id', 'class', 'name', 'value', 'min', 'max', 'step', 'placeholder', 'pattern' ); + $keys2 = array( 'readonly', 'disabled', 'required' ); + $html = ''; + + // step + if ( ! $field['step'] ) { + $field['step'] = 'any'; } - - - // return early + + // prepend + if ( $field['prepend'] !== '' ) { + + $field['class'] .= ' acf-is-prepended'; + $html .= '
                        ' . acf_esc_html( $field['prepend'] ) . '
                        '; + + } + + // append + if ( $field['append'] !== '' ) { + + $field['class'] .= ' acf-is-appended'; + $html .= '
                        ' . acf_esc_html( $field['append'] ) . '
                        '; + + } + + // atts (value="123") + foreach ( $keys as $k ) { + if ( isset( $field[ $k ] ) ) { + $atts[ $k ] = $field[ $k ]; + } + } + + // atts2 (disabled="disabled") + foreach ( $keys2 as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $atts[ $k ] = $k; + } + } + + // remove empty atts + $atts = acf_clean_atts( $atts ); + + // render + $html .= '
                        ' . acf_get_text_input( $atts ) . '
                        '; + + // return + echo $html; + + } + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'text', + 'name' => 'default_value', + ) + ); + + // placeholder + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placeholder Text', 'acf' ), + 'instructions' => __( 'Appears within the input', 'acf' ), + 'type' => 'text', + 'name' => 'placeholder', + ) + ); + + // prepend + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prepend', 'acf' ), + 'instructions' => __( 'Appears before the input', 'acf' ), + 'type' => 'text', + 'name' => 'prepend', + ) + ); + + // append + acf_render_field_setting( + $field, + array( + 'label' => __( 'Append', 'acf' ), + 'instructions' => __( 'Appears after the input', 'acf' ), + 'type' => 'text', + 'name' => 'append', + ) + ); + + // min + acf_render_field_setting( + $field, + array( + 'label' => __( 'Minimum Value', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'min', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Maximum Value', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'max', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Step Size', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'step', + ) + ); + + } + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // remove ',' + if ( acf_str_exists( ',', $value ) ) { + + $value = str_replace( ',', '', $value ); + + } + + // if value is not numeric... + if ( ! is_numeric( $value ) ) { + + // allow blank to be saved + if ( ! empty( $value ) ) { + + $valid = __( 'Value must be a number', 'acf' ); + + } + + // return early + return $valid; + + } + + // convert + $value = floatval( $value ); + + // min + if ( is_numeric( $field['min'] ) && $value < floatval( $field['min'] ) ) { + + $valid = sprintf( __( 'Value must be equal to or higher than %d', 'acf' ), $field['min'] ); + + } + + // max + if ( is_numeric( $field['max'] ) && $value > floatval( $field['max'] ) ) { + + $valid = sprintf( __( 'Value must be equal to or lower than %d', 'acf' ), $field['max'] ); + + } + + // return return $valid; - + } - - - // convert - $value = floatval($value); - - - // min - if( is_numeric($field['min']) && $value < floatval($field['min'])) { - - $valid = sprintf(__('Value must be equal to or higher than %d', 'acf'), $field['min'] ); - - } - - - // max - if( is_numeric($field['max']) && $value > floatval($field['max']) ) { - - $valid = sprintf(__('Value must be equal to or lower than %d', 'acf'), $field['max'] ); - - } - - - // return - return $valid; - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $field - the field array holding all the field options - * @param $post_id - the $post_id of which the value will be saved - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // no formatting needed for empty value - if( empty($value) ) { - + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $field - the field array holding all the field options + * @param $post_id - the $post_id of which the value will be saved + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // no formatting needed for empty value + if ( empty( $value ) ) { + + return $value; + + } + + // remove ',' + if ( acf_str_exists( ',', $value ) ) { + + $value = str_replace( ',', '', $value ); + + } + + // return return $value; - + } - - - // remove ',' - if( acf_str_exists(',', $value) ) { - - $value = str_replace(',', '', $value); - - } - - - // return - return $value; - + + } - - -} -// initialize -acf_register_field_type( 'acf_field_number' ); + // initialize + acf_register_field_type( 'acf_field_number' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-oembed.php b/includes/fields/class-acf-field-oembed.php index 6e59465..70fd083 100644 --- a/includes/fields/class-acf-field-oembed.php +++ b/includes/fields/class-acf-field-oembed.php @@ -1,219 +1,237 @@ name = 'oembed'; + $this->label = __( 'oEmbed', 'acf' ); + $this->category = 'content'; + $this->defaults = array( + 'width' => '', + 'height' => '', + ); + $this->width = 640; + $this->height = 390; + + // extra + add_action( 'wp_ajax_acf/fields/oembed/search', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/oembed/search', array( $this, 'ajax_query' ) ); -class acf_field_oembed extends acf_field { - - - /* - * __construct - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'oembed'; - $this->label = __("oEmbed",'acf'); - $this->category = 'content'; - $this->defaults = array( - 'width' => '', - 'height' => '', - ); - $this->width = 640; - $this->height = 390; - - - // extra - add_action('wp_ajax_acf/fields/oembed/search', array($this, 'ajax_query')); - add_action('wp_ajax_nopriv_acf/fields/oembed/search', array($this, 'ajax_query')); - - } - - - /* - * prepare_field - * - * This function will prepare the field for input - * - * @type function - * @date 14/2/17 - * @since 5.5.8 - * - * @param $field (array) - * @return (int) - */ - - function prepare_field( $field ) { - - // defaults - if( !$field['width'] ) $field['width'] = $this->width; - if( !$field['height'] ) $field['height'] = $this->height; - - - // return - return $field; - - } - - - /* - * wp_oembed_get - * - * description - * - * @type function - * @date 24/01/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function wp_oembed_get( $url = '', $width = 0, $height = 0 ) { - - // vars - $embed = ''; - $res = array( - 'width' => $width, - 'height' => $height - ); - - - // get emebed - $embed = @wp_oembed_get( $url, $res ); - - - // try shortcode - if( !$embed ) { - - // global - global $wp_embed; - - - // get emebed - $embed = $wp_embed->shortcode($res, $url); - } - - - // return - return $embed; - } + + + /* + * prepare_field + * + * This function will prepare the field for input + * + * @type function + * @date 14/2/17 + * @since 5.5.8 + * + * @param $field (array) + * @return (int) + */ + + function prepare_field( $field ) { + + // defaults + if ( ! $field['width'] ) { + $field['width'] = $this->width; + } + if ( ! $field['height'] ) { + $field['height'] = $this->height; + } + + // return + return $field; + + } + + + /* + * wp_oembed_get + * + * description + * + * @type function + * @date 24/01/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function wp_oembed_get( $url = '', $width = 0, $height = 0 ) { + + // vars + $embed = ''; + $res = array( + 'width' => $width, + 'height' => $height, + ); + + // get emebed + $embed = @wp_oembed_get( $url, $res ); + + // try shortcode + if ( ! $embed ) { + + // global + global $wp_embed; + + // get emebed + $embed = $wp_embed->shortcode( $res, $url ); + + } + + // return + return $embed; + } + + + /* + * ajax_query + * + * description + * + * @type function + * @date 24/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // get choices + $response = $this->get_ajax_query( $_POST ); + + // return + wp_send_json( $response ); + + } + + + /* + * get_ajax_query + * + * This function will return an array of data formatted for use in a select2 AJAX response + * + * @type function + * @date 15/10/2014 + * @since 5.0.9 + * + * @param $options (array) + * @return (array) + */ + + function get_ajax_query( $args = array() ) { + + // defaults + $args = acf_parse_args( + $args, + array( + 's' => '', + 'field_key' => '', + ) + ); + + // load field + $field = acf_get_field( $args['field_key'] ); + if ( ! $field ) { + return false; + } + + // prepare field to correct width and height + $field = $this->prepare_field( $field ); + + // vars + $response = array( + 'url' => $args['s'], + 'html' => $this->wp_oembed_get( $args['s'], $field['width'], $field['height'] ), + ); + + // return + return $response; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // atts + $atts = array( + 'class' => 'acf-oembed', + ); + + // _e("No embed found for the given URL.", 'acf'); + + // value + if ( $field['value'] ) { + $atts['class'] .= ' has-value'; + } + + ?> +
                        > - - /* - * ajax_query - * - * description - * - * @type function - * @date 24/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // get choices - $response = $this->get_ajax_query( $_POST ); - - - // return - wp_send_json($response); - - } - - - /* - * get_ajax_query - * - * This function will return an array of data formatted for use in a select2 AJAX response - * - * @type function - * @date 15/10/2014 - * @since 5.0.9 - * - * @param $options (array) - * @return (array) - */ - - function get_ajax_query( $args = array() ) { - - // defaults - $args = acf_parse_args($args, array( - 's' => '', - 'field_key' => '', - )); - - - // load field - $field = acf_get_field( $args['field_key'] ); - if( !$field ) return false; - - - // prepare field to correct width and height - $field = $this->prepare_field($field); - - - // vars - $response = array( - 'url' => $args['s'], - 'html' => $this->wp_oembed_get($args['s'], $field['width'], $field['height']) - ); - - - // return - return $response; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // atts - $atts = array( - 'class' => 'acf-oembed', - ); - - // _e("No embed found for the given URL.", 'acf'); - - // value - if( $field['value'] ) $atts['class'] .= ' has-value'; - -?> -
                        > - - 'input-value', 'name' => $field['name'], 'value' => $field['value'] )); ?> + 'input-value', + 'name' => $field['name'], + 'value' => $field['value'], + ) + ); + ?>
                        - 'input-search', 'value' => $field['value'], 'placeholder' => __("Enter URL", 'acf'), 'autocomplete' => 'off' )); ?> + 'input-search', + 'value' => $field['value'], + 'placeholder' => __( 'Enter URL', 'acf' ), + 'autocomplete' => 'off', + ) + ); + ?>
                        @@ -221,100 +239,106 @@ class acf_field_oembed extends acf_field {
                        - wp_oembed_get($field['value'], $field['width'], $field['height']); - } ?> + wp_oembed_get( $field['value'], $field['width'], $field['height'] ); + } + ?>
                        - __('Embed Size','acf'), - 'type' => 'text', - 'name' => 'width', - 'prepend' => __('Width', 'acf'), - 'append' => 'px', - 'placeholder' => $this->width - )); - - - // height - acf_render_field_setting( $field, array( - 'label' => __('Embed Size','acf'), - 'type' => 'text', - 'name' => 'height', - 'prepend' => __('Height', 'acf'), - 'append' => 'px', - 'placeholder' => $this->height, - '_append' => 'width' - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return $value; - - - // prepare field to correct width and height - $field = $this->prepare_field($field); - - - // get oembed - $value = $this->wp_oembed_get($value, $field['width'], $field['height']); - - - // return - return $value; - - } - -} + __( 'Embed Size', 'acf' ), + 'type' => 'text', + 'name' => 'width', + 'prepend' => __( 'Width', 'acf' ), + 'append' => 'px', + 'placeholder' => $this->width, + ) + ); + + // height + acf_render_field_setting( + $field, + array( + 'label' => __( 'Embed Size', 'acf' ), + 'type' => 'text', + 'name' => 'height', + 'prepend' => __( 'Height', 'acf' ), + 'append' => 'px', + 'placeholder' => $this->height, + '_append' => 'width', + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return $value; + } + + // prepare field to correct width and height + $field = $this->prepare_field( $field ); + + // get oembed + $value = $this->wp_oembed_get( $value, $field['width'], $field['height'] ); + + // return + return $value; + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_oembed' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-output.php b/includes/fields/class-acf-field-output.php index 25ff37c..43b6c4c 100644 --- a/includes/fields/class-acf-field-output.php +++ b/includes/fields/class-acf-field-output.php @@ -1,77 +1,78 @@ name = 'output'; + $this->label = 'output'; + $this->public = false; + $this->defaults = array( + 'html' => false, + ); -class acf_field_output extends acf_field { - - - /* - * __construct - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'output'; - $this->label = 'output'; - $this->public = false; - $this->defaults = array( - 'html' => false - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field (array) the $field being rendered - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field (array) the $field being edited - * @return n/a - */ - - function render_field( $field ) { - - // bail early if no html - if( !$field['html'] ) return; - - - // html - if( is_string($field['html']) && !function_exists($field['html']) ) { - - echo $field['html']; - - // function - } else { - - call_user_func_array($field['html'], array($field)); - } - + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field (array) the $field being rendered + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field (array) the $field being edited + * @return n/a + */ + + function render_field( $field ) { + + // bail early if no html + if ( ! $field['html'] ) { + return; + } + + // html + if ( is_string( $field['html'] ) && ! function_exists( $field['html'] ) ) { + + echo $field['html']; + + // function + } else { + + call_user_func_array( $field['html'], array( $field ) ); + + } + + } + } - -} -// initialize -acf_register_field_type( 'acf_field_output' ); + // initialize + acf_register_field_type( 'acf_field_output' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-page_link.php b/includes/fields/class-acf-field-page_link.php index 1df89d4..eae797b 100644 --- a/includes/fields/class-acf-field-page_link.php +++ b/includes/fields/class-acf-field-page_link.php @@ -1,656 +1,630 @@ name = 'page_link'; - $this->label = __("Page Link",'acf'); - $this->category = 'relational'; - $this->defaults = array( - 'post_type' => array(), - 'taxonomy' => array(), - 'allow_null' => 0, - 'multiple' => 0, - 'allow_archives' => 1 - ); - - - // extra - add_action('wp_ajax_acf/fields/page_link/query', array($this, 'ajax_query')); - add_action('wp_ajax_nopriv_acf/fields/page_link/query', array($this, 'ajax_query')); - - } - - - /* - * ajax_query - * - * description - * - * @type function - * @date 24/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // defaults - $options = acf_parse_args($_POST, array( - 'post_id' => 0, - 's' => '', - 'field_key' => '', - 'paged' => 1 - )); - - - // vars - $results = array(); - $args = array(); - $s = false; - $is_search = false; - - - // paged - $args['posts_per_page'] = 20; - $args['paged'] = $options['paged']; - - - // search - if( $options['s'] !== '' ) { - - // strip slashes (search may be integer) - $s = wp_unslash( strval($options['s']) ); - - - // update vars - $args['s'] = $s; - $is_search = true; - - } - - - // load field - $field = acf_get_field( $options['field_key'] ); - if( !$field ) die(); - - - // update $args - if( !empty($field['post_type']) ) { - - $args['post_type'] = acf_get_array( $field['post_type'] ); - - } else { - - $args['post_type'] = acf_get_post_types(); - - } - - // create tax queries - if( !empty($field['taxonomy']) ) { - - // append to $args - $args['tax_query'] = array(); - - - // decode terms - $taxonomies = acf_decode_taxonomy_terms( $field['taxonomy'] ); - - - // now create the tax queries - foreach( $taxonomies as $taxonomy => $terms ) { - - $args['tax_query'][] = array( - 'taxonomy' => $taxonomy, - 'field' => 'slug', - 'terms' => $terms, - ); - - } - } - - - // filters - $args = apply_filters('acf/fields/page_link/query', $args, $field, $options['post_id']); - $args = apply_filters('acf/fields/page_link/query/name=' . $field['name'], $args, $field, $options['post_id'] ); - $args = apply_filters('acf/fields/page_link/query/key=' . $field['key'], $args, $field, $options['post_id'] ); - - - // add archives to $results - if( $field['allow_archives'] && $args['paged'] == 1 ) { - - // Generate unique list of URLs. - $links = array(); - $links[] = home_url(); - foreach( $args['post_type'] as $post_type ) { - $links[] = get_post_type_archive_link( $post_type ); - } - $links = array_filter( $links ); - $links = array_unique( $links ); + class acf_field_page_link extends acf_field { - // Convert list into choices. - $children = array(); - foreach( $links as $link ) { - // Ignore if search does not match. - if( $is_search && stripos($link, $s) === false ) { - continue; - } - $children[] = array( - 'id' => $link, - 'text' => $link - ); - } - if( $children ) { - $results[] = array( - 'text' => __('Archives', 'acf'), - 'children' => $children - ); - } - } - - - // get posts grouped by post type - $groups = acf_get_grouped_posts( $args ); - - - // loop - if( !empty($groups) ) { - - foreach( array_keys($groups) as $group_title ) { - - // vars - $posts = acf_extract_var( $groups, $group_title ); - - - // data - $data = array( - 'text' => $group_title, - 'children' => array() - ); - - - // convert post objects to post titles - foreach( array_keys($posts) as $post_id ) { - - $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'], $is_search ); - - } - - - // order posts by search - if( $is_search && empty($args['orderby']) && isset($args['s']) ) { - - $posts = acf_order_by_search( $posts, $args['s'] ); - - } - - - // append to $data - foreach( array_keys($posts) as $post_id ) { - - $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ]); - - } - - - // append to $results - $results[] = $data; - - } - - } - - - // return - acf_send_ajax_results(array( - 'results' => $results, - 'limit' => $args['posts_per_page'] - )); - - } - - - /* - * get_post_result - * - * This function will return an array containing id, text and maybe description data - * - * @type function - * @date 7/07/2016 - * @since 5.4.0 - * - * @param $id (mixed) - * @param $text (string) - * @return (array) - */ - - function get_post_result( $id, $text ) { - - // vars - $result = array( - 'id' => $id, - 'text' => $text - ); - - - // look for parent - $search = '| ' . __('Parent', 'acf') . ':'; - $pos = strpos($text, $search); - - if( $pos !== false ) { - - $result['description'] = substr($text, $pos+2); - $result['text'] = substr($text, 0, $pos); - - } - - - // return - return $result; - - } - - - /* - * get_post_title - * - * This function returns the HTML for a result - * - * @type function - * @date 1/11/2013 - * @since 5.0.0 - * - * @param $post (object) - * @param $field (array) - * @param $post_id (int) the post_id to which this value is saved to - * @return (string) - */ - - function get_post_title( $post, $field, $post_id = 0, $is_search = 0 ) { - - // get post_id - if( !$post_id ) $post_id = acf_get_form_data('post_id'); - - - // vars - $title = acf_get_post_title( $post, $is_search ); - - - // filters - $title = apply_filters('acf/fields/page_link/result', $title, $post, $field, $post_id); - $title = apply_filters('acf/fields/page_link/result/name=' . $field['_name'], $title, $post, $field, $post_id); - $title = apply_filters('acf/fields/page_link/result/key=' . $field['key'], $title, $post, $field, $post_id); - - - // return - return $title; - - } - - - /* - * get_posts - * - * This function will return an array of posts for a given field value - * - * @type function - * @date 13/06/2014 - * @since 5.0.0 - * - * @param $value (array) - * @return $value - */ - - function get_posts( $value, $field ) { - - // force value to array - $value = acf_get_array( $value ); - - - // get selected post ID's - $post__in = array(); - - foreach( $value as $k => $v ) { - - if( is_numeric($v) ) { - - // append to $post__in - $post__in[] = (int) $v; - - } - - } - - - // bail early if no posts - if( empty($post__in) ) { - - return $value; - - } - - - // get posts - $posts = acf_get_posts(array( - 'post__in' => $post__in, - 'post_type' => $field['post_type'] - )); - - - // override value with post - $return = array(); - - - // append to $return - foreach( $value as $k => $v ) { - - if( is_numeric($v) ) { - - // extract first post - $post = array_shift( $posts ); - - - // append - if( $post ) { - - $return[] = $post; - - } - - } else { - - $return[] = $v; - - } - - } - - - // return - return $return; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ){ - - // Change Field into a select - $field['type'] = 'select'; - $field['ui'] = 1; - $field['ajax'] = 1; - $field['choices'] = array(); - - - // populate choices if value exists - if( !empty($field['value']) ) { - - // get posts - $posts = $this->get_posts( $field['value'], $field ); - - - // set choices - if( !empty($posts) ) { - - foreach( array_keys($posts) as $i ) { - - // vars - $post = acf_extract_var( $posts, $i ); - - - if( is_object($post) ) { - - // append to choices - $field['choices'][ $post->ID ] = $this->get_post_title( $post, $field ); - - } else { - - // append to choices - $field['choices'][ $post ] = $post; - - } - - } - - } - - } - - - // render - acf_render_field( $field ); - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // post_type - acf_render_field_setting( $field, array( - 'label' => __('Filter by Post Type','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'post_type', - 'choices' => acf_get_pretty_post_types(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All post types",'acf'), - )); - - - // taxonomy - acf_render_field_setting( $field, array( - 'label' => __('Filter by Taxonomy','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'taxonomy', - 'choices' => acf_get_taxonomy_terms(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All taxonomies",'acf'), - )); - - - // allow_null - acf_render_field_setting( $field, array( - 'label' => __('Allow Null?','acf'), - 'instructions' => '', - 'name' => 'allow_null', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // allow_archives - acf_render_field_setting( $field, array( - 'label' => __('Allow Archives URLs','acf'), - 'instructions' => '', - 'name' => 'allow_archives', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // multiple - acf_render_field_setting( $field, array( - 'label' => __('Select multiple values?','acf'), - 'instructions' => '', - 'name' => 'multiple', - 'type' => 'true_false', - 'ui' => 1, - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // ACF4 null - if( $value === 'null' ) { - - return false; - - } - - - // bail early if no value - if( empty($value) ) { - - return $value; - - } - - - // get posts - $value = $this->get_posts( $value, $field ); - - - // set choices - foreach( array_keys($value) as $i ) { - + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + // vars - $post = acf_extract_var( $value, $i ); - - - // convert $post to permalink - if( is_object($post) ) { - - $post = get_permalink( $post ); - + $this->name = 'page_link'; + $this->label = __( 'Page Link', 'acf' ); + $this->category = 'relational'; + $this->defaults = array( + 'post_type' => array(), + 'taxonomy' => array(), + 'allow_null' => 0, + 'multiple' => 0, + 'allow_archives' => 1, + ); + + // extra + add_action( 'wp_ajax_acf/fields/page_link/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/page_link/query', array( $this, 'ajax_query' ) ); + + } + + + /* + * ajax_query + * + * description + * + * @type function + * @date 24/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); } - - - // append back to $value - $value[ $i ] = $post; - + + // defaults + $options = acf_parse_args( + $_POST, + array( + 'post_id' => 0, + 's' => '', + 'field_key' => '', + 'paged' => 1, + ) + ); + + // vars + $results = array(); + $args = array(); + $s = false; + $is_search = false; + + // paged + $args['posts_per_page'] = 20; + $args['paged'] = $options['paged']; + + // search + if ( $options['s'] !== '' ) { + + // strip slashes (search may be integer) + $s = wp_unslash( strval( $options['s'] ) ); + + // update vars + $args['s'] = $s; + $is_search = true; + + } + + // load field + $field = acf_get_field( $options['field_key'] ); + if ( ! $field ) { + die(); + } + + // update $args + if ( ! empty( $field['post_type'] ) ) { + + $args['post_type'] = acf_get_array( $field['post_type'] ); + + } else { + + $args['post_type'] = acf_get_post_types(); + + } + + // create tax queries + if ( ! empty( $field['taxonomy'] ) ) { + + // append to $args + $args['tax_query'] = array(); + + // decode terms + $taxonomies = acf_decode_taxonomy_terms( $field['taxonomy'] ); + + // now create the tax queries + foreach ( $taxonomies as $taxonomy => $terms ) { + + $args['tax_query'][] = array( + 'taxonomy' => $taxonomy, + 'field' => 'slug', + 'terms' => $terms, + ); + + } + } + + // filters + $args = apply_filters( 'acf/fields/page_link/query', $args, $field, $options['post_id'] ); + $args = apply_filters( 'acf/fields/page_link/query/name=' . $field['name'], $args, $field, $options['post_id'] ); + $args = apply_filters( 'acf/fields/page_link/query/key=' . $field['key'], $args, $field, $options['post_id'] ); + + // add archives to $results + if ( $field['allow_archives'] && $args['paged'] == 1 ) { + + // Generate unique list of URLs. + $links = array(); + $links[] = home_url(); + foreach ( $args['post_type'] as $post_type ) { + $links[] = get_post_type_archive_link( $post_type ); + } + $links = array_filter( $links ); + $links = array_unique( $links ); + + // Convert list into choices. + $children = array(); + foreach ( $links as $link ) { + + // Ignore if search does not match. + if ( $is_search && stripos( $link, $s ) === false ) { + continue; + } + $children[] = array( + 'id' => $link, + 'text' => $link, + ); + } + if ( $children ) { + $results[] = array( + 'text' => __( 'Archives', 'acf' ), + 'children' => $children, + ); + } + } + + // get posts grouped by post type + $groups = acf_get_grouped_posts( $args ); + + // loop + if ( ! empty( $groups ) ) { + + foreach ( array_keys( $groups ) as $group_title ) { + + // vars + $posts = acf_extract_var( $groups, $group_title ); + + // data + $data = array( + 'text' => $group_title, + 'children' => array(), + ); + + // convert post objects to post titles + foreach ( array_keys( $posts ) as $post_id ) { + + $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'], $is_search ); + + } + + // order posts by search + if ( $is_search && empty( $args['orderby'] ) && isset( $args['s'] ) ) { + + $posts = acf_order_by_search( $posts, $args['s'] ); + + } + + // append to $data + foreach ( array_keys( $posts ) as $post_id ) { + + $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ] ); + + } + + // append to $results + $results[] = $data; + + } + } + + // return + acf_send_ajax_results( + array( + 'results' => $results, + 'limit' => $args['posts_per_page'], + ) + ); + } - - - // convert back from array if neccessary - if( !$field['multiple'] ) { - - $value = array_shift($value); - + + + /* + * get_post_result + * + * This function will return an array containing id, text and maybe description data + * + * @type function + * @date 7/07/2016 + * @since 5.4.0 + * + * @param $id (mixed) + * @param $text (string) + * @return (array) + */ + + function get_post_result( $id, $text ) { + + // vars + $result = array( + 'id' => $id, + 'text' => $text, + ); + + // look for parent + $search = '| ' . __( 'Parent', 'acf' ) . ':'; + $pos = strpos( $text, $search ); + + if ( $pos !== false ) { + + $result['description'] = substr( $text, $pos + 2 ); + $result['text'] = substr( $text, 0, $pos ); + + } + + // return + return $result; + } - - - // return value - return $value; - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( empty($value) ) { + + + /* + * get_post_title + * + * This function returns the HTML for a result + * + * @type function + * @date 1/11/2013 + * @since 5.0.0 + * + * @param $post (object) + * @param $field (array) + * @param $post_id (int) the post_id to which this value is saved to + * @return (string) + */ + + function get_post_title( $post, $field, $post_id = 0, $is_search = 0 ) { + + // get post_id + if ( ! $post_id ) { + $post_id = acf_get_form_data( 'post_id' ); + } + + // vars + $title = acf_get_post_title( $post, $is_search ); + + // filters + $title = apply_filters( 'acf/fields/page_link/result', $title, $post, $field, $post_id ); + $title = apply_filters( 'acf/fields/page_link/result/name=' . $field['_name'], $title, $post, $field, $post_id ); + $title = apply_filters( 'acf/fields/page_link/result/key=' . $field['key'], $title, $post, $field, $post_id ); + + // return + return $title; + + } + + + /* + * get_posts + * + * This function will return an array of posts for a given field value + * + * @type function + * @date 13/06/2014 + * @since 5.0.0 + * + * @param $value (array) + * @return $value + */ + + function get_posts( $value, $field ) { + + // force value to array + $value = acf_get_array( $value ); + + // get selected post ID's + $post__in = array(); + + foreach ( $value as $k => $v ) { + + if ( is_numeric( $v ) ) { + + // append to $post__in + $post__in[] = (int) $v; + + } + } + + // bail early if no posts + if ( empty( $post__in ) ) { + + return $value; + + } + + // get posts + $posts = acf_get_posts( + array( + 'post__in' => $post__in, + 'post_type' => $field['post_type'], + ) + ); + + // override value with post + $return = array(); + + // append to $return + foreach ( $value as $k => $v ) { + + if ( is_numeric( $v ) ) { + + // extract first post + $post = array_shift( $posts ); + + // append + if ( $post ) { + + $return[] = $post; + + } + } else { + + $return[] = $v; + + } + } + + // return + return $return; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // Change Field into a select + $field['type'] = 'select'; + $field['ui'] = 1; + $field['ajax'] = 1; + $field['choices'] = array(); + + // populate choices if value exists + if ( ! empty( $field['value'] ) ) { + + // get posts + $posts = $this->get_posts( $field['value'], $field ); + + // set choices + if ( ! empty( $posts ) ) { + + foreach ( array_keys( $posts ) as $i ) { + + // vars + $post = acf_extract_var( $posts, $i ); + + if ( is_object( $post ) ) { + + // append to choices + $field['choices'][ $post->ID ] = $this->get_post_title( $post, $field ); + + } else { + + // append to choices + $field['choices'][ $post ] = $post; + + } + } + } + } + + // render + acf_render_field( $field ); + } + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // post_type + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by Post Type', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'post_type', + 'choices' => acf_get_pretty_post_types(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All post types', 'acf' ), + ) + ); + + // taxonomy + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by Taxonomy', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'taxonomy', + 'choices' => acf_get_taxonomy_terms(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All taxonomies', 'acf' ), + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // allow_archives + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Archives URLs', 'acf' ), + 'instructions' => '', + 'name' => 'allow_archives', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // multiple + acf_render_field_setting( + $field, + array( + 'label' => __( 'Select multiple values?', 'acf' ), + 'instructions' => '', + 'name' => 'multiple', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // ACF4 null + if ( $value === 'null' ) { + + return false; + + } + + // bail early if no value + if ( empty( $value ) ) { + + return $value; + + } + + // get posts + $value = $this->get_posts( $value, $field ); + + // set choices + foreach ( array_keys( $value ) as $i ) { + + // vars + $post = acf_extract_var( $value, $i ); + + // convert $post to permalink + if ( is_object( $post ) ) { + + $post = get_permalink( $post ); + + } + + // append back to $value + $value[ $i ] = $post; + + } + + // convert back from array if neccessary + if ( ! $field['multiple'] ) { + + $value = array_shift( $value ); + + } + + // return value + return $value; + + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( empty( $value ) ) { + return $value; + } + + // Format array of values. + // - ensure each value is an id. + // - Parse each id as string for SQL LIKE queries. + if ( acf_is_sequential_array( $value ) ) { + $value = array_map( 'acf_maybe_idval', $value ); + $value = array_map( 'strval', $value ); + + // Parse single value for id. + } else { + $value = acf_maybe_idval( $value ); + } + + // Return value. return $value; } - - // Format array of values. - // - ensure each value is an id. - // - Parse each id as string for SQL LIKE queries. - if( acf_is_sequential_array($value) ) { - $value = array_map('acf_maybe_idval', $value); - $value = array_map('strval', $value); - - // Parse single value for id. - } else { - $value = acf_maybe_idval( $value ); - } - - // Return value. - return $value; + } - -} -// initialize -acf_register_field_type( 'acf_field_page_link' ); + // initialize + acf_register_field_type( 'acf_field_page_link' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-password.php b/includes/fields/class-acf-field-password.php index cb0efe2..100a108 100644 --- a/includes/fields/class-acf-field-password.php +++ b/includes/fields/class-acf-field-password.php @@ -1,104 +1,111 @@ name = 'password'; - $this->label = __("Password",'acf'); - $this->defaults = array( - 'placeholder' => '', - 'prepend' => '', - 'append' => '', - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - acf_get_field_type('text')->render_field( $field ); - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // placeholder - acf_render_field_setting( $field, array( - 'label' => __('Placeholder Text','acf'), - 'instructions' => __('Appears within the input','acf'), - 'type' => 'text', - 'name' => 'placeholder', - )); - - - // prepend - acf_render_field_setting( $field, array( - 'label' => __('Prepend','acf'), - 'instructions' => __('Appears before the input','acf'), - 'type' => 'text', - 'name' => 'prepend', - )); - - - // append - acf_render_field_setting( $field, array( - 'label' => __('Append','acf'), - 'instructions' => __('Appears after the input','acf'), - 'type' => 'text', - 'name' => 'append', - )); - } - -} + class acf_field_password extends acf_field { -// initialize -acf_register_field_type( 'acf_field_password' ); + /* + * initialize + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'password'; + $this->label = __( 'Password', 'acf' ); + $this->defaults = array( + 'placeholder' => '', + 'prepend' => '', + 'append' => '', + ); + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + acf_get_field_type( 'text' )->render_field( $field ); + + } + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // placeholder + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placeholder Text', 'acf' ), + 'instructions' => __( 'Appears within the input', 'acf' ), + 'type' => 'text', + 'name' => 'placeholder', + ) + ); + + // prepend + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prepend', 'acf' ), + 'instructions' => __( 'Appears before the input', 'acf' ), + 'type' => 'text', + 'name' => 'prepend', + ) + ); + + // append + acf_render_field_setting( + $field, + array( + 'label' => __( 'Append', 'acf' ), + 'instructions' => __( 'Appears after the input', 'acf' ), + 'type' => 'text', + 'name' => 'append', + ) + ); + } + + } + + + // initialize + acf_register_field_type( 'acf_field_password' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-post_object.php b/includes/fields/class-acf-field-post_object.php index f41d248..d1d47e4 100644 --- a/includes/fields/class-acf-field-post_object.php +++ b/includes/fields/class-acf-field-post_object.php @@ -1,603 +1,591 @@ name = 'post_object'; - $this->label = __("Post Object",'acf'); - $this->category = 'relational'; - $this->defaults = array( - 'post_type' => array(), - 'taxonomy' => array(), - 'allow_null' => 0, - 'multiple' => 0, - 'return_format' => 'object', - 'ui' => 1, - ); - - - // extra - add_action('wp_ajax_acf/fields/post_object/query', array($this, 'ajax_query')); - add_action('wp_ajax_nopriv_acf/fields/post_object/query', array($this, 'ajax_query')); - - } - - - /* - * ajax_query - * - * description - * - * @type function - * @date 24/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // get choices - $response = $this->get_ajax_query( $_POST ); - - - // return - acf_send_ajax_results($response); - - } - - - /* - * get_ajax_query - * - * This function will return an array of data formatted for use in a select2 AJAX response - * - * @type function - * @date 15/10/2014 - * @since 5.0.9 - * - * @param $options (array) - * @return (array) - */ - - function get_ajax_query( $options = array() ) { - - // defaults - $options = acf_parse_args($options, array( - 'post_id' => 0, - 's' => '', - 'field_key' => '', - 'paged' => 1 - )); - - - // load field - $field = acf_get_field( $options['field_key'] ); - if( !$field ) return false; - - - // vars - $results = array(); - $args = array(); - $s = false; - $is_search = false; - - - // paged - $args['posts_per_page'] = 20; - $args['paged'] = $options['paged']; - - - // search - if( $options['s'] !== '' ) { - - // strip slashes (search may be integer) - $s = wp_unslash( strval($options['s']) ); - - - // update vars - $args['s'] = $s; - $is_search = true; - - } - - - // post_type - if( !empty($field['post_type']) ) { - - $args['post_type'] = acf_get_array( $field['post_type'] ); - - } else { - - $args['post_type'] = acf_get_post_types(); - - } - - - // taxonomy - if( !empty($field['taxonomy']) ) { - // vars - $terms = acf_decode_taxonomy_terms( $field['taxonomy'] ); - - - // append to $args - $args['tax_query'] = array(); - - - // now create the tax queries - foreach( $terms as $k => $v ) { - - $args['tax_query'][] = array( - 'taxonomy' => $k, - 'field' => 'slug', - 'terms' => $v, - ); - - } - - } - - - // filters - $args = apply_filters('acf/fields/post_object/query', $args, $field, $options['post_id']); - $args = apply_filters('acf/fields/post_object/query/name=' . $field['name'], $args, $field, $options['post_id'] ); - $args = apply_filters('acf/fields/post_object/query/key=' . $field['key'], $args, $field, $options['post_id'] ); - - - // get posts grouped by post type - $groups = acf_get_grouped_posts( $args ); - - - // bail early if no posts - if( empty($groups) ) return false; - - - // loop - foreach( array_keys($groups) as $group_title ) { - - // vars - $posts = acf_extract_var( $groups, $group_title ); - - - // data - $data = array( - 'text' => $group_title, - 'children' => array() + $this->name = 'post_object'; + $this->label = __( 'Post Object', 'acf' ); + $this->category = 'relational'; + $this->defaults = array( + 'post_type' => array(), + 'taxonomy' => array(), + 'allow_null' => 0, + 'multiple' => 0, + 'return_format' => 'object', + 'ui' => 1, ); - - - // convert post objects to post titles - foreach( array_keys($posts) as $post_id ) { - - $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'], $is_search ); - - } - - - // order posts by search - if( $is_search && empty($args['orderby']) && isset($args['s']) ) { - - $posts = acf_order_by_search( $posts, $args['s'] ); - - } - - - // append to $data - foreach( array_keys($posts) as $post_id ) { - - $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ]); - - } - - - // append to $results - $results[] = $data; - - } - - - // optgroup or single - $post_type = acf_get_array( $args['post_type'] ); - if( count($post_type) == 1 ) { - $results = $results[0]['children']; - } - - - // vars - $response = array( - 'results' => $results, - 'limit' => $args['posts_per_page'] - ); - - - // return - return $response; - - } - - - /* - * get_post_result - * - * This function will return an array containing id, text and maybe description data - * - * @type function - * @date 7/07/2016 - * @since 5.4.0 - * - * @param $id (mixed) - * @param $text (string) - * @return (array) - */ - - function get_post_result( $id, $text ) { - - // vars - $result = array( - 'id' => $id, - 'text' => $text - ); - - - // look for parent - $search = '| ' . __('Parent', 'acf') . ':'; - $pos = strpos($text, $search); - - if( $pos !== false ) { - - $result['description'] = substr($text, $pos+2); - $result['text'] = substr($text, 0, $pos); - - } - - - // return - return $result; - - } - - - /* - * get_post_title - * - * This function returns the HTML for a result - * - * @type function - * @date 1/11/2013 - * @since 5.0.0 - * - * @param $post (object) - * @param $field (array) - * @param $post_id (int) the post_id to which this value is saved to - * @return (string) - */ - - function get_post_title( $post, $field, $post_id = 0, $is_search = 0 ) { - - // get post_id - if( !$post_id ) $post_id = acf_get_form_data('post_id'); - - - // vars - $title = acf_get_post_title( $post, $is_search ); - - - // filters - $title = apply_filters('acf/fields/post_object/result', $title, $post, $field, $post_id); - $title = apply_filters('acf/fields/post_object/result/name=' . $field['_name'], $title, $post, $field, $post_id); - $title = apply_filters('acf/fields/post_object/result/key=' . $field['key'], $title, $post, $field, $post_id); - - - // return - return $title; - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // Change Field into a select - $field['type'] = 'select'; - $field['ui'] = 1; - $field['ajax'] = 1; - $field['choices'] = array(); - - - // load posts - $posts = $this->get_posts( $field['value'], $field ); - - if( $posts ) { - - foreach( array_keys($posts) as $i ) { - - // vars - $post = acf_extract_var( $posts, $i ); - - - // append to choices - $field['choices'][ $post->ID ] = $this->get_post_title( $post, $field ); - - } - + + // extra + add_action( 'wp_ajax_acf/fields/post_object/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/post_object/query', array( $this, 'ajax_query' ) ); + } - - // render - acf_render_field( $field ); - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Filter by Post Type','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'post_type', - 'choices' => acf_get_pretty_post_types(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All post types",'acf'), - )); - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Filter by Taxonomy','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'taxonomy', - 'choices' => acf_get_taxonomy_terms(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All taxonomies",'acf'), - )); - - - // allow_null - acf_render_field_setting( $field, array( - 'label' => __('Allow Null?','acf'), - 'instructions' => '', - 'name' => 'allow_null', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // multiple - acf_render_field_setting( $field, array( - 'label' => __('Select multiple values?','acf'), - 'instructions' => '', - 'name' => 'multiple', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'return_format', - 'choices' => array( - 'object' => __("Post Object",'acf'), - 'id' => __("Post ID",'acf'), - ), - 'layout' => 'horizontal', - )); - - } - - - /* - * load_value() - * - * This filter is applied to the $value after it is loaded from the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value found in the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * @return $value - */ - - function load_value( $value, $post_id, $field ) { - - // ACF4 null - if( $value === 'null' ) return false; - - - // return - return $value; - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // numeric - $value = acf_get_numeric($value); - - - // bail early if no value - if( empty($value) ) return false; - - - // load posts if needed - if( $field['return_format'] == 'object' ) { - - $value = $this->get_posts( $value, $field ); - + + /* + * ajax_query + * + * description + * + * @type function + * @date 24/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // get choices + $response = $this->get_ajax_query( $_POST ); + + // return + acf_send_ajax_results( $response ); + } - - - // convert back from array if neccessary - if( !$field['multiple'] && is_array($value) ) { - - $value = current($value); - + + + /* + * get_ajax_query + * + * This function will return an array of data formatted for use in a select2 AJAX response + * + * @type function + * @date 15/10/2014 + * @since 5.0.9 + * + * @param $options (array) + * @return (array) + */ + + function get_ajax_query( $options = array() ) { + + // defaults + $options = acf_parse_args( + $options, + array( + 'post_id' => 0, + 's' => '', + 'field_key' => '', + 'paged' => 1, + ) + ); + + // load field + $field = acf_get_field( $options['field_key'] ); + if ( ! $field ) { + return false; + } + + // vars + $results = array(); + $args = array(); + $s = false; + $is_search = false; + + // paged + $args['posts_per_page'] = 20; + $args['paged'] = $options['paged']; + + // search + if ( $options['s'] !== '' ) { + + // strip slashes (search may be integer) + $s = wp_unslash( strval( $options['s'] ) ); + + // update vars + $args['s'] = $s; + $is_search = true; + + } + + // post_type + if ( ! empty( $field['post_type'] ) ) { + + $args['post_type'] = acf_get_array( $field['post_type'] ); + + } else { + + $args['post_type'] = acf_get_post_types(); + + } + + // taxonomy + if ( ! empty( $field['taxonomy'] ) ) { + + // vars + $terms = acf_decode_taxonomy_terms( $field['taxonomy'] ); + + // append to $args + $args['tax_query'] = array(); + + // now create the tax queries + foreach ( $terms as $k => $v ) { + + $args['tax_query'][] = array( + 'taxonomy' => $k, + 'field' => 'slug', + 'terms' => $v, + ); + + } + } + + // filters + $args = apply_filters( 'acf/fields/post_object/query', $args, $field, $options['post_id'] ); + $args = apply_filters( 'acf/fields/post_object/query/name=' . $field['name'], $args, $field, $options['post_id'] ); + $args = apply_filters( 'acf/fields/post_object/query/key=' . $field['key'], $args, $field, $options['post_id'] ); + + // get posts grouped by post type + $groups = acf_get_grouped_posts( $args ); + + // bail early if no posts + if ( empty( $groups ) ) { + return false; + } + + // loop + foreach ( array_keys( $groups ) as $group_title ) { + + // vars + $posts = acf_extract_var( $groups, $group_title ); + + // data + $data = array( + 'text' => $group_title, + 'children' => array(), + ); + + // convert post objects to post titles + foreach ( array_keys( $posts ) as $post_id ) { + + $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'], $is_search ); + + } + + // order posts by search + if ( $is_search && empty( $args['orderby'] ) && isset( $args['s'] ) ) { + + $posts = acf_order_by_search( $posts, $args['s'] ); + + } + + // append to $data + foreach ( array_keys( $posts ) as $post_id ) { + + $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ] ); + + } + + // append to $results + $results[] = $data; + + } + + // optgroup or single + $post_type = acf_get_array( $args['post_type'] ); + if ( count( $post_type ) == 1 ) { + $results = $results[0]['children']; + } + + // vars + $response = array( + 'results' => $results, + 'limit' => $args['posts_per_page'], + ); + + // return + return $response; + } - - - // return value - return $value; - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( empty($value) ) { + + + /* + * get_post_result + * + * This function will return an array containing id, text and maybe description data + * + * @type function + * @date 7/07/2016 + * @since 5.4.0 + * + * @param $id (mixed) + * @param $text (string) + * @return (array) + */ + + function get_post_result( $id, $text ) { + + // vars + $result = array( + 'id' => $id, + 'text' => $text, + ); + + // look for parent + $search = '| ' . __( 'Parent', 'acf' ) . ':'; + $pos = strpos( $text, $search ); + + if ( $pos !== false ) { + + $result['description'] = substr( $text, $pos + 2 ); + $result['text'] = substr( $text, 0, $pos ); + + } + + // return + return $result; + + } + + + /* + * get_post_title + * + * This function returns the HTML for a result + * + * @type function + * @date 1/11/2013 + * @since 5.0.0 + * + * @param $post (object) + * @param $field (array) + * @param $post_id (int) the post_id to which this value is saved to + * @return (string) + */ + + function get_post_title( $post, $field, $post_id = 0, $is_search = 0 ) { + + // get post_id + if ( ! $post_id ) { + $post_id = acf_get_form_data( 'post_id' ); + } + + // vars + $title = acf_get_post_title( $post, $is_search ); + + // filters + $title = apply_filters( 'acf/fields/post_object/result', $title, $post, $field, $post_id ); + $title = apply_filters( 'acf/fields/post_object/result/name=' . $field['_name'], $title, $post, $field, $post_id ); + $title = apply_filters( 'acf/fields/post_object/result/key=' . $field['key'], $title, $post, $field, $post_id ); + + // return + return $title; + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // Change Field into a select + $field['type'] = 'select'; + $field['ui'] = 1; + $field['ajax'] = 1; + $field['choices'] = array(); + + // load posts + $posts = $this->get_posts( $field['value'], $field ); + + if ( $posts ) { + + foreach ( array_keys( $posts ) as $i ) { + + // vars + $post = acf_extract_var( $posts, $i ); + + // append to choices + $field['choices'][ $post->ID ] = $this->get_post_title( $post, $field ); + + } + } + + // render + acf_render_field( $field ); + + } + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by Post Type', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'post_type', + 'choices' => acf_get_pretty_post_types(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All post types', 'acf' ), + ) + ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by Taxonomy', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'taxonomy', + 'choices' => acf_get_taxonomy_terms(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All taxonomies', 'acf' ), + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // multiple + acf_render_field_setting( + $field, + array( + 'label' => __( 'Select multiple values?', 'acf' ), + 'instructions' => '', + 'name' => 'multiple', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'return_format', + 'choices' => array( + 'object' => __( 'Post Object', 'acf' ), + 'id' => __( 'Post ID', 'acf' ), + ), + 'layout' => 'horizontal', + ) + ); + + } + + + /* + * load_value() + * + * This filter is applied to the $value after it is loaded from the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value found in the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * @return $value + */ + + function load_value( $value, $post_id, $field ) { + + // ACF4 null + if ( $value === 'null' ) { + return false; + } + + // return + return $value; + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // numeric + $value = acf_get_numeric( $value ); + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // load posts if needed + if ( $field['return_format'] == 'object' ) { + + $value = $this->get_posts( $value, $field ); + + } + + // convert back from array if neccessary + if ( ! $field['multiple'] && is_array( $value ) ) { + + $value = current( $value ); + + } + + // return value + return $value; + + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( empty( $value ) ) { + return $value; + } + + // Format array of values. + // - ensure each value is an id. + // - Parse each id as string for SQL LIKE queries. + if ( acf_is_sequential_array( $value ) ) { + $value = array_map( 'acf_idval', $value ); + $value = array_map( 'strval', $value ); + + // Parse single value for id. + } else { + $value = acf_idval( $value ); + } + + // Return value. return $value; } - - // Format array of values. - // - ensure each value is an id. - // - Parse each id as string for SQL LIKE queries. - if( acf_is_sequential_array($value) ) { - $value = array_map('acf_idval', $value); - $value = array_map('strval', $value); - - // Parse single value for id. - } else { - $value = acf_idval( $value ); + + + /* + * get_posts + * + * This function will return an array of posts for a given field value + * + * @type function + * @date 13/06/2014 + * @since 5.0.0 + * + * @param $value (array) + * @return $value + */ + + function get_posts( $value, $field ) { + + // numeric + $value = acf_get_numeric( $value ); + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // get posts + $posts = acf_get_posts( + array( + 'post__in' => $value, + 'post_type' => $field['post_type'], + ) + ); + + // return + return $posts; + } - - // Return value. - return $value; + } - - - /* - * get_posts - * - * This function will return an array of posts for a given field value - * - * @type function - * @date 13/06/2014 - * @since 5.0.0 - * - * @param $value (array) - * @return $value - */ - - function get_posts( $value, $field ) { - - // numeric - $value = acf_get_numeric($value); - - - // bail early if no value - if( empty($value) ) return false; - - - // get posts - $posts = acf_get_posts(array( - 'post__in' => $value, - 'post_type' => $field['post_type'] - )); - - - // return - return $posts; - - } - -} -// initialize -acf_register_field_type( 'acf_field_post_object' ); + // initialize + acf_register_field_type( 'acf_field_post_object' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-radio.php b/includes/fields/class-acf-field-radio.php index c3c18f6..71583be 100644 --- a/includes/fields/class-acf-field-radio.php +++ b/includes/fields/class-acf-field-radio.php @@ -1,448 +1,454 @@ name = 'radio'; - $this->label = __("Radio Button",'acf'); - $this->category = 'choice'; - $this->defaults = array( - 'layout' => 'vertical', - 'choices' => array(), - 'default_value' => '', - 'other_choice' => 0, - 'save_other_choice' => 0, - 'allow_null' => 0, - 'return_format' => 'value' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field (array) the $field being rendered - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field (array) the $field being edited - * @return n/a - */ - - function render_field( $field ) { + class acf_field_radio extends acf_field { - // vars - $e = ''; - $ul = array( - 'class' => 'acf-radio-list', - 'data-allow_null' => $field['allow_null'], - 'data-other_choice' => $field['other_choice'] - ); - - - // append to class - $ul['class'] .= ' ' . ($field['layout'] == 'horizontal' ? 'acf-hl' : 'acf-bl'); - $ul['class'] .= ' ' . $field['class']; - - - // Determine selected value. - $value = (string) $field['value']; - - // 1. Selected choice. - if( isset( $field['choices'][ $value ] ) ) { - $checked = (string) $value; - - // 2. Custom choice. - } elseif( $field['other_choice'] && $value !== '' ) { - $checked = 'other'; - - // 3. Empty choice. - } elseif( $field['allow_null'] ) { - $checked = ''; - - // 4. Default to first choice. - } else { - $checked = (string) key( $field['choices'] ); - } - - // other choice - $other_input = false; - if( $field['other_choice'] ) { - - // Define other input attrs. - $other_input = array( - 'type' => 'text', - 'name' => $field['name'], - 'value' => '', - 'disabled' => 'disabled', - 'class' => 'acf-disabled' + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'radio'; + $this->label = __( 'Radio Button', 'acf' ); + $this->category = 'choice'; + $this->defaults = array( + 'layout' => 'vertical', + 'choices' => array(), + 'default_value' => '', + 'other_choice' => 0, + 'save_other_choice' => 0, + 'allow_null' => 0, + 'return_format' => 'value', ); - - // Select other choice if value is not a valid choice. - if( $checked === 'other' ) { - unset( $other_input['disabled'] ); - $other_input['value'] = $field['value']; - } - - // Ensure an 'other' choice is defined. - if( !isset( $field['choices']['other'] ) ) { - $field['choices']['other'] = ''; - } + } - - // Bail early if no choices. - if( empty( $field['choices'] ) ) { - return; - } - - // Hiden input. - $e .= acf_get_hidden_input( array('name' => $field['name']) ); - - // Open
                          . - $e .= '
                            '; - - // Loop through choices. - foreach( $field['choices'] as $value => $label ) { - $is_selected = false; - - // Ensure value is a string. - $value = (string) $value; - - // Define input attrs. - $attrs = array( - 'type' => 'radio', - 'id' => sanitize_title( $field['id'] . '-' . $value ), - 'name' => $field['name'], - 'value' => $value + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field (array) the $field being rendered + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field (array) the $field being edited + * @return n/a + */ + + function render_field( $field ) { + + // vars + $e = ''; + $ul = array( + 'class' => 'acf-radio-list', + 'data-allow_null' => $field['allow_null'], + 'data-other_choice' => $field['other_choice'], ); - - // Check if selected. - if( esc_attr($value) === esc_attr($checked) ) { - $attrs['checked'] = 'checked'; - $is_selected = true; + + // append to class + $ul['class'] .= ' ' . ( $field['layout'] == 'horizontal' ? 'acf-hl' : 'acf-bl' ); + $ul['class'] .= ' ' . $field['class']; + + // Determine selected value. + $value = (string) $field['value']; + + // 1. Selected choice. + if ( isset( $field['choices'][ $value ] ) ) { + $checked = (string) $value; + + // 2. Custom choice. + } elseif ( $field['other_choice'] && $value !== '' ) { + $checked = 'other'; + + // 3. Empty choice. + } elseif ( $field['allow_null'] ) { + $checked = ''; + + // 4. Default to first choice. + } else { + $checked = (string) key( $field['choices'] ); } - - // Check if is disabled. - if( isset($field['disabled']) && acf_in_array($value, $field['disabled']) ) { - $attrs['disabled'] = 'disabled'; + + // other choice + $other_input = false; + if ( $field['other_choice'] ) { + + // Define other input attrs. + $other_input = array( + 'type' => 'text', + 'name' => $field['name'], + 'value' => '', + 'disabled' => 'disabled', + 'class' => 'acf-disabled', + ); + + // Select other choice if value is not a valid choice. + if ( $checked === 'other' ) { + unset( $other_input['disabled'] ); + $other_input['value'] = $field['value']; + } + + // Ensure an 'other' choice is defined. + if ( ! isset( $field['choices']['other'] ) ) { + $field['choices']['other'] = ''; + } } - - // Additional HTML (the "Other" input). - $additional_html = ''; - if( $value === 'other' && $other_input ) { - $additional_html = ' ' . acf_get_text_input( $other_input ); + + // Bail early if no choices. + if ( empty( $field['choices'] ) ) { + return; } - - // append - $e .= '
                          • ' . acf_esc_html( $label ) . '' . $additional_html . '
                          • '; + + // Hiden input. + $e .= acf_get_hidden_input( array( 'name' => $field['name'] ) ); + + // Open
                              . + $e .= '
                                '; + + // Loop through choices. + foreach ( $field['choices'] as $value => $label ) { + $is_selected = false; + + // Ensure value is a string. + $value = (string) $value; + + // Define input attrs. + $attrs = array( + 'type' => 'radio', + 'id' => sanitize_title( $field['id'] . '-' . $value ), + 'name' => $field['name'], + 'value' => $value, + ); + + // Check if selected. + if ( esc_attr( $value ) === esc_attr( $checked ) ) { + $attrs['checked'] = 'checked'; + $is_selected = true; + } + + // Check if is disabled. + if ( isset( $field['disabled'] ) && acf_in_array( $value, $field['disabled'] ) ) { + $attrs['disabled'] = 'disabled'; + } + + // Additional HTML (the "Other" input). + $additional_html = ''; + if ( $value === 'other' && $other_input ) { + $additional_html = ' ' . acf_get_text_input( $other_input ); + } + + // append + $e .= '
                              • ' . acf_esc_html( $label ) . '' . $additional_html . '
                              • '; + } + + // Close
                                  . + $e .= '
                                '; + + // Output HTML. + echo $e; } - - // Close
                                  . - $e .= '
                                '; - - // Output HTML. - echo $e; - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // encode choices (convert from array) - $field['choices'] = acf_encode_choices($field['choices']); - - - // choices - acf_render_field_setting( $field, array( - 'label' => __('Choices','acf'), - 'instructions' => __('Enter each choice on a new line.','acf') . '

                                ' . __('For more control, you may specify both a value and label like this:','acf'). '

                                ' . __('red : Red','acf'), - 'type' => 'textarea', - 'name' => 'choices', - )); - - - // allow_null - acf_render_field_setting( $field, array( - 'label' => __('Allow Null?','acf'), - 'instructions' => '', - 'name' => 'allow_null', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // other_choice - acf_render_field_setting( $field, array( - 'label' => __('Other','acf'), - 'instructions' => '', - 'name' => 'other_choice', - 'type' => 'true_false', - 'ui' => 1, - 'message' => __("Add 'other' choice to allow for custom values", 'acf'), - )); - - - // save_other_choice - acf_render_field_setting( $field, array( - 'label' => __('Save Other','acf'), - 'instructions' => '', - 'name' => 'save_other_choice', - 'type' => 'true_false', - 'ui' => 1, - 'message' => __("Save 'other' values to the field's choices", 'acf'), - 'conditions' => array( - 'field' => 'other_choice', - 'operator' => '==', - 'value' => 1 - ) - )); - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'text', - 'name' => 'default_value', - )); - - - // layout - acf_render_field_setting( $field, array( - 'label' => __('Layout','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'layout', - 'layout' => 'horizontal', - 'choices' => array( - 'vertical' => __("Vertical",'acf'), - 'horizontal' => __("Horizontal",'acf') - ) - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Value','acf'), - 'instructions' => __('Specify the returned value on front end','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'layout' => 'horizontal', - 'choices' => array( - 'value' => __('Value','acf'), - 'label' => __('Label','acf'), - 'array' => __('Both (Array)','acf') - ) - )); - - } - - - /* - * update_field() - * - * This filter is appied to the $field before it is saved to the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * @param $post_id - the field group ID (post_type = acf) - * - * @return $field - the modified field - */ - function update_field( $field ) { - - // decode choices (convert to array) - $field['choices'] = acf_decode_choices($field['choices']); - - - // return - return $field; - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * @todo Fix bug where $field was found via json and has no ID - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // bail early if no value (allow 0 to be saved) - if( !$value && !is_numeric($value) ) return $value; - - - // save_other_choice - if( $field['save_other_choice'] ) { - - // value isn't in choices yet - if( !isset($field['choices'][ $value ]) ) { - - // get raw $field (may have been changed via repeater field) - // if field is local, it won't have an ID - $selector = $field['ID'] ? $field['ID'] : $field['key']; - $field = acf_get_field( $selector, true ); - - - // bail early if no ID (JSON only) - if( !$field['ID'] ) return $value; - - - // unslash (fixes serialize single quote issue) - $value = wp_unslash($value); - - - // sanitize (remove tags) - $value = sanitize_text_field($value); - - - // update $field - $field['choices'][ $value ] = $value; - - - // save - acf_update_field( $field ); - - } - - } - - - // return - return $value; - } - - - /* - * load_value() - * - * This filter is appied to the $value after it is loaded from the db - * - * @type filter - * @since 5.2.9 - * @date 23/01/13 - * - * @param $value - the value found in the database - * @param $post_id - the $post_id from which the value was loaded from - * @param $field - the field array holding all the field options - * - * @return $value - the value to be saved in te database - */ - - function load_value( $value, $post_id, $field ) { - - // must be single value - if( is_array($value) ) { - - $value = array_pop($value); - + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // encode choices (convert from array) + $field['choices'] = acf_encode_choices( $field['choices'] ); + + // choices + acf_render_field_setting( + $field, + array( + 'label' => __( 'Choices', 'acf' ), + 'instructions' => __( 'Enter each choice on a new line.', 'acf' ) . '

                                ' . __( 'For more control, you may specify both a value and label like this:', 'acf' ) . '

                                ' . __( 'red : Red', 'acf' ), + 'type' => 'textarea', + 'name' => 'choices', + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // other_choice + acf_render_field_setting( + $field, + array( + 'label' => __( 'Other', 'acf' ), + 'instructions' => '', + 'name' => 'other_choice', + 'type' => 'true_false', + 'ui' => 1, + 'message' => __( "Add 'other' choice to allow for custom values", 'acf' ), + ) + ); + + // save_other_choice + acf_render_field_setting( + $field, + array( + 'label' => __( 'Save Other', 'acf' ), + 'instructions' => '', + 'name' => 'save_other_choice', + 'type' => 'true_false', + 'ui' => 1, + 'message' => __( "Save 'other' values to the field's choices", 'acf' ), + 'conditions' => array( + 'field' => 'other_choice', + 'operator' => '==', + 'value' => 1, + ), + ) + ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'text', + 'name' => 'default_value', + ) + ); + + // layout + acf_render_field_setting( + $field, + array( + 'label' => __( 'Layout', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'layout', + 'layout' => 'horizontal', + 'choices' => array( + 'vertical' => __( 'Vertical', 'acf' ), + 'horizontal' => __( 'Horizontal', 'acf' ), + ), + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Value', 'acf' ), + 'instructions' => __( 'Specify the returned value on front end', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'layout' => 'horizontal', + 'choices' => array( + 'value' => __( 'Value', 'acf' ), + 'label' => __( 'Label', 'acf' ), + 'array' => __( 'Both (Array)', 'acf' ), + ), + ) + ); + } - - - // return - return $value; - - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @type function - * @date 8/03/2016 - * @since 5.3.2 - * - * @param $field (array) - * @return $field - */ - - function translate_field( $field ) { - - return acf_get_field_type('select')->translate_field( $field ); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - return acf_get_field_type('select')->format_value( $value, $post_id, $field ); - - } - -} -// initialize -acf_register_field_type( 'acf_field_radio' ); + /* + * update_field() + * + * This filter is appied to the $field before it is saved to the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * @param $post_id - the field group ID (post_type = acf) + * + * @return $field - the modified field + */ + + function update_field( $field ) { + + // decode choices (convert to array) + $field['choices'] = acf_decode_choices( $field['choices'] ); + + // return + return $field; + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * @todo Fix bug where $field was found via json and has no ID + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // bail early if no value (allow 0 to be saved) + if ( ! $value && ! is_numeric( $value ) ) { + return $value; + } + + // save_other_choice + if ( $field['save_other_choice'] ) { + + // value isn't in choices yet + if ( ! isset( $field['choices'][ $value ] ) ) { + + // get raw $field (may have been changed via repeater field) + // if field is local, it won't have an ID + $selector = $field['ID'] ? $field['ID'] : $field['key']; + $field = acf_get_field( $selector, true ); + + // bail early if no ID (JSON only) + if ( ! $field['ID'] ) { + return $value; + } + + // unslash (fixes serialize single quote issue) + $value = wp_unslash( $value ); + + // sanitize (remove tags) + $value = sanitize_text_field( $value ); + + // update $field + $field['choices'][ $value ] = $value; + + // save + acf_update_field( $field ); + + } + } + + // return + return $value; + } + + + /* + * load_value() + * + * This filter is appied to the $value after it is loaded from the db + * + * @type filter + * @since 5.2.9 + * @date 23/01/13 + * + * @param $value - the value found in the database + * @param $post_id - the $post_id from which the value was loaded from + * @param $field - the field array holding all the field options + * + * @return $value - the value to be saved in te database + */ + + function load_value( $value, $post_id, $field ) { + + // must be single value + if ( is_array( $value ) ) { + + $value = array_pop( $value ); + + } + + // return + return $value; + + } + + + /* + * translate_field + * + * This function will translate field settings + * + * @type function + * @date 8/03/2016 + * @since 5.3.2 + * + * @param $field (array) + * @return $field + */ + + function translate_field( $field ) { + + return acf_get_field_type( 'select' )->translate_field( $field ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + return acf_get_field_type( 'select' )->format_value( $value, $post_id, $field ); + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_radio' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-range.php b/includes/fields/class-acf-field-range.php index 8970326..0deb2f4 100644 --- a/includes/fields/class-acf-field-range.php +++ b/includes/fields/class-acf-field-range.php @@ -1,220 +1,239 @@ name = 'range'; + $this->label = __( 'Range', 'acf' ); + $this->defaults = array( + 'default_value' => '', + 'min' => '', + 'max' => '', + 'step' => '', + 'prepend' => '', + 'append' => '', + ); -class acf_field_range extends acf_field_number { - - - /* - * initialize - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'range'; - $this->label = __("Range",'acf'); - $this->defaults = array( - 'default_value' => '', - 'min' => '', - 'max' => '', - 'step' => '', - 'prepend' => '', - 'append' => '' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $atts = array(); - $keys = array( 'type', 'id', 'class', 'name', 'value', 'min', 'max', 'step' ); - $keys2 = array( 'readonly', 'disabled', 'required' ); - $html = ''; - - // step - if( !$field['step'] ) { - $field['step'] = 1; } - - // min / max - if( !$field['min'] ) { - $field['min'] = 0; - } - if( !$field['max'] ) { - $field['max'] = 100; - } - - // allow for prev 'non numeric' value - if( !is_numeric($field['value']) ) { - $field['value'] = 0; - } - - // constrain within max and min - $field['value'] = max($field['value'], $field['min']); - $field['value'] = min($field['value'], $field['max']); - - // atts (value="123") - foreach( $keys as $k ) { - if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ]; - } - - // atts2 (disabled="disabled") - foreach( $keys2 as $k ) { - if( !empty($field[ $k ]) ) $atts[ $k ] = $k; - } - - // remove empty atts - $atts = acf_clean_atts( $atts ); - - // open - $html .= '
                                '; - - // prepend - if( $field['prepend'] !== '' ) { - $html .= '
                                ' . acf_esc_html($field['prepend']) . '
                                '; + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $atts = array(); + $keys = array( 'type', 'id', 'class', 'name', 'value', 'min', 'max', 'step' ); + $keys2 = array( 'readonly', 'disabled', 'required' ); + $html = ''; + + // step + if ( ! $field['step'] ) { + $field['step'] = 1; } - + + // min / max + if ( ! $field['min'] ) { + $field['min'] = 0; + } + if ( ! $field['max'] ) { + $field['max'] = 100; + } + + // allow for prev 'non numeric' value + if ( ! is_numeric( $field['value'] ) ) { + $field['value'] = 0; + } + + // constrain within max and min + $field['value'] = max( $field['value'], $field['min'] ); + $field['value'] = min( $field['value'], $field['max'] ); + + // atts (value="123") + foreach ( $keys as $k ) { + if ( isset( $field[ $k ] ) ) { + $atts[ $k ] = $field[ $k ]; + } + } + + // atts2 (disabled="disabled") + foreach ( $keys2 as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $atts[ $k ] = $k; + } + } + + // remove empty atts + $atts = acf_clean_atts( $atts ); + + // open + $html .= '
                                '; + + // prepend + if ( $field['prepend'] !== '' ) { + $html .= '
                                ' . acf_esc_html( $field['prepend'] ) . '
                                '; + } + // range $html .= acf_get_text_input( $atts ); // Calculate input width based on the largest possible input character length. // Also take into account the step size for decimal steps minus - 1.5 chars for leading "0.". $len = max( - strlen( strval($field['min']) ), - strlen( strval($field['max']) ) + strlen( strval( $field['min'] ) ), + strlen( strval( $field['max'] ) ) ); - if( floatval($atts['step']) < 1 ) { - $len += strlen( strval($field['step']) ) - 1.5; + if ( floatval( $atts['step'] ) < 1 ) { + $len += strlen( strval( $field['step'] ) ) - 1.5; } - - // input - $html .= acf_get_text_input(array( - 'type' => 'number', - 'id' => $atts['id'] . '-alt', - 'value' => $atts['value'], - 'step' => $atts['step'], - //'min' => $atts['min'], // removed to avoid browser validation errors - //'max' => $atts['max'], - 'style' => 'width: ' . (1.8 + $len*0.7) . 'em;' - )); - + + // input + $html .= acf_get_text_input( + array( + 'type' => 'number', + 'id' => $atts['id'] . '-alt', + 'value' => $atts['value'], + 'step' => $atts['step'], + // 'min' => $atts['min'], // removed to avoid browser validation errors + // 'max' => $atts['max'], + 'style' => 'width: ' . ( 1.8 + $len * 0.7 ) . 'em;', + ) + ); + + // append + if ( $field['append'] !== '' ) { + $html .= '
                                ' . acf_esc_html( $field['append'] ) . '
                                '; + } + + // close + $html .= '
                                '; + + // return + echo $html; + } + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'number', + 'name' => 'default_value', + ) + ); + + // min + acf_render_field_setting( + $field, + array( + 'label' => __( 'Minimum Value', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'min', + 'placeholder' => '0', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Maximum Value', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'max', + 'placeholder' => '100', + ) + ); + + // step + acf_render_field_setting( + $field, + array( + 'label' => __( 'Step Size', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'step', + 'placeholder' => '1', + ) + ); + + // prepend + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prepend', 'acf' ), + 'instructions' => __( 'Appears before the input', 'acf' ), + 'type' => 'text', + 'name' => 'prepend', + ) + ); + // append - if( $field['append'] !== '' ) { - $html .= '
                                ' . acf_esc_html($field['append']) . '
                                '; - } - - // close - $html .= '
                                '; - - // return - echo $html; - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'number', - 'name' => 'default_value', - )); - - - // min - acf_render_field_setting( $field, array( - 'label' => __('Minimum Value','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'min', - 'placeholder' => '0' - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Maximum Value','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'max', - 'placeholder' => '100' - )); - - - // step - acf_render_field_setting( $field, array( - 'label' => __('Step Size','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'step', - 'placeholder' => '1' - )); - - - // prepend - acf_render_field_setting( $field, array( - 'label' => __('Prepend','acf'), - 'instructions' => __('Appears before the input','acf'), - 'type' => 'text', - 'name' => 'prepend', - )); - - - // append - acf_render_field_setting( $field, array( - 'label' => __('Append','acf'), - 'instructions' => __('Appears after the input','acf'), - 'type' => 'text', - 'name' => 'append', - )); - - } - - -} + acf_render_field_setting( + $field, + array( + 'label' => __( 'Append', 'acf' ), + 'instructions' => __( 'Appears after the input', 'acf' ), + 'type' => 'text', + 'name' => 'append', + ) + ); + + } -// initialize -acf_register_field_type( 'acf_field_range' ); + } + + + // initialize + acf_register_field_type( 'acf_field_range' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-relationship.php b/includes/fields/class-acf-field-relationship.php index eb67e72..71dd2f8 100644 --- a/includes/fields/class-acf-field-relationship.php +++ b/includes/fields/class-acf-field-relationship.php @@ -1,499 +1,512 @@ name = 'relationship'; - $this->label = __("Relationship",'acf'); - $this->category = 'relational'; - $this->defaults = array( - 'post_type' => array(), - 'taxonomy' => array(), - 'min' => 0, - 'max' => 0, - 'filters' => array('search', 'post_type', 'taxonomy'), - 'elements' => array(), - 'return_format' => 'object' - ); - - // extra - add_action('wp_ajax_acf/fields/relationship/query', array($this, 'ajax_query')); - add_action('wp_ajax_nopriv_acf/fields/relationship/query', array($this, 'ajax_query')); - - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // localize - acf_localize_text(array( - //'Minimum values reached ( {min} values )' => __('Minimum values reached ( {min} values )', 'acf'), - 'Maximum values reached ( {max} values )' => __('Maximum values reached ( {max} values )', 'acf'), - 'Loading' => __('Loading', 'acf'), - 'No matches found' => __('No matches found', 'acf'), - )); - } - - - /* - * ajax_query - * - * description - * - * @type function - * @date 24/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // get choices - $response = $this->get_ajax_query( $_POST ); - - - // return - acf_send_ajax_results($response); - - } - - - /* - * get_ajax_query - * - * This function will return an array of data formatted for use in a select2 AJAX response - * - * @type function - * @date 15/10/2014 - * @since 5.0.9 - * - * @param $options (array) - * @return (array) - */ - - function get_ajax_query( $options = array() ) { - - // defaults - $options = wp_parse_args($options, array( - 'post_id' => 0, - 's' => '', - 'field_key' => '', - 'paged' => 1, - 'post_type' => '', - 'taxonomy' => '' - )); - - - // load field - $field = acf_get_field( $options['field_key'] ); - if( !$field ) return false; - - - // vars - $results = array(); - $args = array(); - $s = false; - $is_search = false; - - - // paged - $args['posts_per_page'] = 20; - $args['paged'] = intval($options['paged']); - - - // search - if( $options['s'] !== '' ) { - - // strip slashes (search may be integer) - $s = wp_unslash( strval($options['s']) ); - - - // update vars - $args['s'] = $s; - $is_search = true; - - } - - - // post_type - if( !empty($options['post_type']) ) { - - $args['post_type'] = acf_get_array( $options['post_type'] ); - - } elseif( !empty($field['post_type']) ) { - - $args['post_type'] = acf_get_array( $field['post_type'] ); - - } else { - - $args['post_type'] = acf_get_post_types(); - - } - - - // taxonomy - if( !empty($options['taxonomy']) ) { - // vars - $term = acf_decode_taxonomy_term($options['taxonomy']); - - - // tax query - $args['tax_query'] = array(); - - - // append - $args['tax_query'][] = array( - 'taxonomy' => $term['taxonomy'], - 'field' => 'slug', - 'terms' => $term['term'], + $this->name = 'relationship'; + $this->label = __( 'Relationship', 'acf' ); + $this->category = 'relational'; + $this->defaults = array( + 'post_type' => array(), + 'taxonomy' => array(), + 'min' => 0, + 'max' => 0, + 'filters' => array( 'search', 'post_type', 'taxonomy' ), + 'elements' => array(), + 'return_format' => 'object', ); - - - } elseif( !empty($field['taxonomy']) ) { - + + // extra + add_action( 'wp_ajax_acf/fields/relationship/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/relationship/query', array( $this, 'ajax_query' ) ); + + } + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // localize + acf_localize_text( + array( + // 'Minimum values reached ( {min} values )' => __('Minimum values reached ( {min} values )', 'acf'), + 'Maximum values reached ( {max} values )' => __( 'Maximum values reached ( {max} values )', 'acf' ), + 'Loading' => __( 'Loading', 'acf' ), + 'No matches found' => __( 'No matches found', 'acf' ), + ) + ); + } + + + /* + * ajax_query + * + * description + * + * @type function + * @date 24/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // get choices + $response = $this->get_ajax_query( $_POST ); + + // return + acf_send_ajax_results( $response ); + + } + + + /* + * get_ajax_query + * + * This function will return an array of data formatted for use in a select2 AJAX response + * + * @type function + * @date 15/10/2014 + * @since 5.0.9 + * + * @param $options (array) + * @return (array) + */ + + function get_ajax_query( $options = array() ) { + + // defaults + $options = wp_parse_args( + $options, + array( + 'post_id' => 0, + 's' => '', + 'field_key' => '', + 'paged' => 1, + 'post_type' => '', + 'taxonomy' => '', + ) + ); + + // load field + $field = acf_get_field( $options['field_key'] ); + if ( ! $field ) { + return false; + } + // vars - $terms = acf_decode_taxonomy_terms( $field['taxonomy'] ); - - - // append to $args - $args['tax_query'] = array( - 'relation' => 'OR', - ); - - - // now create the tax queries - foreach( $terms as $k => $v ) { - - $args['tax_query'][] = array( - 'taxonomy' => $k, - 'field' => 'slug', - 'terms' => $v, - ); - + $results = array(); + $args = array(); + $s = false; + $is_search = false; + + // paged + $args['posts_per_page'] = 20; + $args['paged'] = intval( $options['paged'] ); + + // search + if ( $options['s'] !== '' ) { + + // strip slashes (search may be integer) + $s = wp_unslash( strval( $options['s'] ) ); + + // update vars + $args['s'] = $s; + $is_search = true; + } - - } - - - // filters - $args = apply_filters('acf/fields/relationship/query', $args, $field, $options['post_id']); - $args = apply_filters('acf/fields/relationship/query/name=' . $field['name'], $args, $field, $options['post_id'] ); - $args = apply_filters('acf/fields/relationship/query/key=' . $field['key'], $args, $field, $options['post_id'] ); - - - // get posts grouped by post type - $groups = acf_get_grouped_posts( $args ); - - - // bail early if no posts - if( empty($groups) ) return false; - - - // loop - foreach( array_keys($groups) as $group_title ) { - - // vars - $posts = acf_extract_var( $groups, $group_title ); - - - // data - $data = array( - 'text' => $group_title, - 'children' => array() - ); - - - // convert post objects to post titles - foreach( array_keys($posts) as $post_id ) { - - $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'] ); - - } - - - // order posts by search - if( $is_search && empty($args['orderby']) && isset($args['s']) ) { - - $posts = acf_order_by_search( $posts, $args['s'] ); - - } - - - // append to $data - foreach( array_keys($posts) as $post_id ) { - - $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ]); - - } - - - // append to $results - $results[] = $data; - - } - - - // add as optgroup or results - if( count($args['post_type']) == 1 ) { - - $results = $results[0]['children']; - - } - - - // vars - $response = array( - 'results' => $results, - 'limit' => $args['posts_per_page'] - ); - - - // return - return $response; - - } - - - /* - * get_post_result - * - * This function will return an array containing id, text and maybe description data - * - * @type function - * @date 7/07/2016 - * @since 5.4.0 - * - * @param $id (mixed) - * @param $text (string) - * @return (array) - */ - - function get_post_result( $id, $text ) { - - // vars - $result = array( - 'id' => $id, - 'text' => $text - ); - - - // return - return $result; - - } - - - /* - * get_post_title - * - * This function returns the HTML for a result - * - * @type function - * @date 1/11/2013 - * @since 5.0.0 - * - * @param $post (object) - * @param $field (array) - * @param $post_id (int) the post_id to which this value is saved to - * @return (string) - */ - - function get_post_title( $post, $field, $post_id = 0, $is_search = 0 ) { - - // get post_id - if( !$post_id ) $post_id = acf_get_form_data('post_id'); - - - // vars - $title = acf_get_post_title( $post, $is_search ); - - - // featured_image - if( acf_in_array('featured_image', $field['elements']) ) { - - // vars - $class = 'thumbnail'; - $thumbnail = acf_get_post_thumbnail($post->ID, array(17, 17)); - - - // icon - if( $thumbnail['type'] == 'icon' ) { - - $class .= ' -' . $thumbnail['type']; - - } - - - // append - $title = '
                                ' . $thumbnail['html'] . '
                                ' . $title; - - } - - - // filters - $title = apply_filters('acf/fields/relationship/result', $title, $post, $field, $post_id); - $title = apply_filters('acf/fields/relationship/result/name=' . $field['_name'], $title, $post, $field, $post_id); - $title = apply_filters('acf/fields/relationship/result/key=' . $field['key'], $title, $post, $field, $post_id); - - - // return - return $title; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $post_type = acf_get_array( $field['post_type'] ); - $taxonomy = acf_get_array( $field['taxonomy'] ); - $filters = acf_get_array( $field['filters'] ); - - // filters - $filter_count = count($filters); - $filter_post_type_choices = array(); - $filter_taxonomy_choices = array(); - - // post_type filter - if( in_array('post_type', $filters) ) { - - $filter_post_type_choices = array( - '' => __('Select post type', 'acf') - ) + acf_get_pretty_post_types( $post_type ); - } - - // taxonomy filter - if( in_array('taxonomy', $filters) ) { - - $term_choices = array(); - $filter_taxonomy_choices = array( - '' => __('Select taxonomy', 'acf') - ); - - // check for specific taxonomy setting - if( $taxonomy ) { - $terms = acf_get_encoded_terms( $taxonomy ); - $term_choices = acf_get_choices_from_terms( $terms, 'slug' ); - - // if no terms were specified, find all terms + + // post_type + if ( ! empty( $options['post_type'] ) ) { + + $args['post_type'] = acf_get_array( $options['post_type'] ); + + } elseif ( ! empty( $field['post_type'] ) ) { + + $args['post_type'] = acf_get_array( $field['post_type'] ); + } else { - - // restrict taxonomies by the post_type selected - $term_args = array(); - if( $post_type ) { - $term_args['taxonomy'] = acf_get_taxonomies(array( - 'post_type' => $post_type - )); - } - - // get terms - $terms = acf_get_grouped_terms( $term_args ); - $term_choices = acf_get_choices_from_grouped_terms( $terms, 'slug' ); + + $args['post_type'] = acf_get_post_types(); + } - - // append term choices - $filter_taxonomy_choices = $filter_taxonomy_choices + $term_choices; - + + // taxonomy + if ( ! empty( $options['taxonomy'] ) ) { + + // vars + $term = acf_decode_taxonomy_term( $options['taxonomy'] ); + + // tax query + $args['tax_query'] = array(); + + // append + $args['tax_query'][] = array( + 'taxonomy' => $term['taxonomy'], + 'field' => 'slug', + 'terms' => $term['term'], + ); + + } elseif ( ! empty( $field['taxonomy'] ) ) { + + // vars + $terms = acf_decode_taxonomy_terms( $field['taxonomy'] ); + + // append to $args + $args['tax_query'] = array( + 'relation' => 'OR', + ); + + // now create the tax queries + foreach ( $terms as $k => $v ) { + + $args['tax_query'][] = array( + 'taxonomy' => $k, + 'field' => 'slug', + 'terms' => $v, + ); + + } + } + + // filters + $args = apply_filters( 'acf/fields/relationship/query', $args, $field, $options['post_id'] ); + $args = apply_filters( 'acf/fields/relationship/query/name=' . $field['name'], $args, $field, $options['post_id'] ); + $args = apply_filters( 'acf/fields/relationship/query/key=' . $field['key'], $args, $field, $options['post_id'] ); + + // get posts grouped by post type + $groups = acf_get_grouped_posts( $args ); + + // bail early if no posts + if ( empty( $groups ) ) { + return false; + } + + // loop + foreach ( array_keys( $groups ) as $group_title ) { + + // vars + $posts = acf_extract_var( $groups, $group_title ); + + // data + $data = array( + 'text' => $group_title, + 'children' => array(), + ); + + // convert post objects to post titles + foreach ( array_keys( $posts ) as $post_id ) { + + $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'] ); + + } + + // order posts by search + if ( $is_search && empty( $args['orderby'] ) && isset( $args['s'] ) ) { + + $posts = acf_order_by_search( $posts, $args['s'] ); + + } + + // append to $data + foreach ( array_keys( $posts ) as $post_id ) { + + $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ] ); + + } + + // append to $results + $results[] = $data; + + } + + // add as optgroup or results + if ( count( $args['post_type'] ) == 1 ) { + + $results = $results[0]['children']; + + } + + // vars + $response = array( + 'results' => $results, + 'limit' => $args['posts_per_page'], + ); + + // return + return $response; + } - - // div attributes - $atts = array( - 'id' => $field['id'], - 'class' => "acf-relationship {$field['class']}", - 'data-min' => $field['min'], - 'data-max' => $field['max'], - 'data-s' => '', - 'data-paged' => 1, - 'data-post_type' => '', - 'data-taxonomy' => '', - ); - - ?> -
                                > + + + /* + * get_post_result + * + * This function will return an array containing id, text and maybe description data + * + * @type function + * @date 7/07/2016 + * @since 5.4.0 + * + * @param $id (mixed) + * @param $text (string) + * @return (array) + */ + + function get_post_result( $id, $text ) { + + // vars + $result = array( + 'id' => $id, + 'text' => $text, + ); + + // return + return $result; + + } + + + /* + * get_post_title + * + * This function returns the HTML for a result + * + * @type function + * @date 1/11/2013 + * @since 5.0.0 + * + * @param $post (object) + * @param $field (array) + * @param $post_id (int) the post_id to which this value is saved to + * @return (string) + */ + + function get_post_title( $post, $field, $post_id = 0, $is_search = 0 ) { + + // get post_id + if ( ! $post_id ) { + $post_id = acf_get_form_data( 'post_id' ); + } + + // vars + $title = acf_get_post_title( $post, $is_search ); + + // featured_image + if ( acf_in_array( 'featured_image', $field['elements'] ) ) { + + // vars + $class = 'thumbnail'; + $thumbnail = acf_get_post_thumbnail( $post->ID, array( 17, 17 ) ); + + // icon + if ( $thumbnail['type'] == 'icon' ) { + + $class .= ' -' . $thumbnail['type']; + + } + + // append + $title = '
                                ' . $thumbnail['html'] . '
                                ' . $title; + + } + + // filters + $title = apply_filters( 'acf/fields/relationship/result', $title, $post, $field, $post_id ); + $title = apply_filters( 'acf/fields/relationship/result/name=' . $field['_name'], $title, $post, $field, $post_id ); + $title = apply_filters( 'acf/fields/relationship/result/key=' . $field['key'], $title, $post, $field, $post_id ); + + // return + return $title; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $post_type = acf_get_array( $field['post_type'] ); + $taxonomy = acf_get_array( $field['taxonomy'] ); + $filters = acf_get_array( $field['filters'] ); + + // filters + $filter_count = count( $filters ); + $filter_post_type_choices = array(); + $filter_taxonomy_choices = array(); + + // post_type filter + if ( in_array( 'post_type', $filters ) ) { + + $filter_post_type_choices = array( + '' => __( 'Select post type', 'acf' ), + ) + acf_get_pretty_post_types( $post_type ); + } + + // taxonomy filter + if ( in_array( 'taxonomy', $filters ) ) { + + $term_choices = array(); + $filter_taxonomy_choices = array( + '' => __( 'Select taxonomy', 'acf' ), + ); + + // check for specific taxonomy setting + if ( $taxonomy ) { + $terms = acf_get_encoded_terms( $taxonomy ); + $term_choices = acf_get_choices_from_terms( $terms, 'slug' ); + + // if no terms were specified, find all terms + } else { + + // restrict taxonomies by the post_type selected + $term_args = array(); + if ( $post_type ) { + $term_args['taxonomy'] = acf_get_taxonomies( + array( + 'post_type' => $post_type, + ) + ); + } + + // get terms + $terms = acf_get_grouped_terms( $term_args ); + $term_choices = acf_get_choices_from_grouped_terms( $terms, 'slug' ); + } + + // append term choices + $filter_taxonomy_choices = $filter_taxonomy_choices + $term_choices; + + } + + // div attributes + $atts = array( + 'id' => $field['id'], + 'class' => "acf-relationship {$field['class']}", + 'data-min' => $field['min'], + 'data-max' => $field['max'], + 'data-s' => '', + 'data-paged' => 1, + 'data-post_type' => '', + 'data-taxonomy' => '', + ); + + ?> +
                                > - $field['name'], 'value' => '') ); ?> + $field['name'], + 'value' => '', + ) + ); + ?> - -
                                - + +
                                + - +
                                - $filter_post_type_choices, 'data-filter' => 'post_type') ); ?> + $filter_post_type_choices, + 'data-filter' => 'post_type', + ) + ); + ?>
                                - +
                                - $filter_taxonomy_choices, 'data-filter' => 'taxonomy') ); ?> + $filter_taxonomy_choices, + 'data-filter' => 'taxonomy', + ) + ); + ?>
                                - +
                                - +
                                @@ -501,279 +514,296 @@ class acf_field_relationship extends acf_field {
                                  - $field['value'], - 'post_type' => $field['post_type'] - )); - - - // loop - foreach( $posts as $post ): ?> + $field['value'], + 'post_type' => $field['post_type'], + ) + ); + + // loop + foreach ( $posts as $post ) : + ?>
                                • - $field['name'].'[]', 'value' => $post->ID) ); ?> - - get_post_title( $post, $field ) ); ?> + $field['name'] . '[]', + 'value' => $post->ID, + ) + ); + ?> + + get_post_title( $post, $field ) ); ?>
                                • - - + +
                                - __('Filter by Post Type','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'post_type', - 'choices' => acf_get_pretty_post_types(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All post types",'acf'), - )); - - - // taxonomy - acf_render_field_setting( $field, array( - 'label' => __('Filter by Taxonomy','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'taxonomy', - 'choices' => acf_get_taxonomy_terms(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All taxonomies",'acf'), - )); - - - // filters - acf_render_field_setting( $field, array( - 'label' => __('Filters','acf'), - 'instructions' => '', - 'type' => 'checkbox', - 'name' => 'filters', - 'choices' => array( - 'search' => __("Search",'acf'), - 'post_type' => __("Post Type",'acf'), - 'taxonomy' => __("Taxonomy",'acf'), - ), - )); - - - // filters - acf_render_field_setting( $field, array( - 'label' => __('Elements','acf'), - 'instructions' => __('Selected elements will be displayed in each result','acf'), - 'type' => 'checkbox', - 'name' => 'elements', - 'choices' => array( - 'featured_image' => __("Featured Image",'acf'), - ), - )); - - - // min - acf_render_field_setting( $field, array( - 'label' => __('Minimum posts','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'min', - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Maximum posts','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'max', - )); - - - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'return_format', - 'choices' => array( - 'object' => __("Post Object",'acf'), - 'id' => __("Post ID",'acf'), - ), - 'layout' => 'horizontal', - )); - - - } - - - /* - * format_value() - * - * This filter is applied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) { - - return $value; - + $value, - 'post_type' => $field['post_type'] - )); - - } - - - // return - return $value; - - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // default - if( empty($value) || !is_array($value) ) { - - $value = array(); - - } - - - // min - if( count($value) < $field['min'] ) { - - $valid = _n( '%s requires at least %s selection', '%s requires at least %s selections', $field['min'], 'acf' ); - $valid = sprintf( $valid, $field['label'], $field['min'] ); - - } - - - // return - return $valid; - - } - - - /* - * update_value() - * - * This filter is applied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( empty($value) ) { - return $value; - } - - // Format array of values. - // - ensure each value is an id. - // - Parse each id as string for SQL LIKE queries. - if( acf_is_sequential_array($value) ) { - $value = array_map('acf_idval', $value); - $value = array_map('strval', $value); - - // Parse single value for id. - } else { - $value = acf_idval( $value ); - } - - // Return value. - return $value; - } - -} -// initialize -acf_register_field_type( 'acf_field_relationship' ); + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // vars + $field['min'] = empty( $field['min'] ) ? '' : $field['min']; + $field['max'] = empty( $field['max'] ) ? '' : $field['max']; + + // post_type + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by Post Type', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'post_type', + 'choices' => acf_get_pretty_post_types(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All post types', 'acf' ), + ) + ); + + // taxonomy + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by Taxonomy', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'taxonomy', + 'choices' => acf_get_taxonomy_terms(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All taxonomies', 'acf' ), + ) + ); + + // filters + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filters', 'acf' ), + 'instructions' => '', + 'type' => 'checkbox', + 'name' => 'filters', + 'choices' => array( + 'search' => __( 'Search', 'acf' ), + 'post_type' => __( 'Post Type', 'acf' ), + 'taxonomy' => __( 'Taxonomy', 'acf' ), + ), + ) + ); + + // filters + acf_render_field_setting( + $field, + array( + 'label' => __( 'Elements', 'acf' ), + 'instructions' => __( 'Selected elements will be displayed in each result', 'acf' ), + 'type' => 'checkbox', + 'name' => 'elements', + 'choices' => array( + 'featured_image' => __( 'Featured Image', 'acf' ), + ), + ) + ); + + // min + acf_render_field_setting( + $field, + array( + 'label' => __( 'Minimum posts', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'min', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Maximum posts', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'max', + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'return_format', + 'choices' => array( + 'object' => __( 'Post Object', 'acf' ), + 'id' => __( 'Post ID', 'acf' ), + ), + 'layout' => 'horizontal', + ) + ); + + } + + + /* + * format_value() + * + * This filter is applied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + + return $value; + + } + + // force value to array + $value = acf_get_array( $value ); + + // convert to int + $value = array_map( 'intval', $value ); + + // load posts if needed + if ( $field['return_format'] == 'object' ) { + + // get posts + $value = acf_get_posts( + array( + 'post__in' => $value, + 'post_type' => $field['post_type'], + ) + ); + + } + + // return + return $value; + + } + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // default + if ( empty( $value ) || ! is_array( $value ) ) { + + $value = array(); + + } + + // min + if ( count( $value ) < $field['min'] ) { + + $valid = _n( '%1$s requires at least %2$s selection', '%1$s requires at least %2$s selections', $field['min'], 'acf' ); + $valid = sprintf( $valid, $field['label'], $field['min'] ); + + } + + // return + return $valid; + + } + + + /* + * update_value() + * + * This filter is applied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( empty( $value ) ) { + return $value; + } + + // Format array of values. + // - ensure each value is an id. + // - Parse each id as string for SQL LIKE queries. + if ( acf_is_sequential_array( $value ) ) { + $value = array_map( 'acf_idval', $value ); + $value = array_map( 'strval', $value ); + + // Parse single value for id. + } else { + $value = acf_idval( $value ); + } + + // Return value. + return $value; + } + + } + + + // initialize + acf_register_field_type( 'acf_field_relationship' ); endif; // class_exists check diff --git a/includes/fields/class-acf-field-select.php b/includes/fields/class-acf-field-select.php index 99f207c..2ceb14f 100644 --- a/includes/fields/class-acf-field-select.php +++ b/includes/fields/class-acf-field-select.php @@ -1,631 +1,638 @@ name = 'select'; - $this->label = _x('Select', 'noun', 'acf'); - $this->category = 'choice'; - $this->defaults = array( - 'multiple' => 0, - 'allow_null' => 0, - 'choices' => array(), - 'default_value' => '', - 'ui' => 0, - 'ajax' => 0, - 'placeholder' => '', - 'return_format' => 'value' - ); - - - // ajax - add_action('wp_ajax_acf/fields/select/query', array($this, 'ajax_query')); - add_action('wp_ajax_nopriv_acf/fields/select/query', array($this, 'ajax_query')); - - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // bail ealry if no enqueue - if( !acf_get_setting('enqueue_select2') ) return; - - - // globals - global $wp_scripts, $wp_styles; - - - // vars - $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - $major = acf_get_setting('select2_version'); - $version = ''; - $script = ''; - $style = ''; - - - // attempt to find 3rd party Select2 version - // - avoid including v3 CSS when v4 JS is already enququed - if( isset($wp_scripts->registered['select2']) ) { - - $major = (int) $wp_scripts->registered['select2']->ver; - - } - - - // v4 - if( $major == 4 ) { - - $version = '4.0'; - $script = acf_get_url("assets/inc/select2/4/select2.full{$min}.js"); - $style = acf_get_url("assets/inc/select2/4/select2{$min}.css"); - - // v3 - } else { - - $version = '3.5.2'; - $script = acf_get_url("assets/inc/select2/3/select2{$min}.js"); - $style = acf_get_url("assets/inc/select2/3/select2.css"); - - } - - - // enqueue - wp_enqueue_script('select2', $script, array('jquery'), $version ); - wp_enqueue_style('select2', $style, '', $version ); - - - // localize - acf_localize_data(array( - 'select2L10n' => array( - 'matches_1' => _x('One result is available, press enter to select it.', 'Select2 JS matches_1', 'acf'), - 'matches_n' => _x('%d results are available, use up and down arrow keys to navigate.', 'Select2 JS matches_n', 'acf'), - 'matches_0' => _x('No matches found', 'Select2 JS matches_0', 'acf'), - 'input_too_short_1' => _x('Please enter 1 or more characters', 'Select2 JS input_too_short_1', 'acf' ), - 'input_too_short_n' => _x('Please enter %d or more characters', 'Select2 JS input_too_short_n', 'acf' ), - 'input_too_long_1' => _x('Please delete 1 character', 'Select2 JS input_too_long_1', 'acf' ), - 'input_too_long_n' => _x('Please delete %d characters', 'Select2 JS input_too_long_n', 'acf' ), - 'selection_too_long_1' => _x('You can only select 1 item', 'Select2 JS selection_too_long_1', 'acf' ), - 'selection_too_long_n' => _x('You can only select %d items', 'Select2 JS selection_too_long_n', 'acf' ), - 'load_more' => _x('Loading more results…', 'Select2 JS load_more', 'acf' ), - 'searching' => _x('Searching…', 'Select2 JS searching', 'acf' ), - 'load_fail' => _x('Loading failed', 'Select2 JS load_fail', 'acf' ), - ) - )); - } - - - /* - * ajax_query - * - * description - * - * @type function - * @date 24/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // get choices - $response = $this->get_ajax_query( $_POST ); - - - // return - acf_send_ajax_results($response); - - } - - - /* - * get_ajax_query - * - * This function will return an array of data formatted for use in a select2 AJAX response - * - * @type function - * @date 15/10/2014 - * @since 5.0.9 - * - * @param $options (array) - * @return (array) - */ - - function get_ajax_query( $options = array() ) { - - // defaults - $options = acf_parse_args($options, array( - 'post_id' => 0, - 's' => '', - 'field_key' => '', - 'paged' => 1 - )); - - - // load field - $field = acf_get_field( $options['field_key'] ); - if( !$field ) return false; - - - // get choices - $choices = acf_get_array($field['choices']); - if( empty($field['choices']) ) return false; - - - // vars - $results = array(); - $s = null; - - - // search - if( $options['s'] !== '' ) { - - // strip slashes (search may be integer) - $s = strval( $options['s'] ); - $s = wp_unslash( $s ); - - } - - - // loop - foreach( $field['choices'] as $k => $v ) { - - // ensure $v is a string - $v = strval( $v ); - - - // if searching, but doesn't exist - if( is_string($s) && stripos($v, $s) === false ) continue; - - - // append - $results[] = array( - 'id' => $k, - 'text' => $v + class acf_field_select extends acf_field { + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'select'; + $this->label = _x( 'Select', 'noun', 'acf' ); + $this->category = 'choice'; + $this->defaults = array( + 'multiple' => 0, + 'allow_null' => 0, + 'choices' => array(), + 'default_value' => '', + 'ui' => 0, + 'ajax' => 0, + 'placeholder' => '', + 'return_format' => 'value', ); - + + // ajax + add_action( 'wp_ajax_acf/fields/select/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/select/query', array( $this, 'ajax_query' ) ); + } - - - // vars - $response = array( - 'results' => $results - ); - - - // return - return $response; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // convert - $value = acf_get_array($field['value']); - $choices = acf_get_array($field['choices']); - - - // placeholder - if( empty($field['placeholder']) ) { - $field['placeholder'] = _x('Select', 'verb', 'acf'); + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // bail ealry if no enqueue + if ( ! acf_get_setting( 'enqueue_select2' ) ) { + return; + } + + // globals + global $wp_scripts, $wp_styles; + + // vars + $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + $major = acf_get_setting( 'select2_version' ); + $version = ''; + $script = ''; + $style = ''; + + // attempt to find 3rd party Select2 version + // - avoid including v3 CSS when v4 JS is already enququed + if ( isset( $wp_scripts->registered['select2'] ) ) { + + $major = (int) $wp_scripts->registered['select2']->ver; + + } + + // v4 + if ( $major == 4 ) { + + $version = '4.0'; + $script = acf_get_url( "assets/inc/select2/4/select2.full{$min}.js" ); + $style = acf_get_url( "assets/inc/select2/4/select2{$min}.css" ); + + // v3 + } else { + + $version = '3.5.2'; + $script = acf_get_url( "assets/inc/select2/3/select2{$min}.js" ); + $style = acf_get_url( 'assets/inc/select2/3/select2.css' ); + + } + + // enqueue + wp_enqueue_script( 'select2', $script, array( 'jquery' ), $version ); + wp_enqueue_style( 'select2', $style, '', $version ); + + // localize + acf_localize_data( + array( + 'select2L10n' => array( + 'matches_1' => _x( 'One result is available, press enter to select it.', 'Select2 JS matches_1', 'acf' ), + 'matches_n' => _x( '%d results are available, use up and down arrow keys to navigate.', 'Select2 JS matches_n', 'acf' ), + 'matches_0' => _x( 'No matches found', 'Select2 JS matches_0', 'acf' ), + 'input_too_short_1' => _x( 'Please enter 1 or more characters', 'Select2 JS input_too_short_1', 'acf' ), + 'input_too_short_n' => _x( 'Please enter %d or more characters', 'Select2 JS input_too_short_n', 'acf' ), + 'input_too_long_1' => _x( 'Please delete 1 character', 'Select2 JS input_too_long_1', 'acf' ), + 'input_too_long_n' => _x( 'Please delete %d characters', 'Select2 JS input_too_long_n', 'acf' ), + 'selection_too_long_1' => _x( 'You can only select 1 item', 'Select2 JS selection_too_long_1', 'acf' ), + 'selection_too_long_n' => _x( 'You can only select %d items', 'Select2 JS selection_too_long_n', 'acf' ), + 'load_more' => _x( 'Loading more results…', 'Select2 JS load_more', 'acf' ), + 'searching' => _x( 'Searching…', 'Select2 JS searching', 'acf' ), + 'load_fail' => _x( 'Loading failed', 'Select2 JS load_fail', 'acf' ), + ), + ) + ); } - - - // add empty value (allows '' to be selected) - if( empty($value) ) { - $value = array(''); + + + /* + * ajax_query + * + * description + * + * @type function + * @date 24/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // get choices + $response = $this->get_ajax_query( $_POST ); + + // return + acf_send_ajax_results( $response ); + } - - - // prepend empty choice - // - only for single selects - // - have tried array_merge but this causes keys to re-index if is numeric (post ID's) - if( $field['allow_null'] && !$field['multiple'] ) { - $choices = array( '' => "- {$field['placeholder']} -" ) + $choices; + + + /* + * get_ajax_query + * + * This function will return an array of data formatted for use in a select2 AJAX response + * + * @type function + * @date 15/10/2014 + * @since 5.0.9 + * + * @param $options (array) + * @return (array) + */ + + function get_ajax_query( $options = array() ) { + + // defaults + $options = acf_parse_args( + $options, + array( + 'post_id' => 0, + 's' => '', + 'field_key' => '', + 'paged' => 1, + ) + ); + + // load field + $field = acf_get_field( $options['field_key'] ); + if ( ! $field ) { + return false; + } + + // get choices + $choices = acf_get_array( $field['choices'] ); + if ( empty( $field['choices'] ) ) { + return false; + } + + // vars + $results = array(); + $s = null; + + // search + if ( $options['s'] !== '' ) { + + // strip slashes (search may be integer) + $s = strval( $options['s'] ); + $s = wp_unslash( $s ); + + } + + // loop + foreach ( $field['choices'] as $k => $v ) { + + // ensure $v is a string + $v = strval( $v ); + + // if searching, but doesn't exist + if ( is_string( $s ) && stripos( $v, $s ) === false ) { + continue; + } + + // append + $results[] = array( + 'id' => $k, + 'text' => $v, + ); + + } + + // vars + $response = array( + 'results' => $results, + ); + + // return + return $response; + } - - - // clean up choices if using ajax - if( $field['ui'] && $field['ajax'] ) { - $minimal = array(); - foreach( $value as $key ) { - if( isset($choices[ $key ]) ) { - $minimal[ $key ] = $choices[ $key ]; + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // convert + $value = acf_get_array( $field['value'] ); + $choices = acf_get_array( $field['choices'] ); + + // placeholder + if ( empty( $field['placeholder'] ) ) { + $field['placeholder'] = _x( 'Select', 'verb', 'acf' ); + } + + // add empty value (allows '' to be selected) + if ( empty( $value ) ) { + $value = array( '' ); + } + + // prepend empty choice + // - only for single selects + // - have tried array_merge but this causes keys to re-index if is numeric (post ID's) + if ( $field['allow_null'] && ! $field['multiple'] ) { + $choices = array( '' => "- {$field['placeholder']} -" ) + $choices; + } + + // clean up choices if using ajax + if ( $field['ui'] && $field['ajax'] ) { + $minimal = array(); + foreach ( $value as $key ) { + if ( isset( $choices[ $key ] ) ) { + $minimal[ $key ] = $choices[ $key ]; + } + } + $choices = $minimal; + } + + // vars + $select = array( + 'id' => $field['id'], + 'class' => $field['class'], + 'name' => $field['name'], + 'data-ui' => $field['ui'], + 'data-ajax' => $field['ajax'], + 'data-multiple' => $field['multiple'], + 'data-placeholder' => $field['placeholder'], + 'data-allow_null' => $field['allow_null'], + ); + + // multiple + if ( $field['multiple'] ) { + + $select['multiple'] = 'multiple'; + $select['size'] = 5; + $select['name'] .= '[]'; + + // Reduce size to single line if UI. + if ( $field['ui'] ) { + $select['size'] = 1; } } - $choices = $minimal; - } - - - // vars - $select = array( - 'id' => $field['id'], - 'class' => $field['class'], - 'name' => $field['name'], - 'data-ui' => $field['ui'], - 'data-ajax' => $field['ajax'], - 'data-multiple' => $field['multiple'], - 'data-placeholder' => $field['placeholder'], - 'data-allow_null' => $field['allow_null'] - ); - - - // multiple - if( $field['multiple'] ) { - - $select['multiple'] = 'multiple'; - $select['size'] = 5; - $select['name'] .= '[]'; - - // Reduce size to single line if UI. - if( $field['ui'] ) { - $select['size'] = 1; + + // special atts + if ( ! empty( $field['readonly'] ) ) { + $select['readonly'] = 'readonly'; } - } - - - // special atts - if( !empty($field['readonly']) ) $select['readonly'] = 'readonly'; - if( !empty($field['disabled']) ) $select['disabled'] = 'disabled'; - if( !empty($field['ajax_action']) ) $select['data-ajax_action'] = $field['ajax_action']; - - - // hidden input is needed to allow validation to see element with no selected value + if ( $field['multiple'] || $field['ui'] ) { + acf_hidden_input( + array( + 'id' => $field['id'] . '-input', + 'name' => $field['name'], + ) + ); + } + + // append + $select['value'] = $value; + $select['choices'] = $choices; + + // render + acf_select_input( $select ); + } - // Otherwise, return a single value. - return acf_unarray( $value ); - } - - - /* - * update_field() - * - * This filter is appied to the $field before it is saved to the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * @param $post_id - the field group ID (post_type = acf) - * - * @return $field - the modified field - */ - function update_field( $field ) { - - // decode choices (convert to array) - $field['choices'] = acf_decode_choices($field['choices']); - $field['default_value'] = acf_decode_choices($field['default_value'], true); + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // encode choices (convert from array) + $field['choices'] = acf_encode_choices( $field['choices'] ); + $field['default_value'] = acf_encode_choices( $field['default_value'], false ); + + // choices + acf_render_field_setting( + $field, + array( + 'label' => __( 'Choices', 'acf' ), + 'instructions' => __( 'Enter each choice on a new line.', 'acf' ) . '

                                ' . __( 'For more control, you may specify both a value and label like this:', 'acf' ) . '

                                ' . __( 'red : Red', 'acf' ), + 'name' => 'choices', + 'type' => 'textarea', + ) + ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Enter each default value on a new line', 'acf' ), + 'name' => 'default_value', + 'type' => 'textarea', + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // multiple + acf_render_field_setting( + $field, + array( + 'label' => __( 'Select multiple values?', 'acf' ), + 'instructions' => '', + 'name' => 'multiple', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // ui + acf_render_field_setting( + $field, + array( + 'label' => __( 'Stylised UI', 'acf' ), + 'instructions' => '', + 'name' => 'ui', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // ajax + acf_render_field_setting( + $field, + array( + 'label' => __( 'Use AJAX to lazy load choices?', 'acf' ), + 'instructions' => '', + 'name' => 'ajax', + 'type' => 'true_false', + 'ui' => 1, + 'conditions' => array( + 'field' => 'ui', + 'operator' => '==', + 'value' => 1, + ), + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => __( 'Specify the value returned', 'acf' ), + 'type' => 'select', + 'name' => 'return_format', + 'choices' => array( + 'value' => __( 'Value', 'acf' ), + 'label' => __( 'Label', 'acf' ), + 'array' => __( 'Both (Array)', 'acf' ), + ), + ) + ); - // Convert back to string for single selects. - if( !$field['multiple'] ) { - $field['default_value'] = acf_unarray( $field['default_value'] ); } - - // return - return $field; - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $post_id - the $post_id of which the value will be saved - * @param $field - the field array holding all the field options - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( empty($value) ) { + + + /* + * load_value() + * + * This filter is applied to the $value after it is loaded from the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value found in the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * @return $value + */ + function load_value( $value, $post_id, $field ) { + + // Return an array when field is set for multiple. + if ( $field['multiple'] ) { + if ( acf_is_empty( $value ) ) { + return array(); + } + return acf_array( $value ); + } + + // Otherwise, return a single value. + return acf_unarray( $value ); + } + + + /* + * update_field() + * + * This filter is appied to the $field before it is saved to the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * @param $post_id - the field group ID (post_type = acf) + * + * @return $field - the modified field + */ + + function update_field( $field ) { + + // decode choices (convert to array) + $field['choices'] = acf_decode_choices( $field['choices'] ); + $field['default_value'] = acf_decode_choices( $field['default_value'], true ); + + // Convert back to string for single selects. + if ( ! $field['multiple'] ) { + $field['default_value'] = acf_unarray( $field['default_value'] ); + } + + // return + return $field; + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $post_id - the $post_id of which the value will be saved + * @param $field - the field array holding all the field options + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( empty( $value ) ) { + return $value; + } + + // Format array of values. + // - Parse each value as string for SQL LIKE queries. + if ( is_array( $value ) ) { + $value = array_map( 'strval', $value ); + } + + // return return $value; } - - // Format array of values. - // - Parse each value as string for SQL LIKE queries. - if( is_array($value) ) { - $value = array_map('strval', $value); + + + /* + * translate_field + * + * This function will translate field settings + * + * @type function + * @date 8/03/2016 + * @since 5.3.2 + * + * @param $field (array) + * @return $field + */ + + function translate_field( $field ) { + + // translate + $field['choices'] = acf_translate( $field['choices'] ); + + // return + return $field; + } - - // return - return $value; - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @type function - * @date 8/03/2016 - * @since 5.3.2 - * - * @param $field (array) - * @return $field - */ - - function translate_field( $field ) { - - // translate - $field['choices'] = acf_translate( $field['choices'] ); - - - // return - return $field; - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - function format_value( $value, $post_id, $field ) { - if( is_array( $value ) ) { - foreach( $value as $i => $val ) { - $value[ $i ] = $this->format_value_single( $val, $post_id, $field ); + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + function format_value( $value, $post_id, $field ) { + if ( is_array( $value ) ) { + foreach ( $value as $i => $val ) { + $value[ $i ] = $this->format_value_single( $val, $post_id, $field ); + } + } else { + $value = $this->format_value_single( $value, $post_id, $field ); } - } else { - $value = $this->format_value_single( $value, $post_id, $field ); + return $value; } - return $value; - } - - - function format_value_single( $value, $post_id, $field ) { - - // bail ealry if is empty - if( acf_is_empty($value) ) return $value; - - - // vars - $label = acf_maybe_get($field['choices'], $value, $value); - - - // value - if( $field['return_format'] == 'value' ) { - - // do nothing - - // label - } elseif( $field['return_format'] == 'label' ) { - - $value = $label; - - // array - } elseif( $field['return_format'] == 'array' ) { - - $value = array( - 'value' => $value, - 'label' => $label - ); - - } - - - // return - return $value; - - } - -} -// initialize -acf_register_field_type( 'acf_field_select' ); + function format_value_single( $value, $post_id, $field ) { + + // bail ealry if is empty + if ( acf_is_empty( $value ) ) { + return $value; + } + + // vars + $label = acf_maybe_get( $field['choices'], $value, $value ); + + // value + if ( $field['return_format'] == 'value' ) { + + // do nothing + + // label + } elseif ( $field['return_format'] == 'label' ) { + + $value = $label; + + // array + } elseif ( $field['return_format'] == 'array' ) { + + $value = array( + 'value' => $value, + 'label' => $label, + ); + + } + + // return + return $value; + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_select' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-separator.php b/includes/fields/class-acf-field-separator.php index e2cee33..c3d7ba7 100644 --- a/includes/fields/class-acf-field-separator.php +++ b/includes/fields/class-acf-field-separator.php @@ -1,91 +1,88 @@ name = 'separator'; - $this->label = __("Separator",'acf'); - $this->category = 'layout'; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - /* do nothing */ - - } - - - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - - function load_field( $field ) { - - // remove name to avoid caching issue - $field['name'] = ''; - - - // remove required to avoid JS issues - $field['required'] = 0; - - - // set value other than 'null' to avoid ACF loading / caching issue - $field['value'] = false; - - - // return - return $field; - - } - -} + class acf_field_separator extends acf_field { -// initialize -acf_register_field_type( 'acf_field_separator' ); + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'separator'; + $this->label = __( 'Separator', 'acf' ); + $this->category = 'layout'; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + /* do nothing */ + + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + + function load_field( $field ) { + + // remove name to avoid caching issue + $field['name'] = ''; + + // remove required to avoid JS issues + $field['required'] = 0; + + // set value other than 'null' to avoid ACF loading / caching issue + $field['value'] = false; + + // return + return $field; + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_separator' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-tab.php b/includes/fields/class-acf-field-tab.php index 0e00760..9b16b42 100644 --- a/includes/fields/class-acf-field-tab.php +++ b/includes/fields/class-acf-field-tab.php @@ -1,164 +1,167 @@ name = 'tab'; - $this->label = __("Tab",'acf'); - $this->category = 'layout'; - $this->defaults = array( - 'placement' => 'top', - 'endpoint' => 0 // added in 5.2.8 - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $atts = array( - 'href' => '', - 'class' => 'acf-tab-button', - 'data-placement' => $field['placement'], - 'data-endpoint' => $field['endpoint'], - 'data-key' => $field['key'] - ); - - ?> - > - ' . __( 'Use "Tab Fields" to better organize your edit screen by grouping fields together.', 'acf') . '

                                '; - $message .= '

                                ' . __( 'All fields following this "tab field" (or until another "tab field" is defined) will be grouped together using this field\'s label as the tab heading.','acf') . '

                                '; - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Instructions','acf'), - 'instructions' => '', - 'name' => 'notes', - 'type' => 'message', - 'message' => $message, - )); -*/ - - - // preview_size - acf_render_field_setting( $field, array( - 'label' => __('Placement','acf'), - 'type' => 'select', - 'name' => 'placement', - 'choices' => array( - 'top' => __("Top aligned", 'acf'), - 'left' => __("Left aligned", 'acf'), - ) - )); - - - // endpoint - acf_render_field_setting( $field, array( - 'label' => __('Endpoint','acf'), - 'instructions' => __('Define an endpoint for the previous tabs to stop. This will start a new group of tabs.', 'acf'), - 'name' => 'endpoint', - 'type' => 'true_false', - 'ui' => 1, - )); - - } - - - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - function load_field( $field ) { - - // remove name to avoid caching issue - $field['name'] = ''; - - // remove instructions - $field['instructions'] = ''; - - // remove required to avoid JS issues - $field['required'] = 0; - - // set value other than 'null' to avoid ACF loading / caching issue - $field['value'] = false; - - // return - return $field; - - } - -} + class acf_field_tab extends acf_field { -// initialize -acf_register_field_type( 'acf_field_tab' ); + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'tab'; + $this->label = __( 'Tab', 'acf' ); + $this->category = 'layout'; + $this->defaults = array( + 'placement' => 'top', + 'endpoint' => 0, // added in 5.2.8 + ); + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $atts = array( + 'href' => '', + 'class' => 'acf-tab-button', + 'data-placement' => $field['placement'], + 'data-endpoint' => $field['endpoint'], + 'data-key' => $field['key'], + ); + + ?> + > + ' . __( 'Use "Tab Fields" to better organize your edit screen by grouping fields together.', 'acf') . '

                                '; + $message .= '

                                ' . __( 'All fields following this "tab field" (or until another "tab field" is defined) will be grouped together using this field\'s label as the tab heading.','acf') . '

                                '; + + + // default_value + acf_render_field_setting( $field, array( + 'label' => __('Instructions','acf'), + 'instructions' => '', + 'name' => 'notes', + 'type' => 'message', + 'message' => $message, + )); + */ + + // preview_size + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placement', 'acf' ), + 'type' => 'select', + 'name' => 'placement', + 'choices' => array( + 'top' => __( 'Top aligned', 'acf' ), + 'left' => __( 'Left aligned', 'acf' ), + ), + ) + ); + + // endpoint + acf_render_field_setting( + $field, + array( + 'label' => __( 'Endpoint', 'acf' ), + 'instructions' => __( 'Define an endpoint for the previous tabs to stop. This will start a new group of tabs.', 'acf' ), + 'name' => 'endpoint', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + function load_field( $field ) { + + // remove name to avoid caching issue + $field['name'] = ''; + + // remove instructions + $field['instructions'] = ''; + + // remove required to avoid JS issues + $field['required'] = 0; + + // set value other than 'null' to avoid ACF loading / caching issue + $field['value'] = false; + + // return + return $field; + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_tab' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-taxonomy.php b/includes/fields/class-acf-field-taxonomy.php index 6331f95..7ad82b8 100644 --- a/includes/fields/class-acf-field-taxonomy.php +++ b/includes/fields/class-acf-field-taxonomy.php @@ -1,979 +1,978 @@ name = 'taxonomy'; - $this->label = __("Taxonomy",'acf'); - $this->category = 'relational'; - $this->defaults = array( - 'taxonomy' => 'category', - 'field_type' => 'checkbox', - 'multiple' => 0, - 'allow_null' => 0, - 'return_format' => 'id', - 'add_term' => 1, // 5.2.3 - 'load_terms' => 0, // 5.2.7 - 'save_terms' => 0 // 5.2.7 - ); - - // Register filter variations. - acf_add_filter_variations( 'acf/fields/taxonomy/query', array('name', 'key'), 1 ); - acf_add_filter_variations( 'acf/fields/taxonomy/result', array('name', 'key'), 2 ); - - - // ajax - add_action('wp_ajax_acf/fields/taxonomy/query', array($this, 'ajax_query')); - add_action('wp_ajax_nopriv_acf/fields/taxonomy/query', array($this, 'ajax_query')); - add_action('wp_ajax_acf/fields/taxonomy/add_term', array($this, 'ajax_add_term')); - - - // actions - add_action('acf/save_post', array($this, 'save_post'), 15, 1); - - } - - - /* - * ajax_query - * - * description - * - * @type function - * @date 24/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // get choices - $response = $this->get_ajax_query( $_POST ); - - - // return - acf_send_ajax_results($response); - - } - - - /* - * get_ajax_query - * - * This function will return an array of data formatted for use in a select2 AJAX response - * - * @type function - * @date 15/10/2014 - * @since 5.0.9 - * - * @param $options (array) - * @return (array) - */ - - function get_ajax_query( $options = array() ) { - - // defaults - $options = acf_parse_args($options, array( - 'post_id' => 0, - 's' => '', - 'field_key' => '', - 'paged' => 0 - )); - - - // load field - $field = acf_get_field( $options['field_key'] ); - if( !$field ) return false; - - - // bail early if taxonomy does not exist - if( !taxonomy_exists($field['taxonomy']) ) return false; - - - // vars - $results = array(); - $is_hierarchical = is_taxonomy_hierarchical( $field['taxonomy'] ); - $is_pagination = ($options['paged'] > 0); - $is_search = false; - $limit = 20; - $offset = 20 * ($options['paged'] - 1); - - - // args - $args = array( - 'taxonomy' => $field['taxonomy'], - 'hide_empty' => false - ); - - - // pagination - // - don't bother for hierarchial terms, we will need to load all terms anyway - if( $is_pagination && !$is_hierarchical ) { - - $args['number'] = $limit; - $args['offset'] = $offset; - - } - - - // search - if( $options['s'] !== '' ) { - - // strip slashes (search may be integer) - $s = wp_unslash( strval($options['s']) ); - - - // update vars - $args['search'] = $s; - $is_search = true; - - } - - - // filters - $args = apply_filters('acf/fields/taxonomy/query', $args, $field, $options['post_id']); - - - // get terms - $terms = acf_get_terms( $args ); - - - // sort into hierachial order! - if( $is_hierarchical ) { - - // update vars - $limit = acf_maybe_get( $args, 'number', $limit ); - $offset = acf_maybe_get( $args, 'offset', $offset ); - - - // get parent - $parent = acf_maybe_get( $args, 'parent', 0 ); - $parent = acf_maybe_get( $args, 'child_of', $parent ); - - - // this will fail if a search has taken place because parents wont exist - if( !$is_search ) { - - // order terms - $ordered_terms = _get_term_children( $parent, $terms, $field['taxonomy'] ); - - - // check for empty array (possible if parent did not exist within original data) - if( !empty($ordered_terms) ) { - - $terms = $ordered_terms; - - } - } - - - // fake pagination - if( $is_pagination ) { - - $terms = array_slice($terms, $offset, $limit); - - } - - } - - - /// append to r - foreach( $terms as $term ) { - - // add to json - $results[] = array( - 'id' => $term->term_id, - 'text' => $this->get_term_title( $term, $field, $options['post_id'] ) - ); - - } - - - // vars - $response = array( - 'results' => $results, - 'limit' => $limit - ); - - - // return - return $response; - - } - - /** - * Returns the Term's title displayed in the field UI. - * - * @date 1/11/2013 - * @since 5.0.0 - * - * @param WP_Term $term The term object. - * @param array $field The field settings. - * @param mixed $post_id The post_id being edited. - * @return string - */ - function get_term_title( $term, $field, $post_id = 0 ) { - $title = acf_get_term_title( $term ); - - // Default $post_id to current post being edited. - $post_id = $post_id ? $post_id : acf_get_form_data('post_id'); - - /** - * Filters the term title. - * - * @date 1/11/2013 - * @since 5.0.0 - * - * @param string $title The term title. - * @param WP_Term $term The term object. - * @param array $field The field settings. - * @param (int|string) $post_id The post_id being edited. - */ - return apply_filters('acf/fields/taxonomy/result', $title, $term, $field, $post_id); - } - - - /* - * get_terms - * - * This function will return an array of terms for a given field value - * - * @type function - * @date 13/06/2014 - * @since 5.0.0 - * - * @param $value (array) - * @return $value - */ - - function get_terms( $value, $taxonomy = 'category' ) { - - // load terms in 1 query to save multiple DB calls from following code - if( count($value) > 1 ) { - - $terms = acf_get_terms(array( - 'taxonomy' => $taxonomy, - 'include' => $value, - 'hide_empty' => false - )); - - } - - - // update value to include $post - foreach( array_keys($value) as $i ) { - - $value[ $i ] = get_term( $value[ $i ], $taxonomy ); - - } - - - // filter out null values - $value = array_filter($value); - - - // return - return $value; - } - - - /* - * load_value() - * - * This filter is appied to the $value after it is loaded from the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value found in the database - * @param $post_id - the $post_id from which the value was loaded from - * @param $field - the field array holding all the field options - * - * @return $value - the value to be saved in te database - */ - - function load_value( $value, $post_id, $field ) { - - // get valid terms - $value = acf_get_valid_terms($value, $field['taxonomy']); - - - // load_terms - if( $field['load_terms'] ) { - - // Decode $post_id for $type and $id. - extract( acf_decode_post_id($post_id) ); - if( $type === 'block' ) { - // Get parent block... - } - - // get terms - $term_ids = wp_get_object_terms( $id, $field['taxonomy'], array('fields' => 'ids', 'orderby' => 'none') ); - - - // bail early if no terms - if( empty($term_ids) || is_wp_error($term_ids) ) return false; - - - // sort - if( !empty($value) ) { - - $order = array(); - - foreach( $term_ids as $i => $v ) { - - $order[ $i ] = array_search($v, $value); - - } - - array_multisort($order, $term_ids); - - } - - - // update value - $value = $term_ids; - - } - - - // convert back from array if neccessary - if( $field['field_type'] == 'select' || $field['field_type'] == 'radio' ) { - - $value = array_shift($value); - - } - - - // return - return $value; - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $field - the field array holding all the field options - * @param $post_id - the $post_id of which the value will be saved - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // vars - if( is_array($value) ) { - - $value = array_filter($value); - - } - - - // save_terms - if( $field['save_terms'] ) { - + var $save_post_terms = array(); + + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + // vars - $taxonomy = $field['taxonomy']; - - - // force value to array - $term_ids = acf_get_array( $value ); - - - // convert to int - $term_ids = array_map('intval', $term_ids); - - - // get existing term id's (from a previously saved field) - $old_term_ids = isset($this->save_post_terms[ $taxonomy ]) ? $this->save_post_terms[ $taxonomy ] : array(); - - - // append - $this->save_post_terms[ $taxonomy ] = array_merge($old_term_ids, $term_ids); - - - // if called directly from frontend update_field() - if( !did_action('acf/save_post') ) { - - $this->save_post( $post_id ); - - return $value; - - } - - } - - - // return - return $value; - - } - - - /* - * save_post - * - * This function will save any terms in the save_post_terms array - * - * @type function - * @date 26/11/2014 - * @since 5.0.9 - * - * @param $post_id (int) - * @return n/a - */ - - function save_post( $post_id ) { - - // Check for saved terms. - if( !empty($this->save_post_terms) ) { - - // Determine object ID allowing for non "post" $post_id (user, taxonomy, etc). - // Although not fully supported by WordPress, non "post" objects may use the term relationships table. - // Sharing taxonomies across object types is discoraged, but unique taxonomies work well. - // Note: Do not attempt to restrict to "post" only. This has been attempted in 5.8.9 and later reverted. - extract( acf_decode_post_id($post_id) ); - if( $type === 'block' ) { - // Get parent block... - } - - // Loop over taxonomies and save terms. - foreach( $this->save_post_terms as $taxonomy => $term_ids ){ - wp_set_object_terms( $id, $term_ids, $taxonomy, false ); - } - - // Reset storage. - $this->save_post_terms = array(); - } - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return false; - - - // force value to array - $value = acf_get_array( $value ); - - - // load posts if needed - if( $field['return_format'] == 'object' ) { - - // get posts - $value = $this->get_terms( $value, $field["taxonomy"] ); - - } - - - // convert back from array if neccessary - if( $field['field_type'] == 'select' || $field['field_type'] == 'radio' ) { - - $value = array_shift($value); - - } - + $this->name = 'taxonomy'; + $this->label = __( 'Taxonomy', 'acf' ); + $this->category = 'relational'; + $this->defaults = array( + 'taxonomy' => 'category', + 'field_type' => 'checkbox', + 'multiple' => 0, + 'allow_null' => 0, + 'return_format' => 'id', + 'add_term' => 1, // 5.2.3 + 'load_terms' => 0, // 5.2.7 + 'save_terms' => 0, // 5.2.7 + ); - // return - return $value; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field( $field ) { - - // force value to array - $field['value'] = acf_get_array( $field['value'] ); - - - // vars - $div = array( - 'class' => 'acf-taxonomy-field', - 'data-save' => $field['save_terms'], - 'data-ftype' => $field['field_type'], - 'data-taxonomy' => $field['taxonomy'], - 'data-allow_null' => $field['allow_null'] - ); - - - // get taxonomy - $taxonomy = get_taxonomy( $field['taxonomy'] ); - - - // bail early if taxonomy does not exist - if( !$taxonomy ) return; - - - ?> -
                                > - cap->manage_terms) ): ?> -
                                - -
                                - render_field_select( $field ); - - } elseif( $field['field_type'] == 'multi_select' ) { - - $field['multiple'] = 1; - - $this->render_field_select( $field ); - - } elseif( $field['field_type'] == 'radio' ) { - - $this->render_field_checkbox( $field ); - - } elseif( $field['field_type'] == 'checkbox' ) { - - $this->render_field_checkbox( $field ); - - } + // ajax + add_action( 'wp_ajax_acf/fields/taxonomy/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/taxonomy/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_acf/fields/taxonomy/add_term', array( $this, 'ajax_add_term' ) ); + + // actions + add_action( 'acf/save_post', array( $this, 'save_post' ), 15, 1 ); + + } + + + /* + * ajax_query + * + * description + * + * @type function + * @date 24/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // get choices + $response = $this->get_ajax_query( $_POST ); + + // return + acf_send_ajax_results( $response ); + + } + + + /* + * get_ajax_query + * + * This function will return an array of data formatted for use in a select2 AJAX response + * + * @type function + * @date 15/10/2014 + * @since 5.0.9 + * + * @param $options (array) + * @return (array) + */ + + function get_ajax_query( $options = array() ) { + + // defaults + $options = acf_parse_args( + $options, + array( + 'post_id' => 0, + 's' => '', + 'field_key' => '', + 'paged' => 0, + ) + ); + + // load field + $field = acf_get_field( $options['field_key'] ); + if ( ! $field ) { + return false; + } + + // bail early if taxonomy does not exist + if ( ! taxonomy_exists( $field['taxonomy'] ) ) { + return false; + } + + // vars + $results = array(); + $is_hierarchical = is_taxonomy_hierarchical( $field['taxonomy'] ); + $is_pagination = ( $options['paged'] > 0 ); + $is_search = false; + $limit = 20; + $offset = 20 * ( $options['paged'] - 1 ); + + // args + $args = array( + 'taxonomy' => $field['taxonomy'], + 'hide_empty' => false, + ); + + // pagination + // - don't bother for hierarchial terms, we will need to load all terms anyway + if ( $is_pagination && ! $is_hierarchical ) { + + $args['number'] = $limit; + $args['offset'] = $offset; + + } + + // search + if ( $options['s'] !== '' ) { + + // strip slashes (search may be integer) + $s = wp_unslash( strval( $options['s'] ) ); + + // update vars + $args['search'] = $s; + $is_search = true; + + } + + // filters + $args = apply_filters( 'acf/fields/taxonomy/query', $args, $field, $options['post_id'] ); - ?> -
                                get_terms( $field['value'], $field['taxonomy'] ); - - - // set choices - if( !empty($terms) ) { - - foreach( array_keys($terms) as $i ) { - - // vars - $term = acf_extract_var( $terms, $i ); - - - // append to choices - $field['choices'][ $term->term_id ] = $this->get_term_title( $term, $field ); - + $terms = acf_get_terms( $args ); + + // sort into hierachial order! + if ( $is_hierarchical ) { + + // update vars + $limit = acf_maybe_get( $args, 'number', $limit ); + $offset = acf_maybe_get( $args, 'offset', $offset ); + + // get parent + $parent = acf_maybe_get( $args, 'parent', 0 ); + $parent = acf_maybe_get( $args, 'child_of', $parent ); + + // this will fail if a search has taken place because parents wont exist + if ( ! $is_search ) { + + // order terms + $ordered_terms = _get_term_children( $parent, $terms, $field['taxonomy'] ); + + // check for empty array (possible if parent did not exist within original data) + if ( ! empty( $ordered_terms ) ) { + + $terms = $ordered_terms; + + } + } + + // fake pagination + if ( $is_pagination ) { + + $terms = array_slice( $terms, $offset, $limit ); + } - } - + + // append to r + foreach ( $terms as $term ) { + + // add to json + $results[] = array( + 'id' => $term->term_id, + 'text' => $this->get_term_title( $term, $field, $options['post_id'] ), + ); + + } + + // vars + $response = array( + 'results' => $results, + 'limit' => $limit, + ); + + // return + return $response; + } - - - // render select - acf_render_field( $field ); - - } - - - /* - * render_field_checkbox() - * - * Create the HTML interface for your field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_checkbox( $field ) { - - // hidden input - acf_hidden_input(array( - 'type' => 'hidden', - 'name' => $field['name'], - )); - - - // checkbox saves an array - if( $field['field_type'] == 'checkbox' ) { - - $field['name'] .= '[]'; - + + /** + * Returns the Term's title displayed in the field UI. + * + * @date 1/11/2013 + * @since 5.0.0 + * + * @param WP_Term $term The term object. + * @param array $field The field settings. + * @param mixed $post_id The post_id being edited. + * @return string + */ + function get_term_title( $term, $field, $post_id = 0 ) { + $title = acf_get_term_title( $term ); + + // Default $post_id to current post being edited. + $post_id = $post_id ? $post_id : acf_get_form_data( 'post_id' ); + + /** + * Filters the term title. + * + * @date 1/11/2013 + * @since 5.0.0 + * + * @param string $title The term title. + * @param WP_Term $term The term object. + * @param array $field The field settings. + * @param (int|string) $post_id The post_id being edited. + */ + return apply_filters( 'acf/fields/taxonomy/result', $title, $term, $field, $post_id ); } - - - // taxonomy - $taxonomy_obj = get_taxonomy($field['taxonomy']); - - - // include walker - acf_include('includes/walkers/class-acf-walker-taxonomy-field.php'); - - - // vars - $args = array( - 'taxonomy' => $field['taxonomy'], - 'show_option_none' => sprintf( _x('No %s', 'No terms', 'acf'), strtolower($taxonomy_obj->labels->name) ), - 'hide_empty' => false, - 'style' => 'none', - 'walker' => new ACF_Taxonomy_Field_Walker( $field ), - ); - - - // filter for 3rd party customization - $args = apply_filters('acf/fields/taxonomy/wp_list_categories', $args, $field); - $args = apply_filters('acf/fields/taxonomy/wp_list_categories/name=' . $field['_name'], $args, $field); - $args = apply_filters('acf/fields/taxonomy/wp_list_categories/key=' . $field['key'], $args, $field); - - ?> + + + /* + * get_terms + * + * This function will return an array of terms for a given field value + * + * @type function + * @date 13/06/2014 + * @since 5.0.0 + * + * @param $value (array) + * @return $value + */ + + function get_terms( $value, $taxonomy = 'category' ) { + + // load terms in 1 query to save multiple DB calls from following code + if ( count( $value ) > 1 ) { + + $terms = acf_get_terms( + array( + 'taxonomy' => $taxonomy, + 'include' => $value, + 'hide_empty' => false, + ) + ); + + } + + // update value to include $post + foreach ( array_keys( $value ) as $i ) { + + $value[ $i ] = get_term( $value[ $i ], $taxonomy ); + + } + + // filter out null values + $value = array_filter( $value ); + + // return + return $value; + } + + + /* + * load_value() + * + * This filter is appied to the $value after it is loaded from the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value found in the database + * @param $post_id - the $post_id from which the value was loaded from + * @param $field - the field array holding all the field options + * + * @return $value - the value to be saved in te database + */ + + function load_value( $value, $post_id, $field ) { + + // get valid terms + $value = acf_get_valid_terms( $value, $field['taxonomy'] ); + + // load_terms + if ( $field['load_terms'] ) { + + // Decode $post_id for $type and $id. + extract( acf_decode_post_id( $post_id ) ); + if ( $type === 'block' ) { + // Get parent block... + } + + // get terms + $term_ids = wp_get_object_terms( + $id, + $field['taxonomy'], + array( + 'fields' => 'ids', + 'orderby' => 'none', + ) + ); + + // bail early if no terms + if ( empty( $term_ids ) || is_wp_error( $term_ids ) ) { + return false; + } + + // sort + if ( ! empty( $value ) ) { + + $order = array(); + + foreach ( $term_ids as $i => $v ) { + + $order[ $i ] = array_search( $v, $value ); + + } + + array_multisort( $order, $term_ids ); + + } + + // update value + $value = $term_ids; + + } + + // convert back from array if neccessary + if ( $field['field_type'] == 'select' || $field['field_type'] == 'radio' ) { + + $value = array_shift( $value ); + + } + + // return + return $value; + + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $field - the field array holding all the field options + * @param $post_id - the $post_id of which the value will be saved + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // vars + if ( is_array( $value ) ) { + + $value = array_filter( $value ); + + } + + // save_terms + if ( $field['save_terms'] ) { + + // vars + $taxonomy = $field['taxonomy']; + + // force value to array + $term_ids = acf_get_array( $value ); + + // convert to int + $term_ids = array_map( 'intval', $term_ids ); + + // get existing term id's (from a previously saved field) + $old_term_ids = isset( $this->save_post_terms[ $taxonomy ] ) ? $this->save_post_terms[ $taxonomy ] : array(); + + // append + $this->save_post_terms[ $taxonomy ] = array_merge( $old_term_ids, $term_ids ); + + // if called directly from frontend update_field() + if ( ! did_action( 'acf/save_post' ) ) { + + $this->save_post( $post_id ); + + return $value; + + } + } + + // return + return $value; + + } + + + /* + * save_post + * + * This function will save any terms in the save_post_terms array + * + * @type function + * @date 26/11/2014 + * @since 5.0.9 + * + * @param $post_id (int) + * @return n/a + */ + + function save_post( $post_id ) { + + // Check for saved terms. + if ( ! empty( $this->save_post_terms ) ) { + + // Determine object ID allowing for non "post" $post_id (user, taxonomy, etc). + // Although not fully supported by WordPress, non "post" objects may use the term relationships table. + // Sharing taxonomies across object types is discoraged, but unique taxonomies work well. + // Note: Do not attempt to restrict to "post" only. This has been attempted in 5.8.9 and later reverted. + extract( acf_decode_post_id( $post_id ) ); + if ( $type === 'block' ) { + // Get parent block... + } + + // Loop over taxonomies and save terms. + foreach ( $this->save_post_terms as $taxonomy => $term_ids ) { + wp_set_object_terms( $id, $term_ids, $taxonomy, false ); + } + + // Reset storage. + $this->save_post_terms = array(); + } + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // force value to array + $value = acf_get_array( $value ); + + // load posts if needed + if ( $field['return_format'] == 'object' ) { + + // get posts + $value = $this->get_terms( $value, $field['taxonomy'] ); + + } + + // convert back from array if neccessary + if ( $field['field_type'] == 'select' || $field['field_type'] == 'radio' ) { + + $value = array_shift( $value ); + + } + + // return + return $value; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field( $field ) { + + // force value to array + $field['value'] = acf_get_array( $field['value'] ); + + // vars + $div = array( + 'class' => 'acf-taxonomy-field', + 'data-save' => $field['save_terms'], + 'data-ftype' => $field['field_type'], + 'data-taxonomy' => $field['taxonomy'], + 'data-allow_null' => $field['allow_null'], + ); + + // get taxonomy + $taxonomy = get_taxonomy( $field['taxonomy'] ); + + // bail early if taxonomy does not exist + if ( ! $taxonomy ) { + return; + } + + ?> +
                                > + cap->manage_terms ) ) : ?> +
                                + +
                                + render_field_select( $field ); + + } elseif ( $field['field_type'] == 'multi_select' ) { + + $field['multiple'] = 1; + + $this->render_field_select( $field ); + + } elseif ( $field['field_type'] == 'radio' ) { + + $this->render_field_checkbox( $field ); + + } elseif ( $field['field_type'] == 'checkbox' ) { + + $this->render_field_checkbox( $field ); + + } + + ?> +
                                + get_terms( $field['value'], $field['taxonomy'] ); + + // set choices + if ( ! empty( $terms ) ) { + + foreach ( array_keys( $terms ) as $i ) { + + // vars + $term = acf_extract_var( $terms, $i ); + + // append to choices + $field['choices'][ $term->term_id ] = $this->get_term_title( $term, $field ); + + } + } + } + + // render select + acf_render_field( $field ); + + } + + + /* + * render_field_checkbox() + * + * Create the HTML interface for your field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_checkbox( $field ) { + + // hidden input + acf_hidden_input( + array( + 'type' => 'hidden', + 'name' => $field['name'], + ) + ); + + // checkbox saves an array + if ( $field['field_type'] == 'checkbox' ) { + + $field['name'] .= '[]'; + + } + + // taxonomy + $taxonomy_obj = get_taxonomy( $field['taxonomy'] ); + + // include walker + acf_include( 'includes/walkers/class-acf-walker-taxonomy-field.php' ); + + // vars + $args = array( + 'taxonomy' => $field['taxonomy'], + 'show_option_none' => sprintf( _x( 'No %s', 'No terms', 'acf' ), strtolower( $taxonomy_obj->labels->name ) ), + 'hide_empty' => false, + 'style' => 'none', + 'walker' => new ACF_Taxonomy_Field_Walker( $field ), + ); + + // filter for 3rd party customization + $args = apply_filters( 'acf/fields/taxonomy/wp_list_categories', $args, $field ); + $args = apply_filters( 'acf/fields/taxonomy/wp_list_categories/name=' . $field['_name'], $args, $field ); + $args = apply_filters( 'acf/fields/taxonomy/wp_list_categories/key=' . $field['key'], $args, $field ); + + ?>
                                  - +
                                - __('Taxonomy','acf'), - 'instructions' => __('Select the taxonomy to be displayed','acf'), - 'type' => 'select', - 'name' => 'taxonomy', - 'choices' => acf_get_taxonomy_labels(), - )); - - - // field_type - acf_render_field_setting( $field, array( - 'label' => __('Appearance','acf'), - 'instructions' => __('Select the appearance of this field','acf'), - 'type' => 'select', - 'name' => 'field_type', - 'optgroup' => true, - 'choices' => array( - __("Multiple Values",'acf') => array( - 'checkbox' => __('Checkbox', 'acf'), - 'multi_select' => __('Multi Select', 'acf') - ), - __("Single Value",'acf') => array( - 'radio' => __('Radio Buttons', 'acf'), - 'select' => _x('Select', 'noun', 'acf') + __( 'Taxonomy', 'acf' ), + 'instructions' => __( 'Select the taxonomy to be displayed', 'acf' ), + 'type' => 'select', + 'name' => 'taxonomy', + 'choices' => acf_get_taxonomy_labels(), ) - ) - )); - - - // allow_null - acf_render_field_setting( $field, array( - 'label' => __('Allow Null?','acf'), - 'instructions' => '', - 'name' => 'allow_null', - 'type' => 'true_false', - 'ui' => 1, - 'conditions' => array( - 'field' => 'field_type', - 'operator' => '!=', - 'value' => 'checkbox' - ) - )); - - - // add_term - acf_render_field_setting( $field, array( - 'label' => __('Create Terms','acf'), - 'instructions' => __('Allow new terms to be created whilst editing','acf'), - 'name' => 'add_term', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // save_terms - acf_render_field_setting( $field, array( - 'label' => __('Save Terms','acf'), - 'instructions' => __('Connect selected terms to the post','acf'), - 'name' => 'save_terms', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // load_terms - acf_render_field_setting( $field, array( - 'label' => __('Load Terms','acf'), - 'instructions' => __('Load value from posts terms','acf'), - 'name' => 'load_terms', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Value','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'return_format', - 'choices' => array( - 'object' => __("Term Object",'acf'), - 'id' => __("Term ID",'acf') - ), - 'layout' => 'horizontal', - )); - - } - - - /* - * ajax_add_term - * - * description - * - * @type function - * @date 17/04/2015 - * @since 5.2.3 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_add_term() { - - // vars - $args = wp_parse_args($_POST, array( - 'nonce' => '', - 'field_key' => '', - 'term_name' => '', - 'term_parent' => '' - )); - - // verify nonce - if( !acf_verify_ajax() ) { - die(); - } - - // load field - $field = acf_get_field( $args['field_key'] ); - if( !$field ) { - die(); + ); + + // field_type + acf_render_field_setting( + $field, + array( + 'label' => __( 'Appearance', 'acf' ), + 'instructions' => __( 'Select the appearance of this field', 'acf' ), + 'type' => 'select', + 'name' => 'field_type', + 'optgroup' => true, + 'choices' => array( + __( 'Multiple Values', 'acf' ) => array( + 'checkbox' => __( 'Checkbox', 'acf' ), + 'multi_select' => __( 'Multi Select', 'acf' ), + ), + __( 'Single Value', 'acf' ) => array( + 'radio' => __( 'Radio Buttons', 'acf' ), + 'select' => _x( 'Select', 'noun', 'acf' ), + ), + ), + ) + ); + + // allow_null + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + 'conditions' => array( + 'field' => 'field_type', + 'operator' => '!=', + 'value' => 'checkbox', + ), + ) + ); + + // add_term + acf_render_field_setting( + $field, + array( + 'label' => __( 'Create Terms', 'acf' ), + 'instructions' => __( 'Allow new terms to be created whilst editing', 'acf' ), + 'name' => 'add_term', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // save_terms + acf_render_field_setting( + $field, + array( + 'label' => __( 'Save Terms', 'acf' ), + 'instructions' => __( 'Connect selected terms to the post', 'acf' ), + 'name' => 'save_terms', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // load_terms + acf_render_field_setting( + $field, + array( + 'label' => __( 'Load Terms', 'acf' ), + 'instructions' => __( 'Load value from posts terms', 'acf' ), + 'name' => 'load_terms', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Value', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'return_format', + 'choices' => array( + 'object' => __( 'Term Object', 'acf' ), + 'id' => __( 'Term ID', 'acf' ), + ), + 'layout' => 'horizontal', + ) + ); + } - - // vars - $taxonomy_obj = get_taxonomy($field['taxonomy']); - $taxonomy_label = $taxonomy_obj->labels->singular_name; - - // validate cap - // note: this situation should never occur due to condition of the add new button - if( !current_user_can( $taxonomy_obj->cap->manage_terms) ) { - wp_send_json_error(array( - 'error' => sprintf( __('User unable to add new %s', 'acf'), $taxonomy_label ) - )); - } - - // save? - if( $args['term_name'] ) { - - // exists - if( term_exists($args['term_name'], $field['taxonomy'], $args['term_parent']) ) { - wp_send_json_error(array( - 'error' => sprintf( __('%s already exists', 'acf'), $taxonomy_label ) - )); - } - + + + /* + * ajax_add_term + * + * description + * + * @type function + * @date 17/04/2015 + * @since 5.2.3 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_add_term() { + // vars - $extra = array(); - if( $args['term_parent'] ) { - $extra['parent'] = (int) $args['term_parent']; + $args = wp_parse_args( + $_POST, + array( + 'nonce' => '', + 'field_key' => '', + 'term_name' => '', + 'term_parent' => '', + ) + ); + + // verify nonce + if ( ! acf_verify_ajax() ) { + die(); } - - // insert - $data = wp_insert_term( $args['term_name'], $field['taxonomy'], $extra ); - - // error - if( is_wp_error($data) ) { - wp_send_json_error(array( - 'error' => $data->get_error_message() - )); + + // load field + $field = acf_get_field( $args['field_key'] ); + if ( ! $field ) { + die(); } - - // load term - $term = get_term($data['term_id']); - - // prepend ancenstors count to term name - $prefix = ''; - $ancestors = get_ancestors( $term->term_id, $term->taxonomy ); - if( !empty($ancestors) ) { - $prefix = str_repeat('- ', count($ancestors)); + + // vars + $taxonomy_obj = get_taxonomy( $field['taxonomy'] ); + $taxonomy_label = $taxonomy_obj->labels->singular_name; + + // validate cap + // note: this situation should never occur due to condition of the add new button + if ( ! current_user_can( $taxonomy_obj->cap->manage_terms ) ) { + wp_send_json_error( + array( + 'error' => sprintf( __( 'User unable to add new %s', 'acf' ), $taxonomy_label ), + ) + ); } - - // success - wp_send_json_success(array( - 'message' => sprintf( __('%s added', 'acf'), $taxonomy_label ), - 'term_id' => $term->term_id, - 'term_name' => $term->name, - 'term_label' => $prefix . $term->name, - 'term_parent' => $term->parent - )); - - } - - ?>
                                __('Name', 'acf'), - 'name' => 'term_name', - 'type' => 'text' - )); - - - if( is_taxonomy_hierarchical( $field['taxonomy'] ) ) { - - $choices = array(); - $response = $this->get_ajax_query($args); - - if( $response ) { - - foreach( $response['results'] as $v ) { - - $choices[ $v['id'] ] = $v['text']; - + + // save? + if ( $args['term_name'] ) { + + // exists + if ( term_exists( $args['term_name'], $field['taxonomy'], $args['term_parent'] ) ) { + wp_send_json_error( + array( + 'error' => sprintf( __( '%s already exists', 'acf' ), $taxonomy_label ), + ) + ); } - + + // vars + $extra = array(); + if ( $args['term_parent'] ) { + $extra['parent'] = (int) $args['term_parent']; + } + + // insert + $data = wp_insert_term( $args['term_name'], $field['taxonomy'], $extra ); + + // error + if ( is_wp_error( $data ) ) { + wp_send_json_error( + array( + 'error' => $data->get_error_message(), + ) + ); + } + + // load term + $term = get_term( $data['term_id'] ); + + // prepend ancenstors count to term name + $prefix = ''; + $ancestors = get_ancestors( $term->term_id, $term->taxonomy ); + if ( ! empty( $ancestors ) ) { + $prefix = str_repeat( '- ', count( $ancestors ) ); + } + + // success + wp_send_json_success( + array( + 'message' => sprintf( __( '%s added', 'acf' ), $taxonomy_label ), + 'term_id' => $term->term_id, + 'term_name' => $term->name, + 'term_label' => $prefix . $term->name, + 'term_parent' => $term->parent, + ) + ); + } - - acf_render_field_wrap(array( - 'label' => __('Parent', 'acf'), - 'name' => 'term_parent', - 'type' => 'select', - 'allow_null' => 1, - 'ui' => 0, - 'choices' => $choices - )); - - } - - - ?>

                                - + + ?> + + __( 'Name', 'acf' ), + 'name' => 'term_name', + 'type' => 'text', + ) + ); + + if ( is_taxonomy_hierarchical( $field['taxonomy'] ) ) { + + $choices = array(); + $response = $this->get_ajax_query( $args ); + + if ( $response ) { + + foreach ( $response['results'] as $v ) { + + $choices[ $v['id'] ] = $v['text']; + + } + } + + acf_render_field_wrap( + array( + 'label' => __( 'Parent', 'acf' ), + 'name' => 'term_parent', + 'type' => 'select', + 'allow_null' => 1, + 'ui' => 0, + 'choices' => $choices, + ) + ); + + } + + ?> +

                                +

                                \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-text.php b/includes/fields/class-acf-field-text.php index fcaaaaa..0183041 100644 --- a/includes/fields/class-acf-field-text.php +++ b/includes/fields/class-acf-field-text.php @@ -1,171 +1,182 @@ name = 'text'; + $this->label = __( 'Text', 'acf' ); + $this->defaults = array( + 'default_value' => '', + 'maxlength' => '', + 'placeholder' => '', + 'prepend' => '', + 'append' => '', + ); -class acf_field_text extends acf_field { - - - /* - * initialize - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'text'; - $this->label = __("Text",'acf'); - $this->defaults = array( - 'default_value' => '', - 'maxlength' => '', - 'placeholder' => '', - 'prepend' => '', - 'append' => '' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - $html = ''; - - // Prepend text. - if( $field['prepend'] !== '' ) { - $field['class'] .= ' acf-is-prepended'; - $html .= '
                                ' . acf_esc_html($field['prepend']) . '
                                '; } - - // Append text. - if( $field['append'] !== '' ) { - $field['class'] .= ' acf-is-appended'; - $html .= '
                                ' . acf_esc_html($field['append']) . '
                                '; - } - - // Input. - $input_attrs = array(); - foreach( array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'maxlength', 'pattern', 'readonly', 'disabled', 'required' ) as $k ) { - if( isset($field[ $k ]) ) { - $input_attrs[ $k ] = $field[ $k ]; + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + $html = ''; + + // Prepend text. + if ( $field['prepend'] !== '' ) { + $field['class'] .= ' acf-is-prepended'; + $html .= '
                                ' . acf_esc_html( $field['prepend'] ) . '
                                '; } + + // Append text. + if ( $field['append'] !== '' ) { + $field['class'] .= ' acf-is-appended'; + $html .= '
                                ' . acf_esc_html( $field['append'] ) . '
                                '; + } + + // Input. + $input_attrs = array(); + foreach ( array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'maxlength', 'pattern', 'readonly', 'disabled', 'required' ) as $k ) { + if ( isset( $field[ $k ] ) ) { + $input_attrs[ $k ] = $field[ $k ]; + } + } + $html .= '
                                ' . acf_get_text_input( acf_filter_attrs( $input_attrs ) ) . '
                                '; + + // Display. + echo $html; } - $html .= '
                                ' . acf_get_text_input( acf_filter_attrs($input_attrs) ) . '
                                '; - - // Display. - echo $html; - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'text', - 'name' => 'default_value', - )); - - - // placeholder - acf_render_field_setting( $field, array( - 'label' => __('Placeholder Text','acf'), - 'instructions' => __('Appears within the input','acf'), - 'type' => 'text', - 'name' => 'placeholder', - )); - - - // prepend - acf_render_field_setting( $field, array( - 'label' => __('Prepend','acf'), - 'instructions' => __('Appears before the input','acf'), - 'type' => 'text', - 'name' => 'prepend', - )); - - - // append - acf_render_field_setting( $field, array( - 'label' => __('Append','acf'), - 'instructions' => __('Appears after the input','acf'), - 'type' => 'text', - 'name' => 'append', - )); - - - // maxlength - acf_render_field_setting( $field, array( - 'label' => __('Character Limit','acf'), - 'instructions' => __('Leave blank for no limit','acf'), - 'type' => 'number', - 'name' => 'maxlength', - )); - - } - - /** - * validate_value - * - * Validates a field's value. - * - * @date 29/1/19 - * @since 5.7.11 - * - * @param (bool|string) Whether the value is vaid or not. - * @param mixed $value The field value. - * @param array $field The field array. - * @param string $input The HTML input name. - * @return (bool|string) - */ - function validate_value( $valid, $value, $field, $input ){ - - // Check maxlength - if( $field['maxlength'] && (acf_strlen($value) > $field['maxlength']) ) { - return sprintf( __('Value must not exceed %d characters', 'acf'), $field['maxlength'] ); - } - - // Return. - return $valid; - } -} -// initialize -acf_register_field_type( 'acf_field_text' ); + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'text', + 'name' => 'default_value', + ) + ); + + // placeholder + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placeholder Text', 'acf' ), + 'instructions' => __( 'Appears within the input', 'acf' ), + 'type' => 'text', + 'name' => 'placeholder', + ) + ); + + // prepend + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prepend', 'acf' ), + 'instructions' => __( 'Appears before the input', 'acf' ), + 'type' => 'text', + 'name' => 'prepend', + ) + ); + + // append + acf_render_field_setting( + $field, + array( + 'label' => __( 'Append', 'acf' ), + 'instructions' => __( 'Appears after the input', 'acf' ), + 'type' => 'text', + 'name' => 'append', + ) + ); + + // maxlength + acf_render_field_setting( + $field, + array( + 'label' => __( 'Character Limit', 'acf' ), + 'instructions' => __( 'Leave blank for no limit', 'acf' ), + 'type' => 'number', + 'name' => 'maxlength', + ) + ); + + } + + /** + * validate_value + * + * Validates a field's value. + * + * @date 29/1/19 + * @since 5.7.11 + * + * @param (bool|string) Whether the value is vaid or not. + * @param mixed $value The field value. + * @param array $field The field array. + * @param string $input The HTML input name. + * @return (bool|string) + */ + function validate_value( $valid, $value, $field, $input ) { + + // Check maxlength + if ( $field['maxlength'] && ( acf_strlen( $value ) > $field['maxlength'] ) ) { + return sprintf( __( 'Value must not exceed %d characters', 'acf' ), $field['maxlength'] ); + } + + // Return. + return $valid; + } + } + + + // initialize + acf_register_field_type( 'acf_field_text' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-textarea.php b/includes/fields/class-acf-field-textarea.php index 8b87cd1..4d1d22e 100644 --- a/includes/fields/class-acf-field-textarea.php +++ b/includes/fields/class-acf-field-textarea.php @@ -1,227 +1,235 @@ name = 'textarea'; + $this->label = __( 'Text Area', 'acf' ); + $this->defaults = array( + 'default_value' => '', + 'new_lines' => '', + 'maxlength' => '', + 'placeholder' => '', + 'rows' => '', + ); -class acf_field_textarea extends acf_field { - - - /* - * initialize - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'textarea'; - $this->label = __("Text Area",'acf'); - $this->defaults = array( - 'default_value' => '', - 'new_lines' => '', - 'maxlength' => '', - 'placeholder' => '', - 'rows' => '' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $atts = array(); - $keys = array( 'id', 'class', 'name', 'value', 'placeholder', 'rows', 'maxlength' ); - $keys2 = array( 'readonly', 'disabled', 'required' ); - - - // rows - if( !$field['rows'] ) { - $field['rows'] = 8; } - - - // atts (value="123") - foreach( $keys as $k ) { - if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ]; + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $atts = array(); + $keys = array( 'id', 'class', 'name', 'value', 'placeholder', 'rows', 'maxlength' ); + $keys2 = array( 'readonly', 'disabled', 'required' ); + + // rows + if ( ! $field['rows'] ) { + $field['rows'] = 8; + } + + // atts (value="123") + foreach ( $keys as $k ) { + if ( isset( $field[ $k ] ) ) { + $atts[ $k ] = $field[ $k ]; + } + } + + // atts2 (disabled="disabled") + foreach ( $keys2 as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $atts[ $k ] = $k; + } + } + + // remove empty atts + $atts = acf_clean_atts( $atts ); + + // return + acf_textarea_input( $atts ); + } - - - // atts2 (disabled="disabled") - foreach( $keys2 as $k ) { - if( !empty($field[ $k ]) ) $atts[ $k ] = $k; + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'textarea', + 'name' => 'default_value', + ) + ); + + // placeholder + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placeholder Text', 'acf' ), + 'instructions' => __( 'Appears within the input', 'acf' ), + 'type' => 'text', + 'name' => 'placeholder', + ) + ); + + // maxlength + acf_render_field_setting( + $field, + array( + 'label' => __( 'Character Limit', 'acf' ), + 'instructions' => __( 'Leave blank for no limit', 'acf' ), + 'type' => 'number', + 'name' => 'maxlength', + ) + ); + + // rows + acf_render_field_setting( + $field, + array( + 'label' => __( 'Rows', 'acf' ), + 'instructions' => __( 'Sets the textarea height', 'acf' ), + 'type' => 'number', + 'name' => 'rows', + 'placeholder' => 8, + ) + ); + + // formatting + acf_render_field_setting( + $field, + array( + 'label' => __( 'New Lines', 'acf' ), + 'instructions' => __( 'Controls how new lines are rendered', 'acf' ), + 'type' => 'select', + 'name' => 'new_lines', + 'choices' => array( + 'wpautop' => __( 'Automatically add paragraphs', 'acf' ), + 'br' => __( 'Automatically add <br>', 'acf' ), + '' => __( 'No Formatting', 'acf' ), + ), + ) + ); + } - - - // remove empty atts - $atts = acf_clean_atts( $atts ); - - - // return - acf_textarea_input( $atts ); - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'textarea', - 'name' => 'default_value', - )); - - - // placeholder - acf_render_field_setting( $field, array( - 'label' => __('Placeholder Text','acf'), - 'instructions' => __('Appears within the input','acf'), - 'type' => 'text', - 'name' => 'placeholder', - )); - - - // maxlength - acf_render_field_setting( $field, array( - 'label' => __('Character Limit','acf'), - 'instructions' => __('Leave blank for no limit','acf'), - 'type' => 'number', - 'name' => 'maxlength', - )); - - - // rows - acf_render_field_setting( $field, array( - 'label' => __('Rows','acf'), - 'instructions' => __('Sets the textarea height','acf'), - 'type' => 'number', - 'name' => 'rows', - 'placeholder' => 8 - )); - - - // formatting - acf_render_field_setting( $field, array( - 'label' => __('New Lines','acf'), - 'instructions' => __('Controls how new lines are rendered','acf'), - 'type' => 'select', - 'name' => 'new_lines', - 'choices' => array( - 'wpautop' => __("Automatically add paragraphs",'acf'), - 'br' => __("Automatically add <br>",'acf'), - '' => __("No Formatting",'acf') - ) - )); - - } - - - /* - * format_value() - * - * This filter is applied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value or not for template - if( empty($value) || !is_string($value) ) { - + + + /* + * format_value() + * + * This filter is applied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value or not for template + if ( empty( $value ) || ! is_string( $value ) ) { + + return $value; + + } + + // new lines + if ( $field['new_lines'] == 'wpautop' ) { + + $value = wpautop( $value ); + + } elseif ( $field['new_lines'] == 'br' ) { + + $value = nl2br( $value ); + + } + + // return return $value; - } - - - // new lines - if( $field['new_lines'] == 'wpautop' ) { - - $value = wpautop($value); - - } elseif( $field['new_lines'] == 'br' ) { - - $value = nl2br($value); - + + /** + * validate_value + * + * Validates a field's value. + * + * @date 29/1/19 + * @since 5.7.11 + * + * @param (bool|string) Whether the value is vaid or not. + * @param mixed $value The field value. + * @param array $field The field array. + * @param string $input The HTML input name. + * @return (bool|string) + */ + function validate_value( $valid, $value, $field, $input ) { + + // Check maxlength. + if ( $field['maxlength'] && ( acf_strlen( $value ) > $field['maxlength'] ) ) { + return sprintf( __( 'Value must not exceed %d characters', 'acf' ), $field['maxlength'] ); + } + + // Return. + return $valid; } - - - // return - return $value; } - - /** - * validate_value - * - * Validates a field's value. - * - * @date 29/1/19 - * @since 5.7.11 - * - * @param (bool|string) Whether the value is vaid or not. - * @param mixed $value The field value. - * @param array $field The field array. - * @param string $input The HTML input name. - * @return (bool|string) - */ - function validate_value( $valid, $value, $field, $input ){ - - // Check maxlength. - if( $field['maxlength'] && (acf_strlen($value) > $field['maxlength']) ) { - return sprintf( __('Value must not exceed %d characters', 'acf'), $field['maxlength'] ); - } - - // Return. - return $valid; - } -} -// initialize -acf_register_field_type( 'acf_field_textarea' ); + // initialize + acf_register_field_type( 'acf_field_textarea' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-time_picker.php b/includes/fields/class-acf-field-time_picker.php index e2e4341..ef97e8b 100644 --- a/includes/fields/class-acf-field-time_picker.php +++ b/includes/fields/class-acf-field-time_picker.php @@ -1,173 +1,177 @@ name = 'time_picker'; + $this->label = __( 'Time Picker', 'acf' ); + $this->category = 'jquery'; + $this->defaults = array( + 'display_format' => 'g:i a', + 'return_format' => 'g:i a', + ); -class acf_field_time_picker extends acf_field { - - - /* - * __construct - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'time_picker'; - $this->label = __("Time Picker",'acf'); - $this->category = 'jquery'; - $this->defaults = array( - 'display_format' => 'g:i a', - 'return_format' => 'g:i a' - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // Set value. - $display_value = ''; - - if( $field['value'] ) { - $display_value = acf_format_date( $field['value'], $field['display_format'] ); } - - // Elements. - $div = array( - 'class' => 'acf-time-picker acf-input-wrap', - 'data-time_format' => acf_convert_time_to_js($field['display_format']) - ); - $hidden_input = array( - 'id' => $field['id'], - 'class' => 'input-alt', - 'type' => 'hidden', - 'name' => $field['name'], - 'value' => $field['value'], - ); - $text_input = array( - 'class' => 'input', - 'type' => 'text', - 'value' => $display_value, - ); - foreach( array( 'readonly', 'disabled' ) as $k ) { - if( !empty($field[ $k ]) ) { - $hidden_input[ $k ] = $k; - $text_input[ $k ] = $k; + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // Set value. + $display_value = ''; + + if ( $field['value'] ) { + $display_value = acf_format_date( $field['value'], $field['display_format'] ); } - } - - // Output. - ?> + + // Elements. + $div = array( + 'class' => 'acf-time-picker acf-input-wrap', + 'data-time_format' => acf_convert_time_to_js( $field['display_format'] ), + ); + $hidden_input = array( + 'id' => $field['id'], + 'class' => 'input-alt', + 'type' => 'hidden', + 'name' => $field['name'], + 'value' => $field['value'], + ); + $text_input = array( + 'class' => 'input', + 'type' => 'text', + 'value' => $display_value, + ); + foreach ( array( 'readonly', 'disabled' ) as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $hidden_input[ $k ] = $k; + $text_input[ $k ] = $k; + } + } + + // Output. + ?>
                                >
                                - __('Display Format','acf'), - 'instructions' => __('The format displayed when editing a post','acf'), - 'type' => 'radio', - 'name' => 'display_format', - 'other_choice' => 1, - 'choices' => array( - 'g:i a' => '' . $g_i_a . 'g:i a', - 'H:i:s' => '' . $H_i_s . 'H:i:s', - 'other' => '' . __('Custom:','acf') . '' - ) - )); - - - // return_format - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => __('The format returned via template functions','acf'), - 'type' => 'radio', - 'name' => 'return_format', - 'other_choice' => 1, - 'choices' => array( - 'g:i a' => '' . $g_i_a . 'g:i a', - 'H:i:s' => '' . $H_i_s . 'H:i:s', - 'other' => '' . __('Custom:','acf') . '' - ) - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - return acf_format_date( $value, $field['return_format'] ); - - } - -} + __( 'Display Format', 'acf' ), + 'instructions' => __( 'The format displayed when editing a post', 'acf' ), + 'type' => 'radio', + 'name' => 'display_format', + 'other_choice' => 1, + 'choices' => array( + 'g:i a' => '' . $g_i_a . 'g:i a', + 'H:i:s' => '' . $H_i_s . 'H:i:s', + 'other' => '' . __( 'Custom:', 'acf' ) . '', + ), + ) + ); + + // return_format + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => __( 'The format returned via template functions', 'acf' ), + 'type' => 'radio', + 'name' => 'return_format', + 'other_choice' => 1, + 'choices' => array( + 'g:i a' => '' . $g_i_a . 'g:i a', + 'H:i:s' => '' . $H_i_s . 'H:i:s', + 'other' => '' . __( 'Custom:', 'acf' ) . '', + ), + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + return acf_format_date( $value, $field['return_format'] ); + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_time_picker' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-true_false.php b/includes/fields/class-acf-field-true_false.php index 027e978..49addd0 100644 --- a/includes/fields/class-acf-field-true_false.php +++ b/includes/fields/class-acf-field-true_false.php @@ -1,279 +1,296 @@ name = 'true_false'; - $this->label = __('True / False','acf'); - $this->category = 'choice'; - $this->defaults = array( - 'default_value' => 0, - 'message' => '', - 'ui' => 0, - 'ui_on_text' => '', - 'ui_off_text' => '', - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $input = array( - 'type' => 'checkbox', - 'id' => $field['id'], - 'name' => $field['name'], - 'value' => '1', - 'class' => $field['class'], - 'autocomplete' => 'off' - ); - - $hidden = array( - 'name' => $field['name'], - 'value' => 0 - ); - - $active = $field['value'] ? true : false; - $switch = ''; - - - // checked - if( $active ) $input['checked'] = 'checked'; - - - // ui - if( $field['ui'] ) { - // vars - if( $field['ui_on_text'] === '' ) $field['ui_on_text'] = __('Yes', 'acf'); - if( $field['ui_off_text'] === '' ) $field['ui_off_text'] = __('No', 'acf'); - - - // update input - $input['class'] .= ' acf-switch-input'; - //$input['style'] = 'display:none;'; - - $switch .= '
                                '; - $switch .= ''.$field['ui_on_text'].''; - $switch .= ''.$field['ui_off_text'].''; - $switch .= '
                                '; - $switch .= '
                                '; - + $this->name = 'true_false'; + $this->label = __( 'True / False', 'acf' ); + $this->category = 'choice'; + $this->defaults = array( + 'default_value' => 0, + 'message' => '', + 'ui' => 0, + 'ui_on_text' => '', + 'ui_off_text' => '', + ); + } - -?> + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $input = array( + 'type' => 'checkbox', + 'id' => $field['id'], + 'name' => $field['name'], + 'value' => '1', + 'class' => $field['class'], + 'autocomplete' => 'off', + ); + + $hidden = array( + 'name' => $field['name'], + 'value' => 0, + ); + + $active = $field['value'] ? true : false; + $switch = ''; + + // checked + if ( $active ) { + $input['checked'] = 'checked'; + } + + // ui + if ( $field['ui'] ) { + + // vars + if ( $field['ui_on_text'] === '' ) { + $field['ui_on_text'] = __( 'Yes', 'acf' ); + } + if ( $field['ui_off_text'] === '' ) { + $field['ui_off_text'] = __( 'No', 'acf' ); + } + + // update input + $input['class'] .= ' acf-switch-input'; + // $input['style'] = 'display:none;'; + + $switch .= '
                                '; + $switch .= '' . $field['ui_on_text'] . ''; + $switch .= '' . $field['ui_off_text'] . ''; + $switch .= '
                                '; + $switch .= '
                                '; + + } + + ?>
                                - +
                                - __('Message','acf'), - 'instructions' => __('Displays text alongside the checkbox','acf'), - 'type' => 'text', - 'name' => 'message', - )); - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => '', - 'type' => 'true_false', - 'name' => 'default_value', - )); - - - // ui - acf_render_field_setting( $field, array( - 'label' => __('Stylised UI','acf'), - 'instructions' => '', - 'type' => 'true_false', - 'name' => 'ui', - 'ui' => 1, - 'class' => 'acf-field-object-true-false-ui' - )); - - - // on_text - acf_render_field_setting( $field, array( - 'label' => __('On Text','acf'), - 'instructions' => __('Text shown when active','acf'), - 'type' => 'text', - 'name' => 'ui_on_text', - 'placeholder' => __('Yes', 'acf'), - 'conditions' => array( - 'field' => 'ui', - 'operator' => '==', - 'value' => 1 - ) - )); - - - // on_text - acf_render_field_setting( $field, array( - 'label' => __('Off Text','acf'), - 'instructions' => __('Text shown when inactive','acf'), - 'type' => 'text', - 'name' => 'ui_off_text', - 'placeholder' => __('No', 'acf'), - 'conditions' => array( - 'field' => 'ui', - 'operator' => '==', - 'value' => 1 - ) - )); - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - return empty($value) ? false : true; - - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // bail early if not required - if( ! $field['required'] ) { - + __( 'Message', 'acf' ), + 'instructions' => __( 'Displays text alongside the checkbox', 'acf' ), + 'type' => 'text', + 'name' => 'message', + ) + ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => '', + 'type' => 'true_false', + 'name' => 'default_value', + ) + ); + + // ui + acf_render_field_setting( + $field, + array( + 'label' => __( 'Stylised UI', 'acf' ), + 'instructions' => '', + 'type' => 'true_false', + 'name' => 'ui', + 'ui' => 1, + 'class' => 'acf-field-object-true-false-ui', + ) + ); + + // on_text + acf_render_field_setting( + $field, + array( + 'label' => __( 'On Text', 'acf' ), + 'instructions' => __( 'Text shown when active', 'acf' ), + 'type' => 'text', + 'name' => 'ui_on_text', + 'placeholder' => __( 'Yes', 'acf' ), + 'conditions' => array( + 'field' => 'ui', + 'operator' => '==', + 'value' => 1, + ), + ) + ); + + // on_text + acf_render_field_setting( + $field, + array( + 'label' => __( 'Off Text', 'acf' ), + 'instructions' => __( 'Text shown when inactive', 'acf' ), + 'type' => 'text', + 'name' => 'ui_off_text', + 'placeholder' => __( 'No', 'acf' ), + 'conditions' => array( + 'field' => 'ui', + 'operator' => '==', + 'value' => 1, + ), + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + return empty( $value ) ? false : true; + + } + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // bail early if not required + if ( ! $field['required'] ) { + + return $valid; + + } + + // value may be '0' + if ( ! $value ) { + + return false; + + } + + // return return $valid; - + } - - - // value may be '0' - if( !$value ) { - - return false; - - } - - - // return - return $valid; - - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @type function - * @date 8/03/2016 - * @since 5.3.2 - * - * @param $field (array) - * @return $field - */ - - function translate_field( $field ) { - - // translate - $field['message'] = acf_translate( $field['message'] ); - $field['ui_on_text'] = acf_translate( $field['ui_on_text'] ); - $field['ui_off_text'] = acf_translate( $field['ui_off_text'] ); - - - // return - return $field; - - } - -} -// initialize -acf_register_field_type( 'acf_field_true_false' ); + /* + * translate_field + * + * This function will translate field settings + * + * @type function + * @date 8/03/2016 + * @since 5.3.2 + * + * @param $field (array) + * @return $field + */ + + function translate_field( $field ) { + + // translate + $field['message'] = acf_translate( $field['message'] ); + $field['ui_on_text'] = acf_translate( $field['ui_on_text'] ); + $field['ui_off_text'] = acf_translate( $field['ui_off_text'] ); + + // return + return $field; + + } + + } + + + // initialize + acf_register_field_type( 'acf_field_true_false' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field-url.php b/includes/fields/class-acf-field-url.php index aac378e..e6b49fe 100644 --- a/includes/fields/class-acf-field-url.php +++ b/includes/fields/class-acf-field-url.php @@ -1,169 +1,171 @@ name = 'url'; + $this->label = __( 'Url', 'acf' ); + $this->defaults = array( + 'default_value' => '', + 'placeholder' => '', + ); -class acf_field_url extends acf_field { - - - /* - * initialize - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'url'; - $this->label = __("Url",'acf'); - $this->defaults = array( - 'default_value' => '', - 'placeholder' => '', - ); - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // vars - $atts = array(); - $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' ); - $keys2 = array( 'readonly', 'disabled', 'required' ); - $html = ''; - - - // atts (value="123") - foreach( $keys as $k ) { - if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ]; } - - - // atts2 (disabled="disabled") - foreach( $keys2 as $k ) { - if( !empty($field[ $k ]) ) $atts[ $k ] = $k; + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // vars + $atts = array(); + $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' ); + $keys2 = array( 'readonly', 'disabled', 'required' ); + $html = ''; + + // atts (value="123") + foreach ( $keys as $k ) { + if ( isset( $field[ $k ] ) ) { + $atts[ $k ] = $field[ $k ]; + } + } + + // atts2 (disabled="disabled") + foreach ( $keys2 as $k ) { + if ( ! empty( $field[ $k ] ) ) { + $atts[ $k ] = $k; + } + } + + // remove empty atts + $atts = acf_clean_atts( $atts ); + + // render + $html .= '
                                '; + $html .= '' . acf_get_text_input( $atts ); + $html .= '
                                '; + + // return + echo $html; + } - - - // remove empty atts - $atts = acf_clean_atts( $atts ); - - - // render - $html .= '
                                '; - $html .= '' . acf_get_text_input( $atts ) ; - $html .= '
                                '; - - - // return - echo $html; - - } - - - /* - * render_field_settings() - * - * Create extra options for your field. This is rendered when editing a field. - * The value of $field['name'] can be used (like bellow) to save extra data to the $field - * - * @type action - * @since 3.6 - * @date 23/01/13 - * - * @param $field - an array holding all the field's data - */ - - function render_field_settings( $field ) { - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'text', - 'name' => 'default_value', - )); - - - // placeholder - acf_render_field_setting( $field, array( - 'label' => __('Placeholder Text','acf'), - 'instructions' => __('Appears within the input','acf'), - 'type' => 'text', - 'name' => 'placeholder', - )); - - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // bail early if empty - if( empty($value) ) { - + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'text', + 'name' => 'default_value', + ) + ); + + // placeholder + acf_render_field_setting( + $field, + array( + 'label' => __( 'Placeholder Text', 'acf' ), + 'instructions' => __( 'Appears within the input', 'acf' ), + 'type' => 'text', + 'name' => 'placeholder', + ) + ); + + } + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // bail early if empty + if ( empty( $value ) ) { + + return $valid; + + } + + if ( strpos( $value, '://' ) !== false ) { + + // url + + } elseif ( strpos( $value, '//' ) === 0 ) { + + // protocol relative url + + } else { + + $valid = __( 'Value must be a valid URL', 'acf' ); + + } + + // return return $valid; - + } - - - if( strpos($value, '://') !== false ) { - - // url - - } elseif( strpos($value, '//') === 0 ) { - - // protocol relative url - - } else { - - $valid = __('Value must be a valid URL', 'acf'); - - } - - - // return - return $valid; - + } - -} -// initialize -acf_register_field_type( 'acf_field_url' ); + // initialize + acf_register_field_type( 'acf_field_url' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/fields/class-acf-field-user.php b/includes/fields/class-acf-field-user.php index 775ee5a..0a0f5fd 100644 --- a/includes/fields/class-acf-field-user.php +++ b/includes/fields/class-acf-field-user.php @@ -1,461 +1,477 @@ name = 'user'; - $this->label = __("User",'acf'); - $this->category = 'relational'; - $this->defaults = array( - 'role' => '', - 'multiple' => 0, - 'allow_null' => 0, - 'return_format' => 'array', - ); - - // Register filter variations. - acf_add_filter_variations( 'acf/fields/user/query', array('name', 'key'), 1 ); - acf_add_filter_variations( 'acf/fields/user/result', array('name', 'key'), 2 ); - acf_add_filter_variations( 'acf/fields/user/search_columns', array('name', 'key'), 3 ); - - // Add AJAX query. - add_action( 'wp_ajax_acf/fields/user/query', array( $this, 'ajax_query' ) ); - add_action( 'wp_ajax_nopriv_acf/fields/user/query', array( $this, 'ajax_query' ) ); - } - - /** - * Renders the field settings HTML. - * - * @date 23/01/13 - * @since 3.6.0 - * - * @param array $field The ACF field. - * @return void - */ - function render_field_settings( $field ) { - - acf_render_field_setting( $field, array( - 'label' => __('Filter by role','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'role', - 'choices' => acf_get_user_role_labels(), - 'multiple' => 1, - 'ui' => 1, - 'allow_null' => 1, - 'placeholder' => __("All user roles",'acf'), - )); - - acf_render_field_setting( $field, array( - 'label' => __('Allow Null?','acf'), - 'instructions' => '', - 'name' => 'allow_null', - 'type' => 'true_false', - 'ui' => 1, - )); - - acf_render_field_setting( $field, array( - 'label' => __('Select multiple values?','acf'), - 'instructions' => '', - 'name' => 'multiple', - 'type' => 'true_false', - 'ui' => 1, - )); - - acf_render_field_setting( $field, array( - 'label' => __('Return Format','acf'), - 'instructions' => '', - 'type' => 'radio', - 'name' => 'return_format', - 'choices' => array( - 'array' => __("User Array",'acf'), - 'object' => __("User Object",'acf'), - 'id' => __("User ID",'acf'), - ), - 'layout' => 'horizontal', - )); - } - - /** - * Renders the field input HTML. - * - * @date 23/01/13 - * @since 3.6.0 - * - * @param array $field The ACF field. - * @return void - */ - function render_field( $field ) { - - // Change Field into a select. - $field['type'] = 'select'; - $field['ui'] = 1; - $field['ajax'] = 1; - $field['choices'] = array(); - - // Populate choices. - if( $field['value'] ) { - - // Clean value into an array of IDs. - $user_ids = array_map('intval', acf_array($field['value'])); - - // Find users in database (ensures all results are real). - $users = acf_get_users(array( - 'include' => $user_ids - )); - - // Append. - if( $users ) { - foreach( $users as $user ) { - $field['choices'][ $user->ID ] = $this->get_result( $user, $field ); - } - } - } - - // Render. - acf_render_field( $field ); - } - - /** - * Returns the result text for a fiven WP_User object. - * - * @date 1/11/2013 - * @since 5.0.0 - * - * @param WP_User $user The WP_User object. - * @param array $field The ACF field related to this query. - * @param (int|string) $post_id The post_id being edited. - * @return string - */ - function get_result( $user, $field, $post_id = 0 ) { - - // Get user result item. - $item = acf_get_user_result( $user ); - - // Default $post_id to current post being edited. - $post_id = $post_id ? $post_id : acf_get_form_data('post_id'); - /** - * Filters the result text. + * Initializes the field type. * - * @date 21/5/19 - * @since 5.8.1 + * @date 5/03/2014 + * @since 5.0.0 * - * @param array $args The query args. - * @param array $field The ACF field related to this query. - * @param (int|string) $post_id The post_id being edited. + * @param void + * @return void */ - return apply_filters( "acf/fields/user/result", $item['text'], $user, $field, $post_id ); - } - - /** - * Filters the field value after it is loaded from the database. - * - * @date 23/01/13 - * @since 3.6.0 - * - * @param mixed $value The field value. - * @param mixed $post_id The post ID where the value is saved. - * @param array $field The field array containing all settings. - * @return mixed - */ - function load_value( $value, $post_id, $field ) { - - // Add compatibility for version 4. - if( $value === 'null' ) { - return false; + function initialize() { + + // Props. + $this->name = 'user'; + $this->label = __( 'User', 'acf' ); + $this->category = 'relational'; + $this->defaults = array( + 'role' => '', + 'multiple' => 0, + 'allow_null' => 0, + 'return_format' => 'array', + ); + + // Register filter variations. + acf_add_filter_variations( 'acf/fields/user/query', array( 'name', 'key' ), 1 ); + acf_add_filter_variations( 'acf/fields/user/result', array( 'name', 'key' ), 2 ); + acf_add_filter_variations( 'acf/fields/user/search_columns', array( 'name', 'key' ), 3 ); + + // Add AJAX query. + add_action( 'wp_ajax_acf/fields/user/query', array( $this, 'ajax_query' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/user/query', array( $this, 'ajax_query' ) ); } - return $value; - } - - /** - * Filters the field value after it is loaded from the database but before it is returned to the front-end API. - * - * @date 23/01/13 - * @since 3.6.0 - * - * @param mixed $value The field value. - * @param mixed $post_id The post ID where the value is saved. - * @param array $field The field array containing all settings. - * @return mixed - */ - function format_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( !$value ) { - return false; + + /** + * Renders the field settings HTML. + * + * @date 23/01/13 + * @since 3.6.0 + * + * @param array $field The ACF field. + * @return void + */ + function render_field_settings( $field ) { + + acf_render_field_setting( + $field, + array( + 'label' => __( 'Filter by role', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'role', + 'choices' => acf_get_user_role_labels(), + 'multiple' => 1, + 'ui' => 1, + 'allow_null' => 1, + 'placeholder' => __( 'All user roles', 'acf' ), + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => __( 'Allow Null?', 'acf' ), + 'instructions' => '', + 'name' => 'allow_null', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => __( 'Select multiple values?', 'acf' ), + 'instructions' => '', + 'name' => 'multiple', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + acf_render_field_setting( + $field, + array( + 'label' => __( 'Return Format', 'acf' ), + 'instructions' => '', + 'type' => 'radio', + 'name' => 'return_format', + 'choices' => array( + 'array' => __( 'User Array', 'acf' ), + 'object' => __( 'User Object', 'acf' ), + 'id' => __( 'User ID', 'acf' ), + ), + 'layout' => 'horizontal', + ) + ); } - - // Clean value into an array of IDs. - $user_ids = array_map('intval', acf_array($value)); - - // Find users in database (ensures all results are real). - $users = acf_get_users(array( - 'include' => $user_ids - )); - - // Bail early if no users found. - if( !$users ) { - return false; - } - - // Format values using field settings. - $value = array(); - foreach( $users as $user ) { - - // Return object. - if( $field['return_format'] == 'object' ) { - $item = $user; - - // Return array. - } elseif( $field['return_format'] == 'array' ) { - $item = array( - 'ID' => $user->ID, - 'user_firstname' => $user->user_firstname, - 'user_lastname' => $user->user_lastname, - 'nickname' => $user->nickname, - 'user_nicename' => $user->user_nicename, - 'display_name' => $user->display_name, - 'user_email' => $user->user_email, - 'user_url' => $user->user_url, - 'user_registered' => $user->user_registered, - 'user_description' => $user->user_description, - 'user_avatar' => get_avatar( $user->ID ), + + /** + * Renders the field input HTML. + * + * @date 23/01/13 + * @since 3.6.0 + * + * @param array $field The ACF field. + * @return void + */ + function render_field( $field ) { + + // Change Field into a select. + $field['type'] = 'select'; + $field['ui'] = 1; + $field['ajax'] = 1; + $field['choices'] = array(); + + // Populate choices. + if ( $field['value'] ) { + + // Clean value into an array of IDs. + $user_ids = array_map( 'intval', acf_array( $field['value'] ) ); + + // Find users in database (ensures all results are real). + $users = acf_get_users( + array( + 'include' => $user_ids, + ) ); - - // Return ID. - } else { - $item = $user->ID; + + // Append. + if ( $users ) { + foreach ( $users as $user ) { + $field['choices'][ $user->ID ] = $this->get_result( $user, $field ); + } + } } - - // Append item - $value[] = $item; + + // Render. + acf_render_field( $field ); } - - // Convert to single. - if( !$field['multiple'] ) { - $value = array_shift( $value ); + + /** + * Returns the result text for a fiven WP_User object. + * + * @date 1/11/2013 + * @since 5.0.0 + * + * @param WP_User $user The WP_User object. + * @param array $field The ACF field related to this query. + * @param (int|string) $post_id The post_id being edited. + * @return string + */ + function get_result( $user, $field, $post_id = 0 ) { + + // Get user result item. + $item = acf_get_user_result( $user ); + + // Default $post_id to current post being edited. + $post_id = $post_id ? $post_id : acf_get_form_data( 'post_id' ); + + /** + * Filters the result text. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $args The query args. + * @param array $field The ACF field related to this query. + * @param (int|string) $post_id The post_id being edited. + */ + return apply_filters( 'acf/fields/user/result', $item['text'], $user, $field, $post_id ); } - - // Return. - return $value; - } - - /** - * Filters the field value before it is saved into the database. - * - * @date 23/01/13 - * @since 3.6.0 - * - * @param mixed $value The field value. - * @param mixed $post_id The post ID where the value is saved. - * @param array $field The field array containing all settings. - * @return mixed - */ - function update_value( $value, $post_id, $field ) { - - // Bail early if no value. - if( empty($value) ) { + + /** + * Filters the field value after it is loaded from the database. + * + * @date 23/01/13 + * @since 3.6.0 + * + * @param mixed $value The field value. + * @param mixed $post_id The post ID where the value is saved. + * @param array $field The field array containing all settings. + * @return mixed + */ + function load_value( $value, $post_id, $field ) { + + // Add compatibility for version 4. + if ( $value === 'null' ) { + return false; + } return $value; } - - // Format array of values. - // - ensure each value is an id. - // - Parse each id as string for SQL LIKE queries. - if( acf_is_sequential_array($value) ) { - $value = array_map('acf_idval', $value); - $value = array_map('strval', $value); - - // Parse single value for id. - } else { - $value = acf_idval( $value ); + + /** + * Filters the field value after it is loaded from the database but before it is returned to the front-end API. + * + * @date 23/01/13 + * @since 3.6.0 + * + * @param mixed $value The field value. + * @param mixed $post_id The post ID where the value is saved. + * @param array $field The field array containing all settings. + * @return mixed + */ + function format_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( ! $value ) { + return false; + } + + // Clean value into an array of IDs. + $user_ids = array_map( 'intval', acf_array( $value ) ); + + // Find users in database (ensures all results are real). + $users = acf_get_users( + array( + 'include' => $user_ids, + ) + ); + + // Bail early if no users found. + if ( ! $users ) { + return false; + } + + // Format values using field settings. + $value = array(); + foreach ( $users as $user ) { + + // Return object. + if ( $field['return_format'] == 'object' ) { + $item = $user; + + // Return array. + } elseif ( $field['return_format'] == 'array' ) { + $item = array( + 'ID' => $user->ID, + 'user_firstname' => $user->user_firstname, + 'user_lastname' => $user->user_lastname, + 'nickname' => $user->nickname, + 'user_nicename' => $user->user_nicename, + 'display_name' => $user->display_name, + 'user_email' => $user->user_email, + 'user_url' => $user->user_url, + 'user_registered' => $user->user_registered, + 'user_description' => $user->user_description, + 'user_avatar' => get_avatar( $user->ID ), + ); + + // Return ID. + } else { + $item = $user->ID; + } + + // Append item + $value[] = $item; + } + + // Convert to single. + if ( ! $field['multiple'] ) { + $value = array_shift( $value ); + } + + // Return. + return $value; + } + + /** + * Filters the field value before it is saved into the database. + * + * @date 23/01/13 + * @since 3.6.0 + * + * @param mixed $value The field value. + * @param mixed $post_id The post ID where the value is saved. + * @param array $field The field array containing all settings. + * @return mixed + */ + function update_value( $value, $post_id, $field ) { + + // Bail early if no value. + if ( empty( $value ) ) { + return $value; + } + + // Format array of values. + // - ensure each value is an id. + // - Parse each id as string for SQL LIKE queries. + if ( acf_is_sequential_array( $value ) ) { + $value = array_map( 'acf_idval', $value ); + $value = array_map( 'strval', $value ); + + // Parse single value for id. + } else { + $value = acf_idval( $value ); + } + + // Return value. + return $value; + } + + /** + * Callback for the AJAX query request. + * + * @date 24/10/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + function ajax_query() { + + // Modify Request args. + if ( isset( $_REQUEST['s'] ) ) { + $_REQUEST['search'] = $_REQUEST['s']; + } + if ( isset( $_REQUEST['paged'] ) ) { + $_REQUEST['page'] = $_REQUEST['paged']; + } + + // Add query hooks. + add_action( 'acf/ajax/query_users/init', array( $this, 'ajax_query_init' ), 10, 2 ); + add_filter( 'acf/ajax/query_users/args', array( $this, 'ajax_query_args' ), 10, 3 ); + add_filter( 'acf/ajax/query_users/result', array( $this, 'ajax_query_result' ), 10, 3 ); + add_filter( 'acf/ajax/query_users/search_columns', array( $this, 'ajax_query_search_columns' ), 10, 4 ); + + // Simulate AJAX request. + acf_get_instance( 'ACF_Ajax_Query_Users' )->request(); + } + + /** + * Runs during the AJAX query initialization. + * + * @date 9/3/20 + * @since 5.8.8 + * + * @param array $request The query request. + * @param ACF_Ajax_Query $query The query object. + * @return void + */ + function ajax_query_init( $request, $query ) { + + // Require field. + if ( ! $query->field ) { + $query->send( new WP_Error( 'acf_missing_field', __( 'Error loading field.', 'acf' ), array( 'status' => 404 ) ) ); + } + } + + /** + * Filters the AJAX query args. + * + * @date 9/3/20 + * @since 5.8.8 + * + * @param array $args The query args. + * @param array $request The query request. + * @param ACF_Ajax_Query $query The query object. + * @return array + */ + function ajax_query_args( $args, $request, $query ) { + + // Add specific roles. + if ( $query->field['role'] ) { + $args['role__in'] = acf_array( $query->field['role'] ); + } + + /** + * Filters the query args. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $args The query args. + * @param array $field The ACF field related to this query. + * @param (int|string) $post_id The post_id being edited. + */ + return apply_filters( 'acf/fields/user/query', $args, $query->field, $query->post_id ); + } + + /** + * Filters the WP_User_Query search columns. + * + * @date 9/3/20 + * @since 5.8.8 + * + * @param array $columns An array of column names to be searched. + * @param string $search The search term. + * @param WP_User_Query $WP_User_Query The WP_User_Query instance. + * @return array + */ + function ajax_query_search_columns( $columns, $search, $WP_User_Query, $query ) { + + /** + * Filters the column names to be searched. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param array $columns An array of column names to be searched. + * @param string $search The search term. + * @param WP_User_Query $WP_User_Query The WP_User_Query instance. + * @param array $field The ACF field related to this query. + */ + return apply_filters( 'acf/fields/user/search_columns', $columns, $search, $WP_User_Query, $query->field ); + } + + /** + * Filters the AJAX Query result. + * + * @date 9/3/20 + * @since 5.8.8 + * + * @param array $item The choice id and text. + * @param WP_User $user The user object. + * @param ACF_Ajax_Query $query The query object. + * @return array + */ + function ajax_query_result( $item, $user, $query ) { + + /** + * Filters the result text. + * + * @date 21/5/19 + * @since 5.8.1 + * + * @param string The result text. + * @param WP_User $user The user object. + * @param array $field The ACF field related to this query. + * @param (int|string) $post_id The post_id being edited. + */ + $item['text'] = apply_filters( 'acf/fields/user/result', $item['text'], $user, $query->field, $query->post_id ); + return $item; + } + + /** + * Return an array of data formatted for use in a select2 AJAX response. + * + * @date 15/10/2014 + * @since 5.0.9 + * @deprecated 5.8.9 + * + * @param array $args An array of query args. + * @return array + */ + function get_ajax_query( $options = array() ) { + _deprecated_function( __FUNCTION__, '5.8.9' ); + return array(); + } + + /** + * Filters the WP_User_Query search columns. + * + * @date 15/10/2014 + * @since 5.0.9 + * @deprecated 5.8.9 + * + * @param array $columns An array of column names to be searched. + * @param string $search The search term. + * @param WP_User_Query $WP_User_Query The WP_User_Query instance. + * @return array + */ + function user_search_columns( $columns, $search, $WP_User_Query ) { + _deprecated_function( __FUNCTION__, '5.8.9' ); + return $columns; } - - // Return value. - return $value; } - /** - * Callback for the AJAX query request. - * - * @date 24/10/13 - * @since 5.0.0 - * - * @param void - * @return void - */ - function ajax_query() { - - // Modify Request args. - if( isset($_REQUEST['s']) ) { - $_REQUEST['search'] = $_REQUEST['s']; - } - if( isset($_REQUEST['paged']) ) { - $_REQUEST['page'] = $_REQUEST['paged']; - } - - // Add query hooks. - add_action( 'acf/ajax/query_users/init', array( $this, 'ajax_query_init' ), 10, 2 ); - add_filter( 'acf/ajax/query_users/args', array( $this, 'ajax_query_args' ), 10, 3 ); - add_filter( 'acf/ajax/query_users/result', array( $this, 'ajax_query_result' ), 10, 3 ); - add_filter( 'acf/ajax/query_users/search_columns', array( $this, 'ajax_query_search_columns' ), 10, 4 ); - - // Simulate AJAX request. - acf_get_instance('ACF_Ajax_Query_Users')->request(); - } - - /** - * Runs during the AJAX query initialization. - * - * @date 9/3/20 - * @since 5.8.8 - * - * @param array $request The query request. - * @param ACF_Ajax_Query $query The query object. - * @return void - */ - function ajax_query_init( $request, $query ) { - - // Require field. - if( !$query->field ) { - $query->send( new WP_Error( 'acf_missing_field', __( 'Error loading field.', 'acf' ), array( 'status' => 404 ) ) ); - } - } - - /** - * Filters the AJAX query args. - * - * @date 9/3/20 - * @since 5.8.8 - * - * @param array $args The query args. - * @param array $request The query request. - * @param ACF_Ajax_Query $query The query object. - * @return array - */ - function ajax_query_args( $args, $request, $query ) { - - // Add specific roles. - if( $query->field['role'] ) { - $args['role__in'] = acf_array( $query->field['role'] ); - } - - /** - * Filters the query args. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param array $args The query args. - * @param array $field The ACF field related to this query. - * @param (int|string) $post_id The post_id being edited. - */ - return apply_filters( "acf/fields/user/query", $args, $query->field, $query->post_id ); - } - - /** - * Filters the WP_User_Query search columns. - * - * @date 9/3/20 - * @since 5.8.8 - * - * @param array $columns An array of column names to be searched. - * @param string $search The search term. - * @param WP_User_Query $WP_User_Query The WP_User_Query instance. - * @return array - */ - function ajax_query_search_columns( $columns, $search, $WP_User_Query, $query ) { - - /** - * Filters the column names to be searched. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param array $columns An array of column names to be searched. - * @param string $search The search term. - * @param WP_User_Query $WP_User_Query The WP_User_Query instance. - * @param array $field The ACF field related to this query. - */ - return apply_filters( "acf/fields/user/search_columns", $columns, $search, $WP_User_Query, $query->field ); - } - - /** - * Filters the AJAX Query result. - * - * @date 9/3/20 - * @since 5.8.8 - * - * @param array $item The choice id and text. - * @param WP_User $user The user object. - * @param ACF_Ajax_Query $query The query object. - * @return array - */ - function ajax_query_result( $item, $user, $query ) { - - /** - * Filters the result text. - * - * @date 21/5/19 - * @since 5.8.1 - * - * @param string The result text. - * @param WP_User $user The user object. - * @param array $field The ACF field related to this query. - * @param (int|string) $post_id The post_id being edited. - */ - $item['text'] = apply_filters( "acf/fields/user/result", $item['text'], $user, $query->field, $query->post_id ); - return $item; - } - - /** - * Return an array of data formatted for use in a select2 AJAX response. - * - * @date 15/10/2014 - * @since 5.0.9 - * @deprecated 5.8.9 - * - * @param array $args An array of query args. - * @return array - */ - function get_ajax_query( $options = array() ) { - _deprecated_function( __FUNCTION__, '5.8.9' ); - return array(); - } - - /** - * Filters the WP_User_Query search columns. - * - * @date 15/10/2014 - * @since 5.0.9 - * @deprecated 5.8.9 - * - * @param array $columns An array of column names to be searched. - * @param string $search The search term. - * @param WP_User_Query $WP_User_Query The WP_User_Query instance. - * @return array - */ - function user_search_columns( $columns, $search, $WP_User_Query ) { - _deprecated_function( __FUNCTION__, '5.8.9' ); - return $columns; - } -} - -// initialize -acf_register_field_type( 'ACF_Field_User' ); + // initialize + acf_register_field_type( 'ACF_Field_User' ); endif; // class_exists check diff --git a/includes/fields/class-acf-field-wysiwyg.php b/includes/fields/class-acf-field-wysiwyg.php index f97a7ca..367e295 100644 --- a/includes/fields/class-acf-field-wysiwyg.php +++ b/includes/fields/class-acf-field-wysiwyg.php @@ -1,454 +1,449 @@ name = 'wysiwyg'; - $this->label = __("Wysiwyg Editor",'acf'); - $this->category = 'content'; - $this->defaults = array( - 'tabs' => 'all', - 'toolbar' => 'full', - 'media_upload' => 1, - 'default_value' => '', - 'delay' => 0 - ); - - - // add acf_the_content filters - $this->add_filters(); - - // actions - add_action('acf/enqueue_uploader', array($this, 'acf_enqueue_uploader')); - } - - - /* - * add_filters - * - * This function will add filters to 'acf_the_content' - * - * @type function - * @date 20/09/2016 - * @since 5.4.0 - * - * @param n/a - * @return n/a - */ - - function add_filters() { - - // WordPress 5.5 introduced new function for applying image tags. - $wp_filter_content_tags = function_exists('wp_filter_content_tags') ? 'wp_filter_content_tags' : 'wp_make_content_images_responsive'; + class acf_field_wysiwyg extends acf_field { - // Mimic filters added to "the_content" in "wp-includes/default-filters.php". - add_filter( 'acf_the_content', 'capital_P_dangit', 11 ); - //add_filter( 'acf_the_content', 'do_blocks', 9 ); Not yet supported. - add_filter( 'acf_the_content', 'wptexturize' ); - add_filter( 'acf_the_content', 'convert_smilies', 20 ); - add_filter( 'acf_the_content', 'wpautop' ); - add_filter( 'acf_the_content', 'shortcode_unautop' ); - //add_filter( 'acf_the_content', 'prepend_attachment' ); Causes double image on attachment page. - add_filter( 'acf_the_content', $wp_filter_content_tags ); - add_filter( 'acf_the_content', 'do_shortcode', 11); - // Mimic filters added to "the_content" in "wp-includes/class-wp-embed.php" - if( isset($GLOBALS['wp_embed']) ) { - add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 ); - add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 ); - } - } - - - /* - * get_toolbars - * - * This function will return an array of toolbars for the WYSIWYG field - * - * @type function - * @date 18/04/2014 - * @since 5.0.0 - * - * @param n/a - * @return (array) - */ - - function get_toolbars() { - - // vars - $editor_id = 'acf_content'; - $toolbars = array(); - - - // mce buttons (Full) - $mce_buttons = array( 'formatselect', 'bold', 'italic', 'bullist', 'numlist', 'blockquote', 'alignleft', 'aligncenter', 'alignright', 'link', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ); - $mce_buttons_2 = array( 'strikethrough', 'hr', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ); - - // mce buttons (Basic) - $teeny_mce_buttons = array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'fullscreen'); - - - // WP < 4.7 - if( acf_version_compare('wp', '<', '4.7') ) { - - $mce_buttons = array( 'bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ); - $mce_buttons_2 = array( 'formatselect', 'underline', 'alignjustify', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ); - } - - - // Full - $toolbars['Full'] = array( - 1 => apply_filters('mce_buttons', $mce_buttons, $editor_id), - 2 => apply_filters('mce_buttons_2', $mce_buttons_2, $editor_id), - 3 => apply_filters('mce_buttons_3', array(), $editor_id), - 4 => apply_filters('mce_buttons_4', array(), $editor_id) - ); - - - // Basic - $toolbars['Basic'] = array( - 1 => apply_filters('teeny_mce_buttons', $teeny_mce_buttons, $editor_id) - ); - - - // Filter for 3rd party - $toolbars = apply_filters( 'acf/fields/wysiwyg/toolbars', $toolbars ); - - - // return - return $toolbars; - - } - - - /* - * acf_enqueue_uploader - * - * Registers toolbars data for the WYSIWYG field. - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param void - * @return void - */ - - function acf_enqueue_uploader() { - - // vars - $data = array(); - $toolbars = $this->get_toolbars(); - - // loop - if( $toolbars ) { - foreach( $toolbars as $label => $rows ) { - + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + // vars - $key = $label; - $key = sanitize_title( $key ); - $key = str_replace('-', '_', $key); - - - // append - $data[ $key ] = array(); - - if( $rows ) { - foreach( $rows as $i => $row ) { - $data[ $key ][ $i ] = implode(',', $row); + $this->name = 'wysiwyg'; + $this->label = __( 'Wysiwyg Editor', 'acf' ); + $this->category = 'content'; + $this->defaults = array( + 'tabs' => 'all', + 'toolbar' => 'full', + 'media_upload' => 1, + 'default_value' => '', + 'delay' => 0, + ); + + // add acf_the_content filters + $this->add_filters(); + + // actions + add_action( 'acf/enqueue_uploader', array( $this, 'acf_enqueue_uploader' ) ); + } + + + /* + * add_filters + * + * This function will add filters to 'acf_the_content' + * + * @type function + * @date 20/09/2016 + * @since 5.4.0 + * + * @param n/a + * @return n/a + */ + + function add_filters() { + + // WordPress 5.5 introduced new function for applying image tags. + $wp_filter_content_tags = function_exists( 'wp_filter_content_tags' ) ? 'wp_filter_content_tags' : 'wp_make_content_images_responsive'; + + // Mimic filters added to "the_content" in "wp-includes/default-filters.php". + add_filter( 'acf_the_content', 'capital_P_dangit', 11 ); + // add_filter( 'acf_the_content', 'do_blocks', 9 ); Not yet supported. + add_filter( 'acf_the_content', 'wptexturize' ); + add_filter( 'acf_the_content', 'convert_smilies', 20 ); + add_filter( 'acf_the_content', 'wpautop' ); + add_filter( 'acf_the_content', 'shortcode_unautop' ); + // add_filter( 'acf_the_content', 'prepend_attachment' ); Causes double image on attachment page. + add_filter( 'acf_the_content', $wp_filter_content_tags ); + add_filter( 'acf_the_content', 'do_shortcode', 11 ); + + // Mimic filters added to "the_content" in "wp-includes/class-wp-embed.php" + if ( isset( $GLOBALS['wp_embed'] ) ) { + add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 ); + add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 ); + } + } + + + /* + * get_toolbars + * + * This function will return an array of toolbars for the WYSIWYG field + * + * @type function + * @date 18/04/2014 + * @since 5.0.0 + * + * @param n/a + * @return (array) + */ + + function get_toolbars() { + + // vars + $editor_id = 'acf_content'; + $toolbars = array(); + + // mce buttons (Full) + $mce_buttons = array( 'formatselect', 'bold', 'italic', 'bullist', 'numlist', 'blockquote', 'alignleft', 'aligncenter', 'alignright', 'link', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ); + $mce_buttons_2 = array( 'strikethrough', 'hr', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ); + + // mce buttons (Basic) + $teeny_mce_buttons = array( 'bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'fullscreen' ); + + // WP < 4.7 + if ( acf_version_compare( 'wp', '<', '4.7' ) ) { + + $mce_buttons = array( 'bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'fullscreen', 'wp_adv' ); + $mce_buttons_2 = array( 'formatselect', 'underline', 'alignjustify', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help' ); + } + + // Full + $toolbars['Full'] = array( + 1 => apply_filters( 'mce_buttons', $mce_buttons, $editor_id ), + 2 => apply_filters( 'mce_buttons_2', $mce_buttons_2, $editor_id ), + 3 => apply_filters( 'mce_buttons_3', array(), $editor_id ), + 4 => apply_filters( 'mce_buttons_4', array(), $editor_id ), + ); + + // Basic + $toolbars['Basic'] = array( + 1 => apply_filters( 'teeny_mce_buttons', $teeny_mce_buttons, $editor_id ), + ); + + // Filter for 3rd party + $toolbars = apply_filters( 'acf/fields/wysiwyg/toolbars', $toolbars ); + + // return + return $toolbars; + + } + + + /* + * acf_enqueue_uploader + * + * Registers toolbars data for the WYSIWYG field. + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param void + * @return void + */ + + function acf_enqueue_uploader() { + + // vars + $data = array(); + $toolbars = $this->get_toolbars(); + + // loop + if ( $toolbars ) { + foreach ( $toolbars as $label => $rows ) { + + // vars + $key = $label; + $key = sanitize_title( $key ); + $key = str_replace( '-', '_', $key ); + + // append + $data[ $key ] = array(); + + if ( $rows ) { + foreach ( $rows as $i => $row ) { + $data[ $key ][ $i ] = implode( ',', $row ); + } + } } } - }} - - // localize - acf_localize_data(array( - 'toolbars' => $data - )); - } - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // enqueue - acf_enqueue_uploader(); - - - // vars - $id = uniqid('acf-editor-'); - $default_editor = 'html'; - $show_tabs = true; - - - // get height - $height = acf_get_user_setting('wysiwyg_height', 300); - $height = max( $height, 300 ); // minimum height is 300 - - - // detect mode - if( !user_can_richedit() ) { - - $show_tabs = false; - - } elseif( $field['tabs'] == 'visual' ) { - - // case: visual tab only - $default_editor = 'tinymce'; - $show_tabs = false; - - } elseif( $field['tabs'] == 'text' ) { - - // case: text tab only - $show_tabs = false; - - } elseif( wp_default_editor() == 'tinymce' ) { - - // case: both tabs - $default_editor = 'tinymce'; - + + // localize + acf_localize_data( + array( + 'toolbars' => $data, + ) + ); } - - - // must be logged in to upload - if( !current_user_can('upload_files') ) { - - $field['media_upload'] = 0; - - } - - - // mode - $switch_class = ($default_editor === 'html') ? 'html-active' : 'tmce-active'; - - - // filter - add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 ); - $field['value'] = apply_filters( 'acf_the_editor_content', $field['value'], $default_editor ); - - - // attr - $wrap = array( - 'id' => 'wp-' . $id . '-wrap', - 'class' => 'acf-editor-wrap wp-core-ui wp-editor-wrap ' . $switch_class, - 'data-toolbar' => $field['toolbar'] - ); - - - // delay - if( $field['delay'] ) { - $wrap['class'] .= ' delay'; - } - - - // vars - $textarea = acf_get_textarea_input(array( - 'id' => $id, - 'class' => 'wp-editor-area', - 'name' => $field['name'], - 'style' => $height ? "height:{$height}px;" : '', - 'value' => '%s' - )); - - ?> -
                                > + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // enqueue + acf_enqueue_uploader(); + + // vars + $id = uniqid( 'acf-editor-' ); + $default_editor = 'html'; + $show_tabs = true; + + // get height + $height = acf_get_user_setting( 'wysiwyg_height', 300 ); + $height = max( $height, 300 ); // minimum height is 300 + + // detect mode + if ( ! user_can_richedit() ) { + + $show_tabs = false; + + } elseif ( $field['tabs'] == 'visual' ) { + + // case: visual tab only + $default_editor = 'tinymce'; + $show_tabs = false; + + } elseif ( $field['tabs'] == 'text' ) { + + // case: text tab only + $show_tabs = false; + + } elseif ( wp_default_editor() == 'tinymce' ) { + + // case: both tabs + $default_editor = 'tinymce'; + + } + + // must be logged in to upload + if ( ! current_user_can( 'upload_files' ) ) { + + $field['media_upload'] = 0; + + } + + // mode + $switch_class = ( $default_editor === 'html' ) ? 'html-active' : 'tmce-active'; + + // filter + add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 ); + $field['value'] = apply_filters( 'acf_the_editor_content', $field['value'], $default_editor ); + + // attr + $wrap = array( + 'id' => 'wp-' . $id . '-wrap', + 'class' => 'acf-editor-wrap wp-core-ui wp-editor-wrap ' . $switch_class, + 'data-toolbar' => $field['toolbar'], + ); + + // delay + if ( $field['delay'] ) { + $wrap['class'] .= ' delay'; + } + + // vars + $textarea = acf_get_textarea_input( + array( + 'id' => $id, + 'class' => 'wp-editor-area', + 'name' => $field['name'], + 'style' => $height ? "height:{$height}px;" : '', + 'value' => '%s', + ) + ); + + ?> +
                                >
                                - +
                                -
                                - +
                                - +
                                - -
                                + +
                                - +
                                - get_toolbars(); - $choices = array(); - - if( !empty($toolbars) ) { - - foreach( $toolbars as $k => $v ) { - - $label = $k; - $name = sanitize_title( $label ); - $name = str_replace('-', '_', $name); - - $choices[ $name ] = $label; + get_toolbars(); + $choices = array(); + + if ( ! empty( $toolbars ) ) { + + foreach ( $toolbars as $k => $v ) { + + $label = $k; + $name = sanitize_title( $label ); + $name = str_replace( '-', '_', $name ); + + $choices[ $name ] = $label; + } } - } - - - // default_value - acf_render_field_setting( $field, array( - 'label' => __('Default Value','acf'), - 'instructions' => __('Appears when creating a new post','acf'), - 'type' => 'textarea', - 'name' => 'default_value', - )); - - - // tabs - acf_render_field_setting( $field, array( - 'label' => __('Tabs','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'tabs', - 'choices' => array( - 'all' => __("Visual & Text",'acf'), - 'visual' => __("Visual Only",'acf'), - 'text' => __("Text Only",'acf'), - ) - )); - - - // toolbar - acf_render_field_setting( $field, array( - 'label' => __('Toolbar','acf'), - 'instructions' => '', - 'type' => 'select', - 'name' => 'toolbar', - 'choices' => $choices, - 'conditions' => array( - 'field' => 'tabs', - 'operator' => '!=', - 'value' => 'text' - ) - )); - - - // media_upload - acf_render_field_setting( $field, array( - 'label' => __('Show Media Upload Buttons?','acf'), - 'instructions' => '', - 'name' => 'media_upload', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // delay - acf_render_field_setting( $field, array( - 'label' => __('Delay initialization?','acf'), - 'instructions' => __('TinyMCE will not be initialized until field is clicked','acf'), - 'name' => 'delay', - 'type' => 'true_false', - 'ui' => 1, - 'conditions' => array( - 'field' => 'tabs', - 'operator' => '!=', - 'value' => 'text' - ) - )); - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) { - + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Default Value', 'acf' ), + 'instructions' => __( 'Appears when creating a new post', 'acf' ), + 'type' => 'textarea', + 'name' => 'default_value', + ) + ); + + // tabs + acf_render_field_setting( + $field, + array( + 'label' => __( 'Tabs', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'tabs', + 'choices' => array( + 'all' => __( 'Visual & Text', 'acf' ), + 'visual' => __( 'Visual Only', 'acf' ), + 'text' => __( 'Text Only', 'acf' ), + ), + ) + ); + + // toolbar + acf_render_field_setting( + $field, + array( + 'label' => __( 'Toolbar', 'acf' ), + 'instructions' => '', + 'type' => 'select', + 'name' => 'toolbar', + 'choices' => $choices, + 'conditions' => array( + 'field' => 'tabs', + 'operator' => '!=', + 'value' => 'text', + ), + ) + ); + + // media_upload + acf_render_field_setting( + $field, + array( + 'label' => __( 'Show Media Upload Buttons?', 'acf' ), + 'instructions' => '', + 'name' => 'media_upload', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // delay + acf_render_field_setting( + $field, + array( + 'label' => __( 'Delay initialization?', 'acf' ), + 'instructions' => __( 'TinyMCE will not be initialized until field is clicked', 'acf' ), + 'name' => 'delay', + 'type' => 'true_false', + 'ui' => 1, + 'conditions' => array( + 'field' => 'tabs', + 'operator' => '!=', + 'value' => 'text', + ), + ) + ); + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + + return $value; + + } + + // apply filters + $value = apply_filters( 'acf_the_content', $value ); + + // follow the_content function in /wp-includes/post-template.php + $value = str_replace( ']]>', ']]>', $value ); + return $value; - } - - - // apply filters - $value = apply_filters( 'acf_the_content', $value ); - - - // follow the_content function in /wp-includes/post-template.php - $value = str_replace(']]>', ']]>', $value); - - - return $value; + } - -} -// initialize -acf_register_field_type( 'acf_field_wysiwyg' ); + // initialize + acf_register_field_type( 'acf_field_wysiwyg' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/fields/class-acf-field.php b/includes/fields/class-acf-field.php old mode 100644 new mode 100755 index 117f019..65ba4b2 --- a/includes/fields/class-acf-field.php +++ b/includes/fields/class-acf-field.php @@ -1,277 +1,275 @@ initialize(); - - - // register info - acf_register_field_type_info(array( - 'label' => $this->label, - 'name' => $this->name, - 'category' => $this->category, - 'public' => $this->public - )); - - - // value - $this->add_field_filter('acf/load_value', array($this, 'load_value'), 10, 3); - $this->add_field_filter('acf/update_value', array($this, 'update_value'), 10, 3); - $this->add_field_filter('acf/format_value', array($this, 'format_value'), 10, 3); - $this->add_field_filter('acf/validate_value', array($this, 'validate_value'), 10, 4); - $this->add_field_action('acf/delete_value', array($this, 'delete_value'), 10, 3); - - - // field - $this->add_field_filter('acf/validate_field', array($this, 'validate_field'), 10, 1); - $this->add_field_filter('acf/load_field', array($this, 'load_field'), 10, 1); - $this->add_field_filter('acf/update_field', array($this, 'update_field'), 10, 1); - $this->add_field_filter('acf/duplicate_field', array($this, 'duplicate_field'), 10, 1); - $this->add_field_action('acf/delete_field', array($this, 'delete_field'), 10, 1); - $this->add_field_action('acf/render_field', array($this, 'render_field'), 9, 1); - $this->add_field_action('acf/render_field_settings', array($this, 'render_field_settings'), 9, 1); - $this->add_field_filter('acf/prepare_field', array($this, 'prepare_field'), 10, 1); - $this->add_field_filter('acf/translate_field', array($this, 'translate_field'), 10, 1); - - - // input actions - $this->add_action("acf/input/admin_enqueue_scripts", array($this, 'input_admin_enqueue_scripts'), 10, 0); - $this->add_action("acf/input/admin_head", array($this, 'input_admin_head'), 10, 0); - $this->add_action("acf/input/form_data", array($this, 'input_form_data'), 10, 1); - $this->add_filter("acf/input/admin_l10n", array($this, 'input_admin_l10n'), 10, 1); - $this->add_action("acf/input/admin_footer", array($this, 'input_admin_footer'), 10, 1); - - - // field group actions - $this->add_action("acf/field_group/admin_enqueue_scripts", array($this, 'field_group_admin_enqueue_scripts'), 10, 0); - $this->add_action("acf/field_group/admin_head", array($this, 'field_group_admin_head'), 10, 0); - $this->add_action("acf/field_group/admin_footer", array($this, 'field_group_admin_footer'), 10, 0); - - } - - - /* - * initialize - * - * This function will initialize the field type - * - * @type function - * @date 27/6/17 - * @since 5.6.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - /* do nothing */ - - } - - - /* - * add_filter - * - * This function checks if the function is_callable before adding the filter - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param $tag (string) - * @param $function_to_add (string) - * @param $priority (int) - * @param $accepted_args (int) - * @return n/a - */ - - function add_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { - - // bail early if no callable - if( !is_callable($function_to_add) ) return; - - - // add - add_filter( $tag, $function_to_add, $priority, $accepted_args ); - - } - - - /* - * add_field_filter - * - * This function will add a field type specific filter - * - * @type function - * @date 29/09/2016 - * @since 5.4.0 - * - * @param $tag (string) - * @param $function_to_add (string) - * @param $priority (int) - * @param $accepted_args (int) - * @return n/a - */ - - function add_field_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { - - // append - $tag .= '/type=' . $this->name; - - - // add - $this->add_filter( $tag, $function_to_add, $priority, $accepted_args ); - - } - - - /* - * add_action - * - * This function checks if the function is_callable before adding the action - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param $tag (string) - * @param $function_to_add (string) - * @param $priority (int) - * @param $accepted_args (int) - * @return n/a - */ - - function add_action( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { - - // bail early if no callable - if( !is_callable($function_to_add) ) return; - - - // add - add_action( $tag, $function_to_add, $priority, $accepted_args ); - - } - - - /* - * add_field_action - * - * This function will add a field type specific filter - * - * @type function - * @date 29/09/2016 - * @since 5.4.0 - * - * @param $tag (string) - * @param $function_to_add (string) - * @param $priority (int) - * @param $accepted_args (int) - * @return n/a - */ - - function add_field_action( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { - - // append - $tag .= '/type=' . $this->name; - - - // add - $this->add_action( $tag, $function_to_add, $priority, $accepted_args ); - - } - - - /* - * validate_field - * - * This function will append default settings to a field - * - * @type filter ("acf/validate_field/type={$this->name}") - * @since 3.6 - * @date 23/01/13 - * - * @param $field (array) - * @return $field (array) - */ - - function validate_field( $field ) { - - // bail early if no defaults - if( !is_array($this->defaults) ) return $field; - - - // merge in defaults but keep order of $field keys - foreach( $this->defaults as $k => $v ) { - - if( !isset($field[ $k ]) ) $field[ $k ] = $v; - + $l10n = array(), + $public = true; + + + /* + * __construct + * + * This function will initialize the field type + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // initialize + $this->initialize(); + + // register info + acf_register_field_type_info( + array( + 'label' => $this->label, + 'name' => $this->name, + 'category' => $this->category, + 'public' => $this->public, + ) + ); + + // value + $this->add_field_filter( 'acf/load_value', array( $this, 'load_value' ), 10, 3 ); + $this->add_field_filter( 'acf/update_value', array( $this, 'update_value' ), 10, 3 ); + $this->add_field_filter( 'acf/format_value', array( $this, 'format_value' ), 10, 3 ); + $this->add_field_filter( 'acf/validate_value', array( $this, 'validate_value' ), 10, 4 ); + $this->add_field_action( 'acf/delete_value', array( $this, 'delete_value' ), 10, 3 ); + + // field + $this->add_field_filter( 'acf/validate_field', array( $this, 'validate_field' ), 10, 1 ); + $this->add_field_filter( 'acf/load_field', array( $this, 'load_field' ), 10, 1 ); + $this->add_field_filter( 'acf/update_field', array( $this, 'update_field' ), 10, 1 ); + $this->add_field_filter( 'acf/duplicate_field', array( $this, 'duplicate_field' ), 10, 1 ); + $this->add_field_action( 'acf/delete_field', array( $this, 'delete_field' ), 10, 1 ); + $this->add_field_action( 'acf/render_field', array( $this, 'render_field' ), 9, 1 ); + $this->add_field_action( 'acf/render_field_settings', array( $this, 'render_field_settings' ), 9, 1 ); + $this->add_field_filter( 'acf/prepare_field', array( $this, 'prepare_field' ), 10, 1 ); + $this->add_field_filter( 'acf/translate_field', array( $this, 'translate_field' ), 10, 1 ); + + // input actions + $this->add_action( 'acf/input/admin_enqueue_scripts', array( $this, 'input_admin_enqueue_scripts' ), 10, 0 ); + $this->add_action( 'acf/input/admin_head', array( $this, 'input_admin_head' ), 10, 0 ); + $this->add_action( 'acf/input/form_data', array( $this, 'input_form_data' ), 10, 1 ); + $this->add_filter( 'acf/input/admin_l10n', array( $this, 'input_admin_l10n' ), 10, 1 ); + $this->add_action( 'acf/input/admin_footer', array( $this, 'input_admin_footer' ), 10, 1 ); + + // field group actions + $this->add_action( 'acf/field_group/admin_enqueue_scripts', array( $this, 'field_group_admin_enqueue_scripts' ), 10, 0 ); + $this->add_action( 'acf/field_group/admin_head', array( $this, 'field_group_admin_head' ), 10, 0 ); + $this->add_action( 'acf/field_group/admin_footer', array( $this, 'field_group_admin_footer' ), 10, 0 ); + } - - - // return - return $field; - + + + /* + * initialize + * + * This function will initialize the field type + * + * @type function + * @date 27/6/17 + * @since 5.6.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + /* do nothing */ + + } + + + /* + * add_filter + * + * This function checks if the function is_callable before adding the filter + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param $tag (string) + * @param $function_to_add (string) + * @param $priority (int) + * @param $accepted_args (int) + * @return n/a + */ + + function add_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { + + // bail early if no callable + if ( ! is_callable( $function_to_add ) ) { + return; + } + + // add + add_filter( $tag, $function_to_add, $priority, $accepted_args ); + + } + + + /* + * add_field_filter + * + * This function will add a field type specific filter + * + * @type function + * @date 29/09/2016 + * @since 5.4.0 + * + * @param $tag (string) + * @param $function_to_add (string) + * @param $priority (int) + * @param $accepted_args (int) + * @return n/a + */ + + function add_field_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { + + // append + $tag .= '/type=' . $this->name; + + // add + $this->add_filter( $tag, $function_to_add, $priority, $accepted_args ); + + } + + + /* + * add_action + * + * This function checks if the function is_callable before adding the action + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param $tag (string) + * @param $function_to_add (string) + * @param $priority (int) + * @param $accepted_args (int) + * @return n/a + */ + + function add_action( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { + + // bail early if no callable + if ( ! is_callable( $function_to_add ) ) { + return; + } + + // add + add_action( $tag, $function_to_add, $priority, $accepted_args ); + + } + + + /* + * add_field_action + * + * This function will add a field type specific filter + * + * @type function + * @date 29/09/2016 + * @since 5.4.0 + * + * @param $tag (string) + * @param $function_to_add (string) + * @param $priority (int) + * @param $accepted_args (int) + * @return n/a + */ + + function add_field_action( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) { + + // append + $tag .= '/type=' . $this->name; + + // add + $this->add_action( $tag, $function_to_add, $priority, $accepted_args ); + + } + + + /* + * validate_field + * + * This function will append default settings to a field + * + * @type filter ("acf/validate_field/type={$this->name}") + * @since 3.6 + * @date 23/01/13 + * + * @param $field (array) + * @return $field (array) + */ + + function validate_field( $field ) { + + // bail early if no defaults + if ( ! is_array( $this->defaults ) ) { + return $field; + } + + // merge in defaults but keep order of $field keys + foreach ( $this->defaults as $k => $v ) { + + if ( ! isset( $field[ $k ] ) ) { + $field[ $k ] = $v; + } + } + + // return + return $field; + + } + + + /* + * admin_l10n + * + * This function will append l10n text translations to an array which is later passed to JS + * + * @type filter ("acf/input/admin_l10n") + * @since 3.6 + * @date 23/01/13 + * + * @param $l10n (array) + * @return $l10n (array) + */ + + function input_admin_l10n( $l10n ) { + + // bail early if no defaults + if ( empty( $this->l10n ) ) { + return $l10n; + } + + // append + $l10n[ $this->name ] = $this->l10n; + + // return + return $l10n; + + } + } - - - /* - * admin_l10n - * - * This function will append l10n text translations to an array which is later passed to JS - * - * @type filter ("acf/input/admin_l10n") - * @since 3.6 - * @date 23/01/13 - * - * @param $l10n (array) - * @return $l10n (array) - */ - - function input_admin_l10n( $l10n ) { - - // bail early if no defaults - if( empty($this->l10n) ) return $l10n; - - - // append - $l10n[ $this->name ] = $this->l10n; - - - // return - return $l10n; - - } - -} endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/forms/form-attachment.php b/includes/forms/form-attachment.php index 6acbfee..9ea2ae1 100644 --- a/includes/forms/form-attachment.php +++ b/includes/forms/form-attachment.php @@ -5,239 +5,232 @@ * * All the logic for adding fields to attachments * -* @class acf_form_attachment -* @package ACF -* @subpackage Forms +* @class acf_form_attachment +* @package ACF +* @subpackage Forms */ -if( ! class_exists('acf_form_attachment') ) : +if ( ! class_exists( 'acf_form_attachment' ) ) : + + class acf_form_attachment { + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // actions + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + + // render + add_filter( 'attachment_fields_to_edit', array( $this, 'edit_attachment' ), 10, 2 ); + + // save + add_filter( 'attachment_fields_to_save', array( $this, 'save_attachment' ), 10, 2 ); -class acf_form_attachment { - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // actions - add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); - - - // render - add_filter('attachment_fields_to_edit', array($this, 'edit_attachment'), 10, 2); - - - // save - add_filter('attachment_fields_to_save', array($this, 'save_attachment'), 10, 2); - - } - - - /* - * admin_enqueue_scripts - * - * This action is run after post query but before any admin script / head actions. - * It is a good place to register all actions. - * - * @type action (admin_enqueue_scripts) - * @date 26/01/13 - * @since 3.6.0 - * - * @param N/A - * @return N/A - */ - - function admin_enqueue_scripts() { - - // bail early if not valid screen - if( !acf_is_screen(array('attachment', 'upload')) ) { - return; } - - // load acf scripts - acf_enqueue_scripts(array( - 'uploader' => true, - )); - - // actions - if( acf_is_screen('upload') ) { - add_action('admin_footer', array($this, 'admin_footer'), 0); + + + /* + * admin_enqueue_scripts + * + * This action is run after post query but before any admin script / head actions. + * It is a good place to register all actions. + * + * @type action (admin_enqueue_scripts) + * @date 26/01/13 + * @since 3.6.0 + * + * @param N/A + * @return N/A + */ + + function admin_enqueue_scripts() { + + // bail early if not valid screen + if ( ! acf_is_screen( array( 'attachment', 'upload' ) ) ) { + return; + } + + // load acf scripts + acf_enqueue_scripts( + array( + 'uploader' => true, + ) + ); + + // actions + if ( acf_is_screen( 'upload' ) ) { + add_action( 'admin_footer', array( $this, 'admin_footer' ), 0 ); + } } - } - - - /* - * admin_footer - * - * This function will add acf_form_data to the WP 4.0 attachment grid - * - * @type action (admin_footer) - * @date 11/09/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function admin_footer() { - - // render post data - acf_form_data(array( - 'screen' => 'attachment', - 'post_id' => 0, - )); - -?> + + + /* + * admin_footer + * + * This function will add acf_form_data to the WP 4.0 attachment grid + * + * @type action (admin_footer) + * @date 11/09/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function admin_footer() { + + // render post data + acf_form_data( + array( + 'screen' => 'attachment', + 'post_id' => 0, + ) + ); + + ?> -ID; - $el = 'tr'; - - - // get field groups - $field_groups = acf_get_field_groups(array( - 'attachment_id' => $post_id, - 'attachment' => $post_id // Leave for backwards compatibility - )); - - - // render - if( !empty($field_groups) ) { - - // get acf_form_data - ob_start(); - - - acf_form_data(array( - 'screen' => 'attachment', - 'post_id' => $post_id, - )); - - - // open - echo ''; - - - // loop - foreach( $field_groups as $field_group ) { - - // load fields - $fields = acf_get_fields( $field_group ); - - - // override instruction placement for modal - if( !$is_page ) { - - $field_group['instruction_placement'] = 'field'; - } - - - // render - acf_render_fields( $fields, $post_id, $el, $field_group['instruction_placement'] ); - - } - - - // close - echo ''; - - - - $html = ob_get_contents(); - - - ob_end_clean(); - - - $form_fields[ 'acf-form-data' ] = array( - 'label' => '', - 'input' => 'html', - 'html' => $html - ); - + ID; + $el = 'tr'; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'attachment_id' => $post_id, + 'attachment' => $post_id, // Leave for backwards compatibility + ) + ); + + // render + if ( ! empty( $field_groups ) ) { + + // get acf_form_data + ob_start(); + + acf_form_data( + array( + 'screen' => 'attachment', + 'post_id' => $post_id, + ) + ); + + // open + echo ''; + + // loop + foreach ( $field_groups as $field_group ) { + + // load fields + $fields = acf_get_fields( $field_group ); + + // override instruction placement for modal + if ( ! $is_page ) { + + $field_group['instruction_placement'] = 'field'; + } + + // render + acf_render_fields( $fields, $post_id, $el, $field_group['instruction_placement'] ); + + } + + // close + echo ''; + + $html = ob_get_contents(); + + ob_end_clean(); + + $form_fields['acf-form-data'] = array( + 'label' => '', + 'input' => 'html', + 'html' => $html, + ); + + } + + // return + return $form_fields; + + } + + + /* + * save_attachment + * + * description + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function save_attachment( $post, $attachment ) { + + // bail early if not valid nonce + if ( ! acf_verify_nonce( 'attachment' ) ) { + return $post; + } + + // bypass validation for ajax + if ( acf_is_ajax( 'save-attachment-compat' ) ) { + acf_save_post( $post['ID'] ); + + // validate and save + } elseif ( acf_validate_save_post( true ) ) { + acf_save_post( $post['ID'] ); + } + + // return return $post; } - - // bypass validation for ajax - if( acf_is_ajax('save-attachment-compat') ) { - acf_save_post( $post['ID'] ); - - // validate and save - } elseif( acf_validate_save_post(true) ) { - acf_save_post( $post['ID'] ); - } - - // return - return $post; - } - - -} -new acf_form_attachment(); + + } + + new acf_form_attachment(); endif; -?> \ No newline at end of file +?> diff --git a/includes/forms/form-comment.php b/includes/forms/form-comment.php index b911722..9defdce 100644 --- a/includes/forms/form-comment.php +++ b/includes/forms/form-comment.php @@ -5,320 +5,309 @@ * * All the logic for adding fields to comments * -* @class acf_form_comment -* @package ACF -* @subpackage Forms +* @class acf_form_comment +* @package ACF +* @subpackage Forms */ -if( ! class_exists('acf_form_comment') ) : +if ( ! class_exists( 'acf_form_comment' ) ) : -class acf_form_comment { - - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // actions - add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); - - - // render - add_filter('comment_form_field_comment', array($this, 'comment_form_field_comment'), 999, 1); - - //add_action( 'comment_form_logged_in_after', array( $this, 'add_comment') ); - //add_action( 'comment_form', array( $this, 'add_comment') ); + class acf_form_comment { + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // actions + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + + // render + add_filter( 'comment_form_field_comment', array( $this, 'comment_form_field_comment' ), 999, 1 ); + + // add_action( 'comment_form_logged_in_after', array( $this, 'add_comment') ); + // add_action( 'comment_form', array( $this, 'add_comment') ); + + // save + add_action( 'edit_comment', array( $this, 'save_comment' ), 10, 1 ); + add_action( 'comment_post', array( $this, 'save_comment' ), 10, 1 ); - - // save - add_action( 'edit_comment', array( $this, 'save_comment' ), 10, 1 ); - add_action( 'comment_post', array( $this, 'save_comment' ), 10, 1 ); - - } - - - /* - * validate_page - * - * This function will check if the current page is for a post/page edit form - * - * @type function - * @date 23/06/12 - * @since 3.1.8 - * - * @param n/a - * @return (boolean) - */ - - function validate_page() { - - // global - global $pagenow; - - - // validate page - if( $pagenow == 'comment.php' ) { - - return true; - } - - - // return - return false; - } - - - /* - * admin_enqueue_scripts - * - * This action is run after post query but before any admin script / head actions. - * It is a good place to register all actions. - * - * @type action (admin_enqueue_scripts) - * @date 26/01/13 - * @since 3.6.0 - * - * @param n/a - * @return n/a - */ - - function admin_enqueue_scripts() { - - // validate page - if( ! $this->validate_page() ) { - - return; - + + + /* + * validate_page + * + * This function will check if the current page is for a post/page edit form + * + * @type function + * @date 23/06/12 + * @since 3.1.8 + * + * @param n/a + * @return (boolean) + */ + + function validate_page() { + + // global + global $pagenow; + + // validate page + if ( $pagenow == 'comment.php' ) { + + return true; + + } + + // return + return false; } - - - // load acf scripts - acf_enqueue_scripts(); - - - // actions - add_action('admin_footer', array($this, 'admin_footer'), 10, 1); - add_action('add_meta_boxes_comment', array($this, 'edit_comment'), 10, 1); - } - - - /* - * edit_comment - * - * This function is run on the admin comment.php page and will render the ACF fields within custom metaboxes to look native - * - * @type function - * @date 19/10/13 - * @since 5.0.0 - * - * @param $comment (object) - * @return n/a - */ - - function edit_comment( $comment ) { - - // vars - $post_id = "comment_{$comment->comment_ID}"; - - // get field groups - $field_groups = acf_get_field_groups(array( - 'comment' => get_post_type( $comment->comment_post_ID ) - )); - - - // render - if( !empty($field_groups) ) { - - // render post data - acf_form_data(array( - 'screen' => 'comment', - 'post_id' => $post_id - )); - - - foreach( $field_groups as $field_group ) { - - // load fields - $fields = acf_get_fields( $field_group ); - - - // vars - $o = array( - 'id' => 'acf-'.$field_group['ID'], - 'key' => $field_group['key'], - //'style' => $field_group['style'], - 'label' => $field_group['label_placement'], - 'edit_url' => '', - 'edit_title' => __('Edit field group', 'acf'), - //'visibility' => $visibility + /* + * admin_enqueue_scripts + * + * This action is run after post query but before any admin script / head actions. + * It is a good place to register all actions. + * + * @type action (admin_enqueue_scripts) + * @date 26/01/13 + * @since 3.6.0 + * + * @param n/a + * @return n/a + */ + + function admin_enqueue_scripts() { + + // validate page + if ( ! $this->validate_page() ) { + + return; + + } + + // load acf scripts + acf_enqueue_scripts(); + + // actions + add_action( 'admin_footer', array( $this, 'admin_footer' ), 10, 1 ); + add_action( 'add_meta_boxes_comment', array( $this, 'edit_comment' ), 10, 1 ); + + } + + + /* + * edit_comment + * + * This function is run on the admin comment.php page and will render the ACF fields within custom metaboxes to look native + * + * @type function + * @date 19/10/13 + * @since 5.0.0 + * + * @param $comment (object) + * @return n/a + */ + + function edit_comment( $comment ) { + + // vars + $post_id = "comment_{$comment->comment_ID}"; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'comment' => get_post_type( $comment->comment_post_ID ), + ) + ); + + // render + if ( ! empty( $field_groups ) ) { + + // render post data + acf_form_data( + array( + 'screen' => 'comment', + 'post_id' => $post_id, + ) ); - - - // edit_url - if( $field_group['ID'] && acf_current_user_can_admin() ) { - - $o['edit_url'] = admin_url('post.php?post=' . $field_group['ID'] . '&action=edit'); - - } - - ?> + + foreach ( $field_groups as $field_group ) { + + // load fields + $fields = acf_get_fields( $field_group ); + + // vars + $o = array( + 'id' => 'acf-' . $field_group['ID'], + 'key' => $field_group['key'], + // 'style' => $field_group['style'], + 'label' => $field_group['label_placement'], + 'edit_url' => '', + 'edit_title' => __( 'Edit field group', 'acf' ), + // 'visibility' => $visibility + ); + + // edit_url + if ( $field_group['ID'] && acf_current_user_can_admin() ) { + + $o['edit_url'] = admin_url( 'post.php?post=' . $field_group['ID'] . '&action=edit' ); + + } + + ?>

                                - +
                                - $post->post_type - )); - - - // bail early if no field groups - if( !$field_groups ) return $html; - - - // enqueue scripts - acf_enqueue_scripts(); - - - // ob - ob_start(); - - // render post data - acf_form_data(array( - 'screen' => 'comment', - 'post_id' => $post_id - )); - - echo '
                                '; - - foreach( $field_groups as $field_group ) { - - $fields = acf_get_fields( $field_group ); - - acf_render_fields( $fields, $post_id, 'p', $field_group['instruction_placement'] ); - + } } - - echo '
                                '; - - - // append - $html .= ob_get_contents(); - ob_end_clean(); - - - // return - return $html; - - } - - - /* - * save_comment - * - * This function will save the comment data - * - * @type function - * @date 19/10/13 - * @since 5.0.0 - * - * @param comment_id (int) - * @return n/a - */ - - function save_comment( $comment_id ) { - - // bail early if not valid nonce - if( !acf_verify_nonce('comment') ) { - return $comment_id; + } - - - // kses - if( isset($_POST['acf']) ) { - $_POST['acf'] = wp_kses_post_deep( $_POST['acf'] ); - } - - - // validate and save - if( acf_validate_save_post(true) ) { - acf_save_post( "comment_{$comment_id}" ); + + + /* + * comment_form_field_comment + * + * description + * + * @type function + * @date 18/04/2016 + * @since 5.3.8 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function comment_form_field_comment( $html ) { + + // global + global $post; + + // vars + $post_id = false; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'comment' => $post->post_type, + ) + ); + + // bail early if no field groups + if ( ! $field_groups ) { + return $html; + } + + // enqueue scripts + acf_enqueue_scripts(); + + // ob + ob_start(); + + // render post data + acf_form_data( + array( + 'screen' => 'comment', + 'post_id' => $post_id, + ) + ); + + echo '
                                '; + + foreach ( $field_groups as $field_group ) { + + $fields = acf_get_fields( $field_group ); + + acf_render_fields( $fields, $post_id, 'p', $field_group['instruction_placement'] ); + + } + + echo '
                                '; + + // append + $html .= ob_get_contents(); + ob_end_clean(); + + // return + return $html; + } - - } - - - /* - * admin_footer - * - * description - * - * @type function - * @date 27/03/2015 - * @since 5.1.5 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function admin_footer() { - -?> + + + /* + * save_comment + * + * This function will save the comment data + * + * @type function + * @date 19/10/13 + * @since 5.0.0 + * + * @param comment_id (int) + * @return n/a + */ + + function save_comment( $comment_id ) { + + // bail early if not valid nonce + if ( ! acf_verify_nonce( 'comment' ) ) { + return $comment_id; + } + + // kses + if ( isset( $_POST['acf'] ) ) { + $_POST['acf'] = wp_kses_post_deep( $_POST['acf'] ); + } + + // validate and save + if ( acf_validate_save_post( true ) ) { + acf_save_post( "comment_{$comment_id}" ); + } + + } + + + /* + * admin_footer + * + * description + * + * @type function + * @date 27/03/2015 + * @since 5.1.5 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function admin_footer() { + + ?> - \ No newline at end of file +?> diff --git a/includes/forms/form-customizer.php b/includes/forms/form-customizer.php index 5f32ad8..8186fad 100644 --- a/includes/forms/form-customizer.php +++ b/includes/forms/form-customizer.php @@ -1,397 +1,389 @@ preview_values = array(); - $this->preview_fields = array(); - $this->preview_errors = array(); - - - // actions - add_action('customize_controls_init', array($this, 'customize_controls_init')); - add_action('customize_preview_init', array($this, 'customize_preview_init'), 1, 1); - add_action('customize_save', array($this, 'customize_save'), 1, 1); - - - // save - add_filter('widget_update_callback', array($this, 'save_widget'), 10, 4); - - } - - - /* - * admin_enqueue_scripts - * - * This action is run after post query but before any admin script / head actions. - * It is a good place to register all actions. - * - * @type action (admin_enqueue_scripts) - * @date 26/01/13 - * @since 3.6.0 - * - * @param N/A - * @return N/A - */ - - function customize_controls_init() { - - // load acf scripts - acf_enqueue_scripts(array( - 'context' => 'customize_controls' - )); - - - // actions - add_action('acf/input/admin_footer', array($this, 'admin_footer'), 1); + class acf_form_customizer { + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { - } - - - /* - * save_widget - * - * This function will hook into the widget update filter and save ACF data - * - * @type function - * @date 27/05/2015 - * @since 5.2.3 - * - * @param $instance (array) widget settings - * @param $new_instance (array) widget settings - * @param $old_instance (array) widget settings - * @param $widget (object) widget info - * @return $instance - */ - - function save_widget( $instance, $new_instance, $old_instance, $widget ) { - - // bail ealry if not valid (customize + acf values + nonce) - if( !isset($_POST['wp_customize']) || !isset($new_instance['acf']) || !acf_verify_nonce('widget') ) return $instance; - - - // vars - $data = array( - 'post_id' => "widget_{$widget->id}", - 'values' => array(), - 'fields' => array() - ); - - - // append values - $data['values'] = $new_instance['acf']; - - - // append fields (name => key relationship) - used later in 'acf/get_field_reference' for customizer previews - foreach( $data['values'] as $k => $v ) { - - // get field - $field = acf_get_field( $k ); - - - // continue if no field - if( !$field ) continue; - - - // update - $data['fields'][ $field['name'] ] = $field['key']; - - } - - - // append data to instance - $instance['acf'] = $data; - - - - // return - return $instance; - - } - - - /* - * settings - * - * This function will return an array of cutomizer settings that include ACF data - * similar to `$customizer->settings();` - * - * @type function - * @date 22/03/2016 - * @since 5.3.2 - * - * @param $customizer (object) - * @return $value (mixed) - */ - - function settings( $customizer ) { - - // vars - $data = array(); - $settings = $customizer->settings(); - - - // bail ealry if no settings - if( empty($settings) ) return false; - - - // loop over settings - foreach( $settings as $setting ) { - // vars - $id = $setting->id; - - - // verify settings type - if( substr($id, 0, 6) == 'widget' || substr($id, 0, 7) == 'nav_menu' ) { - // allow - } else { - continue; + $this->preview_values = array(); + $this->preview_fields = array(); + $this->preview_errors = array(); + + // actions + add_action( 'customize_controls_init', array( $this, 'customize_controls_init' ) ); + add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ), 1, 1 ); + add_action( 'customize_save', array( $this, 'customize_save' ), 1, 1 ); + + // save + add_filter( 'widget_update_callback', array( $this, 'save_widget' ), 10, 4 ); + + } + + + /* + * admin_enqueue_scripts + * + * This action is run after post query but before any admin script / head actions. + * It is a good place to register all actions. + * + * @type action (admin_enqueue_scripts) + * @date 26/01/13 + * @since 3.6.0 + * + * @param N/A + * @return N/A + */ + + function customize_controls_init() { + + // load acf scripts + acf_enqueue_scripts( + array( + 'context' => 'customize_controls', + ) + ); + + // actions + add_action( 'acf/input/admin_footer', array( $this, 'admin_footer' ), 1 ); + + } + + + /* + * save_widget + * + * This function will hook into the widget update filter and save ACF data + * + * @type function + * @date 27/05/2015 + * @since 5.2.3 + * + * @param $instance (array) widget settings + * @param $new_instance (array) widget settings + * @param $old_instance (array) widget settings + * @param $widget (object) widget info + * @return $instance + */ + + function save_widget( $instance, $new_instance, $old_instance, $widget ) { + + // bail ealry if not valid (customize + acf values + nonce) + if ( ! isset( $_POST['wp_customize'] ) || ! isset( $new_instance['acf'] ) || ! acf_verify_nonce( 'widget' ) ) { + return $instance; } - - - // get value - $value = $setting->post_value(); - - - // bail early if no acf - if( !is_array($value) || !isset($value['acf']) ) continue; - - - // set data - $setting->acf = $value['acf']; - - - // append - $data[] = $setting; - + + // vars + $data = array( + 'post_id' => "widget_{$widget->id}", + 'values' => array(), + 'fields' => array(), + ); + + // append values + $data['values'] = $new_instance['acf']; + + // append fields (name => key relationship) - used later in 'acf/get_field_reference' for customizer previews + foreach ( $data['values'] as $k => $v ) { + + // get field + $field = acf_get_field( $k ); + + // continue if no field + if ( ! $field ) { + continue; + } + + // update + $data['fields'][ $field['name'] ] = $field['key']; + + } + + // append data to instance + $instance['acf'] = $data; + + // return + return $instance; + } - - - // bail ealry if no settings - if( empty($data) ) return false; - - - // return - return $data; - - } - - - /* - * customize_preview_init - * - * This function is called when customizer preview is initialized - * - * @type function - * @date 22/03/2016 - * @since 5.3.2 - * - * @param $customizer (object) - * @return n/a - */ - - function customize_preview_init( $customizer ) { - - // get customizer settings (widgets) - $settings = $this->settings( $customizer ); - - - // bail ealry if no settings - if( empty($settings) ) return; - - - // append values - foreach( $settings as $setting ) { - - // get acf data - $data = $setting->acf; - - - // append acf_value to preview_values - $this->preview_values[ $data['post_id'] ] = $data['values']; - $this->preview_fields[ $data['post_id'] ] = $data['fields']; - + + + /* + * settings + * + * This function will return an array of cutomizer settings that include ACF data + * similar to `$customizer->settings();` + * + * @type function + * @date 22/03/2016 + * @since 5.3.2 + * + * @param $customizer (object) + * @return $value (mixed) + */ + + function settings( $customizer ) { + + // vars + $data = array(); + $settings = $customizer->settings(); + + // bail ealry if no settings + if ( empty( $settings ) ) { + return false; + } + + // loop over settings + foreach ( $settings as $setting ) { + + // vars + $id = $setting->id; + + // verify settings type + if ( substr( $id, 0, 6 ) == 'widget' || substr( $id, 0, 7 ) == 'nav_menu' ) { + // allow + } else { + continue; + } + + // get value + $value = $setting->post_value(); + + // bail early if no acf + if ( ! is_array( $value ) || ! isset( $value['acf'] ) ) { + continue; + } + + // set data + $setting->acf = $value['acf']; + + // append + $data[] = $setting; + + } + + // bail ealry if no settings + if ( empty( $data ) ) { + return false; + } + + // return + return $data; + } - - - // bail ealry if no preview_values - if( empty($this->preview_values) ) return; - - - // add filters - add_filter('acf/pre_load_value', array($this, 'pre_load_value'), 10, 3); - add_filter('acf/pre_load_reference', array($this, 'pre_load_reference'), 10, 3); - - } - - /** - * pre_load_value - * - * Used to inject preview value - * - * @date 2/2/18 - * @since 5.6.5 - * - * @param type $var Description. Default. - * @return type Description. - */ - - function pre_load_value( $value, $post_id, $field ) { - - // check - if( isset($this->preview_values[ $post_id ][ $field['key'] ]) ) { - return $this->preview_values[ $post_id ][ $field['key'] ]; + + + /* + * customize_preview_init + * + * This function is called when customizer preview is initialized + * + * @type function + * @date 22/03/2016 + * @since 5.3.2 + * + * @param $customizer (object) + * @return n/a + */ + + function customize_preview_init( $customizer ) { + + // get customizer settings (widgets) + $settings = $this->settings( $customizer ); + + // bail ealry if no settings + if ( empty( $settings ) ) { + return; + } + + // append values + foreach ( $settings as $setting ) { + + // get acf data + $data = $setting->acf; + + // append acf_value to preview_values + $this->preview_values[ $data['post_id'] ] = $data['values']; + $this->preview_fields[ $data['post_id'] ] = $data['fields']; + + } + + // bail ealry if no preview_values + if ( empty( $this->preview_values ) ) { + return; + } + + // add filters + add_filter( 'acf/pre_load_value', array( $this, 'pre_load_value' ), 10, 3 ); + add_filter( 'acf/pre_load_reference', array( $this, 'pre_load_reference' ), 10, 3 ); + } - - // return - return $value; - } - - /** - * pre_load_reference - * - * Used to inject preview value - * - * @date 2/2/18 - * @since 5.6.5 - * - * @param type $var Description. Default. - * @return type Description. - */ - - function pre_load_reference( $field_key, $field_name, $post_id ) { - - // check - if( isset($this->preview_fields[ $post_id ][ $field_name ]) ) { - return $this->preview_fields[ $post_id ][ $field_name ]; + + /** + * pre_load_value + * + * Used to inject preview value + * + * @date 2/2/18 + * @since 5.6.5 + * + * @param type $var Description. Default. + * @return type Description. + */ + + function pre_load_value( $value, $post_id, $field ) { + + // check + if ( isset( $this->preview_values[ $post_id ][ $field['key'] ] ) ) { + return $this->preview_values[ $post_id ][ $field['key'] ]; + } + + // return + return $value; } - - // return - return $field_key; - } - - - /* - * customize_save - * - * This function is called when customizer saves a widget. - * Normally, the widget_update_callback filter would be used, but the customizer disables this and runs a custom action - * class-customizer-settings.php will save the widget data via the function set_root_value which uses update_option - * - * @type function - * @date 22/03/2016 - * @since 5.3.2 - * - * @param $customizer (object) - * @return n/a - */ - - function customize_save( $customizer ) { - - // get customizer settings (widgets) - $settings = $this->settings( $customizer ); - - - // bail ealry if no settings - if( empty($settings) ) return; - - - // append values - foreach( $settings as $setting ) { - - // get acf data - $data = $setting->acf; - - - // save acf data - acf_save_post( $data['post_id'], $data['values'] ); - - - // remove [acf] data from saved widget array - $id_data = $setting->id_data(); - add_filter('pre_update_option_' . $id_data['base'], array($this, 'pre_update_option'), 10, 3); - + + /** + * pre_load_reference + * + * Used to inject preview value + * + * @date 2/2/18 + * @since 5.6.5 + * + * @param type $var Description. Default. + * @return type Description. + */ + + function pre_load_reference( $field_key, $field_name, $post_id ) { + + // check + if ( isset( $this->preview_fields[ $post_id ][ $field_name ] ) ) { + return $this->preview_fields[ $post_id ][ $field_name ]; + } + + // return + return $field_key; } - - } - - - /* - * pre_update_option - * - * this function will remove the [acf] data from widget insance - * - * @type function - * @date 22/03/2016 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function pre_update_option( $value, $option, $old_value ) { - - // bail ealry if no value - if( empty($value) ) return $value; - - - // loop over widgets - // WP saves all widgets (of the same type) as an array of widgets - foreach( $value as $i => $widget ) { - - // bail ealry if no acf - if( !isset($widget['acf']) ) continue; - - - // remove widget - unset($value[ $i ]['acf']); - + + + /* + * customize_save + * + * This function is called when customizer saves a widget. + * Normally, the widget_update_callback filter would be used, but the customizer disables this and runs a custom action + * class-customizer-settings.php will save the widget data via the function set_root_value which uses update_option + * + * @type function + * @date 22/03/2016 + * @since 5.3.2 + * + * @param $customizer (object) + * @return n/a + */ + + function customize_save( $customizer ) { + + // get customizer settings (widgets) + $settings = $this->settings( $customizer ); + + // bail ealry if no settings + if ( empty( $settings ) ) { + return; + } + + // append values + foreach ( $settings as $setting ) { + + // get acf data + $data = $setting->acf; + + // save acf data + acf_save_post( $data['post_id'], $data['values'] ); + + // remove [acf] data from saved widget array + $id_data = $setting->id_data(); + add_filter( 'pre_update_option_' . $id_data['base'], array( $this, 'pre_update_option' ), 10, 3 ); + + } + } - - - // return - return $value; - - } - - - /* - * admin_footer - * - * This function will add some custom HTML to the footer of the edit page - * - * @type function - * @date 11/06/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function admin_footer() { - -?> + + + /* + * pre_update_option + * + * this function will remove the [acf] data from widget insance + * + * @type function + * @date 22/03/2016 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function pre_update_option( $value, $option, $old_value ) { + + // bail ealry if no value + if ( empty( $value ) ) { + return $value; + } + + // loop over widgets + // WP saves all widgets (of the same type) as an array of widgets + foreach ( $value as $i => $widget ) { + + // bail ealry if no acf + if ( ! isset( $widget['acf'] ) ) { + continue; + } + + // remove widget + unset( $value[ $i ]['acf'] ); + + } + + // return + return $value; + + } + + + /* + * admin_footer + * + * This function will add some custom HTML to the footer of the edit page + * + * @type function + * @date 11/06/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function admin_footer() { + + ?> - \ No newline at end of file +?> diff --git a/includes/forms/form-front.php b/includes/forms/form-front.php index e8cec83..f385176 100644 --- a/includes/forms/form-front.php +++ b/includes/forms/form-front.php @@ -1,606 +1,601 @@ -fields = array( + + '_post_title' => array( + 'prefix' => 'acf', + 'name' => '_post_title', + 'key' => '_post_title', + 'label' => __( 'Title', 'acf' ), + 'type' => 'text', + 'required' => true, + ), + + '_post_content' => array( + 'prefix' => 'acf', + 'name' => '_post_content', + 'key' => '_post_content', + 'label' => __( 'Content', 'acf' ), + 'type' => 'wysiwyg', + ), + + '_validate_email' => array( + 'prefix' => 'acf', + 'name' => '_validate_email', + 'key' => '_validate_email', + 'label' => __( 'Validate Email', 'acf' ), + 'type' => 'text', + 'value' => '', + 'wrapper' => array( 'style' => 'display:none !important;' ), + ), + + ); + + // actions + add_action( 'acf/validate_save_post', array( $this, 'validate_save_post' ), 1 ); + + // filters + add_filter( 'acf/pre_save_post', array( $this, 'pre_save_post' ), 5, 2 ); -class acf_form_front { - - /** @var array An array of registered form settings */ - private $forms = array(); - - /** @var array An array of default fields */ - public $fields = array(); - - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // vars - $this->fields = array( - - '_post_title' => array( - 'prefix' => 'acf', - 'name' => '_post_title', - 'key' => '_post_title', - 'label' => __('Title', 'acf'), - 'type' => 'text', - 'required' => true, - ), - - '_post_content' => array( - 'prefix' => 'acf', - 'name' => '_post_content', - 'key' => '_post_content', - 'label' => __('Content', 'acf'), - 'type' => 'wysiwyg', - ), - - '_validate_email' => array( - 'prefix' => 'acf', - 'name' => '_validate_email', - 'key' => '_validate_email', - 'label' => __('Validate Email', 'acf'), - 'type' => 'text', - 'value' => '', - 'wrapper' => array('style' => 'display:none !important;') - ) - - ); - - - // actions - add_action('acf/validate_save_post', array($this, 'validate_save_post'), 1); - - - // filters - add_filter('acf/pre_save_post', array($this, 'pre_save_post'), 5, 2); - - } - - - /* - * validate_form - * - * description - * - * @type function - * @date 28/2/17 - * @since 5.5.8 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_form( $args ) { - - // defaults - // Todo: Allow message and button text to be generated by CPT settings. - $args = wp_parse_args( $args, array( - 'id' => 'acf-form', - 'post_id' => false, - 'new_post' => false, - 'field_groups' => false, - 'fields' => false, - 'post_title' => false, - 'post_content' => false, - 'form' => true, - 'form_attributes' => array(), - 'return' => add_query_arg( 'updated', 'true', acf_get_current_url() ), - 'html_before_fields' => '', - 'html_after_fields' => '', - 'submit_value' => __("Update", 'acf'), - 'updated_message' => __("Post updated", 'acf'), - 'label_placement' => 'top', - 'instruction_placement' => 'label', - 'field_el' => 'div', - 'uploader' => 'wp', - 'honeypot' => true, - 'html_updated_message' => '

                                %s

                                ', // 5.5.10 - 'html_submit_button' => '', // 5.5.10 - 'html_submit_spinner' => '', // 5.5.10 - 'kses' => true // 5.6.5 - )); - - $args['form_attributes'] = wp_parse_args( $args['form_attributes'], array( - 'id' => $args['id'], - 'class' => 'acf-form', - 'action' => '', - 'method' => 'post', - )); - - - // filter post_id - $args['post_id'] = acf_get_valid_post_id( $args['post_id'] ); - - - // new post? - if( $args['post_id'] === 'new_post' ) { - - $args['new_post'] = wp_parse_args( $args['new_post'], array( - 'post_type' => 'post', - 'post_status' => 'draft', - )); - } - - - // filter - $args = apply_filters('acf/validate_form', $args); - - - // return - return $args; - - } - - - /* - * add_form - * - * description - * - * @type function - * @date 28/2/17 - * @since 5.5.8 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function add_form( $args = array() ) { - - // validate - $args = $this->validate_form( $args ); - - - // append - $this->forms[ $args['id'] ] = $args; - - } - - - /* - * get_form - * - * description - * - * @type function - * @date 28/2/17 - * @since 5.5.8 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function get_form( $id = '' ) { - - // bail early if not set - if( !isset($this->forms[ $id ]) ) return false; - - - // return - return $this->forms[ $id ]; - - } - - - /* - * validate_save_post - * - * This function will validate fields from the above array - * - * @type function - * @date 7/09/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_save_post() { - - // register field if isset in $_POST - foreach( $this->fields as $k => $field ) { - - // bail early if no in $_POST - if( !isset($_POST['acf'][ $k ]) ) continue; - - - // register - acf_add_local_field($field); - + + + /* + * validate_form + * + * description + * + * @type function + * @date 28/2/17 + * @since 5.5.8 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_form( $args ) { + + // defaults + // Todo: Allow message and button text to be generated by CPT settings. + $args = wp_parse_args( + $args, + array( + 'id' => 'acf-form', + 'post_id' => false, + 'new_post' => false, + 'field_groups' => false, + 'fields' => false, + 'post_title' => false, + 'post_content' => false, + 'form' => true, + 'form_attributes' => array(), + 'return' => add_query_arg( 'updated', 'true', acf_get_current_url() ), + 'html_before_fields' => '', + 'html_after_fields' => '', + 'submit_value' => __( 'Update', 'acf' ), + 'updated_message' => __( 'Post updated', 'acf' ), + 'label_placement' => 'top', + 'instruction_placement' => 'label', + 'field_el' => 'div', + 'uploader' => 'wp', + 'honeypot' => true, + 'html_updated_message' => '

                                %s

                                ', // 5.5.10 + 'html_submit_button' => '', // 5.5.10 + 'html_submit_spinner' => '', // 5.5.10 + 'kses' => true, // 5.6.5 + ) + ); + + $args['form_attributes'] = wp_parse_args( + $args['form_attributes'], + array( + 'id' => $args['id'], + 'class' => 'acf-form', + 'action' => '', + 'method' => 'post', + ) + ); + + // filter post_id + $args['post_id'] = acf_get_valid_post_id( $args['post_id'] ); + + // new post? + if ( $args['post_id'] === 'new_post' ) { + + $args['new_post'] = wp_parse_args( + $args['new_post'], + array( + 'post_type' => 'post', + 'post_status' => 'draft', + ) + ); + + } + + // filter + $args = apply_filters( 'acf/validate_form', $args ); + + // return + return $args; + } - - - // honeypot - if( !empty($_POST['acf']['_validate_email']) ) { - - acf_add_validation_error( '', __('Spam Detected', 'acf') ); - - } - - } - - - /* - * pre_save_post - * - * description - * - * @type function - * @date 7/09/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function pre_save_post( $post_id, $form ) { - - // vars - $save = array( - 'ID' => 0 - ); - - - // determine save data - if( is_numeric($post_id) ) { - - // update post - $save['ID'] = $post_id; - - } elseif( $post_id == 'new_post' ) { - - // merge in new post data - $save = array_merge($save, $form['new_post']); - - } else { - - // not post - return $post_id; - - } - - - // save post_title - if( isset($_POST['acf']['_post_title']) ) { - - $save['post_title'] = acf_extract_var($_POST['acf'], '_post_title'); - - } - - - // save post_content - if( isset($_POST['acf']['_post_content']) ) { - - $save['post_content'] = acf_extract_var($_POST['acf'], '_post_content'); - - } - - - // honeypot - if( !empty($_POST['acf']['_validate_email']) ) return false; - - - // validate - if( count($save) == 1 ) { - - return $post_id; - - } - - - // save - if( $save['ID'] ) { - - wp_update_post( $save ); - - } else { - - $post_id = wp_insert_post( $save ); - - } - - - // return - return $post_id; - - } - - - /* - * enqueue - * - * This function will enqueue a form - * - * @type function - * @date 7/09/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function enqueue_form() { - - // check - $this->check_submit_form(); - - - // load acf scripts - acf_enqueue_scripts(); - - } - - - /* - * check_submit_form - * - * This function will maybe submit form data - * - * @type function - * @date 3/3/17 - * @since 5.5.10 - * - * @param n/a - * @return n/a - */ - - function check_submit_form() { - - // Verify nonce. - if( !acf_verify_nonce('acf_form') ) { - return false; - } - - // Confirm form was submit. - if( !isset($_POST['_acf_form']) ) { - return false; - } - - // Load registered form using id. - $form = $this->get_form( $_POST['_acf_form'] ); - - // Fallback to encrypted JSON. - if( !$form ) { - $form = json_decode( acf_decrypt($_POST['_acf_form']), true ); - if( !$form ) { - return false; - } - } - - // Run kses on all $_POST data. - if( $form['kses'] && isset($_POST['acf']) ) { - $_POST['acf'] = wp_kses_post_deep( $_POST['acf'] ); - } - - // Validate data and show errors. - // Todo: Return WP_Error and show above form, keeping input values. - acf_validate_save_post( true ); - - // Submit form. - $this->submit_form( $form ); - } - - - /* - * submit_form - * - * This function will submit form data - * - * @type function - * @date 3/3/17 - * @since 5.5.10 - * - * @param n/a - * @return n/a - */ - - function submit_form( $form ) { - - // filter - $form = apply_filters('acf/pre_submit_form', $form); - - - // vars - $post_id = acf_maybe_get($form, 'post_id', 0); - - - // add global for backwards compatibility - $GLOBALS['acf_form'] = $form; - - - // allow for custom save - $post_id = apply_filters('acf/pre_save_post', $post_id, $form); - - - // save - acf_save_post( $post_id ); - - - // restore form (potentially modified) - $form = $GLOBALS['acf_form']; - - - // action - do_action('acf/submit_form', $form, $post_id); - - - // vars - $return = acf_maybe_get($form, 'return', ''); - - - // redirect - if( $return ) { - - // update %placeholders% - $return = str_replace('%post_id%', $post_id, $return); - $return = str_replace('%post_url%', get_permalink($post_id), $return); - - - // redirect - wp_redirect( $return ); - exit; - - } - - } - - - /* - * render - * - * description - * - * @type function - * @date 7/09/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_form( $args = array() ) { - - // Vars. - $is_registered = false; - $field_groups = array(); - $fields = array(); - - // Allow form settings to be directly provided. - if( is_array($args) ) { + + + /* + * add_form + * + * description + * + * @type function + * @date 28/2/17 + * @since 5.5.8 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function add_form( $args = array() ) { + + // validate $args = $this->validate_form( $args ); - - // Otherwise, lookup registered form. - } else { - $is_registered = true; - $args = $this->get_form( $args ); - if( !$args ) { + + // append + $this->forms[ $args['id'] ] = $args; + + } + + + /* + * get_form + * + * description + * + * @type function + * @date 28/2/17 + * @since 5.5.8 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function get_form( $id = '' ) { + + // bail early if not set + if ( ! isset( $this->forms[ $id ] ) ) { return false; } + + // return + return $this->forms[ $id ]; + } - - // Extract vars. - $post_id = $args['post_id']; - - // Prevent ACF from loading values for "new_post". - if( $post_id === 'new_post' ) { - $post_id = false; - } - - // Set uploader type. - acf_update_setting('uploader', $args['uploader']); - - // Register local fields. - foreach( $this->fields as $k => $field ) { - acf_add_local_field($field); - } - - // Append post_title field. - if( $args['post_title'] ) { - $_post_title = acf_get_field('_post_title'); - $_post_title['value'] = $post_id ? get_post_field('post_title', $post_id) : ''; - $fields[] = $_post_title; - } - - // Append post_content field. - if( $args['post_content'] ) { - $_post_content = acf_get_field('_post_content'); - $_post_content['value'] = $post_id ? get_post_field('post_content', $post_id) : ''; - $fields[] = $_post_content; - } - - // Load specific fields. - if( $args['fields'] ) { - - // Lookup fields using $strict = false for better compatibility with field names. - foreach( $args['fields'] as $selector ) { - $fields[] = acf_maybe_get_field( $selector, $post_id, false ); + + + /* + * validate_save_post + * + * This function will validate fields from the above array + * + * @type function + * @date 7/09/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_save_post() { + + // register field if isset in $_POST + foreach ( $this->fields as $k => $field ) { + + // bail early if no in $_POST + if ( ! isset( $_POST['acf'][ $k ] ) ) { + continue; + } + + // register + acf_add_local_field( $field ); + } - - // Load specific field groups. - } elseif( $args['field_groups'] ) { - foreach( $args['field_groups'] as $selector ) { - $field_groups[] = acf_get_field_group( $selector ); + + // honeypot + if ( ! empty( $_POST['acf']['_validate_email'] ) ) { + + acf_add_validation_error( '', __( 'Spam Detected', 'acf' ) ); + } - - // Load fields for the given "new_post" args. - } elseif( $args['post_id'] == 'new_post' ) { - $field_groups = acf_get_field_groups( $args['new_post'] ); - - // Load fields for the given "post_id" arg. - } else { - $field_groups = acf_get_field_groups(array( - 'post_id' => $args['post_id'] - )); + } - - // load fields from the found field groups. - if( $field_groups ) { - foreach( $field_groups as $field_group ) { - $_fields = acf_get_fields( $field_group ); - if( $_fields ) { - foreach( $_fields as $_field ) { - $fields[] = $_field; + + + /* + * pre_save_post + * + * description + * + * @type function + * @date 7/09/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function pre_save_post( $post_id, $form ) { + + // vars + $save = array( + 'ID' => 0, + ); + + // determine save data + if ( is_numeric( $post_id ) ) { + + // update post + $save['ID'] = $post_id; + + } elseif ( $post_id == 'new_post' ) { + + // merge in new post data + $save = array_merge( $save, $form['new_post'] ); + + } else { + + // not post + return $post_id; + + } + + // save post_title + if ( isset( $_POST['acf']['_post_title'] ) ) { + + $save['post_title'] = acf_extract_var( $_POST['acf'], '_post_title' ); + + } + + // save post_content + if ( isset( $_POST['acf']['_post_content'] ) ) { + + $save['post_content'] = acf_extract_var( $_POST['acf'], '_post_content' ); + + } + + // honeypot + if ( ! empty( $_POST['acf']['_validate_email'] ) ) { + return false; + } + + // validate + if ( count( $save ) == 1 ) { + + return $post_id; + + } + + // save + if ( $save['ID'] ) { + + wp_update_post( $save ); + + } else { + + $post_id = wp_insert_post( $save ); + + } + + // return + return $post_id; + + } + + + /* + * enqueue + * + * This function will enqueue a form + * + * @type function + * @date 7/09/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function enqueue_form() { + + // check + $this->check_submit_form(); + + // load acf scripts + acf_enqueue_scripts(); + + } + + + /* + * check_submit_form + * + * This function will maybe submit form data + * + * @type function + * @date 3/3/17 + * @since 5.5.10 + * + * @param n/a + * @return n/a + */ + + function check_submit_form() { + + // Verify nonce. + if ( ! acf_verify_nonce( 'acf_form' ) ) { + return false; + } + + // Confirm form was submit. + if ( ! isset( $_POST['_acf_form'] ) ) { + return false; + } + + // Load registered form using id. + $form = $this->get_form( $_POST['_acf_form'] ); + + // Fallback to encrypted JSON. + if ( ! $form ) { + $form = json_decode( acf_decrypt( $_POST['_acf_form'] ), true ); + if ( ! $form ) { + return false; + } + } + + // Run kses on all $_POST data. + if ( $form['kses'] && isset( $_POST['acf'] ) ) { + $_POST['acf'] = wp_kses_post_deep( $_POST['acf'] ); + } + + // Validate data and show errors. + // Todo: Return WP_Error and show above form, keeping input values. + acf_validate_save_post( true ); + + // Submit form. + $this->submit_form( $form ); + } + + + /* + * submit_form + * + * This function will submit form data + * + * @type function + * @date 3/3/17 + * @since 5.5.10 + * + * @param n/a + * @return n/a + */ + + function submit_form( $form ) { + + // filter + $form = apply_filters( 'acf/pre_submit_form', $form ); + + // vars + $post_id = acf_maybe_get( $form, 'post_id', 0 ); + + // add global for backwards compatibility + $GLOBALS['acf_form'] = $form; + + // allow for custom save + $post_id = apply_filters( 'acf/pre_save_post', $post_id, $form ); + + // save + acf_save_post( $post_id ); + + // restore form (potentially modified) + $form = $GLOBALS['acf_form']; + + // action + do_action( 'acf/submit_form', $form, $post_id ); + + // vars + $return = acf_maybe_get( $form, 'return', '' ); + + // redirect + if ( $return ) { + + // update %placeholders% + $return = str_replace( '%post_id%', $post_id, $return ); + $return = str_replace( '%post_url%', get_permalink( $post_id ), $return ); + + // redirect + wp_redirect( $return ); + exit; + + } + + } + + + /* + * render + * + * description + * + * @type function + * @date 7/09/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_form( $args = array() ) { + + // Vars. + $is_registered = false; + $field_groups = array(); + $fields = array(); + + // Allow form settings to be directly provided. + if ( is_array( $args ) ) { + $args = $this->validate_form( $args ); + + // Otherwise, lookup registered form. + } else { + $is_registered = true; + $args = $this->get_form( $args ); + if ( ! $args ) { + return false; + } + } + + // Extract vars. + $post_id = $args['post_id']; + + // Prevent ACF from loading values for "new_post". + if ( $post_id === 'new_post' ) { + $post_id = false; + } + + // Set uploader type. + acf_update_setting( 'uploader', $args['uploader'] ); + + // Register local fields. + foreach ( $this->fields as $k => $field ) { + acf_add_local_field( $field ); + } + + // Append post_title field. + if ( $args['post_title'] ) { + $_post_title = acf_get_field( '_post_title' ); + $_post_title['value'] = $post_id ? get_post_field( 'post_title', $post_id ) : ''; + $fields[] = $_post_title; + } + + // Append post_content field. + if ( $args['post_content'] ) { + $_post_content = acf_get_field( '_post_content' ); + $_post_content['value'] = $post_id ? get_post_field( 'post_content', $post_id ) : ''; + $fields[] = $_post_content; + } + + // Load specific fields. + if ( $args['fields'] ) { + + // Lookup fields using $strict = false for better compatibility with field names. + foreach ( $args['fields'] as $selector ) { + $fields[] = acf_maybe_get_field( $selector, $post_id, false ); + } + + // Load specific field groups. + } elseif ( $args['field_groups'] ) { + foreach ( $args['field_groups'] as $selector ) { + $field_groups[] = acf_get_field_group( $selector ); + } + + // Load fields for the given "new_post" args. + } elseif ( $args['post_id'] == 'new_post' ) { + $field_groups = acf_get_field_groups( $args['new_post'] ); + + // Load fields for the given "post_id" arg. + } else { + $field_groups = acf_get_field_groups( + array( + 'post_id' => $args['post_id'], + ) + ); + } + + // load fields from the found field groups. + if ( $field_groups ) { + foreach ( $field_groups as $field_group ) { + $_fields = acf_get_fields( $field_group ); + if ( $_fields ) { + foreach ( $_fields as $_field ) { + $fields[] = $_field; + } } } } - } - - // Add honeypot field. - if( $args['honeypot'] ) { - $fields[] = acf_get_field('_validate_email'); - } - - // Display updated_message - if( !empty($_GET['updated']) && $args['updated_message'] ) { - printf( $args['html_updated_message'], $args['updated_message'] ); - } - - // display form - if( $args['form'] ): ?> + + // Add honeypot field. + if ( $args['honeypot'] ) { + $fields[] = acf_get_field( '_validate_email' ); + } + + // Display updated_message + if ( ! empty( $_GET['updated'] ) && $args['updated_message'] ) { + printf( $args['html_updated_message'], $args['updated_message'] ); + } + + // display form + if ( $args['form'] ) : ?>
                                > - 'acf_form', - 'post_id' => $args['post_id'], - 'form' => $is_registered ? $args['id'] : acf_encrypt(json_encode($args)) - )); - + acf_form_data( + array( + 'screen' => 'acf_form', + 'post_id' => $args['post_id'], + 'form' => $is_registered ? $args['id'] : acf_encrypt( json_encode( $args ) ), + ) + ); + ?> -
                                +
                                - +
                                form_front = new acf_form_front(); + } + + // initialize + acf()->form_front = new acf_form_front(); endif; // class_exists check @@ -610,37 +605,37 @@ endif; // class_exists check * * alias of acf()->form->functions * -* @type function -* @date 11/06/2014 -* @since 5.0.0 +* @type function +* @date 11/06/2014 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_form_head() { - + acf()->form_front->enqueue_form(); - + } function acf_form( $args = array() ) { - + acf()->form_front->render_form( $args ); - + } function acf_get_form( $id = '' ) { - + return acf()->form_front->get_form( $id ); - + } function acf_register_form( $args ) { - + acf()->form_front->add_form( $args ); - + } -?> \ No newline at end of file +?> diff --git a/includes/forms/form-gutenberg.php b/includes/forms/form-gutenberg.php index 7422409..3602b0f 100644 --- a/includes/forms/form-gutenberg.php +++ b/includes/forms/form-gutenberg.php @@ -1,177 +1,183 @@ edit_form_after_title(); - } - - /** - * filter_block_editor_meta_boxes - * - * description - * - * @date 5/4/19 - * @since 5.7.14 - * - * @param type $var Description. Default. - * @return type Description. - */ - function filter_block_editor_meta_boxes( $wp_meta_boxes ) { - - // Globals - global $current_screen; - - // Move 'acf_after_title' metaboxes into 'normal' location. - if( isset($wp_meta_boxes[ $current_screen->id ][ 'acf_after_title' ]) ) { - - // Extract locations. - $locations = $wp_meta_boxes[ $current_screen->id ]; - - // Ensure normal location exists. - if( !isset($locations['normal']) ) $locations['normal'] = array(); - if( !isset($locations['normal']['high']) ) $locations['normal']['high'] = array(); - - // Append metaboxes. - foreach( $locations['acf_after_title'] as $priority => $meta_boxes ) { - $locations['normal']['high'] = array_merge( $meta_boxes, $locations['normal']['high'] ); - } - - // Update original data. - $wp_meta_boxes[ $current_screen->id ] = $locations; - unset( $wp_meta_boxes[ $current_screen->id ]['acf_after_title'] ); - - // Avoid conflicts with saved metabox order. - add_filter( 'get_user_option_meta-box-order_' . $current_screen->id, array($this, 'modify_user_option_meta_box_order') ); - } - - // Return - return $wp_meta_boxes; - } - - /** - * modify_user_option_meta_box_order - * - * Filters the `meta-box-order_{$post_type}` value by prepending "acf_after_title" data to "normal". - * Fixes a bug where metaboxes with position "acf_after_title" do not appear in the block editor. - * - * @date 11/7/19 - * @since 5.8.2 - * - * @param array $stored_meta_box_order User's existing meta box order. - * @return array Modified array with meta boxes moved around. - */ - function modify_user_option_meta_box_order( $locations ) { - if( !empty($locations['acf_after_title']) ) { - if( !empty($locations['normal']) ) { - $locations['normal'] = $locations['acf_after_title'] . ',' . $locations['normal']; - } else { - $locations['normal'] = $locations['acf_after_title']; - } - unset($locations['acf_after_title']); - } - return $locations; - } - - /** - * acf_validate_save_post - * - * Ignore errors during the Gutenberg "save metaboxes" AJAX request. - * Allows data to save and prevent UX issues. - * - * @date 16/12/18 - * @since 5.8.0 - * - * @param void - * @return void - */ - function acf_validate_save_post() { - - // Check if current request came from Gutenberg. - if( isset($_GET['meta-box-loader']) ) { - acf_reset_validation_errors(); - } - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly. } -acf_new_instance('ACF_Form_Gutenberg'); +if ( ! class_exists( 'ACF_Form_Gutenberg' ) ) : + + class ACF_Form_Gutenberg { + + /** + * __construct + * + * Setup for class functionality. + * + * @date 13/12/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + + function __construct() { + + // Add actions. + add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); + + // Ignore validation during meta-box-loader AJAX request. + add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 999 ); + } + + /** + * enqueue_block_editor_assets + * + * Allows a safe way to customize Guten-only functionality. + * + * @date 14/12/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + function enqueue_block_editor_assets() { + + // Remove edit_form_after_title. + add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 20, 0 ); + + // Call edit_form_after_title manually. + add_action( 'block_editor_meta_box_hidden_fields', array( $this, 'block_editor_meta_box_hidden_fields' ) ); + + // Cusotmize editor metaboxes. + add_filter( 'filter_block_editor_meta_boxes', array( $this, 'filter_block_editor_meta_boxes' ) ); + } + + /** + * add_meta_boxes + * + * Modify screen for Gutenberg. + * + * @date 13/12/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + function add_meta_boxes() { + + // Remove 'edit_form_after_title' action. + remove_action( 'edit_form_after_title', array( acf_get_instance( 'ACF_Form_Post' ), 'edit_form_after_title' ) ); + } + + /** + * block_editor_meta_box_hidden_fields + * + * Modify screen for Gutenberg. + * + * @date 13/12/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + function block_editor_meta_box_hidden_fields() { + + // Manually call 'edit_form_after_title' function. + acf_get_instance( 'ACF_Form_Post' )->edit_form_after_title(); + } + + /** + * filter_block_editor_meta_boxes + * + * description + * + * @date 5/4/19 + * @since 5.7.14 + * + * @param type $var Description. Default. + * @return type Description. + */ + function filter_block_editor_meta_boxes( $wp_meta_boxes ) { + + // Globals + global $current_screen; + + // Move 'acf_after_title' metaboxes into 'normal' location. + if ( isset( $wp_meta_boxes[ $current_screen->id ]['acf_after_title'] ) ) { + + // Extract locations. + $locations = $wp_meta_boxes[ $current_screen->id ]; + + // Ensure normal location exists. + if ( ! isset( $locations['normal'] ) ) { + $locations['normal'] = array(); + } + if ( ! isset( $locations['normal']['high'] ) ) { + $locations['normal']['high'] = array(); + } + + // Append metaboxes. + foreach ( $locations['acf_after_title'] as $priority => $meta_boxes ) { + $locations['normal']['high'] = array_merge( $meta_boxes, $locations['normal']['high'] ); + } + + // Update original data. + $wp_meta_boxes[ $current_screen->id ] = $locations; + unset( $wp_meta_boxes[ $current_screen->id ]['acf_after_title'] ); + + // Avoid conflicts with saved metabox order. + add_filter( 'get_user_option_meta-box-order_' . $current_screen->id, array( $this, 'modify_user_option_meta_box_order' ) ); + } + + // Return + return $wp_meta_boxes; + } + + /** + * modify_user_option_meta_box_order + * + * Filters the `meta-box-order_{$post_type}` value by prepending "acf_after_title" data to "normal". + * Fixes a bug where metaboxes with position "acf_after_title" do not appear in the block editor. + * + * @date 11/7/19 + * @since 5.8.2 + * + * @param array $stored_meta_box_order User's existing meta box order. + * @return array Modified array with meta boxes moved around. + */ + function modify_user_option_meta_box_order( $locations ) { + if ( ! empty( $locations['acf_after_title'] ) ) { + if ( ! empty( $locations['normal'] ) ) { + $locations['normal'] = $locations['acf_after_title'] . ',' . $locations['normal']; + } else { + $locations['normal'] = $locations['acf_after_title']; + } + unset( $locations['acf_after_title'] ); + } + return $locations; + } + + /** + * acf_validate_save_post + * + * Ignore errors during the Gutenberg "save metaboxes" AJAX request. + * Allows data to save and prevent UX issues. + * + * @date 16/12/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + function acf_validate_save_post() { + + // Check if current request came from Gutenberg. + if ( isset( $_GET['meta-box-loader'] ) ) { + acf_reset_validation_errors(); + } + } + } + + acf_new_instance( 'ACF_Form_Gutenberg' ); endif; diff --git a/includes/forms/form-nav-menu.php b/includes/forms/form-nav-menu.php index 3f8130f..6659554 100644 --- a/includes/forms/form-nav-menu.php +++ b/includes/forms/form-nav-menu.php @@ -1,338 +1,345 @@ $item->type, - 'nav_menu_item_id' => $item_id, - 'nav_menu_item_depth' => $depth - )); - - // render - if( !empty($field_groups) ) { - - // open - echo '
                                '; - - // loop - foreach( $field_groups as $field_group ) { - - // load fields - $fields = acf_get_fields( $field_group ); - - // bail if not fields - if( empty($fields) ) continue; - - // change prefix - acf_prefix_fields( $fields, $prefix ); - - // render - acf_render_fields( $fields, $item_id, 'div', $field_group['instruction_placement'] ); + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // actions + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'wp_update_nav_menu', array( $this, 'update_nav_menu' ) ); + add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 ); + add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'wp_nav_menu_item_custom_fields' ), 10, 5 ); + + // filters + add_filter( 'wp_get_nav_menu_items', array( $this, 'wp_get_nav_menu_items' ), 10, 3 ); + add_filter( 'wp_edit_nav_menu_walker', array( $this, 'wp_edit_nav_menu_walker' ), 10, 2 ); + + } + + + /* + * admin_enqueue_scripts + * + * This action is run after post query but before any admin script / head actions. + * It is a good place to register all actions. + * + * @type action (admin_enqueue_scripts) + * @date 26/01/13 + * @since 3.6.0 + * + * @param N/A + * @return N/A + */ + + function admin_enqueue_scripts() { + + // validate screen + if ( ! acf_is_screen( 'nav-menus' ) ) { + return; } - - // close - echo '
                                '; - - // Trigger append for newly created menu item (via AJAX) - if( acf_is_ajax('add-menu-item') ): ?> + + // load acf scripts + acf_enqueue_scripts(); + + // actions + add_action( 'admin_footer', array( $this, 'admin_footer' ), 1 ); + + } + + + /** + * wp_nav_menu_item_custom_fields + * + * description + * + * @date 30/7/18 + * @since 5.6.9 + * + * @param type $var Description. Default. + * @return type Description. + */ + + function wp_nav_menu_item_custom_fields( $item_id, $item, $depth, $args, $id = '' ) { + + // vars + $prefix = "menu-item-acf[$item_id]"; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'nav_menu_item' => $item->type, + 'nav_menu_item_id' => $item_id, + 'nav_menu_item_depth' => $depth, + ) + ); + + // render + if ( ! empty( $field_groups ) ) { + + // open + echo '
                                '; + + // loop + foreach ( $field_groups as $field_group ) { + + // load fields + $fields = acf_get_fields( $field_group ); + + // bail if not fields + if ( empty( $fields ) ) { + continue; + } + + // change prefix + acf_prefix_fields( $fields, $prefix ); + + // render + acf_render_fields( $fields, $item_id, 'div', $field_group['instruction_placement'] ); + } + + // close + echo '
                                '; + + // Trigger append for newly created menu item (via AJAX) + if ( acf_is_ajax( 'add-menu-item' ) ) : ?> - update_nav_menu_items( $menu_id ); - - } - - - /* - * update_nav_menu_items - * - * description - * - * @type function - * @date 26/5/17 - * @since 5.6.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function update_nav_menu_items( $menu_id ) { - - // bail ealry if not set - if( empty($_POST['menu-item-acf']) ) return; - - - // loop - foreach( $_POST['menu-item-acf'] as $post_id => $values ) { - - acf_save_post( $post_id, $values ); - - } - - } - - - /** - * wp_get_nav_menu_items - * - * WordPress does not provide an easy way to find the current menu being edited. - * This function listens to when a menu's items are loaded and stores the menu. - * Needed on nav-menus.php page for new menu with no items - * - * @date 23/2/18 - * @since 5.6.9 - * - * @param type $var Description. Default. - * @return type Description. - */ - - function wp_get_nav_menu_items( $items, $menu, $args ) { - acf_set_data('nav_menu_id', $menu->term_id); - return $items; - } - - /** - * Called when WP renders a menu edit form. - * Used to set global data and customize the Walker class. - * - * @date 26/5/17 - * @since 5.6.0 - * - * @param string $class The walker class to use. Default 'Walker_Nav_Menu_Edit'. - * @param int $menu_id ID of the menu being rendered. - * @return string - */ - function wp_edit_nav_menu_walker( $class, $menu_id = 0 ) { - - // update data (needed for ajax location rules to work) - acf_set_data('nav_menu_id', $menu_id); - - // Use custom walker class to inject "wp_nav_menu_item_custom_fields" action prioir to WP 5.4. - if( acf_version_compare('wp', '<', '5.3.99') ) { - acf_include('includes/walkers/class-acf-walker-nav-menu-edit.php'); - return 'ACF_Walker_Nav_Menu_Edit'; - } - - // Return class. - return $class; - } - - - /* - * acf_validate_save_post - * - * This function will loop over $_POST data and validate - * - * @type action 'acf/validate_save_post' 5 - * @date 7/09/2016 - * @since 5.4.0 - * - * @param n/a - * @return n/a - */ - - function acf_validate_save_post() { - - // bail ealry if not set - if( empty($_POST['menu-item-acf']) ) return; - - - // loop - foreach( $_POST['menu-item-acf'] as $post_id => $values ) { - + + + /* + * update_nav_menu + * + * description + * + * @type function + * @date 26/5/17 + * @since 5.6.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function update_nav_menu( $menu_id ) { + // vars - $prefix = 'menu-item-acf['.$post_id.']'; - - - // validate - acf_validate_values( $values, $prefix ); - + $post_id = 'term_' . $menu_id; + + // verify and remove nonce + if ( ! acf_verify_nonce( 'nav_menu' ) ) { + return $menu_id; + } + + // validate and show errors + acf_validate_save_post( true ); + + // save + acf_save_post( $post_id ); + + // save nav menu items + $this->update_nav_menu_items( $menu_id ); + } - - } - - - /* - * admin_footer - * - * This function will add some custom HTML to the footer of the edit page - * - * @type function - * @date 11/06/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function admin_footer() { - - // vars - $nav_menu_id = acf_get_data('nav_menu_id'); - $post_id = 'term_' . $nav_menu_id; - - - // get field groups - $field_groups = acf_get_field_groups(array( - 'nav_menu' => $nav_menu_id - )); - -?> + + + /* + * update_nav_menu_items + * + * description + * + * @type function + * @date 26/5/17 + * @since 5.6.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function update_nav_menu_items( $menu_id ) { + + // bail ealry if not set + if ( empty( $_POST['menu-item-acf'] ) ) { + return; + } + + // loop + foreach ( $_POST['menu-item-acf'] as $post_id => $values ) { + + acf_save_post( $post_id, $values ); + + } + + } + + + /** + * wp_get_nav_menu_items + * + * WordPress does not provide an easy way to find the current menu being edited. + * This function listens to when a menu's items are loaded and stores the menu. + * Needed on nav-menus.php page for new menu with no items + * + * @date 23/2/18 + * @since 5.6.9 + * + * @param type $var Description. Default. + * @return type Description. + */ + + function wp_get_nav_menu_items( $items, $menu, $args ) { + acf_set_data( 'nav_menu_id', $menu->term_id ); + return $items; + } + + /** + * Called when WP renders a menu edit form. + * Used to set global data and customize the Walker class. + * + * @date 26/5/17 + * @since 5.6.0 + * + * @param string $class The walker class to use. Default 'Walker_Nav_Menu_Edit'. + * @param int $menu_id ID of the menu being rendered. + * @return string + */ + function wp_edit_nav_menu_walker( $class, $menu_id = 0 ) { + + // update data (needed for ajax location rules to work) + acf_set_data( 'nav_menu_id', $menu_id ); + + // Use custom walker class to inject "wp_nav_menu_item_custom_fields" action prioir to WP 5.4. + if ( acf_version_compare( 'wp', '<', '5.3.99' ) ) { + acf_include( 'includes/walkers/class-acf-walker-nav-menu-edit.php' ); + return 'ACF_Walker_Nav_Menu_Edit'; + } + + // Return class. + return $class; + } + + + /* + * acf_validate_save_post + * + * This function will loop over $_POST data and validate + * + * @type action 'acf/validate_save_post' 5 + * @date 7/09/2016 + * @since 5.4.0 + * + * @param n/a + * @return n/a + */ + + function acf_validate_save_post() { + + // bail ealry if not set + if ( empty( $_POST['menu-item-acf'] ) ) { + return; + } + + // loop + foreach ( $_POST['menu-item-acf'] as $post_id => $values ) { + + // vars + $prefix = 'menu-item-acf[' . $post_id . ']'; + + // validate + acf_validate_values( $values, $prefix ); + + } + + } + + + /* + * admin_footer + * + * This function will add some custom HTML to the footer of the edit page + * + * @type function + * @date 11/06/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function admin_footer() { + + // vars + $nav_menu_id = acf_get_data( 'nav_menu_id' ); + $post_id = 'term_' . $nav_menu_id; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'nav_menu' => $nav_menu_id, + ) + ); + + ?> - \ No newline at end of file +?> diff --git a/includes/forms/form-post.php b/includes/forms/form-post.php index d4328e9..597cc2a 100644 --- a/includes/forms/form-post.php +++ b/includes/forms/form-post.php @@ -1,329 +1,339 @@ true, - )); - - // actions - add_action('add_meta_boxes', array($this, 'add_meta_boxes'), 10, 2); - } - - /** - * add_meta_boxes - * - * Adds ACF metaboxes for the given $post_type and $post. - * - * @date 19/9/18 - * @since 5.7.6 - * - * @param string $post_type The post type. - * @param WP_Post $post The post being edited. - * @return void - */ - function add_meta_boxes( $post_type, $post ) { - - // Storage for localized postboxes. - $postboxes = array(); - - // Get field groups for this screen. - $field_groups = acf_get_field_groups(array( - 'post_id' => $post->ID, - 'post_type' => $post_type - )); - - // Loop over field groups. - if( $field_groups ) { - foreach( $field_groups as $field_group ) { - - // vars - $id = "acf-{$field_group['key']}"; // acf-group_123 - $title = $field_group['title']; // Group 1 - $context = $field_group['position']; // normal, side, acf_after_title - $priority = 'high'; // high, core, default, low - - // Reduce priority for sidebar metaboxes for best position. - if( $context == 'side' ) { - $priority = 'core'; - } - - /** - * Filters the metabox priority. - * - * @date 23/06/12 - * @since 3.1.8 - * - * @param string $priority The metabox priority (high, core, default, low). - * @param array $field_group The field group array. - */ - $priority = apply_filters('acf/input/meta_box_priority', $priority, $field_group); - - // Localize data - $postboxes[] = array( - 'id' => $id, - 'key' => $field_group['key'], - 'style' => $field_group['style'], - 'label' => $field_group['label_placement'], - 'edit' => acf_get_field_group_edit_link( $field_group['ID'] ) - ); - - // Add the meta box. - add_meta_box( $id, acf_esc_html( $title ), array($this, 'render_meta_box'), $post_type, $context, $priority, array('field_group' => $field_group) ); - - } - - // Set style from first field group. - $this->style = acf_get_field_group_style( $field_groups[0] ); - - // Localize postboxes. - acf_localize_data(array( - 'postboxes' => $postboxes - )); - } - - // remove postcustom metabox (removes expensive SQL query) - if( acf_get_setting('remove_wp_meta_box') ) { - remove_meta_box( 'postcustom', false, 'normal' ); - } - - // Add hidden input fields. - add_action('edit_form_after_title', array($this, 'edit_form_after_title')); - - /** - * Fires after metaboxes have been added. - * - * @date 13/12/18 - * @since 5.8.0 - * - * @param string $post_type The post type. - * @param WP_Post $post The post being edited. - * @param array $field_groups The field groups added. - */ - do_action('acf/add_meta_boxes', $post_type, $post, $field_groups); - } - - /** - * edit_form_after_title - * - * Called after the title adn before the content editor. - * - * @date 19/9/18 - * @since 5.7.6 - * - * @param void - * @return void - */ - function edit_form_after_title() { - - // globals - global $post, $wp_meta_boxes; - - // render post data - acf_form_data(array( - 'screen' => 'post', - 'post_id' => $post->ID - )); - - // render 'acf_after_title' metaboxes - do_meta_boxes( get_current_screen(), 'acf_after_title', $post ); - - // render dynamic field group style - echo ''; - } - - /** - * render_meta_box - * - * Renders the ACF metabox HTML. - * - * @date 19/9/18 - * @since 5.7.6 - * - * @param WP_Post $post The post being edited. - * @param array metabox The add_meta_box() args. - * @return void - */ - function render_meta_box( $post, $metabox ) { - - // vars - $id = $metabox['id']; - $field_group = $metabox['args']['field_group']; - - // Render fields. - $fields = acf_get_fields( $field_group ); - acf_render_fields( $fields, $post->ID, 'div', $field_group['instruction_placement'] ); - } - - /** - * wp_insert_post_empty_content - * - * Allows WP to insert a new post without title or post_content if ACF data exists. - * - * @date 16/07/2014 - * @since 5.0.1 - * - * @param bool $maybe_empty Whether the post should be considered "empty". - * @param array $postarr Array of post data. - * @return bool - */ - function wp_insert_post_empty_content( $maybe_empty, $postarr ) { - - // return false and allow insert if '_acf_changed' exists - if( $maybe_empty && acf_maybe_get_POST('_acf_changed') ) { - return false; - } - - // return - return $maybe_empty; - } - - /* - * allow_save_post - * - * Checks if the $post is allowed to be saved. - * Used to avoid triggering "acf/save_post" on dynamically created posts during save. - * - * @type function - * @date 26/06/2016 - * @since 5.3.8 - * - * @param WP_Post $post The post to check. - * @return bool - */ - function allow_save_post( $post ) { - - // vars - $allow = true; - - // restrict post types - $restrict = array( 'auto-draft', 'revision', 'acf-field', 'acf-field-group' ); - if( in_array($post->post_type, $restrict) ) { - $allow = false; - } - - // disallow if the $_POST ID value does not match the $post->ID - $form_post_id = (int) acf_maybe_get_POST('post_ID'); - if( $form_post_id && $form_post_id !== $post->ID ) { - $allow = false; - } - - // revision (preview) - if( $post->post_type == 'revision' ) { - - // allow if doing preview and this $post is a child of the $_POST ID - if( acf_maybe_get_POST('wp-preview') == 'dopreview' && $form_post_id === $post->post_parent) { - $allow = true; - } - } - - // return - return $allow; - } - - /* - * save_post - * - * Triggers during the 'save_post' action to save the $_POST data. - * - * @type function - * @date 23/06/12 - * @since 1.0.0 - * - * @param int $post_id The post ID - * @param WP_POST $post the post object. - * @return int - */ - - function save_post( $post_id, $post ) { - - // bail ealry if no allowed to save this post type - if( !$this->allow_save_post($post) ) { - return $post_id; - } - - // verify nonce - if( !acf_verify_nonce('post') ) { - return $post_id; - } - - // validate for published post (allow draft to save without validation) - if( $post->post_status == 'publish' ) { - - // bail early if validation fails - if( !acf_validate_save_post() ) { - return; - } - } - - // save - acf_save_post( $post_id ); - - // save revision - if( post_type_supports($post->post_type, 'revisions') ) { - acf_save_post_revision( $post_id ); - } - - // return - return $post_id; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -acf_new_instance('ACF_Form_Post'); +if ( ! class_exists( 'ACF_Form_Post' ) ) : + + class ACF_Form_Post { + + /** @var string The first field groups style CSS. */ + var $style = ''; + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function __construct() { + + // initialize on post edit screens + add_action( 'load-post.php', array( $this, 'initialize' ) ); + add_action( 'load-post-new.php', array( $this, 'initialize' ) ); + + // save + add_filter( 'wp_insert_post_empty_content', array( $this, 'wp_insert_post_empty_content' ), 10, 2 ); + add_action( 'save_post', array( $this, 'save_post' ), 10, 2 ); + } + + + /** + * initialize + * + * Sets up Form functionality. + * + * @date 19/9/18 + * @since 5.7.6 + * + * @param void + * @return void + */ + function initialize() { + + // globals + global $typenow; + + // restrict specific post types + $restricted = array( 'acf-field-group', 'attachment' ); + if ( in_array( $typenow, $restricted ) ) { + return; + } + + // enqueue scripts + acf_enqueue_scripts( + array( + 'uploader' => true, + ) + ); + + // actions + add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 ); + } + + /** + * add_meta_boxes + * + * Adds ACF metaboxes for the given $post_type and $post. + * + * @date 19/9/18 + * @since 5.7.6 + * + * @param string $post_type The post type. + * @param WP_Post $post The post being edited. + * @return void + */ + function add_meta_boxes( $post_type, $post ) { + + // Storage for localized postboxes. + $postboxes = array(); + + // Get field groups for this screen. + $field_groups = acf_get_field_groups( + array( + 'post_id' => $post->ID, + 'post_type' => $post_type, + ) + ); + + // Loop over field groups. + if ( $field_groups ) { + foreach ( $field_groups as $field_group ) { + + // vars + $id = "acf-{$field_group['key']}"; // acf-group_123 + $title = $field_group['title']; // Group 1 + $context = $field_group['position']; // normal, side, acf_after_title + $priority = 'high'; // high, core, default, low + + // Reduce priority for sidebar metaboxes for best position. + if ( $context == 'side' ) { + $priority = 'core'; + } + + /** + * Filters the metabox priority. + * + * @date 23/06/12 + * @since 3.1.8 + * + * @param string $priority The metabox priority (high, core, default, low). + * @param array $field_group The field group array. + */ + $priority = apply_filters( 'acf/input/meta_box_priority', $priority, $field_group ); + + // Localize data + $postboxes[] = array( + 'id' => $id, + 'key' => $field_group['key'], + 'style' => $field_group['style'], + 'label' => $field_group['label_placement'], + 'edit' => acf_get_field_group_edit_link( $field_group['ID'] ), + ); + + // Add the meta box. + add_meta_box( $id, acf_esc_html( $title ), array( $this, 'render_meta_box' ), $post_type, $context, $priority, array( 'field_group' => $field_group ) ); + + } + + // Set style from first field group. + $this->style = acf_get_field_group_style( $field_groups[0] ); + + // Localize postboxes. + acf_localize_data( + array( + 'postboxes' => $postboxes, + ) + ); + } + + // remove postcustom metabox (removes expensive SQL query) + if ( acf_get_setting( 'remove_wp_meta_box' ) ) { + remove_meta_box( 'postcustom', false, 'normal' ); + } + + // Add hidden input fields. + add_action( 'edit_form_after_title', array( $this, 'edit_form_after_title' ) ); + + /** + * Fires after metaboxes have been added. + * + * @date 13/12/18 + * @since 5.8.0 + * + * @param string $post_type The post type. + * @param WP_Post $post The post being edited. + * @param array $field_groups The field groups added. + */ + do_action( 'acf/add_meta_boxes', $post_type, $post, $field_groups ); + } + + /** + * edit_form_after_title + * + * Called after the title adn before the content editor. + * + * @date 19/9/18 + * @since 5.7.6 + * + * @param void + * @return void + */ + function edit_form_after_title() { + + // globals + global $post, $wp_meta_boxes; + + // render post data + acf_form_data( + array( + 'screen' => 'post', + 'post_id' => $post->ID, + ) + ); + + // render 'acf_after_title' metaboxes + do_meta_boxes( get_current_screen(), 'acf_after_title', $post ); + + // render dynamic field group style + echo ''; + } + + /** + * render_meta_box + * + * Renders the ACF metabox HTML. + * + * @date 19/9/18 + * @since 5.7.6 + * + * @param WP_Post $post The post being edited. + * @param array metabox The add_meta_box() args. + * @return void + */ + function render_meta_box( $post, $metabox ) { + + // vars + $id = $metabox['id']; + $field_group = $metabox['args']['field_group']; + + // Render fields. + $fields = acf_get_fields( $field_group ); + acf_render_fields( $fields, $post->ID, 'div', $field_group['instruction_placement'] ); + } + + /** + * wp_insert_post_empty_content + * + * Allows WP to insert a new post without title or post_content if ACF data exists. + * + * @date 16/07/2014 + * @since 5.0.1 + * + * @param bool $maybe_empty Whether the post should be considered "empty". + * @param array $postarr Array of post data. + * @return bool + */ + function wp_insert_post_empty_content( $maybe_empty, $postarr ) { + + // return false and allow insert if '_acf_changed' exists + if ( $maybe_empty && acf_maybe_get_POST( '_acf_changed' ) ) { + return false; + } + + // return + return $maybe_empty; + } + + /* + * allow_save_post + * + * Checks if the $post is allowed to be saved. + * Used to avoid triggering "acf/save_post" on dynamically created posts during save. + * + * @type function + * @date 26/06/2016 + * @since 5.3.8 + * + * @param WP_Post $post The post to check. + * @return bool + */ + function allow_save_post( $post ) { + + // vars + $allow = true; + + // restrict post types + $restrict = array( 'auto-draft', 'revision', 'acf-field', 'acf-field-group' ); + if ( in_array( $post->post_type, $restrict ) ) { + $allow = false; + } + + // disallow if the $_POST ID value does not match the $post->ID + $form_post_id = (int) acf_maybe_get_POST( 'post_ID' ); + if ( $form_post_id && $form_post_id !== $post->ID ) { + $allow = false; + } + + // revision (preview) + if ( $post->post_type == 'revision' ) { + + // allow if doing preview and this $post is a child of the $_POST ID + if ( acf_maybe_get_POST( 'wp-preview' ) == 'dopreview' && $form_post_id === $post->post_parent ) { + $allow = true; + } + } + + // return + return $allow; + } + + /* + * save_post + * + * Triggers during the 'save_post' action to save the $_POST data. + * + * @type function + * @date 23/06/12 + * @since 1.0.0 + * + * @param int $post_id The post ID + * @param WP_POST $post the post object. + * @return int + */ + + function save_post( $post_id, $post ) { + + // bail ealry if no allowed to save this post type + if ( ! $this->allow_save_post( $post ) ) { + return $post_id; + } + + // verify nonce + if ( ! acf_verify_nonce( 'post' ) ) { + return $post_id; + } + + // validate for published post (allow draft to save without validation) + if ( $post->post_status == 'publish' ) { + + // bail early if validation fails + if ( ! acf_validate_save_post() ) { + return; + } + } + + // save + acf_save_post( $post_id ); + + // save revision + if ( post_type_supports( $post->post_type, 'revisions' ) ) { + acf_save_post_revision( $post_id ); + } + + // return + return $post_id; + } + } + + acf_new_instance( 'ACF_Form_Post' ); endif; -?> \ No newline at end of file + diff --git a/includes/forms/form-taxonomy.php b/includes/forms/form-taxonomy.php index 3b511e9..48c5e45 100644 --- a/includes/forms/form-taxonomy.php +++ b/includes/forms/form-taxonomy.php @@ -5,249 +5,243 @@ * * All the logic for adding fields to taxonomy terms * -* @class acf_form_taxonomy -* @package ACF -* @subpackage Forms +* @class acf_form_taxonomy +* @package ACF +* @subpackage Forms */ -if( ! class_exists('acf_form_taxonomy') ) : +if ( ! class_exists( 'acf_form_taxonomy' ) ) : + + class acf_form_taxonomy { + + var $view = 'add'; + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // actions + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + + // save + add_action( 'create_term', array( $this, 'save_term' ), 10, 3 ); + add_action( 'edit_term', array( $this, 'save_term' ), 10, 3 ); + + // delete + add_action( 'delete_term', array( $this, 'delete_term' ), 10, 4 ); -class acf_form_taxonomy { - - var $view = 'add'; - - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // actions - add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); - - - // save - add_action('create_term', array($this, 'save_term'), 10, 3); - add_action('edit_term', array($this, 'save_term'), 10, 3); - - - // delete - add_action('delete_term', array($this, 'delete_term'), 10, 4); - - } - - - /* - * validate_page - * - * This function will check if the current page is for a post/page edit form - * - * @type function - * @date 23/06/12 - * @since 3.1.8 - * - * @param n/a - * @return (boolean) - */ - - function validate_page() { - - // global - global $pagenow; - - - // validate page - if( $pagenow === 'edit-tags.php' || $pagenow === 'term.php' ) { - - return true; - } - - - // return - return false; - } - - - /* - * admin_enqueue_scripts - * - * This action is run after post query but before any admin script / head actions. - * It is a good place to register all actions. - * - * @type action (admin_enqueue_scripts) - * @date 26/01/13 - * @since 3.6.0 - * - * @param N/A - * @return N/A - */ - - function admin_enqueue_scripts() { - - // validate page - if( !$this->validate_page() ) { - - return; - - } - - - // vars - $screen = get_current_screen(); - $taxonomy = $screen->taxonomy; - - - // load acf scripts - acf_enqueue_scripts(); - - - // actions - add_action('admin_footer', array($this, 'admin_footer'), 10, 1); - add_action("{$taxonomy}_add_form_fields", array($this, 'add_term'), 10, 1); - add_action("{$taxonomy}_edit_form", array($this, 'edit_term'), 10, 2); - - } - - - /* - * add_term - * - * description - * - * @type function - * @date 8/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function add_term( $taxonomy ) { - - // vars - $post_id = 'term_0'; - - - // update vars - $this->view = 'add'; - - - // get field groups - $field_groups = acf_get_field_groups(array( - 'taxonomy' => $taxonomy - )); - - - // render - if( !empty($field_groups) ) { - - // data - acf_form_data(array( - 'screen' => 'taxonomy', - 'post_id' => $post_id, - )); - - // wrap - echo '
                                '; - - // loop - foreach( $field_groups as $field_group ) { - $fields = acf_get_fields( $field_group ); - acf_render_fields( $fields, $post_id, 'div', 'field' ); + + + /* + * validate_page + * + * This function will check if the current page is for a post/page edit form + * + * @type function + * @date 23/06/12 + * @since 3.1.8 + * + * @param n/a + * @return (boolean) + */ + + function validate_page() { + + // global + global $pagenow; + + // validate page + if ( $pagenow === 'edit-tags.php' || $pagenow === 'term.php' ) { + + return true; + } - - // wrap - echo '
                                '; - + + // return + return false; } - - } - - - /* - * edit_term - * - * description - * - * @type function - * @date 8/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function edit_term( $term, $taxonomy ) { - - // vars - $post_id = 'term_' . $term->term_id; - - - // update vars - $this->view = 'edit'; - - - // get field groups - $field_groups = acf_get_field_groups(array( - 'taxonomy' => $taxonomy - )); - - - // render - if( !empty($field_groups) ) { - - acf_form_data(array( - 'screen' => 'taxonomy', - 'post_id' => $post_id, - )); - - foreach( $field_groups as $field_group ) { - - // title - if( $field_group['style'] == 'default' ) { - echo '

                                ' . $field_group['title'] . '

                                '; + + + /* + * admin_enqueue_scripts + * + * This action is run after post query but before any admin script / head actions. + * It is a good place to register all actions. + * + * @type action (admin_enqueue_scripts) + * @date 26/01/13 + * @since 3.6.0 + * + * @param N/A + * @return N/A + */ + + function admin_enqueue_scripts() { + + // validate page + if ( ! $this->validate_page() ) { + + return; + + } + + // vars + $screen = get_current_screen(); + $taxonomy = $screen->taxonomy; + + // load acf scripts + acf_enqueue_scripts(); + + // actions + add_action( 'admin_footer', array( $this, 'admin_footer' ), 10, 1 ); + add_action( "{$taxonomy}_add_form_fields", array( $this, 'add_term' ), 10, 1 ); + add_action( "{$taxonomy}_edit_form", array( $this, 'edit_term' ), 10, 2 ); + + } + + + /* + * add_term + * + * description + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function add_term( $taxonomy ) { + + // vars + $post_id = 'term_0'; + + // update vars + $this->view = 'add'; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'taxonomy' => $taxonomy, + ) + ); + + // render + if ( ! empty( $field_groups ) ) { + + // data + acf_form_data( + array( + 'screen' => 'taxonomy', + 'post_id' => $post_id, + ) + ); + + // wrap + echo '
                                '; + + // loop + foreach ( $field_groups as $field_group ) { + $fields = acf_get_fields( $field_group ); + acf_render_fields( $fields, $post_id, 'div', 'field' ); } - - // fields - echo ''; + + // wrap + echo ''; + + } + + } + + + /* + * edit_term + * + * description + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function edit_term( $term, $taxonomy ) { + + // vars + $post_id = 'term_' . $term->term_id; + + // update vars + $this->view = 'edit'; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'taxonomy' => $taxonomy, + ) + ); + + // render + if ( ! empty( $field_groups ) ) { + + acf_form_data( + array( + 'screen' => 'taxonomy', + 'post_id' => $post_id, + ) + ); + + foreach ( $field_groups as $field_group ) { + + // title + if ( $field_group['style'] == 'default' ) { + echo '

                                ' . $field_group['title'] . '

                                '; + } + + // fields + echo '
                                '; $fields = acf_get_fields( $field_group ); acf_render_fields( $fields, $post_id, 'tr', 'field' ); - echo '
                                '; - + echo ''; + + } } - + } - - } - - - /* - * admin_footer - * - * description - * - * @type function - * @date 27/03/2015 - * @since 5.1.5 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function admin_footer() { - -?> + + + /* + * admin_footer + * + * description + * + * @type function + * @date 27/03/2015 + * @since 5.1.5 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function admin_footer() { + + ?> -query($wpdb->prepare( - "DELETE FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s", - $search, - $_search - )); - - } - -} + query( + $wpdb->prepare( + "DELETE FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s", + $search, + $_search + ) + ); + + } + + } + + new acf_form_taxonomy(); endif; diff --git a/includes/forms/form-user.php b/includes/forms/form-user.php index 4596a94..6f322e2 100644 --- a/includes/forms/form-user.php +++ b/includes/forms/form-user.php @@ -1,274 +1,291 @@ - 'login' - )); - } - - - /* - * register_user - * - * Called during the user register form - * - * @type function - * @date 8/10/13 - * @since 5.0.0 - * - * @param void - * @return void - */ - - function render_register() { - - // render - $this->render(array( - 'user_id' => 0, - 'view' => 'register', - 'el' => 'div' - )); - } - - - /* - * render_edit - * - * Called during the user edit form - * - * @type function - * @date 8/10/13 - * @since 5.0.0 - * - * @param void - * @return void - */ - - function render_edit( $user ) { - - // add compatibility with front-end user profile edit forms such as bbPress - if( !is_admin() ) { + + + /** + * admin_enqueue_scripts + * + * Checks current screen and enqueues scripts + * + * @date 17/4/18 + * @since 5.6.9 + * + * @param void + * @return void + */ + + function admin_enqueue_scripts() { + + // bail early if not valid screen + if ( ! acf_is_screen( array( 'profile', 'user', 'user-edit' ) ) ) { + return; + } + + // enqueue acf_enqueue_scripts(); } - - // render - $this->render(array( - 'user_id' => $user->ID, - 'view' => 'edit', - 'el' => 'tr' - )); - } - - - /* - * user_new_form - * - * description - * - * @type function - * @date 8/10/13 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_new() { - - // Multisite uses a different 'user-new.php' form. Don't render fields here - if( is_multisite() ) { - return; + + + /** + * login_form_register + * + * Customizes and enqueues scripts + * + * @date 17/4/18 + * @since 5.6.9 + * + * @param void + * @return void + */ + + function login_form_register() { + + // customize action prefix so that "admin_head" = "login_head" + acf_enqueue_scripts( + array( + 'context' => 'login', + ) + ); } - - // render - $this->render(array( - 'user_id' => 0, - 'view' => 'add', - 'el' => 'tr' - )); - } - - - /* - * render - * - * This function will render ACF fields for a given $post_id parameter - * - * @type function - * @date 7/10/13 - * @since 5.0.0 - * - * @param $user_id (int) this can be set to 0 for a new user - * @param $user_form (string) used for location rule matching. edit | add | register - * @param $el (string) - * @return n/a - */ - - function render( $args = array() ) { - - // Allow $_POST data to persist across form submission attempts. - if( isset($_POST['acf']) ) { - add_filter('acf/pre_load_value', array($this, 'filter_pre_load_value'), 10, 3); - } - - // defaults - $args = wp_parse_args($args, array( - 'user_id' => 0, - 'view' => 'edit', - 'el' => 'tr', - )); - - // vars - $post_id = 'user_' . $args['user_id']; - - // get field groups - $field_groups = acf_get_field_groups(array( - 'user_id' => $args['user_id'] ? $args['user_id'] : 'new', - 'user_form' => $args['view'] - )); - - // bail early if no field groups - if( empty($field_groups) ) { - return; - } - - // form data - acf_form_data(array( - 'screen' => 'user', - 'post_id' => $post_id, - 'validation' => ($args['view'] == 'register') ? 0 : 1 - )); - - // elements - $before = ''; - $after = '
                                '; - - if( $args['el'] == 'div') { - $before = '
                                '; - $after = '
                                '; - } - - // loop - foreach( $field_groups as $field_group ) { - - // vars - $fields = acf_get_fields( $field_group ); - - // title - if( $field_group['style'] === 'default' ) { - echo '

                                ' . $field_group['title'] . '

                                '; - } - + + + /* + * register_user + * + * Called during the user register form + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + + function render_register() { + // render - echo $before; - acf_render_fields( $fields, $post_id, $args['el'], $field_group['instruction_placement'] ); - echo $after; + $this->render( + array( + 'user_id' => 0, + 'view' => 'register', + 'el' => 'div', + ) + ); } - - // actions - add_action('acf/input/admin_footer', array($this, 'admin_footer'), 10, 1); - } - - - /* - * admin_footer - * - * description - * - * @type function - * @date 27/03/2015 - * @since 5.1.5 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function admin_footer() { - - // script - ?> + + + /* + * render_edit + * + * Called during the user edit form + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + + function render_edit( $user ) { + + // add compatibility with front-end user profile edit forms such as bbPress + if ( ! is_admin() ) { + acf_enqueue_scripts(); + } + + // render + $this->render( + array( + 'user_id' => $user->ID, + 'view' => 'edit', + 'el' => 'tr', + ) + ); + } + + + /* + * user_new_form + * + * description + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_new() { + + // Multisite uses a different 'user-new.php' form. Don't render fields here + if ( is_multisite() ) { + return; + } + + // render + $this->render( + array( + 'user_id' => 0, + 'view' => 'add', + 'el' => 'tr', + ) + ); + } + + + /* + * render + * + * This function will render ACF fields for a given $post_id parameter + * + * @type function + * @date 7/10/13 + * @since 5.0.0 + * + * @param $user_id (int) this can be set to 0 for a new user + * @param $user_form (string) used for location rule matching. edit | add | register + * @param $el (string) + * @return n/a + */ + + function render( $args = array() ) { + + // Allow $_POST data to persist across form submission attempts. + if ( isset( $_POST['acf'] ) ) { + add_filter( 'acf/pre_load_value', array( $this, 'filter_pre_load_value' ), 10, 3 ); + } + + // defaults + $args = wp_parse_args( + $args, + array( + 'user_id' => 0, + 'view' => 'edit', + 'el' => 'tr', + ) + ); + + // vars + $post_id = 'user_' . $args['user_id']; + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'user_id' => $args['user_id'] ? $args['user_id'] : 'new', + 'user_form' => $args['view'], + ) + ); + + // bail early if no field groups + if ( empty( $field_groups ) ) { + return; + } + + // form data + acf_form_data( + array( + 'screen' => 'user', + 'post_id' => $post_id, + 'validation' => ( $args['view'] == 'register' ) ? 0 : 1, + ) + ); + + // elements + $before = ''; + $after = '
                                '; + + if ( $args['el'] == 'div' ) { + $before = '
                                '; + $after = '
                                '; + } + + // loop + foreach ( $field_groups as $field_group ) { + + // vars + $fields = acf_get_fields( $field_group ); + + // title + if ( $field_group['style'] === 'default' ) { + echo '

                                ' . $field_group['title'] . '

                                '; + } + + // render + echo $before; + acf_render_fields( $fields, $post_id, $args['el'], $field_group['instruction_placement'] ); + echo $after; + } + + // actions + add_action( 'acf/input/admin_footer', array( $this, 'admin_footer' ), 10, 1 ); + } + + + /* + * admin_footer + * + * description + * + * @type function + * @date 27/03/2015 + * @since 5.1.5 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function admin_footer() { + + // script + ?> -add( - acf_idify( $acf_error['input'] ), - acf_esc_html( acf_punctify( sprintf( __('Error: %s', 'acf'), $acf_error['message'] ) ) ) - ); + + + /* + * save_user + * + * description + * + * @type function + * @date 8/10/13 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function save_user( $user_id ) { + + // verify nonce + if ( ! acf_verify_nonce( 'user' ) ) { + return $user_id; + } + + // save + if ( acf_validate_save_post( true ) ) { + acf_save_post( "user_$user_id" ); } } - return $errors; - } - - /** - * filter_pre_load_value - * - * Checks if a $_POST value exists for this field to allow persistent values. - * - * @date 12/7/19 - * @since 5.8.2 - * - * @param null $null A null placeholder. - * @param (int|string) $post_id The post id. - * @param array $field The field array. - * @return mixed - */ - function filter_pre_load_value( $null, $post_id, $field ) { - $field_key = $field['key']; - if( isset( $_POST['acf'][ $field_key ] )) { - return $_POST['acf'][ $field_key ]; - } - return $null; - } -} -// instantiate -acf_new_instance('ACF_Form_User'); + /** + * filter_registration_errors + * + * Validates $_POST data and appends any errors to prevent new user registration. + * + * @date 12/7/19 + * @since 5.8.1 + * + * @param WP_Error $errors A WP_Error object containing any errors encountered during registration. + * @param string $sanitized_user_login User's username after it has been sanitized. + * @param string $user_email User's email. + * @return WP_Error + */ + function filter_registration_errors( $errors, $sanitized_user_login, $user_email ) { + if ( ! acf_validate_save_post() ) { + $acf_errors = acf_get_validation_errors(); + foreach ( $acf_errors as $acf_error ) { + $errors->add( + acf_idify( $acf_error['input'] ), + acf_esc_html( acf_punctify( sprintf( __( 'Error: %s', 'acf' ), $acf_error['message'] ) ) ) + ); + } + } + return $errors; + } + + /** + * filter_pre_load_value + * + * Checks if a $_POST value exists for this field to allow persistent values. + * + * @date 12/7/19 + * @since 5.8.2 + * + * @param null $null A null placeholder. + * @param (int|string) $post_id The post id. + * @param array $field The field array. + * @return mixed + */ + function filter_pre_load_value( $null, $post_id, $field ) { + $field_key = $field['key']; + if ( isset( $_POST['acf'][ $field_key ] ) ) { + return $_POST['acf'][ $field_key ]; + } + return $null; + } + } + + // instantiate + acf_new_instance( 'ACF_Form_User' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/includes/forms/form-widget.php b/includes/forms/form-widget.php index 489a7e8..f806a0c 100644 --- a/includes/forms/form-widget.php +++ b/includes/forms/form-widget.php @@ -5,197 +5,191 @@ * * All the logic for adding fields to widgets * -* @class acf_form_widget -* @package ACF -* @subpackage Forms +* @class acf_form_widget +* @package ACF +* @subpackage Forms */ -if( ! class_exists('acf_form_widget') ) : +if ( ! class_exists( 'acf_form_widget' ) ) : -class acf_form_widget { - - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // vars - $this->preview_values = array(); - $this->preview_reference = array(); - $this->preview_errors = array(); - - - // actions - add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); - add_action('in_widget_form', array($this, 'edit_widget'), 10, 3); - add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5); - - - // filters - add_filter('widget_update_callback', array($this, 'save_widget'), 10, 4); - - } - - - /* - * admin_enqueue_scripts - * - * This action is run after post query but before any admin script / head actions. - * It is a good place to register all actions. - * - * @type action (admin_enqueue_scripts) - * @date 26/01/13 - * @since 3.6.0 - * - * @param N/A - * @return N/A - */ - - function admin_enqueue_scripts() { - - // validate screen - if( acf_is_screen('widgets') || acf_is_screen('customize') ) { - - // valid - - } else { - - return; - - } - - - // load acf scripts - acf_enqueue_scripts(); - - - // actions - add_action('acf/input/admin_footer', array($this, 'admin_footer'), 1); + class acf_form_widget { + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // vars + $this->preview_values = array(); + $this->preview_reference = array(); + $this->preview_errors = array(); + + // actions + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'in_widget_form', array( $this, 'edit_widget' ), 10, 3 ); + add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 ); + + // filters + add_filter( 'widget_update_callback', array( $this, 'save_widget' ), 10, 4 ); - } - - - /* - * acf_validate_save_post - * - * This function will loop over $_POST data and validate - * - * @type action 'acf/validate_save_post' 5 - * @date 7/09/2016 - * @since 5.4.0 - * - * @param n/a - * @return n/a - */ - - function acf_validate_save_post() { - - // bail ealry if not widget - if( !isset($_POST['_acf_widget_id']) ) return; - - - // vars - $id = $_POST['_acf_widget_id']; - $number = $_POST['_acf_widget_number']; - $prefix = $_POST['_acf_widget_prefix']; - - - // validate - acf_validate_values( $_POST[ $id ][ $number ]['acf'], $prefix ); - - } - - - /* - * edit_widget - * - * This function will render the fields for a widget form - * - * @type function - * @date 11/06/2014 - * @since 5.0.0 - * - * @param $widget (object) - * @param $return (null) - * @param $instance (object) - * @return $post_id (int) - */ - - function edit_widget( $widget, $return, $instance ) { - - // vars - $post_id = 0; - $prefix = 'widget-' . $widget->id_base . '[' . $widget->number . '][acf]'; - - - // get id - if( $widget->number !== '__i__' ) { - - $post_id = "widget_{$widget->id}"; - } - - - // get field groups - $field_groups = acf_get_field_groups(array( - 'widget' => $widget->id_base - )); - - - // render - if( !empty($field_groups) ) { - - // render post data - acf_form_data(array( - 'screen' => 'widget', - 'post_id' => $post_id, - 'widget_id' => 'widget-' . $widget->id_base, - 'widget_number' => $widget->number, - 'widget_prefix' => $prefix - )); - - - // wrap - echo '
                                '; - - // loop - foreach( $field_groups as $field_group ) { - - // load fields - $fields = acf_get_fields( $field_group ); - - - // bail if not fields - if( empty($fields) ) continue; - - - // change prefix - acf_prefix_fields( $fields, $prefix ); - - - // render - acf_render_fields( $fields, $post_id, 'div', $field_group['instruction_placement'] ); - + + + /* + * admin_enqueue_scripts + * + * This action is run after post query but before any admin script / head actions. + * It is a good place to register all actions. + * + * @type action (admin_enqueue_scripts) + * @date 26/01/13 + * @since 3.6.0 + * + * @param N/A + * @return N/A + */ + + function admin_enqueue_scripts() { + + // validate screen + if ( acf_is_screen( 'widgets' ) || acf_is_screen( 'customize' ) ) { + + // valid + + } else { + + return; + } - - //wrap - echo '
                                '; - - - // jQuery selector looks odd, but is necessary due to WP adding an incremental number into the ID - // - not possible to find number via PHP parameters - if( $widget->updated ): ?> + + // load acf scripts + acf_enqueue_scripts(); + + // actions + add_action( 'acf/input/admin_footer', array( $this, 'admin_footer' ), 1 ); + + } + + + /* + * acf_validate_save_post + * + * This function will loop over $_POST data and validate + * + * @type action 'acf/validate_save_post' 5 + * @date 7/09/2016 + * @since 5.4.0 + * + * @param n/a + * @return n/a + */ + + function acf_validate_save_post() { + + // bail ealry if not widget + if ( ! isset( $_POST['_acf_widget_id'] ) ) { + return; + } + + // vars + $id = $_POST['_acf_widget_id']; + $number = $_POST['_acf_widget_number']; + $prefix = $_POST['_acf_widget_prefix']; + + // validate + acf_validate_values( $_POST[ $id ][ $number ]['acf'], $prefix ); + + } + + + /* + * edit_widget + * + * This function will render the fields for a widget form + * + * @type function + * @date 11/06/2014 + * @since 5.0.0 + * + * @param $widget (object) + * @param $return (null) + * @param $instance (object) + * @return $post_id (int) + */ + + function edit_widget( $widget, $return, $instance ) { + + // vars + $post_id = 0; + $prefix = 'widget-' . $widget->id_base . '[' . $widget->number . '][acf]'; + + // get id + if ( $widget->number !== '__i__' ) { + + $post_id = "widget_{$widget->id}"; + + } + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'widget' => $widget->id_base, + ) + ); + + // render + if ( ! empty( $field_groups ) ) { + + // render post data + acf_form_data( + array( + 'screen' => 'widget', + 'post_id' => $post_id, + 'widget_id' => 'widget-' . $widget->id_base, + 'widget_number' => $widget->number, + 'widget_prefix' => $prefix, + ) + ); + + // wrap + echo '
                                '; + + // loop + foreach ( $field_groups as $field_group ) { + + // load fields + $fields = acf_get_fields( $field_group ); + + // bail if not fields + if ( empty( $fields ) ) { + continue; + } + + // change prefix + acf_prefix_fields( $fields, $prefix ); + + // render + acf_render_fields( $fields, $post_id, 'div', $field_group['instruction_placement'] ); + + } + + // wrap + echo '
                                '; + + // jQuery selector looks odd, but is necessary due to WP adding an incremental number into the ID + // - not possible to find number via PHP parameters + if ( $widget->updated ) : ?> - id}", $new_instance['acf'] ); - - - // return - return $instance; - - } - - - /* - * admin_footer - * - * This function will add some custom HTML to the footer of the edit page - * - * @type function - * @date 11/06/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function admin_footer() { -?> + + + /* + * save_widget + * + * This function will hook into the widget update filter and save ACF data + * + * @type function + * @date 27/05/2015 + * @since 5.2.3 + * + * @param $instance (array) widget settings + * @param $new_instance (array) widget settings + * @param $old_instance (array) widget settings + * @param $widget (object) widget info + * @return $instance + */ + + function save_widget( $instance, $new_instance, $old_instance, $widget ) { + + // validate nonce if we're not a REST API request. + // the $_POST object is not available to us to validate if we're in a REST API call. + if ( ! ( function_exists( 'wp_is_json_request' ) && wp_is_json_request() ) ) { + if ( ! acf_verify_nonce( 'widget' ) ) { + return $instance; + } + } + + // bail early if not valid (!customize + acf values + nonce). + if ( isset( $_POST['wp_customize'] ) || ! isset( $new_instance['acf'] ) ) { + return $instance; + } + + // save + acf_save_post( "widget_{$widget->id}", $new_instance['acf'] ); + + // return + return $instance; + + } + + + /* + * admin_footer + * + * This function will add some custom HTML to the footer of the edit page + * + * @type function + * @date 11/06/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function admin_footer() { + ?> - 'az', // Azerbaijani (Turkey) - 'zh_HK' => 'zh_TW', // Chinese (Hong Kong) - 'nl_BE' => 'nl_NL', // Dutch (Belgium) - 'fr_BE' => 'fr_FR', // French (Belgium) - 'nn_NO' => 'nb_NO', // Norwegian (Nynorsk) - 'fa_AF' => 'fa_IR', // Persian (Afghanistan) - 'ru_UA' => 'ru_RU', // Russian (Ukraine) + 'az_TR' => 'az', // Azerbaijani (Turkey) + 'zh_HK' => 'zh_TW', // Chinese (Hong Kong) + 'nl_BE' => 'nl_NL', // Dutch (Belgium) + 'fr_BE' => 'fr_FR', // French (Belgium) + 'nn_NO' => 'nb_NO', // Norwegian (Nynorsk) + 'fa_AF' => 'fa_IR', // Persian (Afghanistan) + 'ru_UA' => 'ru_RU', // Russian (Ukraine) ); - if( isset($langs[ $locale ]) ) { + if ( isset( $langs[ $locale ] ) ) { $locale = $langs[ $locale ]; } - + /** * Filters the determined local. * - * @date 8/1/19 - * @since 5.7.10 + * @date 8/1/19 + * @since 5.7.10 * - * @param string $locale The local. + * @param string $locale The local. */ return apply_filters( 'acf/get_locale', $locale ); } @@ -97,54 +97,54 @@ function acf_get_locale() { * * Loads the plugin's translated strings similar to load_plugin_textdomain(). * - * @date 8/1/19 - * @since 5.7.10 + * @date 8/1/19 + * @since 5.7.10 * - * @param string $locale The plugin's current locale. - * @return void + * @param string $locale The plugin's current locale. + * @return void */ function acf_load_textdomain( $domain = 'acf' ) { - + /** * Filters a plugin's locale. * - * @date 8/1/19 - * @since 5.7.10 + * @date 8/1/19 + * @since 5.7.10 * - * @param string $locale The plugin's current locale. - * @param string $domain Text domain. Unique identifier for retrieving translated strings. + * @param string $locale The plugin's current locale. + * @param string $domain Text domain. Unique identifier for retrieving translated strings. */ $locale = apply_filters( 'plugin_locale', acf_get_locale(), $domain ); $mofile = $domain . '-' . $locale . '.mo'; - + // Try to load from the languages directory first. - if( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ) ) { + if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ) ) { return true; } - + // Load from plugin lang folder. return load_textdomain( $domain, acf_get_path( 'lang/' . $mofile ) ); } /** - * _acf_apply_language_cache_key - * - * Applies the current language to the cache key. - * - * @date 23/1/19 - * @since 5.7.11 - * - * @param string $key The cache key. - * @return string - */ + * _acf_apply_language_cache_key + * + * Applies the current language to the cache key. + * + * @date 23/1/19 + * @since 5.7.11 + * + * @param string $key The cache key. + * @return string + */ function _acf_apply_language_cache_key( $key ) { - + // Get current language. - $current_language = acf_get_setting('current_language'); - if( $current_language ) { + $current_language = acf_get_setting( 'current_language' ); + if ( $current_language ) { $key = "{$key}:{$current_language}"; } - + // Return key. return $key; } diff --git a/includes/legacy/legacy-locations.php b/includes/legacy/legacy-locations.php index dab321c..54b1412 100644 --- a/includes/legacy/legacy-locations.php +++ b/includes/legacy/legacy-locations.php @@ -1,70 +1,72 @@ -reset(); @@ -97,11 +97,11 @@ function acf_reset_local() { * * Returns all local field groups. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param void - * @return array + * @param void + * @return array */ function acf_get_local_field_groups() { return acf_get_local_store( 'groups' )->get(); @@ -112,11 +112,11 @@ function acf_get_local_field_groups() { * * description * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param type $var Description. Default. - * @return type Description. + * @param type $var Description. Default. + * @return type Description. */ function acf_have_local_field_groups() { return acf_get_local_store( 'groups' )->count() ? true : false; @@ -127,11 +127,11 @@ function acf_have_local_field_groups() { * * description * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param type $var Description. Default. - * @return type Description. + * @param type $var Description. Default. + * @return type Description. */ function acf_count_local_field_groups() { return acf_get_local_store( 'groups' )->count(); @@ -142,46 +142,49 @@ function acf_count_local_field_groups() { * * Adds a local field group. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param array $field_group The field group array. - * @return bool + * @param array $field_group The field group array. + * @return bool */ function acf_add_local_field_group( $field_group ) { - + // Apply default properties needed for import. - $field_group = wp_parse_args($field_group, array( - 'key' => '', - 'title' => '', - 'fields' => array(), - 'local' => 'php' - )); - + $field_group = wp_parse_args( + $field_group, + array( + 'key' => '', + 'title' => '', + 'fields' => array(), + 'local' => 'php', + ) + ); + // Generate key if only name is provided. - if( !$field_group['key'] ) { - $field_group['key'] = 'group_' . acf_slugify($field_group['title'], '_'); + if ( ! $field_group['key'] ) { + $field_group['key'] = 'group_' . acf_slugify( $field_group['title'], '_' ); } - + // Bail early if field group already exists. - if( acf_is_local_field_group($field_group['key']) ) { + if ( acf_is_local_field_group( $field_group['key'] ) ) { return false; } - + // Prepare field group for import (adds menu_order and parent properties to fields). $field_group = acf_prepare_field_group_for_import( $field_group ); - + // Extract fields from group. $fields = acf_extract_var( $field_group, 'fields' ); - + // Add to store acf_get_local_store( 'groups' )->set( $field_group['key'], $field_group ); - + // Add fields - if( $fields ) { + if ( $fields ) { acf_add_local_fields( $fields ); } - + // Return true on success. return true; } @@ -191,11 +194,11 @@ function acf_add_local_field_group( $field_group ) { * * See acf_add_local_field_group(). * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param array $field_group The field group array. - * @return void + * @param array $field_group The field group array. + * @return void */ function register_field_group( $field_group ) { acf_add_local_field_group( $field_group ); @@ -206,11 +209,11 @@ function register_field_group( $field_group ) { * * Removes a field group for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group key. - * @return bool + * @param string $key The field group key. + * @return bool */ function acf_remove_local_field_group( $key = '' ) { return acf_get_local_store( 'groups' )->remove( $key ); @@ -221,11 +224,11 @@ function acf_remove_local_field_group( $key = '' ) { * * Returns true if a field group exists for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group key. - * @return bool + * @param string $key The field group key. + * @return bool */ function acf_is_local_field_group( $key = '' ) { return acf_get_local_store( 'groups' )->has( $key ); @@ -236,11 +239,11 @@ function acf_is_local_field_group( $key = '' ) { * * Returns true if a field group exists for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group group key. - * @return bool + * @param string $key The field group group key. + * @return bool */ function acf_is_local_field_group_key( $key = '' ) { return acf_get_local_store( 'groups' )->is( $key ); @@ -251,11 +254,11 @@ function acf_is_local_field_group_key( $key = '' ) { * * Returns a field group for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group key. - * @return (array|null) + * @param string $key The field group key. + * @return (array|null) */ function acf_get_local_field_group( $key = '' ) { return acf_get_local_store( 'groups' )->get( $key ); @@ -266,19 +269,19 @@ function acf_get_local_field_group( $key = '' ) { * * Adds an array of local fields. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param array $fields An array of un prepared fields. - * @return array + * @param array $fields An array of un prepared fields. + * @return array */ function acf_add_local_fields( $fields = array() ) { - + // Prepare for import (allows parent fields to offer up children). $fields = acf_prepare_fields_for_import( $fields ); - + // Add each field. - foreach( $fields as $field ) { + foreach ( $fields as $field ) { acf_add_local_field( $field, true ); } } @@ -288,21 +291,23 @@ function acf_add_local_fields( $fields = array() ) { * * Returns all local fields for the given parent. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $parent The parent key. - * @return array + * @param string $parent The parent key. + * @return array */ function acf_get_local_fields( $parent = '' ) { - + // Return children - if( $parent ) { - return acf_get_local_store( 'fields' )->query(array( - 'parent' => $parent - )); - - // Return all. + if ( $parent ) { + return acf_get_local_store( 'fields' )->query( + array( + 'parent' => $parent, + ) + ); + + // Return all. } else { return acf_get_local_store( 'fields' )->get(); } @@ -313,14 +318,14 @@ function acf_get_local_fields( $parent = '' ) { * * Returns true if local fields exist. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $parent The parent key. - * @return bool + * @param string $parent The parent key. + * @return bool */ function acf_have_local_fields( $parent = '' ) { - return acf_get_local_fields($parent) ? true : false; + return acf_get_local_fields( $parent ) ? true : false; } /** @@ -328,14 +333,14 @@ function acf_have_local_fields( $parent = '' ) { * * Returns the number of local fields for the given parent. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $parent The parent key. - * @return int + * @param string $parent The parent key. + * @return int */ function acf_count_local_fields( $parent = '' ) { - return count( acf_get_local_fields($parent) ); + return count( acf_get_local_fields( $parent ) ); } /** @@ -343,47 +348,50 @@ function acf_count_local_fields( $parent = '' ) { * * Adds a local field. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param array $field The field array. - * @param bool $prepared Whether or not the field has already been prepared for import. - * @return void + * @param array $field The field array. + * @param bool $prepared Whether or not the field has already been prepared for import. + * @return void */ function acf_add_local_field( $field, $prepared = false ) { - + // Apply default properties needed for import. - $field = wp_parse_args($field, array( - 'key' => '', - 'name' => '', - 'type' => '', - 'parent' => '', - )); - + $field = wp_parse_args( + $field, + array( + 'key' => '', + 'name' => '', + 'type' => '', + 'parent' => '', + ) + ); + // Generate key if only name is provided. - if( !$field['key'] ) { + if ( ! $field['key'] ) { $field['key'] = 'field_' . $field['name']; } - + // If called directly, allow sub fields to be correctly prepared. - if( !$prepared ) { + if ( ! $prepared ) { return acf_add_local_fields( array( $field ) ); } - + // Extract attributes. - $key = $field['key']; + $key = $field['key']; $name = $field['name']; - + // Allow sub field to be added multipel times to different parents. $store = acf_get_local_store( 'fields' ); - if( $store->is($key) ) { - $old_key = _acf_generate_local_key( $store->get($key) ); + if ( $store->is( $key ) ) { + $old_key = _acf_generate_local_key( $store->get( $key ) ); $new_key = _acf_generate_local_key( $field ); - if( $old_key !== $new_key ) { + if ( $old_key !== $new_key ) { $key = $new_key; } } - + // Add field. $store->set( $key, $field )->alias( $key, $name ); } @@ -393,11 +401,11 @@ function acf_add_local_field( $field, $prepared = false ) { * * Generates a unique key based on the field's parent. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field key. - * @return bool + * @param string $key The field key. + * @return bool */ function _acf_generate_local_key( $field ) { return "{$field['key']}:{$field['parent']}"; @@ -408,11 +416,11 @@ function _acf_generate_local_key( $field ) { * * Removes a field for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field key. - * @return bool + * @param string $key The field key. + * @return bool */ function acf_remove_local_field( $key = '' ) { return acf_get_local_store( 'fields' )->remove( $key ); @@ -423,11 +431,11 @@ function acf_remove_local_field( $key = '' ) { * * Returns true if a field exists for the given key or name. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group key. - * @return bool + * @param string $key The field group key. + * @return bool */ function acf_is_local_field( $key = '' ) { return acf_get_local_store( 'fields' )->has( $key ); @@ -438,11 +446,11 @@ function acf_is_local_field( $key = '' ) { * * Returns true if a field exists for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group key. - * @return bool + * @param string $key The field group key. + * @return bool */ function acf_is_local_field_key( $key = '' ) { return acf_get_local_store( 'fields' )->is( $key ); @@ -453,11 +461,11 @@ function acf_is_local_field_key( $key = '' ) { * * Returns a field for the given key. * - * @date 22/1/19 - * @since 5.7.10 + * @date 22/1/19 + * @since 5.7.10 * - * @param string $key The field group key. - * @return (array|null) + * @param string $key The field group key. + * @return (array|null) */ function acf_get_local_field( $key = '' ) { return acf_get_local_store( 'fields' )->get( $key ); @@ -466,45 +474,51 @@ function acf_get_local_field( $key = '' ) { /** * _acf_apply_get_local_field_groups * - * Appends local field groups to the provided array. + * Appends local field groups to the provided array. * - * @date 23/1/19 - * @since 5.7.10 + * @date 23/1/19 + * @since 5.7.10 * - * @param array $field_groups An array of field groups. - * @return array + * @param array $field_groups An array of field groups. + * @return array */ function _acf_apply_get_local_field_groups( $groups = array() ) { - + // Get local groups $local = acf_get_local_field_groups(); - if( $local ) { - + if ( $local ) { + // Generate map of "index" => "key" data. - $map = wp_list_pluck($groups, 'key'); - + $map = wp_list_pluck( $groups, 'key' ); + // Loop over groups and update/append local. - foreach( $local as $group ) { - + foreach ( $local as $group ) { + // Get group allowing cache and filters to run. - //$group = acf_get_field_group( $group['key'] ); - + // $group = acf_get_field_group( $group['key'] ); + // Update. - $i = array_search($group['key'], $map); - if( $i !== false ) { - unset($group['ID']); - $groups[ $i ] = array_merge($groups[ $i ], $group); - - // Append + $i = array_search( $group['key'], $map ); + if ( $i !== false ) { + unset( $group['ID'] ); + $groups[ $i ] = array_merge( $groups[ $i ], $group ); + + // Append } else { $groups[] = acf_get_field_group( $group['key'] ); } } - + // Sort list via menu_order and title. - $groups = wp_list_sort( $groups, array('menu_order' => 'ASC', 'title' => 'ASC') ); + $groups = wp_list_sort( + $groups, + array( + 'menu_order' => 'ASC', + 'title' => 'ASC', + ) + ); } - + // Return groups. return $groups; } @@ -517,12 +531,12 @@ add_filter( 'acf/load_field_groups', '_acf_apply_get_local_field_groups', 20, 1 * * Returns true if is a local key. * - * @date 23/1/19 - * @since 5.7.10 + * @date 23/1/19 + * @since 5.7.10 * - * @param bool $bool The result. - * @param string $id The identifier. - * @return bool + * @param bool $bool The result. + * @param string $id The identifier. + * @return bool */ function _acf_apply_is_local_field_key( $bool, $id ) { return acf_is_local_field_key( $id ); @@ -536,12 +550,12 @@ add_filter( 'acf/is_field_key', '_acf_apply_is_local_field_key', 20, 2 ); * * Returns true if is a local key. * - * @date 23/1/19 - * @since 5.7.10 + * @date 23/1/19 + * @since 5.7.10 * - * @param bool $bool The result. - * @param string $id The identifier. - * @return bool + * @param bool $bool The result. + * @param string $id The identifier. + * @return bool */ function _acf_apply_is_local_field_group_key( $bool, $id ) { return acf_is_local_field_group_key( $id ); @@ -553,21 +567,21 @@ add_filter( 'acf/is_field_group_key', '_acf_apply_is_local_field_group_key', 20, /** * _acf_do_prepare_local_fields * - * Local fields that are added too early will not be correctly prepared by the field type class. + * Local fields that are added too early will not be correctly prepared by the field type class. * - * @date 23/1/19 - * @since 5.7.10 + * @date 23/1/19 + * @since 5.7.10 * - * @param void - * @return void + * @param void + * @return void */ function _acf_do_prepare_local_fields() { - + // Get fields. $fields = acf_get_local_fields(); - + // If fields have been registered early, re-add to correctly prepare them. - if( $fields ) { + if ( $fields ) { acf_add_local_fields( $fields ); } } @@ -575,4 +589,4 @@ function _acf_do_prepare_local_fields() { // Hook into action. add_action( 'acf/include_fields', '_acf_do_prepare_local_fields', 0, 1 ); -?> \ No newline at end of file + diff --git a/includes/local-json.php b/includes/local-json.php index 20b53ee..2c8962d 100644 --- a/includes/local-json.php +++ b/includes/local-json.php @@ -1,292 +1,294 @@ -is_enabled() ) { - return false; + class ACF_Local_JSON { + + /** + * The found JSON field group files. + * + * @since 5.9.0 + * @var array + */ + private $files = array(); + + /** + * Constructor. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + public function __construct() { + + // Update settings. + acf_update_setting( 'save_json', get_stylesheet_directory() . '/acf-json' ); + acf_append_setting( 'load_json', get_stylesheet_directory() . '/acf-json' ); + + // Add listeners. + add_action( 'acf/update_field_group', array( $this, 'update_field_group' ) ); + add_action( 'acf/untrash_field_group', array( $this, 'update_field_group' ) ); + add_action( 'acf/trash_field_group', array( $this, 'delete_field_group' ) ); + add_action( 'acf/delete_field_group', array( $this, 'delete_field_group' ) ); + + // Include fields. + add_action( 'acf/include_fields', array( $this, 'include_fields' ) ); } - - // Append fields. - $field_group['fields'] = acf_get_fields( $field_group ); - - // Save to file. - $this->save_file( $field_group['key'], $field_group ); - } - - /** - * Deletes a field group JSON file. - * - * @date 14/4/20 - * @since 5.9.0 - * - * @param array $field_group The field group. - * @return void - */ - public function delete_field_group( $field_group ) { - - // Bail early if disabled. - if( !$this->is_enabled() ) { - return false; + + /** + * Returns true if this component is enabled. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param void + * @return bool. + */ + public function is_enabled() { + return (bool) acf_get_setting( 'json' ); } - - // WP appends '__trashed' to end of 'key' (post_name). - $key = str_replace( '__trashed', '', $field_group['key'] ); - - // Delete file. - $this->delete_file( $key ); - } - - /** - * Includes all local JSON fields. - * - * @date 14/4/20 - * @since 5.9.0 - * - * @param void - * @return void - */ - public function include_fields() { - - // Bail early if disabled. - if( !$this->is_enabled() ) { - return false; + + /** + * Writes field group data to JSON file. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param array $field_group The field group. + * @return void + */ + public function update_field_group( $field_group ) { + + // Bail early if disabled. + if ( ! $this->is_enabled() ) { + return false; + } + + // Append fields. + $field_group['fields'] = acf_get_fields( $field_group ); + + // Save to file. + $this->save_file( $field_group['key'], $field_group ); } - - // Get load paths. - $files = $this->scan_field_groups(); - foreach( $files as $key => $file ) { - $json = json_decode( file_get_contents( $file ), true ); - $json['local'] = 'json'; - $json['local_file'] = $file; - acf_add_local_field_group( $json ); + + /** + * Deletes a field group JSON file. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param array $field_group The field group. + * @return void + */ + public function delete_field_group( $field_group ) { + + // Bail early if disabled. + if ( ! $this->is_enabled() ) { + return false; + } + + // WP appends '__trashed' to end of 'key' (post_name). + $key = str_replace( '__trashed', '', $field_group['key'] ); + + // Delete file. + $this->delete_file( $key ); } - } - - /** - * Scans for JSON field groups. - * - * @date 14/4/20 - * @since 5.9.0 - * - * @param void - * @return array - */ - function scan_field_groups() { - $json_files = array(); - - // Loop over "local_json" paths and parse JSON files. - $paths = (array) acf_get_setting( 'load_json' ); - foreach( $paths as $path ) { - if( is_dir( $path ) ) { - $files = scandir( $path ); - if( $files ) { - foreach( $files as $filename ) { - - // Ignore hidden files. - if( $filename[0] === '.' ) { - continue; + + /** + * Includes all local JSON fields. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + public function include_fields() { + + // Bail early if disabled. + if ( ! $this->is_enabled() ) { + return false; + } + + // Get load paths. + $files = $this->scan_field_groups(); + foreach ( $files as $key => $file ) { + $json = json_decode( file_get_contents( $file ), true ); + $json['local'] = 'json'; + $json['local_file'] = $file; + acf_add_local_field_group( $json ); + } + } + + /** + * Scans for JSON field groups. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param void + * @return array + */ + function scan_field_groups() { + $json_files = array(); + + // Loop over "local_json" paths and parse JSON files. + $paths = (array) acf_get_setting( 'load_json' ); + foreach ( $paths as $path ) { + if ( is_dir( $path ) ) { + $files = scandir( $path ); + if ( $files ) { + foreach ( $files as $filename ) { + + // Ignore hidden files. + if ( $filename[0] === '.' ) { + continue; + } + + // Ignore sub directories. + $file = untrailingslashit( $path ) . '/' . $filename; + if ( is_dir( $file ) ) { + continue; + } + + // Ignore non JSON files. + $ext = pathinfo( $filename, PATHINFO_EXTENSION ); + if ( $ext !== 'json' ) { + continue; + } + + // Read JSON data. + $json = json_decode( file_get_contents( $file ), true ); + if ( ! is_array( $json ) || ! isset( $json['key'] ) ) { + continue; + } + + // Append data. + $json_files[ $json['key'] ] = $file; } - - // Ignore sub directories. - $file = untrailingslashit( $path ) . '/' . $filename; - if( is_dir($file) ) { - continue; - } - - // Ignore non JSON files. - $ext = pathinfo( $filename, PATHINFO_EXTENSION ); - if( $ext !== 'json' ) { - continue; - } - - // Read JSON data. - $json = json_decode( file_get_contents( $file ), true ); - if( !is_array($json) || !isset($json['key']) ) { - continue; - } - - // Append data. - $json_files[ $json['key'] ] = $file; } } } + + // Store data and return. + $this->files = $json_files; + return $json_files; } - - // Store data and return. - $this->files = $json_files; - return $json_files; - } - - /** - * Returns an array of found JSON field group files. - * - * @date 14/4/20 - * @since 5.9.0 - * - * @param void - * @return array - */ - public function get_files() { - return $this->files; - } - - /** - * Saves a field group JSON file. - * - * @date 17/4/20 - * @since 5.9.0 - * - * @param string $key The field group key. - * @param array $field_group The field group. - * @return bool - */ - public function save_file( $key, $field_group ) { - $path = acf_get_setting( 'save_json' ); - $file = untrailingslashit( $path ) . '/' . $key . '.json'; - if( !is_writable($path) ) { + + /** + * Returns an array of found JSON field group files. + * + * @date 14/4/20 + * @since 5.9.0 + * + * @param void + * @return array + */ + public function get_files() { + return $this->files; + } + + /** + * Saves a field group JSON file. + * + * @date 17/4/20 + * @since 5.9.0 + * + * @param string $key The field group key. + * @param array $field_group The field group. + * @return bool + */ + public function save_file( $key, $field_group ) { + $path = acf_get_setting( 'save_json' ); + $file = untrailingslashit( $path ) . '/' . $key . '.json'; + if ( ! is_writable( $path ) ) { + return false; + } + + // Append modified time. + if ( $field_group['ID'] ) { + $field_group['modified'] = get_post_modified_time( 'U', true, $field_group['ID'] ); + } else { + $field_group['modified'] = strtotime( 'now' ); + } + + // Prepare for export. + $field_group = acf_prepare_field_group_for_export( $field_group ); + + // Save and return true if bytes were written. + $result = file_put_contents( $file, acf_json_encode( $field_group ) ); + return is_int( $result ); + } + + /** + * Deletes a field group JSON file. + * + * @date 17/4/20 + * @since 5.9.0 + * + * @param string $key The field group key. + * @return bool True on success. + */ + public function delete_file( $key ) { + $path = acf_get_setting( 'save_json' ); + $file = untrailingslashit( $path ) . '/' . $key . '.json'; + if ( is_readable( $file ) ) { + unlink( $file ); + return true; + } return false; } - - // Append modified time. - if( $field_group['ID'] ) { - $field_group['modified'] = get_post_modified_time( 'U', true, $field_group['ID'] ); - } else { - $field_group['modified'] = strtotime( 'now' ); + + /** + * Includes all local JSON files. + * + * @date 10/03/2014 + * @since 5.0.0 + * @deprecated 5.9.0 + * + * @param void + * @return void + */ + public function include_json_folders() { + _deprecated_function( __METHOD__, '5.9.0', 'ACF_Local_JSON::include_fields()' ); + $this->include_fields(); } - - // Prepare for export. - $field_group = acf_prepare_field_group_for_export( $field_group ); - - // Save and return true if bytes were written. - $result = file_put_contents( $file, acf_json_encode( $field_group ) ); - return is_int( $result ); - } - - /** - * Deletes a field group JSON file. - * - * @date 17/4/20 - * @since 5.9.0 - * - * @param string $key The field group key. - * @return bool True on success. - */ - public function delete_file( $key ) { - $path = acf_get_setting( 'save_json' ); - $file = untrailingslashit( $path ) . '/' . $key . '.json'; - if( is_readable($file) ) { - unlink( $file ); - return true; + + /** + * Includes local JSON files within a specific folder. + * + * @date 01/05/2017 + * @since 5.5.13 + * @deprecated 5.9.0 + * + * @param string $path The path to a specific JSON folder. + * @return void + */ + public function include_json_folder( $path = '' ) { + _deprecated_function( __METHOD__, '5.9.0' ); + // Do nothing. } - return false; } - /** - * Includes all local JSON files. - * - * @date 10/03/2014 - * @since 5.0.0 - * @deprecated 5.9.0 - * - * @param void - * @return void - */ - public function include_json_folders() { - _deprecated_function( __METHOD__, '5.9.0', 'ACF_Local_JSON::include_fields()' ); - $this->include_fields(); - } - - /** - * Includes local JSON files within a specific folder. - * - * @date 01/05/2017 - * @since 5.5.13 - * @deprecated 5.9.0 - * - * @param string $path The path to a specific JSON folder. - * @return void - */ - public function include_json_folder( $path = '' ) { - _deprecated_function( __METHOD__, '5.9.0' ); - // Do nothing. - } -} - -// Initialize. -acf_new_instance('ACF_Local_JSON'); + // Initialize. + acf_new_instance( 'ACF_Local_JSON' ); endif; // class_exists check /** * Returns an array of found JSON field group files. * - * @date 14/4/20 - * @since 5.9.0 + * @date 14/4/20 + * @since 5.9.0 * - * @param type $var Description. Default. - * @return type Description. + * @param type $var Description. Default. + * @return type Description. */ function acf_get_local_json_files() { return acf_get_instance( 'ACF_Local_JSON' )->get_files(); @@ -295,25 +297,25 @@ function acf_get_local_json_files() { /** * Saves a field group JSON file. * - * @date 5/12/2014 - * @since 5.1.5 + * @date 5/12/2014 + * @since 5.1.5 * - * @param array $field_group The field group. - * @return bool + * @param array $field_group The field group. + * @return bool */ function acf_write_json_field_group( $field_group ) { - return acf_get_instance( 'ACF_Local_JSON' )->save_file( $field_group['key'], $field_group ); + return acf_get_instance( 'ACF_Local_JSON' )->save_file( $field_group['key'], $field_group ); } /** * Deletes a field group JSON file. * - * @date 5/12/2014 - * @since 5.1.5 + * @date 5/12/2014 + * @since 5.1.5 * - * @param string $key The field group key. - * @return bool True on success. + * @param string $key The field group key. + * @return bool True on success. */ function acf_delete_json_field_group( $key ) { - return acf_get_instance( 'ACF_Local_JSON' )->delete_file( $key ); + return acf_get_instance( 'ACF_Local_JSON' )->delete_file( $key ); } diff --git a/includes/local-meta.php b/includes/local-meta.php old mode 100644 new mode 100755 index 657b88a..e175584 --- a/includes/local-meta.php +++ b/includes/local-meta.php @@ -1,225 +1,227 @@ is_request($meta) ) { - $meta = $this->capture( $meta, $post_id ); + class ACF_Local_Meta { + + /** @var array Storage for meta data. */ + var $meta = array(); + + /** @var mixed Storage for the current post_id. */ + var $post_id = 0; + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 8/10/18 + * @since 5.8.0 + * + * @param void + * @return void + */ + function __construct() { + + // add filters + add_filter( 'acf/pre_load_post_id', array( $this, 'pre_load_post_id' ), 1, 2 ); + add_filter( 'acf/pre_load_meta', array( $this, 'pre_load_meta' ), 1, 2 ); + add_filter( 'acf/pre_load_metadata', array( $this, 'pre_load_metadata' ), 1, 4 ); } - - // Add to storage. - $this->meta[ $post_id ] = $meta; - - // Set $post_id reference when is the "main" postmeta. - if( $is_main ) { - $this->post_id = $post_id; + + /** + * add + * + * Adds postmeta to storage. + * Accepts data in either raw or request format. + * + * @date 8/10/18 + * @since 5.8.0 + * + * @param array $meta An array of metdata to store. + * @param mixed $post_id The post_id for this data. + * @param bool $is_main Makes this postmeta visible to get_field() without a $post_id value. + * @return array + */ + function add( $meta = array(), $post_id = 0, $is_main = false ) { + + // Capture meta if supplied meta is from a REQUEST. + if ( $this->is_request( $meta ) ) { + $meta = $this->capture( $meta, $post_id ); + } + + // Add to storage. + $this->meta[ $post_id ] = $meta; + + // Set $post_id reference when is the "main" postmeta. + if ( $is_main ) { + $this->post_id = $post_id; + } + + // Return meta. + return $meta; } - - // Return meta. - return $meta; - } - - /** - * is_request - * - * Returns true if the supplied $meta is from a REQUEST (serialized
                                data). - * - * @date 11/3/19 - * @since 5.7.14 - * - * @param array $meta An array of metdata to check. - * @return bool - */ - function is_request( $meta = array() ) { - return acf_is_field_key( key( $meta ) ); - } - - /** - * capture - * - * Returns a flattened array of meta for the given postdata. - * This is achieved by simulating a save whilst capturing all meta changes. - * - * @date 26/2/19 - * @since 5.7.13 - * - * @param array $values An array of raw values. - * @param mixed $post_id The post_id for this data. - * @return array - */ - function capture( $values = array(), $post_id = 0 ) { - - // Reset meta. - $this->meta[ $post_id ] = array(); - - // Listen for any added meta. - add_filter('acf/pre_update_metadata', array($this, 'capture_update_metadata'), 1, 5); - - // Simulate update. - if( $values ) { - acf_update_values( $values, $post_id ); + + /** + * is_request + * + * Returns true if the supplied $meta is from a REQUEST (serialized data). + * + * @date 11/3/19 + * @since 5.7.14 + * + * @param array $meta An array of metdata to check. + * @return bool + */ + function is_request( $meta = array() ) { + return acf_is_field_key( key( $meta ) ); } - - // Remove listener filter. - remove_filter('acf/pre_update_metadata', array($this, 'capture_update_metadata'), 1, 5); - - // Return meta. - return $this->meta[ $post_id ]; - } - - /** - * capture_update_metadata - * - * Records all meta activity and returns a non null value to bypass DB updates. - * - * @date 26/2/19 - * @since 5.7.13 - * - * @param null $null . - * @param (int|string) $post_id The post id. - * @param string $name The meta name. - * @param mixed $value The meta value. - * @param bool $hidden If the meta is hidden (starts with an underscore). - * @return false. - */ - function capture_update_metadata( $null, $post_id, $name, $value, $hidden ) { - $name = ($hidden ? '_' : '') . $name; - $this->meta[ $post_id ][ $name ] = $value; - - // Return non null value to escape update process. - return true; - } - - /** - * remove - * - * Removes postmeta from storage. - * - * @date 8/10/18 - * @since 5.8.0 - * - * @param mixed $post_id The post_id for this data. - * @return void - */ - function remove( $post_id = 0 ) { - - // unset meta - unset( $this->meta[ $post_id ] ); - - // reset post_id - if( $post_id === $this->post_id ) { - $this->post_id = 0; - } - } - - /** - * pre_load_meta - * - * Injects the local meta. - * - * @date 8/10/18 - * @since 5.8.0 - * - * @param null $null An empty parameter. Return a non null value to short-circuit the function. - * @param mixed $post_id The post_id for this data. - * @return mixed - */ - function pre_load_meta( $null, $post_id ) { - if( isset($this->meta[ $post_id ]) ) { + + /** + * capture + * + * Returns a flattened array of meta for the given postdata. + * This is achieved by simulating a save whilst capturing all meta changes. + * + * @date 26/2/19 + * @since 5.7.13 + * + * @param array $values An array of raw values. + * @param mixed $post_id The post_id for this data. + * @return array + */ + function capture( $values = array(), $post_id = 0 ) { + + // Reset meta. + $this->meta[ $post_id ] = array(); + + // Listen for any added meta. + add_filter( 'acf/pre_update_metadata', array( $this, 'capture_update_metadata' ), 1, 5 ); + + // Simulate update. + if ( $values ) { + acf_update_values( $values, $post_id ); + } + + // Remove listener filter. + remove_filter( 'acf/pre_update_metadata', array( $this, 'capture_update_metadata' ), 1, 5 ); + + // Return meta. return $this->meta[ $post_id ]; } - return $null; - } - - /** - * pre_load_metadata - * - * Injects the local meta. - * - * @date 8/10/18 - * @since 5.8.0 - * - * @param null $null An empty parameter. Return a non null value to short-circuit the function. - * @param (int|string) $post_id The post id. - * @param string $name The meta name. - * @param bool $hidden If the meta is hidden (starts with an underscore). - * @return mixed - */ - function pre_load_metadata( $null, $post_id, $name, $hidden ) { - $name = ($hidden ? '_' : '') . $name; - if( isset($this->meta[ $post_id ]) ) { - if( isset($this->meta[ $post_id ][ $name ]) ) { - return $this->meta[ $post_id ][ $name ]; + + /** + * capture_update_metadata + * + * Records all meta activity and returns a non null value to bypass DB updates. + * + * @date 26/2/19 + * @since 5.7.13 + * + * @param null $null . + * @param (int|string) $post_id The post id. + * @param string $name The meta name. + * @param mixed $value The meta value. + * @param bool $hidden If the meta is hidden (starts with an underscore). + * @return false. + */ + function capture_update_metadata( $null, $post_id, $name, $value, $hidden ) { + $name = ( $hidden ? '_' : '' ) . $name; + $this->meta[ $post_id ][ $name ] = $value; + + // Return non null value to escape update process. + return true; + } + + /** + * remove + * + * Removes postmeta from storage. + * + * @date 8/10/18 + * @since 5.8.0 + * + * @param mixed $post_id The post_id for this data. + * @return void + */ + function remove( $post_id = 0 ) { + + // unset meta + unset( $this->meta[ $post_id ] ); + + // reset post_id + if ( $post_id === $this->post_id ) { + $this->post_id = 0; } - return '__return_null'; } - return $null; - } - - /** - * pre_load_post_id - * - * Injects the local post_id. - * - * @date 8/10/18 - * @since 5.8.0 - * - * @param null $null An empty parameter. Return a non null value to short-circuit the function. - * @param mixed $post_id The post_id for this data. - * @return mixed - */ - function pre_load_post_id( $null, $post_id ) { - if( !$post_id && $this->post_id ) { - return $this->post_id; + + /** + * pre_load_meta + * + * Injects the local meta. + * + * @date 8/10/18 + * @since 5.8.0 + * + * @param null $null An empty parameter. Return a non null value to short-circuit the function. + * @param mixed $post_id The post_id for this data. + * @return mixed + */ + function pre_load_meta( $null, $post_id ) { + if ( isset( $this->meta[ $post_id ] ) ) { + return $this->meta[ $post_id ]; + } + return $null; + } + + /** + * pre_load_metadata + * + * Injects the local meta. + * + * @date 8/10/18 + * @since 5.8.0 + * + * @param null $null An empty parameter. Return a non null value to short-circuit the function. + * @param (int|string) $post_id The post id. + * @param string $name The meta name. + * @param bool $hidden If the meta is hidden (starts with an underscore). + * @return mixed + */ + function pre_load_metadata( $null, $post_id, $name, $hidden ) { + $name = ( $hidden ? '_' : '' ) . $name; + if ( isset( $this->meta[ $post_id ] ) ) { + if ( isset( $this->meta[ $post_id ][ $name ] ) ) { + return $this->meta[ $post_id ][ $name ]; + } + return '__return_null'; + } + return $null; + } + + /** + * pre_load_post_id + * + * Injects the local post_id. + * + * @date 8/10/18 + * @since 5.8.0 + * + * @param null $null An empty parameter. Return a non null value to short-circuit the function. + * @param mixed $post_id The post_id for this data. + * @return mixed + */ + function pre_load_post_id( $null, $post_id ) { + if ( ! $post_id && $this->post_id ) { + return $this->post_id; + } + return $null; } - return $null; } -} endif; // class_exists check @@ -228,14 +230,14 @@ endif; // class_exists check * * Adds postmeta to storage. * - * @date 8/10/18 - * @since 5.8.0 - * @see ACF_Local_Meta::add() for list of parameters. + * @date 8/10/18 + * @since 5.8.0 + * @see ACF_Local_Meta::add() for list of parameters. * - * @return array + * @return array */ function acf_setup_meta( $meta = array(), $post_id = 0, $is_main = false ) { - return acf_get_instance('ACF_Local_Meta')->add( $meta, $post_id, $is_main ); + return acf_get_instance( 'ACF_Local_Meta' )->add( $meta, $post_id, $is_main ); } /** @@ -243,12 +245,12 @@ function acf_setup_meta( $meta = array(), $post_id = 0, $is_main = false ) { * * Removes postmeta to storage. * - * @date 8/10/18 - * @since 5.8.0 - * @see ACF_Local_Meta::remove() for list of parameters. + * @date 8/10/18 + * @since 5.8.0 + * @see ACF_Local_Meta::remove() for list of parameters. * - * @return void + * @return void */ function acf_reset_meta( $post_id = 0 ) { - return acf_get_instance('ACF_Local_Meta')->remove( $post_id ); + return acf_get_instance( 'ACF_Local_Meta' )->remove( $post_id ); } diff --git a/includes/locations.php b/includes/locations.php index 0d04e2d..5e2cf88 100644 --- a/includes/locations.php +++ b/includes/locations.php @@ -1,7 +1,9 @@ name; - + $name = $location_type->name; + // Check location type is unique. - if( $store->has( $name ) ) { + if ( $store->has( $name ) ) { $message = sprintf( __( 'Location type "%s" is already registered.' ), $name ); _doing_it_wrong( __FUNCTION__, $message, '5.9.0' ); return false; } - + // Add to store. $store->set( $name, $location_type ); - + /** * Fires after a location type is registered. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param string $name The location type name. - * @param ACF_Location $location_type The location type instance. + * @param string $name The location type name. + * @param ACF_Location $location_type The location type instance. */ do_action( 'acf/registered_location_type', $name, $location_type ); - + // Return location type instance. return $location_type; } @@ -57,11 +59,11 @@ function acf_register_location_type( $class_name ) { /** * Returns an array of all registered location types. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param void - * @return array + * @param void + * @return array */ function acf_get_location_types() { return acf_get_store( 'location-types' )->get(); @@ -70,11 +72,11 @@ function acf_get_location_types() { /** * Returns a location type for the given name. * - * @date 18/2/19 - * @since 5.7.12 + * @date 18/2/19 + * @since 5.7.12 * - * @param string $name The location type name. - * @return (ACF_Location|null) + * @param string $name The location type name. + * @return (ACF_Location|null) */ function acf_get_location_type( $name ) { return acf_get_store( 'location-types' )->get( $name ); @@ -83,49 +85,49 @@ function acf_get_location_type( $name ) { /** * Returns a grouped array of all location rule types. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param void - * @return array + * @param void + * @return array */ function acf_get_location_rule_types() { $types = array(); - + // Default categories. $categories = array( - 'post' => __('Post', 'acf'), - 'page' => __('Page', 'acf'), - 'user' => __('User', 'acf'), - 'forms' => __('Forms', 'acf'), + 'post' => __( 'Post', 'acf' ), + 'page' => __( 'Page', 'acf' ), + 'user' => __( 'User', 'acf' ), + 'forms' => __( 'Forms', 'acf' ), ); - + // Loop over all location types and append to $type. $location_types = acf_get_location_types(); - foreach( $location_types as $location_type ) { - + foreach ( $location_types as $location_type ) { + // Ignore if not public. - if( !$location_type->public ) { + if ( ! $location_type->public ) { continue; } - + // Find category label from category name. $category = $location_type->category; - if( isset($categories[ $category ]) ) { + if ( isset( $categories[ $category ] ) ) { $category = $categories[ $category ]; } - + // Append $types[ $category ][ $location_type->name ] = esc_html( $location_type->label ); } - + /** * Filters the location rule types. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param array $types The location rule types. + * @param array $types The location rule types. */ return apply_filters( 'acf/location/rule_types', $types ); } @@ -133,164 +135,170 @@ function acf_get_location_rule_types() { /** * Returns a validated location rule with all props. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param array $rule The location rule. - * @return array + * @param array $rule The location rule. + * @return array */ function acf_validate_location_rule( $rule = array() ) { - + // Apply defaults. - $rule = wp_parse_args($rule, array( - 'id' => '', - 'group' => '', - 'param' => '', - 'operator' => '==', - 'value' => '', - )); - + $rule = wp_parse_args( + $rule, + array( + 'id' => '', + 'group' => '', + 'param' => '', + 'operator' => '==', + 'value' => '', + ) + ); + /** * Filters the location rule to ensure is valid. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param array $rule The location rule. + * @param array $rule The location rule. */ $rule = apply_filters( "acf/location/validate_rule/type={$rule['param']}", $rule ); - $rule = apply_filters( "acf/location/validate_rule", $rule ); + $rule = apply_filters( 'acf/location/validate_rule', $rule ); return $rule; } /** * Returns an array of operators for a given rule. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $rule The location rule. - * @return array + * @param array $rule The location rule. + * @return array */ function acf_get_location_rule_operators( $rule ) { $operators = ACF_Location::get_operators( $rule ); - + // Get operators from location type since 5.9. $location_type = acf_get_location_type( $rule['param'] ); - if( $location_type ) { + if ( $location_type ) { $operators = $location_type->get_operators( $rule ); } - + /** * Filters the location rule operators. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $types The location rule operators. + * @param array $types The location rule operators. */ $operators = apply_filters( "acf/location/rule_operators/type={$rule['param']}", $operators, $rule ); $operators = apply_filters( "acf/location/rule_operators/{$rule['param']}", $operators, $rule ); - $operators = apply_filters( "acf/location/rule_operators", $operators, $rule ); + $operators = apply_filters( 'acf/location/rule_operators', $operators, $rule ); return $operators; } /** * Returns an array of values for a given rule. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $rule The location rule. - * @return array + * @param array $rule The location rule. + * @return array */ function acf_get_location_rule_values( $rule ) { $values = array(); - + // Get values from location type since 5.9. $location_type = acf_get_location_type( $rule['param'] ); - if( $location_type ) { + if ( $location_type ) { $values = $location_type->get_values( $rule ); } - + /** * Filters the location rule values. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $types The location rule values. + * @param array $types The location rule values. */ $values = apply_filters( "acf/location/rule_values/type={$rule['param']}", $values, $rule ); $values = apply_filters( "acf/location/rule_values/{$rule['param']}", $values, $rule ); - $values = apply_filters( "acf/location/rule_values", $values, $rule ); + $values = apply_filters( 'acf/location/rule_values', $values, $rule ); return $values; } /** * Returns true if the provided rule matches the screen args. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field The field group array. - * @return bool + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field The field group array. + * @return bool */ function acf_match_location_rule( $rule, $screen, $field_group ) { $result = false; - + // Get result from location type since 5.9. $location_type = acf_get_location_type( $rule['param'] ); - if( $location_type ) { + if ( $location_type ) { $result = $location_type->match( $rule, $screen, $field_group ); } - + /** * Filters the result. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param bool $result The match result. - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group array. + * @param bool $result The match result. + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group array. */ $result = apply_filters( "acf/location/match_rule/type={$rule['param']}", $result, $rule, $screen, $field_group ); - $result = apply_filters( "acf/location/match_rule", $result, $rule, $screen, $field_group ); + $result = apply_filters( 'acf/location/match_rule', $result, $rule, $screen, $field_group ); $result = apply_filters( "acf/location/rule_match/{$rule['param']}", $result, $rule, $screen, $field_group ); - $result = apply_filters( "acf/location/rule_match", $result, $rule, $screen, $field_group ); + $result = apply_filters( 'acf/location/rule_match', $result, $rule, $screen, $field_group ); return $result; } /** * Returns ann array of screen args to be used against matching rules. * - * @date 8/4/20 - * @since 5.9.0 + * @date 8/4/20 + * @since 5.9.0 * - * @param array $screen The screen args. - * @param array $deprecated The field group array. - * @return array + * @param array $screen The screen args. + * @param array $deprecated The field group array. + * @return array */ function acf_get_location_screen( $screen = array(), $deprecated = false ) { - + // Apply defaults. - $screen = wp_parse_args($screen, array( - 'lang' => acf_get_setting('current_language'), - 'ajax' => false - )); - + $screen = wp_parse_args( + $screen, + array( + 'lang' => acf_get_setting( 'current_language' ), + 'ajax' => false, + ) + ); + /** * Filters the result. * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $screen The screen args. - * @param array $deprecated The field group array. + * @param array $screen The screen args. + * @param array $deprecated The field group array. */ return apply_filters( 'acf/location/screen', $screen, $deprecated ); } @@ -298,11 +306,11 @@ function acf_get_location_screen( $screen = array(), $deprecated = false ) { /** * Alias of acf_register_location_type(). * - * @date 31/5/17 - * @since 5.6.0 + * @date 31/5/17 + * @since 5.6.0 * - * @param string $class_name The location class name. - * @return (ACF_Location|false) + * @param string $class_name The location class name. + * @return (ACF_Location|false) */ function acf_register_location_rule( $class_name ) { return acf_register_location_type( $class_name ); @@ -311,11 +319,11 @@ function acf_register_location_rule( $class_name ) { /** * Alias of acf_get_location_type(). * - * @date 31/5/17 - * @since 5.6.0 + * @date 31/5/17 + * @since 5.6.0 * - * @param string $class_name The location class name. - * @return (ACF_Location|false) + * @param string $class_name The location class name. + * @return (ACF_Location|false) */ function acf_get_location_rule( $name ) { return acf_get_location_type( $name ); @@ -324,11 +332,11 @@ function acf_get_location_rule( $name ) { /** * Alias of acf_validate_location_rule(). * - * @date 30/5/17 - * @since 5.6.0 + * @date 30/5/17 + * @since 5.6.0 * - * @param array $rule The location rule. - * @return array + * @param array $rule The location rule. + * @return array */ function acf_get_valid_location_rule( $rule ) { return acf_validate_location_rule( $rule ); diff --git a/includes/locations/abstract-acf-legacy-location.php b/includes/locations/abstract-acf-legacy-location.php index 5bad5d0..25743ec 100644 --- a/includes/locations/abstract-acf-legacy-location.php +++ b/includes/locations/abstract-acf-legacy-location.php @@ -1,62 +1,64 @@ -name}", array( $this, 'rule_match' ), 5, 3 ); - } - if( method_exists($this, 'rule_operators') ) { - add_filter( "acf/location/rule_operators/{$this->name}", array( $this, 'rule_operators' ), 5, 2 ); - } - if( method_exists($this, 'rule_values') ) { - add_filter( "acf/location/rule_values/{$this->name}", array( $this, 'rule_values' ), 5, 2 ); - } - } - - /** - * Magic __call method for backwards compatibility. - * - * @date 10/4/20 - * @since 5.9.0 - * - * @param string $name The method name. - * @param array $arguments The array of arguments. - * @return mixed - */ - public function __call( $name, $arguments ) { - - // Add backwards compatibility for legacy methods. - // - Combine 3x legacy filters cases together (remove first args). - switch( $name ) { - case 'rule_match': - $method = isset($method) ? $method : 'match'; - $arguments[3] = isset($arguments[3]) ? $arguments[3] : false; // Add $field_group param. - case 'rule_operators': - $method = isset($method) ? $method : 'get_operators'; - case 'rule_values': - $method = isset($method) ? $method : 'get_values'; - array_shift( $arguments ); - return call_user_func_array( array($this, $method), $arguments ); - case 'compare': - return call_user_func_array( array($this, 'compare_to_rule'), $arguments ); - } - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Legacy_Location' ) ) : + + abstract class ACF_Legacy_Location { + + /** + * Constructor. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function __construct() { + + // Add legacy method filters. + if ( method_exists( $this, 'rule_match' ) ) { + add_filter( "acf/location/rule_match/{$this->name}", array( $this, 'rule_match' ), 5, 3 ); + } + if ( method_exists( $this, 'rule_operators' ) ) { + add_filter( "acf/location/rule_operators/{$this->name}", array( $this, 'rule_operators' ), 5, 2 ); + } + if ( method_exists( $this, 'rule_values' ) ) { + add_filter( "acf/location/rule_values/{$this->name}", array( $this, 'rule_values' ), 5, 2 ); + } + } + + /** + * Magic __call method for backwards compatibility. + * + * @date 10/4/20 + * @since 5.9.0 + * + * @param string $name The method name. + * @param array $arguments The array of arguments. + * @return mixed + */ + public function __call( $name, $arguments ) { + + // Add backwards compatibility for legacy methods. + // - Combine 3x legacy filters cases together (remove first args). + switch ( $name ) { + case 'rule_match': + $method = isset( $method ) ? $method : 'match'; + $arguments[3] = isset( $arguments[3] ) ? $arguments[3] : false; // Add $field_group param. + case 'rule_operators': + $method = isset( $method ) ? $method : 'get_operators'; + case 'rule_values': + $method = isset( $method ) ? $method : 'get_values'; + array_shift( $arguments ); + return call_user_func_array( array( $this, $method ), $arguments ); + case 'compare': + return call_user_func_array( array( $this, 'compare_to_rule' ), $arguments ); + } + } + } + endif; // class_exists check diff --git a/includes/locations/abstract-acf-location.php b/includes/locations/abstract-acf-location.php index 653cb2a..8446fb1 100644 --- a/includes/locations/abstract-acf-location.php +++ b/includes/locations/abstract-acf-location.php @@ -1,188 +1,190 @@ -initialize(); - - // Call legacy constructor. - parent::__construct(); - } - - /** - * Initializes props. - * - * @date 5/03/2014 - * @since 5.0.0 - * - * @param void - * @return void - */ - public function initialize() { - // Set props here. - } - - /** - * Returns an array of operators for this location. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public static function get_operators( $rule ) { - return array( - '==' => __( "is equal to", 'acf' ), - '!=' => __( "is not equal to", 'acf' ) - ); - } - - /** - * Returns an array of possible values for this location. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array(); - } - - /** - * Returns the object_type connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string - */ - public function get_object_type( $rule ) { - return $this->object_type; - } - - /** - * Returns the object_subtype connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string|array - */ - public function get_object_subtype( $rule ) { - return $this->object_subtype; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - return false; - } - - /** - * Compares the given value and rule params returning true when they match. - * - * @date 17/9/19 - * @since 5.8.1 - * - * @param array $rule The location rule data. - * @param mixed $value The value to compare against. - * @return bool - */ - public function compare_to_rule( $value, $rule ) { - $result = ( $value == $rule['value'] ); - - // Allow "all" to match any value. - if( $rule['value'] === 'all' ) { - $result = true; - } - - // Reverse result for "!=" operator. - if( $rule['operator'] === '!=' ) { - return !$result; - } - return $result; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Location' ) ) : + + abstract class ACF_Location extends ACF_Legacy_Location { + + /** + * The location rule name. + * + * @since 5.9.0 + * @var string + */ + public $name = ''; + + /** + * The location rule label. + * + * @since 5.9.0 + * @var string + */ + public $label = ''; + + /** + * The location rule category. + * + * Accepts "post", "page", "user", "forms" or a custom label. + * + * @since 5.9.0 + * @var string + */ + public $category = 'post'; + + /** + * Whether or not the location rule is publicly accessible. + * + * @since 5.0.0 + * @var bool + */ + public $public = true; + + /** + * The object type related to this location rule. + * + * Accepts an object type discoverable by `acf_get_object_type()`. + * + * @since 5.9.0 + * @var string + */ + public $object_type = ''; + + /** + * The object subtype related to this location rule. + * + * Accepts a custom post type or custom taxonomy. + * + * @since 5.9.0 + * @var string + */ + public $object_subtype = ''; + + /** + * Constructor. + * + * @date 8/4/20 + * @since 5.9.0 + * + * @param void + * @return void + */ + public function __construct() { + $this->initialize(); + + // Call legacy constructor. + parent::__construct(); + } + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + // Set props here. + } + + /** + * Returns an array of operators for this location. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public static function get_operators( $rule ) { + return array( + '==' => __( 'is equal to', 'acf' ), + '!=' => __( 'is not equal to', 'acf' ), + ); + } + + /** + * Returns an array of possible values for this location. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array(); + } + + /** + * Returns the object_type connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string + */ + public function get_object_type( $rule ) { + return $this->object_type; + } + + /** + * Returns the object_subtype connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string|array + */ + public function get_object_subtype( $rule ) { + return $this->object_subtype; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + return false; + } + + /** + * Compares the given value and rule params returning true when they match. + * + * @date 17/9/19 + * @since 5.8.1 + * + * @param array $rule The location rule data. + * @param mixed $value The value to compare against. + * @return bool + */ + public function compare_to_rule( $value, $rule ) { + $result = ( $value == $rule['value'] ); + + // Allow "all" to match any value. + if ( $rule['value'] === 'all' ) { + $result = true; + } + + // Reverse result for "!=" operator. + if ( $rule['operator'] === '!=' ) { + return ! $result; + } + return $result; + } + } + endif; // class_exists check diff --git a/includes/locations/class-acf-location-attachment.php b/includes/locations/class-acf-location-attachment.php index 80bd06c..34ff671 100644 --- a/includes/locations/class-acf-location-attachment.php +++ b/includes/locations/class-acf-location-attachment.php @@ -1,94 +1,96 @@ -name = 'attachment'; - $this->label = __( "Attachment", 'acf' ); - $this->category = 'forms'; - $this->object_type = 'attachment'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['attachment']) ) { - $attachment = $screen['attachment']; - } else { - return false; - } - - // Get attachment mime type - $mime_type = get_post_mime_type( $attachment ); - - // Allow for unspecific mim_type matching such as "image" or "video". - if( !strpos($rule['value'], '/') ) { - - // Explode mime_type into bits ([0] => type, [1] => subtype) and match type. - $bits = explode( '/', $mime_type ); - if( $bits[0] === $rule['value'] ) { - $mime_type = $rule['value']; - } - } - return $this->compare_to_rule( $mime_type, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $choices = array( - 'all' => __('All', 'acf') - ); - - // Get mime types and append into optgroups. - $mime_types = get_allowed_mime_types(); - foreach( $mime_types as $regex => $mime_type ) { - - // Get type "image" from mime_type "image/jpeg". - $type = current( explode('/', $mime_type) ); - - // Append group and mimetype. - $choices[ $type ][ $type ] = sprintf( __('All %s formats', 'acf'), $type); - $choices[ $type ][ $mime_type ] = "$regex ($mime_type)"; - } - - // return - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Attachment' ); +if ( ! class_exists( 'ACF_Location_Attachment' ) ) : + + class ACF_Location_Attachment extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'attachment'; + $this->label = __( 'Attachment', 'acf' ); + $this->category = 'forms'; + $this->object_type = 'attachment'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['attachment'] ) ) { + $attachment = $screen['attachment']; + } else { + return false; + } + + // Get attachment mime type + $mime_type = get_post_mime_type( $attachment ); + + // Allow for unspecific mim_type matching such as "image" or "video". + if ( ! strpos( $rule['value'], '/' ) ) { + + // Explode mime_type into bits ([0] => type, [1] => subtype) and match type. + $bits = explode( '/', $mime_type ); + if ( $bits[0] === $rule['value'] ) { + $mime_type = $rule['value']; + } + } + return $this->compare_to_rule( $mime_type, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $choices = array( + 'all' => __( 'All', 'acf' ), + ); + + // Get mime types and append into optgroups. + $mime_types = get_allowed_mime_types(); + foreach ( $mime_types as $regex => $mime_type ) { + + // Get type "image" from mime_type "image/jpeg". + $type = current( explode( '/', $mime_type ) ); + + // Append group and mimetype. + $choices[ $type ][ $type ] = sprintf( __( 'All %s formats', 'acf' ), $type ); + $choices[ $type ][ $mime_type ] = "$regex ($mime_type)"; + } + + // return + return $choices; + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Attachment' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-comment.php b/includes/locations/class-acf-location-comment.php index 08f3e24..ac35e47 100644 --- a/includes/locations/class-acf-location-comment.php +++ b/includes/locations/class-acf-location-comment.php @@ -1,69 +1,71 @@ -name = 'comment'; - $this->label = __( "Comment", 'acf' ); - $this->category = 'forms'; - $this->object_type = 'comment'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['comment']) ) { - $comment = $screen['comment']; - } else { - return false; - } - return $this->compare_to_rule( $comment, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array_merge( - array( - 'all' => __('All', 'acf') - ), - acf_get_pretty_post_types() // Todo: Change to post types that support comments. - ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Comment' ); +if ( ! class_exists( 'ACF_Location_Comment' ) ) : -endif; // class_exists check \ No newline at end of file + class ACF_Location_Comment extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'comment'; + $this->label = __( 'Comment', 'acf' ); + $this->category = 'forms'; + $this->object_type = 'comment'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['comment'] ) ) { + $comment = $screen['comment']; + } else { + return false; + } + return $this->compare_to_rule( $comment, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array_merge( + array( + 'all' => __( 'All', 'acf' ), + ), + acf_get_pretty_post_types() // Todo: Change to post types that support comments. + ); + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Comment' ); + +endif; // class_exists check diff --git a/includes/locations/class-acf-location-current-user-role.php b/includes/locations/class-acf-location-current-user-role.php index 11a4208..d80ef0d 100644 --- a/includes/locations/class-acf-location-current-user-role.php +++ b/includes/locations/class-acf-location-current-user-role.php @@ -1,87 +1,89 @@ -name = 'current_user_role'; - $this->label = __( "Current User Role", 'acf' ); - $this->category = 'user'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Get current user. - $user = wp_get_current_user(); - if( !$user ) { - return false; - } - - // Check super_admin value. - if( $rule['value'] == 'super_admin' ) { - $result = is_super_admin( $user->ID ); - - // Check role. - } else { - $result = in_array( $rule['value'], $user->roles ); - } - - // Reverse result for "!=" operator. - if( $rule['operator'] === '!=' ) { - return !$result; - } - return $result; - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $choices = wp_roles()->get_names(); - - // Prepend Super Admin choice. - if( is_multisite() ) { - return array_merge( - array( - 'super_admin' => __( 'Super Admin', 'acf' ) - ), - $choices - ); - } - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Current_User_Role' ); +if ( ! class_exists( 'ACF_Location_Current_User_Role' ) ) : -endif; // class_exists check \ No newline at end of file + class ACF_Location_Current_User_Role extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'current_user_role'; + $this->label = __( 'Current User Role', 'acf' ); + $this->category = 'user'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Get current user. + $user = wp_get_current_user(); + if ( ! $user ) { + return false; + } + + // Check super_admin value. + if ( $rule['value'] == 'super_admin' ) { + $result = is_super_admin( $user->ID ); + + // Check role. + } else { + $result = in_array( $rule['value'], $user->roles ); + } + + // Reverse result for "!=" operator. + if ( $rule['operator'] === '!=' ) { + return ! $result; + } + return $result; + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $choices = wp_roles()->get_names(); + + // Prepend Super Admin choice. + if ( is_multisite() ) { + return array_merge( + array( + 'super_admin' => __( 'Super Admin', 'acf' ), + ), + $choices + ); + } + return $choices; + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Current_User_Role' ); + +endif; // class_exists check diff --git a/includes/locations/class-acf-location-current-user.php b/includes/locations/class-acf-location-current-user.php index 7bc72e2..ee523c7 100644 --- a/includes/locations/class-acf-location-current-user.php +++ b/includes/locations/class-acf-location-current-user.php @@ -1,79 +1,81 @@ -name = 'current_user'; - $this->label = __( "Current User", 'acf' ); - $this->category = 'user'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - switch( $rule['value'] ) { - case 'logged_in': - $result = is_user_logged_in(); - break; - case 'viewing_front': - $result = !is_admin(); - break; - case 'viewing_back': - $result = is_admin(); - break; - default: - $result = false; - break; - } - - // Reverse result for "!=" operator. - if( $rule['operator'] === '!=' ) { - return !$result; - } - return $result; - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array( - 'logged_in' => __( 'Logged in', 'acf' ), - 'viewing_front' => __( 'Viewing front end', 'acf' ), - 'viewing_back' => __( 'Viewing back end', 'acf' ) - ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Current_User' ); +if ( ! class_exists( 'ACF_Location_Current_User' ) ) : + + class ACF_Location_Current_User extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'current_user'; + $this->label = __( 'Current User', 'acf' ); + $this->category = 'user'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + switch ( $rule['value'] ) { + case 'logged_in': + $result = is_user_logged_in(); + break; + case 'viewing_front': + $result = ! is_admin(); + break; + case 'viewing_back': + $result = is_admin(); + break; + default: + $result = false; + break; + } + + // Reverse result for "!=" operator. + if ( $rule['operator'] === '!=' ) { + return ! $result; + } + return $result; + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array( + 'logged_in' => __( 'Logged in', 'acf' ), + 'viewing_front' => __( 'Viewing front end', 'acf' ), + 'viewing_back' => __( 'Viewing back end', 'acf' ), + ); + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Current_User' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-nav-menu-item.php b/includes/locations/class-acf-location-nav-menu-item.php index 03f25ab..deccde7 100644 --- a/includes/locations/class-acf-location-nav-menu-item.php +++ b/includes/locations/class-acf-location-nav-menu-item.php @@ -1,69 +1,71 @@ -name = 'nav_menu_item'; - $this->label = __( "Menu Item", 'acf' ); - $this->category = 'forms'; - $this->object_type = 'menu_item'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['nav_menu_item']) ) { - $nav_menu_item = $screen['nav_menu_item']; - } else { - return false; - } - - // Append "nav_menu" global data to $screen and call 'nav_menu' logic. - if( !isset($screen['nav_menu']) ) { - $screen['nav_menu'] = acf_get_data('nav_menu_id'); - } - return acf_get_location_type( 'nav_menu' )->match( $rule, $screen, $field_group ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return acf_get_location_type( 'nav_menu' )->get_values( $rule ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Nav_Menu_Item' ); +if ( ! class_exists( 'ACF_Location_Nav_Menu_Item' ) ) : + + class ACF_Location_Nav_Menu_Item extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'nav_menu_item'; + $this->label = __( 'Menu Item', 'acf' ); + $this->category = 'forms'; + $this->object_type = 'menu_item'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['nav_menu_item'] ) ) { + $nav_menu_item = $screen['nav_menu_item']; + } else { + return false; + } + + // Append "nav_menu" global data to $screen and call 'nav_menu' logic. + if ( ! isset( $screen['nav_menu'] ) ) { + $screen['nav_menu'] = acf_get_data( 'nav_menu_id' ); + } + return acf_get_location_type( 'nav_menu' )->match( $rule, $screen, $field_group ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return acf_get_location_type( 'nav_menu' )->get_values( $rule ); + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Nav_Menu_Item' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-nav-menu.php b/includes/locations/class-acf-location-nav-menu.php index 8050642..ed8422b 100644 --- a/includes/locations/class-acf-location-nav-menu.php +++ b/includes/locations/class-acf-location-nav-menu.php @@ -1,101 +1,103 @@ -name = 'nav_menu'; - $this->label = __( "Menu", 'acf' ); - $this->category = 'forms'; - $this->object_type = 'menu'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['nav_menu']) ) { - $nav_menu = $screen['nav_menu']; - } else { - return false; - } - - // Allow for "location/xxx" rule value. - $bits = explode('/', $rule['value']); - if( $bits[0] === 'location' ) { - $location = $bits[1]; - - // Get the map of menu locations [location => menu_id] and update $nav_menu to a location value. - $menu_locations = get_nav_menu_locations(); - if( isset($menu_locations[ $location ]) ) { - $rule['value'] = $menu_locations[ $location ]; - } - } - - // Compare rule against $nav_menu. - return $this->compare_to_rule( $nav_menu, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $choices = array( - 'all' => __( 'All', 'acf' ) - ); - - // Append locations. - $nav_locations = get_registered_nav_menus(); - if( $nav_locations ) { - $cat = __( 'Menu Locations', 'acf' ); - foreach( $nav_locations as $slug => $title ) { - $choices[ $cat ][ "location/$slug" ] = $title; - } - } - - // Append menu IDs. - $nav_menus = wp_get_nav_menus(); - if( $nav_menus ) { - $cat = __( 'Menus', 'acf' ); - foreach( $nav_menus as $nav_menu ) { - $choices[ $cat ][ $nav_menu->term_id ] = $nav_menu->name; - } - } - - // Return choices. - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Nav_Menu' ); +if ( ! class_exists( 'ACF_Location_Nav_Menu' ) ) : + + class ACF_Location_Nav_Menu extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'nav_menu'; + $this->label = __( 'Menu', 'acf' ); + $this->category = 'forms'; + $this->object_type = 'menu'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['nav_menu'] ) ) { + $nav_menu = $screen['nav_menu']; + } else { + return false; + } + + // Allow for "location/xxx" rule value. + $bits = explode( '/', $rule['value'] ); + if ( $bits[0] === 'location' ) { + $location = $bits[1]; + + // Get the map of menu locations [location => menu_id] and update $nav_menu to a location value. + $menu_locations = get_nav_menu_locations(); + if ( isset( $menu_locations[ $location ] ) ) { + $rule['value'] = $menu_locations[ $location ]; + } + } + + // Compare rule against $nav_menu. + return $this->compare_to_rule( $nav_menu, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $choices = array( + 'all' => __( 'All', 'acf' ), + ); + + // Append locations. + $nav_locations = get_registered_nav_menus(); + if ( $nav_locations ) { + $cat = __( 'Menu Locations', 'acf' ); + foreach ( $nav_locations as $slug => $title ) { + $choices[ $cat ][ "location/$slug" ] = $title; + } + } + + // Append menu IDs. + $nav_menus = wp_get_nav_menus(); + if ( $nav_menus ) { + $cat = __( 'Menus', 'acf' ); + foreach ( $nav_menus as $nav_menu ) { + $choices[ $cat ][ $nav_menu->term_id ] = $nav_menu->name; + } + } + + // Return choices. + return $choices; + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Nav_Menu' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-page-parent.php b/includes/locations/class-acf-location-page-parent.php index dbbc00e..143d6c5 100644 --- a/includes/locations/class-acf-location-page-parent.php +++ b/includes/locations/class-acf-location-page-parent.php @@ -1,70 +1,72 @@ -name = 'page_parent'; - $this->label = __( "Page Parent", 'acf' ); - $this->category = 'page'; - $this->object_type = 'post'; - $this->object_subtype = 'page'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['page_parent']) ) { - $page_parent = $screen['page_parent']; - } elseif( isset($screen['post_id']) ) { - $post = get_post( $screen['post_id'] ); - $page_parent = $post ? $post->post_parent : false; - } else { - return false; - } - - // Compare rule against $page_parent. - return $this->compare_to_rule( $page_parent, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return acf_get_location_type( 'page' )->get_values( $rule ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Page_Parent' ); +if ( ! class_exists( 'ACF_Location_Page_Parent' ) ) : + + class ACF_Location_Page_Parent extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'page_parent'; + $this->label = __( 'Page Parent', 'acf' ); + $this->category = 'page'; + $this->object_type = 'post'; + $this->object_subtype = 'page'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['page_parent'] ) ) { + $page_parent = $screen['page_parent']; + } elseif ( isset( $screen['post_id'] ) ) { + $post = get_post( $screen['post_id'] ); + $page_parent = $post ? $post->post_parent : false; + } else { + return false; + } + + // Compare rule against $page_parent. + return $this->compare_to_rule( $page_parent, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return acf_get_location_type( 'page' )->get_values( $rule ); + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Page_Parent' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-page-template.php b/includes/locations/class-acf-location-page-template.php index 9953e93..25fa876 100644 --- a/includes/locations/class-acf-location-page-template.php +++ b/includes/locations/class-acf-location-page-template.php @@ -1,81 +1,83 @@ -name = 'page_template'; - $this->label = __( "Page Template", 'acf' ); - $this->category = 'page'; - $this->object_type = 'post'; - $this->object_subtype = 'page'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_type']) ) { - $post_type = $screen['post_type']; - } elseif( isset($screen['post_id']) ) { - $post_type = get_post_type( $screen['post_id'] ); - } else { - return false; - } - - // Page templates were extended in WordPress version 4.7 for all post types. - // Prevent this rule (which is scoped to the "page" post type) appearing on all post types without a template selected (default template). - if( $rule['value'] === 'default' && $post_type !== 'page' ) { - return false; - } - - // Match rule using Post Template logic. - return acf_get_location_type( 'post_template' )->match( $rule, $screen, $field_group ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $post_templates = acf_get_post_templates(); - return array_merge( - array( - 'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') ) - ), - $post_templates[ 'page' ] - ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Page_Template' ); +if ( ! class_exists( 'ACF_Location_Page_Template' ) ) : + + class ACF_Location_Page_Template extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'page_template'; + $this->label = __( 'Page Template', 'acf' ); + $this->category = 'page'; + $this->object_type = 'post'; + $this->object_subtype = 'page'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_type'] ) ) { + $post_type = $screen['post_type']; + } elseif ( isset( $screen['post_id'] ) ) { + $post_type = get_post_type( $screen['post_id'] ); + } else { + return false; + } + + // Page templates were extended in WordPress version 4.7 for all post types. + // Prevent this rule (which is scoped to the "page" post type) appearing on all post types without a template selected (default template). + if ( $rule['value'] === 'default' && $post_type !== 'page' ) { + return false; + } + + // Match rule using Post Template logic. + return acf_get_location_type( 'post_template' )->match( $rule, $screen, $field_group ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $post_templates = acf_get_post_templates(); + return array_merge( + array( + 'default' => apply_filters( 'default_page_template_title', __( 'Default Template', 'acf' ) ), + ), + $post_templates['page'] + ); + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Page_Template' ); endif; // class_exists check. diff --git a/includes/locations/class-acf-location-page-type.php b/includes/locations/class-acf-location-page-type.php index bd9073a..6a6e392 100644 --- a/includes/locations/class-acf-location-page-type.php +++ b/includes/locations/class-acf-location-page-type.php @@ -1,118 +1,122 @@ -name = 'page_type'; - $this->label = __( "Page Type", 'acf' ); - $this->category = 'page'; - $this->object_type = 'post'; - $this->object_subtype = 'page'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_id']) ) { - $post_id = $screen['post_id']; - } else { - return false; - } - - // Get post. - $post = get_post( $post_id ); - if ( !$post ) { - return false; - } - - // Compare. - switch( $rule['value'] ) { - case 'front_page': - $front_page = (int) get_option('page_on_front'); - $result = ( $front_page === $post->ID ); - break; - - case 'posts_page': - $posts_page = (int) get_option('page_for_posts'); - $result = ( $posts_page === $post->ID ); - break; - - case 'top_level': - $page_parent = (int) ( isset($screen['page_parent']) ? $screen['page_parent'] : $post->post_parent ); - $result = ( $page_parent === 0 ); - break; - - case 'parent': - $children = get_posts(array( - 'post_type' => $post->post_type, - 'post_parent' => $post->ID, - 'posts_per_page' => 1, - 'fields' => 'ids', - )); - $result = !empty( $children ); - break; - - case 'child': - $page_parent = (int) ( isset($screen['page_parent']) ? $screen['page_parent'] : $post->post_parent ); - $result = ( $page_parent !== 0 ); - break; - - default: - return false; - } - - // Reverse result for "!=" operator. - if( $rule['operator'] === '!=' ) { - return !$result; - } - return $result; - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array( - 'front_page' => __("Front Page",'acf'), - 'posts_page' => __("Posts Page",'acf'), - 'top_level' => __("Top Level Page (no parent)",'acf'), - 'parent' => __("Parent Page (has children)",'acf'), - 'child' => __("Child Page (has parent)",'acf'), - ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Page_Type' ); +if ( ! class_exists( 'ACF_Location_Page_Type' ) ) : + + class ACF_Location_Page_Type extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'page_type'; + $this->label = __( 'Page Type', 'acf' ); + $this->category = 'page'; + $this->object_type = 'post'; + $this->object_subtype = 'page'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_id'] ) ) { + $post_id = $screen['post_id']; + } else { + return false; + } + + // Get post. + $post = get_post( $post_id ); + if ( ! $post ) { + return false; + } + + // Compare. + switch ( $rule['value'] ) { + case 'front_page': + $front_page = (int) get_option( 'page_on_front' ); + $result = ( $front_page === $post->ID ); + break; + + case 'posts_page': + $posts_page = (int) get_option( 'page_for_posts' ); + $result = ( $posts_page === $post->ID ); + break; + + case 'top_level': + $page_parent = (int) ( isset( $screen['page_parent'] ) ? $screen['page_parent'] : $post->post_parent ); + $result = ( $page_parent === 0 ); + break; + + case 'parent': + $children = get_posts( + array( + 'post_type' => $post->post_type, + 'post_parent' => $post->ID, + 'posts_per_page' => 1, + 'fields' => 'ids', + ) + ); + $result = ! empty( $children ); + break; + + case 'child': + $page_parent = (int) ( isset( $screen['page_parent'] ) ? $screen['page_parent'] : $post->post_parent ); + $result = ( $page_parent !== 0 ); + break; + + default: + return false; + } + + // Reverse result for "!=" operator. + if ( $rule['operator'] === '!=' ) { + return ! $result; + } + return $result; + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array( + 'front_page' => __( 'Front Page', 'acf' ), + 'posts_page' => __( 'Posts Page', 'acf' ), + 'top_level' => __( 'Top Level Page (no parent)', 'acf' ), + 'parent' => __( 'Parent Page (has children)', 'acf' ), + 'child' => __( 'Child Page (has parent)', 'acf' ), + ); + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Page_Type' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-page.php b/includes/locations/class-acf-location-page.php index c23e7fa..748b07e 100644 --- a/includes/locations/class-acf-location-page.php +++ b/includes/locations/class-acf-location-page.php @@ -1,74 +1,78 @@ -name = 'page'; - $this->label = __( "Page", 'acf' ); - $this->category = 'page'; - $this->object_type = 'post'; - $this->object_subtype = 'page'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - return acf_get_location_type( 'post' )->match( $rule, $screen, $field_group ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $choices = array(); - - // Get grouped posts. - $groups = acf_get_grouped_posts(array( - 'post_type' => array( 'page' ) - )); - - // Get first group. - $posts = reset( $groups ); - - // Append to choices. - if( $posts ) { - foreach( $posts as $post ) { - $choices[ $post->ID ] = acf_get_post_title( $post ); - } - } - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_Page' ); +if ( ! class_exists( 'ACF_Location_Page' ) ) : + + class ACF_Location_Page extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'page'; + $this->label = __( 'Page', 'acf' ); + $this->category = 'page'; + $this->object_type = 'post'; + $this->object_subtype = 'page'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + return acf_get_location_type( 'post' )->match( $rule, $screen, $field_group ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $choices = array(); + + // Get grouped posts. + $groups = acf_get_grouped_posts( + array( + 'post_type' => array( 'page' ), + ) + ); + + // Get first group. + $posts = reset( $groups ); + + // Append to choices. + if ( $posts ) { + foreach ( $posts as $post ) { + $choices[ $post->ID ] = acf_get_post_title( $post ); + } + } + return $choices; + } + } + + // Register. + acf_register_location_type( 'ACF_Location_Page' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post-category.php b/includes/locations/class-acf-location-post-category.php index ccdb65e..820ce5c 100644 --- a/includes/locations/class-acf-location-post-category.php +++ b/includes/locations/class-acf-location-post-category.php @@ -1,74 +1,76 @@ -name = 'post_category'; - $this->label = __( "Post Category", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - return acf_get_location_type( 'post_taxonomy' )->match( $rule, $screen, $field_group ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $choices = acf_get_taxonomy_terms(array( 'category' )); - if( $choices ) { - return reset( $choices ); - } - return array(); - } - - /** - * Returns the object_subtype connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string|array - */ - public function get_object_subtype( $rule ) { - return acf_get_location_type( 'post_taxonomy' )->get_object_subtype( $rule ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_rule( 'ACF_Location_Post_Category' ); +if ( ! class_exists( 'ACF_Location_Post_Category' ) ) : + + class ACF_Location_Post_Category extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post_category'; + $this->label = __( 'Post Category', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + return acf_get_location_type( 'post_taxonomy' )->match( $rule, $screen, $field_group ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $choices = acf_get_taxonomy_terms( array( 'category' ) ); + if ( $choices ) { + return reset( $choices ); + } + return array(); + } + + /** + * Returns the object_subtype connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string|array + */ + public function get_object_subtype( $rule ) { + return acf_get_location_type( 'post_taxonomy' )->get_object_subtype( $rule ); + } + } + + // initialize + acf_register_location_rule( 'ACF_Location_Post_Category' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post-format.php b/includes/locations/class-acf-location-post-format.php index 1248593..98e48ff 100644 --- a/includes/locations/class-acf-location-post-format.php +++ b/includes/locations/class-acf-location-post-format.php @@ -1,74 +1,76 @@ -name = 'post_format'; - $this->label = __( "Post Format", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_format']) ) { - $post_format = $screen['post_format']; - } elseif( isset($screen['post_id']) ) { - $post_type = get_post_type( $screen['post_id'] ); - $post_format = get_post_format( $screen['post_id'] ); - - // Treat new posts (that support post-formats) without a saved format as "standard". - if( !$post_format && post_type_supports($post_type, 'post-formats') ) { - $post_format = 'standard'; - } - } else { - return false; - } - - // Compare rule against $post_format. - return $this->compare_to_rule( $post_format, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return get_post_format_strings(); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Post_Format' ); +if ( ! class_exists( 'ACF_Location_Post_Format' ) ) : + + class ACF_Location_Post_Format extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post_format'; + $this->label = __( 'Post Format', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_format'] ) ) { + $post_format = $screen['post_format']; + } elseif ( isset( $screen['post_id'] ) ) { + $post_type = get_post_type( $screen['post_id'] ); + $post_format = get_post_format( $screen['post_id'] ); + + // Treat new posts (that support post-formats) without a saved format as "standard". + if ( ! $post_format && post_type_supports( $post_type, 'post-formats' ) ) { + $post_format = 'standard'; + } + } else { + return false; + } + + // Compare rule against $post_format. + return $this->compare_to_rule( $post_format, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return get_post_format_strings(); + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Post_Format' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post-status.php b/includes/locations/class-acf-location-post-status.php index a103ceb..5964fcb 100644 --- a/includes/locations/class-acf-location-post-status.php +++ b/includes/locations/class-acf-location-post-status.php @@ -1,82 +1,84 @@ -name = 'post_status'; - $this->label = __( "Post Status", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_status']) ) { - $post_status = $screen['post_status']; - } elseif( isset($screen['post_id']) ) { - $post_status = get_post_status( $screen['post_id'] ); - } else { - return false; - } - - // Treat "auto-draft" as "draft". - if( $post_status === 'auto-draft' ) { - $post_status = 'draft'; - } - - // Compare rule against $post_status. - return $this->compare_to_rule( $post_status, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - global $wp_post_statuses; - - // Append to choices. - $choices = array(); - if( $wp_post_statuses ) { - foreach( $wp_post_statuses as $status ) { - $choices[ $status->name ] = $status->label; - } - } - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Post_Status' ); +if ( ! class_exists( 'ACF_Location_Post_Status' ) ) : + + class ACF_Location_Post_Status extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post_status'; + $this->label = __( 'Post Status', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_status'] ) ) { + $post_status = $screen['post_status']; + } elseif ( isset( $screen['post_id'] ) ) { + $post_status = get_post_status( $screen['post_id'] ); + } else { + return false; + } + + // Treat "auto-draft" as "draft". + if ( $post_status === 'auto-draft' ) { + $post_status = 'draft'; + } + + // Compare rule against $post_status. + return $this->compare_to_rule( $post_status, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + global $wp_post_statuses; + + // Append to choices. + $choices = array(); + if ( $wp_post_statuses ) { + foreach ( $wp_post_statuses as $status ) { + $choices[ $status->name ] = $status->label; + } + } + return $choices; + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Post_Status' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post-taxonomy.php b/includes/locations/class-acf-location-post-taxonomy.php index 389e8b2..c7f5712 100644 --- a/includes/locations/class-acf-location-post-taxonomy.php +++ b/includes/locations/class-acf-location-post-taxonomy.php @@ -1,114 +1,116 @@ -name = 'post_taxonomy'; - $this->label = __( "Post Taxonomy", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_id']) ) { - $post_id = $screen['post_id']; - } elseif( isset($screen['attachment_id']) ) { - $post_id = $screen['attachment_id']; - } else { - return false; - } - - // Get WP_Term from rule value. - $term = acf_get_term( $rule['value'] ); - if( !$term || is_wp_error($term) ) { - return false; - } - - // Get terms connected to post. - if( isset($screen['post_terms']) ) { - $post_terms = acf_maybe_get( $screen['post_terms'], $term->taxonomy, array() ); - } else { - $post_terms = wp_get_post_terms( $post_id, $term->taxonomy, array('fields' => 'ids') ); - } - - // If no post terms are found, and we are dealing with the "category" taxonomy, treat as default "Uncategorized" category. - if( !$post_terms && $term->taxonomy == 'category' ) { - $post_terms = array( 1 ); - } - - // Search $post_terms for a match. - $result = ( in_array($term->term_id, $post_terms) || in_array($term->slug, $post_terms) ); - - // Reverse result for "!=" operator. - if( $rule['operator'] === '!=' ) { - return !$result; - } - return $result; - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return acf_get_taxonomy_terms(); - } - - /** - * Returns the object_subtype connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string|array - */ - public function get_object_subtype( $rule ) { - if( $rule['operator'] === '==' ) { - $term = acf_decode_term( $rule['value'] ); - if( $term ) { - $taxonomy = get_taxonomy( $term['taxonomy'] ); - if( $taxonomy ) { - return $taxonomy->object_type; - } - } - } - return ''; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Post_Taxonomy' ); +if ( ! class_exists( 'ACF_Location_Post_Taxonomy' ) ) : + + class ACF_Location_Post_Taxonomy extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post_taxonomy'; + $this->label = __( 'Post Taxonomy', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_id'] ) ) { + $post_id = $screen['post_id']; + } elseif ( isset( $screen['attachment_id'] ) ) { + $post_id = $screen['attachment_id']; + } else { + return false; + } + + // Get WP_Term from rule value. + $term = acf_get_term( $rule['value'] ); + if ( ! $term || is_wp_error( $term ) ) { + return false; + } + + // Get terms connected to post. + if ( isset( $screen['post_terms'] ) ) { + $post_terms = acf_maybe_get( $screen['post_terms'], $term->taxonomy, array() ); + } else { + $post_terms = wp_get_post_terms( $post_id, $term->taxonomy, array( 'fields' => 'ids' ) ); + } + + // If no post terms are found, and we are dealing with the "category" taxonomy, treat as default "Uncategorized" category. + if ( ! $post_terms && $term->taxonomy == 'category' ) { + $post_terms = array( 1 ); + } + + // Search $post_terms for a match. + $result = ( in_array( $term->term_id, $post_terms ) || in_array( $term->slug, $post_terms ) ); + + // Reverse result for "!=" operator. + if ( $rule['operator'] === '!=' ) { + return ! $result; + } + return $result; + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return acf_get_taxonomy_terms(); + } + + /** + * Returns the object_subtype connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string|array + */ + public function get_object_subtype( $rule ) { + if ( $rule['operator'] === '==' ) { + $term = acf_decode_term( $rule['value'] ); + if ( $term ) { + $taxonomy = get_taxonomy( $term['taxonomy'] ); + if ( $taxonomy ) { + return $taxonomy->object_type; + } + } + } + return ''; + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Post_Taxonomy' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post-template.php b/includes/locations/class-acf-location-post-template.php index 95e2dd3..67cd2ec 100644 --- a/includes/locations/class-acf-location-post-template.php +++ b/includes/locations/class-acf-location-post-template.php @@ -1,124 +1,126 @@ -name = 'post_template'; - $this->label = __( "Post Template", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_type']) ) { - $post_type = $screen['post_type']; - } elseif( isset($screen['post_id']) ) { - $post_type = get_post_type( $screen['post_id'] ); - } else { - return false; - } - - // Check if this post type has templates. - $post_templates = acf_get_post_templates(); - if( !isset($post_templates[ $post_type ]) ) { - return false; - } - - // Get page template allowing for screen or database value. - if( isset($screen['page_template']) ) { - $page_template = $screen['page_template']; - } elseif( isset($screen['post_id']) ) { - $page_template = get_post_meta( $screen['post_id'], '_wp_page_template', true ); - } else { - $page_template = ''; - } - - // Treat empty value as default template. - if( $page_template === '' ) { - $page_template = 'default'; - } - - // Compare rule against $page_template. - return $this->compare_to_rule( $page_template, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array_merge( - array( - 'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') ) - ), - acf_get_post_templates() - ); - } - - /** - * Returns the object_subtype connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string|array - */ - public function get_object_subtype( $rule ) { - if( $rule['operator'] === '==' ) { - $post_templates = acf_get_post_templates(); - - // If "default", return array of all post types which have templates. - if( $rule['value'] === 'default' ) { - return array_keys( $post_templates ); - - // Otherwise, generate list of post types that have the selected template. - } else { - $post_types = array(); - foreach( $post_templates as $post_type => $templates ) { - if( isset( $templates[ $rule['value'] ] ) ) { - $post_types[] = $post_type; - } - } - return $post_types; - } - } - return ''; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Post_Template' ); +if ( ! class_exists( 'ACF_Location_Post_Template' ) ) : + + class ACF_Location_Post_Template extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post_template'; + $this->label = __( 'Post Template', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_type'] ) ) { + $post_type = $screen['post_type']; + } elseif ( isset( $screen['post_id'] ) ) { + $post_type = get_post_type( $screen['post_id'] ); + } else { + return false; + } + + // Check if this post type has templates. + $post_templates = acf_get_post_templates(); + if ( ! isset( $post_templates[ $post_type ] ) ) { + return false; + } + + // Get page template allowing for screen or database value. + if ( isset( $screen['page_template'] ) ) { + $page_template = $screen['page_template']; + } elseif ( isset( $screen['post_id'] ) ) { + $page_template = get_post_meta( $screen['post_id'], '_wp_page_template', true ); + } else { + $page_template = ''; + } + + // Treat empty value as default template. + if ( $page_template === '' ) { + $page_template = 'default'; + } + + // Compare rule against $page_template. + return $this->compare_to_rule( $page_template, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array_merge( + array( + 'default' => apply_filters( 'default_page_template_title', __( 'Default Template', 'acf' ) ), + ), + acf_get_post_templates() + ); + } + + /** + * Returns the object_subtype connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string|array + */ + public function get_object_subtype( $rule ) { + if ( $rule['operator'] === '==' ) { + $post_templates = acf_get_post_templates(); + + // If "default", return array of all post types which have templates. + if ( $rule['value'] === 'default' ) { + return array_keys( $post_templates ); + + // Otherwise, generate list of post types that have the selected template. + } else { + $post_types = array(); + foreach ( $post_templates as $post_type => $templates ) { + if ( isset( $templates[ $rule['value'] ] ) ) { + $post_types[] = $post_type; + } + } + return $post_types; + } + } + return ''; + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Post_Template' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post-type.php b/includes/locations/class-acf-location-post-type.php index 68fac02..2fac7ff 100644 --- a/includes/locations/class-acf-location-post-type.php +++ b/includes/locations/class-acf-location-post-type.php @@ -1,93 +1,97 @@ -name = 'post_type'; - $this->label = __( "Post Type", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_type']) ) { - $post_type = $screen['post_type']; - } elseif( isset($screen['post_id']) ) { - $post_type = get_post_type( $screen['post_id'] ); - } else { - return false; - } - - // Compare rule against $post_type. - return $this->compare_to_rule( $post_type, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - - // Get post types. - $post_types = acf_get_post_types(array( - 'show_ui' => 1, - 'exclude' => array( 'attachment' ) - )); - - // Return array of [type => label]. - return acf_get_pretty_post_types( $post_types ); - } - - /** - * Returns the object_subtype connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string|array - */ - public function get_object_subtype( $rule ) { - if( $rule['operator'] === '==' ) { - return $rule['value']; - } - return ''; - } - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Post_Type' ); +if ( ! class_exists( 'ACF_Location_Post_Type' ) ) : + + class ACF_Location_Post_Type extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post_type'; + $this->label = __( 'Post Type', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_type'] ) ) { + $post_type = $screen['post_type']; + } elseif ( isset( $screen['post_id'] ) ) { + $post_type = get_post_type( $screen['post_id'] ); + } else { + return false; + } + + // Compare rule against $post_type. + return $this->compare_to_rule( $post_type, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + + // Get post types. + $post_types = acf_get_post_types( + array( + 'show_ui' => 1, + 'exclude' => array( 'attachment' ), + ) + ); + + // Return array of [type => label]. + return acf_get_pretty_post_types( $post_types ); + } + + /** + * Returns the object_subtype connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string|array + */ + public function get_object_subtype( $rule ) { + if ( $rule['operator'] === '==' ) { + return $rule['value']; + } + return ''; + } + + } + + // initialize + acf_register_location_type( 'ACF_Location_Post_Type' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-post.php b/includes/locations/class-acf-location-post.php index 5625f10..257806e 100644 --- a/includes/locations/class-acf-location-post.php +++ b/includes/locations/class-acf-location-post.php @@ -1,88 +1,94 @@ -name = 'post'; - $this->label = __( "Post", 'acf' ); - $this->category = 'post'; - $this->object_type = 'post'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['post_id']) ) { - $post_id = $screen['post_id']; - } else { - return false; - } - - // Compare rule against post_id. - return $this->compare_to_rule( $post_id, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - $choices = array(); - - // Get post types. - $post_types = acf_get_post_types(array( - 'show_ui' => 1, - 'exclude' => array('page', 'attachment') - )); - - // Get grouped posts. - $groups = acf_get_grouped_posts(array( - 'post_type' => $post_types - )); - - // Append to choices. - if( $groups ) { - foreach( $groups as $label => $posts ) { - $choices[ $label ] = array(); - foreach( $posts as $post ) { - $choices[ $label ][ $post->ID ] = acf_get_post_title( $post ); - } - } - } - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Post' ); +if ( ! class_exists( 'ACF_Location_Post' ) ) : + + class ACF_Location_Post extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'post'; + $this->label = __( 'Post', 'acf' ); + $this->category = 'post'; + $this->object_type = 'post'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['post_id'] ) ) { + $post_id = $screen['post_id']; + } else { + return false; + } + + // Compare rule against post_id. + return $this->compare_to_rule( $post_id, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + $choices = array(); + + // Get post types. + $post_types = acf_get_post_types( + array( + 'show_ui' => 1, + 'exclude' => array( 'page', 'attachment' ), + ) + ); + + // Get grouped posts. + $groups = acf_get_grouped_posts( + array( + 'post_type' => $post_types, + ) + ); + + // Append to choices. + if ( $groups ) { + foreach ( $groups as $label => $posts ) { + $choices[ $label ] = array(); + foreach ( $posts as $post ) { + $choices[ $label ][ $post->ID ] = acf_get_post_title( $post ); + } + } + } + return $choices; + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Post' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-taxonomy.php b/includes/locations/class-acf-location-taxonomy.php index bb4f6a0..0bc81ab 100644 --- a/includes/locations/class-acf-location-taxonomy.php +++ b/includes/locations/class-acf-location-taxonomy.php @@ -1,88 +1,90 @@ -name = 'taxonomy'; - $this->label = __( "Taxonomy", 'acf' ); - $this->category = 'forms'; - $this->object_type = 'term'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['taxonomy']) ) { - $taxonomy = $screen['taxonomy']; - } else { - return false; - } - - // Compare rule against $taxonomy. - return $this->compare_to_rule( $taxonomy, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array_merge( - array( - 'all' => __('All', 'acf') - ), - acf_get_taxonomy_labels() - ); - } - - /** - * Returns the object_subtype connected to this location. - * - * @date 1/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return string|array - */ - function get_object_subtype( $rule ) { - if( $rule['operator'] === '==' ) { - return $rule['value']; - } - return ''; - } - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Taxonomy' ); +if ( ! class_exists( 'ACF_Location_Taxonomy' ) ) : + + class ACF_Location_Taxonomy extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'taxonomy'; + $this->label = __( 'Taxonomy', 'acf' ); + $this->category = 'forms'; + $this->object_type = 'term'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['taxonomy'] ) ) { + $taxonomy = $screen['taxonomy']; + } else { + return false; + } + + // Compare rule against $taxonomy. + return $this->compare_to_rule( $taxonomy, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array_merge( + array( + 'all' => __( 'All', 'acf' ), + ), + acf_get_taxonomy_labels() + ); + } + + /** + * Returns the object_subtype connected to this location. + * + * @date 1/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return string|array + */ + function get_object_subtype( $rule ) { + if ( $rule['operator'] === '==' ) { + return $rule['value']; + } + return ''; + } + + } + + // initialize + acf_register_location_type( 'ACF_Location_Taxonomy' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-user-form.php b/includes/locations/class-acf-location-user-form.php index da03992..81f2943 100644 --- a/includes/locations/class-acf-location-user-form.php +++ b/includes/locations/class-acf-location-user-form.php @@ -1,76 +1,78 @@ -name = 'user_form'; - $this->label = __( "User Form", 'acf' ); - $this->category = 'user'; - $this->object_type = 'user'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['user_form']) ) { - $user_form = $screen['user_form']; - } else { - return false; - } - - // The "Add / Edit" choice (foolishly valued "edit") should match true for either "add" or "edit". - if( $rule['value'] === 'edit' && $user_form === 'add' ) { - $user_form = 'edit'; - } - - // Compare rule against $user_form. - return $this->compare_to_rule( $user_form, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - return array( - 'all' => __('All', 'acf'), - 'add' => __('Add', 'acf'), - 'edit' => __('Add / Edit', 'acf'), - 'register' => __('Register', 'acf') - ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Register. -acf_register_location_type( 'ACF_Location_User_Form' ); +if ( ! class_exists( 'ACF_Location_User_Form' ) ) : + + class ACF_Location_User_Form extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'user_form'; + $this->label = __( 'User Form', 'acf' ); + $this->category = 'user'; + $this->object_type = 'user'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['user_form'] ) ) { + $user_form = $screen['user_form']; + } else { + return false; + } + + // The "Add / Edit" choice (foolishly valued "edit") should match true for either "add" or "edit". + if ( $rule['value'] === 'edit' && $user_form === 'add' ) { + $user_form = 'edit'; + } + + // Compare rule against $user_form. + return $this->compare_to_rule( $user_form, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + return array( + 'all' => __( 'All', 'acf' ), + 'add' => __( 'Add', 'acf' ), + 'edit' => __( 'Add / Edit', 'acf' ), + 'register' => __( 'Register', 'acf' ), + ); + } + } + + // Register. + acf_register_location_type( 'ACF_Location_User_Form' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-user-role.php b/includes/locations/class-acf-location-user-role.php index e5e6c05..425fe03 100644 --- a/includes/locations/class-acf-location-user-role.php +++ b/includes/locations/class-acf-location-user-role.php @@ -1,86 +1,88 @@ -name = 'user_role'; - $this->label = __( "User Role", 'acf' ); - $this->category = 'user'; - $this->object_type = 'user'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['user_role']) ) { - $user_role = $screen['user_role']; - } elseif( isset($screen['user_id']) ) { - $user_id = $screen['user_id']; - $user_role = ''; - - // Determine $user_role from $user_id. - if( $user_id === 'new' ) { - $user_role = get_option( 'default_role' ); - - // Check if user can, and if so, set the value allowing them to match. - } elseif( user_can($user_id, $rule['value']) ) { - $user_role = $rule['value']; - } - } else { - return false; - } - - // Compare rule against $user_role. - return $this->compare_to_rule( $user_role, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - global $wp_roles; - return array_merge( - array( - 'all' => __( 'All', 'acf' ) - ), - $wp_roles->get_names() - ); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_User_Role' ); +if ( ! class_exists( 'ACF_Location_User_Role' ) ) : + + class ACF_Location_User_Role extends ACF_Location { + + /** + * initialize + * + * Sets up the class functionality. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function initialize() { + $this->name = 'user_role'; + $this->label = __( 'User Role', 'acf' ); + $this->category = 'user'; + $this->object_type = 'user'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['user_role'] ) ) { + $user_role = $screen['user_role']; + } elseif ( isset( $screen['user_id'] ) ) { + $user_id = $screen['user_id']; + $user_role = ''; + + // Determine $user_role from $user_id. + if ( $user_id === 'new' ) { + $user_role = get_option( 'default_role' ); + + // Check if user can, and if so, set the value allowing them to match. + } elseif ( user_can( $user_id, $rule['value'] ) ) { + $user_role = $rule['value']; + } + } else { + return false; + } + + // Compare rule against $user_role. + return $this->compare_to_rule( $user_role, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + global $wp_roles; + return array_merge( + array( + 'all' => __( 'All', 'acf' ), + ), + $wp_roles->get_names() + ); + } + } + + // initialize + acf_register_location_type( 'ACF_Location_User_Role' ); endif; // class_exists check diff --git a/includes/locations/class-acf-location-widget.php b/includes/locations/class-acf-location-widget.php index 43fbf84..ebdddc2 100644 --- a/includes/locations/class-acf-location-widget.php +++ b/includes/locations/class-acf-location-widget.php @@ -1,77 +1,79 @@ -name = 'widget'; - $this->label = __( "Widget", 'acf' ); - $this->category = 'forms'; - $this->object_type = 'widget'; - } - - /** - * Matches the provided rule against the screen args returning a bool result. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule The location rule. - * @param array $screen The screen args. - * @param array $field_group The field group settings. - * @return bool - */ - public function match( $rule, $screen, $field_group ) { - - // Check screen args. - if( isset($screen['widget']) ) { - $widget = $screen['widget']; - } else { - return false; - } - - // Compare rule against $widget. - return $this->compare_to_rule( $widget, $rule ); - } - - /** - * Returns an array of possible values for this rule type. - * - * @date 9/4/20 - * @since 5.9.0 - * - * @param array $rule A location rule. - * @return array - */ - public function get_values( $rule ) { - global $wp_widget_factory; - - // Populate choices. - $choices = array( - 'all' => __( 'All', 'acf' ) - ); - if( $wp_widget_factory->widgets ) { - foreach( $wp_widget_factory->widgets as $widget ) { - $choices[ $widget->id_base ] = $widget->name; - } - } - return $choices; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf_register_location_type( 'ACF_Location_Widget' ); +if ( ! class_exists( 'ACF_Location_Widget' ) ) : + + class ACF_Location_Widget extends ACF_Location { + + /** + * Initializes props. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function initialize() { + $this->name = 'widget'; + $this->label = __( 'Widget', 'acf' ); + $this->category = 'forms'; + $this->object_type = 'widget'; + } + + /** + * Matches the provided rule against the screen args returning a bool result. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule The location rule. + * @param array $screen The screen args. + * @param array $field_group The field group settings. + * @return bool + */ + public function match( $rule, $screen, $field_group ) { + + // Check screen args. + if ( isset( $screen['widget'] ) ) { + $widget = $screen['widget']; + } else { + return false; + } + + // Compare rule against $widget. + return $this->compare_to_rule( $widget, $rule ); + } + + /** + * Returns an array of possible values for this rule type. + * + * @date 9/4/20 + * @since 5.9.0 + * + * @param array $rule A location rule. + * @return array + */ + public function get_values( $rule ) { + global $wp_widget_factory; + + // Populate choices. + $choices = array( + 'all' => __( 'All', 'acf' ), + ); + if ( $wp_widget_factory->widgets ) { + foreach ( $wp_widget_factory->widgets as $widget ) { + $choices[ $widget->id_base ] = $widget->name; + } + } + return $choices; + } + } + + // initialize + acf_register_location_type( 'ACF_Location_Widget' ); endif; // class_exists check diff --git a/includes/loop.php b/includes/loop.php index 9ca3e86..ff7d0c5 100644 --- a/includes/loop.php +++ b/includes/loop.php @@ -1,273 +1,272 @@ -loops = array(); - - } - - - /* - * is_empty - * - * This function will return true if no loops exist - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param n/a - * @return (boolean) - */ - - function is_empty() { - - return empty( $this->loops ); - - } - - - /* - * is_loop - * - * This function will return true if a loop exists for the given array index - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param $i (int) - * @return (boolean) - */ - - function is_loop( $i = 0 ) { - - return isset( $this->loops[ $i ] ); - - } - - - /* - * get_i - * - * This function will return a valid array index for the given $i - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param $i (mixed) - * @return (int) - */ - - function get_i( $i = 0 ) { - - // 'active' - if( $i === 'active' ) $i = -1; - - - // 'previous' - if( $i === 'previous' ) $i = -2; - - - // allow negative to look at end of loops - if( $i < 0 ) { - - $i = count($this->loops) + $i; - - } - - - // return - return $i; - - } - - - /* - * add_loop - * - * This function will add a new loop - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param $loop (array) - * @return n/a - */ - - function add_loop( $loop = array() ) { - - // defaults - $loop = wp_parse_args( $loop, array( - 'selector' => '', - 'name' => '', - 'value' => false, - 'field' => false, - 'i' => -1, - 'post_id' => 0, - 'key' => '' - )); - - - // ensure array - $loop['value'] = acf_get_array( $loop['value'] ); - - - // Re-index values if this loop starts from index 0. - // This allows ajax previews to work ($_POST data contains random unique array keys) - if( $loop['i'] == -1 ) { - - $loop['value'] = array_values($loop['value']); - - } - - - // append - $this->loops[] = $loop; - - - // return - return $loop; - - } - - - /* - * update_loop - * - * This function will update a loop's setting - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param $i (mixed) - * @param $key (string) the loop setting name - * @param $value (mixed) the loop setting value - * @return (boolean) true on success - */ - - function update_loop( $i = 'active', $key = null, $value = null ) { - - // i - $i = $this->get_i( $i ); - - - // bail early if no set - if( !$this->is_loop($i) ) return false; - - - // set - $this->loops[ $i ][ $key ] = $value; - - - // return - return true; - - } - - - /* - * get_loop - * - * This function will return a loop, or loop's setting for a given index & key - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param $i (mixed) - * @param $key (string) the loop setting name - * @return (mixed) false on failure - */ - - function get_loop( $i = 'active', $key = null ) { - - // i - $i = $this->get_i( $i ); - - - // bail early if no set - if( !$this->is_loop($i) ) return false; - - - // check for key - if( $key !== null ) { - - return $this->loops[ $i ][ $key ]; - - } - - - // return - return $this->loops[ $i ]; - - } - - - /* - * remove_loop - * - * This function will remove a loop - * - * @type function - * @date 3/03/2016 - * @since 5.3.2 - * - * @param $i (mixed) - * @return (boolean) true on success - */ - - function remove_loop( $i = 'active' ) { - - // i - $i = $this->get_i( $i ); - - - // bail early if no set - if( !$this->is_loop($i) ) return false; - - - // remove - unset($this->loops[ $i ]); - - - // reset keys - $this->loops = array_values( $this->loops ); - - // PHP 7.2 no longer resets array keys for empty value - if( $this->is_empty() ) { - $this->loops = array(); - } - } - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf()->loop = new acf_loop(); +if ( ! class_exists( 'acf_loop' ) ) : + + class acf_loop { + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // vars + $this->loops = array(); + + } + + + /* + * is_empty + * + * This function will return true if no loops exist + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param n/a + * @return (boolean) + */ + + function is_empty() { + + return empty( $this->loops ); + + } + + + /* + * is_loop + * + * This function will return true if a loop exists for the given array index + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param $i (int) + * @return (boolean) + */ + + function is_loop( $i = 0 ) { + + return isset( $this->loops[ $i ] ); + + } + + + /* + * get_i + * + * This function will return a valid array index for the given $i + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param $i (mixed) + * @return (int) + */ + + function get_i( $i = 0 ) { + + // 'active' + if ( $i === 'active' ) { + $i = -1; + } + + // 'previous' + if ( $i === 'previous' ) { + $i = -2; + } + + // allow negative to look at end of loops + if ( $i < 0 ) { + + $i = count( $this->loops ) + $i; + + } + + // return + return $i; + + } + + + /* + * add_loop + * + * This function will add a new loop + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param $loop (array) + * @return n/a + */ + + function add_loop( $loop = array() ) { + + // defaults + $loop = wp_parse_args( + $loop, + array( + 'selector' => '', + 'name' => '', + 'value' => false, + 'field' => false, + 'i' => -1, + 'post_id' => 0, + 'key' => '', + ) + ); + + // ensure array + $loop['value'] = acf_get_array( $loop['value'] ); + + // Re-index values if this loop starts from index 0. + // This allows ajax previews to work ($_POST data contains random unique array keys) + if ( $loop['i'] == -1 ) { + + $loop['value'] = array_values( $loop['value'] ); + + } + + // append + $this->loops[] = $loop; + + // return + return $loop; + + } + + + /* + * update_loop + * + * This function will update a loop's setting + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param $i (mixed) + * @param $key (string) the loop setting name + * @param $value (mixed) the loop setting value + * @return (boolean) true on success + */ + + function update_loop( $i = 'active', $key = null, $value = null ) { + + // i + $i = $this->get_i( $i ); + + // bail early if no set + if ( ! $this->is_loop( $i ) ) { + return false; + } + + // set + $this->loops[ $i ][ $key ] = $value; + + // return + return true; + + } + + + /* + * get_loop + * + * This function will return a loop, or loop's setting for a given index & key + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param $i (mixed) + * @param $key (string) the loop setting name + * @return (mixed) false on failure + */ + + function get_loop( $i = 'active', $key = null ) { + + // i + $i = $this->get_i( $i ); + + // bail early if no set + if ( ! $this->is_loop( $i ) ) { + return false; + } + + // check for key + if ( $key !== null ) { + + return $this->loops[ $i ][ $key ]; + + } + + // return + return $this->loops[ $i ]; + + } + + + /* + * remove_loop + * + * This function will remove a loop + * + * @type function + * @date 3/03/2016 + * @since 5.3.2 + * + * @param $i (mixed) + * @return (boolean) true on success + */ + + function remove_loop( $i = 'active' ) { + + // i + $i = $this->get_i( $i ); + + // bail early if no set + if ( ! $this->is_loop( $i ) ) { + return false; + } + + // remove + unset( $this->loops[ $i ] ); + + // reset keys + $this->loops = array_values( $this->loops ); + + // PHP 7.2 no longer resets array keys for empty value + if ( $this->is_empty() ) { + $this->loops = array(); + } + } + + } + + // initialize + acf()->loop = new acf_loop(); endif; // class_exists check @@ -278,18 +277,18 @@ endif; // class_exists check * * alias of acf()->loop->add_loop() * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_add_loop( $loop = array() ) { - + return acf()->loop->add_loop( $loop ); - + } @@ -298,18 +297,18 @@ function acf_add_loop( $loop = array() ) { * * alias of acf()->loop->update_loop() * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_update_loop( $i = 'active', $key = null, $value = null ) { - + return acf()->loop->update_loop( $i, $key, $value ); - + } @@ -318,18 +317,18 @@ function acf_update_loop( $i = 'active', $key = null, $value = null ) { * * alias of acf()->loop->get_loop() * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_get_loop( $i = 'active', $key = null ) { - + return acf()->loop->get_loop( $i, $key ); - + } @@ -338,18 +337,18 @@ function acf_get_loop( $i = 'active', $key = null ) { * * alias of acf()->loop->remove_loop() * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_remove_loop( $i = 'active' ) { - + return acf()->loop->remove_loop( $i ); - + } -?> \ No newline at end of file + diff --git a/includes/media.php b/includes/media.php index dfacca3..9cffd14 100644 --- a/includes/media.php +++ b/includes/media.php @@ -1,219 +1,243 @@ - _x('Select', 'verb', 'acf'), - 'Edit.verb' => _x('Edit', 'verb', 'acf'), - 'Update.verb' => _x('Update', 'verb', 'acf'), - 'Uploaded to this post' => __('Uploaded to this post', 'acf'), - 'Expand Details' => __('Expand Details', 'acf'), - 'Collapse Details' => __('Collapse Details', 'acf'), - 'Restricted' => __('Restricted', 'acf'), - 'All images' => __('All images', 'acf') - )); - acf_localize_data(array( - 'mimeTypeIcon' => wp_mime_type_icon(), - 'mimeTypes' => get_allowed_mime_types() - )); - } - } - - /** - * Uploads attachments found in the basic `$_FILES` array. - * - * @date 24/10/2014 - * @since 5.0.9 - * - * @param string|int $post_id The post ID being saved. - * @return void - */ - public function save_files( $post_id = 0 ) { - if( isset( $_FILES['acf']['name'] ) ) { - acf_upload_files(); - } - } - - /** - * Filters data for the current file being uploaded. - * - * @date 16/02/2015 - * @since 5.1.5 - * - * @param array $file An array of data for a single file. - * @return array - */ - public function handle_upload_prefilter( $file ) { - $field = $this->get_source_field(); - if( !$field ) { - return $file; - } - - // Validate the attachment and append any errors. - $errors = acf_validate_attachment( $file, $field, 'upload' ); - - /** - * Filters the errors for a file before it is uploaded to WordPress. - * - * @date 16/02/2015 - * @since 5.1.5 - * - * @param array $errors An array of errors. - * @param array $file An array of data for a single file. - * @param array $field The field array. - */ - $errors = apply_filters( "acf/upload_prefilter/type={$field['type']}", $errors, $file, $field ); - $errors = apply_filters( "acf/upload_prefilter/name={$field['_name']}", $errors, $file, $field ); - $errors = apply_filters( "acf/upload_prefilter/key={$field['key']}", $errors, $file, $field ); - $errors = apply_filters( "acf/upload_prefilter", $errors, $file, $field ); - - // Append errors. - if( !empty($errors) ) { - $file['error'] = implode("\n", $errors); - } - - // Ensure newly uploaded image contains "preview_size" within the "size" data. - add_filter( 'image_size_names_choose', array( $this, 'image_size_names_choose' ), 10, 1 ); - - // Return. - return $file; - } - - - - - /** - * Returns the field responsible for the current Media query or upload context. - * - * @date 21/5/21 - * @since 5.9.7 - * - * @param void - * @return array| false. - */ - private function get_source_field() { - $field = false; - - // Search for field key within available data. - // Case 1) Media modal query. - if( isset( $_POST['query']['_acfuploader'] ) ) { - $field_key = (string) $_POST['query']['_acfuploader']; - - // Case 2) Media modal upload. - } elseif( isset( $_POST['_acfuploader'] ) ) { - $field_key = (string) $_POST['_acfuploader']; - } - - // Attempt to load field. - // Note the `acf_get_field()` function will return false if not found. - if( isset( $field_key ) ) { - $field = acf_get_field( $field_key ); - } - return $field; - } - - /** - * Fires during the WP Modal Query AJAX call. - * - * @date 26/06/2015 - * @since 5.2.3 - * - * @param void - * @return void - */ - function wp_ajax_query_attachments() { - if( $this->get_source_field() ) { - add_filter( 'wp_prepare_attachment_for_js', array( $this, 'wp_prepare_attachment_for_js' ), 10, 3 ); - add_filter( 'image_size_names_choose', array( $this, 'image_size_names_choose' ), 10, 1 ); - } - } - - /** - * Filters attachment data as it is being prepared for JS. - * - * @date 21/5/21 - * @since 5.9.7 - * - * @param array $response Array of prepared attachment data. - * @param WP_Post $attachment Attachment object. - * @param array|false $meta Array of attachment meta data, or false if there is none. - * @return array - */ - function wp_prepare_attachment_for_js( $response, $attachment, $meta ) { - $field = $this->get_source_field(); - - // Validate the attachment and append any errors. - $errors = acf_validate_attachment( $response, $field, 'prepare' ); - $response['acf_errors'] = false; - if( !empty($errors) ) { - $response['acf_errors'] = implode('
                                ', $errors); - } - - // Return. - return $response; - } - - /** - * Filters the names and labels of the default image sizes. - * - * @date 21/5/21 - * @since 5.9.7 - * - * @param array $size_names Array of image size labels keyed by their name. - * @return array - */ - function image_size_names_choose( $size_names ) { - $field = $this->get_source_field(); - - // Append "preview_size" setting to array of image sizes so WP will include in prepared JS data. - if( isset( $field['preview_size'] ) ) { - $name = (string) $field['preview_size']; - $size_names[ $name ] = $name; // Don't worry about size label, it is never used. - } - return $size_names; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Instantiate. -acf_new_instance( 'ACF_Media' ); +if ( ! class_exists( 'ACF_Media' ) ) : -endif; // class_exists check \ No newline at end of file + class ACF_Media { + + /** + * Constructor. + * + * @date 23/06/12 + * @since 5.0.0 + * + * @param void + * @return void + */ + public function __construct() { + + // Localize media strings. + add_action( 'acf/enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + + // Save files uploaded from basic `$_FILE` field. + add_action( 'acf/save_post', array( $this, 'save_files' ), 5, 1 ); + + // Hook into Media Upload to run additional logic. + add_filter( 'wp_handle_upload_prefilter', array( $this, 'handle_upload_prefilter' ), 10, 1 ); + + // Hook into Media Modal Query to run additional logic. + add_action( 'wp_ajax_query-attachments', array( $this, 'wp_ajax_query_attachments' ), -1 ); + } + + /** + * Fires when ACF scrtips are enqueued. + * + * @date 27/4/18 + * @since 5.6.9 + * + * @param void + * @return void + */ + public function enqueue_scripts() { + if ( wp_script_is( 'acf-input' ) ) { + acf_localize_text( + array( + 'Select.verb' => _x( 'Select', 'verb', 'acf' ), + 'Edit.verb' => _x( 'Edit', 'verb', 'acf' ), + 'Update.verb' => _x( 'Update', 'verb', 'acf' ), + 'Uploaded to this post' => __( 'Uploaded to this post', 'acf' ), + 'Expand Details' => __( 'Expand Details', 'acf' ), + 'Collapse Details' => __( 'Collapse Details', 'acf' ), + 'Restricted' => __( 'Restricted', 'acf' ), + 'All images' => __( 'All images', 'acf' ), + ) + ); + acf_localize_data( + array( + 'mimeTypeIcon' => wp_mime_type_icon(), + 'mimeTypes' => get_allowed_mime_types(), + ) + ); + } + } + + /** + * Uploads attachments found in the basic `$_FILES` array. + * + * @date 24/10/2014 + * @since 5.0.9 + * + * @param string|int $post_id The post ID being saved. + * @return void + */ + public function save_files( $post_id = 0 ) { + if ( isset( $_FILES['acf']['name'] ) ) { + acf_upload_files(); + } + } + + /** + * Filters data for the current file being uploaded. + * + * @date 16/02/2015 + * @since 5.1.5 + * + * @param array $file An array of data for a single file. + * @return array + */ + public function handle_upload_prefilter( $file ) { + $field = $this->get_source_field(); + if ( ! $field ) { + return $file; + } + + // Validate the attachment and append any errors. + $errors = acf_validate_attachment( $file, $field, 'upload' ); + + /** + * Filters the errors for a file before it is uploaded to WordPress. + * + * @date 16/02/2015 + * @since 5.1.5 + * + * @param array $errors An array of errors. + * @param array $file An array of data for a single file. + * @param array $field The field array. + */ + $errors = apply_filters( "acf/upload_prefilter/type={$field['type']}", $errors, $file, $field ); + $errors = apply_filters( "acf/upload_prefilter/name={$field['_name']}", $errors, $file, $field ); + $errors = apply_filters( "acf/upload_prefilter/key={$field['key']}", $errors, $file, $field ); + $errors = apply_filters( 'acf/upload_prefilter', $errors, $file, $field ); + + // Append errors. + if ( ! empty( $errors ) ) { + $file['error'] = implode( "\n", $errors ); + } + + // Ensure newly uploaded image contains "preview_size" within the "size" data. + add_filter( 'image_size_names_choose', array( $this, 'image_size_names_choose' ), 10, 1 ); + + // Return. + return $file; + } + + + + + /** + * Returns the field responsible for the current Media query or upload context. + * + * @date 21/5/21 + * @since 5.9.7 + * + * @param void + * @return array| false. + */ + private function get_source_field() { + $field = false; + + // Search for field key within available data. + // Case 1) Media modal query. + if ( isset( $_POST['query']['_acfuploader'] ) ) { + $field_key = (string) $_POST['query']['_acfuploader']; + + // Case 2) Media modal upload. + } elseif ( isset( $_POST['_acfuploader'] ) ) { + $field_key = (string) $_POST['_acfuploader']; + } + + // Attempt to load field. + // Note the `acf_get_field()` function will return false if not found. + if ( isset( $field_key ) ) { + $field = acf_get_field( $field_key ); + } + return $field; + } + + /** + * Fires during the WP Modal Query AJAX call. + * + * @date 26/06/2015 + * @since 5.2.3 + * + * @param void + * @return void + */ + function wp_ajax_query_attachments() { + if ( $this->get_source_field() ) { + add_filter( 'wp_prepare_attachment_for_js', array( $this, 'wp_prepare_attachment_for_js' ), 10, 3 ); + add_filter( 'image_size_names_choose', array( $this, 'image_size_names_choose' ), 10, 1 ); + } else { + add_filter( 'wp_prepare_attachment_for_js', array( $this, 'clear_acf_errors_for_core_requests' ), 5, 3 ); + } + } + + /** + * Append acf_errors false for non-acf media library calls to prevent media library caching. + * + * @date 31/8/21 + * @since 5.10.2 + * + * @param array $response Array of prepared attachment data. + * @param WP_Post $attachment Attachment object. + * @param array|false $meta Array of attachment meta data, or false if there is none. + * @return array + */ + function clear_acf_errors_for_core_requests( $response, $attachment, $meta ) { + $response['acf_errors'] = false; + return $response; + } + + /** + * Filters attachment data as it is being prepared for JS. + * + * @date 21/5/21 + * @since 5.9.7 + * + * @param array $response Array of prepared attachment data. + * @param WP_Post $attachment Attachment object. + * @param array|false $meta Array of attachment meta data, or false if there is none. + * @return array + */ + function wp_prepare_attachment_for_js( $response, $attachment, $meta ) { + $field = $this->get_source_field(); + + // Validate the attachment and append any errors. + $errors = acf_validate_attachment( $response, $field, 'prepare' ); + $response['acf_errors'] = false; + if ( ! empty( $errors ) ) { + $response['acf_errors'] = implode( '
                                ', $errors ); + } + + // Return. + return $response; + } + + /** + * Filters the names and labels of the default image sizes. + * + * @date 21/5/21 + * @since 5.9.7 + * + * @param array $size_names Array of image size labels keyed by their name. + * @return array + */ + function image_size_names_choose( $size_names ) { + $field = $this->get_source_field(); + + // Append "preview_size" setting to array of image sizes so WP will include in prepared JS data. + if ( isset( $field['preview_size'] ) ) { + $name = (string) $field['preview_size']; + $size_names[ $name ] = $name; // Don't worry about size label, it is never used. + } + return $size_names; + } + } + + // Instantiate. + acf_new_instance( 'ACF_Media' ); + +endif; // class_exists check diff --git a/includes/revisions.php b/includes/revisions.php index be09766..4e50595 100644 --- a/includes/revisions.php +++ b/includes/revisions.php @@ -1,416 +1,400 @@ -ID; - - } - - - // get all postmeta - $meta = get_post_meta( $post_id ); - - - // bail early if no meta - if( !$meta ) return $fields; - - - // loop - foreach( $meta as $name => $value ) { - - // attempt to find key value - $key = acf_maybe_get( $meta, '_'.$name ); - - - // bail ealry if no key - if( !$key ) continue; - - - // update vars - $value = $value[0]; - $key = $key[0]; - - // Load field. - $field = acf_get_field( $key ); - if( !$field ) { - continue; - } - - // get field - $field_title = $field['label'] . ' (' . $name . ')'; - $field_order = $field['menu_order']; - $ancestors = acf_get_field_ancestors( $field ); - - - // ancestors - if( !empty($ancestors) ) { - - // vars - $count = count($ancestors); - $oldest = acf_get_field( $ancestors[$count-1] ); - - - // update vars - $field_title = str_repeat('- ', $count) . $field_title; - $field_order = $oldest['menu_order'] . '.1'; - - } - - - // append - $append[ $name ] = $field_title; - $order[ $name ] = $field_order; - - - // hook into specific revision field filter and return local value - add_filter("_wp_post_revision_field_{$name}", array($this, 'wp_post_revision_field'), 10, 4); - - } - - - // append - if( !empty($append) ) { - - // vars - $prefix = '_'; - - - // add prefix - $append = acf_add_array_key_prefix($append, $prefix); - $order = acf_add_array_key_prefix($order, $prefix); - - - // sort by name (orders sub field values correctly) - array_multisort($order, $append); - - - // remove prefix - $append = acf_remove_array_key_prefix($append, $prefix); - - - // append - $fields = $fields + $append; - - } - - - // return - return $fields; - - } - - - /* - * wp_post_revision_field - * - * This filter will load the value for the given field and return it for rendering - * - * @type filter - * @date 11/08/13 - * - * @param $value (mixed) should be false as it has not yet been loaded - * @param $field_name (string) The name of the field - * @param $post (mixed) Holds the $post object to load from - in WP 3.5, this is not passed! - * @param $direction (string) to / from - not used - * @return $value (string) - */ - - function wp_post_revision_field( $value, $field_name, $post = null, $direction = false) { - - // bail ealry if is empty - if( empty($value) ) return $value; - - - // value has not yet been 'maybe_unserialize' - $value = maybe_unserialize( $value ); - - - // vars - $post_id = $post->ID; - - - // load field - $field = acf_maybe_get_field( $field_name, $post_id ); - - - // default formatting - if( is_array($value) ) { - - $value = implode(', ', $value); - - } elseif( is_object($value) ) { - - $value = serialize($value); - - } - - - // image - if( $field['type'] == 'image' || $field['type'] == 'file' ) { - - $url = wp_get_attachment_url($value); - $value = $value . ' (' . $url . ')'; - - } - - - // return - return $value; - - } - - - /* - * wp_restore_post_revision - * - * This action will copy and paste the metadata from a revision to the post - * - * @type action - * @date 11/08/13 - * - * @param $parent_id (int) the destination post - * @return $revision_id (int) the source post - */ - - function wp_restore_post_revision( $post_id, $revision_id ) { - - // copy postmeta from revision to post (restore from revision) - acf_copy_postmeta( $revision_id, $post_id ); - - - // Make sure the latest revision is also updated to match the new $post data - // get latest revision - $revision = acf_get_post_latest_revision( $post_id ); - - - // save - if( $revision ) { - - // copy postmeta from revision to latest revision (potentialy may be the same, but most likely are different) - acf_copy_postmeta( $revision_id, $revision->ID ); - - } - - } - - - /* - * acf_validate_post_id - * - * This function will modify the $post_id and allow loading values from a revision - * - * @type function - * @date 6/3/17 - * @since 5.5.10 - * - * @param $post_id (int) - * @param $_post_id (int) - * @return $post_id (int) - */ - - function acf_validate_post_id( $post_id, $_post_id ) { - - // bail early if no preview in URL - if( !isset($_GET['preview']) ) return $post_id; - - - // bail early if $post_id is not numeric - if( !is_numeric($post_id) ) return $post_id; - - - // vars - $k = $post_id; - $preview_id = 0; - - - // check cache - if( isset($this->cache[$k]) ) return $this->cache[$k]; - - - // validate - if( isset($_GET['preview_id']) ) { - - $preview_id = (int) $_GET['preview_id']; - - } elseif( isset($_GET['p']) ) { - - $preview_id = (int) $_GET['p']; - - } elseif( isset($_GET['page_id']) ) { - - $preview_id = (int) $_GET['page_id']; - - } - - - // bail early id $preview_id does not match $post_id - if( $preview_id != $post_id ) return $post_id; - - - // attempt find revision - $revision = acf_get_post_latest_revision( $post_id ); - - - // save - if( $revision && $revision->post_parent == $post_id) { - - $post_id = (int) $revision->ID; - - } - - - // set cache - $this->cache[$k] = $post_id; - - - // return - return $post_id; - - } - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf()->revisions = new acf_revisions(); +if ( ! class_exists( 'acf_revisions' ) ) : + + class acf_revisions { + + // vars + var $cache = array(); + + + /* + * __construct + * + * A good place to add actions / filters + * + * @type function + * @date 11/08/13 + * + * @param N/A + * @return N/A + */ + + function __construct() { + + // actions + add_action( 'wp_restore_post_revision', array( $this, 'wp_restore_post_revision' ), 10, 2 ); + + // filters + add_filter( 'wp_save_post_revision_check_for_changes', array( $this, 'wp_save_post_revision_check_for_changes' ), 10, 3 ); + add_filter( '_wp_post_revision_fields', array( $this, 'wp_preview_post_fields' ), 10, 2 ); + add_filter( '_wp_post_revision_fields', array( $this, 'wp_post_revision_fields' ), 10, 2 ); + add_filter( 'acf/validate_post_id', array( $this, 'acf_validate_post_id' ), 10, 2 ); + + } + + + /* + * wp_preview_post_fields + * + * This function is used to trick WP into thinking that one of the $post's fields has changed and + * will allow an autosave to be updated. + * Fixes an odd bug causing the preview page to render the non autosave post data on every odd attempt + * + * @type function + * @date 21/10/2014 + * @since 5.1.0 + * + * @param $fields (array) + * @return $fields + */ + + function wp_preview_post_fields( $fields ) { + + // bail early if not previewing a post + if ( acf_maybe_get_POST( 'wp-preview' ) !== 'dopreview' ) { + return $fields; + } + + // add to fields if ACF has changed + if ( acf_maybe_get_POST( '_acf_changed' ) ) { + + $fields['_acf_changed'] = 'different than 1'; + + } + + // return + return $fields; + + } + + + /* + * wp_save_post_revision_check_for_changes + * + * This filter will return false and force WP to save a revision. This is required due to + * WP checking only post_title, post_excerpt and post_content values, not custom fields. + * + * @type filter + * @date 19/09/13 + * + * @param $return (boolean) defaults to true + * @param $last_revision (object) the last revision that WP will compare against + * @param $post (object) the $post that WP will compare against + * @return $return (boolean) + */ + + function wp_save_post_revision_check_for_changes( $return, $last_revision, $post ) { + + // if acf has changed, return false and prevent WP from performing 'compare' logic + if ( acf_maybe_get_POST( '_acf_changed' ) ) { + return false; + } + + // return + return $return; + + } + + + /* + * wp_post_revision_fields + * + * This filter will add the ACF fields to the returned array + * Versions 3.5 and 3.6 of WP feature different uses of the revisions filters, so there are + * some hacks to allow both versions to work correctly + * + * @type filter + * @date 11/08/13 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function wp_post_revision_fields( $fields, $post = null ) { + + // validate page + if ( acf_is_screen( 'revision' ) || acf_is_ajax( 'get-revision-diffs' ) ) { + + // bail early if is restoring + if ( acf_maybe_get_GET( 'action' ) === 'restore' ) { + return $fields; + } + + // allow + + } else { + + // bail early (most likely saving a post) + return $fields; + + } + + // vars + $append = array(); + $order = array(); + $post_id = acf_maybe_get( $post, 'ID' ); + + // compatibility with WP < 4.5 (test) + if ( ! $post_id ) { + + global $post; + $post_id = $post->ID; + + } + + // get all postmeta + $meta = get_post_meta( $post_id ); + + // bail early if no meta + if ( ! $meta ) { + return $fields; + } + + // loop + foreach ( $meta as $name => $value ) { + + // attempt to find key value + $key = acf_maybe_get( $meta, '_' . $name ); + + // bail ealry if no key + if ( ! $key ) { + continue; + } + + // update vars + $value = $value[0]; + $key = $key[0]; + + // Load field. + $field = acf_get_field( $key ); + if ( ! $field ) { + continue; + } + + // get field + $field_title = $field['label'] . ' (' . $name . ')'; + $field_order = $field['menu_order']; + $ancestors = acf_get_field_ancestors( $field ); + + // ancestors + if ( ! empty( $ancestors ) ) { + + // vars + $count = count( $ancestors ); + $oldest = acf_get_field( $ancestors[ $count - 1 ] ); + + // update vars + $field_title = str_repeat( '- ', $count ) . $field_title; + $field_order = $oldest['menu_order'] . '.1'; + + } + + // append + $append[ $name ] = $field_title; + $order[ $name ] = $field_order; + + // hook into specific revision field filter and return local value + add_filter( "_wp_post_revision_field_{$name}", array( $this, 'wp_post_revision_field' ), 10, 4 ); + + } + + // append + if ( ! empty( $append ) ) { + + // vars + $prefix = '_'; + + // add prefix + $append = acf_add_array_key_prefix( $append, $prefix ); + $order = acf_add_array_key_prefix( $order, $prefix ); + + // sort by name (orders sub field values correctly) + array_multisort( $order, $append ); + + // remove prefix + $append = acf_remove_array_key_prefix( $append, $prefix ); + + // append + $fields = $fields + $append; + + } + + // return + return $fields; + + } + + + /* + * wp_post_revision_field + * + * This filter will load the value for the given field and return it for rendering + * + * @type filter + * @date 11/08/13 + * + * @param $value (mixed) should be false as it has not yet been loaded + * @param $field_name (string) The name of the field + * @param $post (mixed) Holds the $post object to load from - in WP 3.5, this is not passed! + * @param $direction (string) to / from - not used + * @return $value (string) + */ + + function wp_post_revision_field( $value, $field_name, $post = null, $direction = false ) { + + // bail ealry if is empty + if ( empty( $value ) ) { + return $value; + } + + // value has not yet been 'maybe_unserialize' + $value = maybe_unserialize( $value ); + + // vars + $post_id = $post->ID; + + // load field + $field = acf_maybe_get_field( $field_name, $post_id ); + + // default formatting + if ( is_array( $value ) ) { + + $value = implode( ', ', $value ); + + } elseif ( is_object( $value ) ) { + + $value = serialize( $value ); + + } + + // image + if ( $field['type'] == 'image' || $field['type'] == 'file' ) { + + $url = wp_get_attachment_url( $value ); + $value = $value . ' (' . $url . ')'; + + } + + // return + return $value; + + } + + + /* + * wp_restore_post_revision + * + * This action will copy and paste the metadata from a revision to the post + * + * @type action + * @date 11/08/13 + * + * @param $parent_id (int) the destination post + * @return $revision_id (int) the source post + */ + + function wp_restore_post_revision( $post_id, $revision_id ) { + + // copy postmeta from revision to post (restore from revision) + acf_copy_postmeta( $revision_id, $post_id ); + + // Make sure the latest revision is also updated to match the new $post data + // get latest revision + $revision = acf_get_post_latest_revision( $post_id ); + + // save + if ( $revision ) { + + // copy postmeta from revision to latest revision (potentialy may be the same, but most likely are different) + acf_copy_postmeta( $revision_id, $revision->ID ); + + } + + } + + + /* + * acf_validate_post_id + * + * This function will modify the $post_id and allow loading values from a revision + * + * @type function + * @date 6/3/17 + * @since 5.5.10 + * + * @param $post_id (int) + * @param $_post_id (int) + * @return $post_id (int) + */ + + function acf_validate_post_id( $post_id, $_post_id ) { + + // bail early if no preview in URL + if ( ! isset( $_GET['preview'] ) ) { + return $post_id; + } + + // bail early if $post_id is not numeric + if ( ! is_numeric( $post_id ) ) { + return $post_id; + } + + // vars + $k = $post_id; + $preview_id = 0; + + // check cache + if ( isset( $this->cache[ $k ] ) ) { + return $this->cache[ $k ]; + } + + // validate + if ( isset( $_GET['preview_id'] ) ) { + + $preview_id = (int) $_GET['preview_id']; + + } elseif ( isset( $_GET['p'] ) ) { + + $preview_id = (int) $_GET['p']; + + } elseif ( isset( $_GET['page_id'] ) ) { + + $preview_id = (int) $_GET['page_id']; + + } + + // bail early id $preview_id does not match $post_id + if ( $preview_id != $post_id ) { + return $post_id; + } + + // attempt find revision + $revision = acf_get_post_latest_revision( $post_id ); + + // save + if ( $revision && $revision->post_parent == $post_id ) { + + $post_id = (int) $revision->ID; + + } + + // set cache + $this->cache[ $k ] = $post_id; + + // return + return $post_id; + + } + + } + + // initialize + acf()->revisions = new acf_revisions(); endif; // class_exists check @@ -420,27 +404,26 @@ endif; // class_exists check * * This function will copy meta from a post to it's latest revision * -* @type function -* @date 26/09/2016 -* @since 5.4.0 +* @type function +* @date 26/09/2016 +* @since 5.4.0 * -* @param $post_id (int) -* @return n/a +* @param $post_id (int) +* @return n/a */ function acf_save_post_revision( $post_id = 0 ) { - + // get latest revision $revision = acf_get_post_latest_revision( $post_id ); - - + // save - if( $revision ) { - + if ( $revision ) { + acf_copy_postmeta( $post_id, $revision->ID ); - + } - + } @@ -449,28 +432,26 @@ function acf_save_post_revision( $post_id = 0 ) { * * This function will return the latest revision for a given post * -* @type function -* @date 25/06/2016 -* @since 5.3.8 +* @type function +* @date 25/06/2016 +* @since 5.3.8 * -* @param $post_id (int) -* @return $post_id (int) +* @param $post_id (int) +* @return $post_id (int) */ function acf_get_post_latest_revision( $post_id ) { - + // vars $revisions = wp_get_post_revisions( $post_id ); - - + // shift off and return first revision (will return null if no revisions) - $revision = array_shift($revisions); - - + $revision = array_shift( $revisions ); + // return - return $revision; - + return $revision; + } -?> \ No newline at end of file + diff --git a/includes/third-party.php b/includes/third-party.php index 286cc52..075c14d 100644 --- a/includes/third-party.php +++ b/includes/third-party.php @@ -5,210 +5,202 @@ * * All the logic for 3rd party functionality * -* @class acf_third_party -* @package ACF -* @subpackage Core +* @class acf_third_party +* @package ACF +* @subpackage Core */ -if( ! class_exists('acf_third_party') ) : +if ( ! class_exists( 'acf_third_party' ) ) : -class acf_third_party { - - - /* - * __construct - * - * This function will setup the class functionality - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function __construct() { - - // Tabify Edit Screen - http://wordpress.org/extend/plugins/tabify-edit-screen/ - if( class_exists('Tabify_Edit_Screen') ) { - add_filter('tabify_posttypes', array($this, 'tabify_posttypes')); - add_action('tabify_add_meta_boxes', array($this, 'tabify_add_meta_boxes')); - } - - // Post Type Switcher - http://wordpress.org/extend/plugins/post-type-switcher/ - if( class_exists('Post_Type_Switcher') ) { - add_filter('pts_allowed_pages', array($this, 'pts_allowed_pages')); - } - - // Event Espresso - https://wordpress.org/plugins/event-espresso-decaf/ - if( function_exists('espresso_version') ) { - add_filter('acf/get_post_types', array($this, 'ee_get_post_types'), 10, 2); - } - - // Dark Mode - if( class_exists('Dark_Mode') ) { - add_action('doing_dark_mode', array($this, 'doing_dark_mode')); - } - } - - - /** - * acf_get_post_types - * - * EE post types do not use the native post.php edit page, but instead render their own. - * Show the EE post types in lists where 'show_ui' is used. - * - * @date 24/2/18 - * @since 5.6.9 - * - * @param array $post_types - * @param array $args - * @return array - */ - - function ee_get_post_types( $post_types, $args ) { - - if( !empty($args['show_ui']) ) { - $ee_post_types = get_post_types(array('show_ee_ui' => 1)); - $ee_post_types = array_keys($ee_post_types); - $post_types = array_merge($post_types, $ee_post_types); - $post_types = array_unique($post_types); - } - - // return - return $post_types; - } - - - /* - * tabify_posttypes - * - * This function removes ACF post types from the tabify edit screen (post type selection sidebar) - * - * @type function - * @date 9/10/12 - * @since 3.5.1 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function tabify_posttypes( $posttypes ) { - - // unset - unset( $posttypes['acf-field-group'] ); - unset( $posttypes['acf-field'] ); - - - // return - return $posttypes; - } - - - /* - * tabify_add_meta_boxes - * - * This function creates dummy metaboxes on the tabify edit screen page - * - * @type function - * @date 9/10/12 - * @since 3.5.1 - * - * @param $post_type (string) - * @return n/a - */ - - function tabify_add_meta_boxes( $post_type ) { - - // get field groups - $field_groups = acf_get_field_groups(); - - - if( !empty($field_groups) ) { - - foreach( $field_groups as $field_group ) { - - // vars - $id = "acf-{$field_group['key']}"; - $title = 'ACF: ' . $field_group['title']; + class acf_third_party { - - - // add meta box - add_meta_box( $id, acf_esc_html( $title ), '__return_true', $post_type ); - + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // Tabify Edit Screen - http://wordpress.org/extend/plugins/tabify-edit-screen/ + if ( class_exists( 'Tabify_Edit_Screen' ) ) { + add_filter( 'tabify_posttypes', array( $this, 'tabify_posttypes' ) ); + add_action( 'tabify_add_meta_boxes', array( $this, 'tabify_add_meta_boxes' ) ); } - - } - - } - - - /* - * pts_allowed_pages - * - * This filter will prevent PTS from running on the field group page! - * - * @type function - * @date 25/09/2014 - * @since 5.0.0 - * - * @param $pages (array) - * @return $pages - */ - - function pts_allowed_pages( $pages ) { - - // vars - $post_type = ''; - - - // check $_GET becuase it is too early to use functions / global vars - if( !empty($_GET['post_type']) ) { - - $post_type = $_GET['post_type']; - - } elseif( !empty($_GET['post']) ) { - - $post_type = get_post_type( $_GET['post'] ); - - } - - - // check post type - if( $post_type == 'acf-field-group' ) { - - $pages = array(); - - } - - - // return - return $pages; - - } - - /** - * doing_dark_mode - * - * Runs during 'admin_enqueue_scripts' if dark mode is enabled - * - * @date 13/8/18 - * @since 5.7.3 - * - * @param void - * @return void - */ - - function doing_dark_mode() { - wp_enqueue_style('acf-dark', acf_get_url('assets/css/acf-dark.css'), array(), ACF_VERSION ); - } - -} -new acf_third_party(); + // Post Type Switcher - http://wordpress.org/extend/plugins/post-type-switcher/ + if ( class_exists( 'Post_Type_Switcher' ) ) { + add_filter( 'pts_allowed_pages', array( $this, 'pts_allowed_pages' ) ); + } + + // Event Espresso - https://wordpress.org/plugins/event-espresso-decaf/ + if ( function_exists( 'espresso_version' ) ) { + add_filter( 'acf/get_post_types', array( $this, 'ee_get_post_types' ), 10, 2 ); + } + + // Dark Mode + if ( class_exists( 'Dark_Mode' ) ) { + add_action( 'doing_dark_mode', array( $this, 'doing_dark_mode' ) ); + } + } + + + /** + * acf_get_post_types + * + * EE post types do not use the native post.php edit page, but instead render their own. + * Show the EE post types in lists where 'show_ui' is used. + * + * @date 24/2/18 + * @since 5.6.9 + * + * @param array $post_types + * @param array $args + * @return array + */ + + function ee_get_post_types( $post_types, $args ) { + + if ( ! empty( $args['show_ui'] ) ) { + $ee_post_types = get_post_types( array( 'show_ee_ui' => 1 ) ); + $ee_post_types = array_keys( $ee_post_types ); + $post_types = array_merge( $post_types, $ee_post_types ); + $post_types = array_unique( $post_types ); + } + + // return + return $post_types; + } + + + /* + * tabify_posttypes + * + * This function removes ACF post types from the tabify edit screen (post type selection sidebar) + * + * @type function + * @date 9/10/12 + * @since 3.5.1 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function tabify_posttypes( $posttypes ) { + + // unset + unset( $posttypes['acf-field-group'] ); + unset( $posttypes['acf-field'] ); + + // return + return $posttypes; + } + + + /* + * tabify_add_meta_boxes + * + * This function creates dummy metaboxes on the tabify edit screen page + * + * @type function + * @date 9/10/12 + * @since 3.5.1 + * + * @param $post_type (string) + * @return n/a + */ + + function tabify_add_meta_boxes( $post_type ) { + + // get field groups + $field_groups = acf_get_field_groups(); + + if ( ! empty( $field_groups ) ) { + + foreach ( $field_groups as $field_group ) { + + // vars + $id = "acf-{$field_group['key']}"; + $title = 'ACF: ' . $field_group['title']; + + // add meta box + add_meta_box( $id, acf_esc_html( $title ), '__return_true', $post_type ); + + } + } + + } + + + /* + * pts_allowed_pages + * + * This filter will prevent PTS from running on the field group page! + * + * @type function + * @date 25/09/2014 + * @since 5.0.0 + * + * @param $pages (array) + * @return $pages + */ + + function pts_allowed_pages( $pages ) { + + // vars + $post_type = ''; + + // check $_GET becuase it is too early to use functions / global vars + if ( ! empty( $_GET['post_type'] ) ) { + + $post_type = $_GET['post_type']; + + } elseif ( ! empty( $_GET['post'] ) ) { + + $post_type = get_post_type( $_GET['post'] ); + + } + + // check post type + if ( $post_type == 'acf-field-group' ) { + + $pages = array(); + + } + + // return + return $pages; + + } + + /** + * doing_dark_mode + * + * Runs during 'admin_enqueue_scripts' if dark mode is enabled + * + * @date 13/8/18 + * @since 5.7.3 + * + * @param void + * @return void + */ + + function doing_dark_mode() { + wp_enqueue_style( 'acf-dark', acf_get_url( 'assets/css/acf-dark.css' ), array(), ACF_VERSION ); + } + + } + + new acf_third_party(); endif; -?> \ No newline at end of file + diff --git a/includes/updates.php b/includes/updates.php index bb0cd7f..0746e73 100644 --- a/includes/updates.php +++ b/includes/updates.php @@ -1,490 +1,508 @@ - '', - 'key' => '', - 'slug' => '', - 'basename' => '', - 'version' => '', - )); - - // Check if is_plugin_active() function exists. This is required on the front end of the - // site, since it is in a file that is normally only loaded in the admin. - if( !function_exists( 'is_plugin_active' ) ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; + class ACF_Updates { + + /** @var string The ACF_Updates version */ + var $version = '2.4'; + + /** @var array The array of registered plugins */ + var $plugins = array(); + + /** @var int Counts the number of plugin update checks */ + var $checked = 0; + + /* + * __construct + * + * Sets up the class functionality. + * + * @date 5/03/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + + function __construct() { + + // append update information to transient + add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'modify_plugins_transient' ), 10, 1 ); + + // modify plugin data visible in the 'View details' popup + add_filter( 'plugins_api', array( $this, 'modify_plugin_details' ), 10, 3 ); } - - // add if is active plugin (not included in theme) - if( is_plugin_active($plugin['basename']) ) { - $this->plugins[ $plugin['basename'] ] = $plugin; - } - } - - /** - * get_plugin_by - * - * Returns a registered plugin for the give key and value. - * - * @date 3/8/18 - * @since 5.7.2 - * - * @param string $key The array key to compare - * @param string $value The value to compare against - * @return array|false - */ - - function get_plugin_by( $key = '', $value = null ) { - foreach( $this->plugins as $plugin ) { - if( $plugin[$key] === $value ) { - return $plugin; + + /* + * add_plugin + * + * Registeres a plugin for updates. + * + * @date 8/4/17 + * @since 5.5.10 + * + * @param array $plugin The plugin array. + * @return void + */ + + function add_plugin( $plugin ) { + + // validate + $plugin = wp_parse_args( + $plugin, + array( + 'id' => '', + 'key' => '', + 'slug' => '', + 'basename' => '', + 'version' => '', + ) + ); + + // Check if is_plugin_active() function exists. This is required on the front end of the + // site, since it is in a file that is normally only loaded in the admin. + if ( ! function_exists( 'is_plugin_active' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + // add if is active plugin (not included in theme) + if ( is_plugin_active( $plugin['basename'] ) ) { + $this->plugins[ $plugin['basename'] ] = $plugin; } } - return false; - } - - /* - * request - * - * Makes a request to the ACF connect server. - * - * @date 8/4/17 - * @since 5.5.10 - * - * @param string $endpoint The API endpoint. - * @param array $body The body to post. - * @return (array|string|WP_Error) - */ - function request( $endpoint = '', $body = null ) { - - // Determine URL. - $url = "https://connect.advancedcustomfields.com/$endpoint"; - - // Staging environment. - if( defined('ACF_DEV_API') && ACF_DEV_API === 'STAGE' ) { - $url = "https://staging.connect.advancedcustomfields.com/$endpoint"; - acf_log( $url, $body ); - - // Dev environment. - } elseif( defined('ACF_DEV_API') && ACF_DEV_API ) { - $url = "http://connect/$endpoint"; - acf_log( $url, $body ); - } - - // Make request. - $raw_response = wp_remote_post( $url, array( - 'timeout' => 10, - 'body' => $body - )); - - // Handle response error. - if( is_wp_error($raw_response) ) { - return $raw_response; - - // Handle http error. - } elseif( wp_remote_retrieve_response_code($raw_response) != 200 ) { - return new WP_Error( 'server_error', wp_remote_retrieve_response_message($raw_response) ); - } - - // Decode JSON response. - $json = json_decode( wp_remote_retrieve_body($raw_response), true ); - - // Allow non json value. - if( $json === null ) { - return wp_remote_retrieve_body($raw_response); - } - - // return - return $json; - } - - /* - * get_plugin_info - * - * Returns update information for the given plugin id. - * - * @date 9/4/17 - * @since 5.5.10 - * - * @param string $id The plugin id such as 'pro'. - * @param boolean $force_check Bypasses cached result. Defaults to false. - * @return array|WP_Error - */ - - function get_plugin_info( $id = '', $force_check = false ) { - - // var - $transient_name = 'acf_plugin_info_' . $id; - - // check cache but allow for $force_check override - if( !$force_check ) { - $transient = get_transient( $transient_name ); - if( $transient !== false ) { - return $transient; - } - } - - // connect - $response = $this->request('v2/plugins/get-info?p='.$id); - - // convert string (misc error) to WP_Error object - if( is_string($response) ) { - $response = new WP_Error( 'server_error', esc_html($response) ); - } - - // allow json to include expiration but force minimum and max for safety - $expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS); - - // update transient - set_transient( $transient_name, $response, $expiration ); - - // return - return $response; - } - - /** - * get_plugin_update - * - * Returns specific data from the 'update-check' response. - * - * @date 3/8/18 - * @since 5.7.2 - * - * @param string $basename The plugin basename. - * @param boolean $force_check Bypasses cached result. Defaults to false - * @return array - */ - - function get_plugin_update( $basename = '', $force_check = false ) { - - // get updates - $updates = $this->get_plugin_updates( $force_check ); - - // check for and return update - if( is_array($updates) && isset($updates['plugins'][ $basename ]) ) { - return $updates['plugins'][ $basename ]; - } - return false; - } - - - /** - * get_plugin_updates - * - * Checks for plugin updates. - * - * @date 8/7/18 - * @since 5.6.9 - * @since 5.7.2 Added 'checked' comparison - * - * @param boolean $force_check Bypasses cached result. Defaults to false. - * @return array|WP_Error. - */ - - function get_plugin_updates( $force_check = false ) { - - // var - $transient_name = 'acf_plugin_updates'; - - // construct array of 'checked' plugins - // sort by key to avoid detecting change due to "include order" - $checked = array(); - foreach( $this->plugins as $basename => $plugin ) { - $checked[ $basename ] = $plugin['version']; - } - ksort($checked); - - // $force_check prevents transient lookup - if( !$force_check ) { - $transient = get_transient($transient_name); - // if cached response was found, compare $transient['checked'] against $checked and ignore if they don't match (plugins/versions have changed) - if( is_array($transient) ) { - $transient_checked = isset($transient['checked']) ? $transient['checked'] : array(); - if( wp_json_encode($checked) !== wp_json_encode($transient_checked) ) { - $transient = false; + /** + * get_plugin_by + * + * Returns a registered plugin for the give key and value. + * + * @date 3/8/18 + * @since 5.7.2 + * + * @param string $key The array key to compare + * @param string $value The value to compare against + * @return array|false + */ + + function get_plugin_by( $key = '', $value = null ) { + foreach ( $this->plugins as $plugin ) { + if ( $plugin[ $key ] === $value ) { + return $plugin; } } - if( $transient !== false ) { + return false; + } + + /* + * request + * + * Makes a request to the ACF connect server. + * + * @date 8/4/17 + * @since 5.5.10 + * + * @param string $endpoint The API endpoint. + * @param array $body The body to post. + * @return (array|string|WP_Error) + */ + function request( $endpoint = '', $body = null ) { + + // Determine URL. + $url = "https://connect.advancedcustomfields.com/$endpoint"; + + // Staging environment. + if ( defined( 'ACF_DEV_API' ) && ACF_DEV_API === 'STAGE' ) { + $url = "https://staging.connect.advancedcustomfields.com/$endpoint"; + acf_log( $url, $body ); + + // Dev environment. + } elseif ( defined( 'ACF_DEV_API' ) && ACF_DEV_API ) { + $url = "http://connect/$endpoint"; + acf_log( $url, $body ); + } + + // Make request. + $raw_response = wp_remote_post( + $url, + array( + 'timeout' => 10, + 'body' => $body, + ) + ); + + // Handle response error. + if ( is_wp_error( $raw_response ) ) { + return $raw_response; + + // Handle http error. + } elseif ( wp_remote_retrieve_response_code( $raw_response ) != 200 ) { + return new WP_Error( 'server_error', wp_remote_retrieve_response_message( $raw_response ) ); + } + + // Decode JSON response. + $json = json_decode( wp_remote_retrieve_body( $raw_response ), true ); + + // Allow non json value. + if ( $json === null ) { + return wp_remote_retrieve_body( $raw_response ); + } + + // return + return $json; + } + + /* + * get_plugin_info + * + * Returns update information for the given plugin id. + * + * @date 9/4/17 + * @since 5.5.10 + * + * @param string $id The plugin id such as 'pro'. + * @param boolean $force_check Bypasses cached result. Defaults to false. + * @return array|WP_Error + */ + + function get_plugin_info( $id = '', $force_check = false ) { + + // var + $transient_name = 'acf_plugin_info_' . $id; + + // check cache but allow for $force_check override + if ( ! $force_check ) { + $transient = get_transient( $transient_name ); + if ( $transient !== false ) { + return $transient; + } + } + + // connect + $response = $this->request( 'v2/plugins/get-info?p=' . $id ); + + // convert string (misc error) to WP_Error object + if ( is_string( $response ) ) { + $response = new WP_Error( 'server_error', esc_html( $response ) ); + } + + // allow json to include expiration but force minimum and max for safety + $expiration = $this->get_expiration( $response, DAY_IN_SECONDS, MONTH_IN_SECONDS ); + + // update transient + set_transient( $transient_name, $response, $expiration ); + + // return + return $response; + } + + /** + * get_plugin_update + * + * Returns specific data from the 'update-check' response. + * + * @date 3/8/18 + * @since 5.7.2 + * + * @param string $basename The plugin basename. + * @param boolean $force_check Bypasses cached result. Defaults to false + * @return array + */ + + function get_plugin_update( $basename = '', $force_check = false ) { + + // get updates + $updates = $this->get_plugin_updates( $force_check ); + + // check for and return update + if ( is_array( $updates ) && isset( $updates['plugins'][ $basename ] ) ) { + return $updates['plugins'][ $basename ]; + } + return false; + } + + + /** + * get_plugin_updates + * + * Checks for plugin updates. + * + * @date 8/7/18 + * @since 5.6.9 + * @since 5.7.2 Added 'checked' comparison + * + * @param boolean $force_check Bypasses cached result. Defaults to false. + * @return array|WP_Error. + */ + + function get_plugin_updates( $force_check = false ) { + + // var + $transient_name = 'acf_plugin_updates'; + + // construct array of 'checked' plugins + // sort by key to avoid detecting change due to "include order" + $checked = array(); + foreach ( $this->plugins as $basename => $plugin ) { + $checked[ $basename ] = $plugin['version']; + } + ksort( $checked ); + + // $force_check prevents transient lookup + if ( ! $force_check ) { + $transient = get_transient( $transient_name ); + + // if cached response was found, compare $transient['checked'] against $checked and ignore if they don't match (plugins/versions have changed) + if ( is_array( $transient ) ) { + $transient_checked = isset( $transient['checked'] ) ? $transient['checked'] : array(); + if ( wp_json_encode( $checked ) !== wp_json_encode( $transient_checked ) ) { + $transient = false; + } + } + if ( $transient !== false ) { + return $transient; + } + } + + // vars + $post = array( + 'plugins' => wp_json_encode( $this->plugins ), + 'wp' => wp_json_encode( + array( + 'wp_name' => get_bloginfo( 'name' ), + 'wp_url' => home_url(), + 'wp_version' => get_bloginfo( 'version' ), + 'wp_language' => get_bloginfo( 'language' ), + 'wp_timezone' => get_option( 'timezone_string' ), + ) + ), + 'acf' => wp_json_encode( + array( + 'acf_version' => get_option( 'acf_version' ), + 'acf_pro' => ( defined( 'ACF_PRO' ) && ACF_PRO ), + ) + ), + ); + + // request + $response = $this->request( 'v2/plugins/update-check', $post ); + + // append checked reference + if ( is_array( $response ) ) { + $response['checked'] = $checked; + } + + // allow json to include expiration but force minimum and max for safety + $expiration = $this->get_expiration( $response, DAY_IN_SECONDS, MONTH_IN_SECONDS ); + + // update transient + set_transient( $transient_name, $response, $expiration ); + + // return + return $response; + } + + /** + * get_expiration + * + * This function safely gets the expiration value from a response. + * + * @date 8/7/18 + * @since 5.6.9 + * + * @param mixed $response The response from the server. Default false. + * @param int $min The minimum expiration limit. Default 0. + * @param int $max The maximum expiration limit. Default 0. + * @return int + */ + + function get_expiration( $response = false, $min = 0, $max = 0 ) { + + // vars + $expiration = 0; + + // check + if ( is_array( $response ) && isset( $response['expiration'] ) ) { + $expiration = (int) $response['expiration']; + } + + // min + if ( $expiration < $min ) { + return $min; + } + + // max + if ( $expiration > $max ) { + return $max; + } + + // return + return $expiration; + } + + /* + * refresh_plugins_transient + * + * Deletes transients and allows a fresh lookup. + * + * @date 11/4/17 + * @since 5.5.10 + * + * @param void + * @return void + */ + + function refresh_plugins_transient() { + delete_site_transient( 'update_plugins' ); + delete_transient( 'acf_plugin_updates' ); + } + + /* + * modify_plugins_transient + * + * Called when WP updates the 'update_plugins' site transient. Used to inject ACF plugin update info. + * + * @date 16/01/2014 + * @since 5.0.0 + * + * @param object $transient + * @return $transient + */ + + function modify_plugins_transient( $transient ) { + + // bail early if no response (error) + if ( ! isset( $transient->response ) ) { return $transient; } - } - - // vars - $post = array( - 'plugins' => wp_json_encode($this->plugins), - 'wp' => wp_json_encode(array( - 'wp_name' => get_bloginfo('name'), - 'wp_url' => home_url(), - 'wp_version' => get_bloginfo('version'), - 'wp_language' => get_bloginfo('language'), - 'wp_timezone' => get_option('timezone_string'), - )), - 'acf' => wp_json_encode(array( - 'acf_version' => get_option('acf_version'), - 'acf_pro' => (defined('ACF_PRO') && ACF_PRO), - )), - ); - - // request - $response = $this->request('v2/plugins/update-check', $post); - - // append checked reference - if( is_array($response) ) { - $response['checked'] = $checked; - } - - // allow json to include expiration but force minimum and max for safety - $expiration = $this->get_expiration($response, DAY_IN_SECONDS, MONTH_IN_SECONDS); - - // update transient - set_transient($transient_name, $response, $expiration ); - - // return - return $response; - } - - /** - * get_expiration - * - * This function safely gets the expiration value from a response. - * - * @date 8/7/18 - * @since 5.6.9 - * - * @param mixed $response The response from the server. Default false. - * @param int $min The minimum expiration limit. Default 0. - * @param int $max The maximum expiration limit. Default 0. - * @return int - */ - - function get_expiration( $response = false, $min = 0, $max = 0 ) { - - // vars - $expiration = 0; - - // check - if( is_array($response) && isset($response['expiration']) ) { - $expiration = (int) $response['expiration']; - } - - // min - if( $expiration < $min ) { - return $min; - } - - // max - if( $expiration > $max ) { - return $max; - } - - // return - return $expiration; - } - - /* - * refresh_plugins_transient - * - * Deletes transients and allows a fresh lookup. - * - * @date 11/4/17 - * @since 5.5.10 - * - * @param void - * @return void - */ - - function refresh_plugins_transient() { - delete_site_transient('update_plugins'); - delete_transient('acf_plugin_updates'); - } - - /* - * modify_plugins_transient - * - * Called when WP updates the 'update_plugins' site transient. Used to inject ACF plugin update info. - * - * @date 16/01/2014 - * @since 5.0.0 - * - * @param object $transient - * @return $transient - */ - - function modify_plugins_transient( $transient ) { - - // bail early if no response (error) - if( !isset($transient->response) ) { + + // force-check (only once) + $force_check = ( $this->checked == 0 ) ? ! empty( $_GET['force-check'] ) : false; + + // fetch updates (this filter is called multiple times during a single page load) + $updates = $this->get_plugin_updates( $force_check ); + + // append + if ( is_array( $updates ) ) { + foreach ( $updates['plugins'] as $basename => $update ) { + $transient->response[ $basename ] = (object) $update; + } + } + + // increase + $this->checked++; + + // return return $transient; } - - // force-check (only once) - $force_check = ($this->checked == 0) ? !empty($_GET['force-check']) : false; - - // fetch updates (this filter is called multiple times during a single page load) - $updates = $this->get_plugin_updates( $force_check ); - - // append - if( is_array($updates) ) { - foreach( $updates['plugins'] as $basename => $update ) { - $transient->response[ $basename ] = (object) $update; + + /* + * modify_plugin_details + * + * Returns the plugin data visible in the 'View details' popup + * + * @date 17/01/2014 + * @since 5.0.0 + * + * @param object $result + * @param string $action + * @param object $args + * @return $result + */ + + function modify_plugin_details( $result, $action = null, $args = null ) { + + // vars + $plugin = false; + + // only for 'plugin_information' action + if ( $action !== 'plugin_information' ) { + return $result; } + + // find plugin via slug + $plugin = $this->get_plugin_by( 'slug', $args->slug ); + if ( ! $plugin ) { + return $result; + } + + // connect + $response = $this->get_plugin_info( $plugin['id'] ); + + // bail early if no response + if ( ! is_array( $response ) ) { + return $result; + } + + // remove tags (different context) + unset( $response['tags'] ); + + // convert to object + $response = (object) $response; + + // sections + $sections = array( + 'description' => '', + 'installation' => '', + 'changelog' => '', + 'upgrade_notice' => '', + ); + foreach ( $sections as $k => $v ) { + $sections[ $k ] = $response->$k; + } + $response->sections = $sections; + + // return + return $response; } - - // increase - $this->checked++; - - // return - return $transient; } - + + /* - * modify_plugin_details + * acf_updates * - * Returns the plugin data visible in the 'View details' popup + * The main function responsible for returning the one true acf_updates instance to functions everywhere. + * Use this function like you would a global variable, except without needing to declare the global. * - * @date 17/01/2014 - * @since 5.0.0 + * Example: * - * @param object $result - * @param string $action - * @param object $args - * @return $result + * @date 9/4/17 + * @since 5.5.12 + * + * @param void + * @return object */ - - function modify_plugin_details( $result, $action = null, $args = null ) { - - // vars - $plugin = false; - - // only for 'plugin_information' action - if( $action !== 'plugin_information' ) return $result; - - // find plugin via slug - $plugin = $this->get_plugin_by('slug', $args->slug); - if( !$plugin ) return $result; - - // connect - $response = $this->get_plugin_info($plugin['id']); - - // bail early if no response - if( !is_array($response) ) return $result; - - // remove tags (different context) - unset($response['tags']); - - // convert to object - $response = (object) $response; - - // sections - $sections = array( - 'description' => '', - 'installation' => '', - 'changelog' => '', - 'upgrade_notice' => '' - ); - foreach( $sections as $k => $v ) { - $sections[ $k ] = $response->$k; - } - $response->sections = $sections; - - // return - return $response; - } -} - -/* -* acf_updates -* -* The main function responsible for returning the one true acf_updates instance to functions everywhere. -* Use this function like you would a global variable, except without needing to declare the global. -* -* Example: -* -* @date 9/4/17 -* @since 5.5.12 -* -* @param void -* @return object -*/ - -function acf_updates() { - global $acf_updates; - if( !isset($acf_updates) ) { - $acf_updates = new ACF_Updates(); + function acf_updates() { + global $acf_updates; + if ( ! isset( $acf_updates ) ) { + $acf_updates = new ACF_Updates(); + } + return $acf_updates; } - return $acf_updates; -} -/* -* acf_register_plugin_update -* -* Alias of acf_updates()->add_plugin(). -* -* @type function -* @date 12/4/17 -* @since 5.5.10 -* -* @param array $plugin -* @return void -*/ + /* + * acf_register_plugin_update + * + * Alias of acf_updates()->add_plugin(). + * + * @type function + * @date 12/4/17 + * @since 5.5.10 + * + * @param array $plugin + * @return void + */ -function acf_register_plugin_update( $plugin ) { - acf_updates()->add_plugin( $plugin ); -} + function acf_register_plugin_update( $plugin ) { + acf_updates()->add_plugin( $plugin ); + } endif; // class_exists check -?> \ No newline at end of file + diff --git a/includes/upgrades.php b/includes/upgrades.php index b6acec8..de5ba40 100644 --- a/includes/upgrades.php +++ b/includes/upgrades.php @@ -1,91 +1,91 @@ num_queries, timer_stop(0)); + acf_dev_log( 'ACF Upgrade Complete.', $wpdb->num_queries, timer_stop( 0 ) ); } /** -* acf_get_db_version -* -* Returns the ACF DB version. -* -* @date 10/09/2016 -* @since 5.4.0 -* -* @param void -* @return string -*/ + * acf_get_db_version + * + * Returns the ACF DB version. + * + * @date 10/09/2016 + * @since 5.4.0 + * + * @param void + * @return string + */ function acf_get_db_version() { - return get_option('acf_version'); + return get_option( 'acf_version' ); } /* @@ -93,339 +93,344 @@ function acf_get_db_version() { * * Updates the ACF DB version. * -* @date 10/09/2016 -* @since 5.4.0 +* @date 10/09/2016 +* @since 5.4.0 * -* @param string $version The new version. -* @return void +* @param string $version The new version. +* @return void */ function acf_update_db_version( $version = '' ) { - update_option('acf_version', $version ); + update_option( 'acf_version', $version ); } /** -* acf_upgrade_500 -* -* Version 5 introduces new post types for field groups and fields. -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param void -* @return void -*/ + * acf_upgrade_500 + * + * Version 5 introduces new post types for field groups and fields. + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ function acf_upgrade_500() { - + // log - acf_dev_log('ACF Upgrade 5.0.0.'); - + acf_dev_log( 'ACF Upgrade 5.0.0.' ); + // action - do_action('acf/upgrade_500'); - + do_action( 'acf/upgrade_500' ); + // do tasks acf_upgrade_500_field_groups(); - + // update version - acf_update_db_version('5.0.0'); + acf_update_db_version( '5.0.0' ); } /** -* acf_upgrade_500_field_groups -* -* Upgrades all ACF4 field groups to ACF5 -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param void -* @return void -*/ + * acf_upgrade_500_field_groups + * + * Upgrades all ACF4 field groups to ACF5 + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ function acf_upgrade_500_field_groups() { - + // log - acf_dev_log('ACF Upgrade 5.0.0 Field Groups.'); - + acf_dev_log( 'ACF Upgrade 5.0.0 Field Groups.' ); + // get old field groups - $ofgs = get_posts(array( - 'numberposts' => -1, - 'post_type' => 'acf', - 'orderby' => 'menu_order title', - 'order' => 'asc', - 'suppress_filters' => true, - )); - + $ofgs = get_posts( + array( + 'numberposts' => -1, + 'post_type' => 'acf', + 'orderby' => 'menu_order title', + 'order' => 'asc', + 'suppress_filters' => true, + ) + ); + // loop - if( $ofgs ) { - foreach( $ofgs as $ofg ){ + if ( $ofgs ) { + foreach ( $ofgs as $ofg ) { acf_upgrade_500_field_group( $ofg ); } } } /** -* acf_upgrade_500_field_group -* -* Upgrades a ACF4 field group to ACF5 -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param object $ofg The old field group post object. -* @return array $nfg The new field group array. -*/ + * acf_upgrade_500_field_group + * + * Upgrades a ACF4 field group to ACF5 + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param object $ofg The old field group post object. + * @return array $nfg The new field group array. + */ function acf_upgrade_500_field_group( $ofg ) { - + // log - acf_dev_log('ACF Upgrade 5.0.0 Field Group.', $ofg); - + acf_dev_log( 'ACF Upgrade 5.0.0 Field Group.', $ofg ); + // vars $nfg = array( - 'ID' => 0, - 'title' => $ofg->post_title, - 'menu_order' => $ofg->menu_order, + 'ID' => 0, + 'title' => $ofg->post_title, + 'menu_order' => $ofg->menu_order, ); - + // construct the location rules - $rules = get_post_meta($ofg->ID, 'rule', false); - $anyorall = get_post_meta($ofg->ID, 'allorany', true); - if( is_array($rules) ) { - + $rules = get_post_meta( $ofg->ID, 'rule', false ); + $anyorall = get_post_meta( $ofg->ID, 'allorany', true ); + if ( is_array( $rules ) ) { + // if field group was duplicated, rules may be a serialized string! - $rules = array_map('maybe_unserialize', $rules); - + $rules = array_map( 'maybe_unserialize', $rules ); + // convert rules to groups $nfg['location'] = acf_convert_rules_to_groups( $rules, $anyorall ); } - + // settings - if( $position = get_post_meta($ofg->ID, 'position', true) ) { + if ( $position = get_post_meta( $ofg->ID, 'position', true ) ) { $nfg['position'] = $position; } - - if( $layout = get_post_meta($ofg->ID, 'layout', true) ) { + + if ( $layout = get_post_meta( $ofg->ID, 'layout', true ) ) { $nfg['layout'] = $layout; } - - if( $hide_on_screen = get_post_meta($ofg->ID, 'hide_on_screen', true) ) { - $nfg['hide_on_screen'] = maybe_unserialize($hide_on_screen); + + if ( $hide_on_screen = get_post_meta( $ofg->ID, 'hide_on_screen', true ) ) { + $nfg['hide_on_screen'] = maybe_unserialize( $hide_on_screen ); } - + // save field group // acf_upgrade_field_group will call the acf_get_valid_field_group function and apply 'compatibility' changes $nfg = acf_update_field_group( $nfg ); - + // log - acf_dev_log('> Complete.', $nfg); - + acf_dev_log( '> Complete.', $nfg ); + // action for 3rd party - do_action('acf/upgrade_500_field_group', $nfg, $ofg); - + do_action( 'acf/upgrade_500_field_group', $nfg, $ofg ); + // upgrade fields acf_upgrade_500_fields( $ofg, $nfg ); - + // trash? - if( $ofg->post_status == 'trash' ) { + if ( $ofg->post_status == 'trash' ) { acf_trash_field_group( $nfg['ID'] ); } - + // return return $nfg; } /** -* acf_upgrade_500_fields -* -* Upgrades all ACF4 fields to ACF5 from a specific field group -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param object $ofg The old field group post object. -* @param array $nfg The new field group array. -* @return void -*/ + * acf_upgrade_500_fields + * + * Upgrades all ACF4 fields to ACF5 from a specific field group + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param object $ofg The old field group post object. + * @param array $nfg The new field group array. + * @return void + */ function acf_upgrade_500_fields( $ofg, $nfg ) { - + // log - acf_dev_log('ACF Upgrade 5.0.0 Fields.'); - + acf_dev_log( 'ACF Upgrade 5.0.0 Fields.' ); + // global global $wpdb; - + // get field from postmeta - $rows = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE %s", $ofg->ID, 'field_%'), ARRAY_A); - + $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE %s", $ofg->ID, 'field_%' ), ARRAY_A ); + // check - if( $rows ) { - + if ( $rows ) { + // vars $checked = array(); - + // loop - foreach( $rows as $row ) { - + foreach ( $rows as $row ) { + // vars $field = $row['meta_value']; $field = maybe_unserialize( $field ); $field = maybe_unserialize( $field ); // run again for WPML - + // bail early if key already migrated (potential duplicates in DB) - if( isset($checked[ $field['key'] ]) ) continue; + if ( isset( $checked[ $field['key'] ] ) ) { + continue; + } $checked[ $field['key'] ] = 1; - + // add parent $field['parent'] = $nfg['ID']; - + // migrate field $field = acf_upgrade_500_field( $field ); } - } + } } /** -* acf_upgrade_500_field -* -* Upgrades a ACF4 field to ACF5 -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param array $field The old field. -* @return array $field The new field. -*/ + * acf_upgrade_500_field + * + * Upgrades a ACF4 field to ACF5 + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param array $field The old field. + * @return array $field The new field. + */ function acf_upgrade_500_field( $field ) { - + // log - acf_dev_log('ACF Upgrade 5.0.0 Field.', $field); - + acf_dev_log( 'ACF Upgrade 5.0.0 Field.', $field ); + // order_no is now menu_order $field['menu_order'] = acf_extract_var( $field, 'order_no', 0 ); - + // correct very old field keys (field2 => field_2) - if( substr($field['key'], 0, 6) !== 'field_' ) { - $field['key'] = 'field_' . str_replace('field', '', $field['key']); + if ( substr( $field['key'], 0, 6 ) !== 'field_' ) { + $field['key'] = 'field_' . str_replace( 'field', '', $field['key'] ); } - + // extract sub fields $sub_fields = array(); - if( $field['type'] == 'repeater' ) { - + if ( $field['type'] == 'repeater' ) { + // loop over sub fields - if( !empty($field['sub_fields']) ) { - foreach( $field['sub_fields'] as $sub_field ) { + if ( ! empty( $field['sub_fields'] ) ) { + foreach ( $field['sub_fields'] as $sub_field ) { $sub_fields[] = $sub_field; } } - + // remove sub fields from field unset( $field['sub_fields'] ); - - } elseif( $field['type'] == 'flexible_content' ) { - + + } elseif ( $field['type'] == 'flexible_content' ) { + // loop over layouts - if( is_array($field['layouts']) ) { - foreach( $field['layouts'] as $i => $layout ) { - + if ( is_array( $field['layouts'] ) ) { + foreach ( $field['layouts'] as $i => $layout ) { + // generate key - $layout['key'] = uniqid('layout_'); - + $layout['key'] = uniqid( 'layout_' ); + // loop over sub fields - if( !empty($layout['sub_fields']) ) { - foreach( $layout['sub_fields'] as $sub_field ) { + if ( ! empty( $layout['sub_fields'] ) ) { + foreach ( $layout['sub_fields'] as $sub_field ) { $sub_field['parent_layout'] = $layout['key']; - $sub_fields[] = $sub_field; + $sub_fields[] = $sub_field; } } - + // remove sub fields from layout unset( $layout['sub_fields'] ); - + // update $field['layouts'][ $i ] = $layout; - + } } } - + // save field $field = acf_update_field( $field ); - + // log - acf_dev_log('> Complete.', $field); - + acf_dev_log( '> Complete.', $field ); + // sub fields - if( $sub_fields ) { - foreach( $sub_fields as $sub_field ) { + if ( $sub_fields ) { + foreach ( $sub_fields as $sub_field ) { $sub_field['parent'] = $field['ID']; - acf_upgrade_500_field($sub_field); + acf_upgrade_500_field( $sub_field ); } } - + // action for 3rd party - do_action('acf/update_500_field', $field); - + do_action( 'acf/update_500_field', $field ); + // return return $field; } /** -* acf_upgrade_550 -* -* Version 5.5 adds support for the wp_termmeta table added in WP 4.4. -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param void -* @return void -*/ + * acf_upgrade_550 + * + * Version 5.5 adds support for the wp_termmeta table added in WP 4.4. + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ function acf_upgrade_550() { - + // log - acf_dev_log('ACF Upgrade 5.5.0.'); - + acf_dev_log( 'ACF Upgrade 5.5.0.' ); + // action - do_action('acf/upgrade_550'); - + do_action( 'acf/upgrade_550' ); + // do tasks acf_upgrade_550_termmeta(); - + // update version - acf_update_db_version('5.5.0'); + acf_update_db_version( '5.5.0' ); } /** -* acf_upgrade_550_termmeta -* -* Upgrades all ACF4 termmeta saved in wp_options to the wp_termmeta table. -* -* @date 23/8/18 -* @since 5.7.4 -* -* @param void -* @return void -*/ + * acf_upgrade_550_termmeta + * + * Upgrades all ACF4 termmeta saved in wp_options to the wp_termmeta table. + * + * @date 23/8/18 + * @since 5.7.4 + * + * @param void + * @return void + */ function acf_upgrade_550_termmeta() { - + // log - acf_dev_log('ACF Upgrade 5.5.0 Termmeta.'); - + acf_dev_log( 'ACF Upgrade 5.5.0 Termmeta.' ); + // bail early if no wp_termmeta table - if( get_option('db_version') < 34370 ) { + if ( get_option( 'db_version' ) < 34370 ) { return; } - + // get all taxonomies - $taxonomies = get_taxonomies(false, 'objects'); - + $taxonomies = get_taxonomies( false, 'objects' ); + // loop - if( $taxonomies ) { - foreach( $taxonomies as $taxonomy ) { - acf_upgrade_550_taxonomy( $taxonomy->name ); - }} - + if ( $taxonomies ) { + foreach ( $taxonomies as $taxonomy ) { + acf_upgrade_550_taxonomy( $taxonomy->name ); + } + } + // action for 3rd party - do_action('acf/upgrade_550_termmeta'); + do_action( 'acf/upgrade_550_termmeta' ); } /* @@ -433,102 +438,109 @@ function acf_upgrade_550_termmeta() { * * When the database is updated to support term meta, migrate ACF term meta data across. * -* @date 23/8/18 -* @since 5.7.4 +* @date 23/8/18 +* @since 5.7.4 * -* @param string $wp_db_version The new $wp_db_version. -* @param string $wp_current_db_version The old (current) $wp_db_version. -* @return void +* @param string $wp_db_version The new $wp_db_version. +* @param string $wp_current_db_version The old (current) $wp_db_version. +* @return void */ function acf_wp_upgrade_550_termmeta( $wp_db_version, $wp_current_db_version ) { - if( $wp_db_version >= 34370 && $wp_current_db_version < 34370 ) { - if( acf_version_compare(acf_get_db_version(), '>', '5.5.0') ) { + if ( $wp_db_version >= 34370 && $wp_current_db_version < 34370 ) { + if ( acf_version_compare( acf_get_db_version(), '>', '5.5.0' ) ) { acf_upgrade_550_termmeta(); - } + } } } add_action( 'wp_upgrade', 'acf_wp_upgrade_550_termmeta', 10, 2 ); /** -* acf_upgrade_550_taxonomy -* -* Upgrades all ACF4 termmeta for a specific taxonomy. -* -* @date 24/8/18 -* @since 5.7.4 -* -* @param string $taxonomy The taxonomy name. -* @return void -*/ + * acf_upgrade_550_taxonomy + * + * Upgrades all ACF4 termmeta for a specific taxonomy. + * + * @date 24/8/18 + * @since 5.7.4 + * + * @param string $taxonomy The taxonomy name. + * @return void + */ function acf_upgrade_550_taxonomy( $taxonomy ) { - + // log - acf_dev_log('ACF Upgrade 5.5.0 Taxonomy.', $taxonomy); - + acf_dev_log( 'ACF Upgrade 5.5.0 Taxonomy.', $taxonomy ); + // global global $wpdb; - + // vars - $search = $taxonomy . '_%'; + $search = $taxonomy . '_%'; $_search = '_' . $search; - + // escape '_' // http://stackoverflow.com/questions/2300285/how-do-i-escape-in-sql-server - $search = str_replace('_', '\_', $search); - $_search = str_replace('_', '\_', $_search); - + $search = str_replace( '_', '\_', $search ); + $_search = str_replace( '_', '\_', $_search ); + // search // results show faster query times using 2 LIKE vs 2 wildcards - $rows = $wpdb->get_results($wpdb->prepare( - "SELECT * + $rows = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s", - $search, - $_search - ), ARRAY_A); - + $search, + $_search + ), + ARRAY_A + ); + // loop - if( $rows ) { - foreach( $rows as $row ) { - - /* - Use regex to find "(_)taxonomy_(term_id)_(field_name)" and populate $matches: - Array - ( - [0] => _category_3_color - [1] => _ - [2] => 3 - [3] => color - ) - */ - if( !preg_match("/^(_?){$taxonomy}_(\d+)_(.+)/", $row['option_name'], $matches) ) { - continue; + if ( $rows ) { + foreach ( $rows as $row ) { + + /* + Use regex to find "(_)taxonomy_(term_id)_(field_name)" and populate $matches: + Array + ( + [0] => _category_3_color + [1] => _ + [2] => 3 + [3] => color + ) + */ + if ( ! preg_match( "/^(_?){$taxonomy}_(\d+)_(.+)/", $row['option_name'], $matches ) ) { + continue; + } + + // vars + $term_id = $matches[2]; + $meta_key = $matches[1] . $matches[3]; + $meta_value = $row['option_value']; + + // update + // memory usage reduced by 50% by using a manual insert vs update_metadata() function. + // update_metadata( 'term', $term_id, $meta_name, $meta_value ); + $wpdb->insert( + $wpdb->termmeta, + array( + 'term_id' => $term_id, + 'meta_key' => $meta_key, + 'meta_value' => $meta_value, + ) + ); + + // log + acf_dev_log( 'ACF Upgrade 5.5.0 Term.', $term_id, $meta_key ); + + // action + do_action( 'acf/upgrade_550_taxonomy_term', $term_id ); } - - // vars - $term_id = $matches[2]; - $meta_key = $matches[1] . $matches[3]; - $meta_value = $row['option_value']; - - // update - // memory usage reduced by 50% by using a manual insert vs update_metadata() function. - //update_metadata( 'term', $term_id, $meta_name, $meta_value ); - $wpdb->insert( $wpdb->termmeta, array( - 'term_id' => $term_id, - 'meta_key' => $meta_key, - 'meta_value' => $meta_value - )); - - // log - acf_dev_log('ACF Upgrade 5.5.0 Term.', $term_id, $meta_key); - - // action - do_action('acf/upgrade_550_taxonomy_term', $term_id); - }} - + } + // action for 3rd party - do_action('acf/upgrade_550_taxonomy', $taxonomy); + do_action( 'acf/upgrade_550_taxonomy', $taxonomy ); } -?> \ No newline at end of file + diff --git a/includes/validation.php b/includes/validation.php index 070453f..4c08a82 100644 --- a/includes/validation.php +++ b/includes/validation.php @@ -1,215 +1,217 @@ -errors = array(); - - - // ajax - add_action('wp_ajax_acf/validate_save_post', array($this, 'ajax_validate_save_post')); - add_action('wp_ajax_nopriv_acf/validate_save_post', array($this, 'ajax_validate_save_post')); - add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5); - - } - - - /* - * add_error - * - * This function will add an error message for a field - * - * @type function - * @date 25/11/2013 - * @since 5.0.0 - * - * @param $input (string) name attribute of DOM elmenet - * @param $message (string) error message - * @return $post_id (int) - */ - - function add_error( $input, $message ) { - - // add to array - $this->errors[] = array( - 'input' => $input, - 'message' => $message - ); - - } - - - /* - * get_error - * - * This function will return an error for a given input - * - * @type function - * @date 5/03/2016 - * @since 5.3.2 - * - * @param $input (string) name attribute of DOM elmenet - * @return (mixed) - */ - - function get_error( $input ) { - - // bail early if no errors - if( empty($this->errors) ) return false; - - - // loop - foreach( $this->errors as $error ) { - - if( $error['input'] === $input ) return $error; - - } - - - // return - return false; - - } - - - /* - * get_errors - * - * This function will return validation errors - * - * @type function - * @date 25/11/2013 - * @since 5.0.0 - * - * @param n/a - * @return (array|boolean) - */ - - function get_errors() { - - // bail early if no errors - if( empty($this->errors) ) return false; - - - // return - return $this->errors; - - } - - - /* - * reset_errors - * - * This function will remove all errors - * - * @type function - * @date 4/03/2016 - * @since 5.3.2 - * - * @param n/a - * @return n/a - */ - - function reset_errors() { - - $this->errors = array(); - - } - - - /* - * ajax_validate_save_post - * - * This function will validate the $_POST data via AJAX - * - * @type function - * @date 27/10/2014 - * @since 5.0.9 - * - * @param n/a - * @return n/a - */ - - function ajax_validate_save_post() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // vars - $json = array( - 'valid' => 1, - 'errors' => 0 - ); - - - // success - if( acf_validate_save_post() ) { - - wp_send_json_success($json); - - } - - - // update vars - $json['valid'] = 0; - $json['errors'] = acf_get_validation_errors(); - - - // return - wp_send_json_success($json); - - } - - - /* - * acf_validate_save_post - * - * This function will loop over $_POST data and validate - * - * @type function - * @date 7/09/2016 - * @since 5.4.0 - * - * @param n/a - * @return n/a - */ - - function acf_validate_save_post() { - - // bail early if no $_POST - if( empty($_POST['acf']) ) return; - - - // validate - acf_validate_values( $_POST['acf'], 'acf' ); - - } - +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// initialize -acf()->validation = new acf_validation(); +if ( ! class_exists( 'acf_validation' ) ) : + + class acf_validation { + + + /* + * __construct + * + * This function will setup the class functionality + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function __construct() { + + // vars + $this->errors = array(); + + // ajax + add_action( 'wp_ajax_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) ); + add_action( 'wp_ajax_nopriv_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) ); + add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 ); + + } + + + /* + * add_error + * + * This function will add an error message for a field + * + * @type function + * @date 25/11/2013 + * @since 5.0.0 + * + * @param $input (string) name attribute of DOM elmenet + * @param $message (string) error message + * @return $post_id (int) + */ + + function add_error( $input, $message ) { + + // add to array + $this->errors[] = array( + 'input' => $input, + 'message' => $message, + ); + + } + + + /* + * get_error + * + * This function will return an error for a given input + * + * @type function + * @date 5/03/2016 + * @since 5.3.2 + * + * @param $input (string) name attribute of DOM elmenet + * @return (mixed) + */ + + function get_error( $input ) { + + // bail early if no errors + if ( empty( $this->errors ) ) { + return false; + } + + // loop + foreach ( $this->errors as $error ) { + + if ( $error['input'] === $input ) { + return $error; + } + } + + // return + return false; + + } + + + /* + * get_errors + * + * This function will return validation errors + * + * @type function + * @date 25/11/2013 + * @since 5.0.0 + * + * @param n/a + * @return (array|boolean) + */ + + function get_errors() { + + // bail early if no errors + if ( empty( $this->errors ) ) { + return false; + } + + // return + return $this->errors; + + } + + + /* + * reset_errors + * + * This function will remove all errors + * + * @type function + * @date 4/03/2016 + * @since 5.3.2 + * + * @param n/a + * @return n/a + */ + + function reset_errors() { + + $this->errors = array(); + + } + + + /* + * ajax_validate_save_post + * + * This function will validate the $_POST data via AJAX + * + * @type function + * @date 27/10/2014 + * @since 5.0.9 + * + * @param n/a + * @return n/a + */ + + function ajax_validate_save_post() { + + // validate + if ( ! acf_verify_ajax() ) { + die(); + } + + // vars + $json = array( + 'valid' => 1, + 'errors' => 0, + ); + + // success + if ( acf_validate_save_post() ) { + + wp_send_json_success( $json ); + + } + + // update vars + $json['valid'] = 0; + $json['errors'] = acf_get_validation_errors(); + + // return + wp_send_json_success( $json ); + + } + + + /* + * acf_validate_save_post + * + * This function will loop over $_POST data and validate + * + * @type function + * @date 7/09/2016 + * @since 5.4.0 + * + * @param n/a + * @return n/a + */ + + function acf_validate_save_post() { + + // bail early if no $_POST + if ( empty( $_POST['acf'] ) ) { + return; + } + + // validate + acf_validate_values( $_POST['acf'], 'acf' ); + + } + + } + + // initialize + acf()->validation = new acf_validation(); endif; // class_exists check @@ -219,36 +221,36 @@ endif; // class_exists check * * alias of acf()->validation->function() * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_add_validation_error( $input, $message = '' ) { - + return acf()->validation->add_error( $input, $message ); - + } function acf_get_validation_errors() { - + return acf()->validation->get_errors(); - + } function acf_get_validation_error() { - + return acf()->validation->get_error( $input ); - + } function acf_reset_validation_errors() { - + return acf()->validation->reset_errors(); - + } @@ -257,50 +259,47 @@ function acf_reset_validation_errors() { * * This function will validate $_POST data and add errors * -* @type function -* @date 25/11/2013 -* @since 5.0.0 +* @type function +* @date 25/11/2013 +* @since 5.0.0 * -* @param $show_errors (boolean) if true, errors will be shown via a wp_die screen -* @return (boolean) +* @param $show_errors (boolean) if true, errors will be shown via a wp_die screen +* @return (boolean) */ function acf_validate_save_post( $show_errors = false ) { - + // action - do_action('acf/validate_save_post'); - - + do_action( 'acf/validate_save_post' ); + // vars $errors = acf_get_validation_errors(); - - + // bail ealry if no errors - if( !$errors ) return true; - - + if ( ! $errors ) { + return true; + } + // show errors - if( $show_errors ) { - - $message = '

                                ' . __('Validation failed', 'acf') . '

                                '; + if ( $show_errors ) { + + $message = '

                                ' . __( 'Validation failed', 'acf' ) . '

                                '; $message .= '
                                  '; - foreach( $errors as $error ) { - + foreach ( $errors as $error ) { + $message .= '
                                • ' . $error['message'] . '
                                • '; - + } $message .= '
                                '; - - + // die - wp_die( $message, __('Validation failed', 'acf') ); - + wp_die( $message, __( 'Validation failed', 'acf' ) ); + } - - + // return return false; - + } @@ -309,38 +308,39 @@ function acf_validate_save_post( $show_errors = false ) { * * This function will validate an array of field values * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param values (array) -* @param $input_prefix (string) -* @return n/a +* @param values (array) +* @param $input_prefix (string) +* @return n/a */ function acf_validate_values( $values, $input_prefix = '' ) { - + // bail early if empty - if( empty($values) ) return; - - + if ( empty( $values ) ) { + return; + } + // loop - foreach( $values as $key => $value ) { - + foreach ( $values as $key => $value ) { + // vars $field = acf_get_field( $key ); $input = $input_prefix . '[' . $key . ']'; - - + // bail early if not found - if( !$field ) continue; - - + if ( ! $field ) { + continue; + } + // validate acf_validate_value( $value, $field, $input ); - + } - + } @@ -349,69 +349,63 @@ function acf_validate_values( $values, $input_prefix = '' ) { * * This function will validate a field's value * -* @type function -* @date 6/10/13 -* @since 5.0.0 +* @type function +* @date 6/10/13 +* @since 5.0.0 * -* @param n/a -* @return n/a +* @param n/a +* @return n/a */ function acf_validate_value( $value, $field, $input ) { - + // vars - $valid = true; + $valid = true; $message = sprintf( __( '%s value is required', 'acf' ), $field['label'] ); - - + // valid - if( $field['required'] ) { - + if ( $field['required'] ) { + // valid is set to false if the value is empty, but allow 0 as a valid value - if( empty($value) && !is_numeric($value) ) { - + if ( empty( $value ) && ! is_numeric( $value ) ) { + $valid = false; - + } - } - - + /** * Filters whether the value is valid. * - * @date 28/09/13 - * @since 5.0.0 + * @date 28/09/13 + * @since 5.0.0 * - * @param bool $valid The valid status. Return a string to display a custom error message. - * @param mixed $value The value. - * @param array $field The field array. - * @param string $input The input element's name attribute. + * @param bool $valid The valid status. Return a string to display a custom error message. + * @param mixed $value The value. + * @param array $field The field array. + * @param string $input The input element's name attribute. */ - $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input ); - $valid = apply_filters( "acf/validate_value/name={$field['_name']}", $valid, $value, $field, $input ); - $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input ); - $valid = apply_filters( "acf/validate_value", $valid, $value, $field, $input ); - - + $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input ); + $valid = apply_filters( "acf/validate_value/name={$field['_name']}", $valid, $value, $field, $input ); + $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input ); + $valid = apply_filters( 'acf/validate_value', $valid, $value, $field, $input ); + // allow $valid to be a custom error message - if( !empty($valid) && is_string($valid) ) { - + if ( ! empty( $valid ) && is_string( $valid ) ) { + $message = $valid; - $valid = false; - + $valid = false; + } - - - if( !$valid ) { - + + if ( ! $valid ) { + acf_add_validation_error( $input, $message ); return false; - + } - - + // return return true; - + } diff --git a/includes/walkers/class-acf-walker-nav-menu-edit.php b/includes/walkers/class-acf-walker-nav-menu-edit.php index e77e20a..9e80a2e 100644 --- a/includes/walkers/class-acf-walker-nav-menu-edit.php +++ b/includes/walkers/class-acf-walker-nav-menu-edit.php @@ -1,74 +1,76 @@ -]+class="[^"]*field-move)/', - $this->get_fields( $item, $depth, $args, $id ), - $item_output - ); - } - - - /** - * Get custom fields HTML - * - * @since 5.0.0 - * @since 5.7.2 Added action based on https://github.com/ineagu/wp-menu-item-custom-fields - * - * @param object $item Menu item data object. - * @param int $depth Depth of menu item. Used for padding. - * @param array $args Menu item args. - * @param int $id Nav menu ID. - * @return string - */ - function get_fields( $item, $depth, $args = array(), $id = 0 ) { - ob_start(); - - /** - * Get menu item custom fields from plugins/themes - * - * @since 5.7.2 - * - * @param int $item_id post ID of menu - * @param object $item Menu item data object. - * @param int $depth Depth of menu item. Used for padding. - * @param array $args Menu item args. - * @param int $id Nav menu ID. - */ - do_action( 'wp_nav_menu_item_custom_fields', $item->ID, $item, $depth, $args, $id ); - return ob_get_clean(); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Walker_Nav_Menu_Edit' ) ) : + + class ACF_Walker_Nav_Menu_Edit extends Walker_Nav_Menu_Edit { + + /** + * Starts the element output. + * + * Calls the Walker_Nav_Menu_Edit start_el function and then injects the custom field HTML + * + * @since 5.0.0 + * @since 5.7.2 Added preg_replace based on https://github.com/ineagu/wp-menu-item-custom-fields + * + * @param string $output Used to append additional content (passed by reference). + * @param WP_Post $item Menu item data object. + * @param int $depth Depth of menu item. Used for padding. + * @param stdClass $args An object of wp_nav_menu() arguments. + * @param int $id Current item ID. + */ + function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { + + // vars + $item_output = ''; + + // call parent function + parent::start_el( $item_output, $item, $depth, $args, $id ); + + // inject custom field HTML + $output .= preg_replace( + // NOTE: Check this regex from time to time! + '/(?=<(fieldset|p)[^>]+class="[^"]*field-move)/', + $this->get_fields( $item, $depth, $args, $id ), + $item_output + ); + } + + + /** + * Get custom fields HTML + * + * @since 5.0.0 + * @since 5.7.2 Added action based on https://github.com/ineagu/wp-menu-item-custom-fields + * + * @param object $item Menu item data object. + * @param int $depth Depth of menu item. Used for padding. + * @param array $args Menu item args. + * @param int $id Nav menu ID. + * @return string + */ + function get_fields( $item, $depth, $args = array(), $id = 0 ) { + ob_start(); + + /** + * Get menu item custom fields from plugins/themes + * + * @since 5.7.2 + * + * @param int $item_id post ID of menu + * @param object $item Menu item data object. + * @param int $depth Depth of menu item. Used for padding. + * @param array $args Menu item args. + * @param int $id Nav menu ID. + */ + do_action( 'wp_nav_menu_item_custom_fields', $item->ID, $item, $depth, $args, $id ); + return ob_get_clean(); + } + } + endif; -?> \ No newline at end of file + diff --git a/includes/walkers/class-acf-walker-taxonomy-field.php b/includes/walkers/class-acf-walker-taxonomy-field.php index 73bc3bd..bb780f7 100644 --- a/includes/walkers/class-acf-walker-taxonomy-field.php +++ b/includes/walkers/class-acf-walker-taxonomy-field.php @@ -1,131 +1,133 @@ - 'parent', - 'id' => 'term_id', - ); - - /** - * The field being rendered. - * - * @since 1.0.0 - * @var array - */ - public $field; - - /** - * Constructor - * - * @date 20/4/21 - * @since 1.0.0 - * - * @param array $field The field being rendered. - * @return void - */ - function __construct( $field ) { - $this->field = $field; - } - - /** - * Starts the list before the elements are added. - * - * @see Walker:start_lvl() - * - * @since 1.0.0 - * - * @param string $output Used to append additional content (passed by reference). - * @param int $depth Depth of category. Used for tab indentation. - * @param array $args An array of arguments. @see wp_terms_checklist() - */ - public function start_lvl( &$output, $depth = 0, $args = array() ) { - $indent = str_repeat( "\t", $depth ); - $output .= "$indent
                                  \n"; - } - - /** - * Ends the list of after the elements are added. - * - * @see Walker::end_lvl() - * - * @since 1.0.0 - * - * @param string $output Used to append additional content (passed by reference). - * @param int $depth Depth of category. Used for tab indentation. - * @param array $args An array of arguments. @see wp_terms_checklist() - */ - public function end_lvl( &$output, $depth = 0, $args = array() ) { - $indent = str_repeat( "\t", $depth ); - $output .= "$indent
                                \n"; - } - - /** - * Start the element output. - * - * @see Walker::start_el() - * - * @since 1.0.0 - * - * @param string $output Used to append additional content (passed by reference). - * @param WP_Term $term The current term object. - * @param int $depth Depth of the term in reference to parents. Default 0. - * @param array $args An array of arguments. @see wp_terms_checklist() - * @param int $id ID of the current term. - */ - public function start_el( &$output, $term, $depth = 0, $args = array(), $id = 0 ) { - $is_selected = in_array( $term->term_id, $this->field['value'] ); - - // Generate array of checkbox input attributes. - $input_attrs = array( - 'type' => $this->field['field_type'], - 'name' => $this->field['name'], - 'value' => $term->term_id - ); - if ( $is_selected ) { - $input_attrs['checked'] = true; - } - - $output .= "\n" . '
                              • ' . - '' . - ' ' . - '' . acf_esc_html( $term->name ) . ''. - ''; - } - - /** - * Ends the element output, if needed. - * - * @see Walker::end_el() - * - * @since 1.0.0 - * - * @param string $output Used to append additional content (passed by reference). - * @param WP_Term $category The current term object. - * @param int $depth Depth of the term in reference to parents. Default 0. - * @param array $args An array of arguments. @see wp_terms_checklist() - */ - public function end_el( &$output, $category, $depth = 0, $args = array() ) { - $output .= "
                              • \n"; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } +if ( ! class_exists( 'ACF_Taxonomy_Field_Walker' ) ) : + + class ACF_Taxonomy_Field_Walker extends Walker { + + /** + * What the class handles. + * + * @since 2.1.0 + * @var string + */ + public $tree_type = 'category'; + + /** + * DB fields to use. + * + * @since 2.1.0 + * @var array + */ + public $db_fields = array( + 'parent' => 'parent', + 'id' => 'term_id', + ); + + /** + * The field being rendered. + * + * @since 1.0.0 + * @var array + */ + public $field; + + /** + * Constructor + * + * @date 20/4/21 + * @since 1.0.0 + * + * @param array $field The field being rendered. + * @return void + */ + function __construct( $field ) { + $this->field = $field; + } + + /** + * Starts the list before the elements are added. + * + * @see Walker:start_lvl() + * + * @since 1.0.0 + * + * @param string $output Used to append additional content (passed by reference). + * @param int $depth Depth of category. Used for tab indentation. + * @param array $args An array of arguments. @see wp_terms_checklist() + */ + public function start_lvl( &$output, $depth = 0, $args = array() ) { + $indent = str_repeat( "\t", $depth ); + $output .= "$indent
                                  \n"; + } + + /** + * Ends the list of after the elements are added. + * + * @see Walker::end_lvl() + * + * @since 1.0.0 + * + * @param string $output Used to append additional content (passed by reference). + * @param int $depth Depth of category. Used for tab indentation. + * @param array $args An array of arguments. @see wp_terms_checklist() + */ + public function end_lvl( &$output, $depth = 0, $args = array() ) { + $indent = str_repeat( "\t", $depth ); + $output .= "$indent
                                \n"; + } + + /** + * Start the element output. + * + * @see Walker::start_el() + * + * @since 1.0.0 + * + * @param string $output Used to append additional content (passed by reference). + * @param WP_Term $term The current term object. + * @param int $depth Depth of the term in reference to parents. Default 0. + * @param array $args An array of arguments. @see wp_terms_checklist() + * @param int $id ID of the current term. + */ + public function start_el( &$output, $term, $depth = 0, $args = array(), $id = 0 ) { + $is_selected = in_array( $term->term_id, $this->field['value'] ); + + // Generate array of checkbox input attributes. + $input_attrs = array( + 'type' => $this->field['field_type'], + 'name' => $this->field['name'], + 'value' => $term->term_id, + ); + if ( $is_selected ) { + $input_attrs['checked'] = true; + } + + $output .= "\n" . '
                              • ' . + '' . + ' ' . + '' . acf_esc_html( $term->name ) . '' . + ''; + } + + /** + * Ends the element output, if needed. + * + * @see Walker::end_el() + * + * @since 1.0.0 + * + * @param string $output Used to append additional content (passed by reference). + * @param WP_Term $category The current term object. + * @param int $depth Depth of the term in reference to parents. Default 0. + * @param array $args An array of arguments. @see wp_terms_checklist() + */ + public function end_el( &$output, $category, $depth = 0, $args = array() ) { + $output .= "
                              • \n"; + } + } + endif; diff --git a/includes/wpml.php b/includes/wpml.php index 940a9f79..596cb48 100644 --- a/includes/wpml.php +++ b/includes/wpml.php @@ -1,302 +1,318 @@ get_default_language()); - acf_update_setting('current_language', $sitepress->get_current_language()); - - // localize data - acf_localize_data(array( - 'language' => $sitepress->get_current_language() - )); - - // switch lang during AJAX action - add_action('acf/verify_ajax', array($this, 'verify_ajax')); - - // prevent 'acf-field' from being translated - add_filter('get_translatable_documents', array($this, 'get_translatable_documents')); - - // check if 'acf-field-group' is translatable - if( $this->is_translatable() ) { - - // actions - add_action('acf/upgrade_500_field_group', array($this, 'upgrade_500_field_group'), 10, 2); - add_action('icl_make_duplicate', array($this, 'icl_make_duplicate'), 10, 4); - - // filters - add_filter('acf/settings/save_json', array($this, 'settings_save_json')); - add_filter('acf/settings/load_json', array($this, 'settings_load_json')); - } - } - - /** - * is_translatable - * - * Returns true if the acf-field-group post type is translatable. - * Also adds compatibility with ACF4 settings - * - * @date 10/04/2015 - * @since 5.2.3 - * - * @param void - * @return bool - */ - function is_translatable() { - - // global - global $sitepress; - - // vars - $post_types = $sitepress->get_setting('custom_posts_sync_option'); - - // return false if no post types - if( !acf_is_array($post_types) ) { - return false; - } - - // prevent 'acf-field' from being translated - if( !empty($post_types['acf-field']) ) { - $post_types['acf-field'] = 0; - $sitepress->set_setting('custom_posts_sync_option', $post_types); - } - - // when upgrading to version 5, review 'acf' setting - // update 'acf-field-group' if 'acf' is translatable, and 'acf-field-group' does not yet exist - if( !empty($post_types['acf']) && !isset($post_types['acf-field-group']) ) { - $post_types['acf-field-group'] = 1; - $sitepress->set_setting('custom_posts_sync_option', $post_types); - } - - // return true if acf-field-group is translatable - if( !empty($post_types['acf-field-group']) ) { - return true; - } - - // return - return false; - } - - /** - * upgrade_500_field_group - * - * Update the icl_translations table data when creating the field groups. - * - * @date 10/04/2015 - * @since 5.2.3 - * - * @param array $field_group The new field group array. - * @param object $ofg The old field group WP_Post object. - * @return void - */ - function upgrade_500_field_group($field_group, $ofg) { - - // global - global $wpdb; - - // get translation rows (old acf4 and new acf5) - $old_row = $wpdb->get_row($wpdb->prepare( - "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d", - 'post_acf', $ofg->ID - ), ARRAY_A); - - $new_row = $wpdb->get_row($wpdb->prepare( - "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d", - 'post_acf-field-group', $field_group['ID'] - ), ARRAY_A); - - // bail ealry if no rows - if( !$old_row || !$new_row ) { - return; - } - - // create reference of old trid to new trid - // trid is a simple int used to find associated objects - if( empty($this->trid_ref) ) { - $this->trid_ref = array(); - } - - // update trid - if( isset($this->trid_ref[ $old_row['trid'] ]) ) { - - // this field group is a translation of another, update it's trid to match the previously inserted group - $new_row['trid'] = $this->trid_ref[ $old_row['trid'] ]; - } else { - - // this field group is the first of it's translations, update the reference for future groups - $this->trid_ref[ $old_row['trid'] ] = $new_row['trid']; - } - - // update icl_translations - // Row is created by WPML, and much easier to tweak it here due to the very complicated and nonsensical WPML logic - $table = "{$wpdb->prefix}icl_translations"; - $data = array( 'trid' => $new_row['trid'], 'language_code' => $old_row['language_code'] ); - $where = array( 'translation_id' => $new_row['translation_id'] ); - $data_format = array( '%d', '%s' ); - $where_format = array( '%d' ); - - // allow source_language_code to equal NULL - if( $old_row['source_language_code'] ) { - - $data['source_language_code'] = $old_row['source_language_code']; - $data_format[] = '%s'; - } - - // update wpdb - $result = $wpdb->update( $table, $data, $where, $data_format, $where_format ); - } - - /** - * settings_save_json - * - * Modifies the json path. - * - * @date 19/05/2014 - * @since 5.0.0 - * - * @param string $path The json save path. - * @return string - */ - function settings_save_json( $path ) { - - // bail early if dir does not exist - if( !is_writable($path) ) { - return $path; - } - - // ammend - $path = untrailingslashit($path) . '/' . acf_get_setting('current_language'); - - // make dir if does not exist - if( !file_exists($path) ) { - mkdir($path, 0777, true); - } - - // return - return $path; - } - - /** - * settings_load_json - * - * Modifies the json path. - * - * @date 19/05/2014 - * @since 5.0.0 - * - * @param string $path The json save path. - * @return string - */ - function settings_load_json( $paths ) { - - // loop - if( $paths ) { - foreach( $paths as $i => $path ) { - $paths[ $i ] = untrailingslashit($path) . '/' . acf_get_setting('current_language'); - }} - - // return - return $paths; - } - - /** - * icl_make_duplicate - * - * description - * - * @date 26/02/2014 - * @since 5.0.0 - * - * @param void - * @return void - */ - function icl_make_duplicate( $master_post_id, $lang, $postarr, $id ) { - - // bail early if not acf-field-group - if( $postarr['post_type'] != 'acf-field-group' ) { - return; - } - - // update the lang - acf_update_setting('current_language', $lang); - - // duplicate field group specifying the $post_id - acf_duplicate_field_group( $master_post_id, $id ); - - // always translate independately to avoid many many bugs! - // - translation post gets a new key (post_name) when origional post is saved - // - local json creates new files due to changed key - global $iclTranslationManagement; - $iclTranslationManagement->reset_duplicate_flag( $id ); - } - - - /** - * verify_ajax - * - * Sets the correct language during AJAX requests. - * - * @type function - * @date 7/08/2015 - * @since 5.2.3 - * - * @param void - * @return void - */ - function verify_ajax() { - - // set the language for this AJAX request - // this will allow get_posts to work as expected (load posts from the correct language) - if( isset($_REQUEST['lang']) ) { - global $sitepress; - $sitepress->switch_lang( $_REQUEST['lang'] ); - } - } - - /** - * get_translatable_documents - * - * Removes 'acf-field' from the available post types for translation. - * - * @type function - * @date 17/8/17 - * @since 5.6.0 - * - * @param array $icl_post_types The array of post types. - * @return array - */ - function get_translatable_documents( $icl_post_types ) { - - // unset - unset( $icl_post_types['acf-field'] ); - - // return - return $icl_post_types; - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -acf_new_instance('ACF_WPML_Compatibility'); +if ( ! class_exists( 'ACF_WPML_Compatibility' ) ) : + + class ACF_WPML_Compatibility { + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 23/06/12 + * @since 3.1.8 + * + * @param void + * @return void + */ + function __construct() { + + // global + global $sitepress; + + // update settings + acf_update_setting( 'default_language', $sitepress->get_default_language() ); + acf_update_setting( 'current_language', $sitepress->get_current_language() ); + + // localize data + acf_localize_data( + array( + 'language' => $sitepress->get_current_language(), + ) + ); + + // switch lang during AJAX action + add_action( 'acf/verify_ajax', array( $this, 'verify_ajax' ) ); + + // prevent 'acf-field' from being translated + add_filter( 'get_translatable_documents', array( $this, 'get_translatable_documents' ) ); + + // check if 'acf-field-group' is translatable + if ( $this->is_translatable() ) { + + // actions + add_action( 'acf/upgrade_500_field_group', array( $this, 'upgrade_500_field_group' ), 10, 2 ); + add_action( 'icl_make_duplicate', array( $this, 'icl_make_duplicate' ), 10, 4 ); + + // filters + add_filter( 'acf/settings/save_json', array( $this, 'settings_save_json' ) ); + add_filter( 'acf/settings/load_json', array( $this, 'settings_load_json' ) ); + } + } + + /** + * is_translatable + * + * Returns true if the acf-field-group post type is translatable. + * Also adds compatibility with ACF4 settings + * + * @date 10/04/2015 + * @since 5.2.3 + * + * @param void + * @return bool + */ + function is_translatable() { + + // global + global $sitepress; + + // vars + $post_types = $sitepress->get_setting( 'custom_posts_sync_option' ); + + // return false if no post types + if ( ! acf_is_array( $post_types ) ) { + return false; + } + + // prevent 'acf-field' from being translated + if ( ! empty( $post_types['acf-field'] ) ) { + $post_types['acf-field'] = 0; + $sitepress->set_setting( 'custom_posts_sync_option', $post_types ); + } + + // when upgrading to version 5, review 'acf' setting + // update 'acf-field-group' if 'acf' is translatable, and 'acf-field-group' does not yet exist + if ( ! empty( $post_types['acf'] ) && ! isset( $post_types['acf-field-group'] ) ) { + $post_types['acf-field-group'] = 1; + $sitepress->set_setting( 'custom_posts_sync_option', $post_types ); + } + + // return true if acf-field-group is translatable + if ( ! empty( $post_types['acf-field-group'] ) ) { + return true; + } + + // return + return false; + } + + /** + * upgrade_500_field_group + * + * Update the icl_translations table data when creating the field groups. + * + * @date 10/04/2015 + * @since 5.2.3 + * + * @param array $field_group The new field group array. + * @param object $ofg The old field group WP_Post object. + * @return void + */ + function upgrade_500_field_group( $field_group, $ofg ) { + + // global + global $wpdb; + + // get translation rows (old acf4 and new acf5) + $old_row = $wpdb->get_row( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d", + 'post_acf', + $ofg->ID + ), + ARRAY_A + ); + + $new_row = $wpdb->get_row( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d", + 'post_acf-field-group', + $field_group['ID'] + ), + ARRAY_A + ); + + // bail ealry if no rows + if ( ! $old_row || ! $new_row ) { + return; + } + + // create reference of old trid to new trid + // trid is a simple int used to find associated objects + if ( empty( $this->trid_ref ) ) { + $this->trid_ref = array(); + } + + // update trid + if ( isset( $this->trid_ref[ $old_row['trid'] ] ) ) { + + // this field group is a translation of another, update it's trid to match the previously inserted group + $new_row['trid'] = $this->trid_ref[ $old_row['trid'] ]; + } else { + + // this field group is the first of it's translations, update the reference for future groups + $this->trid_ref[ $old_row['trid'] ] = $new_row['trid']; + } + + // update icl_translations + // Row is created by WPML, and much easier to tweak it here due to the very complicated and nonsensical WPML logic + $table = "{$wpdb->prefix}icl_translations"; + $data = array( + 'trid' => $new_row['trid'], + 'language_code' => $old_row['language_code'], + ); + $where = array( 'translation_id' => $new_row['translation_id'] ); + $data_format = array( '%d', '%s' ); + $where_format = array( '%d' ); + + // allow source_language_code to equal NULL + if ( $old_row['source_language_code'] ) { + + $data['source_language_code'] = $old_row['source_language_code']; + $data_format[] = '%s'; + } + + // update wpdb + $result = $wpdb->update( $table, $data, $where, $data_format, $where_format ); + } + + /** + * settings_save_json + * + * Modifies the json path. + * + * @date 19/05/2014 + * @since 5.0.0 + * + * @param string $path The json save path. + * @return string + */ + function settings_save_json( $path ) { + + // bail early if dir does not exist + if ( ! is_writable( $path ) ) { + return $path; + } + + // ammend + $path = untrailingslashit( $path ) . '/' . acf_get_setting( 'current_language' ); + + // make dir if does not exist + if ( ! file_exists( $path ) ) { + mkdir( $path, 0777, true ); + } + + // return + return $path; + } + + /** + * settings_load_json + * + * Modifies the json path. + * + * @date 19/05/2014 + * @since 5.0.0 + * + * @param string $path The json save path. + * @return string + */ + function settings_load_json( $paths ) { + + // loop + if ( $paths ) { + foreach ( $paths as $i => $path ) { + $paths[ $i ] = untrailingslashit( $path ) . '/' . acf_get_setting( 'current_language' ); + } + } + + // return + return $paths; + } + + /** + * icl_make_duplicate + * + * description + * + * @date 26/02/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function icl_make_duplicate( $master_post_id, $lang, $postarr, $id ) { + + // bail early if not acf-field-group + if ( $postarr['post_type'] != 'acf-field-group' ) { + return; + } + + // update the lang + acf_update_setting( 'current_language', $lang ); + + // duplicate field group specifying the $post_id + acf_duplicate_field_group( $master_post_id, $id ); + + // always translate independately to avoid many many bugs! + // - translation post gets a new key (post_name) when origional post is saved + // - local json creates new files due to changed key + global $iclTranslationManagement; + $iclTranslationManagement->reset_duplicate_flag( $id ); + } + + + /** + * verify_ajax + * + * Sets the correct language during AJAX requests. + * + * @type function + * @date 7/08/2015 + * @since 5.2.3 + * + * @param void + * @return void + */ + function verify_ajax() { + + // set the language for this AJAX request + // this will allow get_posts to work as expected (load posts from the correct language) + if ( isset( $_REQUEST['lang'] ) ) { + global $sitepress; + $sitepress->switch_lang( $_REQUEST['lang'] ); + } + } + + /** + * get_translatable_documents + * + * Removes 'acf-field' from the available post types for translation. + * + * @type function + * @date 17/8/17 + * @since 5.6.0 + * + * @param array $icl_post_types The array of post types. + * @return array + */ + function get_translatable_documents( $icl_post_types ) { + + // unset + unset( $icl_post_types['acf-field'] ); + + // return + return $icl_post_types; + } + } + + acf_new_instance( 'ACF_WPML_Compatibility' ); endif; // class_exists check -?> \ No newline at end of file + diff --git a/lang/acf-ar.mo b/lang/acf-ar.mo old mode 100644 new mode 100755 diff --git a/lang/acf-cs_CZ.mo b/lang/acf-cs_CZ.mo old mode 100644 new mode 100755 diff --git a/lang/acf-de_CH.mo b/lang/acf-de_CH.mo old mode 100644 new mode 100755 diff --git a/lang/acf-de_DE.mo b/lang/acf-de_DE.mo old mode 100644 new mode 100755 diff --git a/lang/acf-de_DE_formal.mo b/lang/acf-de_DE_formal.mo old mode 100644 new mode 100755 diff --git a/lang/acf-fr_FR.mo b/lang/acf-fr_FR.mo old mode 100644 new mode 100755 diff --git a/lang/acf-id_ID.mo b/lang/acf-id_ID.mo old mode 100644 new mode 100755 diff --git a/lang/acf-it_IT.mo b/lang/acf-it_IT.mo old mode 100644 new mode 100755 diff --git a/lang/acf-ja.mo b/lang/acf-ja.mo old mode 100644 new mode 100755 diff --git a/lang/acf-pt_BR.mo b/lang/acf-pt_BR.mo old mode 100644 new mode 100755 diff --git a/lang/acf-sk_SK.mo b/lang/acf-sk_SK.mo old mode 100644 new mode 100755 diff --git a/lang/acf-sv_SE.mo b/lang/acf-sv_SE.mo index bcbf3fb2377fe96c0c914ad9f0e33df1bdb623f9..82d4670822f440f3ba6bf1f0fa15f7b37dd4a6a2 100644 GIT binary patch literal 47307 zcmcJY37A|}weJrQrZCDpDThENNOuN6Fc2V9Cn2Nh41hzZ?yBytbahoxrz%MY5gEM* zf(jyv;DA9zxi}yyD*B9yUd4I1dQq>yeGWWluLJt@{r+q1bLv#51HSitufClA@9FGu z?X}ikd!L;j9X8>O5x?8^jG`03PaY9Pm+cirFP*N?D2mUDqT|7n!2Q5^;Pb#9a1nSB zcmQ}8$g9zN!IQv8z=`0027DSk5dR-RrQhr9C^`;21pGL7D)@TvseoHv6h+(d?>9G! zW`Wm$^S}qes{{U5=ljsEX_PycV1Rz79MC{1kW?_&ZST-TOQ* z=V0(?{KtaFfV06EyfFBOLG|OcpvL(|Q19Obs$cE}Ro@3emHTN>>Awt~0Dd#zuR*0h z@O;nbIB;+LGr%u^b3nD@F9G+tz~c`Grx1QDsQfMfmH*2?r7s4&EZ{2x-Uuq)9iYbX zZJ_G;ZcyPL0yQ2V2i5McgBt&zgNJ~>2aPW2RJHdIQ287Ks=s1T`J5fX&j&TGOF*@& z57hfZpy;9rLc-BC;PK$6K$Y`-Q0adTD*dlPwd=2-=y<;cUaw<8g`W&6-7Ih>crK`V zRY29V32L0K04IUBfQtVRsCqmMo(z5oRQ-PmD*Yco<-gCuD0&HaI4FM&RQxMI)%Rvl z<9IiyeBTc)1|I~~kI#U|f``KlmVjL#Q!{FTs`m%L=YyXFWAF!{#`UiOk0CSp&ji)} zwV=}XgC~Jkfs?>{z>~o*gz#U0Gw>hS>~UaDy#S& z@KkUJ)O@)W+!wqTRDJ#xRQo>-UIIP_ZUCn(jiMvLE5UuhH-bv{R#5$TAE@?!6nrtb z6BIojxyh~MK{lPbbs>eMc{K4S=9H{cX1Bx#^2~Gh21gf0B zfqHM>3q7A>K!r~V*aa&7Y;Zqt8L0f$f_sCPf)l|3Q1O?6`-9uT7`zso0`36CKfej{w!q6F}ATH1GiMd~i0n98~-jpvt`oJOF$HsD8W~oCv-zgg+GgpAGmJ zsPg|E)O`FUcsjV>3ZL)if*RLeQ1JsH{3;Mp6x{)eUcL@0pI?Eh*Ip}~uFnKDzNryc?q~LH~^}Ds-XI3Yrw0(7vR4URQ~sYqL(j%>W3eJ#-Bm8fA3YHzd)rs0o3@+ z0Z#)Lf=soj2C6Hiy?2mTd22z=3MPqzeA zzU#n)!IuQw462@^pvt)kydHcLsQg~A#>eXvQ2j6qR6Sk|Mj5c#p^-kb3ds3KN8|U3##3Zfuh$ZLDlQe zpz_&wT@+0R4+S+2b3wIp5vcr@f@svft2 zD(@js<$MBE`hNpe-s7P9?WdsR$zCvNZhwh{EfkXC%7l! zJHSi9_kc%&`)~AdJP}lW=YgVwRiNrU2p$2pLilSyx+=N{6dnB;RK54V$oy+dz%?y`cK{fe`;uP~-K<5dK|I{qQ4D^?e%Dxcn7V zyZ5-*>w5sG@EBCSQ$UqB6V!WWfJ(mz6g{s3)!s`&_ze69zafxiJ>3cd|gK2lOtpZ!6VdoZYaoB*o*(}I6iz;i*RTN-c! zsQMQ{^+y#{doKq?KUaZ=gExVPfo}(u?}x#e;3vRiz^6gIKjEbw|2$CsV?mWS1ysIg zfJ#3XRQ-EFmGe?i=?6jeR}<8GmxuTpK$UwND0+A+sQ2Fos{Rjxr+|-ulffrJ<-7mO zJf9;#s&N?|^%} z+{-;E;4z@yI~i2D)4|ih^Fg&U0oA|TLACd0Q0d+ZsvaK-_(@Rp{{pD=-vU+cPeb_c zgFo8j>%s#;&9`~r(coH8_1+AM-fjm)zwZWb0Y3_!3@*8pe%T|6hC%ta7n~072G7F( zZSXwsz&_dlE(ewFMo@g?0Z{$_6L1N*Z@=q>tHCMw?*-?AkAdfc`xTMp;9^kYunp8W zya81G-V3T9J`NrS?gT|YKLR!We+uDI$-|EaMW<(g%5Moc0W5&(zX9-tU=qUb1C{;( za0d9<5dLd$7XCkg=YW$3d|V0vw}Kk4*9N>3oQnUwpx*licm}xVpx65>Q1NR)jqi3) z?Rp)!H~1D%6`|0pOr-3f|6eiKxCo(kbV2i2}WgL{E{4|#t3gGzTuz#~BA zdn~vgcnY{L*afQGGeM=F52{{00oQ;Uk4r%H`(@xs;A=q9@%zC?!T$sogYPMm#~$d5 zAS4;h8iogfw}6^29|KPYp9C)e_pLY`ECtnH*MXw5he754J8%U!WyI^1fCu2e0@OI( z0IL5!1KtaM0ellUQuX<@cg@>W7O#rGGhi5I6v8 z-ZjB}z<&WXk8T0={@X#l|9(*P^l?z{eFaoLKLC~f2~gwt`w+ip-N*G%@DRc$fhT}- zz(c{+py=gNP~*D=d;z!}R6XAeYFzIIHE!<(Ro;g|)$0=>{83Qz;TxdZ|1_w2{1y~l zMVEOwhk=Tp1}eTAd>%LtR6SOMYF{b%w*|Zz6rH>aR5_mjHSXU5r-FY6HSSXy-tQNJ zs%HsQ{YSw4z-_^Q6?iEAn?UvJUBQ1J_&ofd0M);bff|qh2>vHPwfi@q>i@S8e?a2p z9R{j>$AO1|F{pH>gX-S}p!&5Z_?Lr9zdD4k2T#F&3AiVCC8+YQ1~q;+gR0Nnpz_@T zs+|vlYUd|GrGFGux^IEX=Lewb^FvU4`!}G*bML0(A)wwnHsEAX^_mT89-IZ90an33 zkl{U``umQppX)B_s@F51@|pNbmxCvQ@-GI}?n}TPuoA*Q44#hv ziy{1Ppz>RIrRTQ+)Vvq~4+m=juK_go zias6ymEV^Geiu9e|4%^G`|qIIGvOM?L%{|3PXIL^Hi4ptYeDtjouKOdPEh0h0H}6- z8dN!71y#TAgUa`(pvL$2pz1gES`VKM>iv1(Byc6D_&TWm-wvJ#-U6yU4}|cKfhzwo zkSQGfAcU{I&g(e{iq2jMD*xAk%J=QyV(>ojXz({+4DNS5a~+%x_JCJ|s{fZj@vZNH z6TlyX`+!e@D*tJ45Ae^R%6kUf6Fl(Mj)#DH@37!M8r&QIaiIDo4mcx(pAG8$^FZZ0 zAKV9A7~(Gk)s8jbUf?C*zTnG2l|KNgpSFRj-<-i0SDrQp{=jceBpp8jl5@fUzIz!l*0!BKDu_$F|F@DWgS`9)CU@crQb zIjC};0Yz8)y~gW(BB**y12xaj0@aS?pweFy;s-)}3sn7Y2=T86)n9K5{(Hgw@jnPo z1RnuU0lx%J1%Cx<9vpR}+eJQhR^?x3y`kVl&zZQb3#}KG; zt^}3;TR@G|hd}k$7eMi&$3pm%;Hmik1TF_B-Qwx0pz6^IcqMos{u@Bm=l0;gJK+03 zwc}&p9PklP^!{5=^tIRPJpKq!a^tvwU7+fB0eAqo4!jz?6x6(Y5>$JC7V!6=#^vwe zY2d!E4|D;_|FYn}0aX1z460u~1s()`8&r8ufM3{|TVtyFukU7Zkl*0BRhDLD6k9__u*E{;NRon|FeeZ=V6xPmhB~ zf=`2IfP38T^?4zvdGQiZ^|~EY|J((tUhf1|kNboFLte-#!h-;8(!u;4eXq>(O`kxSa?p z-ZjL& z%I9uS^|=?c@dr=F|8Y?H{18+>mCqML_zys}=P6L_Kj>}Vj$;Cz1giW~LA7HJ zsQS$h{*|D{{iUGl(E>Hz*MrLUHgG!lDbV^C)cd~+_;>JF{1e~q^*#lB0sgbVDc}ZB z^}hlXoxd8?_}>U>JYNsa1n&U5!7qYp=bu2;ci(q-c}Icj-$|g}n+dAi7lO0EHK6F| zDp2oV530VmgPPy(0M!ob+lu_`iT>;otk6J`d-C%J0RX z=w|@bc-#i6zW0JRfgb@+1Q*;x{(C@A;Pde(@AC3q59+;lf+v6vf{OnJD1P(n;NN?P z=X)}!{+R=w0~SEF^Da>D-4CkYzYLxN{sI*J9CEMI+i9T6>jBm7i@+Exf*SwpK-K?l za4L8|D8BO@Q1$sasQ&&3sD3*3-JxFKQv7p3g$@IQKQ%%1>umww3+nwxz-8bwpy*`Ld!1i3!72D}2gPqb1!~;B4XV5!gX*8BLiis* zwdWt8$~pW#FLxR!x>^dVzt)4|re@aBMT1oy}PR&XMCFSsB0L2zI2;Sl~= zQ13qmD*ZP>_50)CDd5jQ)&HRPIUha)JQe>X;7`Eo!1dtZ`xz_f=TqQj{73z(& z>G@U@ti3177d#-~srr0Y&GxfNJlf;77r) zg0T4L`VV@#lRo7A)dh-A%mvl%rJ(w6O^C06%6AmhyuS_<{oN4a?+pI;fa;%zLDAvo zK;`>G@L=$1P~-6oco=xthdq8WDF5l8=(7hD9lR7&J_#r~ya^P2y&Kd#c{JdEfvVSD z52C|>`+^g}rQji8FR1+cLD9#S5Pl7)`rQgn2Hyedy+=d*H$m0+3Gi_68BqOs@JBqq zBSD2v16AL1!6U(5Q1vbcyc*Pez7sqNd>EVsJ|6I(hn#-S1CJ!U1nv!94yry^fuhTs zg8z-6+Vyr&_5T2<{(U6iW1!mmIH>o24IT>q8Pt3GLkx;P7F2s?fJ%2dsB+H*MPCa* z<=X`J1g`-#53UE*-#3Cve+wwOc_XO#a2Kfbp9R(5p9e)R-vm|OQ=sbcG^ld_3M$_T zAM^D4gGzT4sQjNF@MKVQI6dH*pwi6`@k>F`->Trh2z(L#mxFV_J3ywN(avkZg*;<_ z{UKl)SmfEp3ylz_xuf4y8uv@^fAG9W4Gq7il{vrrdA`7-veyvS2fl-6IZv7N-vUQ? zj^Igu;*a``5`Q!AyfEbDp~z?)D??f8yC%=ad4_W7&LMs?&uxUoJZ0jK245M{h*w`t z{EK;J6Lubt_{}psw}do%2K*~w`u&7QbMNOo+ldo>-om4w#$3N9;eF(JhI^y)<>vV^ z;ivNGcNX||o);4S4g9@4SKUcbfLDU2 z688e0A^cbH+>lF)H~amGwDa+G6aW4Y`Uk?6@_dx%^boct;C~QS%H?$>?h|-kMZD&* zevgsn-+3-IAAE@TpW=i>jj z#WH`vFA;t;2rG;>k^U&~J%nlApUtD+i^ID!!5O6aK4G5=VfW(x4epl(ztW3`ejNW) z@IIc+xUT~ByFAo)U+|NJ&*hneJMrjfONif_aQ%+Jza1O`-$vNoJa<_P`)0VO;Qn7c z;s-y+|5lz~;r=yG5x0KgNjrGHivJ}%(&?@zzY9VA{#QuX14^Fjw-0y{X+G%Q=yv@7 zj{9|lrN2?acH-Fx9>H@E?#0CaC-|TE?*#Q*g1d|Ghr!qL==VBs7SH{`udu)HY~eYF zu-T+P6I{phu8?Lmcy@3r{TKCzUzdaZ{V;zAcz#Q|SAzcrE+elkU=u`SL>KVP=4tWh z_aJev2QMQ2FrKq`9>rhfnMa&{`w>=iXY>$Zr{VuP{^j6g@Fwtq5Puo*%XzjErr){X z<=_PH4TQf2ycN7Q#4F7!cwSA|aXd3|ugb-}3;!&hm+*X#c>PWUALSVg=}yD_Tf#?q zeueuI@ChFM9_KlkXD8vW;`x#S`F)mWA^yMe?7-S=wmBBp+JTtsEjQdEQ&+tqNVQ(Vsr}Wa8-^rx;HevI@ z?p)l@@ZTK#t&qoK_}|NO3~|5DrTsL1{mvuZ1b0Ro!#naW;&~Biz8=zj8~g`hzX1OS z&o!itL;3^o|ADyUd8QM#1bhw8Lfju9?jt;_c$V>`zxUj~0sc4mHy-_@TV6m|#PcVh!n=LAr7O?H{RSTWP7L@F_hx_p zCAbzTp68Vz-6MGaC(kcJyx?x0AFC{W7ld@~+x73)NOy4vF65&33h#X)gnbwMCTXuC z{DdHN>p|=keUcqu+mr^z%d7YVa#= zJ?>ZVJfG)Io_F%BCH!kVpW!(L|3n`BE(gy7?*ebL5b8~y{rGRk|0!@f_!7cifcpua z^mikUiNUj#@HL?>e-2?c5q2x?O9+1w_u)K0;`uPonS`$l=`P0q0MCZtKNh?Xzkcg^ zw+GzIe8_sjr}A7u_$;2kiC+r(MTk-!A90Y&J^Ap_jh}ZAe zxVv~>j=MHg#Ax2 z{k;y#T8uLq9_2{#cp4gUeb|8D#%@IMc{h_D}ocNP6=!ncKV2ZDbj z?nB^f!G8l^#xtVylZ){{xl}18aierutK2BXg=Vu zuTqMewRoshsmG(W7IhqKF%Y#@Gj0x*;wN5p$53r+SF@Hp@v1k+wE+v9zpy9XT5D8_ z-O;nxyw=|uVLS^O6tDYg>QmZAyA##Bm`^~(Nm{OI3e_45NR^Gt%@X87 zB7%n)1Pi3nBT!py#Au;ZEHfhgjZ&#faY?gLs}82k4ZgWd&S-vrf2~o}%$}cCd4<=~ z14;qnbCWuR-Cv=v=S{Lvopj!`$;tF{XDZ^ne>z#Q7-{ZJtx?~`R64RoacT<#Q`>6P z#I$PC44eDZkkm8d#k9wqJ>?2@B5c_R1JZUWizOP|#;66ZDs4?MOmw|OsQcn2jasXo zrC3p5puB*!HGi?v4yy8&SJYl;gcOYylXNi4hYAd471&Z>o)qJS-W20BYRY)QB8_N% zrJ_gtk_k0ZfS<}6_^=JDqQtS%B8e`m4?JaEQ?NN&58h^BTdi6fDF<&0I*J>$ihJqj zsou#`LociM#CD9eQ!pv!H~NQQ21&er?FuV`FmH}(hG*%zl`G&^jp0^ZuNTWnojzkS z##_os*%%lsg=v^H5ffrkFppxX0dEgEtZG#%=Lfg?7)IfAO;sRW=1&o(Sgz1A(R2Gn zU(9S!E`WGyH=3D+*_n_Bsw@ z9`M0Ni9TvJ3;jc4+Bqkq0;{Su1T{!T91cOlAjVTF&2#!1QwE#oj1yU>y@QQHeTWRU z7OY?61j!XGfXk^eWCPSH2_Z?jKU&}ow;@prjj0Wk8;pxlwoj%R@zxSUEIFq}dAu|P z8w$AcvkIjpF7@LCIm@_95V(XE|Xs=ue1is)u~BbhgNDy ztv*C2P=me_6|6VJixV;Y1tsG!rrHFL=?OHmQtKb~zeXRiNqqE$LQruUr9mVN(hu2c zi9K1hFw&u&gh(=k^x|pr8;!!~^k_k=f~=qxs0w(RO%woUKf$v?+Df!gL@216va}HL zAFQE0B+){~9U8Nsfuxgaz5tZ7YlBgS?>J{Y?80kV2 zU-Kot+}&5(<_;2l-0!6u}TnI_mx6jRFo zQmqOUY9TSbYzhM2vM7zQvySfbKA{s}D-5^MKzl+NxdnC{-mEbLtp`LA>&n&9l?xZA zxiXn*gM&zkg%Csd8$^JG#2d@iA}oAitx_q}5$20Z=r<618bBAQ((xK9sctuqNh91N zBLy^CO(Aio3RKY@uP90HGriCRn9Uz!#Y(S98&G9b#mS`2#4BopOfEu9=DV6qo(z+7 zL8EQ45t2wHP0@s*I+b8}dJ>}w8qcYes|*Cg6*#R1vsN!VjH+k*E9H7$tRRRw`gM75s2MFPGz)#w>(OvE4h7?I(Ev2+bMN@ZtVXq0glEm1A zMYU>4g>=Mv&s+SuTCp%XHbIp)Eq0Y8;h4AUjnWp2q_?+>joex)4KIbYml_i`4twOf zGQ2QM8Otgcpt=@DEVub9cS+uk?M0e3C(Iu=g@pRpwvH*HKiA+@%<%E5F~s`7DzX&E zxG6@;{SAuhw^S>GhiSW;#1(izme@VJPh4#^y$vhNa*ms2-8*W{_#Nf3-cf7DeV^J; z0jqtlId_vvtMZUa&T&&U8PwI)%IG>Rq9-5$=ot9z$oMr^YRmCiQ*4J+vsCdVM!4+- zQ@Z+CR2nF>D%8pmM#a2?zO#T0G7ZQl?!?jrougi3&Kn0d)(PE~Yb_XJUQvX*)Vt$# zG6uB6jgv`$p?C)6wfmpS8n$74GMB66QWgh zwE{X)c$dC`v!If&`b=1;8sD|GvlNa+sG;JRjS@T^;jpMxM=!83PF-0~WC6y@+exwX z*vc(?msJiEKTB@4)q0uFP*HsJC+GrgXHdpM05Zv3zP>c4m)UlP71-iRNy0se7BlT3 z9^`Qm3AR|)DE{^_KD`K=XmOxS98$qpPX!lLKa{S3=|3kI3GwcHf?}8frh&);(oPqd z0mJ%SO19OLcV*SUfS{r9;7Z$a(QKd`o8q@P=`Ykvwv3AwZ|g5L>h#Yx7W2h8)rj!Q z2Ge89PE%QFY#OGHGB@o^jc7*e)F2I?+_7eb`g>T_v7$+r@0N3v%Rlcttba&Lf_$)6 zQe%T4`64P6i=rB)u#VKNJ`{3P$uYsB)&3!DHi(vSYLs-u=Cd zEKII=1l7ze5N*S;dW7uS(Z0gyFVT;aMM~*vK6^QYYLfMh#%p8|36xO@Ve8y1V$};l zvWh4#ylMs1AJmBUa;2xj!bS#-R1qH=01GoiIWi@!|Ll}A!9Lv{iBy)lJ|nY^CiPN( zc>sH_7K>)f#@4OrXRA`y7Qz6eE?WhfkKwWYM;oFNN0^s-tc)isZx6?(3qZ zu1A|)c1qmqw%cf_SUwEP?T~l}SriBBid*HEvcN?jXcj8bvH`}i(k!E0dv&}b6zOy* z#)p&_1NZ!}>!QWGnZfGsFQ7TsOiG3Y3L>2~N-<^wK$StgmYG-{Q9LB#Bwua8up84O zXZ!XyP_nxrWp{{{-Q|mijQX;npIoeO>mDafo_=#lww8-jXx9laev)xA5s#+0U0HP& z289RrfF=#9RC6?h&@&y(yB$1+4@S!{=ChQ;JZ+hX7Z3(Vlj#Y$w+z#^DuTVQ(K2fX zmYG7o$;fUh~A`gxpiEzd`^ zbe)z=Z>Ol%FtFgoCJE`ANgQ)oX0f6tnykERdiG%n!>nnR2bFG%!(jhoM?yS^igiOF zZ7ZFW#*mi~V+GKi` z!mUNBbx4-QSV!jGj{WrzOb!f_YF(`%N*+OfQG+7nb;UfX6ervj2h`z@?n^?1V_ z+YJwXZ+P(J8XiJI!-Fq0Jov^oyj;y1Uc*4Wl0OLHV1WrCA#PMghLb zhEveoEgwRg4U9CMv-tdIrKC{o^>$BJ$<$)^NIqE;l4w-{ZAO2xHK*3KCZiDgaE*AH z*kh>yo6&B`^a+ZOR6D?m?zQpPzx1-e3^9cu~gP+@ioRK z6-<1Eak4SP5(QW_I&xOAyM}6hty5=Z(V-$^{hbL-HrT!mx%OfH#po-$s2hs)t`Cr@ z9Bp+Zi$Ef@O~vUhW^VJI%}3wajDrc8G4+ijXWcpFpxZNL@O5({=}px0`E?Z4r2AW~i|k)4#K5 zGXz_>?JTgtSmDe@bvkb*30Bi$v<9wUs7Pq6k?t^5t7tu99bf@ka1&*l@EizWxP2!c zJs5-K2%Js(UtRP>tleodh6l+gv21D|U4d|1?|{d{CDzJ);yJw9 zsv7-<(M;cRVrr}XQZP9P;cvL9H!C5eRUJ4u!L)F(lTBqCgf!z|SC2bYYGW!?hLb3w zf@ZCS1tGzvSt*+OficV+4a(Aft5zk_p!|e{Hkhalo1><%;h-pGob z;;y{WC~2cKMOz4LgL(VtV@tBJwOt?d7#;J_R#o<1I`Vz&;#I3sCuGxxxP9%k#uxI@ zT2zf%?0a$@o&+CTY|+}VnVH(~n}uXJ>F(|(!nX%;RBTXL&!o;|s9eW0BKhTzt_*_@ znMZ`JLQ)JO6)&69kR=XVUlz~D1yj+uOz=VKBXm)m_Rd%?CZ z!pMis3>VaEOPVR{FNS@bw4&C3oTt%Y8VWQoGbAWx3_(YX=0p-tp^CP_VlQa=@v53H zRcWm@ouXcCrHyksL9@mt2P3X6S{Ban%(>3APC1KFZ>cas zmEa^*4rZ}Q2%$~Sg+i3#QK+if(K26LrV=KI1AB+l6nYit5U(9!wBA#QCBVkC%_Z{k zP92f{njcUl0Ot7Z?h%MT;z6|52( z6zd5^xP?O8)sNz(CX;*`Yj|qX*tLFWn6k9W`a_Paem!>+M1|PFNk-Qr%gFwHiiY`KQflYsPA^&g#HFjfJ%f8cc0U;}wLR3G%?s z(^-hk42dXf0Y#1=d2(Hr4y#x*oGV+`hBR}uCuoOkHgOPTllBib&7KhCz8iNjTfk%d zSi`ftRUPxzWbAwCYw0W+QyS#oXts-U#b95Q`~S{j{g%+lCFN7w{QmSoCMiG7IrIr+{A+U%xT(o{QDTOSO|H%&Er!fK|f zXQyeOsj=E!7bEnxh(kDemYeCIcH~o?KyyQ_OasehB)ta9iU?fB~LOJYpO%^H8wHRTF% zYCKp%nz=2g4r!*U^AadI{wwC2L}PrQ!cbcAM_S{iB_ zH&JiBFrv*jWW3%8`vV%yhMg~g-b}X2s7@={29Q>qPnR@D>2))B(|p!eT0SWQld?Wm z|J(~cCn(XHPe0~rdDy zdTbk|y{deqzuNbT*Ds5DQA>JkZvtnXrpzyL8Y$|-XCUb~(a&l6%j*-Ld6evE19a-|yjX+uf<`dX- zwRd)-A-RcEN2RtfM;RKOc4%q+&yo*4g5|i#g;jNSQmTF43XYL(y@X9e8qONb>0^dX zU~1Stb~S&^GUXLyd&o1i#Z^SH5A7(?3XEvjAyFHcGg4Z*tsP;wtdB+t(lVrz(E%I= zVg)>45vkCK3tKr^VYA;RdR;3__22;NYYkh;pld4WYDqLk{nE3Y^oFlrf@Q#UxwdsE z)Z98*`wH>=klshfd8P6W-HW`XX?-Y917)T`qNO@k`vHvgbh0sC9hgaGq^1aJXFG%} zlZvBNj=c7VzMYwV62k@wiW`!wzgG7%u65;RR4}HIG_0+9v1S@*Rs95NcYUaCJuHQ! zThQ$^iA~+3N!4FgC5~iF7@-5`ZCT(IqPh*9aU4m|5xf$(Q z8ZD&>nq(umX%Ztg$_%rOXnT)3sWpC@hXd?^*kcAql!Y+JW@dOz%lslDqR9tI8ugTb z?aQD(zQ(YV*2VnGI%BJS6YZl=hMVgz$9!0-ToGT+JS8)VX-^lV&*{*AL8IYFK-!Dm!_?kL2C-;o(V}%VWS;jt8=Uwh0^SFW&uIJq0ZAS3KQ*MRb$cM$imFH2U9E)LiWD()nQ~*HASBwoxZRM zM73VyfTjI4$s`64yv#-nlIRWGnePb*=~&Waq3z{N7Nn^@=5@Hg?Yh+U zrD>xYGR@9J#C|$sm*6dGnH{L}%+nXr+$G|MICVllYDE=KE{@3}pU@9Ljg!vm%K+X{sLR8tO*QZO5qL4MfxGYP7LjWG5j&B4p=( zBcBGDs@>l1**Kb%w~h{)w$1YM;!+Y_!jdzB;YapKU?hbk8frG{$=sPUw{G3qoqi4A znxrxDq?;)gm5WiHd~kQr!{!&a^a)=$*6EN0ZxU76{G7m79MzILeHk9r?6hS>)y#f~ zyk>)9!hF}V^FfQk!P!Vh5a-5gVPQ<=z6rLBFjvUY+|FGhJD?L?UPw9A_)@mL(uk+A zVefK$dUSaZh{fH!l}7Ut%CHG>w!<1VZMSqSD|SIOvXjrb1t)cyXgV952A^FjU~<7(VkVb13KnI&ip9?M_PP z@kVv9g)ZK;4uksKxR<3pr)09=xpA^(Q}5!5E0?WY+-~md?pYHT`o?IN1j}4AXv}1R zP_CY1COnkldF$8pbe-K!r&{ria@S&xD(TqB-1zLia&sc$p;4%G$>g8RjjODJ@Fw%- zoTD=%IOkR4ljg;<&zX2pS2#bXcCD$|if2yu8QrH7sv#E5>rs~|;Gv=JLX`7&*kknD#HusGF8H(d*_a-=BgBLPqsqG9e zC~BxVQVFTd>8Z?_WxJ_btJS^C>NfYB?&WOS#NrnYyRDg}X}64T{V*^!hvvrJ-R;ng zYy3Npxg3`t(At40v6UiU9G0tH;i%u-c(jzXUvfL$8ZzseMRwywaN<}ikD?NsimiI0 zT|2PzU6p1$+}Qap$cN>CRLJ_s&UZD2lfuXloQkzDnsucxXij!J?X&bEHZ)?=_n1g5 z4hcX!JWF_&l2KqqJAx=adV!)?4e>XwakzI-1YS;tBl}8Cp)78tV8(--7cCFQr7kg- zLb!K;Y=|l~Ik(wFPnzcbMyrnrf)}oi@-Uz#>IQ-pJKr_PT3_o~3)4je&(-|A^16$r z2X7npBm5=4Y1fSe8_KA#eAv$-dl*YZTw?`F6RWfgiJo3ZP~W+O&>h-MO~bmd2e6Z# zU{z!iC!9kC;-SsduU=qWSd%rIF~c-mEyR3q`^2m68q#O?BpTfLPy=sV))q>aIux4% zMzLqFdTn^@jRYI0QCu4tpdh4-P95ixFb>ty(9RwD+?y4LT}vQkNe#4X2^#d}L;5a1 z9zX%1+Yyg`If3Y^WzAvmA0me4KS%Af1&_5PTuu-u9tnxDufSyj%E3C&Zfj7&&{Hak zuHsyrNV$N6fX!GbckYl~4u&?&0qnTmFx9YZf(FzuODl}JOe`~p$5a^deTsCsFKB9P0fI`(rJ9nUEWg(hp;fjJTUomx7 zV>t(o^vN@%FRtH`3M{hCSAZIkdsWrn0F`XED+y{G8W`rdsD?tdC$hNnp~~ih#TM

                                eDaxb4i|VmpV0z=o=2YA!_c(`I?a-S2;&^WzwMxA2_F z+7mTuI|Hj|##0Mb&T&j_H&R_g{}$rXAY<+v1&ifypB-RM-bv8NB5b40Q&FdvwYV}}=kK*-axmppM#VXEx z^`Nlxh(X2ug{oL0W@*mmGi@+0*!VG5VPiJ9k|SbiB4N@(zpRfv6~^u1@|G?Rw9ak6 z$}E8-O!}nBbo#GrxW?*0d7y-14}`h$A%}Re1TtG3CXAT!*?e*HeY>WCWd%i{~+Ig+<{sggAYMdV};E3K}!GV=S z54ACA)8IgLTQm{5aVCO@S=ST>erUkUL~(Wx|3wbet~YJ>o|a$%rs za;1+FNynWFTnUBUM8xG44sJ$P+7WXlcjbZzsOmQXX!Idh8t+#51})=zB}+`Q1nXsW z7xj!y=#bma9mN8tD*f7pl^lA55f755_`&ij%UWj><_vmTG=EE9W3(wUC>r4|XYFJ6 zF7UNFvQ{;Sma||+^ubPSzZFeMF`S~_d2O{QNt>!8$!0cA{E8Ecl5FMzhCx4_T|l{2 zM`AbO`XG*Tj+NHY^2TVAG?;k2(11!|dA>)A0Y|qnG&BcGeBM{A7K+nhVCkgGJC|2z zIXw!`n#}!BcQHoNlO@1)RIQp6{I5o)F&Nz1c}b$>h*9WL8V#zQZYOEyg1wJ%5p6k9 z;Mj~}WdcY98YD)@B1@NAbWLZ$o^Mw*j7NzKr=KBkyR|{|0)q!=ve3;CxtF~Q9V95pQ$=N|^YZ$7~ zpvA|jA(>>npAwK&5JGSS&fXa2tVcb_e=j(A7&GKOT&~$PcEn7Qnw$+t9||!oXU5YA z2D>dD(7s4$f{E}{FzT>sg4gaYQssz&8z*w9=Q+^c+Txrodxv%{<8ad8AibUDV*)mp z7CM%(A(}rXx8QHiO=IlN2S0!!U3yrbablpX6m%>ly&a6RFRt6B`;UQBb{jRpW}(pG zFpY+_uCY=_bvh0qVz=Vo=le1X)Rn2)juVWlwqCP@MvZlDY zm}Eh_*2r2Z_U+3c7$vh)s{)kD!+K|&e0%vQoqp7~h(Ai%OS5T>bkI8tI$BmN3`VPr z5t~dah2;i!Ok&n)jm&J8i`h#9BN6{#7!3vnxdh4cdB?EsKNv>q$89$n1UG^=(wEdx zug7kXG9(elgd|tqw7fK_IryhZan*VE5^A3%Fln7sKb-4GLYsTzg{n3aN{gHNa#DHaYvBG|Y>e+3H;f_*v`(QeXA5P_6Rks0{4w0Z*)Y+k?gRFZ+ z1d2lBskQ!TKLpZtrCpRog-&YwgJ^08z{Ya#BTN`7U#-HA!x}Ahgxos4u1K`QSj1%> zTf${NXOW#=e|xbX9UFUnfZ3G%{(vqBxlt(%o1S4aA?g_wFS9+5`LGQ*Lt`@>Ia35o zc01M4NbWvsCxRqx0{T?zOvs1%6&o>=TPEY+_}+A=HAKR((&4n&a-};KB_}%{!bkxF z%Mqh}@zmvFOar&R$uJJ46ceO33wmf>)7`qs`UNSQ3)WQ%X(DJg7|ASQcF%wbrOEk~ zpl+O8-;`92Z8T5@kW=>8`@Zd@IP+A|;>8EelPZTEgVO22Xa>1VU?6<9X~JT>5s3 zT~vjI8ws?YkUyPgZD%~PbBB)BNVAc>%#6zHJ7IC4|FSoz$&MgLtjS`_Xo4Y;s+P|u z4c4L}EQy1jC<}$Mwe?1bN-Y&*!)2(jFi3YPmq%d#$rLbG5{3 z=_J3sAno}jC<92qXo(J+t9#lP7<8H57A-L|mi>*VZ9(v`v^BMRK-3IRgxY+@m9;#e zTP$KaHx-~X?c6cQwsX)j6ar6TvZev15iT_Yw@V>tR8rVi8(I$~!_=M?L9}$|Lxb@& zH)y2BecfY#Ik<@y8m;CUR%!HJywwQuRfSoDb!yvHI@UE2%}e;RH$ZgSxjA8yFjb`a zAVpeGI#t-~=$tCtI4C2c{sh{WGZ4Rpiu%(qQ-(XJw1e917J|;SyCM0GloIg8e==83 z`)s)`v#&Sk)AV+NF}<4)X3~4|0Zn+*m@&t+Q;ZQJ9T8)=u;iY!Slz56GZ)g$?T}iw z$c_1EjXnWNmk=7XMvFHrK65iqm$hRc22*bI#|=(ZR8?tGx;eF&F?b2h)xOabjJrll zNtbRt2oZTAGw#nvBFvsF9)qEM^M`5*PT1r zRDVd@F*KHM1z81FO%pOJo{SG}-El*Cbx>1`UBVjsIME7Q<7nqwc502khe)fSVGBZT zWZr;jF&bsf-*TZZ%>hFJ_0eSs`Wxo0yY0FJwCL2p5Ut2OoCJ{-Tue9>B*6;di5dYg z-Pyef!{PHh#D|%LOj&VLp7m4~jKaVMHr*OR%nhw$BeK8D28J}VFllARjHll^>~^UQ zK<2N^1ZE6Wyw1#sJDOTXnNiHObO|*$?05;J-0VJqQSutxbUkrlH0}Iy|m;)63d^393Mvz;yDuooj-_ac4?(4Es8tlx$(D ziMswF-1s1gqww}V-YO}K>$JhKs=eptn`CXaMqDuCao59Uct3k5?O1r&khHc`9S`g0 zyujxoz9KTA!@A^!(7bj|W(C@P?$1_mne(nXuCQ;2A6YSAONVy%8Zk3{{ zaxhz^25%plQRasw!Se?O3Rsyt8_`~0Gcw2-t1;ZsklC<}D+>k_8yVL)5Q1zx@Cg)# zDo>TlBod;1iXgKD?F%7XtIU*k1Y@@0r;8!b$s>5~{4M@77>jr7oT@qTHg@S;e@auf+DeE=R;U< z$uQg`VTG8)vg0Dy%rcOkA87z>G%5S>{$|u&j=VGiY(cDbGHW z1*Wx;+^xs#$8KN+v{~A=Gz%67+2s=4t>MMw7DS8=6w6V4Q3BaQJi9J@2yE9+dLx@$ ztW}WHD2*sw=#1Ga-_Hf*E|x&-OQ(SD4YA1jmRc6z{37$B(Pr)-_tIC9Qo3s*^=3=r zG{9&j^|*>|WoA7I9foKlKyOqzRFKcbbp1q7$5};&7OfRg!kcq+}6?WaTo1ziv=?17~Fgd2) zpl8sGG-7?7NmW-G=aSLt-1$28;xql&_oTFT^PMOe9%OTbn^E^&5{iF6M@n6X!R;17 zXUV%)YxjhS&^Di>)m@^Kq=+F!OQ_MgX;7tx5?!#{$GURSc}9{=RB9%pNY?3v^gK8O zwwB)Gk;^vd_=-}dCMI5Xd_-*BtDUzhYC}niil-0fk3u@_jilB`+jz?C!XbH-G1Nboo>mlyGT1Au}sB2vR?4XL1K})pLw)(5Gyb7yLMS9ie`k&y2c6> zd9(}G#TPo!6`EyyO47mCwMa|8US!&`kWM=+9Zb{(#z^eNjDjhfWp5)K3kiHTo~-{2 z!VZe`YPV19d^Q&jq~x?qB zZ8QzX_#*3(C*mXe2ALr9G|#hsvBA?;AUh#cqn$b!EyV+EtT{yz*ExBm-P7!C`+^r4 z$7Vg#oP4vIEb_Cuc0w(bF+0nhEj%+!=VNn)>sud;CgFw#?`+1!cg)fnhJ!YAP?+o- zj(CV`PR06ni9;3RthYt=+OCOi5KOOUn7_p>Mi{hw*DXD6kewRRH4R?ozBP(rOPbnM{zV-)Jz>Id1yn*4xL$%U^hyan}g_RyM~FaS*TV9?YWuQ z)@@b#QOyo1a0(3$C;H?CYzrEH&hptN>>(D5B zv=Zm~38oTOCY>m0o4E-O|A8APl7kbwQ)5JHC1F@6nJG$tym5=^9LU8MxeB%MH7Vmd z4P(M+YEs(i98Q@$YohSkfDWTDmu-YmA=-15Zy2O*PDUZsZ52Jxrgp&bOB`~AtQopG zxeY|eL|rGIU`I%$@s6+4Xbr0T)$xV&YY$$hJuUjoG*{bG>>EYwGR-p*3GmfE2pDai(R37U>p0_E(gxGhW8Ce*?G;&u>cZ3znN9)pQT_^0+fs z*AepSW?S`v5WSusp)3Zuy1$AV)CBUdc^ldILmy$wknIlp%MD>Vq?~5ks@xVh8|*RwhBrHCe{_)mvucfb7}= z2$!|1J6>t4dveTF?rd_THJ3FrFL#o-<)Xr^&j<>bJ&>gR~1*O#}j1+4~ zY*cR0oWUo5;mGSa*%iY%ZR;3r#=t6NnYQb_8{_BhD{cl zFn*M>&gY2b{LB3C-Iw3Up{Zum$ns>kB^j^^!1c^{DhcA`Z3&uOmX~H=%RM-(^wO|z zpGB#U{n%3$Bn2+>1T8M}+tIGf=bzo$#4}|nXs8@0rv2?yTIWjgvefmnqruO}bT0aH z;h7;|gD>$M@_bJEFVfzWMJcCJnet)zb#g9gZi$==^)`&jg(C)BkAyB}pLQVMLiWv$ zb3>9kegts*Xyk@}jICo5USwwmY2|}1z%pB>3niQ;rww}67u5B;zR;GIe(sM`LLB?c z3^ra7)>jgD*%_79s!M7E)*!+|IP!uq7o8vo)11?pf<>i#)M8N%(Z_8`r$`I~{C6j! zPR!$p?5gd#SJeyBmhG&zsm&5mwm=Arg)LbE7VHRem-uEO?7Sd^^~nMq>(YNgY!|_s zfHHNeHe%leOD_xN7Npg*t$vdT_q%VrxOdsciw3y~dTd+uvO#H=!N!vD=pA*NPfe`kiJ_k{c(t+sgc literal 48648 zcmcJ&37lMImH&N_0J0;X2qNADvSGTj00JQ-WF;}HbSDuNVs%$_ccrVVnyTtfn#COi z_k9IL1auUaaYjZ5M;zlexQwVXF5|w==#0$hxcuGb{r=85_tvdWN9O&1-nTxv{kzY; zo#&kMoaebuzJ2nn*CzaKctnz%3C=n-Np>EdB>z5NzDaV~1xfNaa5eZy@G9_8;1KvE za6h;ld>^^ z1)K|>0A36#d?ToQc7*@a!+&qMn}N>_|5t#IA^sacb=~_wwfC!_>h}xqtKhG}*MeW5 z)6N3RG*0C_A5{4-3%o7x9&k4P_kpVCx4`4T{{mNoe*)FNm#s*WMc@|jWN->p`(FYo z|JQ=2fwzN?1wRC);Dh1*1*m>Kmch{Yo(wAeIiS+_fC|3|JQG|M_zds}+*9Bn_-s)1 z`$6D;g6fw)g6jWMS9<;nLHS<-D*Y9p(mge>64(Sa9?u3gzX6rspFov+;pBf z?Z8(Cz86$GKMN}UH^JH9@4z|WnQOh?t3de=f{VZ#13v)H#r+*n>5qU(DBjti{MQGL zf||dtjPU!xb8&wU6g?kDh-lJSg|+f#-n6 z_d(^iE^rU1d3r6Vetl*5-w9rU`~C<&d6U!MLQr(F0aSiva49$iik{yMs$HK1SA(Ae z)!!#P+3Rx(cogolz(<1fz@x#%ffs{k;a&@heg{C&&yAq^Z-DBrhd{+UW{b`>2YwhlAN&-kbiW6uz!P_P`)&bG#Qkzmep?c`2Url;!lMC4WQb2bKomMwc}0T?ckl@;oy3R zTIn`{s_#=k)uRMH3ao?b$L9pT4AeN>3W~lz3eE?=1}+1WK5y4~pz>V~s+=|9-Tpvt)+@Wr6Yc_XO&?*mo;AApGd;skmYe1EI2dH|y4^%$)gG<3rfGX$L5uWUH_er4o|BP_Y1D}k038?(80~doggOF14 zA+Q%bYM0a5lLBuBAA$cjz-NNr0v`>o-0kDq52{`*P;~KpQ1!kQRDZlH{67a$#pFle zN#OFQdiytna$f~L2CRdcuQ!4!=XOx-y*I+|3-^~m(c@P^(apC(jo(iK9|G0R-+-#$ ztSg<)PX*OqXN3D4(8dK+yu}f|3RM4X0@a?K;Xeqf+%Zt~Y)AOZLDl0nQ2E~ts$K67 z_uqpT;QlPQ2t4d*9={h<`4@sJX9cKopA4!!yTW~S;9gMiCP9_+0#NOI87Mk>Gbp;c z8$1R45O^~9IZ*k12h_O#1bi%b8cLATF98*PX}H&eD(4DN^W>SJ;=dYv2Y3&t_Vz!+ z%e@LzJ|m#Yn*h~MH-pOO<)G?!8>n*L35u`0A5=c~gKE!b0>1>FgZrD{T=1}~JpFu7 z`7Hxg-esWZWGg8883dKjwV>wl3qbYn&7k=BOTj0CuLjQr?+4Z2KMnjfsCqu)YRBV2 z<^NdlJg^s3y9Pk@ZxvL1ZU7bU#h}W68>sp8?r?ttRDFL4D&2p9D))#z?*Axo3GTDN z)4=VZ>NyOGj$RFlKJNry4*oTGHn{GY^y6XlJ1F`H72qszGpK&r0X_-5D*RsqD*YS5Mc_T*|8-E~{%uhG_bX82 zFmK3l1!!~}_)Ks<;dM~)Uk9EKei~Fe{t)4(4SV`k;F0+61U0VD0FMBNK#gAw6us;Z z_w&J{aK9Wp6?{FYcHIN2oqq{xd_M*r4t@<(e%}NY@B4v20o9NH4yyjY0*?X@AMtXJ z1r`4^Q1v=9a2}}sSORK1E(bNv&je?KuL7C+$zOw_=M$^Gu2~DNJ}gOY0U^!gvwM?d z0eJ4H&yzmzY~0TRH7<96mw{ggo8TEWr;nF{8lMM1@tNO%qQm)PUfv#1^?fyXEO;Au z0r(f7`r$j^-QbTvvQA!7rw_s3f*OZcG`zoG52`=z0F~}tpvLe0pz{4JcpUguQ2q2n zQ2qaJ;PK#ZLCwP>$35ROz>{##298=J$l6OF)g|lfn653sgV78GIyoFDUxGA3OUVM5>1`vZ{P%*&X983`uLn;Cp9d=bYeDtPouJzPPH-9c zp78%JsDA$;sPz91D&8+Z_49AQx!|c2uCFWyHIA2pCxV+mm49X6GePAy461$&Q1P#g z@SDI#;C?Bnad-u&{&`cl-wi7M2Lt~eRJ}eAYJPkfJRdw}l0KqgtH85y@0s%Qo)4u$h*maKULG{Zm;2q%I z;2Ln#_1+&Z0af2y!7bn&p!(q<@M7?HpxS%>4PMXnp!%^Nd;(YoRj(I-iuWo|{O0Z8 zso+OIweLYtboAYD|03|PXF1)T1gc&0K+)sHpy+oEcrJJ)cn0_aP~-hp@SEVB;7h^h zKHKNdiO=!z=mnMEa_|&zE2#REK=Hpx@O1DEpz8Gja0B=WQ1Om^u8&&^DxaO8>NOI0 z4XAvt4SX4>@wg-0p9Iw(Uk~?BLG|;WK+)f<=XpJk1!v7-K+)HC zK=GlUfsX@!3#va(eZJRkF{t*e0hRt4fdioWe+1Mx?E}@08$pfp%fkIeP~&z7sCwTA zJ{tU7xW5mI{(lLc1^y9K`ZHhPI3HBG%RtrlB5) z235}=fU4gwK-Ks6;CbNDH+uP(g3AALQ0e->v%$d#e<7&xdnK5HcZ163)8IVtpFpMi z1E}#k?k2BS3W^Rc1l6uh;3lvil$?GGn1c6$PXoUSt_7F9(DR=J#YbKM&H`To9tpk@ zR6E}Q9tPe8s+@O#j{rX${vQFA?xW#<06YTsr$Dv$bAewA{~v-%|5H%;{s*Y?9*Xc^ zgBq_tfQN%e-t6@|22}YcgX-sVK-I4YRR1prMMs-J`knd`xAUC`D&0+>#^EiX!tVo>?i=88@K>PXEqSTe zZzH%F_cl=U@+MIAc}w6s13v(&Uq1q>J)ZzozkdYJ0e=muUXOd3m$wX5Ia@)ETLo0V zO@SKU=Y;?3z;kiG3sgP+3ET+Ie!0ir3#vZXfX9N@fyaR_1XZ8cfa24)f-3KQpz8N& za2fa|P~&jKD?Hw@foFlrZz%{%O)dpB&L0Dn{*!@U4Ez`HiTM8*TnL{0N_VdSk!d`QR%+<@X^_{dzyB_z!@p&sRaw{kOmm zfj2@k9Po|cF7PAZD)5vyqbq=Y;8o!JLG}9yx4Qde@C@AJ;JM(7!BfC{LGjB6 zK;{2)a2|NrZ9e}NfEC=AfolKVpy=&`pz8Zca5ng5P~-HgaG&uOr-v2bWAR@Dsy$B! z)t^J4`ezJOe@{gCvq1IlEuiZAW>E3&1y%k>LDAXgLG|aCLCyQGfy(EHpwj;bsC54W zs=TA#>gAsRim#szsvQ@DqW?{x>emNqysi%a2Dk8}CR?&||@22aQR8c=leUQq4$GI%)nEl}h9Jy7-e z3HU_t=U^{*#+}~YO`z(1C8+#IK-H%WimyBmR6o20oCW?PsDAnisCxYn6d!m9)OgOi z%lW}^pvL(!Q2A~G)!v<;>Nx}|{W$m}@H+4`@B^UQ{{X0Z{1R0C4!av&5AANfw7r*lEIdj}{wxgJz~Uj-`PcYx}Td%;Vs$X}3>X#;XH25q~ z{dzOF5qv}Ve-G3={u!wH9r6;Jy%k&m?gdrPcYx}jPl4i3KL*v_-+@Yh;yupq zHiL_CzZjei-UrSDzXht^v)Dh2>c@WNc_JFsz1LAD&L2|W5M5mN`Lr!z26=Q%Kv0g<8v0M zcB}<8-}i!Z!CS#`@Z;dQ;Cb(Z7Qw5*r$R@64VG{p|CcfE!G*YQ2N!`4fGfe@fNQ`f zeZcL`Q=t5h{wt^Zjo@P3*Mk>>_kb$z$DrEvsK565o⁣&I6ACuLeH@mcb_2^Fih` zcsr=}ZNJz1^XcI6xJN+s%Ot4&eO83ODZ<|Y9*+M9L8bq2gntrz6z(s9qPri0qTio` z%J-nDtvpmuL4CUHX<==pu1_|}7g zkN8`!?|GocVH2qGt^k$qRiN582A%+32P)o+BK*~XZwDcjG{H@%k+SHO}XOOTmjll`{%H0=yO!UEctn2R;u}f887Ye+w%8{h-GEli-=) z=Rx()PeJ8#(%*TyQ$W@KG*JDM2F?%vUQp#-2&$edB7765a&~~Cn_Zyz_CSQUBK%rV z^z)o>zX)87`xW2?;FmzARq~HK>v@X5r{VYnfnN;Ig}lF?_fymWeoDWe_iux5kq1A~ zl=}76Jm(Pqm*5pV|HJ#Gkq)Pg;YRRm{P*Jj1n^NjLp&egS;?cH(GKsw<^2qvPw;4- z>$i{RMAGh#xR-*5@qCEqR*S)W;l0fJ9=Un{Ch&AH`?Y!B9rgMK?@x@drxM}a@m?id zv{wUXg`d*j!1H>Z$MIYfd3=U&otfMVegppr-g|gH7U@L$`hAyYIsRAh6n~Jb{eDUO z5A%q2?~SzQ@cta0=kn-x1^#W)p9t1*9{_*BvjD%(f>+|#&-)K}*Y6*A4#V98Ho&)n zmlGyB(l6!xCZ5xI|2@yIc|<$^$@5d54Lolrd<|(I!=v9zd6x2i3D3WnPxqg%;QS}j zJT>Ag^pU*(4nJ6^{T|Kx?|F9dtmauq_(#Df6S@vu0L};RJaQ{8w zW4vD<@y;V%h4+2Kt=sK-e-YN;n~5nC>h`x@R~#`E_)FW~tRe#er} zSHUyEf55K{UV=OOy^WVoh@E9KbKE|_%xSs)gz$5Yh9{38}Uk2a8Gs*Kho}c4)I=Bne?^fRR z`wjRQo@L>d-}-oeFL-T~bqepFgzw3B^lfRmd5w8a4D=lw-1g`>1#QkgDH-jgG^LX^TI`DbCpT_&R z`TC!?;=U%_SCVcR_hWGX8&8S%Dg2%bo(;|h|0Ci)#JhgK;#ox4JIuwL3V%6Yz;iaw zA9ya}c^1!UJU0^O2-2L%`*NQDgL^mlFOl{i1Lxv*2JaK#zw?|$nm_72!k-N;!!P?a zczFrWvG{KWPa^CB-k%JUaxStX3trm(L#r=Ao zOL3pX(<0vEa6iEN7T!Mseh~K#-hak>_Inq8`h5pn&NH9z`@r|$H^#euUw2482i{NE zYrtm`wuSc>NTs36@kFXblpC|0i z5xyVyB+pXZ8+qpPJPP+^dME#X<^4{cYjAJic@K|%pXYfy&&51#9{twxjPRUFy3=`f z%9GzN-t~J#;C}LWU*z+B{BMhQi^QKfxU1l2c`hW)zZSwPynm5r0RP{DA12PpyuS~e z1>Ow)hUb$!`u(LtvN-ZM9K3*de*u0f!ZJ7qfBoJ>*mdCFn5*;WaKcA;?hda1m4(R@)79m2 zxA^ecaQix6&FttC)S(BITV{+m*4Fvcr3%TCSL9d!#a!4mBHNDQ{_|Ty3YV z!DgjW?@d;x^~%1e_fVsmR>lS@<#M$?tg5N@=}4)S4iGm+c6HhsYc$BGnGR00+T`iO zTG>BdX;v%s!Ai1v?S^#6727R`Qk8m+H}+MULld=hs8VWAG%Jk3#NbFu#?8t&UZsIr zC8hPHMd?rtdXY0LzE+xQOtf2z(h{{OO|+}ZXSh_WRhm;#bg5pphLr}YwQ74xt*3SB z%*y_DvqZ(ms`a!nt}&-FrQu3zwpFs;*q63Slhmi$&d9S>X}4)UB!h3gT%D|zCrUM% z0P!>i_A*$lWHsb7sr5A5Psh$qjO0CwVa|Rm|_4b^V3+A>Ku2`&q zl@a^lqm|2vh-<#}_WX2kq(O0N9j&M48m<@uBT?!_?8WJN#@AjqRBO};zfEJbx$~wh zF83ZZ&ux``83rXQ5x(w9FV~FCV{EYjG3ONxPv~Q0UZN(is5zSvqdCEl+RQg^DiA{` zr)U|REI~ZwbgfgBO{qh9r|U#CrB)@~IX>JhmDRYJl8X$J)wP#PKv(44q|(HxK*hAn<{#wS5LIaAwnxZn4jtq{bJ7J+3RGBC-F)g6 zLy26j45{@C(|uJk9EhQ!JKBxmip}+jR-Ut!Hy`d(8mN#X+y}TAeKG@E8gg z2SuhyI>;wFFj?Jhmj*}15Ch5TiS|gNDQJw9+KBF2jUIzf%&WC88EDQMZeKD(;5e;f zf{u^0k~O7Pbud}u)rY62t#+x|PBX%)*qkfvtF#(pm0VCTS0uM9nRFyw(IO83cDkNMZ)h-XnfLaP5Ic-CBknFHC!$H(P55MN zKoSbVOxDyIgQLkB@qh)Zo6XYH!eq@vZIp>?0tZLC4cFLGV!9-2OI8Tjt_(L2n5|?j z-CJn}#PC2eaFVgoc(Rr`KTLy$_0}X$>c6Er28&-iQW+dgR}Uj%{e7UZpO-4Cg<6m< zkmP0n$bKRI5*`7RNv~3*{-#vl+qV{8HEI#+Fz|tZC$&bLM&IPt1&!`Kw4XCATjN4NE?6OjkHBttc8u0#u@Q-l{O5Ms)k2d zZ!oeQWT)kP}j9r6Y8e_(2VJ${c2*I_E$oUh67Jzw*o+ zY5-~l`~~@FYFoLYLP;(5fsRyA)>_V;VTc+d{+2SC7g~S|f@JMPQ)8Z5cjc~~@X;15_E!oMY4K*dLvKe zqJD&^krdV8k#;g&il2GtwFE1_cfZMFo)L2K%>+w zOFsXv^XaRo!%J<%8pD?*tz^VTMYH$x$$hAHkgyo{taXigMTK;QdjDH^f1_NQnjWD} zN(;wO*n zjzdSTPqcl!wpR5zW0vFIQ9EYtC=d0H+A(8#YC{FA_I>txh*(;DMl8L~7^}^oZm-v- z`nAZM1@ER~V5nm=*IcnJ$3Gk6T1YjIl|Ib~w;~zUwUSv^87fWGsFh>dUt!)s-?<0! za6&FAOgXnV`LRmAOwj-Yo>p#|%a{QU7M@iXf$OR*7?(Il!mBi}3{5PTNb24&MkWfY zo(AhO*0jb(1||I@@zym4C&bxZhOKMttJ@lRUb+eO4gODr@M4JyotpxdtV1sm+h|r` zY;eYPnLVQOmNy^^a)wrjV2ZX@+{yY zud!-cU#qB*tzNqAk0B%Z%c4E)L+U0dH9g}Ecrb5L6;OfWjjC%qN#^^Iz1>OoN_NqpsrNo69e$C z5gD?nZ?YQ9|{^FqGO1bmgXG3n3`03B7nWS}LXG z2I`RvW@b(Fkm%7?I>@S6rX1E@C>P^W+^_(-zK7vxU$x947HtdylRjuGN;-24E0CE; z^oKNd9(QLJHE z4&kdQJ1~{*khLl3uNHp&zAm;phL@JbDh{VQgZ70e?&$OzGJ9HRtjTl_o1Iv3>7T3- zOIg|*>t=Q2CJ7{)^xH)#-t_TQ+8VD6R)?nC@=*$Ip$>Mkt5rwErK_#wiB?z&k42Q| zL}LZ>s<7HFY5t}dQJ=i}sfd$ws5Ge+9vX22@rQ@8FTUlgXZZ_!!VF<`f#F}$% z>856-FkI)WXc}Un3zLnm&2E%vf@8XAHQ9)Yn=XiDyc>%*vfx7uBbAa(Lr_PpT}7$& zY&?5L!DoOtFSZ_u5YKOsNj;kw#RMpvbb(ZD^|7hza%iqWRX*A36NrrF z!o&rS{f!ym?@R%I(H!tM*V$(v`SSSw-WlQ)Nxl$;*~t1KBm11@=FS{thD zvD3#|Bt^ShP|Wsi-Gubit!lx+@+AC*G+R+}+EWpW&dUt>Zm#l(Hgk(T-%|W$1BRWV z@Rka$N~=0t@3?oi!Z4j|s++!5$zLAU2Ark%Uql?NO_)^HSdTZxCu%J1ePdu5%h7>m z2>~sOKsBqiSuH2B${BlPTGO186mcjqbt=(pG)niCG`*V@WtKZPin9=u%>jL46iN+N z<$2oX1Qb#qY_Kq8v%|Vv+z-E@27g$ZGNi7qu~OFC!D6c5OV@Xz$nx1t*%@FF)9Ou8 z(f8F^%V7*_xiFKeQnnEi6Dv;)$|LqDl1-TTnC}GChhaF>&*TPsSj;!5Qw(pQG$>0U zuLavv*x{f6adoonWdcnxNCJlRq(X&@(TTLPkY3}0N3Zsia?1nZ+ z?bYm}^7CS`57AJpSzAl>*xSLPB7@F^tgpjjXULjrOB*s+<`G)fy<;V$jRv&VXpAC` z&BmA8%4etB8rUl6nAYZ|o82(`4S1)tS~iQR}rWXo!YPH2r($Bld&u3Rs`EU?h0 z0cyk6(tbVFv5Bz^W3|xA-E59@96k}%xsfdObyViE&dS5sHPO}>3OoI=;JUHW{u?lX z?`tj0W4MWm{IY0yh>buYb?V8(yOYCpCaG_563KGO3cC(b#(n{_zIg*l7*c*joT!|ja^N1^fI6O9j7G(KF@8(*#GjgJ^JG*OW{O_YIL8bz{IZz01G53XjI z?TU_VVfd>nZ2#Bd2B%~b3E8DxQWqi? zMp5iXwnn;H#VX|?o@BW|Gtvu!b-P1Kf^}IdvGs}m7}pc&YE5s70$fnLFbg!1D@~Z0 zwmBBgQh2fro1|AVe~Xo-SK9!KDLy7Pc++S$~SR| z1s9!Wv1c*$u-S!_L^MbwT6Ax?SG9ZRj#Y(btYifRj)`PS(Ezv+M!R~Z-OUSwy!UIC zi;J*Kk24~)EMq%|S&j(yO-2|Ord?^;bX~2SVicILUL(f_|I(rXHu>)a<$V4UDbzGLos#P zHF}j%VNg11dmey3(Am^j;ZlBO;m8I%@+SFLW}6)hpKWlM{BDvv>rgKvN@FHEO^PVk z@6a}8mk%-&wq0myvA0{XekG;vhIrn{qil0nnYx-#@Ko9L3V)E$wQNnHH5s(Pv|=U1 zA1U<7_MstT2+4LjUlV`3?`dUdJ43l+ryV&dC)>>gW`EOdjoxIt7+11G%wB&|wgH<} zwu4{?=7uwj`r8hpM}N;vg%-zFuX(Uht@+!ol+iAJ3rT4~HjK)>)xwHj=C&y{)rygw zVx&<+0q_>>$PE`^d7={tGwqD6CY{GfM=Kbk1~d;D&}y4@CXvcV(S&~)WvW^? zvEP{_R-#TtCT#ShyxF{kyg_V z6ebbt21o>Xn4N&CHZv~VoA&FhL^uB~%QP$wTW&VSvk58-0A6Ylym-7wwX><`FekB? zGMS)cfuFrfk?eAW9KNC=IYEeti!iu^3l)d}Td8Ll8Wv6+n6jem@LhQoUM*H891_tR z6O|Q~?;UEL<<>D|pqp*sTGJvK2Rn2uOJI9!LFuvM<{I1;I*h`6%gjz$m5pMUITSxH z8&(R|=?b0oK|9pLi?%(JKB@RK9P7}K+cd<;kAYBxa{(y z-5vvdO$RAh%^1I-5-52rX@E+maf})OvX^-;0;@KsqxTC!zEMC&uxlCp&{n~TV`$YWeQ z(#!(kk(m*)2pZ%=obz&3P^KIyVf*ZSr5hn7qhy@c%A(Ualvn*lY^SoL>8B zdxqG^n-z8v%;1b&x!5#|Be9ytF&PWfV71tqH-c5WI(|tpMJS?smdrw>?AA(sFs$iW ztfjNIGgUo1&G1|y)d>%=MQ@9kfs<#ooegSNKJ{5NH)>^8mO@5afwRaq(JCWdi4)QL zq^p_0u9qgO!-%%7Y+J@6k^i%tE%G)~TfI)mmLkbqsi_Xp+fG8%dZ`_dE_TxlN$ay_ zN=m!zaCIcElv6sw_GEqQsz}PBe%o*Lo*)U6o5c`2);yv;x2a*!u!COLHaI0&)0t5P zNyaeG(c4NGfwIFg`N~-q&Qvy;5ENqb^U}JAe&1RRcQI;u;dKP_ig(~y4ebA(DyfmhL zY~-s_#6Fn@v}tFRpc|8svOLlN7V}cqi}70RDLRzNV*8jZkF@kr1|}`NY5%(fPTS;@ z4OpQzUWu$ud45QF)ap74KVNlVfOGzR6)(^ct$-8%|ulCN_5+LiIt77Bf8 zL!!T&(kZ7qHzj>26dU|hS>J>XMz7YXe7vpmlfHevbIWdxt-&PFlRmbc?N5gtnKQls ziBWa~TYqUF;h|Liw)iuwKX#OODt}3(>m~Z5#hPI()@-q?KeFPN2;xmAaQqFikj;qL z!LbMhZ`O}GN<-;bm`6>`kY1OcmNZqdOMOG=y582E!WM&?WUyLjdvY%3=9y#6Hcf>% zBI+u(bJR%K%yj!V9@K<`8oOC8aU|X9X1bABct3PS7Cv7J8|iK`f;))t@(9t@qQx+z zOS2d&Ne76N;~b4+OJ&GP$yjsy;W|pQ{LLH(7^h znTj3z-z;XzQ}q%j)nZ01&NvMFPN-F^F$Wvtm>w90aph*cH?5J3Yez9+Ws@5Ld&ft# z++^-UIKIh-hRR~j&uvqGh_ceuc~!;ovFl{+%dOy+blJK!*~$wem>m_?P@->#4qAfs zP!~5oSd|IaXDd3ctK$ehKr(L>wxMhlfb5ZljzXlf7b9l;#J2W17={>{E%guO_#fklx7+J0Ii(5cr`g*92T~@3O2~(>Mc`da3C8s$y@O$RiQ3Y)wXGBF) z)Cqo)87j)Gw2Y|}BoZddGtIyfCuT-~f*jkSUGX6I;wLf5a`)SqzzjF)vCWYYo0>@aJ;pC5O|5?v#G z3A5m}dH;BCQl62mIz=Zfl77}hb=&X@t6%;dfvd4L0gJ{$gt6+>#h`bZb<`HuR?ps) zLmT3EoL!l(@8ZnNZ@IAgLygS~VP~;BD^7LOJQ+jAvClxF!TB2~ceQcIlnqSRYDB(# z@IYQ&b>aNKcyX`}j%Z6D58Ah7%F3oMADmVBwh2B<@y3TBg|N6GL#7)-^V%MwOKdg# zf8S=Tcx+X-FP*bzK&SENtUP2N*jEAl_HjVE8dG+Eqfr|uH4TyB*xs5#$7GYK2o!DBGO=Uk8QRyojaumcVcHp-XmC)VFpmBAd^dT z6VEQ8*{i2R`1YvG@S{B8Ke*Up5UgzwGarrp+v5ONj`sOOx zC0qOk+ivc>##XL8G)!7!+NvV+=&Un#+2ILtu`?9&Qd4`wW$G?UB2%c5?rSy>+zeM2 z8_HH*!xN}c#&|RU^_EU?N~f}OzB2JHl1(jB1Iw^EF-vrhoasoTLSx3D-b4ZO1sEUO zaa53H?Ln;AxFmZ4qbf6@j!>0r+4I@MsM$sj>^qZ`uu3T~yDRfyljf;zQLfTMv1iy< zpqW;}fb!8WG6dri8hn$vLo{vnP-@aRgiSKp?cbBI zm7eUjBd7w7-t6XkI9mX9cGY%IwW|B3hV9c`J}0`e(n_9&Ngyc=4(&mCA6u|6Kja$Q zlb!GTw2-uuPJWag-7~Sh9)zKNf}BVcBqQzi`0~Yz_wC!)D^pRU%>W?BdTGOA3v5Mb z_E8Z>^ZC-xXS~O%mJ>QDBVWBsD(CLKPnqD8>?AZBhgMQ&$9L9RGxOSOpIMI*KUI^^ zR(1FCl${>lY%7F=DKMe-4XYByVqn&Kc#*$FQuB4rn%H5&5?T&h}e^DvUK8I+_U6@o~0M0OD~3u}`e%u)3g>UpENJnj0Z zAYD*;5fE>HWg+i8IF zx<^8JxmmRqvnr_8FVW0o^Qe94&i)NO7j@#PUPF~;&w7+@of=!7UNlf`AA?M7mTEm4 zm=3MwX?@(BtxK0(!s$7MTv|_OUz#qx8 zFHgM!c_`=JWWj1}!5FqY-LvPCJ(WxL)R!+^wCs{S`vrseWH0so%g-NNq%b~h*@Mxf zNrL>f(s_*p3L0sT)gqR?dMta*v)xl~G{(Km`hItu=jH6#!v~?9aogX{<8)faSGIf- z*&bP*_V#vsckl48#+IWr4r!f9kXV12Z+WZro-o2JPp2xaP9nFs?jWa7D+{sjB=~zd#9UnVzXLGbw8XKv!6U+&Gi(V@Y+bdt5 zb1MUEpj21LkWvpfNs^8>#yNmi;@g2Pe=^NNSOj+k>3)z=jA|I2W=z)=?1{5_GRHAo zkQ)MCnI6i2l7?VH;4jxfpnPfqRa>LU0w|T`Ge*ElP1k~KIdJDNGDlVsYm#mUdAN?@ z&W;V0n%@z!SqokSkxAiJZGxR|%Z!eZilcRIi&oObbzK26Q@R?ek*88!TC(lZ$3)&m zMfTdwAUeD|$_bYP_aeaC?A8ygEFZYHwzp)VWxF=yz+F0JSgvAVQlXPme0D_C`V@b> zNtV1?A2@Jlxon&DrAcaDuZ$eHi{>w|Q#=dN0WhvG=sx;}RkD?F(ej~bW&_uS z8th2v3Xwb)4Z6OxL0_w}#F?m%>XatFd@e5fV&$!pTb9wHSaw&S!#syYDU*iL)z`!A zIPh8Z`Zq8qj2*alFT)9aGK%Vo)@W(G6o)578}wPtir^EpM$<14!M@G8YE(r&45?Es z4RA3oVX9wtj|g1VO(x#$$!Z$G0P0k&&aJrH|32)2Z%bQx*k~OxOggWr6LCA8kI{jT zUOVG25<74gv{o6WJsu4st#!p>Noi3*shAa}sG^fASU6+cp?x}2UQWAi)u|T4>r;_? zhn%{Dy;F@LObZB2qfi)gz8EJWcD zK1kHofPRNW_ThH%upTFW{IZe~rxnK9VlAC3OKe=kP&A1~{jw6y)_J$m$LQW&in{3@ zuAiX&$O>Q<2W=ar0|)Mcv!H>pNlYm{smOn#J<0c!d^6yrXc-S5xRbq|>hPkpb>J@J zcm>tj=ATq&wz3#uRhN0JtW?)5sr<+#tsl6Hya#w%CG9$P$SK@->=u&1!hB ztuA-AbQr3h~`pa zfAygb-(YWsNiu5VaK%xzi=nU^Q~17yG0!KOk9;T+(t|@FMe;meG}M$<2G_4mnH~wE z*k405Fr7J->EN{AaomfV0<&2s4Nh#eRNISlvme$Hz2Dg!CLj0>6u%k%X^RDQy5FBt z;sTWecaAZQ&1ReN4Dmpp)Jnr(Ku-A^1uz>;F`9&hjY2b<8z^%2Q79cvdFabhjN#)k zjhTo{4_6O6Z>>-=RXI*n!Uh?l5$r=^L!3LHE$|%ehQqsDs7K~mbeN;W2{X@o#+MPA zV3T4P9Fisi1`^{n&0&hhu0BlTv$;vh2m6VZ3Q2?Pll9V&e4_Pfv4F1K|Hk0sU(06q$iL`b8mv z@jVe5hsU}UgabE1DRduvz(xjkiw4kSb|OP$xp;FXfD3_Ku(FUhw+sDTi z^rxf{;f!3no#inxmXn?ck+jLCa%ni(X0qLwab@_xT`nqgE5^jw;&!#1C*lT^)yzC- zZ`%X{2SVg4Bo=$E$|&-PcXW{a9m$YzlgAE@(^%*(QGM_vG9|q|ExyKO#7ookaIAcG z$bsST7tW${GAA6=2#U4}mz#`E#;7!ZS%PpN7kfN>%psff;c|jmgDJCFoz$$+B^RS{ z4Ti*;$u{H794nWH%kcpw2Yc5HcknVU&1j4kF22}ei#@G~=20PrP35f}GdC=({M7UEe`{H_dncxyUtSLI@LV{#DQjQGxJM|?Ea z5ZOy)((QCDyyHi$bBENij?1f%2b$AUulM6w({Ie+dJOig{i{C7ky>R`XNTJ3lEKM_ zDNR4K@2_S-FOITTCh<%#7}JORQMlonNg)nhZbakcF)bd;b9fNDy5fwTMKYt&n?jo* z?llsv1NV-)*vis$M6V_`C-b2{*6{@EquQKyr405se-v5mZ0j7mQ&27n*4x+8`N)Od z99L^h_jbmh`!#m9sRIiKb^Hcq65XV~-p!p?M1eW#Xh)i-<}iau_?O10wo)QZ{3U9j zzNC08{Ae)k(Gp^eoq9=(p}e4uGGx&#A5RVw%q&Hy@7)>OMH}2P;&~Smu`<`<{ouS> zSkIa73bCotTgVWVuVV<1bmHllG%UJ*%PU5p(X!UtWK+uKL|82fSwc&#QK=KtYBJ4~ zHLYPfCxc{wW3$oYr4;jIe=N*I)3YUk> z)Gj(wXHz(vXa4>dS;d5y&?rFNp`Th_QWYxA&J`Szc`znE;>gxVxe`h@Gs$^$EHrN7 zKndJrcX5>Lbi6`2QveO=Vnv_1omVV4cj?HDM7;D)Gw7id({q-0q+pQl@+PF#e`3U_ zDG>?6?8+zemW~ulm(XEY13<&9b_zk+DsZ~LX%LFb4B5!_D*CcM(?ndO^jkT)>{W47 zN0*;VdyS#UiDS^AQEq^7Fs>Rw*L@e+n6Ucb^F=P|z`R8Lec^9bFcV=$m!Xnti9dqx za_v@zrY{1{$0r>YbJ8$RzqO-#g;}Yyci-j=ck$*9UuLM5a7pRfetkzah?kqNswS7~ zw7K=P@hMieSXK5OxYt;LY%jXLWADM2cR=jv0;zaSM!&{r4vA~P#+e(&B6xMtWC7gR zVM>+j$jYOu3|pW|xtaA#e+Y zadpN#n3WbbT}(s*GMf*4ej;T#o1%#D94E?yjl{A$G&H5ySO2B6Pq1Luvvtn@tL~@=@$l-#}ev+IhD8 zjkaOKW7Vz=f7F+HnJG-IjXz}S3YH2?2I4bfAim(X*<>q2u@AR&OR@~NTm{5%SS{mG zxD%vmnKDb^$$V9gJhXen#7v77O5jyl_Yn0g*Bs8 zxtO15CY!`1xe0_0(`pbt7aI=AI-1?AxbU)-rmcps1ZkFvpB}iA{R29u6*`CSaAl?$ zb{pL41K(^DS65N=rUza?tSqf*hRRLL<#d!DE#=Z0t%17MCuD|$;rQQ5MAg*SLAP#rvP(~(C z>BEpaJ^$$Z+*g`7U6+?{*^6i~>(gD?4J9hnWb2G|qSQReA#)C@$Rnl;vinQuYt7@h zz=XW63(e&Q1gq#)dkk%?7g3wSsZ?}OyTt^>lbcHrT`(S|y)H4)!xyluXdv|&tDW~X zF%R9S>_ zS%vi264WL`i&J(GIQKfmqLoz8D?(79)Mf(;U*9yeEHj^j9Y)NWgWApr^(>2RE530% z9R+*k_-K6^?_8C|Y;v8wR~{b>S?XuMPA#`M>Z+7_Vp|Z~qOuIL+YPN+F8a4&T+Ef+ z#A0SUehPBCBmP}l8$}}s^Sgp9JNJvbP;?av>}gR7M>2tkfLp{-alhK0I~&Ma^hEdD z4gxZXB5c3Mss-QFM-p)riUvtdRFvWsC=wv17G?Vf=w!BwEnPi3B-*jhn?A3+W+*w| zz{o!&JvehUI`jp2oJhlV%T=vThvs`3u{RjJ16srGV^Va;NXWRncifolp+O47n`b>q zJuzUYTNs~wd&E1rSbyKA$XF!FG52D-bgAx2jq2^$#a<_&viKu1w^jBcG%`uy8oJJJ zLgU%`KMcy#%fwdRWl(j(g04GVVV2KB=l+UDAUE?_T(9i~l%=`SL7 zZ5KKXhL9_TP@-;VF=KIH7;G>w!O#o_yj~lZ&ifTr< zYzNHNHJT;98Ri>gw$al+3Bk5Z2XM?67NRPP74C?UFfj<4^8kYZ@ykuRWuc1?xDL zZJW`*nAm4J+@#A_bm@z=!qxsRFEfU9%`^7V-Q=q&Zuh?A8wQ#r_;nVsg zoF=mCOg$@ID!$(qBRdzbEL+&QKlsHDvc(=!KxXZ`0**l8sE5gc7j$jegfnzjhAgZ{ z+8*pWA(w0~oL#glWF|O@%XWXhfMa#4g9+GA5UC8Fnk+4l&S4}DiYVUvFfp}h!`Or( zTzucItwDAoJ66%G-o?HAeU*U$TkKJeZj}jgV8=`>ONRl~Pu^GRWNOZ5%_VxOc;?27 zFYYdAmTMLiUD19yum<@Y=s&O5@aM=f0T( z_m0(Itk@vg2{Q9R(Q;{qL6gJI6S!;!Ez|zEhwHTRbhih&q;k`srjEi558kasgUF|; z{l{0a-Hn0V=jSda&0g(B_zOM5Mtc69Z3=}47JYvcdBiJ|Y5H`O0aa(bP^lqpx7Urv zsf8?A+%S`?_p1uop+7EbL9$zc%a6s2vKy9)Ya);QVlij?aZLSZps(To^N*JL!$O@!#Fqi7A3%IYmL1 zRkkZ(SH*mnSL{J-sAUIICT++hZaoxg(`7QN-PV`a(n{;3H^Qe|^2=nhay(P+>8|}uG%SB*UIQnTlBXv9_f;92Z2CMVdUfDyu-4= zv?M5%ZW~i?#>T41iY{5oC5od|Yx3ZrxomGL%nq#=f^DB((r78yedJX3=cAI>%yGA5 zTfbw~R;z}|jB4plUmYEB^7Z>dOiSR5KPyaK?}BqZJ(M}P$D&DE*3h|ZR0rB9b5N|p zSN+tW6FXM-;+RGhoKi~1IROX7IfW^;eX1{dHs(-ie*Zala{$1&zNyHO`_eq$nL-Q2 zY8#1-n7AS(jFnaRthUp$y0IF!gH#yTvzt+DLp?kDlAi#x`%&uE$pd%A6p?P3GiBT4 zK(FdrPVW*=F)CBvY9i5o2{36h(iqGx2^Uek!W=U`^k;n8zA4PU>`=XO(f=N&PsjLR zJ}bjE4Em;6#nr90QokE^vc^V~vo0Aw>$nkpi`+Kr>tepq8P0A{VY88e*UaXBE0or2 zZZV)xb>McpGcnnD3zkX;P$34n+!d64=|HS7W9PC}U6mh;wK)#s-(hz%n!0b-t(342 zS?h`mFI2z&DTtm?R&{aTpnkGEnyvk;oF<*Iyb5T%mHq|DSp-+~qE&FluA^w5#2 zek6xz`V2Q8P&5al06%|`>sb1~MG=>-TXj+pyE9w)$W+F-x!G+n)AP+^HuEcCR9j6i zF5Gu^VOyBf&f=3T3m;}8XOP%N=s*q?kT7O1*6c>zoDkxN zH>|TF@_i83n1=UiS2q+O<*!cRzw)CrkB|u;{_hjT%obwe7q&RwV4oz(rYF5Xb(mp( z@%4tN(3l2G727Aulvhpa&cOhqB@}FKijiFPs74DGVg+#Y3+sYg201;+I?b0s2U*0m zFRCLhQB=X&nq3wn9%8vK?q-m^DGN)ZE0eJ5nAlUaAw!?kq>}DIe{p6vYrhdgt^>hg z;(w8CWf#bV_Mr^(ePM|>Bp0Iug`;e0Wv7wNGH#Xj;@x$ss3Qz`Gut5+KOH}$PGpzs z!a4b6)y~dF+u<2o4N!m>6~fkP-8WY`q=>!G??N8u-LlK6G-|0^U}Fd=3C7%s6ulyJF`? zNjD={WR^$#&)S?rbn5_9H8+qM#oMQbZku!y zk_X*D1DCm>D@~?#jA>HDF4eR>yN8dTZvoDnQvH5#S4&IlC=^Nm1iRyW_{C;>=df{h z`AqR>z7Fmn(!{*1Ycg8$g`X)0zF}|1Gh?J-XztqJFNs;ut$*GYs!kN|JLm$2{OivW z|Czl02kPy%Dz&P`IIs}KT<1pBVp(i|J3-BmG3>#<7QnK?6*ZWGlzFEiGJaVraub|5 zi9U2W_@Wv!!Fxf*rF15(q3n!5Fl(GvSQ#QuIJk)+GCzMYyHn)ukpJlNWvL5XXHs zXsP{}l1=a8dkA)DlI@&V%QryHAw3!??P}7_OwpI!FJs;|BDsc@1t6Nx@j5Ou)MQTd zGETg@K}%N3%s);fuqMyFh>8|Q1Sb%dR3-aZspF;0xG=&up$ZXQ@^r=X(;6DQ!j})8 zrPEa=*U>o0NvpaNJktfEv9+oj_#ZBmOL10*6=aU|N$bNoHpOlJW@kVAdK_j2l|UYM zxCdWD$9IO3w$}TK75yG|2Ig!z$VtGT9F?o5@iE?3)iB@c&@+*V*CUU>D1 zD6;@cRcTZsX`$F6_^LH?>JXBBPf&|4N3uo!THT*O{+q3-ZT0StsIalVZ z*X(K@Be0g8hL$kl3N8L)X3B#)+2~+NxQHHNx5C7SOOB$j5Z8tU%RX@zI{86&^mJ9B z`+go46CAJWY?k;jSgMI8?37zPErniDg_baWR$bem$Mn?~`c8IDkDZ#2^8~sfKuSJW z3|X@@O~x5n4wJwF%w|5Du^Ht2Na$i_lC_1tAM0~IF|)N7iY`+N|8gn2w#SaUCaYt2 z)wzRcvN2}&GN|0JbK$vQpI`68|824R%Dzpzue`j618_Q?_vF$+m-@tV%1r}C^*X5% z%*)J4cC$}A!Q_)@1rt~L#5&>sqg#DwZ(=u611~Fsb55^TfHp3FW zgR*OUfFz8qoqK$ISISK-;>aeEN{M&tb;X50H}M=wrRx%3-S_zTCvbl*t;guP$mjn7 D|BMFc diff --git a/lang/acf-sv_SE.po b/lang/acf-sv_SE.po index cf759bc..d8229a4 100644 --- a/lang/acf-sv_SE.po +++ b/lang/acf-sv_SE.po @@ -2,16 +2,16 @@ msgid "" msgstr "" "Project-Id-Version: Advanced Custom Fields Pro v5.2.9\n" "Report-Msgid-Bugs-To: http://support.advancedcustomfields.com\n" -"POT-Creation-Date: 2017-06-27 15:28+1000\n" -"PO-Revision-Date: 2019-05-15 09:55+1000\n" -"Last-Translator: Elliot Condon \n" +"POT-Creation-Date: 2021-06-03 21:44+0200\n" +"PO-Revision-Date: 2021-06-03 21:44+0200\n" +"Last-Translator: Erik Betshammar \n" "Language-Team: Swedish\n" "Language: sv_SE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.1\n" +"X-Generator: Poedit 2.4.3\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" @@ -22,521 +22,714 @@ msgstr "" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: *.js\n" -#: acf.php:63 +#: acf.php:68 msgid "Advanced Custom Fields" msgstr "Advanced Custom Fields" -#: acf.php:355 includes/admin/admin.php:117 +#: acf.php:348 includes/admin/admin.php:49 msgid "Field Groups" msgstr "Fältgrupper" -#: acf.php:356 +#: acf.php:349 msgid "Field Group" msgstr "Fältgrupp" -#: acf.php:357 acf.php:389 includes/admin/admin.php:118 -#: pro/fields/class-acf-field-flexible-content.php:574 +#: acf.php:350 acf.php:382 includes/admin/admin.php:50 +#: pro/fields/class-acf-field-flexible-content.php:554 msgid "Add New" msgstr "Lägg till ny" -#: acf.php:358 +#: acf.php:351 msgid "Add New Field Group" msgstr "Lägg till ny fältgrupp" -#: acf.php:359 +#: acf.php:352 msgid "Edit Field Group" msgstr "Redigera fältgrupp" -#: acf.php:360 +#: acf.php:353 msgid "New Field Group" msgstr "Skapa fältgrupp" -#: acf.php:361 +#: acf.php:354 msgid "View Field Group" msgstr "Visa fältgrupp" -#: acf.php:362 +#: acf.php:355 msgid "Search Field Groups" msgstr "Sök fältgrupp" -#: acf.php:363 +#: acf.php:356 msgid "No Field Groups found" msgstr "Inga fältgrupper hittades" -#: acf.php:364 +#: acf.php:357 msgid "No Field Groups found in Trash" msgstr "Inga fältgrupper hittades i papperskorgen" -#: acf.php:387 includes/admin/admin-field-group.php:182 -#: includes/admin/admin-field-group.php:275 -#: includes/admin/admin-field-groups.php:510 -#: pro/fields/class-acf-field-clone.php:857 +#: acf.php:380 includes/admin/admin-field-group.php:231 +#: includes/admin/admin-field-groups.php:262 +#: pro/fields/class-acf-field-clone.php:799 msgid "Fields" msgstr "Fält" -#: acf.php:388 +#: acf.php:381 msgid "Field" msgstr "Fält" -#: acf.php:390 +#: acf.php:383 msgid "Add New Field" msgstr "Skapa nytt fält" -#: acf.php:391 +#: acf.php:384 msgid "Edit Field" msgstr "Redigera fält" -#: acf.php:392 includes/admin/views/field-group-fields.php:41 -#: includes/admin/views/settings-info.php:105 +#: acf.php:385 includes/admin/views/field-group-fields.php:41 msgid "New Field" msgstr "Nytt fält" -#: acf.php:393 +#: acf.php:386 msgid "View Field" msgstr "Visa fält" -#: acf.php:394 +#: acf.php:387 msgid "Search Fields" msgstr "Sök fält" -#: acf.php:395 +#: acf.php:388 msgid "No Fields found" msgstr "Inga fält hittades" -#: acf.php:396 +#: acf.php:389 msgid "No Fields found in Trash" msgstr "Inga fält hittades i papperskorgen" -#: acf.php:435 includes/admin/admin-field-group.php:390 -#: includes/admin/admin-field-groups.php:567 -msgid "Inactive" -msgstr "Inaktiv" +#: acf.php:424 includes/admin/admin-field-group.php:387 +#: includes/admin/admin-field-groups.php:226 +msgctxt "post status" +msgid "Disabled" +msgstr "Inaktiverad" -#: acf.php:440 +#: acf.php:429 #, php-format -msgid "Inactive (%s)" -msgid_plural "Inactive (%s)" -msgstr[0] "Inaktiv (%s)" -msgstr[1] "Inaktiva (%s)" +msgid "Disabled (%s)" +msgid_plural "Disabled (%s)" +msgstr[0] "Inaktiverad (%s)" +msgstr[1] "Inaktiverade (%s)" -#: includes/admin/admin-field-group.php:68 -#: includes/admin/admin-field-group.php:69 -#: includes/admin/admin-field-group.php:71 -msgid "Field group updated." -msgstr "Fältgrupper uppdaterades." +#: includes/acf-field-functions.php:831 +#: includes/admin/admin-field-group.php:177 +msgid "(no label)" +msgstr "(ingen etikett)" -#: includes/admin/admin-field-group.php:70 -msgid "Field group deleted." -msgstr "Fältgrupper raderades." - -#: includes/admin/admin-field-group.php:73 -msgid "Field group published." -msgstr "Fältgrupper publicerades." - -#: includes/admin/admin-field-group.php:74 -msgid "Field group saved." -msgstr "Fältgrupper sparades." - -#: includes/admin/admin-field-group.php:75 -msgid "Field group submitted." -msgstr "Fältgruppen skickades." - -#: includes/admin/admin-field-group.php:76 -msgid "Field group scheduled for." -msgstr "Fältgruppen schemalades för." - -#: includes/admin/admin-field-group.php:77 -msgid "Field group draft updated." -msgstr "Utkastet till fältgrupp uppdaterades." - -#: includes/admin/admin-field-group.php:183 -msgid "Location" -msgstr "Plats" - -#: includes/admin/admin-field-group.php:184 -msgid "Settings" -msgstr "Inställningar" - -#: includes/admin/admin-field-group.php:269 -msgid "Move to trash. Are you sure?" -msgstr "Flytta till papperskorgen. Är du säker?" - -#: includes/admin/admin-field-group.php:270 -msgid "checked" -msgstr "vald" - -#: includes/admin/admin-field-group.php:271 -msgid "No toggle fields available" -msgstr "Det finns inga aktiveringsbara fält" - -#: includes/admin/admin-field-group.php:272 -msgid "Field group title is required" -msgstr "Fältgruppen behöver en titel" - -#: includes/admin/admin-field-group.php:273 -#: includes/api/api-field-group.php:732 +#: includes/acf-field-group-functions.php:838 +#: includes/admin/admin-field-group.php:179 msgid "copy" msgstr "kopiera" -#: includes/admin/admin-field-group.php:274 -#: includes/admin/views/field-group-field-conditional-logic.php:54 -#: includes/admin/views/field-group-field-conditional-logic.php:154 -#: includes/admin/views/field-group-locations.php:29 -#: includes/admin/views/html-location-group.php:3 -#: includes/api/api-helpers.php:3970 -msgid "or" -msgstr "eller" +#: includes/acf-wp-functions.php:41 +msgid "Posts" +msgstr "Inlägg" -#: includes/admin/admin-field-group.php:276 -msgid "Parent fields" -msgstr "Föräldrafält" +#: includes/acf-wp-functions.php:54 +msgid "Taxonomies" +msgstr "Taxonomier" -#: includes/admin/admin-field-group.php:277 -msgid "Sibling fields" -msgstr "Syskonfält" +#: includes/acf-wp-functions.php:59 +msgid "Attachments" +msgstr "Bilagor" -#: includes/admin/admin-field-group.php:278 -msgid "Move Custom Field" -msgstr "Flytta egna fält" +#: includes/acf-wp-functions.php:63 +#: includes/admin/views/field-group-options.php:112 +msgid "Comments" +msgstr "Kommentarer" -#: includes/admin/admin-field-group.php:279 +#: includes/acf-wp-functions.php:67 +msgid "Widgets" +msgstr "Widgetar" + +#: includes/acf-wp-functions.php:71 +#: includes/locations/class-acf-location-nav-menu.php:87 +msgid "Menus" +msgstr "Menyer" + +#: includes/acf-wp-functions.php:75 +msgid "Menu items" +msgstr "Menyobjekt" + +#: includes/acf-wp-functions.php:79 +msgid "Users" +msgstr "Användare" + +#: includes/acf-wp-functions.php:83 pro/options-page.php:45 +msgid "Options" +msgstr "Alternativ" + +#: includes/acf-wp-functions.php:87 +msgid "Blocks" +msgstr "Block" + +#: includes/admin/admin-field-group.php:86 +#: includes/admin/admin-field-group.php:87 +#: includes/admin/admin-field-group.php:89 +msgid "Field group updated." +msgstr "Fältgrupper uppdaterades." + +#: includes/admin/admin-field-group.php:88 +msgid "Field group deleted." +msgstr "Fältgrupper togs bort." + +#: includes/admin/admin-field-group.php:91 +msgid "Field group published." +msgstr "Fältgrupper publicerades." + +#: includes/admin/admin-field-group.php:92 +msgid "Field group saved." +msgstr "Fältgrupper sparades." + +#: includes/admin/admin-field-group.php:93 +msgid "Field group submitted." +msgstr "Fältgruppen skickades." + +#: includes/admin/admin-field-group.php:94 +msgid "Field group scheduled for." +msgstr "Fältgruppen schemalades för." + +#: includes/admin/admin-field-group.php:95 +msgid "Field group draft updated." +msgstr "Utkastet till fältgrupp uppdaterades." + +#: includes/admin/admin-field-group.php:170 +msgid "The string \"field_\" may not be used at the start of a field name" +msgstr "Strängen ”field_” får inte användas i början av ett fältnamn" + +#: includes/admin/admin-field-group.php:171 msgid "This field cannot be moved until its changes have been saved" msgstr "Detta fält kan inte flyttas förrän ändringarna har sparats" -#: includes/admin/admin-field-group.php:280 +#: includes/admin/admin-field-group.php:172 +msgid "Field group title is required" +msgstr "Fältgruppen behöver en rubrik" + +#: includes/admin/admin-field-group.php:173 +msgid "Move to trash. Are you sure?" +msgstr "Flytta till papperskorgen. Är du säker?" + +#: includes/admin/admin-field-group.php:174 +msgid "No toggle fields available" +msgstr "Inga växlingsfält är tillgängliga" + +#: includes/admin/admin-field-group.php:175 +msgid "Move Custom Field" +msgstr "Flytta anpassat fält" + +#: includes/admin/admin-field-group.php:176 +msgid "Checked" +msgstr "Markerat" + +#: includes/admin/admin-field-group.php:178 +msgid "(this field)" +msgstr "(detta fält)" + +#: includes/admin/admin-field-group.php:180 +#: includes/admin/views/field-group-field-conditional-logic.php:51 +#: includes/admin/views/field-group-field-conditional-logic.php:151 +#: includes/admin/views/field-group-locations.php:29 +#: includes/admin/views/html-location-group.php:3 +#: includes/api/api-helpers.php:3586 +msgid "or" +msgstr "eller" + +#: includes/admin/admin-field-group.php:181 msgid "Null" msgstr "Nollvärde" -#: includes/admin/admin-field-group.php:281 includes/input.php:257 -msgid "The changes you made will be lost if you navigate away from this page" -msgstr "" -"De ändringar som du gjort kommer att förloras om du navigerar bort från " -"denna sida" +#: includes/admin/admin-field-group.php:184 +msgid "Has any value" +msgstr "Har något värde" -#: includes/admin/admin-field-group.php:282 -msgid "The string \"field_\" may not be used at the start of a field name" -msgstr "Strängen \"field_\" får inte användas i början av ett fältnamn" +#: includes/admin/admin-field-group.php:185 +msgid "Has no value" +msgstr "Har inget värde" -#: includes/admin/admin-field-group.php:360 +#: includes/admin/admin-field-group.php:186 +msgid "Value is equal to" +msgstr "Värde är lika med" + +#: includes/admin/admin-field-group.php:187 +msgid "Value is not equal to" +msgstr "Värde är inte lika med" + +#: includes/admin/admin-field-group.php:188 +msgid "Value matches pattern" +msgstr "Värde matchar mönstret" + +#: includes/admin/admin-field-group.php:189 +msgid "Value contains" +msgstr "Värde innehåller" + +#: includes/admin/admin-field-group.php:190 +msgid "Value is greater than" +msgstr "Värde är större än" + +#: includes/admin/admin-field-group.php:191 +msgid "Value is less than" +msgstr "Värde är mindre än" + +#: includes/admin/admin-field-group.php:192 +msgid "Selection is greater than" +msgstr "Markeringen är större än" + +#: includes/admin/admin-field-group.php:193 +msgid "Selection is less than" +msgstr "Markeringen är mindre än" + +#: includes/admin/admin-field-group.php:232 +#: includes/admin/admin-field-groups.php:261 +msgid "Location" +msgstr "Plats" + +#: includes/admin/admin-field-group.php:233 +#: includes/admin/tools/class-acf-admin-tool-export.php:295 +msgid "Settings" +msgstr "Inställningar" + +#: includes/admin/admin-field-group.php:362 msgid "Field Keys" msgstr "Fältnycklar" -#: includes/admin/admin-field-group.php:390 -#: includes/admin/views/field-group-options.php:9 +#: includes/admin/admin-field-group.php:387 +msgctxt "post status" msgid "Active" msgstr "Aktiv" -#: includes/admin/admin-field-group.php:801 +#: includes/admin/admin-field-group.php:746 msgid "Move Complete." msgstr "Flytt färdig." -#: includes/admin/admin-field-group.php:802 +#: includes/admin/admin-field-group.php:748 #, php-format msgid "The %s field can now be found in the %s field group" msgstr "Fältet %s kan nu hittas i fältgruppen %s" -#: includes/admin/admin-field-group.php:803 +#: includes/admin/admin-field-group.php:752 msgid "Close Window" msgstr "Stäng fönster" -#: includes/admin/admin-field-group.php:844 +#: includes/admin/admin-field-group.php:792 msgid "Please select the destination for this field" msgstr "Välj målet (destinationen) för detta fält" -#: includes/admin/admin-field-group.php:851 +#: includes/admin/admin-field-group.php:799 msgid "Move Field" msgstr "Flytta fält" -#: includes/admin/admin-field-groups.php:74 +#: includes/admin/admin-field-groups.php:114 #, php-format msgid "Active (%s)" msgid_plural "Active (%s)" msgstr[0] "Aktiv (%s)" msgstr[1] "Aktiva (%s)" -#: includes/admin/admin-field-groups.php:142 -#, php-format -msgid "Field group duplicated. %s" -msgstr "Fältgruppen kopierad. %s" +#: includes/admin/admin-field-groups.php:193 +msgid "Review local JSON changes" +msgstr "Granska lokala JSON-ändringar" -#: includes/admin/admin-field-groups.php:146 -#, php-format -msgid "%s field group duplicated." -msgid_plural "%s field groups duplicated." -msgstr[0] "%s fältgrupp kopierad." -msgstr[1] "%s fältgrupper kopierade." +#: includes/admin/admin-field-groups.php:194 +msgid "Loading diff" +msgstr "Laddar diff" -#: includes/admin/admin-field-groups.php:227 -#, php-format -msgid "Field group synchronised. %s" -msgstr "Fältgrupp synkroniserad. %s" +#: includes/admin/admin-field-groups.php:195 +#: includes/admin/admin-field-groups.php:529 +msgid "Sync changes" +msgstr "Synkronisera ändringar" -#: includes/admin/admin-field-groups.php:231 -#, php-format -msgid "%s field group synchronised." -msgid_plural "%s field groups synchronised." -msgstr[0] "%s fältgrupp synkroniserad." -msgstr[1] "%s fältgrupper synkroniserade." - -#: includes/admin/admin-field-groups.php:394 -#: includes/admin/admin-field-groups.php:557 -msgid "Sync available" -msgstr "Synkronisering tillgänglig" - -#: includes/admin/admin-field-groups.php:507 includes/forms/form-front.php:38 -#: pro/fields/class-acf-field-gallery.php:370 -msgid "Title" -msgstr "Titel" - -#: includes/admin/admin-field-groups.php:508 +#: includes/admin/admin-field-groups.php:259 #: includes/admin/views/field-group-options.php:96 -#: includes/admin/views/install-network.php:21 -#: includes/admin/views/install-network.php:29 -#: pro/fields/class-acf-field-gallery.php:397 +#: includes/admin/views/html-admin-page-upgrade-network.php:38 +#: includes/admin/views/html-admin-page-upgrade-network.php:49 +#: pro/fields/class-acf-field-gallery.php:377 msgid "Description" msgstr "Beskrivning" -#: includes/admin/admin-field-groups.php:509 -msgid "Status" -msgstr "Status" +#: includes/admin/admin-field-groups.php:260 +#: includes/admin/views/field-group-fields.php:7 +msgid "Key" +msgstr "Nyckel" -#. Description of the plugin/theme -#: includes/admin/admin-field-groups.php:607 -msgid "Customise WordPress with powerful, professional and intuitive fields." -msgstr "" -"Skräddarsy Wordpress med kraftfulla, professionella och intuitiva fält." +#: includes/admin/admin-field-groups.php:265 +msgid "Local JSON" +msgstr "Lokal JSON" -#: includes/admin/admin-field-groups.php:609 -#: includes/admin/settings-info.php:76 -#: pro/admin/views/html-settings-updates.php:111 -msgid "Changelog" -msgstr "Versionshistorik" +#: includes/admin/admin-field-groups.php:415 +msgid "Various" +msgstr "Olika" -#: includes/admin/admin-field-groups.php:614 +#: includes/admin/admin-field-groups.php:437 #, php-format -msgid "See what's new in version %s." -msgstr "Se vad som är nytt i version %s." +msgid "Located in theme: %s" +msgstr "Finns i temat: %s" -#: includes/admin/admin-field-groups.php:617 -msgid "Resources" -msgstr "Resurser" - -#: includes/admin/admin-field-groups.php:619 -#, fuzzy -msgid "Website" -msgstr "Denna webbplats använder premiumtillägg som behöver laddas ner" - -#: includes/admin/admin-field-groups.php:620 -msgid "Documentation" -msgstr "Dokumentation" - -#: includes/admin/admin-field-groups.php:621 -msgid "Support" -msgstr "Support" - -#: includes/admin/admin-field-groups.php:623 -#, fuzzy -msgid "Pro" -msgstr "Adjö tillägg. Hej PRO" - -#: includes/admin/admin-field-groups.php:628 +#: includes/admin/admin-field-groups.php:441 #, php-format -msgid "Thank you for creating with ACF." -msgstr "Tack för att du skapar med ACF." +msgid "Located in plugin: %s" +msgstr "Finns i tillägget: %s" -#: includes/admin/admin-field-groups.php:668 +#: includes/admin/admin-field-groups.php:445 +#, php-format +msgid "Located in: %s" +msgstr "Finns i: %s" + +#: includes/admin/admin-field-groups.php:465 +#: includes/admin/admin-field-groups.php:683 +msgid "Sync available" +msgstr "Synkronisering tillgänglig" + +#: includes/admin/admin-field-groups.php:468 +msgid "Sync" +msgstr "Synkronisera" + +#: includes/admin/admin-field-groups.php:469 +msgid "Review changes" +msgstr "Granska ändringar" + +#: includes/admin/admin-field-groups.php:473 +msgid "Import" +msgstr "Importera" + +#: includes/admin/admin-field-groups.php:477 +msgid "Saved" +msgstr "Sparat" + +#: includes/admin/admin-field-groups.php:480 +msgid "Awaiting save" +msgstr "Väntar på sparande" + +#: includes/admin/admin-field-groups.php:501 msgid "Duplicate this item" msgstr "Duplicera detta objekt" -#: includes/admin/admin-field-groups.php:668 -#: includes/admin/admin-field-groups.php:684 -#: includes/admin/views/field-group-field.php:49 -#: pro/fields/class-acf-field-flexible-content.php:573 +#: includes/admin/admin-field-groups.php:501 +#: includes/admin/admin-field-groups.php:521 +#: includes/admin/views/field-group-field.php:50 +#: pro/fields/class-acf-field-flexible-content.php:553 msgid "Duplicate" msgstr "Duplicera" -#: includes/admin/admin-field-groups.php:701 -#: includes/fields/class-acf-field-google-map.php:132 -#: includes/fields/class-acf-field-relationship.php:737 -msgid "Search" -msgstr "Sök" +#: includes/admin/admin-field-groups.php:551 +#, php-format +msgid "Field group duplicated." +msgid_plural "%s field groups duplicated." +msgstr[0] "Fältgrupp duplicerad." +msgstr[1] "%s fältgrupper duplicerade." -#: includes/admin/admin-field-groups.php:760 +#: includes/admin/admin-field-groups.php:608 +#, php-format +msgid "Field group synchronised." +msgid_plural "%s field groups synchronised." +msgstr[0] "Fältgrupp synkroniserad." +msgstr[1] "%s fältgrupper synkroniserade." + +#: includes/admin/admin-field-groups.php:794 #, php-format msgid "Select %s" msgstr "Välj %s" -#: includes/admin/admin-field-groups.php:768 -msgid "Synchronise field group" -msgstr "Synkronisera fältgrupp" - -#: includes/admin/admin-field-groups.php:768 -#: includes/admin/admin-field-groups.php:798 -msgid "Sync" -msgstr "Synkronisera" - -#: includes/admin/admin-field-groups.php:780 -msgid "Apply" -msgstr "" - -#: includes/admin/admin-field-groups.php:798 -#, fuzzy -msgid "Bulk Actions" -msgstr "Välj åtgärd" - -#: includes/admin/admin.php:113 -#: includes/admin/views/field-group-options.php:118 -msgid "Custom Fields" -msgstr "Egna fält" - -#: includes/admin/install-network.php:88 includes/admin/install.php:70 -#: includes/admin/install.php:121 -msgid "Upgrade Database" -msgstr "Uppgradera databas" - -#: includes/admin/install-network.php:140 -msgid "Review sites & upgrade" -msgstr "Kontrollera webbplatser & uppgradera" - -#: includes/admin/install.php:187 -msgid "Error validating request" -msgstr "Fel vid validering av begäran" - -#: includes/admin/install.php:210 includes/admin/views/install.php:105 -msgid "No updates available." -msgstr "Inga uppdateringar tillgängliga." - -#: includes/admin/settings-addons.php:51 -#: includes/admin/views/settings-addons.php:3 -msgid "Add-ons" -msgstr "Tillägg" - -#: includes/admin/settings-addons.php:87 -msgid "Error. Could not load add-ons list" -msgstr "Fel. Kunde inte ladda tilläggslistan" - -#: includes/admin/settings-info.php:50 -msgid "Info" -msgstr "Information" - -#: includes/admin/settings-info.php:75 -msgid "What's New" -msgstr "Vad är nytt" - -#: includes/admin/settings-tools.php:50 -#: includes/admin/views/settings-tools-export.php:19 -#: includes/admin/views/settings-tools.php:31 +#: includes/admin/admin-tools.php:116 +#: includes/admin/views/html-admin-tools.php:21 msgid "Tools" msgstr "Verktyg" -#: includes/admin/settings-tools.php:147 includes/admin/settings-tools.php:380 +#: includes/admin/admin-upgrade.php:49 includes/admin/admin-upgrade.php:111 +#: includes/admin/admin-upgrade.php:112 includes/admin/admin-upgrade.php:175 +#: includes/admin/views/html-admin-page-upgrade-network.php:24 +#: includes/admin/views/html-admin-page-upgrade.php:26 +msgid "Upgrade Database" +msgstr "Uppgradera databas" + +#: includes/admin/admin-upgrade.php:199 +msgid "Review sites & upgrade" +msgstr "Kontrollera webbplatser och uppgradera" + +#: includes/admin/admin.php:48 includes/admin/views/field-group-options.php:110 +msgid "Custom Fields" +msgstr "Anpassade fält" + +#: includes/admin/admin.php:128 includes/admin/admin.php:130 +msgid "Overview" +msgstr "Översikt" + +#: includes/admin/admin.php:131 +msgid "" +"The Advanced Custom Fields plugin provides a visual form builder to " +"customize WordPress edit screens with extra fields, and an intuitive API to " +"display custom field values in any theme template file." +msgstr "" +"Tillägget ”Advanced Custom Fields” tillhandahåller en visuell " +"formulärbyggare för att anpassa WordPress redigeringsvyer med extra fält och " +"ett intuitivt API för att visa anpassade fältvärden i alla temamallsfiler." + +#: includes/admin/admin.php:133 +#, php-format +msgid "" +"Before creating your first Field Group, we recommend first reading our Getting started guide to familiarize " +"yourself with the plugin's philosophy and best practises." +msgstr "" +"Innan du skapar din första fältgrupp rekommenderar vi att du först läser vår " +"Komma igång-guide för att bekanta dig " +"med tilläggets filosofi och bästa praxis." + +#: includes/admin/admin.php:136 +msgid "" +"Please use the Help & Support tab to get in touch should you find yourself " +"requiring assistance." +msgstr "" +"Använd fliken ”Hjälp och support” för att komma i kontakt om du behöver " +"hjälp." + +#: includes/admin/admin.php:145 includes/admin/admin.php:147 +msgid "Help & Support" +msgstr "Hjälp och support" + +#: includes/admin/admin.php:148 +msgid "" +"We are fanatical about support, and want you to get the best out of your " +"website with ACF. If you run into any difficulties, there are several places " +"you can find help:" +msgstr "" + +#: includes/admin/admin.php:151 +#, php-format +msgid "" +"Documentation. Our extensive " +"documentation contains references and guides for most situations you may " +"encounter." +msgstr "" +"Dokumentation. Vår omfattande " +"dokumentation innehåller referenser och guider för de flesta situationer du " +"kan stöta på." + +#: includes/admin/admin.php:155 +#, php-format +msgid "" +"Discussions. We have an active and " +"friendly community on our Community Forums who may be able to help you " +"figure out the ‘how-tos’ of the ACF world." +msgstr "" +"Diskussioner. Vi har en aktiv och " +"vänlig community på våra community-forum som kanske kan hjälpa dig att räkna " +"ut ”hur man gör” i ACF-världen." + +#: includes/admin/admin.php:159 +#, php-format +msgid "" +"Help Desk. The support professionals on " +"our Help Desk will assist with your more in depth, technical challenges." +msgstr "" +"Helpdesk. Supportpersonalen på vår " +"helpdesk hjälper dig med dina mer djupgående tekniska utmaningar." + +#: includes/admin/admin.php:168 +msgid "Information" +msgstr "Information" + +#: includes/admin/admin.php:169 +#, php-format +msgid "Version %s" +msgstr "Version %s" + +#: includes/admin/admin.php:170 +msgid "View details" +msgstr "Visa detaljer" + +#: includes/admin/admin.php:171 +msgid "Visit website" +msgstr "Besök webbplatsen" + +#: includes/admin/admin.php:200 +#: includes/admin/views/field-group-field-conditional-logic.php:138 +#: includes/admin/views/html-location-rule.php:86 +msgid "and" +msgstr "och" + +#: includes/admin/tools/class-acf-admin-tool-export.php:33 +msgid "Export Field Groups" +msgstr "Exportera fältgrupper" + +#: includes/admin/tools/class-acf-admin-tool-export.php:38 +#: includes/admin/tools/class-acf-admin-tool-export.php:342 +#: includes/admin/tools/class-acf-admin-tool-export.php:371 +msgid "Generate PHP" +msgstr "Generera PHP" + +#: includes/admin/tools/class-acf-admin-tool-export.php:97 +#: includes/admin/tools/class-acf-admin-tool-export.php:135 msgid "No field groups selected" msgstr "Inga fältgrupper valda" -#: includes/admin/settings-tools.php:184 -#: includes/fields/class-acf-field-file.php:174 +#: includes/admin/tools/class-acf-admin-tool-export.php:174 +#, php-format +msgid "Exported 1 field group." +msgid_plural "Exported %s field groups." +msgstr[0] "Exporterade 1 fältgrupp." +msgstr[1] "Exporterade %s fältgrupper." + +#: includes/admin/tools/class-acf-admin-tool-export.php:241 +#: includes/admin/tools/class-acf-admin-tool-export.php:269 +msgid "Select Field Groups" +msgstr "Välj fältgrupp" + +#: includes/admin/tools/class-acf-admin-tool-export.php:336 +msgid "" +"Select the field groups you would like to export and then select your export " +"method. Use the download button to export to a .json file which you can then " +"import to another ACF installation. Use the generate button to export to PHP " +"code which you can place in your theme." +msgstr "" +"Välj de fältgrupper som du vill exportera och sedan välj din exportmetod. " +"Använd knappen för exportera till en .json fil som du sedan kan importera " +"till en annan ACF installation. Använd generera-knappen för att exportera " +"PHP kod som du kan lägga till i ditt tema." + +#: includes/admin/tools/class-acf-admin-tool-export.php:341 +msgid "Export File" +msgstr "Exportera fil" + +#: includes/admin/tools/class-acf-admin-tool-export.php:414 +msgid "" +"The following code can be used to register a local version of the selected " +"field group(s). A local field group can provide many benefits such as faster " +"load times, version control & dynamic fields/settings. Simply copy and paste " +"the following code to your theme's functions.php file or include it within " +"an external file." +msgstr "" +"Följande kod kan användas för att registrera en lokal version av valda " +"fältgrupp(er). Ett lokal fältgrupp kan ge många fördelar som snabbare " +"laddningstider, versionshantering & dynamiska fält/inställningar. Det är " +"bara att kopiera och klistra in följande kod till ditt temas functions.php " +"fil eller att inkludera det i en extern fil." + +#: includes/admin/tools/class-acf-admin-tool-export.php:446 +msgid "Copy to clipboard" +msgstr "Kopiera till urklipp" + +#: includes/admin/tools/class-acf-admin-tool-export.php:483 +msgid "Copied" +msgstr "Kopierat" + +#: includes/admin/tools/class-acf-admin-tool-import.php:26 +msgid "Import Field Groups" +msgstr "Importera fältgrupper" + +#: includes/admin/tools/class-acf-admin-tool-import.php:47 +msgid "" +"Select the Advanced Custom Fields JSON file you would like to import. When " +"you click the import button below, ACF will import the field groups." +msgstr "" +"Välj den Advanced Custom Fields JSON-fil som du vill importera. När du " +"klickar på import-knappen så kommer ACF importera fältgrupperna." + +#: includes/admin/tools/class-acf-admin-tool-import.php:52 +#: includes/fields/class-acf-field-file.php:57 +msgid "Select File" +msgstr "Välj fil" + +#: includes/admin/tools/class-acf-admin-tool-import.php:62 +msgid "Import File" +msgstr "Importera fil" + +#: includes/admin/tools/class-acf-admin-tool-import.php:85 +#: includes/fields/class-acf-field-file.php:169 msgid "No file selected" msgstr "Ingen fil vald" -#: includes/admin/settings-tools.php:197 +#: includes/admin/tools/class-acf-admin-tool-import.php:93 msgid "Error uploading file. Please try again" -msgstr "Fel vid uppladdning av fil. Vänligen försök igen" +msgstr "Fel vid uppladdning av fil. Försök igen" -#: includes/admin/settings-tools.php:206 +#: includes/admin/tools/class-acf-admin-tool-import.php:98 msgid "Incorrect file type" msgstr "Felaktig filtyp" -#: includes/admin/settings-tools.php:223 +#: includes/admin/tools/class-acf-admin-tool-import.php:107 msgid "Import file empty" msgstr "Importfilen är tom" -#: includes/admin/settings-tools.php:331 +#: includes/admin/tools/class-acf-admin-tool-import.php:138 #, php-format msgid "Imported 1 field group" msgid_plural "Imported %s field groups" msgstr[0] "Importerade 1 fältgrupp" -msgstr[1] "Importerade %s fältgrupp" +msgstr[1] "Importerade %s fältgrupper" -#: includes/admin/views/field-group-field-conditional-logic.php:28 +#: includes/admin/views/field-group-field-conditional-logic.php:25 msgid "Conditional Logic" msgstr "Visningsvillkor" -#: includes/admin/views/field-group-field-conditional-logic.php:54 +#: includes/admin/views/field-group-field-conditional-logic.php:51 msgid "Show this field if" msgstr "Visa detta fält när" -#: includes/admin/views/field-group-field-conditional-logic.php:103 -#: includes/locations.php:243 -msgid "is equal to" -msgstr "är" - -#: includes/admin/views/field-group-field-conditional-logic.php:104 -#: includes/locations.php:244 -msgid "is not equal to" -msgstr "inte är" - -#: includes/admin/views/field-group-field-conditional-logic.php:141 -#: includes/admin/views/html-location-rule.php:80 -msgid "and" -msgstr "och" - -#: includes/admin/views/field-group-field-conditional-logic.php:156 +#: includes/admin/views/field-group-field-conditional-logic.php:153 #: includes/admin/views/field-group-locations.php:31 msgid "Add rule group" msgstr "Lägg till regelgrupp" -#: includes/admin/views/field-group-field.php:41 -#: pro/fields/class-acf-field-flexible-content.php:420 -#: pro/fields/class-acf-field-repeater.php:358 +#: includes/admin/views/field-group-field.php:42 +#: pro/fields/class-acf-field-flexible-content.php:411 +#: pro/fields/class-acf-field-repeater.php:294 msgid "Drag to reorder" msgstr "Dra och släpp för att ändra ordning" -#: includes/admin/views/field-group-field.php:45 -#: includes/admin/views/field-group-field.php:48 +#: includes/admin/views/field-group-field.php:46 +#: includes/admin/views/field-group-field.php:49 msgid "Edit field" msgstr "Redigera fält" -#: includes/admin/views/field-group-field.php:48 -#: includes/fields/class-acf-field-image.php:140 -#: includes/fields/class-acf-field-link.php:152 -#: pro/fields/class-acf-field-gallery.php:357 +#: includes/admin/views/field-group-field.php:49 +#: includes/fields/class-acf-field-file.php:151 +#: includes/fields/class-acf-field-image.php:131 +#: includes/fields/class-acf-field-link.php:139 +#: pro/fields/class-acf-field-gallery.php:334 msgid "Edit" msgstr "Redigera" -#: includes/admin/views/field-group-field.php:49 +#: includes/admin/views/field-group-field.php:50 msgid "Duplicate field" msgstr "Duplicera fält" -#: includes/admin/views/field-group-field.php:50 +#: includes/admin/views/field-group-field.php:51 msgid "Move field to another group" msgstr "Flytta fält till en annan grupp" -#: includes/admin/views/field-group-field.php:50 +#: includes/admin/views/field-group-field.php:51 msgid "Move" msgstr "Flytta" -#: includes/admin/views/field-group-field.php:51 +#: includes/admin/views/field-group-field.php:52 msgid "Delete field" -msgstr "Radera fält" +msgstr "Ta bort fält" -#: includes/admin/views/field-group-field.php:51 -#: pro/fields/class-acf-field-flexible-content.php:572 +#: includes/admin/views/field-group-field.php:52 +#: pro/fields/class-acf-field-flexible-content.php:552 msgid "Delete" -msgstr "Radera" +msgstr "Ta bort" -#: includes/admin/views/field-group-field.php:67 +#: includes/admin/views/field-group-field.php:69 msgid "Field Label" -msgstr "Fälttitel" +msgstr "Fältetikett" -#: includes/admin/views/field-group-field.php:68 +#: includes/admin/views/field-group-field.php:70 msgid "This is the name which will appear on the EDIT page" -msgstr "Detta namn kommer att visas vid redigering" +msgstr "Detta namn kommer att visas på REDIGERINGS-sidan" -#: includes/admin/views/field-group-field.php:78 +#: includes/admin/views/field-group-field.php:79 msgid "Field Name" msgstr "Fältnamn" -#: includes/admin/views/field-group-field.php:79 +#: includes/admin/views/field-group-field.php:80 msgid "Single word, no spaces. Underscores and dashes allowed" msgstr "Ett enda ord, utan mellanslag. Understreck och bindestreck är tillåtna" @@ -544,36 +737,35 @@ msgstr "Ett enda ord, utan mellanslag. Understreck och bindestreck är tillåtna msgid "Field Type" msgstr "Fälttyp" -#: includes/admin/views/field-group-field.php:101 -#: includes/fields/class-acf-field-tab.php:102 +#: includes/admin/views/field-group-field.php:100 msgid "Instructions" msgstr "Instruktioner" -#: includes/admin/views/field-group-field.php:102 +#: includes/admin/views/field-group-field.php:101 msgid "Instructions for authors. Shown when submitting data" -msgstr "Instruktioner för den som redigerar" +msgstr "Instruktioner för författarna. Visas vid publicering" -#: includes/admin/views/field-group-field.php:111 +#: includes/admin/views/field-group-field.php:110 msgid "Required?" msgstr "Obligatorisk?" -#: includes/admin/views/field-group-field.php:134 +#: includes/admin/views/field-group-field.php:133 msgid "Wrapper Attributes" msgstr "Attribut för det omslutande elementet (wrappern)" -#: includes/admin/views/field-group-field.php:140 +#: includes/admin/views/field-group-field.php:139 msgid "width" msgstr "bredd" -#: includes/admin/views/field-group-field.php:155 +#: includes/admin/views/field-group-field.php:154 msgid "class" msgstr "class" -#: includes/admin/views/field-group-field.php:168 +#: includes/admin/views/field-group-field.php:167 msgid "id" msgstr "id" -#: includes/admin/views/field-group-field.php:180 +#: includes/admin/views/field-group-field.php:179 msgid "Close Field" msgstr "Stäng fält" @@ -582,24 +774,20 @@ msgid "Order" msgstr "Ordning" #: includes/admin/views/field-group-fields.php:5 -#: includes/fields/class-acf-field-checkbox.php:317 -#: includes/fields/class-acf-field-radio.php:321 -#: includes/fields/class-acf-field-select.php:530 -#: pro/fields/class-acf-field-flexible-content.php:599 +#: includes/fields/class-acf-field-button-group.php:198 +#: includes/fields/class-acf-field-checkbox.php:420 +#: includes/fields/class-acf-field-radio.php:268 +#: includes/fields/class-acf-field-select.php:433 +#: pro/fields/class-acf-field-flexible-content.php:578 msgid "Label" -msgstr "Titel" +msgstr "Etikett" #: includes/admin/views/field-group-fields.php:6 -#: includes/fields/class-acf-field-taxonomy.php:970 -#: pro/fields/class-acf-field-flexible-content.php:612 +#: includes/fields/class-acf-field-taxonomy.php:926 +#: pro/fields/class-acf-field-flexible-content.php:592 msgid "Name" msgstr "Namn" -#: includes/admin/views/field-group-fields.php:7 -#, fuzzy -msgid "Key" -msgstr "Visa fältnyckel:" - #: includes/admin/views/field-group-fields.php:8 msgid "Type" msgstr "Typ" @@ -624,7 +812,13 @@ msgstr "Regler" msgid "" "Create a set of rules to determine which edit screens will use these " "advanced custom fields" -msgstr "Reglera var denna fältgrupp ska visas" +msgstr "" +"Skapa en uppsättning regler för att bestämma vilka redigeringsvyer som ska " +"använda dessa avancerade anpassade fält" + +#: includes/admin/views/field-group-options.php:9 +msgid "Active" +msgstr "Aktiv" #: includes/admin/views/field-group-options.php:23 msgid "Style" @@ -632,11 +826,11 @@ msgstr "Stil" #: includes/admin/views/field-group-options.php:30 msgid "Standard (WP metabox)" -msgstr "Standard (WP metabox)" +msgstr "Standard (WP-metaruta)" #: includes/admin/views/field-group-options.php:31 msgid "Seamless (no metabox)" -msgstr "Transparent (ingen metabox)" +msgstr "Sömlös (ingen metaruta)" #: includes/admin/views/field-group-options.php:38 msgid "Position" @@ -644,7 +838,7 @@ msgstr "Position" #: includes/admin/views/field-group-options.php:45 msgid "High (after title)" -msgstr "Hög (efter titel)" +msgstr "Hög (efter rubrik)" #: includes/admin/views/field-group-options.php:46 msgid "Normal (after content)" @@ -656,15 +850,15 @@ msgstr "Sidopanel" #: includes/admin/views/field-group-options.php:55 msgid "Label placement" -msgstr "Titel placering" +msgstr "Etikettsplacering" #: includes/admin/views/field-group-options.php:62 -#: includes/fields/class-acf-field-tab.php:116 +#: includes/fields/class-acf-field-tab.php:106 msgid "Top aligned" msgstr "Toppjusterad" #: includes/admin/views/field-group-options.php:63 -#: includes/fields/class-acf-field-tab.php:117 +#: includes/fields/class-acf-field-tab.php:107 msgid "Left aligned" msgstr "Vänsterjusterad" @@ -674,7 +868,7 @@ msgstr "Placering av instruktion" #: includes/admin/views/field-group-options.php:77 msgid "Below labels" -msgstr "Under titlar" +msgstr "Under ettiketer" #: includes/admin/views/field-group-options.php:78 msgid "Below fields" @@ -693,14 +887,67 @@ msgid "Shown in field group list" msgstr "Visas i fältgruppslistan" #: includes/admin/views/field-group-options.php:107 +msgid "Permalink" +msgstr "Permalänk" + +#: includes/admin/views/field-group-options.php:108 +msgid "Content Editor" +msgstr "Innehållsredigerare" + +#: includes/admin/views/field-group-options.php:109 +msgid "Excerpt" +msgstr "Utdrag" + +#: includes/admin/views/field-group-options.php:111 +msgid "Discussion" +msgstr "Diskussion" + +#: includes/admin/views/field-group-options.php:113 +msgid "Revisions" +msgstr "Versioner" + +#: includes/admin/views/field-group-options.php:114 +msgid "Slug" +msgstr "Slug" + +#: includes/admin/views/field-group-options.php:115 +msgid "Author" +msgstr "Författare" + +#: includes/admin/views/field-group-options.php:116 +msgid "Format" +msgstr "Format" + +#: includes/admin/views/field-group-options.php:117 +msgid "Page Attributes" +msgstr "Sidattribut" + +#: includes/admin/views/field-group-options.php:118 +#: includes/fields/class-acf-field-relationship.php:601 +msgid "Featured Image" +msgstr "Utvald bild" + +#: includes/admin/views/field-group-options.php:119 +msgid "Categories" +msgstr "Kategorier" + +#: includes/admin/views/field-group-options.php:120 +msgid "Tags" +msgstr "Etiketter" + +#: includes/admin/views/field-group-options.php:121 +msgid "Send Trackbacks" +msgstr "Skicka trackbacks" + +#: includes/admin/views/field-group-options.php:128 msgid "Hide on screen" msgstr "Dölj på skärmen" -#: includes/admin/views/field-group-options.php:108 +#: includes/admin/views/field-group-options.php:129 msgid "Select items to hide them from the edit screen." -msgstr "Välj objekt för att dölja dem från redigeringsvyn" +msgstr "Välj objekt för att dölja dem från redigeringsvyn." -#: includes/admin/views/field-group-options.php:108 +#: includes/admin/views/field-group-options.php:129 msgid "" "If multiple field groups appear on an edit screen, the first field group's " "options will be used (the one with the lowest order number)" @@ -708,109 +955,49 @@ msgstr "" "Om flera fältgrupper visas i redigeringsvyn, kommer första gruppens " "inställningar att användas (den med lägst ordningsnummer)" -#: includes/admin/views/field-group-options.php:115 -msgid "Permalink" -msgstr "Permalänk" - -#: includes/admin/views/field-group-options.php:116 -msgid "Content Editor" -msgstr "Innehållsredigerare" - -#: includes/admin/views/field-group-options.php:117 -msgid "Excerpt" -msgstr "Utdrag" - -#: includes/admin/views/field-group-options.php:119 -msgid "Discussion" -msgstr "Diskussion" - -#: includes/admin/views/field-group-options.php:120 -msgid "Comments" -msgstr "Kommentarer" - -#: includes/admin/views/field-group-options.php:121 -msgid "Revisions" -msgstr "Versioner" - -#: includes/admin/views/field-group-options.php:122 -msgid "Slug" -msgstr "Permalänk" - -#: includes/admin/views/field-group-options.php:123 -msgid "Author" -msgstr "Författare" - -#: includes/admin/views/field-group-options.php:124 -msgid "Format" -msgstr "Format" - -#: includes/admin/views/field-group-options.php:125 -msgid "Page Attributes" -msgstr "Sidattribut" - -#: includes/admin/views/field-group-options.php:126 -#: includes/fields/class-acf-field-relationship.php:751 -msgid "Featured Image" -msgstr "Utvald bild" - -#: includes/admin/views/field-group-options.php:127 -msgid "Categories" -msgstr "Kategorier" - -#: includes/admin/views/field-group-options.php:128 -msgid "Tags" -msgstr "Taggar" - -#: includes/admin/views/field-group-options.php:129 -msgid "Send Trackbacks" -msgstr "Skicka trackbacks" - -#: includes/admin/views/html-location-group.php:3 -msgid "Show this field group if" -msgstr "Visa detta fält när" - -#: includes/admin/views/install-network.php:4 -msgid "Upgrade Sites" -msgstr "Uppgradera sajter" - -#: includes/admin/views/install-network.php:9 -#: includes/admin/views/install.php:3 -msgid "Advanced Custom Fields Database Upgrade" -msgstr "Advanced Custom Fields databasuppgradering" - -#: includes/admin/views/install-network.php:11 +#: includes/admin/views/html-admin-page-upgrade-network.php:26 #, php-format msgid "" "The following sites require a DB upgrade. Check the ones you want to update " "and then click %s." msgstr "" -"Följande sajter behöver en databasuppdatering. Kryssa i de du vill uppdatera " -"och klicka på %s." +"Följande webbplatser behöver en databasuppdatering. Marker de du vill " +"uppdatera och klicka sedan på %s." -#: includes/admin/views/install-network.php:20 -#: includes/admin/views/install-network.php:28 +#: includes/admin/views/html-admin-page-upgrade-network.php:26 +#: includes/admin/views/html-admin-page-upgrade-network.php:27 +#: includes/admin/views/html-admin-page-upgrade-network.php:92 +msgid "Upgrade Sites" +msgstr "Uppgradera webbplatser" + +#: includes/admin/views/html-admin-page-upgrade-network.php:36 +#: includes/admin/views/html-admin-page-upgrade-network.php:47 msgid "Site" msgstr "Webbplats" -#: includes/admin/views/install-network.php:48 +#: includes/admin/views/html-admin-page-upgrade-network.php:74 #, php-format msgid "Site requires database upgrade from %s to %s" msgstr "Webbplatsen kräver en databasuppgradering från %s till %s" -#: includes/admin/views/install-network.php:50 +#: includes/admin/views/html-admin-page-upgrade-network.php:76 msgid "Site is up to date" msgstr "Webbplatsen är uppdaterad" -#: includes/admin/views/install-network.php:63 +#: includes/admin/views/html-admin-page-upgrade-network.php:93 #, php-format msgid "" "Database Upgrade complete. Return to network dashboard" msgstr "" -"Uppgradering av databas slutförd. Återvänd till nätverkets " -"startpanel" +"Uppgradering av databas slutförd. Återgå till nätverkets " +"adminpanel" -#: includes/admin/views/install-network.php:102 -#: includes/admin/views/install-notice.php:42 +#: includes/admin/views/html-admin-page-upgrade-network.php:113 +msgid "Please select at least one site to upgrade." +msgstr "Välj minst en webbplats att uppgradera." + +#: includes/admin/views/html-admin-page-upgrade-network.php:117 +#: includes/admin/views/html-notice-upgrade.php:38 msgid "" "It is strongly recommended that you backup your database before proceeding. " "Are you sure you wish to run the updater now?" @@ -818,1967 +1005,1740 @@ msgstr "" "Det rekommenderas starkt att du säkerhetskopierar din databas innan du " "fortsätter. Är du säker på att vill köra uppdateringen nu?" -#: includes/admin/views/install-network.php:158 -msgid "Upgrade complete" -msgstr "Uppgradering genomförd" - -#: includes/admin/views/install-network.php:162 -#: includes/admin/views/install.php:9 +#: includes/admin/views/html-admin-page-upgrade-network.php:144 +#: includes/admin/views/html-admin-page-upgrade.php:31 #, php-format msgid "Upgrading data to version %s" msgstr "Uppgradera data till version %s" -#: includes/admin/views/install-notice.php:8 -#: pro/fields/class-acf-field-repeater.php:36 +#: includes/admin/views/html-admin-page-upgrade-network.php:158 +msgid "Upgrade complete." +msgstr "Uppgradering genomförd." + +#: includes/admin/views/html-admin-page-upgrade-network.php:161 +#: includes/admin/views/html-admin-page-upgrade.php:65 +msgid "Upgrade failed." +msgstr "Uppgradering misslyckades." + +#: includes/admin/views/html-admin-page-upgrade.php:30 +msgid "Reading upgrade tasks..." +msgstr "Läser in uppgifter för uppgradering..." + +#: includes/admin/views/html-admin-page-upgrade.php:33 +#, php-format +msgid "Database upgrade complete. See what's new" +msgstr "Databasuppgraderingen genomförd. Se vad som är nytt" + +#: includes/admin/views/html-admin-page-upgrade.php:94 +#: includes/ajax/class-acf-ajax-upgrade.php:32 +msgid "No updates available." +msgstr "Inga uppdateringar tillgängliga." + +#: includes/admin/views/html-admin-tools.php:21 +msgid "Back to all tools" +msgstr "Tillbaka till alla verktyg" + +#: includes/admin/views/html-location-group.php:3 +msgid "Show this field group if" +msgstr "Visa detta fält om" + +#: includes/admin/views/html-notice-upgrade.php:8 +#: pro/fields/class-acf-field-repeater.php:25 msgid "Repeater" msgstr "Upprepningsfält" -#: includes/admin/views/install-notice.php:9 -#: pro/fields/class-acf-field-flexible-content.php:36 +#: includes/admin/views/html-notice-upgrade.php:9 +#: pro/fields/class-acf-field-flexible-content.php:25 msgid "Flexible Content" msgstr "Flexibelt innehåll" -#: includes/admin/views/install-notice.php:10 -#: pro/fields/class-acf-field-gallery.php:36 +#: includes/admin/views/html-notice-upgrade.php:10 +#: pro/fields/class-acf-field-gallery.php:25 msgid "Gallery" msgstr "Galleri" -#: includes/admin/views/install-notice.php:11 -#: pro/locations/class-acf-location-options-page.php:13 +#: includes/admin/views/html-notice-upgrade.php:11 +#: pro/locations/class-acf-location-options-page.php:20 msgid "Options Page" -msgstr "Inställningssida" +msgstr "Alternativsida" -#: includes/admin/views/install-notice.php:26 +#: includes/admin/views/html-notice-upgrade.php:21 msgid "Database Upgrade Required" msgstr "Uppgradering av databasen krävs" -#: includes/admin/views/install-notice.php:28 +#: includes/admin/views/html-notice-upgrade.php:22 #, php-format msgid "Thank you for updating to %s v%s!" msgstr "Tack för du uppdaterade till %s v%s!" -#: includes/admin/views/install-notice.php:28 +#: includes/admin/views/html-notice-upgrade.php:22 msgid "" -"Before you start using the new awesome features, please update your database " -"to the newest version." +"This version contains improvements to your database and requires an upgrade." msgstr "" -"Innan du börjar använda de nya fantastiska funktionerna, vänligen uppdatera " -"din databas till den senaste versionen." +"Denna version innehåller förbättringar av databasen och kräver en " +"uppgradering." -#: includes/admin/views/install-notice.php:31 +#: includes/admin/views/html-notice-upgrade.php:24 #, php-format msgid "" -"Please also ensure any premium add-ons (%s) have first been updated to the " -"latest version." +"Please also check all premium add-ons (%s) are updated to the latest version." msgstr "" +"Kontrollera att alla premium-utökningar (%s) har uppdaterats till den " +"senaste versionen." -#: includes/admin/views/install.php:7 -msgid "Reading upgrade tasks..." -msgstr "Läser in uppgifter för uppgradering..." +#: includes/ajax/class-acf-ajax-local-json-diff.php:34 +msgid "Invalid field group parameter(s)." +msgstr "Ogiltiga fältgruppsparametrer." -#: includes/admin/views/install.php:11 +#: includes/ajax/class-acf-ajax-local-json-diff.php:41 +msgid "Invalid field group ID." +msgstr "Ogiltigt fältgrupps-ID." + +#: includes/ajax/class-acf-ajax-local-json-diff.php:51 +msgid "Sorry, this field group is unavailable for diff comparison." +msgstr "Denna fältgrupp är inte tillgänglig för diff-jämförelse." + +#: includes/ajax/class-acf-ajax-local-json-diff.php:57 #, php-format -msgid "Database Upgrade complete. See what's new" -msgstr "Databasuppgraderingen färdig. Se vad som är nytt" +msgid "Last updated: %s" +msgstr "Senast uppdaterad: %s" -#: includes/admin/views/settings-addons.php:17 -msgid "Download & Install" -msgstr "Ladda ner & installera" +#: includes/ajax/class-acf-ajax-local-json-diff.php:62 +msgid "Original field group" +msgstr "Ursprunglig fältgrupp" -#: includes/admin/views/settings-addons.php:36 -msgid "Installed" -msgstr "Installerad" +#: includes/ajax/class-acf-ajax-local-json-diff.php:66 +msgid "JSON field group (newer)" +msgstr "JSON-fältgrupp (nyare)" -#: includes/admin/views/settings-info.php:3 -msgid "Welcome to Advanced Custom Fields" -msgstr "Välkommen till Advanced Custom Fields" +#: includes/ajax/class-acf-ajax.php:155 +msgid "Invalid nonce." +msgstr "Ogiltig nonce." -#: includes/admin/views/settings-info.php:4 -#, php-format -msgid "" -"Thank you for updating! ACF %s is bigger and better than ever before. We " -"hope you like it." -msgstr "" -"Tack för att du uppdaterar! ACF %s är större och bättre än någonsin " -"tidigare. Vi hoppas att du gillar det." - -#: includes/admin/views/settings-info.php:17 -msgid "A smoother custom field experience" -msgstr "En smidigare fältupplevelse" - -#: includes/admin/views/settings-info.php:22 -msgid "Improved Usability" -msgstr "Förbättrad användarvänlighet" - -#: includes/admin/views/settings-info.php:23 -msgid "" -"Including the popular Select2 library has improved both usability and speed " -"across a number of field types including post object, page link, taxonomy " -"and select." -msgstr "" -"Vi har inkluderat det populära biblioteket Select2 som har förbättrat både " -"användbarhet och laddningstid för ett antal fälttyper såsom inläggsobjekt, " -"sidlänk, taxonomi och val." - -#: includes/admin/views/settings-info.php:27 -msgid "Improved Design" -msgstr "Förbättrad design" - -#: includes/admin/views/settings-info.php:28 -msgid "" -"Many fields have undergone a visual refresh to make ACF look better than " -"ever! Noticeable changes are seen on the gallery, relationship and oEmbed " -"(new) fields!" -msgstr "" -"Många fält har genomgått en visuell förbättring för att låta ACF se bättre " -"ut än någonsin! Märkbara förändringar syns på galleriet-, relation- och " -"oEmbed- (nytt) fälten!" - -#: includes/admin/views/settings-info.php:32 -msgid "Improved Data" -msgstr "Förbättrad data" - -#: includes/admin/views/settings-info.php:33 -msgid "" -"Redesigning the data architecture has allowed sub fields to live " -"independently from their parents. This allows you to drag and drop fields in " -"and out of parent fields!" -msgstr "" -"Omdesignen av dataarkitekturen har tillåtit underfält att leva självständigt " -"från deras föräldrar. Detta gör att du kan dra och släppa fält in och ut " -"från förälderfälten!" - -#: includes/admin/views/settings-info.php:39 -msgid "Goodbye Add-ons. Hello PRO" -msgstr "Adjö tillägg. Hej PRO" - -#: includes/admin/views/settings-info.php:44 -msgid "Introducing ACF PRO" -msgstr "Introducerande av ACF PRO" - -#: includes/admin/views/settings-info.php:45 -msgid "" -"We're changing the way premium functionality is delivered in an exciting way!" -msgstr "Vi ändrar hur premium funktionalitet levereras, på ett spännande sätt!" - -#: includes/admin/views/settings-info.php:46 -#, php-format -msgid "" -"All 4 premium add-ons have been combined into a new Pro " -"version of ACF. With both personal and developer licenses available, " -"premium functionality is more affordable and accessible than ever before!" -msgstr "" -"Samtliga 4 premiumtillägg har kombineras till en ny Pro " -"version av ACF. Med både personlig- och utvecklarlicens tillgänglig, så " -"är premium funktionalitet billigare och tillgängligare än någonsin!" - -#: includes/admin/views/settings-info.php:50 -msgid "Powerful Features" -msgstr "Kraftfulla funktioner" - -#: includes/admin/views/settings-info.php:51 -msgid "" -"ACF PRO contains powerful features such as repeatable data, flexible content " -"layouts, a beautiful gallery field and the ability to create extra admin " -"options pages!" -msgstr "" -"ACF PRO innehåller kraftfulla funktioner som upprepningsfält, flexibelt " -"innehåll, ett vackert gallerifält och möjligheten att skapa extra " -"inställningssidor!" - -#: includes/admin/views/settings-info.php:52 -#, php-format -msgid "Read more about ACF PRO features." -msgstr "Läs mer om ACF PRO funktioner." - -#: includes/admin/views/settings-info.php:56 -msgid "Easy Upgrading" -msgstr "Enkelt att uppgradera" - -#: includes/admin/views/settings-info.php:57 -#, php-format -msgid "" -"To help make upgrading easy, login to your store account " -"and claim a free copy of ACF PRO!" -msgstr "" -"För att göra uppgraderingen enkel, logga in till ditt konto och få en gratis kopia av ACF PRO!" - -#: includes/admin/views/settings-info.php:58 -#, php-format -msgid "" -"We also wrote an upgrade guide to answer any questions, " -"but if you do have one, please contact our support team via the help desk" -msgstr "" -"Vi skrev även en uppgraderings guideför svara på " -"eventuella frågor, men om du har en, vänligen kontakta vårt support team via " -"help desk" - -#: includes/admin/views/settings-info.php:66 -msgid "Under the Hood" -msgstr "Under huven" - -#: includes/admin/views/settings-info.php:71 -msgid "Smarter field settings" -msgstr "Smartare fältinställningar" - -#: includes/admin/views/settings-info.php:72 -msgid "ACF now saves its field settings as individual post objects" -msgstr "ACF sparar nu sina fältinställningar som individuella postobjekt" - -#: includes/admin/views/settings-info.php:76 -msgid "More AJAX" -msgstr "Mer AJAX" - -#: includes/admin/views/settings-info.php:77 -msgid "More fields use AJAX powered search to speed up page loading" -msgstr "Fler fält använder AJAX-sök för snabbare laddning" - -#: includes/admin/views/settings-info.php:81 -msgid "Local JSON" -msgstr "Lokal JSON" - -#: includes/admin/views/settings-info.php:82 -msgid "New auto export to JSON feature improves speed" -msgstr "Ny automatisk export till JSON funktion förbättrar snabbheten" - -#: includes/admin/views/settings-info.php:88 -msgid "Better version control" -msgstr "Bättre versionshantering" - -#: includes/admin/views/settings-info.php:89 -msgid "" -"New auto export to JSON feature allows field settings to be version " -"controlled" -msgstr "" -"Ny auto export till JSON funktion möjliggör versionshantering av " -"fältinställningar" - -#: includes/admin/views/settings-info.php:93 -msgid "Swapped XML for JSON" -msgstr "Bytte XML till JSON" - -#: includes/admin/views/settings-info.php:94 -msgid "Import / Export now uses JSON in favour of XML" -msgstr "Import / Export använder nu JSON istället för XML" - -#: includes/admin/views/settings-info.php:98 -msgid "New Forms" -msgstr "Nya formulär" - -#: includes/admin/views/settings-info.php:99 -msgid "Fields can now be mapped to comments, widgets and all user forms!" -msgstr "" -"Fält kan nu kopplas till kommentarer, widgets och alla användarformulär." - -#: includes/admin/views/settings-info.php:106 -msgid "A new field for embedding content has been added" -msgstr "Ett nytt fält för inbäddning av innehåll (embed) har lagts till" - -#: includes/admin/views/settings-info.php:110 -msgid "New Gallery" -msgstr "Nytt galleri" - -#: includes/admin/views/settings-info.php:111 -msgid "The gallery field has undergone a much needed facelift" -msgstr "Gallerifältet har genomgått en välbehövlig ansiktslyftning" - -#: includes/admin/views/settings-info.php:115 -msgid "New Settings" -msgstr "Nya inställningar" - -#: includes/admin/views/settings-info.php:116 -msgid "" -"Field group settings have been added for label placement and instruction " -"placement" -msgstr "" -"Fältgruppsinställningar har lagts till för placering av titel och " -"instruktioner" - -#: includes/admin/views/settings-info.php:122 -msgid "Better Front End Forms" -msgstr "Bättre front-end formulär" - -#: includes/admin/views/settings-info.php:123 -msgid "acf_form() can now create a new post on submission" -msgstr "acf_form() kan nu skapa ett nytt inlägg vid submit" - -#: includes/admin/views/settings-info.php:127 -msgid "Better Validation" -msgstr "Bättre validering" - -#: includes/admin/views/settings-info.php:128 -msgid "Form validation is now done via PHP + AJAX in favour of only JS" -msgstr "Validering av formulär görs nu via PHP + AJAX istället för enbart JS" - -#: includes/admin/views/settings-info.php:132 -msgid "Relationship Field" -msgstr "Relationsfält" - -#: includes/admin/views/settings-info.php:133 -msgid "" -"New Relationship field setting for 'Filters' (Search, Post Type, Taxonomy)" -msgstr "" -"Ny inställning för relationsfält för 'Filter' (Sök, Inläggstyp, Taxonomi)" - -#: includes/admin/views/settings-info.php:139 -msgid "Moving Fields" -msgstr "Flytta runt fält" - -#: includes/admin/views/settings-info.php:140 -msgid "" -"New field group functionality allows you to move a field between groups & " -"parents" -msgstr "" -"Ny fältgrupp funktionalitet tillåter dig att flytta ett fält mellan grupper " -"& föräldrar" - -#: includes/admin/views/settings-info.php:144 -#: includes/fields/class-acf-field-page_link.php:36 -msgid "Page Link" -msgstr "Sidlänk" - -#: includes/admin/views/settings-info.php:145 -msgid "New archives group in page_link field selection" -msgstr "Ny arkivgrupp i page_link fältval" - -#: includes/admin/views/settings-info.php:149 -msgid "Better Options Pages" -msgstr "Bättre inställningssidor" - -#: includes/admin/views/settings-info.php:150 -msgid "" -"New functions for options page allow creation of both parent and child menu " -"pages" -msgstr "" -"Nya funktioner för inställningssidor tillåter skapande av både föräldra- och " -"undersidor" - -#: includes/admin/views/settings-info.php:159 -#, php-format -msgid "We think you'll love the changes in %s." -msgstr "Vi tror att du kommer uppskatta förändringarna i %s." - -#: includes/admin/views/settings-tools-export.php:23 -msgid "Export Field Groups to PHP" -msgstr "Exportera fältgrupper till PHP" - -#: includes/admin/views/settings-tools-export.php:27 -msgid "" -"The following code can be used to register a local version of the selected " -"field group(s). A local field group can provide many benefits such as faster " -"load times, version control & dynamic fields/settings. Simply copy and paste " -"the following code to your theme's functions.php file or include it within " -"an external file." -msgstr "" -"Följande kod kan användas för att registrera en lokal version av valda " -"fältgrupp(er). Ett lokal fältgrupp kan ge många fördelar som snabbare " -"laddningstider, versionshantering & dynamiska fält/inställningar. Det är " -"bara att kopiera och klistra in följande kod till ditt temas functions.php " -"fil eller att inkludera det i en extern fil." - -#: includes/admin/views/settings-tools.php:5 -msgid "Select Field Groups" -msgstr "Välj fältgrupp" - -#: includes/admin/views/settings-tools.php:35 -msgid "Export Field Groups" -msgstr "Exportera fältgrupper" - -#: includes/admin/views/settings-tools.php:38 -msgid "" -"Select the field groups you would like to export and then select your export " -"method. Use the download button to export to a .json file which you can then " -"import to another ACF installation. Use the generate button to export to PHP " -"code which you can place in your theme." -msgstr "" -"Välj de fältgrupper som du vill exportera och sedan välj din exportmetod. " -"Använd knappen för exportera till en .json fil som du sedan kan importera " -"till en annan ACF installation. Använd generera-knappen för att exportera " -"PHP kod som du kan lägga till i ditt tema." - -#: includes/admin/views/settings-tools.php:50 -msgid "Download export file" -msgstr "Ladda ner exportfil" - -#: includes/admin/views/settings-tools.php:51 -msgid "Generate export code" -msgstr "Generera exportkod" - -#: includes/admin/views/settings-tools.php:64 -msgid "Import Field Groups" -msgstr "Importera fältgrupper" - -#: includes/admin/views/settings-tools.php:67 -msgid "" -"Select the Advanced Custom Fields JSON file you would like to import. When " -"you click the import button below, ACF will import the field groups." -msgstr "" -"Välj den Advanced Custom Fields JSON-fil som du vill importera. När du " -"klickar på import knappen så kommer ACF importera fältgrupperna." - -#: includes/admin/views/settings-tools.php:77 -#: includes/fields/class-acf-field-file.php:46 -msgid "Select File" -msgstr "Välj fil" - -#: includes/admin/views/settings-tools.php:86 -msgid "Import" -msgstr "Importera" - -#: includes/api/api-helpers.php:856 +#: includes/api/api-helpers.php:844 msgid "Thumbnail" msgstr "Tumnagel" -#: includes/api/api-helpers.php:857 +#: includes/api/api-helpers.php:845 msgid "Medium" msgstr "Mellan" -#: includes/api/api-helpers.php:858 +#: includes/api/api-helpers.php:846 msgid "Large" msgstr "Stor" -#: includes/api/api-helpers.php:907 +#: includes/api/api-helpers.php:895 msgid "Full Size" msgstr "Full storlek" -#: includes/api/api-helpers.php:1248 includes/api/api-helpers.php:1837 -#: pro/fields/class-acf-field-clone.php:1042 +#: includes/api/api-helpers.php:1632 includes/api/api-term.php:145 +#: pro/fields/class-acf-field-clone.php:984 msgid "(no title)" -msgstr "(ingen titel)" +msgstr "(ingen rubrik)" -#: includes/api/api-helpers.php:1874 -#: includes/fields/class-acf-field-page_link.php:284 -#: includes/fields/class-acf-field-post_object.php:283 -#: includes/fields/class-acf-field-taxonomy.php:992 -msgid "Parent" -msgstr "Förälder" - -#: includes/api/api-helpers.php:3891 +#: includes/api/api-helpers.php:3507 #, php-format msgid "Image width must be at least %dpx." msgstr "Bildens bredd måste vara åtminstone %dpx." -#: includes/api/api-helpers.php:3896 +#: includes/api/api-helpers.php:3512 #, php-format msgid "Image width must not exceed %dpx." msgstr "Bildens bredd får inte överskrida %dpx." -#: includes/api/api-helpers.php:3912 +#: includes/api/api-helpers.php:3528 #, php-format msgid "Image height must be at least %dpx." msgstr "Bildens höjd måste vara åtminstone %dpx." -#: includes/api/api-helpers.php:3917 +#: includes/api/api-helpers.php:3533 #, php-format msgid "Image height must not exceed %dpx." msgstr "Bildens höjd får inte överskrida %dpx." -#: includes/api/api-helpers.php:3935 +#: includes/api/api-helpers.php:3551 #, php-format msgid "File size must be at least %s." msgstr "Filstorlek måste vara åtminstone %s." -#: includes/api/api-helpers.php:3940 +#: includes/api/api-helpers.php:3556 #, php-format -msgid "File size must must not exceed %s." +msgid "File size must not exceed %s." msgstr "Filstorlek får inte överskrida %s." -#: includes/api/api-helpers.php:3974 +#: includes/api/api-helpers.php:3590 #, php-format msgid "File type must be %s." msgstr "Filtyp måste vara %s." -#: includes/fields.php:144 -msgid "Basic" -msgstr "Enkel" +#: includes/assets.php:343 +msgid "Are you sure?" +msgstr "Är du säker?" -#: includes/fields.php:145 includes/forms/form-front.php:47 -msgid "Content" -msgstr "Innehåll" +#: includes/assets.php:344 includes/fields/class-acf-field-true_false.php:79 +#: includes/fields/class-acf-field-true_false.php:159 +#: pro/admin/views/html-settings-updates.php:86 +msgid "Yes" +msgstr "Ja" -#: includes/fields.php:146 -msgid "Choice" -msgstr "Alternativ" +#: includes/assets.php:345 includes/fields/class-acf-field-true_false.php:80 +#: includes/fields/class-acf-field-true_false.php:174 +#: pro/admin/views/html-settings-updates.php:96 +msgid "No" +msgstr "Nej" -#: includes/fields.php:147 -msgid "Relational" -msgstr "Relation" +#: includes/assets.php:346 includes/fields/class-acf-field-file.php:153 +#: includes/fields/class-acf-field-image.php:133 +#: includes/fields/class-acf-field-link.php:140 +#: pro/fields/class-acf-field-gallery.php:335 +#: pro/fields/class-acf-field-gallery.php:475 +msgid "Remove" +msgstr "Ta bort" -#: includes/fields.php:148 -msgid "jQuery" -msgstr "jQuery" +#: includes/assets.php:347 +msgid "Cancel" +msgstr "Avbryt" -#: includes/fields.php:149 includes/fields/class-acf-field-checkbox.php:286 -#: includes/fields/class-acf-field-group.php:485 -#: includes/fields/class-acf-field-radio.php:300 -#: pro/fields/class-acf-field-clone.php:889 -#: pro/fields/class-acf-field-flexible-content.php:569 -#: pro/fields/class-acf-field-flexible-content.php:618 -#: pro/fields/class-acf-field-repeater.php:514 -msgid "Layout" -msgstr "Layout" +#: includes/assets.php:355 +msgid "The changes you made will be lost if you navigate away from this page" +msgstr "" +"De ändringar som du gjort kommer att förloras om du navigerar bort från " +"denna sida" -#: includes/fields.php:305 +#: includes/assets.php:358 +msgid "Validation successful" +msgstr "Validering lyckades" + +#: includes/assets.php:359 includes/validation.php:285 +#: includes/validation.php:296 +msgid "Validation failed" +msgstr "Validering misslyckades" + +#: includes/assets.php:360 +msgid "1 field requires attention" +msgstr "1 fält kräver din uppmärksamhet" + +#: includes/assets.php:361 +#, php-format +msgid "%d fields require attention" +msgstr "%d fält kräver din uppmärksamhet" + +#: includes/assets.php:364 includes/forms/form-comment.php:166 +#: pro/admin/admin-options-page.php:325 +msgid "Edit field group" +msgstr "Redigera fältgrupp" + +#: includes/fields.php:308 msgid "Field type does not exist" msgstr "Fälttyp existerar inte" -#: includes/fields.php:305 -#, fuzzy +#: includes/fields.php:308 msgid "Unknown" msgstr "Okänd fältgrupp" -#: includes/fields/class-acf-field-checkbox.php:36 -#: includes/fields/class-acf-field-taxonomy.php:786 -msgid "Checkbox" -msgstr "Kryssruta" +#: includes/fields.php:349 +msgid "Basic" +msgstr "Enkel" -#: includes/fields/class-acf-field-checkbox.php:150 -msgid "Toggle All" -msgstr "Markera alla" +#: includes/fields.php:350 includes/forms/form-front.php:47 +msgid "Content" +msgstr "Innehåll" -#: includes/fields/class-acf-field-checkbox.php:207 -msgid "Add new choice" -msgstr "Skapa nytt val" +#: includes/fields.php:351 +msgid "Choice" +msgstr "Alternativ" -#: includes/fields/class-acf-field-checkbox.php:246 -#: includes/fields/class-acf-field-radio.php:250 -#: includes/fields/class-acf-field-select.php:466 +#: includes/fields.php:352 +msgid "Relational" +msgstr "Relation" + +#: includes/fields.php:353 +msgid "jQuery" +msgstr "jQuery" + +#: includes/fields.php:354 includes/fields/class-acf-field-button-group.php:177 +#: includes/fields/class-acf-field-checkbox.php:389 +#: includes/fields/class-acf-field-group.php:474 +#: includes/fields/class-acf-field-radio.php:247 +#: pro/fields/class-acf-field-clone.php:831 +#: pro/fields/class-acf-field-flexible-content.php:549 +#: pro/fields/class-acf-field-flexible-content.php:598 +#: pro/fields/class-acf-field-repeater.php:444 +msgid "Layout" +msgstr "Layout" + +#: includes/fields/class-acf-field-accordion.php:24 +msgid "Accordion" +msgstr "Expanderbar lista" + +#: includes/fields/class-acf-field-accordion.php:99 +msgid "Open" +msgstr "Öppen" + +#: includes/fields/class-acf-field-accordion.php:100 +msgid "Display this accordion as open on page load." +msgstr "Visa denna lista som öppen vid sidladdning." + +#: includes/fields/class-acf-field-accordion.php:109 +msgid "Multi-expand" +msgstr "Multi-expandera" + +#: includes/fields/class-acf-field-accordion.php:110 +msgid "Allow this accordion to open without closing others." +msgstr "Tillåt denna expanderbara lista att öppnas utan att stänga övriga." + +#: includes/fields/class-acf-field-accordion.php:119 +#: includes/fields/class-acf-field-tab.php:114 +msgid "Endpoint" +msgstr "Ändpunkt" + +#: includes/fields/class-acf-field-accordion.php:120 +msgid "" +"Define an endpoint for the previous accordion to stop. This accordion will " +"not be visible." +msgstr "" +"Definiera en ändpunkt för där den tidigare expanderbara listan ska stoppa. " +"Denna expanderbara lista kommer inte synas." + +#: includes/fields/class-acf-field-button-group.php:24 +msgid "Button Group" +msgstr "Knappgrupp" + +#: includes/fields/class-acf-field-button-group.php:149 +#: includes/fields/class-acf-field-checkbox.php:344 +#: includes/fields/class-acf-field-radio.php:192 +#: includes/fields/class-acf-field-select.php:364 msgid "Choices" msgstr "Alternativ" -#: includes/fields/class-acf-field-checkbox.php:247 -#: includes/fields/class-acf-field-radio.php:251 -#: includes/fields/class-acf-field-select.php:467 +#: includes/fields/class-acf-field-button-group.php:150 +#: includes/fields/class-acf-field-checkbox.php:345 +#: includes/fields/class-acf-field-radio.php:193 +#: includes/fields/class-acf-field-select.php:365 msgid "Enter each choice on a new line." -msgstr "Ange varje alternativ på en ny rad" +msgstr "Ange varje alternativ på en ny rad." -#: includes/fields/class-acf-field-checkbox.php:247 -#: includes/fields/class-acf-field-radio.php:251 -#: includes/fields/class-acf-field-select.php:467 +#: includes/fields/class-acf-field-button-group.php:150 +#: includes/fields/class-acf-field-checkbox.php:345 +#: includes/fields/class-acf-field-radio.php:193 +#: includes/fields/class-acf-field-select.php:365 msgid "For more control, you may specify both a value and label like this:" msgstr "För mer kontroll, kan du specificera både ett värde och etikett såhär:" -#: includes/fields/class-acf-field-checkbox.php:247 -#: includes/fields/class-acf-field-radio.php:251 -#: includes/fields/class-acf-field-select.php:467 +#: includes/fields/class-acf-field-button-group.php:150 +#: includes/fields/class-acf-field-checkbox.php:345 +#: includes/fields/class-acf-field-radio.php:193 +#: includes/fields/class-acf-field-select.php:365 msgid "red : Red" msgstr "röd : Röd" -#: includes/fields/class-acf-field-checkbox.php:255 -msgid "Allow Custom" -msgstr "Tillåt annat val" +#: includes/fields/class-acf-field-button-group.php:158 +#: includes/fields/class-acf-field-page_link.php:506 +#: includes/fields/class-acf-field-post_object.php:411 +#: includes/fields/class-acf-field-radio.php:201 +#: includes/fields/class-acf-field-select.php:382 +#: includes/fields/class-acf-field-taxonomy.php:771 +#: includes/fields/class-acf-field-user.php:63 +msgid "Allow Null?" +msgstr "Tillått nollvärde?" -#: includes/fields/class-acf-field-checkbox.php:260 -msgid "Allow 'custom' values to be added" -msgstr "Tillåter 'annat val' att väljas" - -#: includes/fields/class-acf-field-checkbox.php:266 -msgid "Save Custom" -msgstr "Spara annat val" - -#: includes/fields/class-acf-field-checkbox.php:271 -msgid "Save 'custom' values to the field's choices" -msgstr "Spara 'annat val' värdet till fältets val" - -#: includes/fields/class-acf-field-checkbox.php:277 -#: includes/fields/class-acf-field-color_picker.php:146 -#: includes/fields/class-acf-field-email.php:133 -#: includes/fields/class-acf-field-number.php:145 -#: includes/fields/class-acf-field-radio.php:291 -#: includes/fields/class-acf-field-select.php:475 -#: includes/fields/class-acf-field-text.php:142 -#: includes/fields/class-acf-field-textarea.php:139 -#: includes/fields/class-acf-field-true_false.php:150 -#: includes/fields/class-acf-field-url.php:114 -#: includes/fields/class-acf-field-wysiwyg.php:436 +#: includes/fields/class-acf-field-button-group.php:168 +#: includes/fields/class-acf-field-checkbox.php:380 +#: includes/fields/class-acf-field-color_picker.php:127 +#: includes/fields/class-acf-field-email.php:118 +#: includes/fields/class-acf-field-number.php:127 +#: includes/fields/class-acf-field-radio.php:238 +#: includes/fields/class-acf-field-range.php:155 +#: includes/fields/class-acf-field-select.php:373 +#: includes/fields/class-acf-field-text.php:95 +#: includes/fields/class-acf-field-textarea.php:102 +#: includes/fields/class-acf-field-true_false.php:135 +#: includes/fields/class-acf-field-url.php:100 +#: includes/fields/class-acf-field-wysiwyg.php:345 msgid "Default Value" msgstr "Standardvärde" -#: includes/fields/class-acf-field-checkbox.php:278 -#: includes/fields/class-acf-field-select.php:476 -msgid "Enter each default value on a new line" -msgstr "Ange varje standardvärde på en ny rad" +#: includes/fields/class-acf-field-button-group.php:169 +#: includes/fields/class-acf-field-email.php:119 +#: includes/fields/class-acf-field-number.php:128 +#: includes/fields/class-acf-field-radio.php:239 +#: includes/fields/class-acf-field-range.php:156 +#: includes/fields/class-acf-field-text.php:96 +#: includes/fields/class-acf-field-textarea.php:103 +#: includes/fields/class-acf-field-url.php:101 +#: includes/fields/class-acf-field-wysiwyg.php:346 +msgid "Appears when creating a new post" +msgstr "Visas när ett nytt inlägg skapas" -#: includes/fields/class-acf-field-checkbox.php:292 -#: includes/fields/class-acf-field-radio.php:306 -msgid "Vertical" -msgstr "Vertikal" - -#: includes/fields/class-acf-field-checkbox.php:293 -#: includes/fields/class-acf-field-radio.php:307 +#: includes/fields/class-acf-field-button-group.php:183 +#: includes/fields/class-acf-field-checkbox.php:396 +#: includes/fields/class-acf-field-radio.php:254 msgid "Horizontal" msgstr "Horisontell" -#: includes/fields/class-acf-field-checkbox.php:300 -msgid "Toggle" -msgstr "Slå på/av" +#: includes/fields/class-acf-field-button-group.php:184 +#: includes/fields/class-acf-field-checkbox.php:395 +#: includes/fields/class-acf-field-radio.php:253 +msgid "Vertical" +msgstr "Vertikal" -#: includes/fields/class-acf-field-checkbox.php:301 -msgid "Prepend an extra checkbox to toggle all choices" -msgstr "Visa en extra kryssruta för att markera alla val" - -#: includes/fields/class-acf-field-checkbox.php:310 -#: includes/fields/class-acf-field-file.php:219 -#: includes/fields/class-acf-field-image.php:206 -#: includes/fields/class-acf-field-link.php:180 -#: includes/fields/class-acf-field-radio.php:314 -#: includes/fields/class-acf-field-taxonomy.php:839 +#: includes/fields/class-acf-field-button-group.php:191 +#: includes/fields/class-acf-field-checkbox.php:413 +#: includes/fields/class-acf-field-file.php:214 +#: includes/fields/class-acf-field-link.php:166 +#: includes/fields/class-acf-field-radio.php:261 +#: includes/fields/class-acf-field-taxonomy.php:816 msgid "Return Value" msgstr "Returvärde" -#: includes/fields/class-acf-field-checkbox.php:311 -#: includes/fields/class-acf-field-file.php:220 -#: includes/fields/class-acf-field-image.php:207 -#: includes/fields/class-acf-field-link.php:181 -#: includes/fields/class-acf-field-radio.php:315 +#: includes/fields/class-acf-field-button-group.php:192 +#: includes/fields/class-acf-field-checkbox.php:414 +#: includes/fields/class-acf-field-file.php:215 +#: includes/fields/class-acf-field-link.php:167 +#: includes/fields/class-acf-field-radio.php:262 msgid "Specify the returned value on front end" msgstr "Välj vilken typ av värde som ska returneras på front-end" -#: includes/fields/class-acf-field-checkbox.php:316 -#: includes/fields/class-acf-field-radio.php:320 -#: includes/fields/class-acf-field-select.php:529 +#: includes/fields/class-acf-field-button-group.php:197 +#: includes/fields/class-acf-field-checkbox.php:419 +#: includes/fields/class-acf-field-radio.php:267 +#: includes/fields/class-acf-field-select.php:432 msgid "Value" msgstr "Värde" -#: includes/fields/class-acf-field-checkbox.php:318 -#: includes/fields/class-acf-field-radio.php:322 -#: includes/fields/class-acf-field-select.php:531 +#: includes/fields/class-acf-field-button-group.php:199 +#: includes/fields/class-acf-field-checkbox.php:421 +#: includes/fields/class-acf-field-radio.php:269 +#: includes/fields/class-acf-field-select.php:434 msgid "Both (Array)" -msgstr "Båda" +msgstr "Båda (array)" -#: includes/fields/class-acf-field-color_picker.php:36 +#: includes/fields/class-acf-field-checkbox.php:25 +#: includes/fields/class-acf-field-taxonomy.php:758 +msgid "Checkbox" +msgstr "Kryssruta" + +#: includes/fields/class-acf-field-checkbox.php:154 +msgid "Toggle All" +msgstr "Markera alla" + +#: includes/fields/class-acf-field-checkbox.php:221 +msgid "Add new choice" +msgstr "Skapa nytt val" + +#: includes/fields/class-acf-field-checkbox.php:353 +msgid "Allow Custom" +msgstr "Tillåt annat val" + +#: includes/fields/class-acf-field-checkbox.php:358 +msgid "Allow 'custom' values to be added" +msgstr "Tillåter ”annat val” att väljas" + +#: includes/fields/class-acf-field-checkbox.php:364 +msgid "Save Custom" +msgstr "Spara annat val" + +#: includes/fields/class-acf-field-checkbox.php:369 +msgid "Save 'custom' values to the field's choices" +msgstr "Spara ”annat val”-värdet till fältets val" + +#: includes/fields/class-acf-field-checkbox.php:381 +#: includes/fields/class-acf-field-select.php:374 +msgid "Enter each default value on a new line" +msgstr "Ange varje standardvärde på en ny rad" + +#: includes/fields/class-acf-field-checkbox.php:403 +msgid "Toggle" +msgstr "Slå på/av" + +#: includes/fields/class-acf-field-checkbox.php:404 +msgid "Prepend an extra checkbox to toggle all choices" +msgstr "Visa en extra kryssruta för att markera alla val" + +#: includes/fields/class-acf-field-color_picker.php:25 msgid "Color Picker" msgstr "Färgväljare" -#: includes/fields/class-acf-field-color_picker.php:83 +#: includes/fields/class-acf-field-color_picker.php:64 msgid "Clear" msgstr "Rensa" -#: includes/fields/class-acf-field-color_picker.php:84 +#: includes/fields/class-acf-field-color_picker.php:65 +msgid "Clear color" +msgstr "Rensa färg" + +#: includes/fields/class-acf-field-color_picker.php:66 msgid "Default" msgstr "Standard" -#: includes/fields/class-acf-field-color_picker.php:85 +#: includes/fields/class-acf-field-color_picker.php:67 +msgid "Select default color" +msgstr "Välj standardfärg" + +#: includes/fields/class-acf-field-color_picker.php:68 msgid "Select Color" msgstr "Välj färg" -#: includes/fields/class-acf-field-color_picker.php:86 -msgid "Current Color" -msgstr "Nuvarande färg" +#: includes/fields/class-acf-field-color_picker.php:69 +msgid "Color value" +msgstr "Färgvärde" -#: includes/fields/class-acf-field-date_picker.php:36 +#: includes/fields/class-acf-field-date_picker.php:25 msgid "Date Picker" msgstr "Datumväljare" -#: includes/fields/class-acf-field-date_picker.php:44 +#: includes/fields/class-acf-field-date_picker.php:59 msgctxt "Date Picker JS closeText" msgid "Done" msgstr "Färdig" -#: includes/fields/class-acf-field-date_picker.php:45 +#: includes/fields/class-acf-field-date_picker.php:60 msgctxt "Date Picker JS currentText" msgid "Today" msgstr "Idag" -#: includes/fields/class-acf-field-date_picker.php:46 +#: includes/fields/class-acf-field-date_picker.php:61 msgctxt "Date Picker JS nextText" msgid "Next" msgstr "Nästa" -#: includes/fields/class-acf-field-date_picker.php:47 +#: includes/fields/class-acf-field-date_picker.php:62 msgctxt "Date Picker JS prevText" msgid "Prev" msgstr "Föregående" -#: includes/fields/class-acf-field-date_picker.php:48 +#: includes/fields/class-acf-field-date_picker.php:63 msgctxt "Date Picker JS weekHeader" msgid "Wk" msgstr "V" -#: includes/fields/class-acf-field-date_picker.php:223 -#: includes/fields/class-acf-field-date_time_picker.php:197 -#: includes/fields/class-acf-field-time_picker.php:127 +#: includes/fields/class-acf-field-date_picker.php:179 +#: includes/fields/class-acf-field-date_time_picker.php:181 +#: includes/fields/class-acf-field-time_picker.php:113 msgid "Display Format" msgstr "Visa format" -#: includes/fields/class-acf-field-date_picker.php:224 -#: includes/fields/class-acf-field-date_time_picker.php:198 -#: includes/fields/class-acf-field-time_picker.php:128 +#: includes/fields/class-acf-field-date_picker.php:180 +#: includes/fields/class-acf-field-date_time_picker.php:182 +#: includes/fields/class-acf-field-time_picker.php:114 msgid "The format displayed when editing a post" -msgstr "Formatet som visas när du redigerar ett inlägg" +msgstr "Visningsformatet vid ändring av inlägg" -#: includes/fields/class-acf-field-date_picker.php:232 -#: includes/fields/class-acf-field-date_picker.php:263 -#: includes/fields/class-acf-field-date_time_picker.php:207 -#: includes/fields/class-acf-field-date_time_picker.php:224 -#: includes/fields/class-acf-field-time_picker.php:135 -#: includes/fields/class-acf-field-time_picker.php:150 -#, fuzzy +#: includes/fields/class-acf-field-date_picker.php:188 +#: includes/fields/class-acf-field-date_picker.php:219 +#: includes/fields/class-acf-field-date_time_picker.php:191 +#: includes/fields/class-acf-field-date_time_picker.php:208 +#: includes/fields/class-acf-field-time_picker.php:121 +#: includes/fields/class-acf-field-time_picker.php:136 msgid "Custom:" -msgstr "Advanced Custom Fields" +msgstr "Anpassat:" -#: includes/fields/class-acf-field-date_picker.php:242 +#: includes/fields/class-acf-field-date_picker.php:198 msgid "Save Format" msgstr "Spara i format" -#: includes/fields/class-acf-field-date_picker.php:243 +#: includes/fields/class-acf-field-date_picker.php:199 msgid "The format used when saving a value" msgstr "Formatet som används när ett värde sparas" -#: includes/fields/class-acf-field-date_picker.php:253 -#: includes/fields/class-acf-field-date_time_picker.php:214 -#: includes/fields/class-acf-field-post_object.php:447 -#: includes/fields/class-acf-field-relationship.php:778 -#: includes/fields/class-acf-field-select.php:524 -#: includes/fields/class-acf-field-time_picker.php:142 +#: includes/fields/class-acf-field-date_picker.php:209 +#: includes/fields/class-acf-field-date_time_picker.php:198 +#: includes/fields/class-acf-field-image.php:194 +#: includes/fields/class-acf-field-post_object.php:431 +#: includes/fields/class-acf-field-relationship.php:628 +#: includes/fields/class-acf-field-select.php:427 +#: includes/fields/class-acf-field-time_picker.php:128 +#: includes/fields/class-acf-field-user.php:79 +#: pro/fields/class-acf-field-gallery.php:554 msgid "Return Format" msgstr "Returvärde" -#: includes/fields/class-acf-field-date_picker.php:254 -#: includes/fields/class-acf-field-date_time_picker.php:215 -#: includes/fields/class-acf-field-time_picker.php:143 +#: includes/fields/class-acf-field-date_picker.php:210 +#: includes/fields/class-acf-field-date_time_picker.php:199 +#: includes/fields/class-acf-field-time_picker.php:129 msgid "The format returned via template functions" msgstr "Formatet som returneras av mallfunktioner" -#: includes/fields/class-acf-field-date_picker.php:272 -#: includes/fields/class-acf-field-date_time_picker.php:231 +#: includes/fields/class-acf-field-date_picker.php:228 +#: includes/fields/class-acf-field-date_time_picker.php:215 msgid "Week Starts On" -msgstr "Veckor börjar på" +msgstr "Veckan börjar på" -#: includes/fields/class-acf-field-date_time_picker.php:36 +#: includes/fields/class-acf-field-date_time_picker.php:25 msgid "Date Time Picker" msgstr "Datum/tidväljare" -#: includes/fields/class-acf-field-date_time_picker.php:44 +#: includes/fields/class-acf-field-date_time_picker.php:68 msgctxt "Date Time Picker JS timeOnlyTitle" msgid "Choose Time" msgstr "Välj tid" -#: includes/fields/class-acf-field-date_time_picker.php:45 +#: includes/fields/class-acf-field-date_time_picker.php:69 msgctxt "Date Time Picker JS timeText" msgid "Time" msgstr "Tid" -#: includes/fields/class-acf-field-date_time_picker.php:46 +#: includes/fields/class-acf-field-date_time_picker.php:70 msgctxt "Date Time Picker JS hourText" msgid "Hour" msgstr "Timme" -#: includes/fields/class-acf-field-date_time_picker.php:47 +#: includes/fields/class-acf-field-date_time_picker.php:71 msgctxt "Date Time Picker JS minuteText" msgid "Minute" msgstr "Minut" -#: includes/fields/class-acf-field-date_time_picker.php:48 +#: includes/fields/class-acf-field-date_time_picker.php:72 msgctxt "Date Time Picker JS secondText" msgid "Second" msgstr "Sekund" -#: includes/fields/class-acf-field-date_time_picker.php:49 +#: includes/fields/class-acf-field-date_time_picker.php:73 msgctxt "Date Time Picker JS millisecText" msgid "Millisecond" msgstr "Millisekund" -#: includes/fields/class-acf-field-date_time_picker.php:50 +#: includes/fields/class-acf-field-date_time_picker.php:74 msgctxt "Date Time Picker JS microsecText" msgid "Microsecond" msgstr "Mikrosekund" -#: includes/fields/class-acf-field-date_time_picker.php:51 +#: includes/fields/class-acf-field-date_time_picker.php:75 msgctxt "Date Time Picker JS timezoneText" msgid "Time Zone" msgstr "Tidszon" -#: includes/fields/class-acf-field-date_time_picker.php:52 +#: includes/fields/class-acf-field-date_time_picker.php:76 msgctxt "Date Time Picker JS currentText" msgid "Now" msgstr "Nu" -#: includes/fields/class-acf-field-date_time_picker.php:53 +#: includes/fields/class-acf-field-date_time_picker.php:77 msgctxt "Date Time Picker JS closeText" msgid "Done" msgstr "Klar" -#: includes/fields/class-acf-field-date_time_picker.php:54 +#: includes/fields/class-acf-field-date_time_picker.php:78 msgctxt "Date Time Picker JS selectText" msgid "Select" msgstr "Välj" -#: includes/fields/class-acf-field-date_time_picker.php:56 +#: includes/fields/class-acf-field-date_time_picker.php:80 msgctxt "Date Time Picker JS amText" msgid "AM" -msgstr "AM" +msgstr "fm" -#: includes/fields/class-acf-field-date_time_picker.php:57 +#: includes/fields/class-acf-field-date_time_picker.php:81 msgctxt "Date Time Picker JS amTextShort" msgid "A" -msgstr "A" +msgstr "fm" -#: includes/fields/class-acf-field-date_time_picker.php:60 +#: includes/fields/class-acf-field-date_time_picker.php:84 msgctxt "Date Time Picker JS pmText" msgid "PM" -msgstr "PM" +msgstr "em" -#: includes/fields/class-acf-field-date_time_picker.php:61 +#: includes/fields/class-acf-field-date_time_picker.php:85 msgctxt "Date Time Picker JS pmTextShort" msgid "P" -msgstr "P" +msgstr "E" -#: includes/fields/class-acf-field-email.php:36 +#: includes/fields/class-acf-field-email.php:25 msgid "Email" msgstr "E-post" -#: includes/fields/class-acf-field-email.php:134 -#: includes/fields/class-acf-field-number.php:146 -#: includes/fields/class-acf-field-radio.php:292 -#: includes/fields/class-acf-field-text.php:143 -#: includes/fields/class-acf-field-textarea.php:140 -#: includes/fields/class-acf-field-url.php:115 -#: includes/fields/class-acf-field-wysiwyg.php:437 -msgid "Appears when creating a new post" -msgstr "Visas när ett nytt inlägg skapas" - -#: includes/fields/class-acf-field-email.php:142 -#: includes/fields/class-acf-field-number.php:154 -#: includes/fields/class-acf-field-password.php:134 -#: includes/fields/class-acf-field-text.php:151 -#: includes/fields/class-acf-field-textarea.php:148 -#: includes/fields/class-acf-field-url.php:123 +#: includes/fields/class-acf-field-email.php:127 +#: includes/fields/class-acf-field-number.php:136 +#: includes/fields/class-acf-field-password.php:71 +#: includes/fields/class-acf-field-text.php:104 +#: includes/fields/class-acf-field-textarea.php:111 +#: includes/fields/class-acf-field-url.php:109 msgid "Placeholder Text" msgstr "Platshållartext" -#: includes/fields/class-acf-field-email.php:143 -#: includes/fields/class-acf-field-number.php:155 -#: includes/fields/class-acf-field-password.php:135 -#: includes/fields/class-acf-field-text.php:152 -#: includes/fields/class-acf-field-textarea.php:149 -#: includes/fields/class-acf-field-url.php:124 +#: includes/fields/class-acf-field-email.php:128 +#: includes/fields/class-acf-field-number.php:137 +#: includes/fields/class-acf-field-password.php:72 +#: includes/fields/class-acf-field-text.php:105 +#: includes/fields/class-acf-field-textarea.php:112 +#: includes/fields/class-acf-field-url.php:110 msgid "Appears within the input" msgstr "Visas inuti fältet" -#: includes/fields/class-acf-field-email.php:151 -#: includes/fields/class-acf-field-number.php:163 -#: includes/fields/class-acf-field-password.php:143 -#: includes/fields/class-acf-field-text.php:160 +#: includes/fields/class-acf-field-email.php:136 +#: includes/fields/class-acf-field-number.php:145 +#: includes/fields/class-acf-field-password.php:80 +#: includes/fields/class-acf-field-range.php:194 +#: includes/fields/class-acf-field-text.php:113 msgid "Prepend" msgstr "Lägg till före" -#: includes/fields/class-acf-field-email.php:152 -#: includes/fields/class-acf-field-number.php:164 -#: includes/fields/class-acf-field-password.php:144 -#: includes/fields/class-acf-field-text.php:161 +#: includes/fields/class-acf-field-email.php:137 +#: includes/fields/class-acf-field-number.php:146 +#: includes/fields/class-acf-field-password.php:81 +#: includes/fields/class-acf-field-range.php:195 +#: includes/fields/class-acf-field-text.php:114 msgid "Appears before the input" msgstr "Visas före fältet" -#: includes/fields/class-acf-field-email.php:160 -#: includes/fields/class-acf-field-number.php:172 -#: includes/fields/class-acf-field-password.php:152 -#: includes/fields/class-acf-field-text.php:169 +#: includes/fields/class-acf-field-email.php:145 +#: includes/fields/class-acf-field-number.php:154 +#: includes/fields/class-acf-field-password.php:89 +#: includes/fields/class-acf-field-range.php:203 +#: includes/fields/class-acf-field-text.php:122 msgid "Append" msgstr "Lägg till efter" -#: includes/fields/class-acf-field-email.php:161 -#: includes/fields/class-acf-field-number.php:173 -#: includes/fields/class-acf-field-password.php:153 -#: includes/fields/class-acf-field-text.php:170 +#: includes/fields/class-acf-field-email.php:146 +#: includes/fields/class-acf-field-number.php:155 +#: includes/fields/class-acf-field-password.php:90 +#: includes/fields/class-acf-field-range.php:204 +#: includes/fields/class-acf-field-text.php:123 msgid "Appears after the input" msgstr "Visas efter fältet" -#: includes/fields/class-acf-field-file.php:36 +#: includes/fields/class-acf-field-email.php:167 +#, php-format +msgid "'%s' is not a valid email address" +msgstr "\"%s\" är inte en giltig e-postadress" + +#: includes/fields/class-acf-field-file.php:25 msgid "File" msgstr "Fil" -#: includes/fields/class-acf-field-file.php:47 +#: includes/fields/class-acf-field-file.php:58 msgid "Edit File" msgstr "Redigera fil" -#: includes/fields/class-acf-field-file.php:48 +#: includes/fields/class-acf-field-file.php:59 msgid "Update File" msgstr "Uppdatera fil" -#: includes/fields/class-acf-field-file.php:49 -#: includes/fields/class-acf-field-image.php:54 includes/media.php:57 -#: pro/fields/class-acf-field-gallery.php:55 -msgid "Uploaded to this post" -msgstr "Uppladdade till detta inlägg" - -#: includes/fields/class-acf-field-file.php:145 +#: includes/fields/class-acf-field-file.php:141 msgid "File name" msgstr "Filnamn" -#: includes/fields/class-acf-field-file.php:149 -#: includes/fields/class-acf-field-file.php:252 -#: includes/fields/class-acf-field-file.php:263 -#: includes/fields/class-acf-field-image.php:266 -#: includes/fields/class-acf-field-image.php:295 -#: pro/fields/class-acf-field-gallery.php:705 -#: pro/fields/class-acf-field-gallery.php:734 +#: includes/fields/class-acf-field-file.php:145 +#: includes/fields/class-acf-field-file.php:247 +#: includes/fields/class-acf-field-file.php:258 +#: includes/fields/class-acf-field-image.php:254 +#: includes/fields/class-acf-field-image.php:283 +#: pro/fields/class-acf-field-gallery.php:639 +#: pro/fields/class-acf-field-gallery.php:668 msgid "File size" msgstr "Filstorlek" -#: includes/fields/class-acf-field-file.php:174 +#: includes/fields/class-acf-field-file.php:169 msgid "Add File" msgstr "Lägg till fil" -#: includes/fields/class-acf-field-file.php:225 +#: includes/fields/class-acf-field-file.php:220 msgid "File Array" -msgstr "Fil array" +msgstr "Fil-array" -#: includes/fields/class-acf-field-file.php:226 +#: includes/fields/class-acf-field-file.php:221 msgid "File URL" -msgstr "Filadress" +msgstr "Fil-URL" -#: includes/fields/class-acf-field-file.php:227 +#: includes/fields/class-acf-field-file.php:222 msgid "File ID" msgstr "Filens ID" -#: includes/fields/class-acf-field-file.php:234 -#: includes/fields/class-acf-field-image.php:231 -#: pro/fields/class-acf-field-gallery.php:670 +#: includes/fields/class-acf-field-file.php:229 +#: includes/fields/class-acf-field-image.php:219 +#: pro/fields/class-acf-field-gallery.php:589 msgid "Library" msgstr "Bibliotek" -#: includes/fields/class-acf-field-file.php:235 -#: includes/fields/class-acf-field-image.php:232 -#: pro/fields/class-acf-field-gallery.php:671 +#: includes/fields/class-acf-field-file.php:230 +#: includes/fields/class-acf-field-image.php:220 +#: pro/fields/class-acf-field-gallery.php:590 msgid "Limit the media library choice" msgstr "Begränsa urvalet i mediabiblioteket" -#: includes/fields/class-acf-field-file.php:240 -#: includes/fields/class-acf-field-image.php:237 -#: includes/locations/class-acf-location-attachment.php:105 -#: includes/locations/class-acf-location-comment.php:83 -#: includes/locations/class-acf-location-nav-menu.php:106 -#: includes/locations/class-acf-location-taxonomy.php:83 -#: includes/locations/class-acf-location-user-form.php:91 -#: includes/locations/class-acf-location-user-role.php:108 -#: includes/locations/class-acf-location-widget.php:87 -#: pro/fields/class-acf-field-gallery.php:676 +#: includes/fields/class-acf-field-file.php:235 +#: includes/fields/class-acf-field-image.php:225 +#: includes/locations/class-acf-location-attachment.php:71 +#: includes/locations/class-acf-location-comment.php:59 +#: includes/locations/class-acf-location-nav-menu.php:72 +#: includes/locations/class-acf-location-taxonomy.php:61 +#: includes/locations/class-acf-location-user-form.php:65 +#: includes/locations/class-acf-location-user-role.php:76 +#: includes/locations/class-acf-location-widget.php:63 +#: pro/fields/class-acf-field-gallery.php:595 +#: pro/locations/class-acf-location-block.php:64 msgid "All" msgstr "Alla" -#: includes/fields/class-acf-field-file.php:241 -#: includes/fields/class-acf-field-image.php:238 -#: pro/fields/class-acf-field-gallery.php:677 +#: includes/fields/class-acf-field-file.php:236 +#: includes/fields/class-acf-field-image.php:226 +#: pro/fields/class-acf-field-gallery.php:596 msgid "Uploaded to post" msgstr "Uppladdade till detta inlägg" -#: includes/fields/class-acf-field-file.php:248 -#: includes/fields/class-acf-field-image.php:245 -#: pro/fields/class-acf-field-gallery.php:684 +#: includes/fields/class-acf-field-file.php:243 +#: includes/fields/class-acf-field-image.php:233 +#: pro/fields/class-acf-field-gallery.php:618 msgid "Minimum" msgstr "Minimalt" -#: includes/fields/class-acf-field-file.php:249 -#: includes/fields/class-acf-field-file.php:260 +#: includes/fields/class-acf-field-file.php:244 +#: includes/fields/class-acf-field-file.php:255 msgid "Restrict which files can be uploaded" msgstr "Begränsa vilka filer som kan laddas upp" -#: includes/fields/class-acf-field-file.php:259 -#: includes/fields/class-acf-field-image.php:274 -#: pro/fields/class-acf-field-gallery.php:713 +#: includes/fields/class-acf-field-file.php:254 +#: includes/fields/class-acf-field-image.php:262 +#: pro/fields/class-acf-field-gallery.php:647 msgid "Maximum" msgstr "Maximalt" -#: includes/fields/class-acf-field-file.php:270 -#: includes/fields/class-acf-field-image.php:303 -#: pro/fields/class-acf-field-gallery.php:742 +#: includes/fields/class-acf-field-file.php:265 +#: includes/fields/class-acf-field-image.php:291 +#: pro/fields/class-acf-field-gallery.php:675 msgid "Allowed file types" msgstr "Tillåtna filtyper" -#: includes/fields/class-acf-field-file.php:271 -#: includes/fields/class-acf-field-image.php:304 -#: pro/fields/class-acf-field-gallery.php:743 +#: includes/fields/class-acf-field-file.php:266 +#: includes/fields/class-acf-field-image.php:292 +#: pro/fields/class-acf-field-gallery.php:676 msgid "Comma separated list. Leave blank for all types" msgstr "Kommaseparerad lista. Lämna blankt för alla typer" -#: includes/fields/class-acf-field-google-map.php:36 +#: includes/fields/class-acf-field-google-map.php:25 msgid "Google Map" -msgstr "Google Map" +msgstr "Google-karta" -#: includes/fields/class-acf-field-google-map.php:51 -msgid "Locating" -msgstr "Söker plats" - -#: includes/fields/class-acf-field-google-map.php:52 +#: includes/fields/class-acf-field-google-map.php:59 msgid "Sorry, this browser does not support geolocation" -msgstr "Tyvärr saknar denna webbläsare stöd för platsinformation" +msgstr "Denna webbläsare saknar stöd för platsinformation" -#: includes/fields/class-acf-field-google-map.php:133 +#: includes/fields/class-acf-field-google-map.php:146 +#: includes/fields/class-acf-field-relationship.php:587 +msgid "Search" +msgstr "Sök" + +#: includes/fields/class-acf-field-google-map.php:147 msgid "Clear location" msgstr "Rensa plats" -#: includes/fields/class-acf-field-google-map.php:134 +#: includes/fields/class-acf-field-google-map.php:148 msgid "Find current location" msgstr "Hitta nuvarande plats" -#: includes/fields/class-acf-field-google-map.php:137 +#: includes/fields/class-acf-field-google-map.php:151 msgid "Search for address..." msgstr "Sök efter adress..." -#: includes/fields/class-acf-field-google-map.php:167 -#: includes/fields/class-acf-field-google-map.php:178 +#: includes/fields/class-acf-field-google-map.php:181 +#: includes/fields/class-acf-field-google-map.php:192 msgid "Center" msgstr "Centrera" -#: includes/fields/class-acf-field-google-map.php:168 -#: includes/fields/class-acf-field-google-map.php:179 +#: includes/fields/class-acf-field-google-map.php:182 +#: includes/fields/class-acf-field-google-map.php:193 msgid "Center the initial map" msgstr "Kartans initiala centrum" -#: includes/fields/class-acf-field-google-map.php:190 +#: includes/fields/class-acf-field-google-map.php:204 msgid "Zoom" msgstr "Zoom" -#: includes/fields/class-acf-field-google-map.php:191 +#: includes/fields/class-acf-field-google-map.php:205 msgid "Set the initial zoom level" -msgstr "Ange kartans initiala zoom nivå" +msgstr "Ange kartans initiala zoom-nivå" -#: includes/fields/class-acf-field-google-map.php:200 -#: includes/fields/class-acf-field-image.php:257 -#: includes/fields/class-acf-field-image.php:286 -#: includes/fields/class-acf-field-oembed.php:297 -#: pro/fields/class-acf-field-gallery.php:696 -#: pro/fields/class-acf-field-gallery.php:725 +#: includes/fields/class-acf-field-google-map.php:214 +#: includes/fields/class-acf-field-image.php:245 +#: includes/fields/class-acf-field-image.php:274 +#: includes/fields/class-acf-field-oembed.php:268 +#: pro/fields/class-acf-field-gallery.php:630 +#: pro/fields/class-acf-field-gallery.php:659 msgid "Height" msgstr "Höjd" -#: includes/fields/class-acf-field-google-map.php:201 -msgid "Customise the map height" +#: includes/fields/class-acf-field-google-map.php:215 +msgid "Customize the map height" msgstr "Ställ in kartans höjd" -#: includes/fields/class-acf-field-group.php:36 -#, fuzzy +#: includes/fields/class-acf-field-group.php:25 msgid "Group" -msgstr "Fältgrupp" +msgstr "Grupp" -#: includes/fields/class-acf-field-group.php:469 -#: pro/fields/class-acf-field-repeater.php:453 +#: includes/fields/class-acf-field-group.php:459 +#: pro/fields/class-acf-field-repeater.php:380 msgid "Sub Fields" msgstr "Underfält" -#: includes/fields/class-acf-field-group.php:486 -#: pro/fields/class-acf-field-clone.php:890 +#: includes/fields/class-acf-field-group.php:475 +#: pro/fields/class-acf-field-clone.php:832 msgid "Specify the style used to render the selected fields" msgstr "Specificera stilen för att rendera valda fält" -#: includes/fields/class-acf-field-group.php:491 -#: pro/fields/class-acf-field-clone.php:895 -#: pro/fields/class-acf-field-flexible-content.php:629 -#: pro/fields/class-acf-field-repeater.php:522 +#: includes/fields/class-acf-field-group.php:480 +#: pro/fields/class-acf-field-clone.php:837 +#: pro/fields/class-acf-field-flexible-content.php:610 +#: pro/fields/class-acf-field-repeater.php:452 +#: pro/locations/class-acf-location-block.php:20 msgid "Block" msgstr "Block" -#: includes/fields/class-acf-field-group.php:492 -#: pro/fields/class-acf-field-clone.php:896 -#: pro/fields/class-acf-field-flexible-content.php:628 -#: pro/fields/class-acf-field-repeater.php:521 +#: includes/fields/class-acf-field-group.php:481 +#: pro/fields/class-acf-field-clone.php:838 +#: pro/fields/class-acf-field-flexible-content.php:609 +#: pro/fields/class-acf-field-repeater.php:451 msgid "Table" msgstr "Tabell" -#: includes/fields/class-acf-field-group.php:493 -#: pro/fields/class-acf-field-clone.php:897 -#: pro/fields/class-acf-field-flexible-content.php:630 -#: pro/fields/class-acf-field-repeater.php:523 +#: includes/fields/class-acf-field-group.php:482 +#: pro/fields/class-acf-field-clone.php:839 +#: pro/fields/class-acf-field-flexible-content.php:611 +#: pro/fields/class-acf-field-repeater.php:453 msgid "Row" msgstr "Rad" -#: includes/fields/class-acf-field-image.php:36 +#: includes/fields/class-acf-field-image.php:25 msgid "Image" msgstr "Bild" -#: includes/fields/class-acf-field-image.php:51 +#: includes/fields/class-acf-field-image.php:63 msgid "Select Image" msgstr "Välj bild" -#: includes/fields/class-acf-field-image.php:52 -#: pro/fields/class-acf-field-gallery.php:53 +#: includes/fields/class-acf-field-image.php:64 msgid "Edit Image" msgstr "Redigera bild" -#: includes/fields/class-acf-field-image.php:53 -#: pro/fields/class-acf-field-gallery.php:54 +#: includes/fields/class-acf-field-image.php:65 msgid "Update Image" msgstr "Uppdatera bild" -#: includes/fields/class-acf-field-image.php:55 +#: includes/fields/class-acf-field-image.php:66 includes/media.php:61 msgid "All images" msgstr "Alla bilder" -#: includes/fields/class-acf-field-image.php:142 -#: includes/fields/class-acf-field-link.php:153 includes/input.php:267 -#: pro/fields/class-acf-field-gallery.php:358 -#: pro/fields/class-acf-field-gallery.php:546 -msgid "Remove" -msgstr "Radera" - -#: includes/fields/class-acf-field-image.php:158 +#: includes/fields/class-acf-field-image.php:148 msgid "No image selected" msgstr "Ingen bild vald" -#: includes/fields/class-acf-field-image.php:158 +#: includes/fields/class-acf-field-image.php:148 msgid "Add Image" msgstr "Lägg till bild" -#: includes/fields/class-acf-field-image.php:212 +#: includes/fields/class-acf-field-image.php:200 +#: pro/fields/class-acf-field-gallery.php:560 msgid "Image Array" -msgstr "Bild Array" +msgstr "Bild-array" -#: includes/fields/class-acf-field-image.php:213 +#: includes/fields/class-acf-field-image.php:201 +#: pro/fields/class-acf-field-gallery.php:561 msgid "Image URL" -msgstr "Bildadress" +msgstr "Bild-URL" -#: includes/fields/class-acf-field-image.php:214 +#: includes/fields/class-acf-field-image.php:202 +#: pro/fields/class-acf-field-gallery.php:562 msgid "Image ID" msgstr "Bildens ID" -#: includes/fields/class-acf-field-image.php:221 +#: includes/fields/class-acf-field-image.php:209 +#: pro/fields/class-acf-field-gallery.php:568 msgid "Preview Size" msgstr "Förhandsvisningens storlek" -#: includes/fields/class-acf-field-image.php:222 -msgid "Shown when entering data" -msgstr "Visas vid inmatning av data" - -#: includes/fields/class-acf-field-image.php:246 -#: includes/fields/class-acf-field-image.php:275 -#: pro/fields/class-acf-field-gallery.php:685 -#: pro/fields/class-acf-field-gallery.php:714 +#: includes/fields/class-acf-field-image.php:234 +#: includes/fields/class-acf-field-image.php:263 +#: pro/fields/class-acf-field-gallery.php:619 +#: pro/fields/class-acf-field-gallery.php:648 msgid "Restrict which images can be uploaded" msgstr "Begränsa vilka bilder som kan laddas upp" -#: includes/fields/class-acf-field-image.php:249 -#: includes/fields/class-acf-field-image.php:278 -#: includes/fields/class-acf-field-oembed.php:286 -#: pro/fields/class-acf-field-gallery.php:688 -#: pro/fields/class-acf-field-gallery.php:717 +#: includes/fields/class-acf-field-image.php:237 +#: includes/fields/class-acf-field-image.php:266 +#: includes/fields/class-acf-field-oembed.php:257 +#: pro/fields/class-acf-field-gallery.php:622 +#: pro/fields/class-acf-field-gallery.php:651 msgid "Width" -msgstr "bredd" +msgstr "Bredd" -#: includes/fields/class-acf-field-link.php:36 -#, fuzzy +#: includes/fields/class-acf-field-link.php:25 msgid "Link" -msgstr "Sidlänk" +msgstr "Länk" -#: includes/fields/class-acf-field-link.php:146 -#, fuzzy +#: includes/fields/class-acf-field-link.php:133 msgid "Select Link" -msgstr "Välj fil" +msgstr "Välj länk" -#: includes/fields/class-acf-field-link.php:151 +#: includes/fields/class-acf-field-link.php:138 msgid "Opens in a new window/tab" -msgstr "" +msgstr "Öppnas i ett nytt fönster/flik" -#: includes/fields/class-acf-field-link.php:186 -#, fuzzy +#: includes/fields/class-acf-field-link.php:172 msgid "Link Array" -msgstr "Fil array" +msgstr "Länk-array" -#: includes/fields/class-acf-field-link.php:187 -#, fuzzy +#: includes/fields/class-acf-field-link.php:173 msgid "Link URL" -msgstr "Filadress" +msgstr "Länk-URL" -#: includes/fields/class-acf-field-message.php:36 -#: includes/fields/class-acf-field-message.php:115 -#: includes/fields/class-acf-field-true_false.php:141 +#: includes/fields/class-acf-field-message.php:25 +#: includes/fields/class-acf-field-message.php:101 +#: includes/fields/class-acf-field-true_false.php:126 msgid "Message" msgstr "Meddelande" -#: includes/fields/class-acf-field-message.php:124 -#: includes/fields/class-acf-field-textarea.php:176 +#: includes/fields/class-acf-field-message.php:110 +#: includes/fields/class-acf-field-textarea.php:139 msgid "New Lines" -msgstr "Nya linjer" +msgstr "Nya rader" -#: includes/fields/class-acf-field-message.php:125 -#: includes/fields/class-acf-field-textarea.php:177 +#: includes/fields/class-acf-field-message.php:111 +#: includes/fields/class-acf-field-textarea.php:140 msgid "Controls how new lines are rendered" -msgstr "Reglerar hur nya linjer renderas" +msgstr "Reglerar hur nya rader renderas" -#: includes/fields/class-acf-field-message.php:129 -#: includes/fields/class-acf-field-textarea.php:181 +#: includes/fields/class-acf-field-message.php:115 +#: includes/fields/class-acf-field-textarea.php:144 msgid "Automatically add paragraphs" -msgstr "Lägg till styckesindelning automatiskt." +msgstr "Lägg till styckesindelning automatiskt" -#: includes/fields/class-acf-field-message.php:130 -#: includes/fields/class-acf-field-textarea.php:182 +#: includes/fields/class-acf-field-message.php:116 +#: includes/fields/class-acf-field-textarea.php:145 msgid "Automatically add <br>" msgstr "Lägg till automatiskt <br>" -#: includes/fields/class-acf-field-message.php:131 -#: includes/fields/class-acf-field-textarea.php:183 +#: includes/fields/class-acf-field-message.php:117 +#: includes/fields/class-acf-field-textarea.php:146 msgid "No Formatting" msgstr "Ingen formattering" -#: includes/fields/class-acf-field-message.php:138 +#: includes/fields/class-acf-field-message.php:124 msgid "Escape HTML" msgstr "Inaktivera HTML-rendering" -#: includes/fields/class-acf-field-message.php:139 +#: includes/fields/class-acf-field-message.php:125 msgid "Allow HTML markup to display as visible text instead of rendering" -msgstr "Tillåt HTML kod att visas som synlig text istället för att renderas" +msgstr "Tillåt HTML-kod att visas som synlig text istället för att renderas" -#: includes/fields/class-acf-field-number.php:36 +#: includes/fields/class-acf-field-number.php:25 msgid "Number" msgstr "Nummer" -#: includes/fields/class-acf-field-number.php:181 +#: includes/fields/class-acf-field-number.php:163 +#: includes/fields/class-acf-field-range.php:164 msgid "Minimum Value" msgstr "Minsta värde" -#: includes/fields/class-acf-field-number.php:190 +#: includes/fields/class-acf-field-number.php:172 +#: includes/fields/class-acf-field-range.php:174 msgid "Maximum Value" msgstr "Högsta värde" -#: includes/fields/class-acf-field-number.php:199 +#: includes/fields/class-acf-field-number.php:181 +#: includes/fields/class-acf-field-range.php:184 msgid "Step Size" msgstr "Stegvärde" -#: includes/fields/class-acf-field-number.php:237 +#: includes/fields/class-acf-field-number.php:219 msgid "Value must be a number" msgstr "Värdet måste vara ett nummer" -#: includes/fields/class-acf-field-number.php:255 +#: includes/fields/class-acf-field-number.php:237 #, php-format msgid "Value must be equal to or higher than %d" msgstr "Värdet måste vara lika med eller högre än %d" -#: includes/fields/class-acf-field-number.php:263 +#: includes/fields/class-acf-field-number.php:245 #, php-format msgid "Value must be equal to or lower than %d" msgstr "Värdet måste vara lika med eller lägre än %d" -#: includes/fields/class-acf-field-oembed.php:36 +#: includes/fields/class-acf-field-oembed.php:25 msgid "oEmbed" msgstr "oEmbed" -#: includes/fields/class-acf-field-oembed.php:237 +#: includes/fields/class-acf-field-oembed.php:216 msgid "Enter URL" msgstr "Fyll i URL" -#: includes/fields/class-acf-field-oembed.php:250 -#: includes/fields/class-acf-field-taxonomy.php:904 -msgid "Error." -msgstr "Fel." - -#: includes/fields/class-acf-field-oembed.php:250 -msgid "No embed found for the given URL." -msgstr "Ingen embed hittades för angiven URL." - -#: includes/fields/class-acf-field-oembed.php:283 -#: includes/fields/class-acf-field-oembed.php:294 +#: includes/fields/class-acf-field-oembed.php:254 +#: includes/fields/class-acf-field-oembed.php:265 msgid "Embed Size" -msgstr "Embed storlek" +msgstr "Embed-storlek" -#: includes/fields/class-acf-field-page_link.php:192 +#: includes/fields/class-acf-field-page_link.php:25 +msgid "Page Link" +msgstr "Sidlänk" + +#: includes/fields/class-acf-field-page_link.php:170 msgid "Archives" msgstr "Arkiv" -#: includes/fields/class-acf-field-page_link.php:500 -#: includes/fields/class-acf-field-post_object.php:399 -#: includes/fields/class-acf-field-relationship.php:704 +#: includes/fields/class-acf-field-page_link.php:262 +#: includes/fields/class-acf-field-post_object.php:267 +#: includes/fields/class-acf-field-taxonomy.php:948 +msgid "Parent" +msgstr "Överordnad" + +#: includes/fields/class-acf-field-page_link.php:478 +#: includes/fields/class-acf-field-post_object.php:383 +#: includes/fields/class-acf-field-relationship.php:554 msgid "Filter by Post Type" msgstr "Filtrera efter inläggstyp" -#: includes/fields/class-acf-field-page_link.php:508 -#: includes/fields/class-acf-field-post_object.php:407 -#: includes/fields/class-acf-field-relationship.php:712 +#: includes/fields/class-acf-field-page_link.php:486 +#: includes/fields/class-acf-field-post_object.php:391 +#: includes/fields/class-acf-field-relationship.php:562 msgid "All post types" -msgstr "Samtliga posttyper" +msgstr "Alla inläggstyper" -#: includes/fields/class-acf-field-page_link.php:514 -#: includes/fields/class-acf-field-post_object.php:413 -#: includes/fields/class-acf-field-relationship.php:718 +#: includes/fields/class-acf-field-page_link.php:492 +#: includes/fields/class-acf-field-post_object.php:397 +#: includes/fields/class-acf-field-relationship.php:568 msgid "Filter by Taxonomy" msgstr "Filtrera efter taxonomi" -#: includes/fields/class-acf-field-page_link.php:522 -#: includes/fields/class-acf-field-post_object.php:421 -#: includes/fields/class-acf-field-relationship.php:726 +#: includes/fields/class-acf-field-page_link.php:500 +#: includes/fields/class-acf-field-post_object.php:405 +#: includes/fields/class-acf-field-relationship.php:576 msgid "All taxonomies" -msgstr "Samtliga taxonomier" +msgstr "Alla taxonomier" -#: includes/fields/class-acf-field-page_link.php:528 -#: includes/fields/class-acf-field-post_object.php:427 -#: includes/fields/class-acf-field-radio.php:259 -#: includes/fields/class-acf-field-select.php:484 -#: includes/fields/class-acf-field-taxonomy.php:799 -#: includes/fields/class-acf-field-user.php:423 -msgid "Allow Null?" -msgstr "Tillått nollvärde?" - -#: includes/fields/class-acf-field-page_link.php:538 +#: includes/fields/class-acf-field-page_link.php:516 msgid "Allow Archives URLs" -msgstr "Tillåt urler från arkiv" +msgstr "Tillåt arkiv-URL:er" -#: includes/fields/class-acf-field-page_link.php:548 -#: includes/fields/class-acf-field-post_object.php:437 -#: includes/fields/class-acf-field-select.php:494 -#: includes/fields/class-acf-field-user.php:433 +#: includes/fields/class-acf-field-page_link.php:526 +#: includes/fields/class-acf-field-post_object.php:421 +#: includes/fields/class-acf-field-select.php:392 +#: includes/fields/class-acf-field-user.php:71 msgid "Select multiple values?" -msgstr "Välj multipla värden?" +msgstr "Välj flera värden?" -#: includes/fields/class-acf-field-password.php:36 +#: includes/fields/class-acf-field-password.php:25 msgid "Password" msgstr "Lösenord" -#: includes/fields/class-acf-field-post_object.php:36 -#: includes/fields/class-acf-field-post_object.php:452 -#: includes/fields/class-acf-field-relationship.php:783 +#: includes/fields/class-acf-field-post_object.php:25 +#: includes/fields/class-acf-field-post_object.php:436 +#: includes/fields/class-acf-field-relationship.php:633 msgid "Post Object" msgstr "Inläggsobjekt" -#: includes/fields/class-acf-field-post_object.php:453 -#: includes/fields/class-acf-field-relationship.php:784 +#: includes/fields/class-acf-field-post_object.php:437 +#: includes/fields/class-acf-field-relationship.php:634 msgid "Post ID" -msgstr "Inläggets ID" +msgstr "Inläggs-ID" -#: includes/fields/class-acf-field-radio.php:36 +#: includes/fields/class-acf-field-radio.php:25 msgid "Radio Button" msgstr "Alternativknapp" -#: includes/fields/class-acf-field-radio.php:269 +#: includes/fields/class-acf-field-radio.php:211 msgid "Other" msgstr "Annat" -#: includes/fields/class-acf-field-radio.php:274 +#: includes/fields/class-acf-field-radio.php:216 msgid "Add 'other' choice to allow for custom values" msgstr "Lägg till värdet 'annat' för att tillåta egna värden" -#: includes/fields/class-acf-field-radio.php:280 +#: includes/fields/class-acf-field-radio.php:222 msgid "Save Other" msgstr "Spara annat" -#: includes/fields/class-acf-field-radio.php:285 +#: includes/fields/class-acf-field-radio.php:227 msgid "Save 'other' values to the field's choices" msgstr "Spara 'annat'-värden till fältets alternativ" -#: includes/fields/class-acf-field-relationship.php:36 +#: includes/fields/class-acf-field-range.php:25 +msgid "Range" +msgstr "Intervall" + +#: includes/fields/class-acf-field-relationship.php:25 msgid "Relationship" msgstr "Relation" -#: includes/fields/class-acf-field-relationship.php:48 -msgid "Minimum values reached ( {min} values )" -msgstr "Lägsta tillåtna antal värden nått ( {min} värden )" - -#: includes/fields/class-acf-field-relationship.php:49 +#: includes/fields/class-acf-field-relationship.php:62 msgid "Maximum values reached ( {max} values )" msgstr "Högsta tillåtna antal värden uppnått ( {max} värden )" -#: includes/fields/class-acf-field-relationship.php:50 +#: includes/fields/class-acf-field-relationship.php:63 msgid "Loading" msgstr "Laddar" -#: includes/fields/class-acf-field-relationship.php:51 +#: includes/fields/class-acf-field-relationship.php:64 msgid "No matches found" msgstr "Inga träffar" -#: includes/fields/class-acf-field-relationship.php:585 -msgid "Search..." -msgstr "Sök..." - -#: includes/fields/class-acf-field-relationship.php:594 +#: includes/fields/class-acf-field-relationship.php:411 msgid "Select post type" -msgstr "Välj posttyp" +msgstr "Välj inläggstyp" -#: includes/fields/class-acf-field-relationship.php:607 +#: includes/fields/class-acf-field-relationship.php:420 msgid "Select taxonomy" msgstr "Välj taxonomi" -#: includes/fields/class-acf-field-relationship.php:732 +#: includes/fields/class-acf-field-relationship.php:476 +msgid "Search..." +msgstr "Sök..." + +#: includes/fields/class-acf-field-relationship.php:582 msgid "Filters" msgstr "Filter" -#: includes/fields/class-acf-field-relationship.php:738 -#: includes/locations/class-acf-location-post-type.php:27 +#: includes/fields/class-acf-field-relationship.php:588 +#: includes/locations/class-acf-location-post-type.php:20 msgid "Post Type" msgstr "Inläggstyp" -#: includes/fields/class-acf-field-relationship.php:739 -#: includes/fields/class-acf-field-taxonomy.php:36 -#: includes/fields/class-acf-field-taxonomy.php:769 +#: includes/fields/class-acf-field-relationship.php:589 +#: includes/fields/class-acf-field-taxonomy.php:28 +#: includes/fields/class-acf-field-taxonomy.php:741 +#: includes/locations/class-acf-location-taxonomy.php:20 msgid "Taxonomy" msgstr "Taxonomi" -#: includes/fields/class-acf-field-relationship.php:746 +#: includes/fields/class-acf-field-relationship.php:596 msgid "Elements" msgstr "Element" -#: includes/fields/class-acf-field-relationship.php:747 +#: includes/fields/class-acf-field-relationship.php:597 msgid "Selected elements will be displayed in each result" msgstr "Valda element visas i varje resultat" -#: includes/fields/class-acf-field-relationship.php:758 +#: includes/fields/class-acf-field-relationship.php:608 msgid "Minimum posts" msgstr "Minsta antal inlägg" -#: includes/fields/class-acf-field-relationship.php:767 +#: includes/fields/class-acf-field-relationship.php:617 msgid "Maximum posts" msgstr "Högsta antal inlägg" -#: includes/fields/class-acf-field-relationship.php:871 -#: pro/fields/class-acf-field-gallery.php:815 +#: includes/fields/class-acf-field-relationship.php:721 +#: pro/fields/class-acf-field-gallery.php:776 #, php-format msgid "%s requires at least %s selection" msgid_plural "%s requires at least %s selections" msgstr[0] "%s kräver minst %s val" msgstr[1] "%s kräver minst %s val" -#: includes/fields/class-acf-field-select.php:36 -#: includes/fields/class-acf-field-taxonomy.php:791 +#: includes/fields/class-acf-field-select.php:25 +#: includes/fields/class-acf-field-taxonomy.php:763 msgctxt "noun" msgid "Select" msgstr "Flerväljare" -#: includes/fields/class-acf-field-select.php:49 +#: includes/fields/class-acf-field-select.php:111 msgctxt "Select2 JS matches_1" msgid "One result is available, press enter to select it." msgstr "Ett resultat, tryck enter för att välja det." -#: includes/fields/class-acf-field-select.php:50 +#: includes/fields/class-acf-field-select.php:112 #, php-format msgctxt "Select2 JS matches_n" msgid "%d results are available, use up and down arrow keys to navigate." msgstr "%d resultat, använd upp och ned pilarna för att navigera." -#: includes/fields/class-acf-field-select.php:51 +#: includes/fields/class-acf-field-select.php:113 msgctxt "Select2 JS matches_0" msgid "No matches found" msgstr "Inget resultat" -#: includes/fields/class-acf-field-select.php:52 +#: includes/fields/class-acf-field-select.php:114 msgctxt "Select2 JS input_too_short_1" msgid "Please enter 1 or more characters" -msgstr "Vänligen skriv in 1 eller fler bokstäver" +msgstr "Skriv in 1 eller fler tecken" -#: includes/fields/class-acf-field-select.php:53 +#: includes/fields/class-acf-field-select.php:115 #, php-format msgctxt "Select2 JS input_too_short_n" msgid "Please enter %d or more characters" -msgstr "Vänligen skriv in %d eller fler bokstäver" +msgstr "Skriv in %d eller fler tecken" -#: includes/fields/class-acf-field-select.php:54 +#: includes/fields/class-acf-field-select.php:116 msgctxt "Select2 JS input_too_long_1" msgid "Please delete 1 character" -msgstr "Vänligen radera 1 bokstav" +msgstr "Ta bort 1 tecken" -#: includes/fields/class-acf-field-select.php:55 +#: includes/fields/class-acf-field-select.php:117 #, php-format msgctxt "Select2 JS input_too_long_n" msgid "Please delete %d characters" -msgstr "Vänligen radera %d bokstäver" +msgstr "Ta bort %d tecken" -#: includes/fields/class-acf-field-select.php:56 +#: includes/fields/class-acf-field-select.php:118 msgctxt "Select2 JS selection_too_long_1" msgid "You can only select 1 item" msgstr "Du kan bara välja 1 resultat" -#: includes/fields/class-acf-field-select.php:57 +#: includes/fields/class-acf-field-select.php:119 #, php-format msgctxt "Select2 JS selection_too_long_n" msgid "You can only select %d items" msgstr "Du kan bara välja %d resultat" -#: includes/fields/class-acf-field-select.php:58 +#: includes/fields/class-acf-field-select.php:120 msgctxt "Select2 JS load_more" msgid "Loading more results…" -msgstr "Laddar fler resultat" +msgstr "Laddar fler resultat …" -#: includes/fields/class-acf-field-select.php:59 +#: includes/fields/class-acf-field-select.php:121 msgctxt "Select2 JS searching" msgid "Searching…" -msgstr "Söker…" +msgstr "Söker …" -#: includes/fields/class-acf-field-select.php:60 +#: includes/fields/class-acf-field-select.php:122 msgctxt "Select2 JS load_fail" msgid "Loading failed" msgstr "Laddning misslyckades" -#: includes/fields/class-acf-field-select.php:270 includes/media.php:54 +#: includes/fields/class-acf-field-select.php:259 includes/media.php:54 msgctxt "verb" msgid "Select" msgstr "Välj" -#: includes/fields/class-acf-field-select.php:504 -#: includes/fields/class-acf-field-true_false.php:159 +#: includes/fields/class-acf-field-select.php:402 +#: includes/fields/class-acf-field-true_false.php:144 msgid "Stylised UI" msgstr "Stylat utseende" -#: includes/fields/class-acf-field-select.php:514 +#: includes/fields/class-acf-field-select.php:412 msgid "Use AJAX to lazy load choices?" msgstr "Använda AJAX för att ladda alternativ efter att sidan laddats?" -#: includes/fields/class-acf-field-select.php:525 +#: includes/fields/class-acf-field-select.php:428 msgid "Specify the value returned" msgstr "Specificera värdet att returnera" -#: includes/fields/class-acf-field-separator.php:36 +#: includes/fields/class-acf-field-separator.php:25 msgid "Separator" -msgstr "" +msgstr "Avgränsare" -#: includes/fields/class-acf-field-tab.php:36 +#: includes/fields/class-acf-field-tab.php:25 msgid "Tab" msgstr "Flik" -#: includes/fields/class-acf-field-tab.php:96 -msgid "" -"The tab field will display incorrectly when added to a Table style repeater " -"field or flexible content field layout" -msgstr "" -"Flik fältet kommer att visas felaktigt om de läggs till ett upprepningsfält " -"med tabellutseende eller ett innehållsfält med flexibel layout" - -#: includes/fields/class-acf-field-tab.php:97 -msgid "" -"Use \"Tab Fields\" to better organize your edit screen by grouping fields " -"together." -msgstr "" -"Använd \"Flikfält\" för att bättre organisera din redigeringsvy genom att " -"gruppera fälten tillsammans." - -#: includes/fields/class-acf-field-tab.php:98 -msgid "" -"All fields following this \"tab field\" (or until another \"tab field\" is " -"defined) will be grouped together using this field's label as the tab " -"heading." -msgstr "" -"Alla fält efter detta \"flikfält\" (eller fram till nästa \"flikfält\") " -"kommer att grupperas tillsammans genom fältets titel som flikrubrik." - -#: includes/fields/class-acf-field-tab.php:112 +#: includes/fields/class-acf-field-tab.php:102 msgid "Placement" msgstr "Placering" -#: includes/fields/class-acf-field-tab.php:124 -msgid "End-point" -msgstr "Slutpunkt" +#: includes/fields/class-acf-field-tab.php:115 +msgid "" +"Define an endpoint for the previous tabs to stop. This will start a new " +"group of tabs." +msgstr "" +"Definiera en ändpunkt där de föregående flikarna att stoppas. Detta kommer " +"starta en ny grupp med flikar." -#: includes/fields/class-acf-field-tab.php:125 -msgid "Use this field as an end-point and start a new group of tabs" -msgstr "Använd detta fält som slutpunkt och starta en ny grupp flikar" +#: includes/fields/class-acf-field-taxonomy.php:701 +#, php-format +msgctxt "No terms" +msgid "No %s" +msgstr "Inga %s" -#: includes/fields/class-acf-field-taxonomy.php:719 -#: includes/fields/class-acf-field-true_false.php:95 -#: includes/fields/class-acf-field-true_false.php:184 includes/input.php:266 -#: pro/admin/views/html-settings-updates.php:103 -msgid "No" -msgstr "Nej" - -#: includes/fields/class-acf-field-taxonomy.php:738 -msgid "None" -msgstr "Ingen" - -#: includes/fields/class-acf-field-taxonomy.php:770 +#: includes/fields/class-acf-field-taxonomy.php:742 msgid "Select the taxonomy to be displayed" -msgstr "Välj taxonomi som ska visas" +msgstr "Välj taxonomin som ska visas" -#: includes/fields/class-acf-field-taxonomy.php:779 +#: includes/fields/class-acf-field-taxonomy.php:751 msgid "Appearance" msgstr "Utseende" -#: includes/fields/class-acf-field-taxonomy.php:780 +#: includes/fields/class-acf-field-taxonomy.php:752 msgid "Select the appearance of this field" msgstr "Välj utseende för detta fält" -#: includes/fields/class-acf-field-taxonomy.php:785 +#: includes/fields/class-acf-field-taxonomy.php:757 msgid "Multiple Values" -msgstr "Multipla värden" +msgstr "Flera värden" -#: includes/fields/class-acf-field-taxonomy.php:787 +#: includes/fields/class-acf-field-taxonomy.php:759 msgid "Multi Select" msgstr "Flerval" -#: includes/fields/class-acf-field-taxonomy.php:789 +#: includes/fields/class-acf-field-taxonomy.php:761 msgid "Single Value" -msgstr "Ett enda värde" +msgstr "Enstaka värde" -#: includes/fields/class-acf-field-taxonomy.php:790 +#: includes/fields/class-acf-field-taxonomy.php:762 msgid "Radio Buttons" msgstr "Alternativknappar" -#: includes/fields/class-acf-field-taxonomy.php:809 +#: includes/fields/class-acf-field-taxonomy.php:786 msgid "Create Terms" -msgstr "Skapa värden" +msgstr "Skapa termer" -#: includes/fields/class-acf-field-taxonomy.php:810 +#: includes/fields/class-acf-field-taxonomy.php:787 msgid "Allow new terms to be created whilst editing" -msgstr "Tillåt att nya värden läggs till under redigering" +msgstr "Tillåt att nya termer läggs till under redigering" -#: includes/fields/class-acf-field-taxonomy.php:819 +#: includes/fields/class-acf-field-taxonomy.php:796 msgid "Save Terms" -msgstr "Spara värden" +msgstr "Spara termer" -#: includes/fields/class-acf-field-taxonomy.php:820 +#: includes/fields/class-acf-field-taxonomy.php:797 msgid "Connect selected terms to the post" -msgstr "Koppla valda värden till inlägget" +msgstr "Koppla valda termer till inlägget" -#: includes/fields/class-acf-field-taxonomy.php:829 +#: includes/fields/class-acf-field-taxonomy.php:806 msgid "Load Terms" -msgstr "Ladda värden" +msgstr "Ladda termer" -#: includes/fields/class-acf-field-taxonomy.php:830 +#: includes/fields/class-acf-field-taxonomy.php:807 msgid "Load value from posts terms" -msgstr "Ladda värde från ett inläggs värden" +msgstr "Ladda term från ett inläggs termer" -#: includes/fields/class-acf-field-taxonomy.php:844 +#: includes/fields/class-acf-field-taxonomy.php:821 msgid "Term Object" -msgstr "Term objekt" +msgstr "Termobjekt" -#: includes/fields/class-acf-field-taxonomy.php:845 +#: includes/fields/class-acf-field-taxonomy.php:822 msgid "Term ID" -msgstr "Term ID" +msgstr "Term-ID" -#: includes/fields/class-acf-field-taxonomy.php:904 +#: includes/fields/class-acf-field-taxonomy.php:872 #, php-format msgid "User unable to add new %s" msgstr "Användare kan inte lägga till ny %s" -#: includes/fields/class-acf-field-taxonomy.php:917 +#: includes/fields/class-acf-field-taxonomy.php:882 #, php-format msgid "%s already exists" msgstr "%s finns redan" -#: includes/fields/class-acf-field-taxonomy.php:958 +#: includes/fields/class-acf-field-taxonomy.php:914 #, php-format msgid "%s added" msgstr "%s tillagt" -#: includes/fields/class-acf-field-taxonomy.php:1003 +#: includes/fields/class-acf-field-taxonomy.php:960 +#: includes/locations/class-acf-location-user-form.php:66 msgid "Add" msgstr "Lägg till" -#: includes/fields/class-acf-field-text.php:36 +#: includes/fields/class-acf-field-text.php:25 msgid "Text" msgstr "Text" -#: includes/fields/class-acf-field-text.php:178 -#: includes/fields/class-acf-field-textarea.php:157 +#: includes/fields/class-acf-field-text.php:131 +#: includes/fields/class-acf-field-textarea.php:120 msgid "Character Limit" msgstr "Maximalt antal tecken" -#: includes/fields/class-acf-field-text.php:179 -#: includes/fields/class-acf-field-textarea.php:158 +#: includes/fields/class-acf-field-text.php:132 +#: includes/fields/class-acf-field-textarea.php:121 msgid "Leave blank for no limit" msgstr "Lämna tomt för att ha utan begränsning" -#: includes/fields/class-acf-field-textarea.php:36 +#: includes/fields/class-acf-field-text.php:157 +#: includes/fields/class-acf-field-textarea.php:213 +#, php-format +msgid "Value must not exceed %d characters" +msgstr "Värdet får inte överstiga %d tecken" + +#: includes/fields/class-acf-field-textarea.php:25 msgid "Text Area" msgstr "Textfält" -#: includes/fields/class-acf-field-textarea.php:166 +#: includes/fields/class-acf-field-textarea.php:129 msgid "Rows" msgstr "Rader" -#: includes/fields/class-acf-field-textarea.php:167 +#: includes/fields/class-acf-field-textarea.php:130 msgid "Sets the textarea height" msgstr "Välj textfältets höjd" -#: includes/fields/class-acf-field-time_picker.php:36 +#: includes/fields/class-acf-field-time_picker.php:25 msgid "Time Picker" msgstr "Tidväljare" -#: includes/fields/class-acf-field-true_false.php:36 +#: includes/fields/class-acf-field-true_false.php:25 msgid "True / False" -msgstr "Sant / Falskt" +msgstr "Sant/Falskt" -#: includes/fields/class-acf-field-true_false.php:94 -#: includes/fields/class-acf-field-true_false.php:174 includes/input.php:265 -#: pro/admin/views/html-settings-updates.php:93 -msgid "Yes" -msgstr "Ja" - -#: includes/fields/class-acf-field-true_false.php:142 +#: includes/fields/class-acf-field-true_false.php:127 msgid "Displays text alongside the checkbox" -msgstr "Visa text bredvid kryssrutan" +msgstr "Visar text bredvid kryssrutan" -#: includes/fields/class-acf-field-true_false.php:170 +#: includes/fields/class-acf-field-true_false.php:155 msgid "On Text" -msgstr "På text" +msgstr "”På”-text" -#: includes/fields/class-acf-field-true_false.php:171 +#: includes/fields/class-acf-field-true_false.php:156 msgid "Text shown when active" msgstr "Text som visas när valet är aktivt" -#: includes/fields/class-acf-field-true_false.php:180 +#: includes/fields/class-acf-field-true_false.php:170 msgid "Off Text" -msgstr "Av text" +msgstr "”Av”-text" -#: includes/fields/class-acf-field-true_false.php:181 +#: includes/fields/class-acf-field-true_false.php:171 msgid "Text shown when inactive" msgstr "Text som visas när valet är inaktivt" -#: includes/fields/class-acf-field-url.php:36 +#: includes/fields/class-acf-field-url.php:25 msgid "Url" -msgstr "Url" +msgstr "URL" -#: includes/fields/class-acf-field-url.php:165 +#: includes/fields/class-acf-field-url.php:151 msgid "Value must be a valid URL" msgstr "Värdet måste vara en giltig URL" -#: includes/fields/class-acf-field-user.php:36 includes/locations.php:95 +#: includes/fields/class-acf-field-user.php:20 includes/locations.php:99 msgid "User" msgstr "Användare" -#: includes/fields/class-acf-field-user.php:408 +#: includes/fields/class-acf-field-user.php:51 msgid "Filter by role" msgstr "Filtrera efter roll" -#: includes/fields/class-acf-field-user.php:416 +#: includes/fields/class-acf-field-user.php:59 msgid "All user roles" msgstr "Alla användarroller" -#: includes/fields/class-acf-field-wysiwyg.php:36 +#: includes/fields/class-acf-field-user.php:84 +msgid "User Array" +msgstr "Användar-array" + +#: includes/fields/class-acf-field-user.php:85 +msgid "User Object" +msgstr "Användarobjekt" + +#: includes/fields/class-acf-field-user.php:86 +msgid "User ID" +msgstr "Användar-ID" + +#: includes/fields/class-acf-field-user.php:334 +msgid "Error loading field." +msgstr "Fel vid inläsning av fält." + +#: includes/fields/class-acf-field-wysiwyg.php:25 msgid "Wysiwyg Editor" msgstr "WYSIWYG-editor" -#: includes/fields/class-acf-field-wysiwyg.php:385 +#: includes/fields/class-acf-field-wysiwyg.php:294 msgid "Visual" msgstr "Visuellt" -#: includes/fields/class-acf-field-wysiwyg.php:386 +#: includes/fields/class-acf-field-wysiwyg.php:295 msgctxt "Name for the Text editor tab (formerly HTML)" msgid "Text" msgstr "Text" -#: includes/fields/class-acf-field-wysiwyg.php:392 +#: includes/fields/class-acf-field-wysiwyg.php:301 msgid "Click to initialize TinyMCE" msgstr "Klicka för att initialisera tinyMCE" -#: includes/fields/class-acf-field-wysiwyg.php:445 +#: includes/fields/class-acf-field-wysiwyg.php:354 msgid "Tabs" msgstr "Flikar" -#: includes/fields/class-acf-field-wysiwyg.php:450 +#: includes/fields/class-acf-field-wysiwyg.php:359 msgid "Visual & Text" -msgstr "Visuellt & Text" +msgstr "Visuell och text" -#: includes/fields/class-acf-field-wysiwyg.php:451 +#: includes/fields/class-acf-field-wysiwyg.php:360 msgid "Visual Only" msgstr "Endast visuellt" -#: includes/fields/class-acf-field-wysiwyg.php:452 +#: includes/fields/class-acf-field-wysiwyg.php:361 msgid "Text Only" msgstr "Endast text" -#: includes/fields/class-acf-field-wysiwyg.php:459 +#: includes/fields/class-acf-field-wysiwyg.php:368 msgid "Toolbar" msgstr "Verktygsfält" -#: includes/fields/class-acf-field-wysiwyg.php:469 +#: includes/fields/class-acf-field-wysiwyg.php:383 msgid "Show Media Upload Buttons?" msgstr "Visa knappar för uppladdning av media?" -#: includes/fields/class-acf-field-wysiwyg.php:479 +#: includes/fields/class-acf-field-wysiwyg.php:393 msgid "Delay initialization?" msgstr "Fördröj initialisering?" -#: includes/fields/class-acf-field-wysiwyg.php:480 -msgid "TinyMCE will not be initalized until field is clicked" +#: includes/fields/class-acf-field-wysiwyg.php:394 +msgid "TinyMCE will not be initialized until field is clicked" msgstr "TinyMCE initialiseras inte förrän fältet klickas på" -#: includes/forms/form-comment.php:166 includes/forms/form-post.php:303 -#: pro/admin/admin-options-page.php:304 -msgid "Edit field group" -msgstr "Redigera fältgrupp" +#: includes/forms/form-front.php:38 pro/fields/class-acf-field-gallery.php:350 +msgid "Title" +msgstr "Rubrik" #: includes/forms/form-front.php:55 msgid "Validate Email" -msgstr "Validera E-post" +msgstr "Validera e-post" -#: includes/forms/form-front.php:103 -#: pro/fields/class-acf-field-gallery.php:588 pro/options-page.php:81 +#: includes/forms/form-front.php:104 pro/fields/class-acf-field-gallery.php:507 +#: pro/options-page.php:73 msgid "Update" msgstr "Uppdatera" -#: includes/forms/form-front.php:104 +#: includes/forms/form-front.php:105 msgid "Post updated" msgstr "Inlägg uppdaterat" -#: includes/forms/form-front.php:229 +#: includes/forms/form-front.php:231 msgid "Spam Detected" -msgstr "Skräppost Upptäckt" +msgstr "Skräppost upptäckt" -#: includes/input.php:258 -msgid "Expand Details" -msgstr "Visa detaljer" - -#: includes/input.php:259 -msgid "Collapse Details" -msgstr "Dölj detaljer" - -#: includes/input.php:260 -msgid "Validation successful" -msgstr "Validering lyckades" - -#: includes/input.php:261 includes/validation.php:285 -#: includes/validation.php:296 -msgid "Validation failed" -msgstr "Validering misslyckades" - -#: includes/input.php:262 -msgid "1 field requires attention" -msgstr "1 fält kräver din uppmärksamhet" - -#: includes/input.php:263 +#: includes/forms/form-user.php:336 #, php-format -msgid "%d fields require attention" -msgstr "%d fält kräver din uppmärksamhet" +msgid "Error: %s" +msgstr "Fel: %s" -#: includes/input.php:264 -msgid "Restricted" -msgstr "Begränsad" +#: includes/locations.php:23 +#, php-format +msgid "Class \"%s\" does not exist." +msgstr "Klassen ”%s” finns inte." -#: includes/input.php:268 -msgid "Cancel" -msgstr "" +#: includes/locations.php:34 +#, php-format +msgid "Location type \"%s\" is already registered." +msgstr "Platstypen ”%s” är redan registrerad." -#: includes/locations.php:93 includes/locations/class-acf-location-post.php:27 +#: includes/locations.php:97 includes/locations/class-acf-location-post.php:20 msgid "Post" msgstr "Inlägg" -#: includes/locations.php:94 includes/locations/class-acf-location-page.php:27 +#: includes/locations.php:98 includes/locations/class-acf-location-page.php:20 msgid "Page" msgstr "Sida" -#: includes/locations.php:96 +#: includes/locations.php:100 msgid "Forms" msgstr "Formulär" -#: includes/locations/class-acf-location-attachment.php:27 +#: includes/locations/abstract-acf-location.php:103 +msgid "is equal to" +msgstr "är lika med" + +#: includes/locations/abstract-acf-location.php:104 +msgid "is not equal to" +msgstr "inte är lika med" + +#: includes/locations/class-acf-location-attachment.php:20 msgid "Attachment" msgstr "Bilaga" -#: includes/locations/class-acf-location-attachment.php:113 +#: includes/locations/class-acf-location-attachment.php:82 #, php-format msgid "All %s formats" -msgstr "" +msgstr "Alla %s-format" -#: includes/locations/class-acf-location-comment.php:27 +#: includes/locations/class-acf-location-comment.php:20 msgid "Comment" msgstr "Kommentar" -#: includes/locations/class-acf-location-current-user-role.php:27 +#: includes/locations/class-acf-location-current-user-role.php:20 msgid "Current User Role" msgstr "Inloggad användarroll" -#: includes/locations/class-acf-location-current-user-role.php:114 +#: includes/locations/class-acf-location-current-user-role.php:75 msgid "Super Admin" msgstr "Superadministratör" -#: includes/locations/class-acf-location-current-user.php:27 +#: includes/locations/class-acf-location-current-user.php:20 msgid "Current User" -msgstr "Inloggad användare" +msgstr "Nuvarande användare" -#: includes/locations/class-acf-location-current-user.php:101 +#: includes/locations/class-acf-location-current-user.php:69 msgid "Logged in" msgstr "Inloggad" -#: includes/locations/class-acf-location-current-user.php:102 +#: includes/locations/class-acf-location-current-user.php:70 msgid "Viewing front end" msgstr "Visar framsida" -#: includes/locations/class-acf-location-current-user.php:103 +#: includes/locations/class-acf-location-current-user.php:71 msgid "Viewing back end" -msgstr "Visar baksida" +msgstr "Visar back-end" -#: includes/locations/class-acf-location-nav-menu-item.php:27 +#: includes/locations/class-acf-location-nav-menu-item.php:20 msgid "Menu Item" -msgstr "" +msgstr "Menyobjekt" -#: includes/locations/class-acf-location-nav-menu.php:27 +#: includes/locations/class-acf-location-nav-menu.php:20 msgid "Menu" -msgstr "" +msgstr "Meny" -#: includes/locations/class-acf-location-nav-menu.php:113 -#, fuzzy +#: includes/locations/class-acf-location-nav-menu.php:78 msgid "Menu Locations" -msgstr "Plats" +msgstr "Menyplatser" -#: includes/locations/class-acf-location-nav-menu.php:123 -msgid "Menus" -msgstr "" - -#: includes/locations/class-acf-location-page-parent.php:27 +#: includes/locations/class-acf-location-page-parent.php:20 msgid "Page Parent" -msgstr "Sidans förälder" +msgstr "Överordnad sida" -#: includes/locations/class-acf-location-page-template.php:27 +#: includes/locations/class-acf-location-page-template.php:20 msgid "Page Template" msgstr "Sidmall" -#: includes/locations/class-acf-location-page-template.php:102 -#: includes/locations/class-acf-location-post-template.php:156 +#: includes/locations/class-acf-location-page-template.php:71 +#: includes/locations/class-acf-location-post-template.php:83 msgid "Default Template" msgstr "Standardmall" -#: includes/locations/class-acf-location-page-type.php:27 +#: includes/locations/class-acf-location-page-type.php:20 msgid "Page Type" msgstr "Sidtyp" -#: includes/locations/class-acf-location-page-type.php:149 +#: includes/locations/class-acf-location-page-type.php:106 msgid "Front Page" -msgstr "Förstasida" +msgstr "Startsida" -#: includes/locations/class-acf-location-page-type.php:150 +#: includes/locations/class-acf-location-page-type.php:107 msgid "Posts Page" -msgstr "Inläggslistningssida" +msgstr "Sida för inlägg" -#: includes/locations/class-acf-location-page-type.php:151 +#: includes/locations/class-acf-location-page-type.php:108 msgid "Top Level Page (no parent)" msgstr "Toppsida (Ingen förälder)" -#: includes/locations/class-acf-location-page-type.php:152 +#: includes/locations/class-acf-location-page-type.php:109 msgid "Parent Page (has children)" -msgstr "Föräldersida (har undersidor)" +msgstr "Överordnad sida (har underordnade)" -#: includes/locations/class-acf-location-page-type.php:153 +#: includes/locations/class-acf-location-page-type.php:110 msgid "Child Page (has parent)" -msgstr "Undersida (har föräldersida)" +msgstr "Undersida (har överordnad)" -#: includes/locations/class-acf-location-post-category.php:27 +#: includes/locations/class-acf-location-post-category.php:20 msgid "Post Category" msgstr "Inläggskategori" -#: includes/locations/class-acf-location-post-format.php:27 +#: includes/locations/class-acf-location-post-format.php:20 msgid "Post Format" msgstr "Inläggsformat" -#: includes/locations/class-acf-location-post-status.php:27 +#: includes/locations/class-acf-location-post-status.php:20 msgid "Post Status" msgstr "Inläggsstatus" -#: includes/locations/class-acf-location-post-taxonomy.php:27 +#: includes/locations/class-acf-location-post-taxonomy.php:20 msgid "Post Taxonomy" msgstr "Inläggstaxonomi" -#: includes/locations/class-acf-location-post-template.php:29 -#, fuzzy +#: includes/locations/class-acf-location-post-template.php:20 msgid "Post Template" -msgstr "Sidmall" +msgstr "Inläggsmall" -#: includes/locations/class-acf-location-taxonomy.php:27 -msgid "Taxonomy Term" -msgstr "Taxonomivärde" - -#: includes/locations/class-acf-location-user-form.php:27 +#: includes/locations/class-acf-location-user-form.php:20 msgid "User Form" msgstr "Användarformulär" -#: includes/locations/class-acf-location-user-form.php:92 +#: includes/locations/class-acf-location-user-form.php:67 msgid "Add / Edit" -msgstr "Skapa / Redigera" +msgstr "Skapa/Redigera" -#: includes/locations/class-acf-location-user-form.php:93 +#: includes/locations/class-acf-location-user-form.php:68 msgid "Register" msgstr "Registrera" -#: includes/locations/class-acf-location-user-role.php:27 +#: includes/locations/class-acf-location-user-role.php:22 msgid "User Role" msgstr "Användarroll" -#: includes/locations/class-acf-location-widget.php:27 +#: includes/locations/class-acf-location-widget.php:20 msgid "Widget" msgstr "Widget" @@ -2792,6 +2752,22 @@ msgctxt "verb" msgid "Update" msgstr "Uppdatera" +#: includes/media.php:57 +msgid "Uploaded to this post" +msgstr "Uppladdade till detta inlägg" + +#: includes/media.php:58 +msgid "Expand Details" +msgstr "Visa detaljer" + +#: includes/media.php:59 +msgid "Collapse Details" +msgstr "Dölj detaljer" + +#: includes/media.php:60 +msgid "Restricted" +msgstr "Begränsad" + #: includes/validation.php:364 #, php-format msgid "%s value is required" @@ -2802,11 +2778,11 @@ msgstr "%s värde är obligatorisk" msgid "Advanced Custom Fields PRO" msgstr "Advanced Custom Fields PRO" -#: pro/admin/admin-options-page.php:196 +#: pro/admin/admin-options-page.php:198 msgid "Publish" msgstr "Publicera" -#: pro/admin/admin-options-page.php:202 +#: pro/admin/admin-options-page.php:204 #, php-format msgid "" "No Custom Field Groups found for this options page. Create a " @@ -2815,351 +2791,390 @@ msgstr "" "Inga fältgrupper hittades för denna inställningssida. Skapa " "en fältgrupp" -#: pro/admin/admin-settings-updates.php:78 +#: pro/admin/admin-updates.php:49 msgid "Error. Could not connect to update server" msgstr "Fel. Kunde inte ansluta till uppdateringsservern" -#: pro/admin/admin-settings-updates.php:162 -#: pro/admin/views/html-settings-updates.php:17 +#: pro/admin/admin-updates.php:118 pro/admin/views/html-settings-updates.php:12 msgid "Updates" msgstr "Uppdateringar" -#: pro/admin/views/html-settings-updates.php:11 +#: pro/admin/admin-updates.php:191 +msgid "" +"Error. Could not authenticate update package. Please check again or " +"deactivate and reactivate your ACF PRO license." +msgstr "" +"Fel. Det gick inte att autentisera uppdateringspaketet. Kontrollera " +"igen eller inaktivera och återaktivera din ACF PRO-licens." + +#: pro/admin/views/html-settings-updates.php:6 msgid "Deactivate License" msgstr "Inaktivera licens" -#: pro/admin/views/html-settings-updates.php:11 +#: pro/admin/views/html-settings-updates.php:6 msgid "Activate License" msgstr "Aktivera licens" -#: pro/admin/views/html-settings-updates.php:21 +#: pro/admin/views/html-settings-updates.php:16 msgid "License Information" msgstr "Licensinformation" -#: pro/admin/views/html-settings-updates.php:24 +#: pro/admin/views/html-settings-updates.php:19 #, php-format msgid "" "To unlock updates, please enter your license key below. If you don't have a " "licence key, please see details & pricing." msgstr "" -"För att aktivera uppdateringar, vänligen fyll i din licensnyckel här " -"nedanför. Om du inte har en licensnyckel, vänligen gå till sidan detaljer & priser" +"För att låsa upp uppdateringar, fyll i din licensnyckel här nedan. Om du " +"inte har en licensnyckel, gå till sidan detaljer och priser." -#: pro/admin/views/html-settings-updates.php:33 +#: pro/admin/views/html-settings-updates.php:26 msgid "License Key" msgstr "Licensnyckel" -#: pro/admin/views/html-settings-updates.php:65 +#: pro/admin/views/html-settings-updates.php:58 msgid "Update Information" msgstr "Uppdateringsinformation" -#: pro/admin/views/html-settings-updates.php:72 +#: pro/admin/views/html-settings-updates.php:65 msgid "Current Version" msgstr "Nuvarande version" -#: pro/admin/views/html-settings-updates.php:80 +#: pro/admin/views/html-settings-updates.php:73 msgid "Latest Version" msgstr "Senaste version" -#: pro/admin/views/html-settings-updates.php:88 +#: pro/admin/views/html-settings-updates.php:81 msgid "Update Available" msgstr "Uppdatering tillgänglig" -#: pro/admin/views/html-settings-updates.php:96 +#: pro/admin/views/html-settings-updates.php:89 msgid "Update Plugin" msgstr "Uppdatera tillägg" -#: pro/admin/views/html-settings-updates.php:98 +#: pro/admin/views/html-settings-updates.php:91 msgid "Please enter your license key above to unlock updates" -msgstr "" -"Vänligen fyll i din licensnyckel här ovan för att låsa upp uppdateringar" +msgstr "Fyll i din licensnyckel här ovan för att låsa upp uppdateringar" -#: pro/admin/views/html-settings-updates.php:104 +#: pro/admin/views/html-settings-updates.php:97 msgid "Check Again" msgstr "Kontrollera igen" -#: pro/admin/views/html-settings-updates.php:121 +#: pro/admin/views/html-settings-updates.php:104 +msgid "Changelog" +msgstr "Ändringslogg" + +#: pro/admin/views/html-settings-updates.php:114 msgid "Upgrade Notice" msgstr "Uppgraderingsnotering" -#: pro/fields/class-acf-field-clone.php:36 +#: pro/blocks.php:37 +msgid "Block type name is required." +msgstr "Blocktypsnamn är obligatoriskt." + +#: pro/blocks.php:44 +#, php-format +msgid "Block type \"%s\" is already registered." +msgstr "Blocktypen \"%s\" är redan registrerad." + +#: pro/blocks.php:444 +msgid "Switch to Edit" +msgstr "Växla till Redigera" + +#: pro/blocks.php:445 +msgid "Switch to Preview" +msgstr "Växla till förhandsgranskning" + +#: pro/blocks.php:446 +msgid "Change content alignment" +msgstr "Ändra innehållsjustering" + +#: pro/blocks.php:449 +#, php-format +msgid "%s settings" +msgstr "%s-inställningar" + +#: pro/fields/class-acf-field-clone.php:25 msgctxt "noun" msgid "Clone" msgstr "Klon" -#: pro/fields/class-acf-field-clone.php:858 +#: pro/fields/class-acf-field-clone.php:800 msgid "Select one or more fields you wish to clone" -msgstr "Välj ett eller fler fält du vill klona" +msgstr "Välj ett eller flera fält som du vill klona" -#: pro/fields/class-acf-field-clone.php:875 +#: pro/fields/class-acf-field-clone.php:817 msgid "Display" -msgstr "Visa" +msgstr "Visning" -#: pro/fields/class-acf-field-clone.php:876 +#: pro/fields/class-acf-field-clone.php:818 msgid "Specify the style used to render the clone field" -msgstr "Specificera stilen som ska användas för att skapa klonfältet" +msgstr "Specificera stilen som ska användas för att rendera det klonade fältet" -#: pro/fields/class-acf-field-clone.php:881 +#: pro/fields/class-acf-field-clone.php:823 msgid "Group (displays selected fields in a group within this field)" msgstr "Grupp (visar valda fält i en grupp i detta fält)" -#: pro/fields/class-acf-field-clone.php:882 +#: pro/fields/class-acf-field-clone.php:824 msgid "Seamless (replaces this field with selected fields)" msgstr "Sömlös (ersätter detta fält med valda fält)" -#: pro/fields/class-acf-field-clone.php:903 +#: pro/fields/class-acf-field-clone.php:845 #, php-format msgid "Labels will be displayed as %s" -msgstr "Fälttitlar visas som %s" +msgstr "Etiketter kommer att visas som %s" -#: pro/fields/class-acf-field-clone.php:906 +#: pro/fields/class-acf-field-clone.php:848 msgid "Prefix Field Labels" -msgstr "Prefix fälttitlar" +msgstr "Prefix för fältetiketter" -#: pro/fields/class-acf-field-clone.php:917 +#: pro/fields/class-acf-field-clone.php:859 #, php-format msgid "Values will be saved as %s" msgstr "Värden sparas som %s" -#: pro/fields/class-acf-field-clone.php:920 +#: pro/fields/class-acf-field-clone.php:862 msgid "Prefix Field Names" -msgstr "Prefix fältnamn" +msgstr "Prefix för fältnamn" -#: pro/fields/class-acf-field-clone.php:1038 +#: pro/fields/class-acf-field-clone.php:980 msgid "Unknown field" msgstr "Okänt fält" -#: pro/fields/class-acf-field-clone.php:1077 +#: pro/fields/class-acf-field-clone.php:1019 msgid "Unknown field group" msgstr "Okänd fältgrupp" -#: pro/fields/class-acf-field-clone.php:1081 +#: pro/fields/class-acf-field-clone.php:1023 #, php-format msgid "All fields from %s field group" msgstr "Alla fält från %s fältgrupp" -#: pro/fields/class-acf-field-flexible-content.php:42 -#: pro/fields/class-acf-field-repeater.php:230 -#: pro/fields/class-acf-field-repeater.php:534 +#: pro/fields/class-acf-field-flexible-content.php:31 +#: pro/fields/class-acf-field-repeater.php:193 +#: pro/fields/class-acf-field-repeater.php:464 msgid "Add Row" msgstr "Lägg till rad" -#: pro/fields/class-acf-field-flexible-content.php:45 +#: pro/fields/class-acf-field-flexible-content.php:73 +#: pro/fields/class-acf-field-flexible-content.php:921 +#: pro/fields/class-acf-field-flexible-content.php:1003 msgid "layout" -msgstr "layout" +msgid_plural "layouts" +msgstr[0] "layout" +msgstr[1] "layouter" -#: pro/fields/class-acf-field-flexible-content.php:46 +#: pro/fields/class-acf-field-flexible-content.php:74 msgid "layouts" msgstr "layouter" -#: pro/fields/class-acf-field-flexible-content.php:47 -msgid "remove {layout}?" -msgstr "radera {layout}?" - -#: pro/fields/class-acf-field-flexible-content.php:48 -msgid "This field requires at least {min} {identifier}" -msgstr "Detta fält kräver minst {min} {identifierare}" - -#: pro/fields/class-acf-field-flexible-content.php:49 -msgid "This field has a limit of {max} {identifier}" -msgstr "Detta fält har en gräns på {max} {identifierare}" - -#: pro/fields/class-acf-field-flexible-content.php:50 +#: pro/fields/class-acf-field-flexible-content.php:77 +#: pro/fields/class-acf-field-flexible-content.php:920 +#: pro/fields/class-acf-field-flexible-content.php:1002 msgid "This field requires at least {min} {label} {identifier}" -msgstr "Detta fält kräver minst {min} {etikett} {identifierare}" +msgstr "Detta fält kräver minst {min} {label} {identifier}" -#: pro/fields/class-acf-field-flexible-content.php:51 -msgid "Maximum {label} limit reached ({max} {identifier})" -msgstr "Maximal {etikett} gräns nåtts ({max} {identifierare})" +#: pro/fields/class-acf-field-flexible-content.php:78 +msgid "This field has a limit of {max} {label} {identifier}" +msgstr "Detta fält har en gräns på {max} {label} {identifier}" -#: pro/fields/class-acf-field-flexible-content.php:52 +#: pro/fields/class-acf-field-flexible-content.php:81 msgid "{available} {label} {identifier} available (max {max})" -msgstr "{tillgänglig} {etikett} {identifierare} tillgänglig (max {max})" +msgstr "{available} {label} {identifier} tillgänglig (max {max})" -#: pro/fields/class-acf-field-flexible-content.php:53 +#: pro/fields/class-acf-field-flexible-content.php:82 msgid "{required} {label} {identifier} required (min {min})" -msgstr "{krävs} {etikett} {identifierare} krävs (min {min})" +msgstr "{required} {label} {identifier} krävs (min {min})" -#: pro/fields/class-acf-field-flexible-content.php:54 +#: pro/fields/class-acf-field-flexible-content.php:85 msgid "Flexible Content requires at least 1 layout" msgstr "Flexibelt innehåll kräver minst 1 layout" -#: pro/fields/class-acf-field-flexible-content.php:288 +#: pro/fields/class-acf-field-flexible-content.php:287 #, php-format msgid "Click the \"%s\" button below to start creating your layout" -msgstr "Klicka på knappen \"%s\" nedan för att börja skapa din layout" +msgstr "Klicka på knappen ”%s” nedan för att börja skapa din layout" -#: pro/fields/class-acf-field-flexible-content.php:423 +#: pro/fields/class-acf-field-flexible-content.php:414 msgid "Add layout" msgstr "Lägg till layout" -#: pro/fields/class-acf-field-flexible-content.php:424 -msgid "Remove layout" -msgstr "Radera layout" +#: pro/fields/class-acf-field-flexible-content.php:415 +msgid "Duplicate layout" +msgstr "Duplicera layout" -#: pro/fields/class-acf-field-flexible-content.php:425 -#: pro/fields/class-acf-field-repeater.php:360 +#: pro/fields/class-acf-field-flexible-content.php:416 +msgid "Remove layout" +msgstr "Ta bort layout" + +#: pro/fields/class-acf-field-flexible-content.php:417 +#: pro/fields/class-acf-field-repeater.php:296 msgid "Click to toggle" msgstr "Klicka för att växla" -#: pro/fields/class-acf-field-flexible-content.php:571 +#: pro/fields/class-acf-field-flexible-content.php:551 msgid "Reorder Layout" msgstr "Ändra layoutens ordning" -#: pro/fields/class-acf-field-flexible-content.php:571 +#: pro/fields/class-acf-field-flexible-content.php:551 msgid "Reorder" msgstr "Ändra ordning" -#: pro/fields/class-acf-field-flexible-content.php:572 +#: pro/fields/class-acf-field-flexible-content.php:552 msgid "Delete Layout" -msgstr "Radera layout" +msgstr "Ta bort layout" -#: pro/fields/class-acf-field-flexible-content.php:573 +#: pro/fields/class-acf-field-flexible-content.php:553 msgid "Duplicate Layout" -msgstr "Kopiera layout" +msgstr "Duplicera layout" -#: pro/fields/class-acf-field-flexible-content.php:574 +#: pro/fields/class-acf-field-flexible-content.php:554 msgid "Add New Layout" msgstr "Lägg till ny layout" -#: pro/fields/class-acf-field-flexible-content.php:645 +#: pro/fields/class-acf-field-flexible-content.php:626 msgid "Min" msgstr "Min" -#: pro/fields/class-acf-field-flexible-content.php:658 +#: pro/fields/class-acf-field-flexible-content.php:639 msgid "Max" msgstr "Max" -#: pro/fields/class-acf-field-flexible-content.php:685 -#: pro/fields/class-acf-field-repeater.php:530 +#: pro/fields/class-acf-field-flexible-content.php:666 +#: pro/fields/class-acf-field-repeater.php:460 msgid "Button Label" -msgstr "Knapp etikett" +msgstr "Knappetikett" -#: pro/fields/class-acf-field-flexible-content.php:694 +#: pro/fields/class-acf-field-flexible-content.php:675 msgid "Minimum Layouts" msgstr "Lägsta tillåtna antal layouter" -#: pro/fields/class-acf-field-flexible-content.php:703 +#: pro/fields/class-acf-field-flexible-content.php:684 msgid "Maximum Layouts" msgstr "Högsta tillåtna antal layouter" -#: pro/fields/class-acf-field-gallery.php:52 +#: pro/fields/class-acf-field-gallery.php:73 msgid "Add Image to Gallery" -msgstr "Lägg till en bild till galleri" +msgstr "Lägg till bild i galleriet" -#: pro/fields/class-acf-field-gallery.php:56 +#: pro/fields/class-acf-field-gallery.php:74 msgid "Maximum selection reached" msgstr "Högsta tillåtna antal val uppnått" -#: pro/fields/class-acf-field-gallery.php:336 +#: pro/fields/class-acf-field-gallery.php:319 msgid "Length" msgstr "Längd" -#: pro/fields/class-acf-field-gallery.php:379 +#: pro/fields/class-acf-field-gallery.php:359 msgid "Caption" msgstr "Bildtext" -#: pro/fields/class-acf-field-gallery.php:388 +#: pro/fields/class-acf-field-gallery.php:368 msgid "Alt Text" -msgstr "Alt Text" +msgstr "Alternativ text" -#: pro/fields/class-acf-field-gallery.php:559 +#: pro/fields/class-acf-field-gallery.php:484 msgid "Add to gallery" -msgstr "Lägg till galleri" +msgstr "Lägg till i galleri" -#: pro/fields/class-acf-field-gallery.php:563 +#: pro/fields/class-acf-field-gallery.php:488 msgid "Bulk actions" -msgstr "Välj åtgärd" +msgstr "Massåtgärder" -#: pro/fields/class-acf-field-gallery.php:564 +#: pro/fields/class-acf-field-gallery.php:489 msgid "Sort by date uploaded" msgstr "Sortera efter uppladdningsdatum" -#: pro/fields/class-acf-field-gallery.php:565 +#: pro/fields/class-acf-field-gallery.php:490 msgid "Sort by date modified" msgstr "Sortera efter redigeringsdatum" -#: pro/fields/class-acf-field-gallery.php:566 +#: pro/fields/class-acf-field-gallery.php:491 msgid "Sort by title" -msgstr "Sortera efter titel" +msgstr "Sortera efter rubrik" -#: pro/fields/class-acf-field-gallery.php:567 +#: pro/fields/class-acf-field-gallery.php:492 msgid "Reverse current order" msgstr "Omvänd nuvarande ordning" -#: pro/fields/class-acf-field-gallery.php:585 +#: pro/fields/class-acf-field-gallery.php:504 msgid "Close" msgstr "Stäng" -#: pro/fields/class-acf-field-gallery.php:639 -msgid "Minimum Selection" -msgstr "Minsta tillåtna antal val" - -#: pro/fields/class-acf-field-gallery.php:648 -msgid "Maximum Selection" -msgstr "Högsta tillåtna antal val" - -#: pro/fields/class-acf-field-gallery.php:657 +#: pro/fields/class-acf-field-gallery.php:577 msgid "Insert" msgstr "Infoga" -#: pro/fields/class-acf-field-gallery.php:658 +#: pro/fields/class-acf-field-gallery.php:578 msgid "Specify where new attachments are added" msgstr "Specifiera var nya bilagor läggs till" -#: pro/fields/class-acf-field-gallery.php:662 +#: pro/fields/class-acf-field-gallery.php:582 msgid "Append to the end" msgstr "Lägg till i slutet" -#: pro/fields/class-acf-field-gallery.php:663 +#: pro/fields/class-acf-field-gallery.php:583 msgid "Prepend to the beginning" msgstr "Lägg till början" -#: pro/fields/class-acf-field-repeater.php:47 +#: pro/fields/class-acf-field-gallery.php:602 +msgid "Minimum Selection" +msgstr "Minsta tillåtna antal val" + +#: pro/fields/class-acf-field-gallery.php:610 +msgid "Maximum Selection" +msgstr "Högsta tillåtna antal val" + +#: pro/fields/class-acf-field-repeater.php:65 +#: pro/fields/class-acf-field-repeater.php:657 msgid "Minimum rows reached ({min} rows)" msgstr "Minsta tillåtna antal rader uppnått ({min} rader)" -#: pro/fields/class-acf-field-repeater.php:48 +#: pro/fields/class-acf-field-repeater.php:66 msgid "Maximum rows reached ({max} rows)" msgstr "Högsta tillåtna antal rader uppnått ({max} rader)" -#: pro/fields/class-acf-field-repeater.php:405 +#: pro/fields/class-acf-field-repeater.php:333 msgid "Add row" msgstr "Lägg till rad" -#: pro/fields/class-acf-field-repeater.php:406 +#: pro/fields/class-acf-field-repeater.php:334 +msgid "Duplicate row" +msgstr "Duplicera rad" + +#: pro/fields/class-acf-field-repeater.php:335 msgid "Remove row" -msgstr "Radera rad" +msgstr "Ta bort rad" -#: pro/fields/class-acf-field-repeater.php:483 +#: pro/fields/class-acf-field-repeater.php:413 msgid "Collapsed" -msgstr "Kollapsa" +msgstr "Ihopfälld" -#: pro/fields/class-acf-field-repeater.php:484 +#: pro/fields/class-acf-field-repeater.php:414 msgid "Select a sub field to show when row is collapsed" -msgstr "Välj ett underfält att visa när raden är kollapsad" +msgstr "Välj ett underfält att visa när raden är ihopfälld" -#: pro/fields/class-acf-field-repeater.php:494 +#: pro/fields/class-acf-field-repeater.php:424 msgid "Minimum Rows" msgstr "Minsta tillåtna antal rader" -#: pro/fields/class-acf-field-repeater.php:504 +#: pro/fields/class-acf-field-repeater.php:434 msgid "Maximum Rows" msgstr "Högsta tillåtna antal rader" -#: pro/locations/class-acf-location-options-page.php:70 +#: pro/locations/class-acf-location-block.php:69 +msgid "No block types exist" +msgstr "Det finns inga blocktyper" + +#: pro/locations/class-acf-location-options-page.php:68 msgid "No options pages exist" -msgstr "Det finns inga inställningssidor" +msgstr "Det finns inga alternativsidor" -#: pro/options-page.php:51 -msgid "Options" -msgstr "Alternativ" - -#: pro/options-page.php:82 +#: pro/options-page.php:74 msgid "Options Updated" -msgstr "Inställningar uppdaterade" +msgstr "Alternativ uppdaterade" #: pro/updates.php:97 #, php-format @@ -3168,61 +3183,385 @@ msgid "" "\">Updates page. If you don't have a licence key, please see details & pricing." msgstr "" -"För att aktivera uppdateringar, vänligen fyll i din licensnyckel på sidan uppdateringar. Om du inte har en licensnyckel, vänligen gå " -"till sidan detaljer & priser" +"För att aktivera uppdateringar, fyll i din licensnyckel på sidan uppdateringar. Om du inte har en licensnyckel, gå till sidan detaljer och priser." #. Plugin URI of the plugin/theme -msgid "https://www.advancedcustomfields.com/" -msgstr "https://www.advancedcustomfields.com/" +#. Author URI of the plugin/theme +msgid "https://www.advancedcustomfields.com" +msgstr "https://www.advancedcustomfields.com" + +#. Description of the plugin/theme +msgid "Customize WordPress with powerful, professional and intuitive fields." +msgstr "Anpassa Wordpress med kraftfulla, professionella och intuitiva fält." #. Author of the plugin/theme msgid "Elliot Condon" msgstr "Elliot Condon" -#. Author URI of the plugin/theme -msgid "http://www.elliotcondon.com/" -msgstr "http://www.elliotcondon.com/" +#~ msgid "Inactive" +#~ msgstr "Inaktiv" -#~ msgid "Features" -#~ msgstr "Funktioner" +#, php-format +#~ msgid "Inactive (%s)" +#~ msgid_plural "Inactive (%s)" +#~ msgstr[0] "Inaktiv (%s)" +#~ msgstr[1] "Inaktiva (%s)" -#~ msgid "How to" -#~ msgstr "Instruktioner" +#~ msgid "Parent fields" +#~ msgstr "Överordnade fält" -#~ msgid "Term meta upgrade not possible (termmeta table does not exist)" -#~ msgstr "" -#~ "Term meta uppgradering ej möjligt (termmeta tabellen existerar inte)" +#~ msgid "Sibling fields" +#~ msgstr "Syskonfält" + +#, php-format +#~ msgid "%s field group synchronised." +#~ msgid_plural "%s field groups synchronised." +#~ msgstr[0] "%s fältgrupp synkroniserad." +#~ msgstr[1] "%s fältgrupper synkroniserade." + +#~ msgid "Status" +#~ msgstr "Status" + +#, php-format +#~ msgid "See what's new in version %s." +#~ msgstr "Se vad som är nytt i version %s." + +#~ msgid "Resources" +#~ msgstr "Resurser" + +#~ msgid "Documentation" +#~ msgstr "Dokumentation" + +#~ msgid "Pro" +#~ msgstr "Pro" + +#, php-format +#~ msgid "Thank you for creating with ACF." +#~ msgstr "Tack för att du skapar med ACF." + +#~ msgid "Synchronise field group" +#~ msgstr "Synkronisera fältgrupp" + +#~ msgid "Apply" +#~ msgstr "Utför" + +#~ msgid "Bulk Actions" +#~ msgstr "Massåtgärder" + +#~ msgid "Error validating request" +#~ msgstr "Fel vid validering av begäran" + +#~ msgid "Add-ons" +#~ msgstr "Utökningar" + +#~ msgid "Error. Could not load add-ons list" +#~ msgstr "Fel. Kunde inte ladda listan med utökningar" + +#~ msgid "Info" +#~ msgstr "Information" + +#~ msgid "What's New" +#~ msgstr "Vad är nytt" + +#~ msgid "Advanced Custom Fields Database Upgrade" +#~ msgstr "Databasuppgradering för Advanced Custom Fields" #~ msgid "" -#~ "Error validating ACF PRO license URL (website does not match). Please re-" -#~ "activate your license" +#~ "Before you start using the new awesome features, please update your " +#~ "database to the newest version." #~ msgstr "" -#~ "Fel vid validering av ACF PRO licens URL (Sajten överensstämmer inte). " -#~ "Vänligen aktivera din licens på nytt" +#~ "Innan du börjar använda de nya fantastiska funktionerna, uppdatera din " +#~ "databas till den senaste versionen." -#~ msgid "Getting Started" -#~ msgstr "Kom igång" +#~ msgid "Download & Install" +#~ msgstr "Ladda ner och installera" -#~ msgid "Field Types" -#~ msgstr "Fälttyper" +#~ msgid "Installed" +#~ msgstr "Installerad" -#~ msgid "Functions" -#~ msgstr "Funktioner" +#~ msgid "Welcome to Advanced Custom Fields" +#~ msgstr "Välkommen till Advanced Custom Fields" -#~ msgid "Actions" -#~ msgstr "Actions" +#, php-format +#~ msgid "" +#~ "Thank you for updating! ACF %s is bigger and better than ever before. We " +#~ "hope you like it." +#~ msgstr "" +#~ "Tack för att du uppdaterar! ACF %s är större och bättre än någonsin " +#~ "tidigare. Vi hoppas att du gillar det." -#~ msgid "Tutorials" -#~ msgstr "Handledningar" +#~ msgid "A smoother custom field experience" +#~ msgstr "En smidigare fältupplevelse" -#~ msgid "FAQ" -#~ msgstr "Frågor & Svar" +#~ msgid "Improved Usability" +#~ msgstr "Förbättrad användarvänlighet" -#~ msgid "Error" -#~ msgstr "Fel" +#~ msgid "" +#~ "Including the popular Select2 library has improved both usability and " +#~ "speed across a number of field types including post object, page link, " +#~ "taxonomy and select." +#~ msgstr "" +#~ "Vi har inkluderat det populära biblioteket Select2 som har förbättrat " +#~ "både användbarhet och laddningstid för ett antal fälttyper såsom " +#~ "inläggsobjekt, sidlänk, taxonomi och val." -#~ msgid "1 field requires attention." -#~ msgid_plural "%d fields require attention." -#~ msgstr[0] "1 fält kräver din uppmärksamhet" -#~ msgstr[1] "%d fält kräver din uppmärksamhet" +#~ msgid "Improved Design" +#~ msgstr "Förbättrad design" + +#~ msgid "" +#~ "Many fields have undergone a visual refresh to make ACF look better than " +#~ "ever! Noticeable changes are seen on the gallery, relationship and oEmbed " +#~ "(new) fields!" +#~ msgstr "" +#~ "Många fält har genomgått en visuell förbättring för att låta ACF se " +#~ "bättre ut än någonsin! Märkbara förändringar syns på fälten galleri, " +#~ "relation och oEmbed (nytt)!" + +#~ msgid "Improved Data" +#~ msgstr "Förbättrad data" + +#~ msgid "" +#~ "Redesigning the data architecture has allowed sub fields to live " +#~ "independently from their parents. This allows you to drag and drop fields " +#~ "in and out of parent fields!" +#~ msgstr "" +#~ "Omdesignen av dataarkitekturen har tillåtit underfält att leva " +#~ "självständigt från deras föräldrar. Detta gör att du kan dra och släppa " +#~ "fält in och ut från förälderfälten!" + +#~ msgid "Goodbye Add-ons. Hello PRO" +#~ msgstr "Adjö tillägg. Hej PRO" + +#~ msgid "Introducing ACF PRO" +#~ msgstr "Introduktion av ACF PRO" + +#~ msgid "" +#~ "We're changing the way premium functionality is delivered in an exciting " +#~ "way!" +#~ msgstr "" +#~ "Vi ändrar hur premium-funktionalitet levereras, på ett spännande sätt!" + +#, php-format +#~ msgid "" +#~ "All 4 premium add-ons have been combined into a new Pro " +#~ "version of ACF. With both personal and developer licenses available, " +#~ "premium functionality is more affordable and accessible than ever before!" +#~ msgstr "" +#~ "Samtliga 4 premiumutökningar har kombineras till en ny Pro " +#~ "version av ACF. Med både personlig- och utvecklarlicens tillgängliga, " +#~ "så är premium-funktionalitet billigare och tillgängligare än någonsin!" + +#~ msgid "Powerful Features" +#~ msgstr "Kraftfulla funktioner" + +#~ msgid "" +#~ "ACF PRO contains powerful features such as repeatable data, flexible " +#~ "content layouts, a beautiful gallery field and the ability to create " +#~ "extra admin options pages!" +#~ msgstr "" +#~ "ACF PRO innehåller kraftfulla funktioner som upprepningsfält, flexibelt " +#~ "innehåll, ett vackert gallerifält och möjligheten att skapa extra " +#~ "inställningssidor!" + +#, php-format +#~ msgid "Read more about ACF PRO features." +#~ msgstr "Läs mer om ACF PRO funktioner." + +#~ msgid "Easy Upgrading" +#~ msgstr "Enkelt att uppgradera" + +#, php-format +#~ msgid "" +#~ "To help make upgrading easy, login to your store account and claim a free copy of ACF PRO!" +#~ msgstr "" +#~ "För att göra uppgraderingen enkel, logga in till ditt " +#~ "konto och få en gratis kopia av ACF PRO!" + +#, php-format +#~ msgid "" +#~ "We also wrote an upgrade guide to answer any " +#~ "questions, but if you do have one, please contact our support team via " +#~ "the help desk" +#~ msgstr "" +#~ "Vi skrev även en uppgraderingsguideför svara på " +#~ "eventuella frågor, men om du har en, kontakta vårt supportteam via help desk" + +#~ msgid "Under the Hood" +#~ msgstr "Under huven" + +#~ msgid "Smarter field settings" +#~ msgstr "Smartare fältinställningar" + +#~ msgid "ACF now saves its field settings as individual post objects" +#~ msgstr "ACF sparar nu sina fältinställningar som individuella inläggsobjekt" + +#~ msgid "More AJAX" +#~ msgstr "Mer AJAX" + +#~ msgid "More fields use AJAX powered search to speed up page loading" +#~ msgstr "Fler fält använder AJAX-sök för snabbare laddning" + +#~ msgid "New auto export to JSON feature improves speed" +#~ msgstr "Ny automatisk export till JSON funktion förbättrar snabbheten" + +#~ msgid "Better version control" +#~ msgstr "Bättre versionshantering" + +#~ msgid "" +#~ "New auto export to JSON feature allows field settings to be version " +#~ "controlled" +#~ msgstr "" +#~ "Ny automatisk export till JSON-funktion möjliggör versionshantering av " +#~ "fältinställningar" + +#~ msgid "Swapped XML for JSON" +#~ msgstr "Bytte XML till JSON" + +#~ msgid "Import / Export now uses JSON in favour of XML" +#~ msgstr "Importera/exportera använder nu JSON istället för XML" + +#~ msgid "New Forms" +#~ msgstr "Nya formulär" + +#~ msgid "Fields can now be mapped to comments, widgets and all user forms!" +#~ msgstr "" +#~ "Fält kan nu kopplas till kommentarer, widgetar och alla användarformulär!" + +#~ msgid "A new field for embedding content has been added" +#~ msgstr "Ett nytt fält för inbäddning av innehåll (embed) har lagts till" + +#~ msgid "New Gallery" +#~ msgstr "Nytt galleri" + +#~ msgid "The gallery field has undergone a much needed facelift" +#~ msgstr "Gallerifältet har genomgått en välbehövlig ansiktslyftning" + +#~ msgid "New Settings" +#~ msgstr "Nya inställningar" + +#~ msgid "" +#~ "Field group settings have been added for label placement and instruction " +#~ "placement" +#~ msgstr "" +#~ "Fältgruppsinställningar har lagts till för placering av rubrik och " +#~ "instruktioner" + +#~ msgid "Better Front End Forms" +#~ msgstr "Bättre front-end formulär" + +#~ msgid "acf_form() can now create a new post on submission" +#~ msgstr "acf_form() kan nu skapa ett nytt inlägg när det skickas" + +#~ msgid "Better Validation" +#~ msgstr "Bättre validering" + +#~ msgid "Form validation is now done via PHP + AJAX in favour of only JS" +#~ msgstr "" +#~ "Validering av formulär görs nu via PHP + AJAX istället för enbart JS" + +#~ msgid "Relationship Field" +#~ msgstr "Relationsfält" + +#~ msgid "" +#~ "New Relationship field setting for 'Filters' (Search, Post Type, Taxonomy)" +#~ msgstr "" +#~ "Ny inställning för relationsfält för ”Filter” (Sök, Inläggstyp, Taxonomi)" + +#~ msgid "Moving Fields" +#~ msgstr "Flytta runt fält" + +#~ msgid "" +#~ "New field group functionality allows you to move a field between groups & " +#~ "parents" +#~ msgstr "" +#~ "Ny fältgrupp funktionalitet tillåter dig att flytta ett fält mellan " +#~ "grupper och föräldrar" + +#~ msgid "New archives group in page_link field selection" +#~ msgstr "Ny arkivgrupp i page_link fältval" + +#~ msgid "Better Options Pages" +#~ msgstr "Bättre inställningssidor" + +#~ msgid "" +#~ "New functions for options page allow creation of both parent and child " +#~ "menu pages" +#~ msgstr "" +#~ "Nya funktioner för inställningssidor tillåter skapande av både föräldra- " +#~ "och undersidor" + +#, php-format +#~ msgid "We think you'll love the changes in %s." +#~ msgstr "Vi tror att du kommer uppskatta förändringarna i %s." + +#~ msgid "Export Field Groups to PHP" +#~ msgstr "Exportera fältgrupper till PHP" + +#~ msgid "Download export file" +#~ msgstr "Ladda ner exportfil" + +#~ msgid "Generate export code" +#~ msgstr "Generera exportkod" + +#~ msgid "Current Color" +#~ msgstr "Nuvarande färg" + +#~ msgid "Locating" +#~ msgstr "Söker plats" + +#~ msgid "Shown when entering data" +#~ msgstr "Visas vid inmatning av data" + +#~ msgid "Error." +#~ msgstr "Fel." + +#~ msgid "No embed found for the given URL." +#~ msgstr "Ingen embed hittades för angiven URL." + +#~ msgid "Minimum values reached ( {min} values )" +#~ msgstr "Lägsta tillåtna antal värden nått ( {min} värden )" + +#~ msgid "" +#~ "The tab field will display incorrectly when added to a Table style " +#~ "repeater field or flexible content field layout" +#~ msgstr "" +#~ "Flikfältet kommer att visas felaktigt om de läggs till i ett " +#~ "upprepningsfält med tabellutseende eller ett innehållsfält med flexibel " +#~ "layout" + +#~ msgid "" +#~ "Use \"Tab Fields\" to better organize your edit screen by grouping fields " +#~ "together." +#~ msgstr "" +#~ "Använd ”Flikfält” för att bättre organisera din redigeringsvy genom att " +#~ "gruppera fälten tillsammans." + +#~ msgid "" +#~ "All fields following this \"tab field\" (or until another \"tab field\" " +#~ "is defined) will be grouped together using this field's label as the tab " +#~ "heading." +#~ msgstr "" +#~ "Alla fält efter detta ”flikfält” (eller fram till nästa ”flikfält”) " +#~ "kommer att grupperas tillsammans genom fältets rubrik som flikrubrik." + +#~ msgid "None" +#~ msgstr "Ingen" + +#~ msgid "Taxonomy Term" +#~ msgstr "Taxonomivärde" + +#~ msgid "remove {layout}?" +#~ msgstr "ta bort {layout}?" + +#~ msgid "This field requires at least {min} {identifier}" +#~ msgstr "Detta fält kräver minst {min} {identifier}" + +#~ msgid "Maximum {label} limit reached ({max} {identifier})" +#~ msgstr "Maximal {label} gräns nåtts ({max} {identifier})" + +#~ msgid "http://www.elliotcondon.com/" +#~ msgstr "http://www.elliotcondon.com/" diff --git a/pro/acf-pro.php b/pro/acf-pro.php index dafd2e4..7a40243 100644 --- a/pro/acf-pro.php +++ b/pro/acf-pro.php @@ -1,181 +1,176 @@ -define( 'ACF_PRO', true ); - - - // update setting - acf_update_setting( 'pro', true ); - acf_update_setting( 'name', __('Advanced Custom Fields PRO', 'acf') ); - + class acf_pro { + + /* + * __construct + * + * + * + * @type function + * @date 23/06/12 + * @since 5.0.0 + * + * @param N/A + * @return N/A + */ + + function __construct() { + + // constants + acf()->define( 'ACF_PRO', true ); + + // update setting + acf_update_setting( 'pro', true ); + acf_update_setting( 'name', __( 'Advanced Custom Fields PRO', 'acf' ) ); + + // includes + acf_include( 'pro/blocks.php' ); + acf_include( 'pro/options-page.php' ); + acf_include( 'pro/updates.php' ); + + if ( is_admin() ) { + + acf_include( 'pro/admin/admin-options-page.php' ); + acf_include( 'pro/admin/admin-updates.php' ); + + } + + // actions + add_action( 'init', array( $this, 'register_assets' ) ); + add_action( 'acf/include_field_types', array( $this, 'include_field_types' ), 5 ); + add_action( 'acf/include_location_rules', array( $this, 'include_location_rules' ), 5 ); + add_action( 'acf/input/admin_enqueue_scripts', array( $this, 'input_admin_enqueue_scripts' ) ); + add_action( 'acf/field_group/admin_enqueue_scripts', array( $this, 'field_group_admin_enqueue_scripts' ) ); - // includes - acf_include('pro/blocks.php'); - acf_include('pro/options-page.php'); - acf_include('pro/updates.php'); - - if( is_admin() ) { - - acf_include('pro/admin/admin-options-page.php'); - acf_include('pro/admin/admin-updates.php'); - } - - - // actions - add_action('init', array($this, 'register_assets')); - add_action('acf/include_field_types', array($this, 'include_field_types'), 5); - add_action('acf/include_location_rules', array($this, 'include_location_rules'), 5); - add_action('acf/input/admin_enqueue_scripts', array($this, 'input_admin_enqueue_scripts')); - add_action('acf/field_group/admin_enqueue_scripts', array($this, 'field_group_admin_enqueue_scripts')); - - } - - - /* - * include_field_types - * - * description - * - * @type function - * @date 21/10/2015 - * @since 5.2.3 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function include_field_types() { - - acf_include('pro/fields/class-acf-field-repeater.php'); - acf_include('pro/fields/class-acf-field-flexible-content.php'); - acf_include('pro/fields/class-acf-field-gallery.php'); - acf_include('pro/fields/class-acf-field-clone.php'); - - } - - - /* - * include_location_rules - * - * description - * - * @type function - * @date 10/6/17 - * @since 5.6.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function include_location_rules() { - - acf_include('pro/locations/class-acf-location-block.php'); - acf_include('pro/locations/class-acf-location-options-page.php'); - - } - - - /* - * register_assets - * - * description - * - * @type function - * @date 4/11/2013 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function register_assets() { - - // vars - $version = acf_get_setting('version'); - $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - - - // register scripts - wp_register_script( 'acf-pro-input', acf_get_url( "assets/build/js/pro/acf-pro-input{$min}.js" ), array('acf-input'), $version ); - wp_register_script( 'acf-pro-field-group', acf_get_url( "assets/build/js/pro/acf-pro-field-group{$min}.js" ), array('acf-field-group'), $version ); - - - // register styles - wp_register_style( 'acf-pro-input', acf_get_url( 'assets/build/css/pro/acf-pro-input.css' ), array('acf-input'), $version ); - wp_register_style( 'acf-pro-field-group', acf_get_url( 'assets/build/css/pro/acf-pro-field-group.css' ), array('acf-input'), $version ); - - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 4/11/2013 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - wp_enqueue_script('acf-pro-input'); - wp_enqueue_style('acf-pro-input'); - - } - - - /* - * field_group_admin_enqueue_scripts - * - * description - * - * @type function - * @date 4/11/2013 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function field_group_admin_enqueue_scripts() { - - wp_enqueue_script('acf-pro-field-group'); - wp_enqueue_style('acf-pro-field-group'); - - } - -} -// instantiate -new acf_pro(); + /* + * include_field_types + * + * description + * + * @type function + * @date 21/10/2015 + * @since 5.2.3 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function include_field_types() { + + acf_include( 'pro/fields/class-acf-field-repeater.php' ); + acf_include( 'pro/fields/class-acf-field-flexible-content.php' ); + acf_include( 'pro/fields/class-acf-field-gallery.php' ); + acf_include( 'pro/fields/class-acf-field-clone.php' ); + + } -// end class + /* + * include_location_rules + * + * description + * + * @type function + * @date 10/6/17 + * @since 5.6.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function include_location_rules() { + + acf_include( 'pro/locations/class-acf-location-block.php' ); + acf_include( 'pro/locations/class-acf-location-options-page.php' ); + + } + + + /* + * register_assets + * + * description + * + * @type function + * @date 4/11/2013 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function register_assets() { + + // vars + $version = acf_get_setting( 'version' ); + $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + + // register scripts + wp_register_script( 'acf-pro-input', acf_get_url( "assets/build/js/pro/acf-pro-input{$min}.js" ), array( 'acf-input' ), $version ); + wp_register_script( 'acf-pro-field-group', acf_get_url( "assets/build/js/pro/acf-pro-field-group{$min}.js" ), array( 'acf-field-group' ), $version ); + + // register styles + wp_register_style( 'acf-pro-input', acf_get_url( 'assets/build/css/pro/acf-pro-input.css' ), array( 'acf-input' ), $version ); + wp_register_style( 'acf-pro-field-group', acf_get_url( 'assets/build/css/pro/acf-pro-field-group.css' ), array( 'acf-input' ), $version ); + + } + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 4/11/2013 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + wp_enqueue_script( 'acf-pro-input' ); + wp_enqueue_style( 'acf-pro-input' ); + + } + + + /* + * field_group_admin_enqueue_scripts + * + * description + * + * @type function + * @date 4/11/2013 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function field_group_admin_enqueue_scripts() { + + wp_enqueue_script( 'acf-pro-field-group' ); + wp_enqueue_style( 'acf-pro-field-group' ); + + } + + } + + + // instantiate + new acf_pro(); + + + // end class endif; -?> \ No newline at end of file + diff --git a/pro/admin/admin-options-page.php b/pro/admin/admin-options-page.php index 9b1184e..d3f34d0 100644 --- a/pro/admin/admin-options-page.php +++ b/pro/admin/admin-options-page.php @@ -1,274 +1,264 @@ page = acf_get_options_page( $plugin_page ); - - - // get post_id (allow lang modification) - $this->page['post_id'] = acf_get_valid_post_id($this->page['post_id']); - - - // verify and remove nonce - if( acf_verify_nonce('options') ) { - - // save data - if( acf_validate_save_post(true) ) { - - // set autoload - acf_update_setting('autoload', $this->page['autoload']); - - - // save - acf_save_post( $this->page['post_id'] ); - - - // redirect - wp_redirect( add_query_arg(array('message' => '1')) ); - exit; - - } - - } - - - // load acf scripts - acf_enqueue_scripts(); - - - // actions - add_action( 'acf/input/admin_enqueue_scripts', array($this,'admin_enqueue_scripts') ); - add_action( 'acf/input/admin_head', array($this,'admin_head') ); - - - // add columns support - add_screen_option('layout_columns', array('max' => 2, 'default' => 2)); - - } - - - /* - * admin_enqueue_scripts - * - * This function will enqueue the 'post.js' script which adds support for 'Screen Options' column toggle - * - * @type function - * @date 23/03/2016 - * @since 5.3.2 - * - * @param - * @return - */ - - function admin_enqueue_scripts() { - - wp_enqueue_script('post'); - - } - - - /* - * admin_head - * - * This action will find and add field groups to the current edit page - * - * @type action (admin_head) - * @date 23/06/12 - * @since 3.1.8 - * - * @param n/a - * @return n/a - */ - - function admin_head() { - - // get field groups - $field_groups = acf_get_field_groups(array( - 'options_page' => $this->page['menu_slug'] - )); - - - // notices - if( !empty($_GET['message']) && $_GET['message'] == '1' ) { - acf_add_admin_notice( $this->page['updated_message'], 'success' ); - } - - - // add submit div - add_meta_box('submitdiv', __('Publish','acf'), array($this, 'postbox_submitdiv'), 'acf_options_page', 'side', 'high'); - - - - if( empty($field_groups) ) { - - acf_add_admin_notice( sprintf( __('No Custom Field Groups found for this options page. Create a Custom Field Group', 'acf'), admin_url('post-new.php?post_type=acf-field-group') ), 'warning' ); - - } else { - - foreach( $field_groups as $i => $field_group ) { - - // vars - $id = "acf-{$field_group['key']}"; - $title = $field_group['title']; - $context = $field_group['position']; - $priority = 'high'; - $args = array( 'field_group' => $field_group ); - - - // tweaks to vars - if( $context == 'acf_after_title' ) { - - $context = 'normal'; - - } elseif( $context == 'side' ) { - - $priority = 'core'; - - } - - - // filter for 3rd party customization - $priority = apply_filters('acf/input/meta_box_priority', $priority, $field_group); - - - // add meta box - add_meta_box( $id, acf_esc_html( $title ), array($this, 'postbox_acf'), 'acf_options_page', $context, $priority, $args ); - - - } - // foreach - - } - // if - - } - - - /* - * postbox_submitdiv - * - * This function will render the submitdiv metabox - * - * @type function - * @date 23/03/2016 - * @since 5.3.2 - * - * @param n/a - * @return n/a - */ - - function postbox_submitdiv( $post, $args ) { - - /** - * Fires before the major-publishing-actions div. + class acf_admin_options_page { + + /** @var array Contains the current options page */ + var $page; + + + /* + * __construct * - * @date 24/9/18 - * @since 5.7.7 + * Initialize filters, action, variables and includes * - * @param array $page The current options page. + * @type function + * @date 23/06/12 + * @since 5.0.0 + * + * @param n/a + * @return n/a */ - do_action( 'acf/options_page/submitbox_before_major_actions', $this->page ); - ?> + + function __construct() { + + // add menu items + add_action( 'admin_menu', array( $this, 'admin_menu' ), 99, 0 ); + + } + + + /* + * admin_menu + * + * description + * + * @type function + * @date 24/02/2014 + * @since 5.0.0 + * + * @param + * @return + */ + + function admin_menu() { + + // vars + $pages = acf_get_options_pages(); + + // bail early if no pages + if ( empty( $pages ) ) { + return; + } + + // loop + foreach ( $pages as $page ) { + + // vars + $slug = ''; + + // parent + if ( empty( $page['parent_slug'] ) ) { + + $slug = add_menu_page( $page['page_title'], $page['menu_title'], $page['capability'], $page['menu_slug'], array( $this, 'html' ), $page['icon_url'], $page['position'] ); + + // child + } else { + + $slug = add_submenu_page( $page['parent_slug'], $page['page_title'], $page['menu_title'], $page['capability'], $page['menu_slug'], array( $this, 'html' ), $page['position'] ); + + } + + // actions + add_action( "load-{$slug}", array( $this, 'admin_load' ) ); + + } + + } + + + /* + * load + * + * description + * + * @type function + * @date 2/02/13 + * @since 3.6 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function admin_load() { + + // globals + global $plugin_page; + + // vars + $this->page = acf_get_options_page( $plugin_page ); + + // get post_id (allow lang modification) + $this->page['post_id'] = acf_get_valid_post_id( $this->page['post_id'] ); + + // verify and remove nonce + if ( acf_verify_nonce( 'options' ) ) { + + // save data + if ( acf_validate_save_post( true ) ) { + + // set autoload + acf_update_setting( 'autoload', $this->page['autoload'] ); + + // save + acf_save_post( $this->page['post_id'] ); + + // redirect + wp_redirect( add_query_arg( array( 'message' => '1' ) ) ); + exit; + + } + } + + // load acf scripts + acf_enqueue_scripts(); + + // actions + add_action( 'acf/input/admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_action( 'acf/input/admin_head', array( $this, 'admin_head' ) ); + + // add columns support + add_screen_option( + 'layout_columns', + array( + 'max' => 2, + 'default' => 2, + ) + ); + + } + + + /* + * admin_enqueue_scripts + * + * This function will enqueue the 'post.js' script which adds support for 'Screen Options' column toggle + * + * @type function + * @date 23/03/2016 + * @since 5.3.2 + * + * @param + * @return + */ + + function admin_enqueue_scripts() { + + wp_enqueue_script( 'post' ); + + } + + + /* + * admin_head + * + * This action will find and add field groups to the current edit page + * + * @type action (admin_head) + * @date 23/06/12 + * @since 3.1.8 + * + * @param n/a + * @return n/a + */ + + function admin_head() { + + // get field groups + $field_groups = acf_get_field_groups( + array( + 'options_page' => $this->page['menu_slug'], + ) + ); + + // notices + if ( ! empty( $_GET['message'] ) && $_GET['message'] == '1' ) { + acf_add_admin_notice( $this->page['updated_message'], 'success' ); + } + + // add submit div + add_meta_box( 'submitdiv', __( 'Publish', 'acf' ), array( $this, 'postbox_submitdiv' ), 'acf_options_page', 'side', 'high' ); + + if ( empty( $field_groups ) ) { + + acf_add_admin_notice( sprintf( __( 'No Custom Field Groups found for this options page. Create a Custom Field Group', 'acf' ), admin_url( 'post-new.php?post_type=acf-field-group' ) ), 'warning' ); + + } else { + + foreach ( $field_groups as $i => $field_group ) { + + // vars + $id = "acf-{$field_group['key']}"; + $title = $field_group['title']; + $context = $field_group['position']; + $priority = 'high'; + $args = array( 'field_group' => $field_group ); + + // tweaks to vars + if ( $context == 'acf_after_title' ) { + + $context = 'normal'; + + } elseif ( $context == 'side' ) { + + $priority = 'core'; + + } + + // filter for 3rd party customization + $priority = apply_filters( 'acf/input/meta_box_priority', $priority, $field_group ); + + // add meta box + add_meta_box( $id, acf_esc_html( $title ), array( $this, 'postbox_acf' ), 'acf_options_page', $context, $priority, $args ); + + } + // foreach + + } + // if + } + + + /* + * postbox_submitdiv + * + * This function will render the submitdiv metabox + * + * @type function + * @date 23/03/2016 + * @since 5.3.2 + * + * @param n/a + * @return n/a + */ + + function postbox_submitdiv( $post, $args ) { + + /** + * Fires before the major-publishing-actions div. + * + * @date 24/9/18 + * @since 5.7.7 + * + * @param array $page The current options page. + */ + do_action( 'acf/options_page/submitbox_before_major_actions', $this->page ); + ?>

                                @@ -278,107 +268,101 @@ class acf_admin_options_page { page ); ?>
                                - $id, - 'key' => $field_group['key'], - 'style' => $field_group['style'], - 'label' => $field_group['label_placement'], - 'editLink' => '', - 'editTitle' => __('Edit field group', 'acf'), - 'visibility' => true - ); - - - // edit_url - if( $field_group['ID'] && acf_current_user_can_admin() ) { - - $o['editLink'] = admin_url('post.php?post=' . $field_group['ID'] . '&action=edit'); - + page['post_id'], 'div', $field_group['instruction_placement'] ); - - - -?> + + + /* + * render_meta_box + * + * description + * + * @type function + * @date 24/02/2014 + * @since 5.0.0 + * + * @param $post (object) + * @param $args (array) + * @return n/a + */ + + function postbox_acf( $post, $args ) { + + // extract args + extract( $args ); // all variables from the add_meta_box function + extract( $args ); // all variables from the args argument + + // vars + $o = array( + 'id' => $id, + 'key' => $field_group['key'], + 'style' => $field_group['style'], + 'label' => $field_group['label_placement'], + 'editLink' => '', + 'editTitle' => __( 'Edit field group', 'acf' ), + 'visibility' => true, + ); + + // edit_url + if ( $field_group['ID'] && acf_current_user_can_admin() ) { + + $o['editLink'] = admin_url( 'post.php?post=' . $field_group['ID'] . '&action=edit' ); + + } + + // load fields + $fields = acf_get_fields( $field_group ); + + // render + acf_render_fields( $fields, $this->page['post_id'], 'div', $field_group['instruction_placement'] ); + + ?> -page); - - } - - -} + page ); + + } + + + } + + + // initialize + new acf_admin_options_page(); endif; -?> \ No newline at end of file +?> diff --git a/pro/admin/admin-updates.php b/pro/admin/admin-updates.php index e6758d1..9c82c19 100644 --- a/pro/admin/admin-updates.php +++ b/pro/admin/admin-updates.php @@ -1,339 +1,344 @@ - __('Error. Could not connect to update server', 'acf') . ' (' . esc_html( $wp_error->get_error_message() ) . ').', - 'type' => 'error' - )); - } - - /** - * get_changelog_changes - * - * Finds the specific changes for a given version from the provided changelog snippet. - * - * @date 14/1/19 - * @since 5.7.10 - * - * @param string $changelog The changelog text. - * @param string $version The version to find. - * @return string - */ - function get_changelog_changes( $changelog = '', $version = '' ) { - - // Explode changelog into sections. - $bits = array_filter( explode('

                                ', $changelog) ); - - // Loop over each version chunk. - foreach( $bits as $bit ) { - - // Find the version number for this chunk. - $bit = explode('

                                ', $bit); - $bit_version = trim( $bit[0] ); - $bit_text = trim( $bit[1] ); - - // Compare the chunk version number against param and return HTML. - if( acf_version_compare($bit_version, '==', $version) ) { - return '

                                ' . esc_html($bit_version) . '

                                ' . acf_esc_html($bit_text); - } - } - - // Return. - return ''; - } - - /** - * admin_menu - * - * Adds the admin menu subpage. - * - * @date 28/09/13 - * @since 5.0.0 - * - * @param void - * @return void - */ - function admin_menu() { - - // Bail early if no show_admin. - if( !acf_get_setting('show_admin') ) { - return; - } - - // Bail early if no show_updates. - if( !acf_get_setting('show_updates') ) { - return; - } - - // Bail early if not a plugin (included in theme). - if( !acf_is_plugin_active() ) { - return; - } - - // Add submenu. - $page = add_submenu_page( 'edit.php?post_type=acf-field-group', __('Updates','acf'), __('Updates','acf'), acf_get_setting('capability'), 'acf-settings-updates', array($this,'html') ); - - // Add actions to page. - add_action( "load-$page", array($this,'load') ); - } - - /** - * load - * - * Runs when loading the submenu page. - * - * @date 7/01/2014 - * @since 5.0.0 - * - * @param void - * @return void - */ - function load() { - - // Check activate. - if( acf_verify_nonce('activate_pro_licence') ) { - $this->activate_pro_licence(); - - // Check deactivate. - } elseif( acf_verify_nonce('deactivate_pro_licence') ) { - $this->deactivate_pro_licence(); - } - - // vars - $license = acf_pro_get_license_key(); - $this->view = array( - 'license' => $license, - 'active' => $license ? 1 : 0, - 'current_version' => acf_get_setting('version'), - 'remote_version' => '', - 'update_available' => false, - 'changelog' => '', - 'upgrade_notice' => '' - ); - - // get plugin updates - $force_check = !empty( $_GET['force-check'] ); - $info = acf_updates()->get_plugin_info('pro', $force_check); - - // Display error. - if( is_wp_error($info) ) { - return $this->display_wp_error( $info ); - } - - // add info to view - $this->view['remote_version'] = $info['version']; - - // add changelog if the remote version is '>' than the current version - $version = acf_get_setting('version'); - - // check if remote version is higher than current version - if( version_compare($info['version'], $version, '>') ) { - - // update view - $this->view['update_available'] = true; - $this->view['changelog'] = $this->get_changelog_changes($info['changelog'], $info['version']); - $this->view['upgrade_notice'] = $this->get_changelog_changes($info['upgrade_notice'], $info['version']); - - // perform update checks if license is active - $basename = acf_get_setting('basename'); - $update = acf_updates()->get_plugin_update( $basename ); - if( $license ) { - - // display error if no package url - // - possible if license key has been modified - if( $update && !$update['package'] ) { - $this->view['update_available'] = false; - acf_new_admin_notice(array( - 'text' => __('Error. Could not authenticate update package. Please check again or deactivate and reactivate your ACF PRO license.', 'acf'), - 'type' => 'error' - )); - } - - // refresh transient - // - if no update exists in the transient - // - or if the transient 'new_version' is stale - if( !$update || $update['new_version'] !== $info['version'] ) { - acf_updates()->refresh_plugins_transient(); - } - } - } - } - - /** - * activate_pro_licence - * - * Activates the submitted license key. - * - * @date 16/01/2014 - * @since 5.0.0 - * - * @param void - * @return void - */ - function activate_pro_licence() { - - // Connect to API. - $post = array( - 'acf_license' => trim($_POST['acf_pro_licence']), - 'acf_version' => acf_get_setting('version'), - 'wp_name' => get_bloginfo('name'), - 'wp_url' => home_url(), - 'wp_version' => get_bloginfo('version'), - 'wp_language' => get_bloginfo('language'), - 'wp_timezone' => get_option('timezone_string'), - ); - $response = acf_updates()->request('v2/plugins/activate?p=pro', $post); - - // Check response is expected JSON array (not string). - if( is_string($response) ) { - $response = new WP_Error( 'server_error', esc_html($response) ); - } - - // Display error. - if( is_wp_error($response) ) { - return $this->display_wp_error( $response ); - } - - // On success. - if( $response['status'] == 1 ) { - - // Update license. - acf_pro_update_license( $response['license'] ); - - // Refresh plugins transient to fetch new update data. - acf_updates()->refresh_plugins_transient(); - - // Show notice. - acf_add_admin_notice( $response['message'], 'success' ); - - // On failure. - } else { - - // Show notice. - acf_add_admin_notice( $response['message'], 'warning' ); - } - } - - /** - * activate_pro_licence - * - * Deactivates the registered license key. - * - * @date 16/01/2014 - * @since 5.0.0 - * - * @param void - * @return void - */ - function deactivate_pro_licence() { - - // Get license key. - $license = acf_pro_get_license_key(); - - // Bail early if no key. - if( !$license ) { - return; - } - - // Connect to API. - $post = array( - 'acf_license' => $license, - 'wp_url' => home_url(), - ); - $response = acf_updates()->request('v2/plugins/deactivate?p=pro', $post); - - - // Check response is expected JSON array (not string). - if( is_string($response) ) { - $response = new WP_Error( 'server_error', esc_html($response) ); - } - - // Display error. - if( is_wp_error($response) ) { - return $this->display_wp_error( $response ); - } - - // Remove license key from DB. - acf_pro_update_license(''); - - // Refresh plugins transient to fetch new update data. - acf_updates()->refresh_plugins_transient(); - - // On success. - if( $response['status'] == 1 ) { - - // Show notice. - acf_add_admin_notice( $response['message'], 'info' ); - - // On failure. - } else { - - // Show notice. - acf_add_admin_notice( $response['message'], 'warning' ); - } - } - - /** - * html - * - * Displays the submenu page's HTML. - * - * @date 7/01/2014 - * @since 5.0.0 - * - * @param void - * @return void - */ - function html() { - acf_get_view( dirname(__FILE__) . '/views/html-settings-updates.php', $this->view); - } +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly } -// Initialize. -acf_new_instance('ACF_Admin_Updates'); +if ( ! class_exists( 'ACF_Admin_Updates' ) ) : + + class ACF_Admin_Updates { + + /** @var array Data used in the view. */ + var $view = array(); + + /** + * __construct + * + * Sets up the class functionality. + * + * @date 23/06/12 + * @since 5.0.0 + * + * @param void + * @return void + */ + function __construct() { + + // Add actions. + add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 ); + } + + /** + * display_wp_error + * + * Adds an admin notice using the provided WP_Error. + * + * @date 14/1/19 + * @since 5.7.10 + * + * @param WP_Error $wp_error The error to display. + * @return void + */ + function display_wp_error( $wp_error ) { + + // Only show one error on page. + if ( acf_has_done( 'display_wp_error' ) ) { + return; + } + + // Create new notice. + acf_new_admin_notice( + array( + 'text' => __( 'Error. Could not connect to update server', 'acf' ) . ' (' . esc_html( $wp_error->get_error_message() ) . ').', + 'type' => 'error', + ) + ); + } + + /** + * get_changelog_changes + * + * Finds the specific changes for a given version from the provided changelog snippet. + * + * @date 14/1/19 + * @since 5.7.10 + * + * @param string $changelog The changelog text. + * @param string $version The version to find. + * @return string + */ + function get_changelog_changes( $changelog = '', $version = '' ) { + + // Explode changelog into sections. + $bits = array_filter( explode( '

                                ', $changelog ) ); + + // Loop over each version chunk. + foreach ( $bits as $bit ) { + + // Find the version number for this chunk. + $bit = explode( '

                                ', $bit ); + $bit_version = trim( $bit[0] ); + $bit_text = trim( $bit[1] ); + + // Compare the chunk version number against param and return HTML. + if ( acf_version_compare( $bit_version, '==', $version ) ) { + return '

                                ' . esc_html( $bit_version ) . '

                                ' . acf_esc_html( $bit_text ); + } + } + + // Return. + return ''; + } + + /** + * admin_menu + * + * Adds the admin menu subpage. + * + * @date 28/09/13 + * @since 5.0.0 + * + * @param void + * @return void + */ + function admin_menu() { + + // Bail early if no show_admin. + if ( ! acf_get_setting( 'show_admin' ) ) { + return; + } + + // Bail early if no show_updates. + if ( ! acf_get_setting( 'show_updates' ) ) { + return; + } + + // Bail early if not a plugin (included in theme). + if ( ! acf_is_plugin_active() ) { + return; + } + + // Add submenu. + $page = add_submenu_page( 'edit.php?post_type=acf-field-group', __( 'Updates', 'acf' ), __( 'Updates', 'acf' ), acf_get_setting( 'capability' ), 'acf-settings-updates', array( $this, 'html' ) ); + + // Add actions to page. + add_action( "load-$page", array( $this, 'load' ) ); + } + + /** + * load + * + * Runs when loading the submenu page. + * + * @date 7/01/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function load() { + + // Check activate. + if ( acf_verify_nonce( 'activate_pro_licence' ) ) { + $this->activate_pro_licence(); + + // Check deactivate. + } elseif ( acf_verify_nonce( 'deactivate_pro_licence' ) ) { + $this->deactivate_pro_licence(); + } + + // vars + $license = acf_pro_get_license_key(); + $this->view = array( + 'license' => $license, + 'active' => $license ? 1 : 0, + 'current_version' => acf_get_setting( 'version' ), + 'remote_version' => '', + 'update_available' => false, + 'changelog' => '', + 'upgrade_notice' => '', + ); + + // get plugin updates + $force_check = ! empty( $_GET['force-check'] ); + $info = acf_updates()->get_plugin_info( 'pro', $force_check ); + + // Display error. + if ( is_wp_error( $info ) ) { + return $this->display_wp_error( $info ); + } + + // add info to view + $this->view['remote_version'] = $info['version']; + + // add changelog if the remote version is '>' than the current version + $version = acf_get_setting( 'version' ); + + // check if remote version is higher than current version + if ( version_compare( $info['version'], $version, '>' ) ) { + + // update view + $this->view['update_available'] = true; + $this->view['changelog'] = $this->get_changelog_changes( $info['changelog'], $info['version'] ); + $this->view['upgrade_notice'] = $this->get_changelog_changes( $info['upgrade_notice'], $info['version'] ); + + // perform update checks if license is active + $basename = acf_get_setting( 'basename' ); + $update = acf_updates()->get_plugin_update( $basename ); + if ( $license ) { + + // display error if no package url + // - possible if license key has been modified + if ( $update && ! $update['package'] ) { + $this->view['update_available'] = false; + acf_new_admin_notice( + array( + 'text' => __( 'Error. Could not authenticate update package. Please check again or deactivate and reactivate your ACF PRO license.', 'acf' ), + 'type' => 'error', + ) + ); + } + + // refresh transient + // - if no update exists in the transient + // - or if the transient 'new_version' is stale + if ( ! $update || $update['new_version'] !== $info['version'] ) { + acf_updates()->refresh_plugins_transient(); + } + } + } + } + + /** + * activate_pro_licence + * + * Activates the submitted license key. + * + * @date 16/01/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function activate_pro_licence() { + + // Connect to API. + $post = array( + 'acf_license' => trim( $_POST['acf_pro_licence'] ), + 'acf_version' => acf_get_setting( 'version' ), + 'wp_name' => get_bloginfo( 'name' ), + 'wp_url' => home_url(), + 'wp_version' => get_bloginfo( 'version' ), + 'wp_language' => get_bloginfo( 'language' ), + 'wp_timezone' => get_option( 'timezone_string' ), + ); + $response = acf_updates()->request( 'v2/plugins/activate?p=pro', $post ); + + // Check response is expected JSON array (not string). + if ( is_string( $response ) ) { + $response = new WP_Error( 'server_error', esc_html( $response ) ); + } + + // Display error. + if ( is_wp_error( $response ) ) { + return $this->display_wp_error( $response ); + } + + // On success. + if ( $response['status'] == 1 ) { + + // Update license. + acf_pro_update_license( $response['license'] ); + + // Refresh plugins transient to fetch new update data. + acf_updates()->refresh_plugins_transient(); + + // Show notice. + acf_add_admin_notice( $response['message'], 'success' ); + + // On failure. + } else { + + // Show notice. + acf_add_admin_notice( $response['message'], 'warning' ); + } + } + + /** + * activate_pro_licence + * + * Deactivates the registered license key. + * + * @date 16/01/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function deactivate_pro_licence() { + + // Get license key. + $license = acf_pro_get_license_key(); + + // Bail early if no key. + if ( ! $license ) { + return; + } + + // Connect to API. + $post = array( + 'acf_license' => $license, + 'wp_url' => home_url(), + ); + $response = acf_updates()->request( 'v2/plugins/deactivate?p=pro', $post ); + + // Check response is expected JSON array (not string). + if ( is_string( $response ) ) { + $response = new WP_Error( 'server_error', esc_html( $response ) ); + } + + // Display error. + if ( is_wp_error( $response ) ) { + return $this->display_wp_error( $response ); + } + + // Remove license key from DB. + acf_pro_update_license( '' ); + + // Refresh plugins transient to fetch new update data. + acf_updates()->refresh_plugins_transient(); + + // On success. + if ( $response['status'] == 1 ) { + + // Show notice. + acf_add_admin_notice( $response['message'], 'info' ); + + // On failure. + } else { + + // Show notice. + acf_add_admin_notice( $response['message'], 'warning' ); + } + } + + /** + * html + * + * Displays the submenu page's HTML. + * + * @date 7/01/2014 + * @since 5.0.0 + * + * @param void + * @return void + */ + function html() { + acf_get_view( dirname( __FILE__ ) . '/views/html-settings-updates.php', $this->view ); + } + } + + // Initialize. + acf_new_instance( 'ACF_Admin_Updates' ); endif; // class_exists check diff --git a/pro/admin/views/html-options-page.php b/pro/admin/views/html-options-page.php index d9fbf72..851aac4 100644 --- a/pro/admin/views/html-options-page.php +++ b/pro/admin/views/html-options-page.php @@ -4,17 +4,19 @@ - 'options', - 'post_id' => $post_id, - )); - + acf_form_data( + array( + 'screen' => 'options', + 'post_id' => $post_id, + ) + ); + wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); - + ?>
                                @@ -23,13 +25,13 @@
                                - +
                                - +
                                @@ -41,4 +43,4 @@ -
                                \ No newline at end of file +
                                diff --git a/pro/admin/views/html-settings-updates.php b/pro/admin/views/html-settings-updates.php index b71f483..be2d27b 100644 --- a/pro/admin/views/html-settings-updates.php +++ b/pro/admin/views/html-settings-updates.php @@ -1,41 +1,43 @@ -
                                -

                                +

                                -

                                +

                                -

                                details & pricing.','acf'), esc_url('https://www.advancedcustomfields.com/pro/?utm_source=ACF%2Bpro%2Bplugin&utm_medium=insideplugin&utm_campaign=ACF%2Bupgrade&utm_content=license%2Bactivations')); ?>

                                +

                                details & pricing.', 'acf' ), esc_url( 'https://www.advancedcustomfields.com/pro/?utm_source=ACF%2Bpro%2Bplugin&utm_medium=insideplugin&utm_campaign=ACF%2Bupgrade&utm_content=license%2Bactivations' ) ); ?>

                                @@ -48,71 +50,71 @@ $readonly = $active ? 1 : 0;
                                - + - 'text', - 'name' => 'acf_pro_licence', - 'value' => str_repeat('*', strlen($license)), - 'readonly' => $readonly - )); - + acf_render_field( + array( + 'type' => 'text', + 'name' => 'acf_pro_licence', + 'value' => str_repeat( '*', strlen( $license ) ), + 'readonly' => $readonly, + ) + ); + ?>
                                - +
                                -

                                +

                                - - - + + + - + - + - + - + - + - + @@ -131,4 +133,4 @@ $readonly = $active ? 1 : 0; #acf-update-information td h4 { display: none; } - \ No newline at end of file + diff --git a/pro/blocks.php b/pro/blocks.php old mode 100644 new mode 100755 index 68b027b..9dba8e7 --- a/pro/blocks.php +++ b/pro/blocks.php @@ -6,60 +6,63 @@ defined( 'ABSPATH' ) || exit; // Register store. acf_register_store( 'block-types' ); acf_register_store( 'block-cache' ); - + /** * acf_register_block_type * * Registers a block type. * - * @date 18/2/19 - * @since 5.8.0 + * @date 18/2/19 + * @since 5.8.0 * - * @param array $block The block settings. - * @return (array|false) + * @param array $block The block settings. + * @return (array|false) */ function acf_register_block_type( $block ) { - + // Validate block type settings. $block = acf_validate_block_type( $block ); - + /** * Filters the arguments for registering a block type. * - * @since 5.8.9 + * @since 5.8.9 * - * @param array $block The array of arguments for registering a block type. + * @param array $block The array of arguments for registering a block type. */ - $block = apply_filters( 'acf/register_block_type_args', $block ); - - // Require name. - if( !$block['name'] ) { - $message = __( 'Block type name is required.', 'acf' ); - _doing_it_wrong( __FUNCTION__, $message, '5.8.0' ); + $block = apply_filters( 'acf/register_block_type_args', $block ); + + // Require name. + if ( ! $block['name'] ) { + $message = __( 'Block type name is required.', 'acf' ); + _doing_it_wrong( __FUNCTION__, $message, '5.8.0' ); return false; - } - + } + // Bail early if already exists. - if( acf_has_block_type($block['name']) ) { + if ( acf_has_block_type( $block['name'] ) ) { $message = sprintf( __( 'Block type "%s" is already registered.' ), $block['name'] ); _doing_it_wrong( __FUNCTION__, $message, '5.8.0' ); return false; } - + // Add to storage. acf_get_store( 'block-types' )->set( $block['name'], $block ); - + // Register block type in WP. - if( function_exists('register_block_type') ) { - register_block_type($block['name'], array( - 'attributes' => acf_get_block_type_default_attributes( $block ), - 'render_callback' => 'acf_render_block_callback', - )); + if ( function_exists( 'register_block_type' ) ) { + register_block_type( + $block['name'], + array( + 'attributes' => acf_get_block_type_default_attributes( $block ), + 'render_callback' => 'acf_render_block_callback', + ) + ); } - + // Register action. add_action( 'enqueue_block_editor_assets', 'acf_enqueue_block_assets' ); - + // Return block. return $block; } @@ -69,11 +72,11 @@ function acf_register_block_type( $block ) { * * See acf_register_block_type(). * - * @date 18/2/19 - * @since 5.7.12 + * @date 18/2/19 + * @since 5.7.12 * - * @param array $block The block settings. - * @return (array|false) + * @param array $block The block settings. + * @return (array|false) */ function acf_register_block( $block ) { return acf_register_block_type( $block ); @@ -84,11 +87,11 @@ function acf_register_block( $block ) { * * Returns true if a block type exists for the given name. * - * @date 18/2/19 - * @since 5.7.12 + * @date 18/2/19 + * @since 5.7.12 * - * @param string $name The block type name. - * @return bool + * @param string $name The block type name. + * @return bool */ function acf_has_block_type( $name ) { return acf_get_store( 'block-types' )->has( $name ); @@ -99,11 +102,11 @@ function acf_has_block_type( $name ) { * * Returns an array of all registered block types. * - * @date 18/2/19 - * @since 5.7.12 + * @date 18/2/19 + * @since 5.7.12 * - * @param void - * @return array + * @param void + * @return array */ function acf_get_block_types() { return acf_get_store( 'block-types' )->get(); @@ -114,11 +117,11 @@ function acf_get_block_types() { * * Returns a block type for the given name. * - * @date 18/2/19 - * @since 5.7.12 + * @date 18/2/19 + * @since 5.7.12 * - * @param string $name The block type name. - * @return (array|null) + * @param string $name The block type name. + * @return (array|null) */ function acf_get_block_type( $name ) { return acf_get_store( 'block-types' )->get( $name ); @@ -129,11 +132,11 @@ function acf_get_block_type( $name ) { * * Removes a block type for the given name. * - * @date 18/2/19 - * @since 5.7.12 + * @date 18/2/19 + * @since 5.7.12 * - * @param string $name The block type name. - * @return void + * @param string $name The block type name. + * @return void */ function acf_remove_block_type( $name ) { acf_get_store( 'block-types' )->remove( $name ); @@ -144,45 +147,45 @@ function acf_remove_block_type( $name ) { * * Returns an array of default attribute settings for a block type. * - * @date 19/11/18 - * @since 5.8.0 + * @date 19/11/18 + * @since 5.8.0 * - * @param void - * @return array + * @param void + * @return array */ function acf_get_block_type_default_attributes( $block_type ) { $attributes = array( - 'id' => array( - 'type' => 'string', - 'default' => '', + 'id' => array( + 'type' => 'string', + 'default' => '', ), - 'name' => array( - 'type' => 'string', - 'default' => '', + 'name' => array( + 'type' => 'string', + 'default' => '', ), - 'data' => array( - 'type' => 'object', - 'default' => array(), + 'data' => array( + 'type' => 'object', + 'default' => array(), ), - 'align' => array( - 'type' => 'string', - 'default' => '', + 'align' => array( + 'type' => 'string', + 'default' => '', + ), + 'mode' => array( + 'type' => 'string', + 'default' => '', ), - 'mode' => array( - 'type' => 'string', - 'default' => '', - ) ); - if( !empty( $block_type['supports']['align_text'] ) ) { + if ( ! empty( $block_type['supports']['align_text'] ) ) { $attributes['align_text'] = array( - 'type' => 'string', - 'default' => '', + 'type' => 'string', + 'default' => '', ); } - if( !empty( $block_type['supports']['align_content'] ) ) { + if ( ! empty( $block_type['supports']['align_content'] ) ) { $attributes['align_content'] = array( - 'type' => 'string', - 'default' => '', + 'type' => 'string', + 'default' => '', ); } return $attributes; @@ -193,55 +196,61 @@ function acf_get_block_type_default_attributes( $block_type ) { * * Validates a block type ensuring all settings exist. * - * @date 10/4/18 - * @since 5.8.0 + * @date 10/4/18 + * @since 5.8.0 * - * @param array $block The block settings. - * @return array + * @param array $block The block settings. + * @return array */ function acf_validate_block_type( $block ) { - + // Add default settings. - $block = wp_parse_args($block, array( - 'name' => '', - 'title' => '', - 'description' => '', - 'category' => 'common', - 'icon' => '', - 'mode' => 'preview', - 'align' => '', - 'keywords' => array(), - 'supports' => array(), - 'post_types' => array(), - 'render_template' => false, - 'render_callback' => false, - 'enqueue_style' => false, - 'enqueue_script' => false, - 'enqueue_assets' => false, - )); - + $block = wp_parse_args( + $block, + array( + 'name' => '', + 'title' => '', + 'description' => '', + 'category' => 'common', + 'icon' => '', + 'mode' => 'preview', + 'align' => '', + 'keywords' => array(), + 'supports' => array(), + 'post_types' => array(), + 'render_template' => false, + 'render_callback' => false, + 'enqueue_style' => false, + 'enqueue_script' => false, + 'enqueue_assets' => false, + ) + ); + // Restrict keywords to 3 max to avoid JS error in older versions. - if( acf_version_compare('wp', '<', '5.2') ) { - $block['keywords'] = array_slice($block['keywords'], 0, 3); + if ( acf_version_compare( 'wp', '<', '5.2' ) ) { + $block['keywords'] = array_slice( $block['keywords'], 0, 3 ); } - + // Generate name with prefix. - if( $block['name'] ) { - $block['name'] = 'acf/' . acf_slugify($block['name']); + if ( $block['name'] ) { + $block['name'] = 'acf/' . acf_slugify( $block['name'] ); } - + // Add default 'supports' settings. - $block['supports'] = wp_parse_args($block['supports'], array( - 'align' => true, - 'html' => false, - 'mode' => true, - )); + $block['supports'] = wp_parse_args( + $block['supports'], + array( + 'align' => true, + 'html' => false, + 'mode' => true, + ) + ); // Correct "Experimental" flags. - if( isset($block['supports']['__experimental_jsx']) ) { + if ( isset( $block['supports']['__experimental_jsx'] ) ) { $block['supports']['jsx'] = $block['supports']['__experimental_jsx']; } - + // Return block. return $block; } @@ -251,34 +260,40 @@ function acf_validate_block_type( $block ) { * * Prepares a block for use in render_callback by merging in all settings and attributes. * - * @date 19/11/18 - * @since 5.8.0 + * @date 19/11/18 + * @since 5.8.0 * - * @param array $block The block props. - * @return array + * @param array $block The block props. + * @return array */ function acf_prepare_block( $block ) { - + // Bail early if no name. - if( !isset($block['name']) ) { + if ( ! isset( $block['name'] ) ) { return false; } - + + // Replace className with wpClassName if it's set. This enables support for blocks API v2 filters. + if ( isset( $block['wpClassName'] ) ) { + $block['className'] = $block['wpClassName']; + unset( $block['wpClassName'] ); + } + // Get block type and return false if doesn't exist. $block_type = acf_get_block_type( $block['name'] ); - if( !$block_type ) { + if ( ! $block_type ) { return false; } - + // Generate default attributes. $attributes = array(); - foreach( acf_get_block_type_default_attributes($block_type) as $k => $v ) { + foreach ( acf_get_block_type_default_attributes( $block_type ) as $k => $v ) { $attributes[ $k ] = $v['default']; } - + // Merge together arrays in order of least to most specific. - $block = array_merge($block_type, $attributes, $block); - + $block = array_merge( $block_type, $attributes, $block ); + // Return block. return $block; } @@ -286,23 +301,23 @@ function acf_prepare_block( $block ) { /** * The render callback for all ACF blocks. * - * @date 28/10/20 - * @since 5.9.2 + * @date 28/10/20 + * @since 5.9.2 * - * @param array $attributes The block attributes. - * @param string $content The block content. - * @param WP_Block $wp_block The block instance (since WP 5.5). - * @return string The block HTML. + * @param array $attributes The block attributes. + * @param string $content The block content. + * @param WP_Block $wp_block The block instance (since WP 5.5). + * @return string The block HTML. */ function acf_render_block_callback( $attributes, $content = '', $wp_block = null ) { $is_preview = false; - $post_id = get_the_ID(); - + $post_id = get_the_ID(); + // Set preview flag to true when rendering for the block editor. - if( is_admin() && acf_is_block_editor() ) { + if ( is_admin() && acf_is_block_editor() ) { $is_preview = true; } - + // Return rendered block HTML. return acf_rendered_block( $attributes, $content, $is_preview, $post_id, $wp_block ); } @@ -310,87 +325,106 @@ function acf_render_block_callback( $attributes, $content = '', $wp_block = null /** * Returns the rendered block HTML. * - * @date 28/2/19 - * @since 5.7.13 + * @date 28/2/19 + * @since 5.7.13 * - * @param array $attributes The block attributes. - * @param string $content The block content. - * @param bool $is_preview Whether or not the block is being rendered for editing preview. - * @param int $post_id The current post being edited or viewed. - * @param WP_Block $wp_block The block instance (since WP 5.5). - * @return string The block HTML. + * @param array $attributes The block attributes. + * @param string $content The block content. + * @param bool $is_preview Whether or not the block is being rendered for editing preview. + * @param int $post_id The current post being edited or viewed. + * @param WP_Block $wp_block The block instance (since WP 5.5). + * @return string The block HTML. */ function acf_rendered_block( $attributes, $content = '', $is_preview = false, $post_id = 0, $wp_block = null ) { - - // Capture block render output. + $mode = isset( $attributes['mode'] ) ? $attributes['mode'] : 'auto'; + ob_start(); - acf_render_block( $attributes, $content, $is_preview, $post_id, $wp_block ); + + if ( 'edit' === $mode && $is_preview ) { + // Load the block form since we're in edit mode. + $block = acf_prepare_block( $attributes ); + acf_setup_meta( $block['data'], $block['id'], true ); + $fields = acf_get_block_fields( $block ); + acf_prefix_fields( $fields, "acf-{$block['id']}" ); + + echo '
                                '; + acf_render_fields( $fields, $block['id'], 'div', 'field' ); + echo '
                                '; + } else { + // Capture block render output. + acf_render_block( $attributes, $content, $is_preview, $post_id, $wp_block ); + } + $html = ob_get_clean(); + if ( 'preview' === $mode && $is_preview ) { + $html = '
                                ' . $html . '
                                '; + } + // Replace placeholder on front-end. - if( !$is_preview ) { + if ( ! $is_preview ) { // Escape "$" character to avoid "capture group" interpretation. $content = str_replace( '$', '\$', $content ); - $html = preg_replace( '//', $content, $html ); + $html = preg_replace( '//', $content, $html ); } - + // Store in cache for preloading. - acf_get_store( 'block-cache' )->set( $attributes['id'], '
                                ' . $html . '
                                ' ); + acf_get_store( 'block-cache' )->set( $attributes['id'], $html ); return $html; } /** * Renders the block HTML. * - * @date 19/2/19 - * @since 5.7.12 + * @date 19/2/19 + * @since 5.7.12 * - * @param array $attributes The block attributes. - * @param string $content The block content. - * @param bool $is_preview Whether or not the block is being rendered for editing preview. - * @param int $post_id The current post being edited or viewed. - * @param WP_Block $wp_block The block instance (since WP 5.5). - * @return void + * @param array $attributes The block attributes. + * @param string $content The block content. + * @param bool $is_preview Whether or not the block is being rendered for editing preview. + * @param int $post_id The current post being edited or viewed. + * @param WP_Block $wp_block The block instance (since WP 5.5). + * @return void */ function acf_render_block( $attributes, $content = '', $is_preview = false, $post_id = 0, $wp_block = null ) { - + // Prepare block ensuring all settings and attributes exist. $block = acf_prepare_block( $attributes ); - if( !$block ) { + if ( ! $block ) { return ''; } - + // Find post_id if not defined. - if( !$post_id ) { + if ( ! $post_id ) { $post_id = get_the_ID(); } - + // Enqueue block type assets. acf_enqueue_block_type_assets( $block ); - + // Setup postdata allowing get_field() to work. acf_setup_meta( $block['data'], $block['id'], true ); - + // Call render_callback. - if( is_callable( $block['render_callback'] ) ) { + if ( is_callable( $block['render_callback'] ) ) { call_user_func( $block['render_callback'], $block, $content, $is_preview, $post_id, $wp_block ); - - // Or include template. - } elseif( $block['render_template'] ) { - + + // Or include template. + } elseif ( $block['render_template'] ) { + // Locate template. - if( file_exists($block['render_template']) ) { + if ( file_exists( $block['render_template'] ) ) { $path = $block['render_template']; - } else { - $path = locate_template( $block['render_template'] ); - } - - // Include template. - if( file_exists($path) ) { - include( $path ); - } + } else { + $path = locate_template( $block['render_template'] ); + } + + // Include template. + if ( file_exists( $path ) ) { + include $path; + } } - + // Reset postdata. acf_reset_meta( $block['id'] ); } @@ -400,28 +434,31 @@ function acf_render_block( $attributes, $content = '', $is_preview = false, $pos * * Returns an array of all fields for the given block. * - * @date 24/10/18 - * @since 5.8.0 + * @date 24/10/18 + * @since 5.8.0 * - * @param array $block The block props. - * @return array + * @param array $block The block props. + * @return array */ function acf_get_block_fields( $block ) { - + // Vars. $fields = array(); - + // Get field groups for this block. - $field_groups = acf_get_field_groups( array( - 'block' => $block['name'] - )); - + $field_groups = acf_get_field_groups( + array( + 'block' => $block['name'], + ) + ); + // Loop over results and append fields. - if( $field_groups ) { - foreach( $field_groups as $field_group ) { - $fields = array_merge( $fields, acf_get_fields( $field_group ) ); - }} - + if ( $field_groups ) { + foreach ( $field_groups as $field_group ) { + $fields = array_merge( $fields, acf_get_fields( $field_group ) ); + } + } + // Return fields. return $fields; } @@ -431,27 +468,29 @@ function acf_get_block_fields( $block ) { * * Enqueues and localizes block scripts and styles. * - * @date 28/2/19 - * @since 5.7.13 + * @date 28/2/19 + * @since 5.7.13 * - * @param void - * @return void + * @param void + * @return void */ function acf_enqueue_block_assets() { - - // Localize text. - acf_localize_text(array( - 'Switch to Edit' => __('Switch to Edit', 'acf'), - 'Switch to Preview' => __('Switch to Preview', 'acf'), - 'Change content alignment' => __('Change content alignment', 'acf'), - /* translators: %s: Block type title */ - '%s settings' => __('%s settings', 'acf'), - )); - + // Localize text. + acf_localize_text( + array( + 'Switch to Edit' => __( 'Switch to Edit', 'acf' ), + 'Switch to Preview' => __( 'Switch to Preview', 'acf' ), + 'Change content alignment' => __( 'Change content alignment', 'acf' ), + + /* translators: %s: Block type title */ + '%s settings' => __( '%s settings', 'acf' ), + ) + ); + // Get block types. $block_types = acf_get_block_types(); - + // Localize data. acf_localize_data( array( @@ -459,22 +498,30 @@ function acf_enqueue_block_assets() { 'postType' => get_post_type(), ) ); - + // Enqueue script. - $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - wp_enqueue_script( 'acf-blocks', acf_get_url("assets/build/js/pro/acf-pro-blocks{$min}.js"), array('acf-input', 'wp-blocks'), ACF_VERSION, true ); - + $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + + + if ( acf_version_compare( 'wp', '<', '5.6' ) ) { + $blocks_js_path = acf_get_url( "assets/build/js/pro/acf-pro-blocks-legacy{$min}.js" ); + } else { + $blocks_js_path = acf_get_url( "assets/build/js/pro/acf-pro-blocks{$min}.js" ); + } + + wp_enqueue_script( 'acf-blocks', $blocks_js_path, array( 'acf-input', 'wp-blocks' ), ACF_VERSION, true ); + // Enqueue block assets. array_map( 'acf_enqueue_block_type_assets', $block_types ); - + // During the edit screen loading, WordPress renders all blocks in its own attempt to preload data. // Retrieve any cached block HTML and include this in the localized data. - if( defined('ACF_EXPERIMENTAL_PRELOAD_BLOCKS') && ACF_EXPERIMENTAL_PRELOAD_BLOCKS ) { - $preloaded_blocks = acf_get_store( 'block-cache' )->get_data(); - acf_localize_data(array( - 'preloadedBlocks' => $preloaded_blocks - )); - } + $preloaded_blocks = acf_get_store( 'block-cache' )->get_data(); + acf_localize_data( + array( + 'preloadedBlocks' => $preloaded_blocks, + ) + ); } /** @@ -482,29 +529,29 @@ function acf_enqueue_block_assets() { * * Enqueues scripts and styles for a specific block type. * - * @date 28/2/19 - * @since 5.7.13 + * @date 28/2/19 + * @since 5.7.13 * - * @param array $block_type The block type settings. - * @return void + * @param array $block_type The block type settings. + * @return void */ function acf_enqueue_block_type_assets( $block_type ) { - + // Generate handle from name. - $handle = 'block-' . acf_slugify($block_type['name']); - + $handle = 'block-' . acf_slugify( $block_type['name'] ); + // Enqueue style. - if( $block_type['enqueue_style'] ) { + if ( $block_type['enqueue_style'] ) { wp_enqueue_style( $handle, $block_type['enqueue_style'], array(), false, 'all' ); } - + // Enqueue script. - if( $block_type['enqueue_script'] ) { + if ( $block_type['enqueue_script'] ) { wp_enqueue_script( $handle, $block_type['enqueue_script'], array(), false, true ); } - + // Enqueue assets callback. - if( $block_type['enqueue_assets'] && is_callable($block_type['enqueue_assets']) ) { + if ( $block_type['enqueue_assets'] && is_callable( $block_type['enqueue_assets'] ) ) { call_user_func( $block_type['enqueue_assets'], $block_type ); } } @@ -514,93 +561,91 @@ function acf_enqueue_block_type_assets( $block_type ) { * * Handles the ajax request for block data. * - * @date 28/2/19 - * @since 5.7.13 + * @date 28/2/19 + * @since 5.7.13 * - * @param void - * @return void + * @param void + * @return void */ function acf_ajax_fetch_block() { - + // Validate ajax request. - if( !acf_verify_ajax() ) { + if ( ! acf_verify_ajax() ) { wp_send_json_error(); } - + // Get request args. - extract(acf_request_args(array( - 'block' => false, - 'post_id' => 0, - 'query' => array(), - ))); - + extract( + acf_request_args( + array( + 'block' => false, + 'post_id' => 0, + 'query' => array(), + ) + ) + ); + // Bail ealry if no block. - if( !$block ) { + if ( ! $block ) { wp_send_json_error(); } - + // Unslash and decode $_POST data. - $block = wp_unslash($block); - $block = json_decode($block, true); - + $block = wp_unslash( $block ); + $block = json_decode( $block, true ); + // Prepare block ensuring all settings and attributes exist. - if( !$block = acf_prepare_block( $block ) ) { + if ( ! $block = acf_prepare_block( $block ) ) { wp_send_json_error(); } - + // Load field defaults when first previewing a block. - if( !empty($query['preview']) && !$block['data'] ) { + if ( ! empty( $query['preview'] ) && ! $block['data'] ) { $fields = acf_get_block_fields( $block ); - foreach( $fields as $field ) { - $block['data'][ "_{$field['name']}" ] = $field['key']; - } + foreach ( $fields as $field ) { + $block['data'][ "_{$field['name']}" ] = $field['key']; + } } - + // Setup postdata allowing form to load meta. acf_setup_meta( $block['data'], $block['id'], true ); - + // Vars. $response = array(); - + // Query form. - if( !empty($query['form']) ) { - + if ( ! empty( $query['form'] ) ) { + // Load fields for form. $fields = acf_get_block_fields( $block ); - + // Prefix field inputs to avoid multiple blocks using the same name/id attributes. acf_prefix_fields( $fields, "acf-{$block['id']}" ); - + // Start Capture. ob_start(); - + // Render. echo '
                                '; - acf_render_fields( $fields, $block['id'], 'div', 'field' ); + acf_render_fields( $fields, $block['id'], 'div', 'field' ); echo '
                                '; - + // Store Capture. $response['form'] = ob_get_contents(); ob_end_clean(); } - + // Query preview. - if( !empty($query['preview']) ) { - + if ( ! empty( $query['preview'] ) ) { + // Render_callback vars. - $content = ''; - $is_preview = true; - - // Render. - $html = ''; - $html .= '
                                '; - $html .= acf_rendered_block( $block, $content, $is_preview, $post_id ); - $html .= '
                                '; - - // Store HTML. - $response['preview'] = $html; + $content = ''; + $is_preview = true; + + // Render and store HTML. + $response['preview'] = acf_rendered_block( $block, $content, $is_preview, $post_id ); } - + // Send repsonse. wp_send_json_success( $response ); } @@ -613,14 +658,14 @@ acf_register_ajax( 'fetch-block', 'acf_ajax_fetch_block' ); * * Parse content that may contain HTML block comments and saves ACF block meta. * - * @date 27/2/19 - * @since 5.7.13 + * @date 27/2/19 + * @since 5.7.13 * - * @param string $text Content that may contain HTML block comments. - * @return string + * @param string $text Content that may contain HTML block comments. + * @return string */ function acf_parse_save_blocks( $text = '' ) { - + // Search text for dynamic blocks and modify attrs. return addslashes( preg_replace_callback( @@ -639,45 +684,45 @@ add_filter( 'content_save_pre', 'acf_parse_save_blocks', 5, 1 ); * * Callback used in preg_replace to modify ACF Block comment. * - * @date 1/3/19 - * @since 5.7.13 + * @date 1/3/19 + * @since 5.7.13 * - * @param array $matches The preg matches. - * @return string + * @param array $matches The preg matches. + * @return string */ function acf_parse_save_blocks_callback( $matches ) { - + // Defaults - $name = isset($matches['name']) ? $matches['name'] : ''; - $attrs = isset($matches['attrs']) ? json_decode( $matches['attrs'], true) : ''; - $void = isset($matches['void']) ? $matches['void'] : ''; - + $name = isset( $matches['name'] ) ? $matches['name'] : ''; + $attrs = isset( $matches['attrs'] ) ? json_decode( $matches['attrs'], true ) : ''; + $void = isset( $matches['void'] ) ? $matches['void'] : ''; + // Bail early if missing data or not an ACF Block. - if( !$name || !$attrs || !acf_has_block_type($name) ) { + if ( ! $name || ! $attrs || ! acf_has_block_type( $name ) ) { return $matches[0]; } - + // Convert "data" to "meta". // No need to check if already in meta format. Local Meta will do this for us. - if( isset($attrs['data']) ) { + if ( isset( $attrs['data'] ) ) { $attrs['data'] = acf_setup_meta( $attrs['data'], $attrs['id'] ); } - + // Prevent wp_targeted_link_rel from corrupting JSON. remove_filter( 'content_save_pre', 'wp_filter_post_kses' ); remove_filter( 'content_save_pre', 'wp_targeted_link_rel' ); remove_filter( 'content_save_pre', 'balanceTags', 50 ); - + /** * Filteres the block attributes before saving. * - * @date 18/3/19 - * @since 5.7.14 + * @date 18/3/19 + * @since 5.7.14 * - * @param array $attrs The block attributes. + * @param array $attrs The block attributes. */ $attrs = apply_filters( 'acf/pre_save_block', $attrs ); - + // Return new comment - return ''; + return ''; } diff --git a/pro/fields/class-acf-field-clone.php b/pro/fields/class-acf-field-clone.php index fbe1995..1ef25ce 100644 --- a/pro/fields/class-acf-field-clone.php +++ b/pro/fields/class-acf-field-clone.php @@ -1,1319 +1,1303 @@ name = 'clone'; - $this->label = _x('Clone', 'noun', 'acf'); - $this->category = 'layout'; - $this->defaults = array( - 'clone' => '', - 'prefix_label' => 0, - 'prefix_name' => 0, - 'display' => 'seamless', - 'layout' => 'block' - ); - $this->cloning = array(); - $this->have_rows = 'single'; - - - // register filter - acf_enable_filter('clone'); - - - // ajax - add_action('wp_ajax_acf/fields/clone/query', array($this, 'ajax_query')); - - - // filters - add_filter('acf/get_fields', array($this, 'acf_get_fields'), 5, 2); - add_filter('acf/prepare_field', array($this, 'acf_prepare_field'), 10, 1); - add_filter('acf/clone_field', array($this, 'acf_clone_field'), 10, 2); - - } - - - /* - * is_enabled - * - * This function will return true if acf_local functionality is enabled - * - * @type function - * @date 14/07/2016 - * @since 5.4.0 - * - * @param n/a - * @return n/a - */ - - function is_enabled() { - - return acf_is_filter_enabled('clone'); - - } - - - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - - function load_field( $field ) { - - // bail early if not enabled - if( !$this->is_enabled() ) return $field; - - - // load sub fields - // - sub field name's will be modified to include prefix_name settings - $field['sub_fields'] = $this->get_cloned_fields( $field ); - - - // return - return $field; - - } - - - /* - * acf_get_fields - * - * This function will hook into the 'acf/get_fields' filter and inject/replace seamless clones fields - * - * @type function - * @date 17/06/2016 - * @since 5.3.8 - * - * @param $fields (array) - * @param $parent (array) - * @return $fields - */ - - function acf_get_fields( $fields, $parent ) { - - // bail early if empty - if( empty($fields) ) return $fields; - - - // bail early if not enabled - if( !$this->is_enabled() ) return $fields; - - - // vars - $i = 0; - - - // loop - while( $i < count($fields) ) { - // vars - $field = $fields[ $i ]; - - - // $i - $i++; - - - // bail ealry if not a clone field - if( $field['type'] != 'clone' ) continue; - - - // bail ealry if not seamless - if( $field['display'] != 'seamless' ) continue; - - - // replace this clone field with sub fields - $i--; - array_splice($fields, $i, 1, $field['sub_fields']); + $this->name = 'clone'; + $this->label = _x( 'Clone', 'noun', 'acf' ); + $this->category = 'layout'; + $this->defaults = array( + 'clone' => '', + 'prefix_label' => 0, + 'prefix_name' => 0, + 'display' => 'seamless', + 'layout' => 'block', + ); + $this->cloning = array(); + $this->have_rows = 'single'; + + // register filter + acf_enable_filter( 'clone' ); + + // ajax + add_action( 'wp_ajax_acf/fields/clone/query', array( $this, 'ajax_query' ) ); + + // filters + add_filter( 'acf/get_fields', array( $this, 'acf_get_fields' ), 5, 2 ); + add_filter( 'acf/prepare_field', array( $this, 'acf_prepare_field' ), 10, 1 ); + add_filter( 'acf/clone_field', array( $this, 'acf_clone_field' ), 10, 2 ); } - - - // return - return $fields; - - } - - - /* - * get_cloned_fields - * - * This function will return an array of fields for a given clone field - * - * @type function - * @date 28/06/2016 - * @since 5.3.8 - * - * @param $field (array) - * @param $parent (array) - * @return (array) - */ - - function get_cloned_fields( $field ) { - - // vars - $fields = array(); - - - // bail early if no clone setting - if( empty($field['clone']) ) return $fields; - - - // bail ealry if already cloning this field (avoid infinite looping) - if( isset($this->cloning[ $field['key'] ]) ) return $fields; - - - // update local ref - $this->cloning[ $field['key'] ] = 1; - - - // Loop over selectors and load fields. - foreach( $field['clone'] as $selector ) { - - // Field Group selector. - if( acf_is_field_group_key($selector) ) { - - $field_group = acf_get_field_group( $selector ); - if( !$field_group ) { + + + /* + * is_enabled + * + * This function will return true if acf_local functionality is enabled + * + * @type function + * @date 14/07/2016 + * @since 5.4.0 + * + * @param n/a + * @return n/a + */ + + function is_enabled() { + + return acf_is_filter_enabled( 'clone' ); + + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + + function load_field( $field ) { + + // bail early if not enabled + if ( ! $this->is_enabled() ) { + return $field; + } + + // load sub fields + // - sub field name's will be modified to include prefix_name settings + $field['sub_fields'] = $this->get_cloned_fields( $field ); + + // return + return $field; + + } + + + /* + * acf_get_fields + * + * This function will hook into the 'acf/get_fields' filter and inject/replace seamless clones fields + * + * @type function + * @date 17/06/2016 + * @since 5.3.8 + * + * @param $fields (array) + * @param $parent (array) + * @return $fields + */ + + function acf_get_fields( $fields, $parent ) { + + // bail early if empty + if ( empty( $fields ) ) { + return $fields; + } + + // bail early if not enabled + if ( ! $this->is_enabled() ) { + return $fields; + } + + // vars + $i = 0; + + // loop + while ( $i < count( $fields ) ) { + + // vars + $field = $fields[ $i ]; + + // $i + $i++; + + // bail early if not a clone field + if ( $field['type'] != 'clone' ) { continue; } - - $field_group_fields = acf_get_fields( $field_group ); - if( !$field_group_fields ) { + + // bail early if not seamless + if ( $field['display'] != 'seamless' ) { continue; } - - $fields = array_merge( $fields, $field_group_fields ); - - // Field selector. - } elseif( acf_is_field_key($selector) ) { - $fields[] = acf_get_field( $selector ); - } - - } - - - // field has ve been loaded for this $parent, time to remove cloning ref - unset( $this->cloning[ $field['key'] ] ); - - - // clear false values (fields that don't exist) - $fields = array_filter($fields); - - - // bail early if no sub fields - if( empty($fields) ) return array(); - - - // loop - // run acf_clone_field() on each cloned field to modify name, key, etc - foreach( array_keys($fields) as $i ) { - - $fields[ $i ] = acf_clone_field( $fields[ $i ], $field ); - - } - - - // return - return $fields; - - } - - - /* - * acf_clone_field - * - * This function is run when cloning a clone field - * Important to run the acf_clone_field function on sub fields to pass on settings such as 'parent_layout' - * - * @type function - * @date 28/06/2016 - * @since 5.3.8 - * - * @param $field (array) - * @param $clone_field (array) - * @return $field - */ - - function acf_clone_field( $field, $clone_field ) { - - // bail early if this field is being cloned by some other kind of field (future proof) - if( $clone_field['type'] != 'clone' ) return $field; - - - // backup (used later) - // - backup only once (cloned clone fields can cause issues) - if( !isset($field['__key']) ) { - - $field['__key'] = $field['key']; - $field['__name'] = $field['_name']; - $field['__label'] = $field['label']; - - } - - - // seamless - if( $clone_field['display'] == 'seamless' ) { - - // modify key - // - this will allow sub clone fields to correctly load values for the same cloned field - // - the original key will later be restored by acf/prepare_field allowing conditional logic JS to work - $field['key'] = $clone_field['key'] . '_' . $field['key']; - - - // modify prefix allowing clone field to save sub fields - // - only used for parent seamless fields. Block or sub field's prefix will be overriden which also works - $field['prefix'] = $clone_field['prefix'] . '[' . $clone_field['key'] . ']'; - - - // modify parent - $field['parent'] = $clone_field['parent']; - - - // label_format - if( $clone_field['prefix_label'] ) { - - $field['label'] = $clone_field['label'] . ' ' . $field['label']; - - } - } - - - // prefix_name - if( $clone_field['prefix_name'] ) { - - // modify the field name - // - this will allow field to load / save correctly - $field['name'] = $clone_field['name'] . '_' . $field['_name']; - - - // modify the field _name (orig name) - // - this will allow fields to correctly understand the modified field - if( $clone_field['display'] == 'seamless' ) { - - $field['_name'] = $clone_field['_name'] . '_' . $field['_name']; - - } - } - - - // required - if( $clone_field['required'] ) { - - $field['required'] = 1; - - } - - - // type specific - // note: seamless clone fields will not be triggered - if( $field['type'] == 'clone' ) { - - $field = $this->acf_clone_clone_field( $field, $clone_field ); - - } - - - // return - return $field; - - } - - - /* - * acf_clone_clone_field - * - * This function is run when cloning a clone field - * Important to run the acf_clone_field function on sub fields to pass on settings such as 'parent_layout' - * Do not delete! Removing this logic causes major issues with cloned clone fields within a flexible content layout. - * - * @type function - * @date 28/06/2016 - * @since 5.3.8 - * - * @param $field (array) - * @param $clone_field (array) - * @return $field - */ - - function acf_clone_clone_field( $field, $clone_field ) { - - // modify the $clone_field name - // This seems odd, however, the $clone_field is later passed into the acf_clone_field() function - // Do not delete! - // when cloning a clone field, it is important to also change the _name too - // this allows sub clone fields to appear correctly in get_row() row array - if( $field['prefix_name'] ) { - - $clone_field['name'] = $field['_name']; - $clone_field['_name'] = $field['_name']; - - } - - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $field; - - - // loop - foreach( $field['sub_fields'] as &$sub_field ) { - - // clone - $sub_field = acf_clone_field( $sub_field, $clone_field ); - - } - - - // return - return $field; - - } - - - /* - * prepare_field_for_db - * - * description - * - * @type function - * @date 4/11/16 - * @since 5.5.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function prepare_field_for_db( $field ) { - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $field; - - - // bail early if name == _name - // this is a parent clone field and does not require any modification to sub field names - if( $field['name'] == $field['_name'] ) return $field; - - - // this is a sub field - // _name = 'my_field' - // name = 'rep_0_my_field' - // modify all sub fields to add 'rep_0_' name prefix (prefix_name setting has already been applied) - $length = strlen($field['_name']); - $prefix = substr($field['name'], 0, -$length); - - - // bail ealry if _name is not found at the end of name (unknown potential error) - if( $prefix . $field['_name'] !== $field['name'] ) return $field; - - //acf_log('== prepare_field_for_db =='); - //acf_log('- clone name:', $field['name']); - //acf_log('- clone _name:', $field['_name']); - - // loop - foreach( $field['sub_fields'] as &$sub_field ) { - - $sub_field['name'] = $prefix . $sub_field['name']; - - } - - // return - return $field; - } - - - /* - * load_value() - * - * This filter is applied to the $value after it is loaded from the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value found in the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * @return $value - */ - - function load_value( $value, $post_id, $field ) { - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $value; - - - // modify names - $field = $this->prepare_field_for_db( $field ); + // bail early if sub_fields isn't set or not an array + if ( ! isset( $field['sub_fields'] ) || ! is_array( $field['sub_fields'] ) ) { + continue; + } + + // replace this clone field with sub fields + $i--; + array_splice( $fields, $i, 1, $field['sub_fields'] ); + + } + + // return + return $fields; + + } - // load sub fields - $value = array(); - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - - // add value - $value[ $sub_field['key'] ] = acf_get_value( $post_id, $sub_field ); - - } - - - // return - return $value; - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) ) return false; - - - // modify names - $field = $this->prepare_field_for_db( $field ); - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - - // extract value - $sub_value = acf_extract_var( $value, $sub_field['key'] ); - - - // format value - $sub_value = acf_format_value( $sub_value, $post_id, $sub_field ); - - - // append to $row - $value[ $sub_field['__name'] ] = $sub_value; - - } - - - // return - return $value; - - } - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $field - the field array holding all the field options - * @param $post_id - the $post_id of which the value will be saved - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // bail early if no value - if( !acf_is_array($value) ) return null; - - - // bail ealry if no sub fields - if( empty($field['sub_fields']) ) return null; - - - // modify names - $field = $this->prepare_field_for_db( $field ); - - - // loop - foreach( $field['sub_fields'] as $sub_field ) { - + /* + * get_cloned_fields + * + * This function will return an array of fields for a given clone field + * + * @type function + * @date 28/06/2016 + * @since 5.3.8 + * + * @param $field (array) + * @param $parent (array) + * @return (array) + */ + + function get_cloned_fields( $field ) { + // vars - $v = false; - - - // key (backend) - if( isset($value[ $sub_field['key'] ]) ) { - - $v = $value[ $sub_field['key'] ]; - - // name (frontend) - } elseif( isset($value[ $sub_field['_name'] ]) ) { - - $v = $value[ $sub_field['_name'] ]; - - // empty + $fields = array(); + + // bail early if no clone setting + if ( empty( $field['clone'] ) ) { + return $fields; + } + + // bail ealry if already cloning this field (avoid infinite looping) + if ( isset( $this->cloning[ $field['key'] ] ) ) { + return $fields; + } + + // update local ref + $this->cloning[ $field['key'] ] = 1; + + // Loop over selectors and load fields. + foreach ( $field['clone'] as $selector ) { + + // Field Group selector. + if ( acf_is_field_group_key( $selector ) ) { + + $field_group = acf_get_field_group( $selector ); + if ( ! $field_group ) { + continue; + } + + $field_group_fields = acf_get_fields( $field_group ); + if ( ! $field_group_fields ) { + continue; + } + + $fields = array_merge( $fields, $field_group_fields ); + + // Field selector. + } elseif ( acf_is_field_key( $selector ) ) { + $fields[] = acf_get_field( $selector ); + } + } + + // field has ve been loaded for this $parent, time to remove cloning ref + unset( $this->cloning[ $field['key'] ] ); + + // clear false values (fields that don't exist) + $fields = array_filter( $fields ); + + // bail early if no sub fields + if ( empty( $fields ) ) { + return array(); + } + + // loop + // run acf_clone_field() on each cloned field to modify name, key, etc + foreach ( array_keys( $fields ) as $i ) { + + $fields[ $i ] = acf_clone_field( $fields[ $i ], $field ); + + } + + // return + return $fields; + + } + + + /* + * acf_clone_field + * + * This function is run when cloning a clone field + * Important to run the acf_clone_field function on sub fields to pass on settings such as 'parent_layout' + * + * @type function + * @date 28/06/2016 + * @since 5.3.8 + * + * @param $field (array) + * @param $clone_field (array) + * @return $field + */ + + function acf_clone_field( $field, $clone_field ) { + + // bail early if this field is being cloned by some other kind of field (future proof) + if ( $clone_field['type'] != 'clone' ) { + return $field; + } + + // backup (used later) + // - backup only once (cloned clone fields can cause issues) + if ( ! isset( $field['__key'] ) ) { + + $field['__key'] = $field['key']; + $field['__name'] = $field['_name']; + $field['__label'] = $field['label']; + + } + + // seamless + if ( $clone_field['display'] == 'seamless' ) { + + // modify key + // - this will allow sub clone fields to correctly load values for the same cloned field + // - the original key will later be restored by acf/prepare_field allowing conditional logic JS to work + $field['key'] = $clone_field['key'] . '_' . $field['key']; + + // modify prefix allowing clone field to save sub fields + // - only used for parent seamless fields. Block or sub field's prefix will be overriden which also works + $field['prefix'] = $clone_field['prefix'] . '[' . $clone_field['key'] . ']'; + + // modify parent + $field['parent'] = $clone_field['parent']; + + // label_format + if ( $clone_field['prefix_label'] ) { + + $field['label'] = $clone_field['label'] . ' ' . $field['label']; + + } + } + + // prefix_name + if ( $clone_field['prefix_name'] ) { + + // modify the field name + // - this will allow field to load / save correctly + $field['name'] = $clone_field['name'] . '_' . $field['_name']; + + // modify the field _name (orig name) + // - this will allow fields to correctly understand the modified field + if ( $clone_field['display'] == 'seamless' ) { + + $field['_name'] = $clone_field['_name'] . '_' . $field['_name']; + + } + } + + // required + if ( $clone_field['required'] ) { + + $field['required'] = 1; + + } + + // type specific + // note: seamless clone fields will not be triggered + if ( $field['type'] == 'clone' ) { + + $field = $this->acf_clone_clone_field( $field, $clone_field ); + + } + + // return + return $field; + + } + + + /* + * acf_clone_clone_field + * + * This function is run when cloning a clone field + * Important to run the acf_clone_field function on sub fields to pass on settings such as 'parent_layout' + * Do not delete! Removing this logic causes major issues with cloned clone fields within a flexible content layout. + * + * @type function + * @date 28/06/2016 + * @since 5.3.8 + * + * @param $field (array) + * @param $clone_field (array) + * @return $field + */ + + function acf_clone_clone_field( $field, $clone_field ) { + + // modify the $clone_field name + // This seems odd, however, the $clone_field is later passed into the acf_clone_field() function + // Do not delete! + // when cloning a clone field, it is important to also change the _name too + // this allows sub clone fields to appear correctly in get_row() row array + if ( $field['prefix_name'] ) { + + $clone_field['name'] = $field['_name']; + $clone_field['_name'] = $field['_name']; + + } + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $field; + } + + // loop + foreach ( $field['sub_fields'] as &$sub_field ) { + + // clone + $sub_field = acf_clone_field( $sub_field, $clone_field ); + + } + + // return + return $field; + + } + + + /* + * prepare_field_for_db + * + * description + * + * @type function + * @date 4/11/16 + * @since 5.5.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function prepare_field_for_db( $field ) { + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $field; + } + + // bail early if name == _name + // this is a parent clone field and does not require any modification to sub field names + if ( $field['name'] == $field['_name'] ) { + return $field; + } + + // this is a sub field + // _name = 'my_field' + // name = 'rep_0_my_field' + // modify all sub fields to add 'rep_0_' name prefix (prefix_name setting has already been applied) + $length = strlen( $field['_name'] ); + $prefix = substr( $field['name'], 0, -$length ); + + // bail ealry if _name is not found at the end of name (unknown potential error) + if ( $prefix . $field['_name'] !== $field['name'] ) { + return $field; + } + + // acf_log('== prepare_field_for_db =='); + // acf_log('- clone name:', $field['name']); + // acf_log('- clone _name:', $field['_name']); + + // loop + foreach ( $field['sub_fields'] as &$sub_field ) { + + $sub_field['name'] = $prefix . $sub_field['name']; + + } + + // return + return $field; + + } + + + /* + * load_value() + * + * This filter is applied to the $value after it is loaded from the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value found in the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * @return $value + */ + + function load_value( $value, $post_id, $field ) { + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $value; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // load sub fields + $value = array(); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // add value + $value[ $sub_field['key'] ] = acf_get_value( $post_id, $sub_field ); + + } + + // return + return $value; + + } + + + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) ) { + return false; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // extract value + $sub_value = acf_extract_var( $value, $sub_field['key'] ); + + // format value + $sub_value = acf_format_value( $sub_value, $post_id, $sub_field ); + + // append to $row + $value[ $sub_field['__name'] ] = $sub_value; + + } + + // return + return $value; + + } + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $field - the field array holding all the field options + * @param $post_id - the $post_id of which the value will be saved + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // bail early if no value + if ( ! acf_is_array( $value ) ) { + return null; + } + + // bail ealry if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return null; + } + + // modify names + $field = $this->prepare_field_for_db( $field ); + + // loop + foreach ( $field['sub_fields'] as $sub_field ) { + + // vars + $v = false; + + // key (backend) + if ( isset( $value[ $sub_field['key'] ] ) ) { + + $v = $value[ $sub_field['key'] ]; + + // name (frontend) + } elseif ( isset( $value[ $sub_field['_name'] ] ) ) { + + $v = $value[ $sub_field['_name'] ]; + + // empty + } else { + + // input is not set (hidden by conditioanl logic) + continue; + + } + + // restore original field key + $sub_field = $this->acf_prepare_field( $sub_field ); + + // update value + acf_update_value( $v, $post_id, $sub_field ); + + } + + // return + return ''; + + } + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return; + } + + // load values + foreach ( $field['sub_fields'] as &$sub_field ) { + + // add value + if ( isset( $field['value'][ $sub_field['key'] ] ) ) { + + // this is a normal value + $sub_field['value'] = $field['value'][ $sub_field['key'] ]; + + } elseif ( isset( $sub_field['default_value'] ) ) { + + // no value, but this sub field has a default value + $sub_field['value'] = $sub_field['default_value']; + + } + + // update prefix to allow for nested values + $sub_field['prefix'] = $field['name']; + + // restore label + $sub_field['label'] = $sub_field['__label']; + + // restore required + if ( $field['required'] ) { + $sub_field['required'] = 0; + } + } + + // render + if ( $field['layout'] == 'table' ) { + + $this->render_field_table( $field ); + } else { - - // input is not set (hidden by conditioanl logic) - continue; - + + $this->render_field_block( $field ); + } - - - // restore original field key - $sub_field = $this->acf_prepare_field( $sub_field ); - - - // update value - acf_update_value( $v, $post_id, $sub_field ); - + } - - - // return - return ''; - - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return; - - - // load values - foreach( $field['sub_fields'] as &$sub_field ) { - - // add value - if( isset($field['value'][ $sub_field['key'] ]) ) { - - // this is a normal value - $sub_field['value'] = $field['value'][ $sub_field['key'] ]; - - } elseif( isset($sub_field['default_value']) ) { - - // no value, but this sub field has a default value - $sub_field['value'] = $sub_field['default_value']; - + + + /* + * render_field_block + * + * description + * + * @type function + * @date 12/07/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_block( $field ) { + + // vars + $label_placement = $field['layout'] == 'block' ? 'top' : 'left'; + + // html + echo '
                                '; + + foreach ( $field['sub_fields'] as $sub_field ) { + + acf_render_field_wrap( $sub_field ); + } - - - // update prefix to allow for nested values - $sub_field['prefix'] = $field['name']; - - - // restore label - $sub_field['label'] = $sub_field['__label']; - - - // restore required - if( $field['required'] ) $sub_field['required'] = 0; - + + echo '
                                '; + } - - - // render - if( $field['layout'] == 'table' ) { - - $this->render_field_table( $field ); - - } else { - - $this->render_field_block( $field ); - - } - - } - - - /* - * render_field_block - * - * description - * - * @type function - * @date 12/07/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_block( $field ) { - - // vars - $label_placement = $field['layout'] == 'block' ? 'top' : 'left'; - - - // html - echo '
                                '; - - foreach( $field['sub_fields'] as $sub_field ) { - - acf_render_field_wrap( $sub_field ); - - } - - echo '
                                '; - - } - - - /* - * render_field_table - * - * description - * - * @type function - * @date 12/07/2016 - * @since 5.4.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function render_field_table( $field ) { - -?> + + + /* + * render_field_table + * + * description + * + * @type function + * @date 12/07/2016 + * @since 5.4.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function render_field_table( $field ) { + + ?>
                                - -
                                + +
                                - - + +
                                - - + + - + - + - - - - + + + + - + - - + +
                                - - + +
                                - - + +
                                - + - + - +
                                >
                                - __('Fields', 'acf'), - 'instructions' => __('Select one or more fields you wish to clone','acf'), - 'type' => 'select', - 'name' => 'clone', - 'multiple' => 1, - 'allow_null' => 1, - 'choices' => $this->get_clone_setting_choices( $field['clone'] ), - 'ui' => 1, - 'ajax' => 1, - 'ajax_action' => 'acf/fields/clone/query', - 'placeholder' => '', - )); - - acf_disable_filter('local'); - - - // display - acf_render_field_setting( $field, array( - 'label' => __('Display','acf'), - 'instructions' => __('Specify the style used to render the clone field', 'acf'), - 'type' => 'select', - 'name' => 'display', - 'class' => 'setting-display', - 'choices' => array( - 'group' => __('Group (displays selected fields in a group within this field)','acf'), - 'seamless' => __('Seamless (replaces this field with selected fields)','acf'), - ), - )); - - - // layout - acf_render_field_setting( $field, array( - 'label' => __('Layout','acf'), - 'instructions' => __('Specify the style used to render the selected fields', 'acf'), - 'type' => 'radio', - 'name' => 'layout', - 'layout' => 'horizontal', - 'choices' => array( - 'block' => __('Block','acf'), - 'table' => __('Table','acf'), - 'row' => __('Row','acf') - ) - )); - - - // prefix_label - $instructions = __('Labels will be displayed as %s', 'acf'); - $instructions = sprintf($instructions, ''); - acf_render_field_setting( $field, array( - 'label' => __('Prefix Field Labels','acf'), - 'message' => $instructions, - //'instructions_placement' => 'field', - 'name' => 'prefix_label', - 'class' => 'setting-prefix-label', - 'type' => 'true_false', - 'ui' => 1, - )); - - - // prefix_name - $instructions = __('Values will be saved as %s', 'acf'); - $instructions = sprintf($instructions, ''); - acf_render_field_setting( $field, array( - 'label' => __('Prefix Field Names','acf'), - 'message' => $instructions, - //'instructions_placement' => 'field', - 'name' => 'prefix_name', - 'class' => 'setting-prefix-name', - 'type' => 'true_false', - 'ui' => 1, - )); - - } - - - /* - * get_clone_setting_choices - * - * This function will return an array of choices data for Select2 - * - * @type function - * @date 17/06/2016 - * @since 5.3.8 - * - * @param $value (mixed) - * @return (array) - */ - - function get_clone_setting_choices( $value ) { - - // vars - $choices = array(); - - - // bail early if no $value - if( empty($value) ) return $choices; - - - // force value to array - $value = acf_get_array( $value ); - - - // loop - foreach( $value as $v ) { - - $choices[ $v ] = $this->get_clone_setting_choice( $v ); - + get_clone_setting_field_choice( $_POST['fields'][ $selector ] ); - - } - - - // field - if( acf_is_field_key($selector) ) { - - return $this->get_clone_setting_field_choice( acf_get_field($selector) ); - - } - - - // group - if( acf_is_field_group_key($selector) ) { - - return $this->get_clone_setting_group_choice( acf_get_field_group($selector) ); - - } - - - // return - return $selector; - - } - - - /* - * get_clone_setting_field_choice - * - * This function will return the text for a field choice - * - * @type function - * @date 20/07/2016 - * @since 5.4.0 - * - * @param $field (array) - * @return (string) - */ - - function get_clone_setting_field_choice( $field ) { - - // bail early if no field - if( !$field ) return __('Unknown field', 'acf'); - - - // title - $title = $field['label'] ? $field['label'] : __('(no title)', 'acf'); - - - // append type - $title .= ' (' . $field['type'] . ')'; - - - // ancestors - // - allow for AJAX to send through ancestors count - $ancestors = isset($field['ancestors']) ? $field['ancestors'] : count(acf_get_field_ancestors($field)); - $title = str_repeat('- ', $ancestors) . $title; - - - // return - return $title; - - } - - - /* - * get_clone_setting_group_choice - * - * This function will return the text for a group choice - * - * @type function - * @date 20/07/2016 - * @since 5.4.0 - * - * @param $field_group (array) - * @return (string) - */ - - function get_clone_setting_group_choice( $field_group ) { - - // bail early if no field group - if( !$field_group ) return __('Unknown field group', 'acf'); - - - // return - return sprintf( __('All fields from %s field group', 'acf'), $field_group['title'] ); - - } - - - /* - * ajax_query - * - * description - * - * @type function - * @date 17/06/2016 - * @since 5.3.8 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_query() { - - // validate - if( !acf_verify_ajax() ) die(); - - - // disable field to allow clone fields to appear selectable - acf_disable_filter('clone'); - - - // options - $options = acf_parse_args($_POST, array( - 'post_id' => 0, - 'paged' => 0, - 's' => '', - 'title' => '', - 'fields' => array() - )); - - - // vars - $results = array(); - $s = false; - $i = -1; - $limit = 20; - $range_start = $limit * ($options['paged']-1); // 0, 20, 40 - $range_end = $range_start + ($limit-1); // 19, 39, 59 - - - // search - if( $options['s'] !== '' ) { - - // strip slashes (search may be integer) - $s = wp_unslash( strval($options['s']) ); - - } - - - // load groups - $field_groups = acf_get_field_groups(); - $field_group = false; - - - // bail early if no field groups - if( empty($field_groups) ) die(); - - - // move current field group to start - foreach( array_keys($field_groups) as $j ) { - - // check ID - if( $field_groups[ $j ]['ID'] !== $options['post_id'] ) continue; - - - // extract field group and move to start - $field_group = acf_extract_var($field_groups, $j); - - - // field group found, stop looking - break; - - } - - - // if field group was not found, this is a new field group (not yet saved) - if( !$field_group ) { - - $field_group = array( - 'ID' => $options['post_id'], - 'title' => $options['title'], - 'key' => '', + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field_settings( $field ) { + + // temp enable 'local' to allow .json fields to be displayed + acf_enable_filter( 'local' ); + + // default_value + acf_render_field_setting( + $field, + array( + 'label' => __( 'Fields', 'acf' ), + 'instructions' => __( 'Select one or more fields you wish to clone', 'acf' ), + 'type' => 'select', + 'name' => 'clone', + 'multiple' => 1, + 'allow_null' => 1, + 'choices' => $this->get_clone_setting_choices( $field['clone'] ), + 'ui' => 1, + 'ajax' => 1, + 'ajax_action' => 'acf/fields/clone/query', + 'placeholder' => '', + ) ); - + + acf_disable_filter( 'local' ); + + // display + acf_render_field_setting( + $field, + array( + 'label' => __( 'Display', 'acf' ), + 'instructions' => __( 'Specify the style used to render the clone field', 'acf' ), + 'type' => 'select', + 'name' => 'display', + 'class' => 'setting-display', + 'choices' => array( + 'group' => __( 'Group (displays selected fields in a group within this field)', 'acf' ), + 'seamless' => __( 'Seamless (replaces this field with selected fields)', 'acf' ), + ), + ) + ); + + // layout + acf_render_field_setting( + $field, + array( + 'label' => __( 'Layout', 'acf' ), + 'instructions' => __( 'Specify the style used to render the selected fields', 'acf' ), + 'type' => 'radio', + 'name' => 'layout', + 'layout' => 'horizontal', + 'choices' => array( + 'block' => __( 'Block', 'acf' ), + 'table' => __( 'Table', 'acf' ), + 'row' => __( 'Row', 'acf' ), + ), + ) + ); + + // prefix_label + $instructions = __( 'Labels will be displayed as %s', 'acf' ); + $instructions = sprintf( $instructions, '' ); + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prefix Field Labels', 'acf' ), + 'message' => $instructions, + // 'instructions_placement' => 'field', + 'name' => 'prefix_label', + 'class' => 'setting-prefix-label', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + + // prefix_name + $instructions = __( 'Values will be saved as %s', 'acf' ); + $instructions = sprintf( $instructions, '' ); + acf_render_field_setting( + $field, + array( + 'label' => __( 'Prefix Field Names', 'acf' ), + 'message' => $instructions, + // 'instructions_placement' => 'field', + 'name' => 'prefix_name', + 'class' => 'setting-prefix-name', + 'type' => 'true_false', + 'ui' => 1, + ) + ); + } - - - // move current field group to start of list - array_unshift($field_groups, $field_group); - - - // loop - foreach( $field_groups as $field_group ) { - + + + /* + * get_clone_setting_choices + * + * This function will return an array of choices data for Select2 + * + * @type function + * @date 17/06/2016 + * @since 5.3.8 + * + * @param $value (mixed) + * @return (array) + */ + + function get_clone_setting_choices( $value ) { + // vars - $fields = false; - $ignore_s = false; - $data = array( - 'text' => $field_group['title'], - 'children' => array() - ); - - - // get fields - if( $field_group['ID'] == $options['post_id'] ) { - - $fields = $options['fields']; - - } else { - - $fields = acf_get_fields( $field_group ); - $fields = acf_prepare_fields_for_import( $fields ); - + $choices = array(); + + // bail early if no $value + if ( empty( $value ) ) { + return $choices; } - - - // bail early if no fields - if( !$fields ) continue; - - - // show all children for field group search match - if( $s !== false && stripos($data['text'], $s) !== false ) { - - $ignore_s = true; - - } - - - // populate children - $children = array(); - $children[] = $field_group['key']; - foreach( $fields as $field ) { $children[] = $field['key']; } - - + + // force value to array + $value = acf_get_array( $value ); + // loop - foreach( $children as $child ) { - - // bail ealry if no key (fake field group or corrupt field) - if( !$child ) continue; - - - // vars - $text = false; - - - // bail early if is search, and $text does not contain $s - if( $s !== false && !$ignore_s ) { - - // get early - $text = $this->get_clone_setting_choice( $child ); - - - // search - if( stripos($text, $s) === false ) continue; - - } - - - // $i - $i++; - - - // bail early if $i is out of bounds - if( $i < $range_start || $i > $range_end ) continue; - - - - // load text - if( $text === false ) $text = $this->get_clone_setting_choice( $child ); - - - // append - $data['children'][] = array( - 'id' => $child, - 'text' => $text - ); - + foreach ( $value as $v ) { + + $choices[ $v ] = $this->get_clone_setting_choice( $v ); + } - - - // bail early if no children - // - this group contained fields, but none shown on this page - if( empty($data['children']) ) continue; - - - // append - $results[] = $data; - - - // end loop if $i is out of bounds - // - no need to look further - if( $i > $range_end ) break; - + + // return + return $choices; + } - - - // return - acf_send_ajax_results(array( - 'results' => $results, - 'limit' => $limit - )); - - } - - - /* - * acf_prepare_field - * - * This function will restore a field's key ready for input - * - * @type function - * @date 6/09/2016 - * @since 5.4.0 - * - * @param $field (array) - * @return $field - */ - - function acf_prepare_field( $field ) { - - // bail ealry if not cloned - if( empty($field['_clone']) ) return $field; - - - // restore key - if( isset($field['__key']) ) { - $field['key'] = $field['__key']; + + + /* + * get_clone_setting_choice + * + * This function will return the label for a given clone choice + * + * @type function + * @date 17/06/2016 + * @since 5.3.8 + * + * @param $selector (mixed) + * @return (string) + */ + + function get_clone_setting_choice( $selector = '' ) { + + // bail early no selector + if ( ! $selector ) { + return ''; + } + + // ajax_fields + if ( isset( $_POST['fields'][ $selector ] ) ) { + + return $this->get_clone_setting_field_choice( $_POST['fields'][ $selector ] ); + + } + + // field + if ( acf_is_field_key( $selector ) ) { + + return $this->get_clone_setting_field_choice( acf_get_field( $selector ) ); + + } + + // group + if ( acf_is_field_group_key( $selector ) ) { + + return $this->get_clone_setting_group_choice( acf_get_field_group( $selector ) ); + + } + + // return + return $selector; + } - - - // return - return $field; - - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // bail early if no $value - if( empty($value) ) return $valid; - - - // bail early if no sub fields - if( empty($field['sub_fields']) ) return $valid; - - - // loop - foreach( array_keys($field['sub_fields']) as $i ) { - - // get sub field - $sub_field = $field['sub_fields'][ $i ]; - $k = $sub_field['key']; - - - // bail early if valu enot set (conditional logic?) - if( !isset($value[ $k ]) ) continue; - - + + + /* + * get_clone_setting_field_choice + * + * This function will return the text for a field choice + * + * @type function + * @date 20/07/2016 + * @since 5.4.0 + * + * @param $field (array) + * @return (string) + */ + + function get_clone_setting_field_choice( $field ) { + + // bail early if no field + if ( ! $field ) { + return __( 'Unknown field', 'acf' ); + } + + // title + $title = $field['label'] ? $field['label'] : __( '(no title)', 'acf' ); + + // append type + $title .= ' (' . $field['type'] . ')'; + + // ancestors + // - allow for AJAX to send through ancestors count + $ancestors = isset( $field['ancestors'] ) ? $field['ancestors'] : count( acf_get_field_ancestors( $field ) ); + $title = str_repeat( '- ', $ancestors ) . $title; + + // return + return $title; + + } + + + /* + * get_clone_setting_group_choice + * + * This function will return the text for a group choice + * + * @type function + * @date 20/07/2016 + * @since 5.4.0 + * + * @param $field_group (array) + * @return (string) + */ + + function get_clone_setting_group_choice( $field_group ) { + + // bail early if no field group + if ( ! $field_group ) { + return __( 'Unknown field group', 'acf' ); + } + + // return + return sprintf( __( 'All fields from %s field group', 'acf' ), $field_group['title'] ); + + } + + + /* + * ajax_query + * + * description + * + * @type function + * @date 17/06/2016 + * @since 5.3.8 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_query() { + // validate - acf_validate_value( $value[ $k ], $sub_field, "{$input}[{$k}]" ); - + if ( ! acf_verify_ajax() ) { + die(); + } + + // disable field to allow clone fields to appear selectable + acf_disable_filter( 'clone' ); + + // options + $options = acf_parse_args( + $_POST, + array( + 'post_id' => 0, + 'paged' => 0, + 's' => '', + 'title' => '', + 'fields' => array(), + ) + ); + + // vars + $results = array(); + $s = false; + $i = -1; + $limit = 20; + $range_start = $limit * ( $options['paged'] - 1 ); // 0, 20, 40 + $range_end = $range_start + ( $limit - 1 ); // 19, 39, 59 + + // search + if ( $options['s'] !== '' ) { + + // strip slashes (search may be integer) + $s = wp_unslash( strval( $options['s'] ) ); + + } + + // load groups + $field_groups = acf_get_field_groups(); + $field_group = false; + + // bail early if no field groups + if ( empty( $field_groups ) ) { + die(); + } + + // move current field group to start + foreach ( array_keys( $field_groups ) as $j ) { + + // check ID + if ( $field_groups[ $j ]['ID'] !== $options['post_id'] ) { + continue; + } + + // extract field group and move to start + $field_group = acf_extract_var( $field_groups, $j ); + + // field group found, stop looking + break; + + } + + // if field group was not found, this is a new field group (not yet saved) + if ( ! $field_group ) { + + $field_group = array( + 'ID' => $options['post_id'], + 'title' => $options['title'], + 'key' => '', + ); + + } + + // move current field group to start of list + array_unshift( $field_groups, $field_group ); + + // loop + foreach ( $field_groups as $field_group ) { + + // vars + $fields = false; + $ignore_s = false; + $data = array( + 'text' => $field_group['title'], + 'children' => array(), + ); + + // get fields + if ( $field_group['ID'] == $options['post_id'] ) { + + $fields = $options['fields']; + + } else { + + $fields = acf_get_fields( $field_group ); + $fields = acf_prepare_fields_for_import( $fields ); + + } + + // bail early if no fields + if ( ! $fields ) { + continue; + } + + // show all children for field group search match + if ( $s !== false && stripos( $data['text'], $s ) !== false ) { + + $ignore_s = true; + + } + + // populate children + $children = array(); + $children[] = $field_group['key']; + foreach ( $fields as $field ) { + $children[] = $field['key']; } + + // loop + foreach ( $children as $child ) { + + // bail ealry if no key (fake field group or corrupt field) + if ( ! $child ) { + continue; + } + + // vars + $text = false; + + // bail early if is search, and $text does not contain $s + if ( $s !== false && ! $ignore_s ) { + + // get early + $text = $this->get_clone_setting_choice( $child ); + + // search + if ( stripos( $text, $s ) === false ) { + continue; + } + } + + // $i + $i++; + + // bail early if $i is out of bounds + if ( $i < $range_start || $i > $range_end ) { + continue; + } + + // load text + if ( $text === false ) { + $text = $this->get_clone_setting_choice( $child ); + } + + // append + $data['children'][] = array( + 'id' => $child, + 'text' => $text, + ); + + } + + // bail early if no children + // - this group contained fields, but none shown on this page + if ( empty( $data['children'] ) ) { + continue; + } + + // append + $results[] = $data; + + // end loop if $i is out of bounds + // - no need to look further + if ( $i > $range_end ) { + break; + } + } + + // return + acf_send_ajax_results( + array( + 'results' => $results, + 'limit' => $limit, + ) + ); + } - - - // return - return $valid; - + + + /* + * acf_prepare_field + * + * This function will restore a field's key ready for input + * + * @type function + * @date 6/09/2016 + * @since 5.4.0 + * + * @param $field (array) + * @return $field + */ + + function acf_prepare_field( $field ) { + + // bail ealry if not cloned + if ( empty( $field['_clone'] ) ) { + return $field; + } + + // restore key + if ( isset( $field['__key'] ) ) { + $field['key'] = $field['__key']; + } + + // return + return $field; + + } + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // bail early if no $value + if ( empty( $value ) ) { + return $valid; + } + + // bail early if no sub fields + if ( empty( $field['sub_fields'] ) ) { + return $valid; + } + + // loop + foreach ( array_keys( $field['sub_fields'] ) as $i ) { + + // get sub field + $sub_field = $field['sub_fields'][ $i ]; + $k = $sub_field['key']; + + // bail early if valu enot set (conditional logic?) + if ( ! isset( $value[ $k ] ) ) { + continue; + } + + // validate + acf_validate_value( $value[ $k ], $sub_field, "{$input}[{$k}]" ); + + } + + // return + return $valid; + + } + } - -} -// initialize -acf_register_field_type( 'acf_field_clone' ); + // initialize + acf_register_field_type( 'acf_field_clone' ); endif; // class_exists check diff --git a/pro/fields/class-acf-field-flexible-content.php b/pro/fields/class-acf-field-flexible-content.php index bfd3ec0..9877581 100644 --- a/pro/fields/class-acf-field-flexible-content.php +++ b/pro/fields/class-acf-field-flexible-content.php @@ -1,1730 +1,1695 @@ name = 'flexible_content'; - $this->label = __("Flexible Content",'acf'); - $this->category = 'layout'; - $this->defaults = array( - 'layouts' => array(), - 'min' => '', - 'max' => '', - 'button_label' => __("Add Row",'acf'), - ); - - - // ajax - $this->add_action('wp_ajax_acf/fields/flexible_content/layout_title', array($this, 'ajax_layout_title')); - $this->add_action('wp_ajax_nopriv_acf/fields/flexible_content/layout_title', array($this, 'ajax_layout_title')); - - - // filters - $this->add_filter('acf/prepare_field_for_export', array($this, 'prepare_any_field_for_export')); - $this->add_filter('acf/clone_field', array($this, 'clone_any_field'), 10, 2); - $this->add_filter('acf/validate_field', array($this, 'validate_any_field')); - - - // field filters - $this->add_field_filter('acf/get_sub_field', array($this, 'get_sub_field'), 10, 3); - $this->add_field_filter('acf/prepare_field_for_export', array($this, 'prepare_field_for_export')); - $this->add_field_filter('acf/prepare_field_for_import', array($this, 'prepare_field_for_import')); - - } - - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // localize - acf_localize_text(array( - - // identifiers - 'layout' => __('layout', 'acf'), - 'layouts' => __('layouts', 'acf'), - - // min / max - 'This field requires at least {min} {label} {identifier}' => __('This field requires at least {min} {label} {identifier}', 'acf'), - 'This field has a limit of {max} {label} {identifier}' => __('This field has a limit of {max} {label} {identifier}', 'acf'), - - // popup badge - '{available} {label} {identifier} available (max {max})' => __('{available} {label} {identifier} available (max {max})', 'acf'), - '{required} {label} {identifier} required (min {min})' => __('{required} {label} {identifier} required (min {min})', 'acf'), - - // field settings - 'Flexible Content requires at least 1 layout' => __('Flexible Content requires at least 1 layout', 'acf') - )); - } - - - /* - * get_valid_layout - * - * This function will fill in the missing keys to create a valid layout - * - * @type function - * @date 3/10/13 - * @since 1.1.0 - * - * @param $layout (array) - * @return $layout (array) - */ - - function get_valid_layout( $layout = array() ) { - - // parse - $layout = wp_parse_args($layout, array( - 'key' => uniqid('layout_'), - 'name' => '', - 'label' => '', - 'display' => 'block', - 'sub_fields' => array(), - 'min' => '', - 'max' => '', - )); - - - // return - return $layout; - } - + class acf_field_flexible_content extends acf_field { - /* - * load_field() - * - * This filter is appied to the $field after it is loaded from the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the field array holding all the field options - */ - - function load_field( $field ) { - - // bail early if no field layouts - if( empty($field['layouts']) ) { - + + /* + * __construct + * + * This function will setup the field type data + * + * @type function + * @date 5/03/2014 + * @since 5.0.0 + * + * @param n/a + * @return n/a + */ + + function initialize() { + + // vars + $this->name = 'flexible_content'; + $this->label = __( 'Flexible Content', 'acf' ); + $this->category = 'layout'; + $this->defaults = array( + 'layouts' => array(), + 'min' => '', + 'max' => '', + 'button_label' => __( 'Add Row', 'acf' ), + ); + + // ajax + $this->add_action( 'wp_ajax_acf/fields/flexible_content/layout_title', array( $this, 'ajax_layout_title' ) ); + $this->add_action( 'wp_ajax_nopriv_acf/fields/flexible_content/layout_title', array( $this, 'ajax_layout_title' ) ); + + // filters + $this->add_filter( 'acf/prepare_field_for_export', array( $this, 'prepare_any_field_for_export' ) ); + $this->add_filter( 'acf/clone_field', array( $this, 'clone_any_field' ), 10, 2 ); + $this->add_filter( 'acf/validate_field', array( $this, 'validate_any_field' ) ); + + // field filters + $this->add_field_filter( 'acf/get_sub_field', array( $this, 'get_sub_field' ), 10, 3 ); + $this->add_field_filter( 'acf/prepare_field_for_export', array( $this, 'prepare_field_for_export' ) ); + $this->add_field_filter( 'acf/prepare_field_for_import', array( $this, 'prepare_field_for_import' ) ); + + } + + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // localize + acf_localize_text( + array( + + // identifiers + 'layout' => __( 'layout', 'acf' ), + 'layouts' => __( 'layouts', 'acf' ), + + // min / max + 'This field requires at least {min} {label} {identifier}' => __( 'This field requires at least {min} {label} {identifier}', 'acf' ), + 'This field has a limit of {max} {label} {identifier}' => __( 'This field has a limit of {max} {label} {identifier}', 'acf' ), + + // popup badge + '{available} {label} {identifier} available (max {max})' => __( '{available} {label} {identifier} available (max {max})', 'acf' ), + '{required} {label} {identifier} required (min {min})' => __( '{required} {label} {identifier} required (min {min})', 'acf' ), + + // field settings + 'Flexible Content requires at least 1 layout' => __( 'Flexible Content requires at least 1 layout', 'acf' ), + ) + ); + } + + + /* + * get_valid_layout + * + * This function will fill in the missing keys to create a valid layout + * + * @type function + * @date 3/10/13 + * @since 1.1.0 + * + * @param $layout (array) + * @return $layout (array) + */ + + function get_valid_layout( $layout = array() ) { + + // parse + $layout = wp_parse_args( + $layout, + array( + 'key' => uniqid( 'layout_' ), + 'name' => '', + 'label' => '', + 'display' => 'block', + 'sub_fields' => array(), + 'min' => '', + 'max' => '', + ) + ); + + // return + return $layout; + } + + + /* + * load_field() + * + * This filter is appied to the $field after it is loaded from the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the field array holding all the field options + */ + + function load_field( $field ) { + + // bail early if no field layouts + if ( empty( $field['layouts'] ) ) { + + return $field; + + } + + // vars + $sub_fields = acf_get_fields( $field ); + + // loop through layouts, sub fields and swap out the field key with the real field + foreach ( array_keys( $field['layouts'] ) as $i ) { + + // extract layout + $layout = acf_extract_var( $field['layouts'], $i ); + + // validate layout + $layout = $this->get_valid_layout( $layout ); + + // append sub fields + if ( ! empty( $sub_fields ) ) { + + foreach ( array_keys( $sub_fields ) as $k ) { + + // check if 'parent_layout' is empty + if ( empty( $sub_fields[ $k ]['parent_layout'] ) ) { + + // parent_layout did not save for this field, default it to first layout + $sub_fields[ $k ]['parent_layout'] = $layout['key']; + + } + + // append sub field to layout, + if ( $sub_fields[ $k ]['parent_layout'] == $layout['key'] ) { + + $layout['sub_fields'][] = acf_extract_var( $sub_fields, $k ); + + } + } + } + + // append back to layouts + $field['layouts'][ $i ] = $layout; + + } + + // return return $field; - } - - - // vars - $sub_fields = acf_get_fields($field); - - - // loop through layouts, sub fields and swap out the field key with the real field - foreach( array_keys($field['layouts']) as $i ) { - - // extract layout - $layout = acf_extract_var( $field['layouts'], $i ); - - - // validate layout - $layout = $this->get_valid_layout( $layout ); - - - // append sub fields - if( !empty($sub_fields) ) { - - foreach( array_keys($sub_fields) as $k ) { - - // check if 'parent_layout' is empty - if( empty($sub_fields[ $k ]['parent_layout']) ) { - - // parent_layout did not save for this field, default it to first layout - $sub_fields[ $k ]['parent_layout'] = $layout['key']; - + + + /* + * get_sub_field + * + * This function will return a specific sub field + * + * @type function + * @date 29/09/2016 + * @since 5.4.0 + * + * @param $sub_field + * @param $selector (string) + * @param $field (array) + * @return $post_id (int) + */ + function get_sub_field( $sub_field, $id, $field ) { + + // Get active layout. + $active = get_row_layout(); + + // Loop over layouts. + if ( $field['layouts'] ) { + foreach ( $field['layouts'] as $layout ) { + + // Restict to active layout if within a have_rows() loop. + if ( $active && $active !== $layout['name'] ) { + continue; } - - - // append sub field to layout, - if( $sub_fields[ $k ]['parent_layout'] == $layout['key'] ) { - - $layout['sub_fields'][] = acf_extract_var( $sub_fields, $k ); - - } - - } - - } - - - // append back to layouts - $field['layouts'][ $i ] = $layout; - - } - - - // return - return $field; - } - - - /* - * get_sub_field - * - * This function will return a specific sub field - * - * @type function - * @date 29/09/2016 - * @since 5.4.0 - * - * @param $sub_field - * @param $selector (string) - * @param $field (array) - * @return $post_id (int) - */ - function get_sub_field( $sub_field, $id, $field ) { - - // Get active layout. - $active = get_row_layout(); - - // Loop over layouts. - if( $field['layouts'] ) { - foreach( $field['layouts'] as $layout ) { - - // Restict to active layout if within a have_rows() loop. - if( $active && $active !== $layout['name'] ) { - continue; - } - - // Check sub fields. - if( $layout['sub_fields'] ) { - $sub_field = acf_search_fields( $id, $layout['sub_fields'] ); - if( $sub_field ) { - break; + + // Check sub fields. + if ( $layout['sub_fields'] ) { + $sub_field = acf_search_fields( $id, $layout['sub_fields'] ); + if ( $sub_field ) { + break; + } } } } + + // return + return $sub_field; } - - // return - return $sub_field; - } - - - /* - * render_field() - * - * Create the HTML interface for your field - * - * @param $field - an array holding all the field's data - * - * @type action - * @since 3.6 - * @date 23/01/13 - */ - - function render_field( $field ) { - - // defaults - if( empty($field['button_label']) ) { - - $field['button_label'] = $this->defaults['button_label']; - - } - - - // sort layouts into names - $layouts = array(); - - foreach( $field['layouts'] as $k => $layout ) { - - $layouts[ $layout['name'] ] = $layout; - - } - - - // vars - $div = array( - 'class' => 'acf-flexible-content', - 'data-min' => $field['min'], - 'data-max' => $field['max'] - ); - - // empty - if( empty($field['value']) ) { - $div['class'] .= ' -empty'; - } - - - // no value message - $no_value_message = __('Click the "%s" button below to start creating your layout','acf'); - $no_value_message = apply_filters('acf/fields/flexible_content/no_value_message', $no_value_message, $field); - $no_value_message = sprintf( $no_value_message, $field['button_label'] ); - -?> + + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // defaults + if ( empty( $field['button_label'] ) ) { + + $field['button_label'] = $this->defaults['button_label']; + + } + + // sort layouts into names + $layouts = array(); + + foreach ( $field['layouts'] as $k => $layout ) { + + $layouts[ $layout['name'] ] = $layout; + + } + + // vars + $div = array( + 'class' => 'acf-flexible-content', + 'data-min' => $field['min'], + 'data-max' => $field['max'], + ); + + // empty + if ( empty( $field['value'] ) ) { + $div['class'] .= ' -empty'; + } + + // no value message + $no_value_message = __( 'Click the "%s" button below to start creating your layout', 'acf' ); + $no_value_message = apply_filters( 'acf/fields/flexible_content/no_value_message', $no_value_message, $field ); + $no_value_message = sprintf( $no_value_message, $field['button_label'] ); + + ?>
                                > - $field['name'] )); ?> + $field['name'] ) ); ?>
                                - +
                                - - render_layout( $field, $layout, 'acfcloneindex', array() ); ?> + + render_layout( $field, $layout, 'acfcloneindex', array() ); ?>
                                - $value ): - - // validate - if( empty($layouts[ $value['acf_fc_layout'] ]) ) continue; - - - // render - $this->render_layout( $field, $layouts[ $value['acf_fc_layout'] ], $i, $value ); - - endforeach; - - endif; ?> + $value ) : + + // validate + if ( empty( $layouts[ $value['acf_fc_layout'] ] ) ) { + continue; + } + + // render + $this->render_layout( $field, $layouts[ $value['acf_fc_layout'] ], $i, $value ); + + endforeach; + + endif; + ?>
                                -
                                - 'layout', - 'data-id' => $id, - 'data-layout' => $layout['name'] - ); - - - // clone - if( is_numeric($i) ) { - - $order = $i + 1; - - } else { - - $div['class'] .= ' acf-clone'; - + 'layout', + 'data-id' => $id, + 'data-layout' => $layout['name'], + ); + + // clone + if ( is_numeric( $i ) ) { + + $order = $i + 1; + + } else { + + $div['class'] .= ' acf-clone'; + + } + + // display + if ( $layout['display'] == 'table' ) { + + $el = 'td'; + + } + + // title + $title = $this->get_layout_title( $field, $layout, $i, $value ); + + // remove row + reset_rows(); + + ?> +
                                > - $el = 'td'; - - } - - - // title - $title = $this->get_layout_title( $field, $layout, $i, $value ); - - - // remove row - reset_rows(); - -?> -
                                > - - $prefix.'[acf_fc_layout]', 'value' => $layout['name'] )); ?> + $prefix . '[acf_fc_layout]', + 'value' => $layout['name'], + ) + ); + ?> -
                                +
                                - - - - + + + +
                                - + - + - . - $sub_field['prefix'] = $prefix; - - // Prepare field (allow sub fields to be removed). - $sub_field = acf_prepare_field($sub_field); - if( !$sub_field ) { - continue; - } - - // Define attrs. - $attrs = array(); - $attrs['class'] = 'acf-th'; - $attrs['data-name'] = $sub_field['_name']; - $attrs['data-type'] = $sub_field['type']; - $attrs['data-key'] = $sub_field['key']; - - if( $sub_field['wrapper']['width'] ) { - $attrs['data-width'] = $sub_field['wrapper']['width']; - $attrs['style'] = 'width: ' . $sub_field['wrapper']['width'] . '%;'; - } - - ?> + . + $sub_field['prefix'] = $prefix; + + // Prepare field (allow sub fields to be removed). + $sub_field = acf_prepare_field( $sub_field ); + if ( ! $sub_field ) { + continue; + } + + // Define attrs. + $attrs = array(); + $attrs['class'] = 'acf-th'; + $attrs['data-name'] = $sub_field['_name']; + $attrs['data-type'] = $sub_field['type']; + $attrs['data-key'] = $sub_field['key']; + + if ( $sub_field['wrapper']['width'] ) { + $attrs['data-width'] = $sub_field['wrapper']['width']; + $attrs['style'] = 'width: ' . $sub_field['wrapper']['width'] . '%;'; + } + + ?> - + - -
                                + +
                                - - // loop though sub fields - foreach( $sub_fields as $sub_field ) { - - // add value - if( isset($value[ $sub_field['key'] ]) ) { - - // this is a normal value - $sub_field['value'] = $value[ $sub_field['key'] ]; - - } elseif( isset($sub_field['default_value']) ) { - - // no value, but this sub field has a default value - $sub_field['value'] = $sub_field['default_value']; - - } - - - // update prefix to allow for nested values - $sub_field['prefix'] = $prefix; - - - // render input - acf_render_field_wrap( $sub_field, $el ); - - } - - ?> - - +
                                >
                                - +
                                - +
                                -get_valid_layout( $layout ); - - - // vars - $layout_prefix = "{$field['prefix']}[layouts][{$layout['key']}]"; - - -?> + + + /* + * render_field_settings() + * + * Create extra options for your field. This is rendered when editing a field. + * The value of $field['name'] can be used (like bellow) to save extra data to the $field + * + * @type action + * @since 3.6 + * @date 23/01/13 + * + * @param $field - an array holding all the field's data + */ + + function render_field_settings( $field ) { + + // load default layout + if ( empty( $field['layouts'] ) ) { + + $field['layouts'] = array( + array(), + ); + + } + + // loop through layouts + foreach ( $field['layouts'] as $layout ) { + + // get valid layout + $layout = $this->get_valid_layout( $layout ); + + // vars + $layout_prefix = "{$field['prefix']}[layouts][{$layout['key']}]"; + + ?> + - + - acf_idify( $layout_prefix . '[key]' ), - 'name' => $layout_prefix . '[key]', - 'class' => 'layout-key', - 'value' => $layout['key'] - )); - - ?> + acf_idify( $layout_prefix . '[key]' ), + 'name' => $layout_prefix . '[key]', + 'class' => 'layout-key', + 'value' => $layout['key'], + ) + ); + + ?>
                                • - 'text', - 'name' => 'label', - 'class' => 'layout-label', - 'prefix' => $layout_prefix, - 'value' => $layout['label'], - 'prepend' => __('Label','acf') - )); - + 'text', + 'name' => 'label', + 'class' => 'layout-label', + 'prefix' => $layout_prefix, + 'value' => $layout['label'], + 'prepend' => __( 'Label', 'acf' ), + ) + ); + ?>
                                • - 'text', - 'name' => 'name', - 'class' => 'layout-name', - 'prefix' => $layout_prefix, - 'value' => $layout['name'], - 'prepend' => __('Name','acf') - )); - - ?> + 'text', + 'name' => 'name', + 'class' => 'layout-name', + 'prefix' => $layout_prefix, + 'value' => $layout['name'], + 'prepend' => __( 'Name', 'acf' ), + ) + ); + + ?>
                                • -
                                  +
                                  - 'select', - 'name' => 'display', - 'prefix' => $layout_prefix, - 'value' => $layout['display'], - 'class' => 'acf-is-prepended', - 'choices' => array( - 'table' => __('Table','acf'), - 'block' => __('Block','acf'), - 'row' => __('Row','acf') - ), - )); - + 'select', + 'name' => 'display', + 'prefix' => $layout_prefix, + 'value' => $layout['display'], + 'class' => 'acf-is-prepended', + 'choices' => array( + 'table' => __( 'Table', 'acf' ), + 'block' => __( 'Block', 'acf' ), + 'row' => __( 'Row', 'acf' ), + ), + ) + ); + ?>
                                • - 'text', - 'name' => 'min', - 'prefix' => $layout_prefix, - 'value' => $layout['min'], - 'prepend' => __('Min','acf') - )); - - ?> + 'text', + 'name' => 'min', + 'prefix' => $layout_prefix, + 'value' => $layout['min'], + 'prepend' => __( 'Min', 'acf' ), + ) + ); + + ?>
                                • - 'text', - 'name' => 'max', - 'prefix' => $layout_prefix, - 'value' => $layout['max'], - 'prepend' => __('Max','acf') - )); - - ?> + 'text', + 'name' => 'max', + 'prefix' => $layout_prefix, + 'value' => $layout['max'], + 'prepend' => __( 'Max', 'acf' ), + ) + ); + + ?>
                                - $layout['sub_fields'], - 'parent' => $field['ID'] - ); - - acf_get_view('field-group-fields', $args); - - ?> + $layout['sub_fields'], + 'parent' => $field['ID'], + ); + + acf_get_view( 'field-group-fields', $args ); + + ?> - __('Button Label','acf'), - 'instructions' => '', - 'type' => 'text', - 'name' => 'button_label', - )); - - - // min - acf_render_field_setting( $field, array( - 'label' => __('Minimum Layouts','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'min', - )); - - - // max - acf_render_field_setting( $field, array( - 'label' => __('Maximum Layouts','acf'), - 'instructions' => '', - 'type' => 'number', - 'name' => 'max', - )); - - } - - - /* - * load_value() - * - * This filter is applied to the $value after it is loaded from the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value found in the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * @return $value - */ - - function load_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) || empty($field['layouts']) ) { - - return $value; - - } - - - // value must be an array - $value = acf_get_array( $value ); - - - // vars - $rows = array(); - - - // sort layouts into names - $layouts = array(); - foreach( $field['layouts'] as $k => $layout ) { - - $layouts[ $layout['name'] ] = $layout['sub_fields']; - - } - - - // loop through rows - foreach( $value as $i => $l ) { - - // append to $values - $rows[ $i ] = array(); - $rows[ $i ]['acf_fc_layout'] = $l; - - - // bail early if layout deosnt contain sub fields - if( empty($layouts[ $l ]) ) { - - continue; - + __( 'Button Label', 'acf' ), + 'instructions' => '', + 'type' => 'text', + 'name' => 'button_label', + ) + ); + + // min + acf_render_field_setting( + $field, + array( + 'label' => __( 'Minimum Layouts', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'min', + ) + ); + + // max + acf_render_field_setting( + $field, + array( + 'label' => __( 'Maximum Layouts', 'acf' ), + 'instructions' => '', + 'type' => 'number', + 'name' => 'max', + ) + ); + + } + + + /* + * load_value() + * + * This filter is applied to the $value after it is loaded from the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value found in the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * @return $value + */ + + function load_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) || empty( $field['layouts'] ) ) { + + return $value; + } - // foreach - - } - // foreach - - - - // return - return $rows; - - } - - - /* - * format_value() - * - * This filter is appied to the $value after it is loaded from the db and before it is returned to the template - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value (mixed) the value which was loaded from the database - * @param $post_id (mixed) the $post_id from which the value was loaded - * @param $field (array) the field array holding all the field options - * - * @return $value (mixed) the modified value - */ - - function format_value( $value, $post_id, $field ) { - - // bail early if no value - if( empty($value) || empty($field['layouts']) ) { - - return false; - - } - - - // sort layouts into names - $layouts = array(); - foreach( $field['layouts'] as $k => $layout ) { - - $layouts[ $layout['name'] ] = $layout['sub_fields']; - - } - - - // loop over rows - foreach( array_keys($value) as $i ) { - - // get layout name - $l = $value[ $i ]['acf_fc_layout']; - - - // bail early if layout deosnt exist - if( empty($layouts[ $l ]) ) continue; - - - // get layout - $layout = $layouts[ $l ]; - - - // loop through sub fields - foreach( array_keys($layout) as $j ) { - - // get sub field - $sub_field = $layout[ $j ]; - - - // bail ealry if no name (tab) - if( acf_is_empty($sub_field['name']) ) continue; - - - // extract value - $sub_value = acf_extract_var( $value[ $i ], $sub_field['key'] ); - - - // update $sub_field name - $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; - - - // format value - $sub_value = acf_format_value( $sub_value, $post_id, $sub_field ); - - - // append to $row - $value[ $i ][ $sub_field['_name'] ] = $sub_value; - - } - - } - - - // return - return $value; - } - - - /* - * validate_value - * - * description - * - * @type function - * @date 11/02/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function validate_value( $valid, $value, $field, $input ){ - - // vars - $count = 0; - - - // check if is value (may be empty string) - if( is_array($value) ) { - - // remove acfcloneindex - if( isset($value['acfcloneindex']) ) { - unset($value['acfcloneindex']); - } - - // count - $count = count($value); - } - - - // validate required - if( $field['required'] && !$count ) { - $valid = false; - } - - - // validate min - $min = (int) $field['min']; - if( $min && $count < $min ) { - + + // value must be an array + $value = acf_get_array( $value ); + // vars - $error = __('This field requires at least {min} {label} {identifier}', 'acf'); - $identifier = _n('layout', 'layouts', $min); - - // replace - $error = str_replace('{min}', $min, $error); - $error = str_replace('{label}', '', $error); - $error = str_replace('{identifier}', $identifier, $error); - - // return - return $error; - } - - - // find layouts - $layouts = array(); - foreach( array_keys($field['layouts']) as $i ) { - - // vars - $layout = $field['layouts'][ $i ]; - - // add count - $layout['count'] = 0; - - // append - $layouts[ $layout['name'] ] = $layout; - } - - - // validate value - if( $count ) { - - // loop rows - foreach( $value as $i => $row ) { - + $rows = array(); + + // sort layouts into names + $layouts = array(); + foreach ( $field['layouts'] as $k => $layout ) { + + $layouts[ $layout['name'] ] = $layout['sub_fields']; + + } + + // loop through rows + foreach ( $value as $i => $l ) { + + // append to $values + $rows[ $i ] = array(); + $rows[ $i ]['acf_fc_layout'] = $l; + + // bail early if layout deosnt contain sub fields + if ( empty( $layouts[ $l ] ) ) { + + continue; + + } + // get layout - $l = $row['acf_fc_layout']; - - // bail if layout doesn't exist - if( !isset($layouts[ $l ]) ) { - continue; - } - - // increase count - $layouts[ $l ]['count']++; - - // bail if no sub fields - if( empty($layouts[ $l ]['sub_fields']) ) { - continue; - } - - // loop sub fields - foreach( $layouts[ $l ]['sub_fields'] as $sub_field ) { - - // get sub field key - $k = $sub_field['key']; - - // bail if no value - if( !isset($value[ $i ][ $k ]) ) { + $layout = $layouts[ $l ]; + + // loop through sub fields + foreach ( array_keys( $layout ) as $j ) { + + // get sub field + $sub_field = $layout[ $j ]; + + // bail ealry if no name (tab) + if ( acf_is_empty( $sub_field['name'] ) ) { continue; } - - // validate - acf_validate_value( $value[ $i ][ $k ], $sub_field, "{$input}[{$i}][{$k}]" ); + + // update full name + $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; + + // get value + $sub_value = acf_get_value( $post_id, $sub_field ); + + // add value + $rows[ $i ][ $sub_field['key'] ] = $sub_value; + } - // end loop sub fields - - } - // end loop rows - } - - - // validate layouts - foreach( $layouts as $layout ) { - - // validate min / max - $min = (int) $layout['min']; - $count = $layout['count']; - $label = $layout['label']; - - if( $min && $count < $min ) { - - // vars - $error = __('This field requires at least {min} {label} {identifier}', 'acf'); - $identifier = _n('layout', 'layouts', $min); - - // replace - $error = str_replace('{min}', $min, $error); - $error = str_replace('{label}', '"' . $label . '"', $error); - $error = str_replace('{identifier}', $identifier, $error); - - // return - return $error; - } - } - - - // return - return $valid; - } - - - /** - * This function will return a specific layout by name from a field - * - * @date 15/2/17 - * @since 5.5.8 - * - * @param string $name - * @param array $field - * @return array|false - */ - function get_layout( $name, $field ) { - - // bail early if no layouts - if( !isset($field['layouts']) ) return false; - - - // loop - foreach( $field['layouts'] as $layout ) { - - // match - if( $layout['name'] === $name ) return $layout; - - } - - - // return - return false; - - } - - - /** - * This function will delete a value row - * - * @date 15/2/17 - * @since 5.5.8 - * - * @param int $i - * @param array $field - * @param mixed $post_id - * @return bool - */ - function delete_row( $i, $field, $post_id ) { + // foreach + + } + // foreach + + // return + return $rows; - // vars - $value = acf_get_metadata( $post_id, $field['name'] ); - - - // bail early if no value - if( !is_array($value) || !isset($value[ $i ]) ) return false; - - - // get layout - $layout = $this->get_layout($value[ $i ], $field); - - - // bail early if no layout - if( !$layout || empty($layout['sub_fields']) ) return false; - - - // loop - foreach( $layout['sub_fields'] as $sub_field ) { - - // modify name for delete - $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; - - - // delete value - acf_delete_value( $post_id, $sub_field ); - } - - - // return - return true; - - } - /** - * This function will update a value row - * - * @date 15/2/17 - * @since 5.5.8 - * - * @param array $row - * @param int $i - * @param array $field - * @param mixed $post_id - * @return bool - */ - function update_row( $row, $i, $field, $post_id ) { - - // bail early if no layout reference - if( !is_array($row) || !isset($row['acf_fc_layout']) ) return false; - - - // get layout - $layout = $this->get_layout($row['acf_fc_layout'], $field); - - - // bail early if no layout - if( !$layout || empty($layout['sub_fields']) ) return false; - - - // loop - foreach( $layout['sub_fields'] as $sub_field ) { - - // value - $value = null; - + /* + * format_value() + * + * This filter is appied to the $value after it is loaded from the db and before it is returned to the template + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value (mixed) the value which was loaded from the database + * @param $post_id (mixed) the $post_id from which the value was loaded + * @param $field (array) the field array holding all the field options + * + * @return $value (mixed) the modified value + */ + + function format_value( $value, $post_id, $field ) { + + // bail early if no value + if ( empty( $value ) || empty( $field['layouts'] ) ) { + + return false; - // find value (key) - if( isset($row[ $sub_field['key'] ]) ) { - - $value = $row[ $sub_field['key'] ]; - - // find value (name) - } elseif( isset($row[ $sub_field['name'] ]) ) { - - $value = $row[ $sub_field['name'] ]; - - // value does not exist - } else { - - continue; - } - - - // modify name for save - $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; - - - // update field - acf_update_value( $value, $post_id, $sub_field ); - - } - - - // return - return true; - - } - - - - - /* - * update_value() - * - * This filter is appied to the $value before it is updated in the db - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $value - the value which will be saved in the database - * @param $field - the field array holding all the field options - * @param $post_id - the $post_id of which the value will be saved - * - * @return $value - the modified value - */ - - function update_value( $value, $post_id, $field ) { - - // bail early if no layouts - if( empty($field['layouts']) ) return $value; - - - // vars - $new_value = array(); - $old_value = acf_get_metadata( $post_id, $field['name'] ); - $old_value = is_array($old_value) ? $old_value : array(); - - - // update - if( !empty($value) ) { $i = -1; - - // remove acfcloneindex - if( isset($value['acfcloneindex']) ) { - - unset($value['acfcloneindex']); - + + // sort layouts into names + $layouts = array(); + foreach ( $field['layouts'] as $k => $layout ) { + + $layouts[ $layout['name'] ] = $layout['sub_fields']; + } - - - // loop through rows - foreach( $value as $row ) { $i++; - - // bail early if no layout reference - if( !is_array($row) || !isset($row['acf_fc_layout']) ) continue; - - - // delete old row if layout has changed - if( isset($old_value[ $i ]) && $old_value[ $i ] !== $row['acf_fc_layout'] ) { - - $this->delete_row( $i, $field, $post_id ); - + + // loop over rows + foreach ( array_keys( $value ) as $i ) { + + // get layout name + $l = $value[ $i ]['acf_fc_layout']; + + // bail early if layout deosnt exist + if ( empty( $layouts[ $l ] ) ) { + continue; } - - - // update row - $this->update_row( $row, $i, $field, $post_id ); - - - // append to order - $new_value[] = $row['acf_fc_layout']; - - } - - } - - - // vars - $old_count = empty($old_value) ? 0 : count($old_value); - $new_count = empty($new_value) ? 0 : count($new_value); - - - // remove old rows - if( $old_count > $new_count ) { - - // loop - for( $i = $new_count; $i < $old_count; $i++ ) { - - $this->delete_row( $i, $field, $post_id ); - - } - - } - - - // save false for empty value - if( empty($new_value) ) $new_value = ''; - - - // return - return $new_value; - - } - - - /* - * delete_value - * - * description - * - * @type function - * @date 1/07/2015 - * @since 5.2.3 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function delete_value( $post_id, $key, $field ) { - - // vars - $old_value = acf_get_metadata( $post_id, $field['name'] ); - $old_value = is_array($old_value) ? $old_value : array(); - - - // bail early if no rows or no sub fields - if( empty($old_value) ) return; - - - // loop - foreach( array_keys($old_value) as $i ) { - - $this->delete_row( $i, $field, $post_id ); - - } - - } - - - /* - * update_field() - * - * This filter is appied to the $field before it is saved to the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * @param $post_id - the field group ID (post_type = acf) - * - * @return $field - the modified field - */ - function update_field( $field ) { - - // loop - if( !empty($field['layouts']) ) { - - foreach( $field['layouts'] as &$layout ) { - - unset($layout['sub_fields']); - - } - - } - - - // return - return $field; - } - - - /* - * delete_field - * - * description - * - * @type function - * @date 4/04/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function delete_field( $field ) { - - if( !empty($field['layouts']) ) { - - // loop through layouts - foreach( $field['layouts'] as $layout ) { - + // get layout + $layout = $layouts[ $l ]; + // loop through sub fields - if( !empty($layout['sub_fields']) ) { - - foreach( $layout['sub_fields'] as $sub_field ) { - - acf_delete_field( $sub_field['ID'] ); - + foreach ( array_keys( $layout ) as $j ) { + + // get sub field + $sub_field = $layout[ $j ]; + + // bail ealry if no name (tab) + if ( acf_is_empty( $sub_field['name'] ) ) { + continue; } - // foreach - + + // extract value + $sub_value = acf_extract_var( $value[ $i ], $sub_field['key'] ); + + // update $sub_field name + $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; + + // format value + $sub_value = acf_format_value( $sub_value, $post_id, $sub_field ); + + // append to $row + $value[ $i ][ $sub_field['_name'] ] = $sub_value; + } - // if - } - // foreach - + + // return + return $value; } - // if - - } - - - /* - * duplicate_field() - * - * This filter is appied to the $field before it is duplicated and saved to the database - * - * @type filter - * @since 3.6 - * @date 23/01/13 - * - * @param $field - the field array holding all the field options - * - * @return $field - the modified field - */ - - function duplicate_field( $field ) { - - // vars - $sub_fields = array(); - - - if( !empty($field['layouts']) ) { - - // loop through layouts - foreach( $field['layouts'] as $layout ) { - - // extract sub fields - $extra = acf_extract_var( $layout, 'sub_fields' ); - - - // merge - if( !empty($extra) ) { - - $sub_fields = array_merge($sub_fields, $extra); - + + + /* + * validate_value + * + * description + * + * @type function + * @date 11/02/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function validate_value( $valid, $value, $field, $input ) { + + // vars + $count = 0; + + // check if is value (may be empty string) + if ( is_array( $value ) ) { + + // remove acfcloneindex + if ( isset( $value['acfcloneindex'] ) ) { + unset( $value['acfcloneindex'] ); } - + + // count + $count = count( $value ); } - // foreach - - } - // if - - - // save field to get ID - $field = acf_update_field( $field ); - - - // duplicate sub fields - acf_duplicate_fields( $sub_fields, $field['ID'] ); - - - // return - return $field; - - } - - - /* - * ajax_layout_title - * - * description - * - * @type function - * @date 2/03/2016 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_layout_title() { - - // options - $options = acf_parse_args( $_POST, array( - 'post_id' => 0, - 'i' => 0, - 'field_key' => '', - 'nonce' => '', - 'layout' => '', - 'value' => array() - )); - - - // load field - $field = acf_get_field( $options['field_key'] ); - if( !$field ) die(); - - - // vars - $layout = $this->get_layout( $options['layout'], $field ); - if( !$layout ) die(); - - - // title - $title = $this->get_layout_title( $field, $layout, $options['i'], $options['value'] ); - - - // echo - echo $title; - die; - - } - - - function get_layout_title( $field, $layout, $i, $value ) { - - // vars - $rows = array(); - $rows[ $i ] = $value; - - - // add loop - acf_add_loop(array( - 'selector' => $field['name'], - 'name' => $field['name'], - 'value' => $rows, - 'field' => $field, - 'i' => $i, - 'post_id' => 0, - )); - - - // vars - $title = $layout['label']; - - - // filters - $title = apply_filters('acf/fields/flexible_content/layout_title', $title, $field, $layout, $i); - $title = apply_filters('acf/fields/flexible_content/layout_title/name='.$field['_name'], $title, $field, $layout, $i); - $title = apply_filters('acf/fields/flexible_content/layout_title/key='.$field['key'], $title, $field, $layout, $i); - - - // remove loop - acf_remove_loop(); - - - // prepend order - $order = is_numeric($i) ? $i+1 : 0; - $title = '' . $order . ' ' . acf_esc_html( $title ); - - - // return - return $title; - - } - - - /* - * clone_any_field - * - * This function will update clone field settings based on the origional field - * - * @type function - * @date 28/06/2016 - * @since 5.3.8 - * - * @param $clone (array) - * @param $field (array) - * @return $clone - */ - - function clone_any_field( $field, $clone_field ) { - - // remove parent_layout - // - allows a sub field to be rendered as a normal field - unset($field['parent_layout']); - - - // attempt to merger parent_layout - if( isset($clone_field['parent_layout']) ) { - - $field['parent_layout'] = $clone_field['parent_layout']; - - } - - - // return - return $field; - - } - - - /* - * prepare_field_for_export - * - * description - * - * @type function - * @date 11/03/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function prepare_field_for_export( $field ) { - - // loop - if( !empty($field['layouts']) ) { - - foreach( $field['layouts'] as &$layout ) { - - $layout['sub_fields'] = acf_prepare_fields_for_export( $layout['sub_fields'] ); - + + // validate required + if ( $field['required'] && ! $count ) { + $valid = false; } - + + // validate min + $min = (int) $field['min']; + if ( $min && $count < $min ) { + + // vars + $error = __( 'This field requires at least {min} {label} {identifier}', 'acf' ); + $identifier = _n( 'layout', 'layouts', $min ); + + // replace + $error = str_replace( '{min}', $min, $error ); + $error = str_replace( '{label}', '', $error ); + $error = str_replace( '{identifier}', $identifier, $error ); + + // return + return $error; + } + + // find layouts + $layouts = array(); + foreach ( array_keys( $field['layouts'] ) as $i ) { + + // vars + $layout = $field['layouts'][ $i ]; + + // add count + $layout['count'] = 0; + + // append + $layouts[ $layout['name'] ] = $layout; + } + + // validate value + if ( $count ) { + + // loop rows + foreach ( $value as $i => $row ) { + + // get layout + $l = $row['acf_fc_layout']; + + // bail if layout doesn't exist + if ( ! isset( $layouts[ $l ] ) ) { + continue; + } + + // increase count + $layouts[ $l ]['count']++; + + // bail if no sub fields + if ( empty( $layouts[ $l ]['sub_fields'] ) ) { + continue; + } + + // loop sub fields + foreach ( $layouts[ $l ]['sub_fields'] as $sub_field ) { + + // get sub field key + $k = $sub_field['key']; + + // bail if no value + if ( ! isset( $value[ $i ][ $k ] ) ) { + continue; + } + + // validate + acf_validate_value( $value[ $i ][ $k ], $sub_field, "{$input}[{$i}][{$k}]" ); + } + // end loop sub fields + + } + // end loop rows + } + + // validate layouts + foreach ( $layouts as $layout ) { + + // validate min / max + $min = (int) $layout['min']; + $count = $layout['count']; + $label = $layout['label']; + + if ( $min && $count < $min ) { + + // vars + $error = __( 'This field requires at least {min} {label} {identifier}', 'acf' ); + $identifier = _n( 'layout', 'layouts', $min ); + + // replace + $error = str_replace( '{min}', $min, $error ); + $error = str_replace( '{label}', '"' . $label . '"', $error ); + $error = str_replace( '{identifier}', $identifier, $error ); + + // return + return $error; + } + } + + // return + return $valid; } - - - // return - return $field; - - } - - function prepare_any_field_for_export( $field ) { - - // remove parent_layout - unset( $field['parent_layout'] ); - - - // return - return $field; - - } - - - /* - * prepare_field_for_import - * - * description - * - * @type function - * @date 11/03/2014 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function prepare_field_for_import( $field ) { - - // Bail early if no layouts - if( empty($field['layouts']) ) { + + + /** + * This function will return a specific layout by name from a field + * + * @date 15/2/17 + * @since 5.5.8 + * + * @param string $name + * @param array $field + * @return array|false + */ + function get_layout( $name, $field ) { + + // bail early if no layouts + if ( ! isset( $field['layouts'] ) ) { + return false; + } + + // loop + foreach ( $field['layouts'] as $layout ) { + + // match + if ( $layout['name'] === $name ) { + return $layout; + } + } + + // return + return false; + + } + + + /** + * This function will delete a value row + * + * @date 15/2/17 + * @since 5.5.8 + * + * @param int $i + * @param array $field + * @param mixed $post_id + * @return bool + */ + function delete_row( $i, $field, $post_id ) { + + // vars + $value = acf_get_metadata( $post_id, $field['name'] ); + + // bail early if no value + if ( ! is_array( $value ) || ! isset( $value[ $i ] ) ) { + return false; + } + + // get layout + $layout = $this->get_layout( $value[ $i ], $field ); + + // bail early if no layout + if ( ! $layout || empty( $layout['sub_fields'] ) ) { + return false; + } + + // loop + foreach ( $layout['sub_fields'] as $sub_field ) { + + // modify name for delete + $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; + + // delete value + acf_delete_value( $post_id, $sub_field ); + + } + + // return + return true; + + } + + + /** + * This function will update a value row + * + * @date 15/2/17 + * @since 5.5.8 + * + * @param array $row + * @param int $i + * @param array $field + * @param mixed $post_id + * @return bool + */ + function update_row( $row, $i, $field, $post_id ) { + + // bail early if no layout reference + if ( ! is_array( $row ) || ! isset( $row['acf_fc_layout'] ) ) { + return false; + } + + // get layout + $layout = $this->get_layout( $row['acf_fc_layout'], $field ); + + // bail early if no layout + if ( ! $layout || empty( $layout['sub_fields'] ) ) { + return false; + } + + // loop + foreach ( $layout['sub_fields'] as $sub_field ) { + + // value + $value = null; + + // find value (key) + if ( isset( $row[ $sub_field['key'] ] ) ) { + + $value = $row[ $sub_field['key'] ]; + + // find value (name) + } elseif ( isset( $row[ $sub_field['name'] ] ) ) { + + $value = $row[ $sub_field['name'] ]; + + // value does not exist + } else { + + continue; + + } + + // modify name for save + $sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}"; + + // update field + acf_update_value( $value, $post_id, $sub_field ); + + } + + // return + return true; + + } + + + + + /* + * update_value() + * + * This filter is appied to the $value before it is updated in the db + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $value - the value which will be saved in the database + * @param $field - the field array holding all the field options + * @param $post_id - the $post_id of which the value will be saved + * + * @return $value - the modified value + */ + + function update_value( $value, $post_id, $field ) { + + // bail early if no layouts + if ( empty( $field['layouts'] ) ) { + return $value; + } + + // vars + $new_value = array(); + $old_value = acf_get_metadata( $post_id, $field['name'] ); + $old_value = is_array( $old_value ) ? $old_value : array(); + + // update + if ( ! empty( $value ) ) { + $i = -1; + + // remove acfcloneindex + if ( isset( $value['acfcloneindex'] ) ) { + + unset( $value['acfcloneindex'] ); + + } + + // loop through rows + foreach ( $value as $row ) { + $i++; + + // bail early if no layout reference + if ( ! is_array( $row ) || ! isset( $row['acf_fc_layout'] ) ) { + continue; + } + + // delete old row if layout has changed + if ( isset( $old_value[ $i ] ) && $old_value[ $i ] !== $row['acf_fc_layout'] ) { + + $this->delete_row( $i, $field, $post_id ); + + } + + // update row + $this->update_row( $row, $i, $field, $post_id ); + + // append to order + $new_value[] = $row['acf_fc_layout']; + + } + } + + // vars + $old_count = empty( $old_value ) ? 0 : count( $old_value ); + $new_count = empty( $new_value ) ? 0 : count( $new_value ); + + // remove old rows + if ( $old_count > $new_count ) { + + // loop + for ( $i = $new_count; $i < $old_count; $i++ ) { + + $this->delete_row( $i, $field, $post_id ); + + } + } + + // save false for empty value + if ( empty( $new_value ) ) { + $new_value = ''; + } + + // return + return $new_value; + + } + + + /* + * delete_value + * + * description + * + * @type function + * @date 1/07/2015 + * @since 5.2.3 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function delete_value( $post_id, $key, $field ) { + + // vars + $old_value = acf_get_metadata( $post_id, $field['name'] ); + $old_value = is_array( $old_value ) ? $old_value : array(); + + // bail early if no rows or no sub fields + if ( empty( $old_value ) ) { + return; + } + + // loop + foreach ( array_keys( $old_value ) as $i ) { + + $this->delete_row( $i, $field, $post_id ); + + } + + } + + + /* + * update_field() + * + * This filter is appied to the $field before it is saved to the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * @param $post_id - the field group ID (post_type = acf) + * + * @return $field - the modified field + */ + + function update_field( $field ) { + + // loop + if ( ! empty( $field['layouts'] ) ) { + + foreach ( $field['layouts'] as &$layout ) { + + unset( $layout['sub_fields'] ); + + } + } + + // return return $field; } - - // Storage for extracted fields. - $extra = array(); - - // Loop over layouts. - foreach( $field['layouts'] as &$layout ) { - - // Ensure layout is valid. - $layout = $this->get_valid_layout( $layout ); - - // Extract sub fields. - $sub_fields = acf_extract_var( $layout, 'sub_fields' ); - - // Modify and append sub fields to $extra. - if( $sub_fields ) { - foreach( $sub_fields as $i => $sub_field ) { - - // Update atttibutes - $sub_field['parent'] = $field['key']; - $sub_field['parent_layout'] = $layout['key']; - $sub_field['menu_order'] = $i; - - // Append to extra. - $extra[] = $sub_field; + + + /* + * delete_field + * + * description + * + * @type function + * @date 4/04/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function delete_field( $field ) { + + if ( ! empty( $field['layouts'] ) ) { + + // loop through layouts + foreach ( $field['layouts'] as $layout ) { + + // loop through sub fields + if ( ! empty( $layout['sub_fields'] ) ) { + + foreach ( $layout['sub_fields'] as $sub_field ) { + + acf_delete_field( $sub_field['ID'] ); + + } + // foreach + + } + // if + + } + // foreach + + } + // if + } + + + /* + * duplicate_field() + * + * This filter is appied to the $field before it is duplicated and saved to the database + * + * @type filter + * @since 3.6 + * @date 23/01/13 + * + * @param $field - the field array holding all the field options + * + * @return $field - the modified field + */ + + function duplicate_field( $field ) { + + // vars + $sub_fields = array(); + + if ( ! empty( $field['layouts'] ) ) { + + // loop through layouts + foreach ( $field['layouts'] as $layout ) { + + // extract sub fields + $extra = acf_extract_var( $layout, 'sub_fields' ); + + // merge + if ( ! empty( $extra ) ) { + + $sub_fields = array_merge( $sub_fields, $extra ); + + } + } + // foreach + + } + // if + + // save field to get ID + $field = acf_update_field( $field ); + + // duplicate sub fields + acf_duplicate_fields( $sub_fields, $field['ID'] ); + + // return + return $field; + + } + + + /* + * ajax_layout_title + * + * description + * + * @type function + * @date 2/03/2016 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_layout_title() { + + // options + $options = acf_parse_args( + $_POST, + array( + 'post_id' => 0, + 'i' => 0, + 'field_key' => '', + 'nonce' => '', + 'layout' => '', + 'value' => array(), + ) + ); + + // load field + $field = acf_get_field( $options['field_key'] ); + if ( ! $field ) { + die(); + } + + // vars + $layout = $this->get_layout( $options['layout'], $field ); + if ( ! $layout ) { + die(); + } + + // title + $title = $this->get_layout_title( $field, $layout, $options['i'], $options['value'] ); + + // echo + echo $title; + die; + + } + + + function get_layout_title( $field, $layout, $i, $value ) { + + // vars + $rows = array(); + $rows[ $i ] = $value; + + // add loop + acf_add_loop( + array( + 'selector' => $field['name'], + 'name' => $field['name'], + 'value' => $rows, + 'field' => $field, + 'i' => $i, + 'post_id' => 0, + ) + ); + + // vars + $title = $layout['label']; + + // filters + $title = apply_filters( 'acf/fields/flexible_content/layout_title', $title, $field, $layout, $i ); + $title = apply_filters( 'acf/fields/flexible_content/layout_title/name=' . $field['_name'], $title, $field, $layout, $i ); + $title = apply_filters( 'acf/fields/flexible_content/layout_title/key=' . $field['key'], $title, $field, $layout, $i ); + + // remove loop + acf_remove_loop(); + + // prepend order + $order = is_numeric( $i ) ? $i + 1 : 0; + $title = '' . $order . ' ' . acf_esc_html( $title ); + + // return + return $title; + + } + + + /* + * clone_any_field + * + * This function will update clone field settings based on the origional field + * + * @type function + * @date 28/06/2016 + * @since 5.3.8 + * + * @param $clone (array) + * @param $field (array) + * @return $clone + */ + + function clone_any_field( $field, $clone_field ) { + + // remove parent_layout + // - allows a sub field to be rendered as a normal field + unset( $field['parent_layout'] ); + + // attempt to merger parent_layout + if ( isset( $clone_field['parent_layout'] ) ) { + + $field['parent_layout'] = $clone_field['parent_layout']; + + } + + // return + return $field; + + } + + + /* + * prepare_field_for_export + * + * description + * + * @type function + * @date 11/03/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function prepare_field_for_export( $field ) { + + // loop + if ( ! empty( $field['layouts'] ) ) { + + foreach ( $field['layouts'] as &$layout ) { + + $layout['sub_fields'] = acf_prepare_fields_for_export( $layout['sub_fields'] ); + } } + + // return + return $field; + } - - // Merge extra sub fields. - if( $extra ) { - array_unshift($extra, $field); - return $extra; + + function prepare_any_field_for_export( $field ) { + + // remove parent_layout + unset( $field['parent_layout'] ); + + // return + return $field; + } - - // Return field. - return $field; - } - - - /* - * validate_any_field - * - * This function will add compatibility for the 'column_width' setting - * - * @type function - * @date 30/1/17 - * @since 5.5.6 - * - * @param $field (array) - * @return $field - */ - - function validate_any_field( $field ) { - - // width has changed - if( isset($field['column_width']) ) { - - $field['wrapper']['width'] = acf_extract_var($field, 'column_width'); - - } - - - // return - return $field; - - } - - - /* - * translate_field - * - * This function will translate field settings - * - * @type function - * @date 8/03/2016 - * @since 5.3.2 - * - * @param $field (array) - * @return $field - */ - - function translate_field( $field ) { - - // translate - $field['button_label'] = acf_translate( $field['button_label'] ); - - - // loop - if( !empty($field['layouts']) ) { - - foreach( $field['layouts'] as &$layout ) { - - $layout['label'] = acf_translate($layout['label']); - + + + /* + * prepare_field_for_import + * + * description + * + * @type function + * @date 11/03/2014 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function prepare_field_for_import( $field ) { + + // Bail early if no layouts + if ( empty( $field['layouts'] ) ) { + return $field; } - + + // Storage for extracted fields. + $extra = array(); + + // Loop over layouts. + foreach ( $field['layouts'] as &$layout ) { + + // Ensure layout is valid. + $layout = $this->get_valid_layout( $layout ); + + // Extract sub fields. + $sub_fields = acf_extract_var( $layout, 'sub_fields' ); + + // Modify and append sub fields to $extra. + if ( $sub_fields ) { + foreach ( $sub_fields as $i => $sub_field ) { + + // Update atttibutes + $sub_field['parent'] = $field['key']; + $sub_field['parent_layout'] = $layout['key']; + $sub_field['menu_order'] = $i; + + // Append to extra. + $extra[] = $sub_field; + } + } + } + + // Merge extra sub fields. + if ( $extra ) { + array_unshift( $extra, $field ); + return $extra; + } + + // Return field. + return $field; } - - - // return - return $field; - + + + /* + * validate_any_field + * + * This function will add compatibility for the 'column_width' setting + * + * @type function + * @date 30/1/17 + * @since 5.5.6 + * + * @param $field (array) + * @return $field + */ + + function validate_any_field( $field ) { + + // width has changed + if ( isset( $field['column_width'] ) ) { + + $field['wrapper']['width'] = acf_extract_var( $field, 'column_width' ); + + } + + // return + return $field; + + } + + + /* + * translate_field + * + * This function will translate field settings + * + * @type function + * @date 8/03/2016 + * @since 5.3.2 + * + * @param $field (array) + * @return $field + */ + + function translate_field( $field ) { + + // translate + $field['button_label'] = acf_translate( $field['button_label'] ); + + // loop + if ( ! empty( $field['layouts'] ) ) { + + foreach ( $field['layouts'] as &$layout ) { + + $layout['label'] = acf_translate( $layout['label'] ); + + } + } + + // return + return $field; + + } + } - -} -// initialize -acf_register_field_type( 'acf_field_flexible_content' ); + // initialize + acf_register_field_type( 'acf_field_flexible_content' ); endif; // class_exists check -?> \ No newline at end of file +?> diff --git a/pro/fields/class-acf-field-gallery.php b/pro/fields/class-acf-field-gallery.php index e65da2f..8ea141e 100644 --- a/pro/fields/class-acf-field-gallery.php +++ b/pro/fields/class-acf-field-gallery.php @@ -1,478 +1,494 @@ name = 'gallery'; + $this->label = __( 'Gallery', 'acf' ); + $this->category = 'content'; + $this->defaults = array( + 'return_format' => 'array', + 'preview_size' => 'medium', + 'insert' => 'append', + 'library' => 'all', + 'min' => 0, + 'max' => 0, + 'min_width' => 0, + 'min_height' => 0, + 'min_size' => 0, + 'max_width' => 0, + 'max_height' => 0, + 'max_size' => 0, + 'mime_types' => '', + ); + + // actions + add_action( 'wp_ajax_acf/fields/gallery/get_attachment', array( $this, 'ajax_get_attachment' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/gallery/get_attachment', array( $this, 'ajax_get_attachment' ) ); + + add_action( 'wp_ajax_acf/fields/gallery/update_attachment', array( $this, 'ajax_update_attachment' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/gallery/update_attachment', array( $this, 'ajax_update_attachment' ) ); + + add_action( 'wp_ajax_acf/fields/gallery/get_sort_order', array( $this, 'ajax_get_sort_order' ) ); + add_action( 'wp_ajax_nopriv_acf/fields/gallery/get_sort_order', array( $this, 'ajax_get_sort_order' ) ); -class acf_field_gallery extends acf_field { - - - /* - * __construct - * - * This function will setup the field type data - * - * @type function - * @date 5/03/2014 - * @since 5.0.0 - * - * @param n/a - * @return n/a - */ - - function initialize() { - - // vars - $this->name = 'gallery'; - $this->label = __("Gallery",'acf'); - $this->category = 'content'; - $this->defaults = array( - 'return_format' => 'array', - 'preview_size' => 'medium', - 'insert' => 'append', - 'library' => 'all', - 'min' => 0, - 'max' => 0, - 'min_width' => 0, - 'min_height' => 0, - 'min_size' => 0, - 'max_width' => 0, - 'max_height' => 0, - 'max_size' => 0, - 'mime_types' => '', - ); - - - // actions - add_action('wp_ajax_acf/fields/gallery/get_attachment', array($this, 'ajax_get_attachment')); - add_action('wp_ajax_nopriv_acf/fields/gallery/get_attachment', array($this, 'ajax_get_attachment')); - - add_action('wp_ajax_acf/fields/gallery/update_attachment', array($this, 'ajax_update_attachment')); - add_action('wp_ajax_nopriv_acf/fields/gallery/update_attachment', array($this, 'ajax_update_attachment')); - - add_action('wp_ajax_acf/fields/gallery/get_sort_order', array($this, 'ajax_get_sort_order')); - add_action('wp_ajax_nopriv_acf/fields/gallery/get_sort_order', array($this, 'ajax_get_sort_order')); - - } - - /* - * input_admin_enqueue_scripts - * - * description - * - * @type function - * @date 16/12/2015 - * @since 5.3.2 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function input_admin_enqueue_scripts() { - - // localize - acf_localize_text(array( - 'Add Image to Gallery' => __('Add Image to Gallery', 'acf'), - 'Maximum selection reached' => __('Maximum selection reached', 'acf'), - )); - } - - - /* - * ajax_get_attachment - * - * description - * - * @type function - * @date 13/12/2013 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_get_attachment() { - - // Validate requrest. - if( !acf_verify_ajax() ) { - die(); } - - // Get args. - $args = acf_request_args(array( - 'id' => 0, - 'field_key' => '', - )); - - // Cast args. - $args['id'] = (int) $args['id']; - - // Bail early if no id. - if( !$args['id'] ) { - die(); + + /* + * input_admin_enqueue_scripts + * + * description + * + * @type function + * @date 16/12/2015 + * @since 5.3.2 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function input_admin_enqueue_scripts() { + + // localize + acf_localize_text( + array( + 'Add Image to Gallery' => __( 'Add Image to Gallery', 'acf' ), + 'Maximum selection reached' => __( 'Maximum selection reached', 'acf' ), + ) + ); } - - // Load field. - $field = acf_get_field( $args['field_key'] ); - if( !$field ) { - die(); - } - - // Render. - $this->render_attachment( $args['id'], $field ); - die; - } - - - /* - * ajax_update_attachment - * - * description - * - * @type function - * @date 13/12/2013 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_update_attachment() { - - // validate nonce - if( !wp_verify_nonce($_POST['nonce'], 'acf_nonce') ) { - - wp_send_json_error(); - - } - - - // bail early if no attachments - if( empty($_POST['attachments']) ) { - - wp_send_json_error(); - - } - - - // loop over attachments - foreach( $_POST['attachments'] as $id => $changes ) { - - if ( !current_user_can( 'edit_post', $id ) ) - wp_send_json_error(); - - $post = get_post( $id, ARRAY_A ); - - if ( 'attachment' != $post['post_type'] ) - wp_send_json_error(); - - if ( isset( $changes['title'] ) ) - $post['post_title'] = $changes['title']; - - if ( isset( $changes['caption'] ) ) - $post['post_excerpt'] = $changes['caption']; - - if ( isset( $changes['description'] ) ) - $post['post_content'] = $changes['description']; - - if ( isset( $changes['alt'] ) ) { - $alt = wp_unslash( $changes['alt'] ); - if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) { - $alt = wp_strip_all_tags( $alt, true ); - update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) ); - } + + + /* + * ajax_get_attachment + * + * description + * + * @type function + * @date 13/12/2013 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_get_attachment() { + + // Validate requrest. + if ( ! acf_verify_ajax() ) { + die(); } - - - // save post - wp_update_post( $post ); - - - /** This filter is documented in wp-admin/includes/media.php */ - // - seems off to run this filter AFTER the update_post function, but there is a reason - // - when placed BEFORE, an empty post_title will be populated by WP - // - this filter will still allow 3rd party to save extra image data! - $post = apply_filters( 'attachment_fields_to_save', $post, $changes ); - - - // save meta - acf_save_post( $id ); - + + // Get args. + $args = acf_request_args( + array( + 'id' => 0, + 'field_key' => '', + ) + ); + + // Cast args. + $args['id'] = (int) $args['id']; + + // Bail early if no id. + if ( ! $args['id'] ) { + die(); + } + + // Load field. + $field = acf_get_field( $args['field_key'] ); + if ( ! $field ) { + die(); + } + + // Render. + $this->render_attachment( $args['id'], $field ); + die; } - - - // return - wp_send_json_success(); - - } - - - /* - * ajax_get_sort_order - * - * description - * - * @type function - * @date 13/12/2013 - * @since 5.0.0 - * - * @param $post_id (int) - * @return $post_id (int) - */ - - function ajax_get_sort_order() { - - // vars - $r = array(); - $order = 'DESC'; - $args = acf_parse_args( $_POST, array( - 'ids' => 0, - 'sort' => 'date', - 'field_key' => '', - 'nonce' => '', - )); - - - // validate - if( ! wp_verify_nonce($args['nonce'], 'acf_nonce') ) { - + + + /* + * ajax_update_attachment + * + * description + * + * @type function + * @date 13/12/2013 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_update_attachment() { + + // validate nonce + if ( ! wp_verify_nonce( $_POST['nonce'], 'acf_nonce' ) ) { + + wp_send_json_error(); + + } + + // bail early if no attachments + if ( empty( $_POST['attachments'] ) ) { + + wp_send_json_error(); + + } + + // loop over attachments + foreach ( $_POST['attachments'] as $id => $changes ) { + + if ( ! current_user_can( 'edit_post', $id ) ) { + wp_send_json_error(); + } + + $post = get_post( $id, ARRAY_A ); + + if ( 'attachment' != $post['post_type'] ) { + wp_send_json_error(); + } + + if ( isset( $changes['title'] ) ) { + $post['post_title'] = $changes['title']; + } + + if ( isset( $changes['caption'] ) ) { + $post['post_excerpt'] = $changes['caption']; + } + + if ( isset( $changes['description'] ) ) { + $post['post_content'] = $changes['description']; + } + + if ( isset( $changes['alt'] ) ) { + $alt = wp_unslash( $changes['alt'] ); + if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) { + $alt = wp_strip_all_tags( $alt, true ); + update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) ); + } + } + + // save post + wp_update_post( $post ); + + /** This filter is documented in wp-admin/includes/media.php */ + // - seems off to run this filter AFTER the update_post function, but there is a reason + // - when placed BEFORE, an empty post_title will be populated by WP + // - this filter will still allow 3rd party to save extra image data! + $post = apply_filters( 'attachment_fields_to_save', $post, $changes ); + + // save meta + acf_save_post( $id ); + + } + + // return + wp_send_json_success(); + + } + + + /* + * ajax_get_sort_order + * + * description + * + * @type function + * @date 13/12/2013 + * @since 5.0.0 + * + * @param $post_id (int) + * @return $post_id (int) + */ + + function ajax_get_sort_order() { + + // vars + $r = array(); + $order = 'DESC'; + $args = acf_parse_args( + $_POST, + array( + 'ids' => 0, + 'sort' => 'date', + 'field_key' => '', + 'nonce' => '', + ) + ); + + // validate + if ( ! wp_verify_nonce( $args['nonce'], 'acf_nonce' ) ) { + + wp_send_json_error(); + + } + + // reverse + if ( $args['sort'] == 'reverse' ) { + + $ids = array_reverse( $args['ids'] ); + + wp_send_json_success( $ids ); + + } + + if ( $args['sort'] == 'title' ) { + + $order = 'ASC'; + + } + + // find attachments (DISTINCT POSTS) + $ids = get_posts( + array( + 'post_type' => 'attachment', + 'numberposts' => -1, + 'post_status' => 'any', + 'post__in' => $args['ids'], + 'order' => $order, + 'orderby' => $args['sort'], + 'fields' => 'ids', + ) + ); + + // success + if ( ! empty( $ids ) ) { + + wp_send_json_success( $ids ); + + } + + // failure wp_send_json_error(); - + } - - - // reverse - if( $args['sort'] == 'reverse' ) { - - $ids = array_reverse($args['ids']); - - wp_send_json_success($ids); - - } - - - if( $args['sort'] == 'title' ) { - - $order = 'ASC'; - - } - - - // find attachments (DISTINCT POSTS) - $ids = get_posts(array( - 'post_type' => 'attachment', - 'numberposts' => -1, - 'post_status' => 'any', - 'post__in' => $args['ids'], - 'order' => $order, - 'orderby' => $args['sort'], - 'fields' => 'ids' - )); - - - // success - if( !empty($ids) ) { - - wp_send_json_success($ids); - - } - - - // failure - wp_send_json_error(); - - } - - /** - * Renders the sidebar HTML shown when selecting an attachmemnt. - * - * @date 13/12/2013 - * @since 5.0.0 - * - * @param int $id The attachment ID. - * @param array $field The field array. - * @return void - */ - function render_attachment( $id, $field ) { - // Load attachmenet data. - $attachment = wp_prepare_attachment_for_js( $id ); - $compat = get_compat_media_markup( $id ); - - // Get attachment thumbnail (video). - if( isset($attachment['thumb']['src']) ) { - $thumb = $attachment['thumb']['src']; - - // Look for thumbnail size (image). - } elseif( isset($attachment['sizes']['thumbnail']['url']) ) { - $thumb = $attachment['sizes']['thumbnail']['url']; - - // Use url for svg. - } elseif( $attachment['type'] === 'image' ) { - $thumb = $attachment['url']; - - // Default to icon. - } else { - $thumb = wp_mime_type_icon( $id ); - } - - // Get attachment dimensions / time / size. - $dimensions = ''; - if( $attachment['type'] === 'audio' ) { - $dimensions = __('Length', 'acf') . ': ' . $attachment['fileLength']; - } elseif( !empty($attachment['width']) ) { - $dimensions = $attachment['width'] . ' x ' . $attachment['height']; - } - if( !empty($attachment['filesizeHumanReadable']) ) { - $dimensions .= ' (' . $attachment['filesizeHumanReadable'] . ')'; - } - - ?> + + /** + * Renders the sidebar HTML shown when selecting an attachmemnt. + * + * @date 13/12/2013 + * @since 5.0.0 + * + * @param int $id The attachment ID. + * @param array $field The field array. + * @return void + */ + function render_attachment( $id, $field ) { + // Load attachmenet data. + $attachment = wp_prepare_attachment_for_js( $id ); + $compat = get_compat_media_markup( $id ); + + // Get attachment thumbnail (video). + if ( isset( $attachment['thumb']['src'] ) ) { + $thumb = $attachment['thumb']['src']; + + // Look for thumbnail size (image). + } elseif ( isset( $attachment['sizes']['thumbnail']['url'] ) ) { + $thumb = $attachment['sizes']['thumbnail']['url']; + + // Use url for svg. + } elseif ( $attachment['type'] === 'image' ) { + $thumb = $attachment['url']; + + // Default to icon. + } else { + $thumb = wp_mime_type_icon( $id ); + } + + // Get attachment dimensions / time / size. + $dimensions = ''; + if ( $attachment['type'] === 'audio' ) { + $dimensions = __( 'Length', 'acf' ) . ': ' . $attachment['fileLength']; + } elseif ( ! empty( $attachment['width'] ) ) { + $dimensions = $attachment['width'] . ' x ' . $attachment['height']; + } + if ( ! empty( $attachment['filesizeHumanReadable'] ) ) { + $dimensions .= ' (' . $attachment['filesizeHumanReadable'] . ')'; + } + + ?> - "{$field['key']}-title", - 'name' => 'title', - 'prefix' => $prefix, - 'type' => 'text', - 'label' => __('Title', 'acf'), - 'value' => $attachment['title'] - ), 'tr'); - - acf_render_field_wrap(array( - //'key' => "{$field['key']}-caption", - 'name' => 'caption', - 'prefix' => $prefix, - 'type' => 'textarea', - 'label' => __('Caption', 'acf'), - 'value' => $attachment['caption'] - ), 'tr'); - - acf_render_field_wrap(array( - //'key' => "{$field['key']}-alt", - 'name' => 'alt', - 'prefix' => $prefix, - 'type' => 'text', - 'label' => __('Alt Text', 'acf'), - 'value' => $attachment['alt'] - ), 'tr'); - - acf_render_field_wrap(array( - //'key' => "{$field['key']}-description", - 'name' => 'description', - 'prefix' => $prefix, - 'type' => 'textarea', - 'label' => __('Description', 'acf'), - 'value' => $attachment['description'] - ), 'tr'); - + + acf_render_field_wrap( + array( + // 'key' => "{$field['key']}-title", + 'name' => 'title', + 'prefix' => $prefix, + 'type' => 'text', + 'label' => __( 'Title', 'acf' ), + 'value' => $attachment['title'], + ), + 'tr' + ); + + acf_render_field_wrap( + array( + // 'key' => "{$field['key']}-caption", + 'name' => 'caption', + 'prefix' => $prefix, + 'type' => 'textarea', + 'label' => __( 'Caption', 'acf' ), + 'value' => $attachment['caption'], + ), + 'tr' + ); + + acf_render_field_wrap( + array( + // 'key' => "{$field['key']}-alt", + 'name' => 'alt', + 'prefix' => $prefix, + 'type' => 'text', + 'label' => __( 'Alt Text', 'acf' ), + 'value' => $attachment['alt'], + ), + 'tr' + ); + + acf_render_field_wrap( + array( + // 'key' => "{$field['key']}-description", + 'name' => 'description', + 'prefix' => $prefix, + 'type' => 'textarea', + 'label' => __( 'Description', 'acf' ), + 'value' => $attachment['description'], + ), + 'tr' + ); + ?>
                                - $field['id'], - 'class' => "acf-gallery {$field['class']}", - 'data-library' => $field['library'], - 'data-preview_size' => $field['preview_size'], - 'data-min' => $field['min'], - 'data-max' => $field['max'], - 'data-mime_types' => $field['mime_types'], - 'data-insert' => $field['insert'], - 'data-columns' => 4 - ); - - // Set gallery height with deafult of 400px and minimum of 200px. - $height = acf_get_user_setting('gallery_height', 400); - $height = max( $height, 200 ); - $attrs['style'] = "height:{$height}px"; - - // Load attachments. - $attachments = array(); - if( $field['value'] ) { - - // Clean value into an array of IDs. - $attachment_ids = array_map('intval', acf_array($field['value'])); - - // Find posts in database (ensures all results are real). - $posts = acf_get_posts(array( - 'post_type' => 'attachment', - 'post__in' => $attachment_ids, - 'update_post_meta_cache' => true, - 'update_post_term_cache' => false - )); - - // Load attatchment data for each post. - $attachments = array_map('acf_get_attachment', $posts); + -
                                > - + + /* + * render_field() + * + * Create the HTML interface for your field + * + * @param $field - an array holding all the field's data + * + * @type action + * @since 3.6 + * @date 23/01/13 + */ + + function render_field( $field ) { + + // Enqueue uploader assets. + acf_enqueue_uploader(); + + // Control attributes. + $attrs = array( + 'id' => $field['id'], + 'class' => "acf-gallery {$field['class']}", + 'data-library' => $field['library'], + 'data-preview_size' => $field['preview_size'], + 'data-min' => $field['min'], + 'data-max' => $field['max'], + 'data-mime_types' => $field['mime_types'], + 'data-insert' => $field['insert'], + 'data-columns' => 4, + ); + + // Set gallery height with deafult of 400px and minimum of 200px. + $height = acf_get_user_setting( 'gallery_height', 400 ); + $height = max( $height, 200 ); + $attrs['style'] = "height:{$height}px"; + + // Load attachments. + $attachments = array(); + if ( $field['value'] ) { + + // Clean value into an array of IDs. + $attachment_ids = array_map( 'intval', acf_array( $field['value'] ) ); + + // Find posts in database (ensures all results are real). + $posts = acf_get_posts( + array( + 'post_type' => 'attachment', + 'post__in' => $attachment_ids, + 'update_post_meta_cache' => true, + 'update_post_term_cache' => false, + ) + ); + + // Load attatchment data for each post. + $attachments = array_map( 'acf_get_attachment', $posts ); + } + + ?> +
                                > +