first commit

This commit is contained in:
DESKTOP-GBA0BK8\Admin
2023-04-08 12:19:53 -04:00
commit 7c8c8b1c76
4586 changed files with 2050693 additions and 0 deletions
@@ -0,0 +1,25 @@
# Advanced Custom Fields
Welcome to the official Advanced Custom Fields repository on GitHub. ACF is a WordPress plugin used to take full control of your edit screens & custom field data.
Looking for ACF version 4? Please use the [previous ACF repository](https://github.com/elliotcondon/acf).
Upgrading from ACF version 4? Please read our [Upgrading from v4 to v5 guide](https://www.advancedcustomfields.com/resources/upgrading-v4-v5/).
## Documentation
Do you need help getting started with ACF, or do you have questions about one of the ACF features? You can [search through our documentation here](https://www.advancedcustomfields.com/resources). If you don't find the answers you're looking for, you can [submit a support ticket](https://support.advancedcustomfields.com/new-ticket/) or start a new forum thread in the [support forum](https://support.advancedcustomfields.com/).
## Support
This repository is not suitable for support. Please don't use our issue tracker for support requests, but for core issues only.
Support can take place in the appropriate channels:
* Email based ticket system
* Community forum
These channels can be accessed from our [support website](https://support.advancedcustomfields.com/).
## Contributing
If you have a patch, or stumbled upon an issue with ACF core, you can contribute this back to the code. Please create a new github issue with as much information as possible.
@@ -0,0 +1,618 @@
<?php
/*
Plugin Name: Advanced Custom Fields
Plugin URI: https://www.advancedcustomfields.com
Description: Customize WordPress with powerful, professional and intuitive fields.
Version: 5.8.5
Author: Elliot Condon
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.8.5';
/** @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/class-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');
// 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/json.php');
acf_include('includes/l10n.php');
acf_include('includes/local-fields.php');
acf_include('includes/local-meta.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');
// 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');
acf_include('includes/admin/settings-info.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' => __( 'Inactive', 'acf' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', '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;
}
}
/*
* 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: <?php $acf = acf(); ?>
*
* @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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,48 @@
Font license info
## Entypo
Copyright (C) 2012 by Daniel Bruce
Author: Daniel Bruce
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://www.entypo.com
## Typicons
(c) Stephen Hutchings 2012
Author: Stephen Hutchings
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://typicons.com/
## Font Awesome
Copyright (C) 2016 by Dave Gandy
Author: Dave Gandy
License: SIL ()
Homepage: http://fortawesome.github.com/Font-Awesome/
## Elusive
Copyright (C) 2013 by Aristeides Stathopoulos
Author: Aristeides Stathopoulos
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://aristeides.com/
## Modern Pictograms
Copyright (c) 2012 by John Caserta. All rights reserved.
Author: John Caserta
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://thedesignoffice.org/project/modern-pictograms/
@@ -0,0 +1,75 @@
This webfont is generated by http://fontello.com open source project.
================================================================================
Please, note, that you should obey original font licenses, used to make this
webfont pack. Details available in LICENSE.txt file.
- Usually, it's enough to publish content of LICENSE.txt file somewhere on your
site in "About" section.
- If your project is open-source, usually, it will be ok to make LICENSE.txt
file publicly available in your repository.
- Fonts, used in Fontello, don't require a clickable link on your site.
But any kind of additional authors crediting is welcome.
================================================================================
Comments on archive content
---------------------------
- /font/* - fonts in different formats
- /css/* - different kinds of css, for all situations. Should be ok with
twitter bootstrap. Also, you can skip <i> style and assign icon classes
directly to text elements, if you don't mind about IE7.
- demo.html - demo file, to show your webfont content
- LICENSE.txt - license info about source fonts, used to build your one.
- config.json - keeps your settings. You can import it back into fontello
anytime, to continue your work
Why so many CSS files ?
-----------------------
Because we like to fit all your needs :)
- basic file, <your_font_name>.css - is usually enough, it contains @font-face
and character code definitions
- *-ie7.css - if you need IE7 support, but still don't wish to put char codes
directly into html
- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
rules, but still wish to benefit from css generation. That can be very
convenient for automated asset build systems. When you need to update font -
no need to manually edit files, just override old version with archive
content. See fontello source code for examples.
- *-embedded.css - basic css file, but with embedded WOFF font, to avoid
CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
We strongly recommend to resolve this issue by `Access-Control-Allow-Origin`
server headers. But if you ok with dirty hack - this file is for you. Note,
that data url moved to separate @font-face to avoid problems with <IE9, when
string is too long.
- animate.css - use it to get ideas about spinner rotation animation.
Attention for server setup
--------------------------
You MUST setup server to reply with proper `mime-types` for font files -
otherwise some browsers will fail to show fonts.
Usually, `apache` already has necessary settings, but `nginx` and other
webservers should be tuned. Here is list of mime types for our file extensions:
- `application/vnd.ms-fontobject` - eot
- `application/x-font-woff` - woff
- `application/x-font-ttf` - ttf
- `image/svg+xml` - svg
@@ -0,0 +1,48 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
<defs>
<font id="acf" horiz-adv-x="1000" >
<font-face font-family="acf" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="plus" unicode="&#xe800;" d="M550 400q30 0 30-50t-30-50l-210 0 0-210q0-30-50-30t-50 30l0 210-210 0q-30 0-30 50t30 50l210 0 0 210q0 30 50 30t50-30l0-210 210 0z" horiz-adv-x="580" />
<glyph glyph-name="minus" unicode="&#xe801;" d="M550 400q30 0 30-50t-30-50l-520 0q-30 0-30 50t30 50l520 0z" horiz-adv-x="580" />
<glyph glyph-name="cancel" unicode="&#xe802;" d="M452 194q18-18 18-43t-18-43q-18-16-43-16t-43 16l-132 152-132-152q-18-16-43-16t-43 16q-16 18-16 43t16 43l138 156-138 158q-16 18-16 43t16 43q18 16 43 16t43-16l132-152 132 152q18 16 43 16t43-16q18-18 18-43t-18-43l-138-158z" horiz-adv-x="470" />
<glyph glyph-name="pencil" unicode="&#xe803;" d="M938 605q22-22 22-55t-22-55l-570-570q-22-21-60-38t-73-17l-235 0 0 234q0 35 17 74t38 60l570 570q23 22 55 22t55-22z m-794-426l65-64 431 433-64 63z m91-205q14 0 33 8-10 10-27 26t-50 50-56 56l-22 22q-9-21-9-32l0-78 52-52 79 0z m74 40l432 432-63 64-433-431z m469 469l67 67-165 165-67-66z" horiz-adv-x="960" />
<glyph glyph-name="location" unicode="&#xe804;" d="M250 750q104 0 177-73t73-177q0-106-62-243t-126-223l-62-84q-10 12-27 35t-60 89-76 130-60 147-27 149q0 104 73 177t177 73z m0-388q56 0 96 40t40 96-40 95-96 39-95-39-39-95 39-96 95-40z" horiz-adv-x="500" />
<glyph glyph-name="down" unicode="&#xe805;" d="M564 422l-234-224q-18-18-40-18t-40 18l-234 224q-16 16-16 41t16 41q38 38 78 0l196-188 196 188q40 38 78 0 16-16 16-41t-16-41z" horiz-adv-x="580" />
<glyph glyph-name="left" unicode="&#xe806;" d="M242 626q14 16 39 16t41-16q38-36 0-80l-186-196 186-194q38-44 0-80-16-16-40-16t-40 16l-226 236q-16 16-16 38 0 24 16 40 206 214 226 236z" horiz-adv-x="341" />
<glyph glyph-name="right" unicode="&#xe807;" d="M98 626l226-236q16-16 16-40 0-22-16-38l-226-236q-16-16-40-16t-40 16q-36 36 0 80l186 194-186 196q-36 44 0 80 16 16 41 16t39-16z" horiz-adv-x="340" />
<glyph glyph-name="up" unicode="&#xe808;" d="M564 280q16-16 16-41t-16-41q-38-38-78 0l-196 188-196-188q-40-38-78 0-16 16-16 41t16 41l234 224q16 16 40 16t40-16z" horiz-adv-x="580" />
<glyph glyph-name="sync" unicode="&#xe809;" d="M843 261q0-3 0-4-36-150-150-243t-267-93q-81 0-157 31t-136 88l-72-72q-11-11-25-11t-25 11-11 25v250q0 14 11 25t25 11h250q14 0 25-11t10-25-10-25l-77-77q40-36 90-57t105-20q74 0 139 37t104 99q6 10 30 66 4 13 16 13h107q8 0 13-6t5-12z m14 446v-250q0-14-10-25t-26-11h-250q-14 0-25 11t-10 25 10 25l77 77q-82 77-194 77-75 0-140-37t-104-99q-6-10-29-66-5-13-17-13h-111q-7 0-13 6t-5 12v4q36 150 151 243t268 93q81 0 158-31t137-88l72 72q11 11 25 11t26-11 10-25z" horiz-adv-x="857.1" />
<glyph glyph-name="globe" unicode="&#xe80a;" d="M480 830q200 0 340-141t140-339q0-200-140-340t-340-140q-198 0-339 140t-141 340q0 198 141 339t339 141z m410-480q0 132-78 239t-202 149q-18-24-16-32 4-38 18-51t30-7l32 12t20 2q22-24 0-47t-45-56-1-77q34-64 96-64 28-2 43-36t17-66q10-80-14-140-22-44 14-76 86 112 86 250z m-466 404q-112-14-199-84t-127-174q6 0 22-2t28-3 26-4 24-8 12-13q4-12-14-45t-18-61q0-30 38-56t38-46q0-28 8-68t8-44q0-12 36-54t52-42q10 0 11 22t-2 54-3 40q0 32 14 74 12 42 59 70t55 46q16 34 9 61t-17 43-34 28-41 17-37 9-22 4q-16 6-42 7t-36-3-27 11-17 29q0 10 15 27t35 37 28 30q8 14 17 21t22 16 27 21q4 4 25 17t27 23z m-72-794q66-20 128-20 128 0 226 68-26 44-118 34-24-2-65-17t-47-17q-74-16-76-16-12-2-26-14t-22-18z" horiz-adv-x="960" />
<glyph glyph-name="picture" unicode="&#xe80b;" d="M0-68l0 836 1000 0 0-836-1000 0z m76 78l848 0 0 680-848 0 0-680z m90 80l0 59 150 195 102-86 193 291 223-228 0-231-668 0z m0 416q0 37 24 62t62 24q33 0 58-24t24-62q0-33-24-57t-58-25q-37 0-62 25t-24 57z" horiz-adv-x="1000" />
<glyph glyph-name="check" unicode="&#xe80c;" d="M249 0q-34 0-56 28l-180 236q-16 24-12 52t26 46 51 14 47-28l118-154 296 474q16 24 43 30t53-8q24-16 30-43t-8-53l-350-560q-20-32-56-32z" horiz-adv-x="667" />
<glyph glyph-name="dot-3" unicode="&#xe80d;" d="M110 460q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z m350 0q46 0 78-32t32-78q0-44-33-77t-77-33-77 33-33 77q0 46 32 78t78 32z m350 0q46 0 78-32t32-78q0-44-32-77t-78-33-78 33-32 77q0 46 32 78t78 32z" horiz-adv-x="920" />
<glyph glyph-name="arrow-combo" unicode="&#xe80e;" d="M230 850l230-364-460 0z m0-1000l-230 366 460 0z" horiz-adv-x="460" />
<glyph glyph-name="arrow-down" unicode="&#xe80f;" d="M540 587l-269-473-271 473 540 0z" horiz-adv-x="540" />
<glyph glyph-name="arrow-up" unicode="&#xe810;" d="M0 114l269 473 271-473-540 0z" horiz-adv-x="540" />
<glyph glyph-name="search" unicode="&#xe811;" d="M772 78q30-34 6-62l-46-46q-36-32-68 0l-190 190q-74-42-156-42-128 0-223 95t-95 223 90 219 218 91 224-95 96-223q0-88-46-162z m-678 358q0-88 68-156t156-68 151 63 63 153q0 88-68 155t-156 67-151-63-63-151z" horiz-adv-x="789" />
<glyph glyph-name="link-ext" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
</font>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

@@ -0,0 +1,124 @@
{
"name": "acf",
"css_prefix_text": "acf-icon-",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "a73c5deb486c8d66249811642e5d719a",
"css": "sync",
"code": 59401,
"src": "fontawesome"
},
{
"uid": "7222571caa5c15f83dcfd447c58d68d9",
"css": "search",
"code": 59409,
"src": "entypo"
},
{
"uid": "14017aae737730faeda4a6fd8fb3a5f0",
"css": "check",
"code": 59404,
"src": "entypo"
},
{
"uid": "c709da589c923ba3c2ad48d9fc563e93",
"css": "cancel",
"code": 59394,
"src": "entypo"
},
{
"uid": "70370693ada58ef0a60fa0984fe8d52a",
"css": "plus",
"code": 59392,
"src": "entypo"
},
{
"uid": "1256e3054823e304d7e452a589cf8bb8",
"css": "minus",
"code": 59393,
"src": "entypo"
},
{
"uid": "a42b598e4298f3319b25a2702a02e7ff",
"css": "location",
"code": 59396,
"src": "entypo"
},
{
"uid": "0a3192de65a73ca1501b073ad601f87d",
"css": "arrow-combo",
"code": 59406,
"src": "entypo"
},
{
"uid": "8704cd847a47b64265b8bb110c8b4d62",
"css": "down",
"code": 59397,
"src": "entypo"
},
{
"uid": "c311c48d79488965b0fab7f9cd12b6b5",
"css": "left",
"code": 59398,
"src": "entypo"
},
{
"uid": "749e7d90a9182938180f1d2d8c33584e",
"css": "right",
"code": 59399,
"src": "entypo"
},
{
"uid": "9c7ff134960bb5a82404e4aeaab366d9",
"css": "up",
"code": 59400,
"src": "entypo"
},
{
"uid": "6a12c2b74456ea21cc984e11dec227a1",
"css": "globe",
"code": 59402,
"src": "entypo"
},
{
"uid": "d10920db2e79c997c5e783279291970c",
"css": "dot-3",
"code": 59405,
"src": "entypo"
},
{
"uid": "1e77a2yvsq3owssduo2lcgsiven57iv5",
"css": "pencil",
"code": 59395,
"src": "typicons"
},
{
"uid": "8ax1xqcbzz1hobyd4i7f0unwib1bztip",
"css": "arrow-down",
"code": 59407,
"src": "modernpics"
},
{
"uid": "6ipws8y9gej6vbloufvhi5qux7rluf64",
"css": "arrow-up",
"code": 59408,
"src": "modernpics"
},
{
"uid": "a1be363d4de9be39857893d4134f6215",
"css": "picture",
"code": 59403,
"src": "elusive"
},
{
"uid": "e15f0d620a7897e2035c18c80142f6d9",
"css": "link-ext",
"code": 61582,
"src": "fontawesome"
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

@@ -0,0 +1,650 @@
/*! jQuery UI - v1.11.4 - 2016-05-31
* http://jqueryui.com
* Includes: core.css, datepicker.css, theme.css
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=%22Open%20Sans%22%2C%E2%80%8B%20sans-serif&fsDefault=14px&fwDefault=normal&cornerRadius=3&bgColorHeader=%23ffffff&bgTextureHeader=highlight_soft&borderColorHeader=%23ffffff&fcHeader=%23222222&iconColorHeader=%23DDDDDD&bgColorContent=%23ffffff&bgTextureContent=flat&borderColorContent=%23E1E1E1&fcContent=%23444444&iconColorContent=%23444444&bgColorDefault=%23F9F9F9&bgTextureDefault=flat&borderColorDefault=%23F0F0F0&fcDefault=%23444444&iconColorDefault=%23444444&bgColorHover=%2398b7e8&bgTextureHover=flat&borderColorHover=%2398b7e8&fcHover=%23ffffff&iconColorHover=%23ffffff&bgColorActive=%233875d7&bgTextureActive=flat&borderColorActive=%233875d7&fcActive=%23ffffff&iconColorActive=%23ffffff&bgColorHighlight=%23ffffff&bgTextureHighlight=flat&borderColorHighlight=%23aaaaaa&fcHighlight=%23444444&iconColorHighlight=%23444444&bgColorError=%23E14D43&bgTextureError=flat&borderColorError=%23E14D43&fcError=%23ffffff&iconColorError=%23ffffff&bgColorOverlay=%23ffffff&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px&bgImgOpacityHeader=0&bgImgOpacityContent=&bgImgOpacityDefault=0&bgImgOpacityHover=0&bgImgOpacityActive=0&bgImgOpacityHighlight=0&bgImgOpacityError=0
* Copyright jQuery Foundation and other contributors; Licensed MIT */
/* Layout helpers
----------------------------------*/
.ui-helper-hidden {
display: none;
}
.ui-helper-hidden-accessible {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.ui-helper-reset {
margin: 0;
padding: 0;
border: 0;
outline: 0;
line-height: 1.3;
text-decoration: none;
font-size: 100%;
list-style: none;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
content: "";
display: table;
border-collapse: collapse;
}
.ui-helper-clearfix:after {
clear: both;
}
.ui-helper-clearfix {
min-height: 0; /* support: IE7 */
}
.ui-helper-zfix {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
opacity: 0;
filter:Alpha(Opacity=0); /* support: IE8 */
}
.ui-front {
z-index: 100;
}
/* Interaction Cues
----------------------------------*/
.ui-state-disabled {
cursor: default !important;
}
/* Icons
----------------------------------*/
/* states and images */
.ui-icon {
display: block;
text-indent: -99999px;
overflow: hidden;
background-repeat: no-repeat;
}
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.ui-datepicker {
width: 17em;
padding: .2em .2em 0;
display: none;
}
.ui-datepicker .ui-datepicker-header {
position: relative;
padding: .2em 0;
}
.ui-datepicker .ui-datepicker-prev,
.ui-datepicker .ui-datepicker-next {
position: absolute;
top: 2px;
width: 1.8em;
height: 1.8em;
}
.ui-datepicker .ui-datepicker-prev-hover,
.ui-datepicker .ui-datepicker-next-hover {
top: 1px;
}
.ui-datepicker .ui-datepicker-prev {
left: 2px;
}
.ui-datepicker .ui-datepicker-next {
right: 2px;
}
.ui-datepicker .ui-datepicker-prev-hover {
left: 1px;
}
.ui-datepicker .ui-datepicker-next-hover {
right: 1px;
}
.ui-datepicker .ui-datepicker-prev span,
.ui-datepicker .ui-datepicker-next span {
display: block;
position: absolute;
left: 50%;
margin-left: -8px;
top: 50%;
margin-top: -8px;
}
.ui-datepicker .ui-datepicker-title {
margin: 0 2.3em;
line-height: 1.8em;
text-align: center;
}
.ui-datepicker .ui-datepicker-title select {
font-size: 1em;
margin: 1px 0;
}
.ui-datepicker select.ui-datepicker-month,
.ui-datepicker select.ui-datepicker-year {
width: 45%;
}
.ui-datepicker table {
width: 100%;
font-size: .9em;
border-collapse: collapse;
margin: 0 0 .4em;
}
.ui-datepicker th {
padding: .7em .3em;
text-align: center;
font-weight: bold;
border: 0;
}
.ui-datepicker td {
border: 0;
padding: 1px;
}
.ui-datepicker td span,
.ui-datepicker td a {
display: block;
padding: .2em;
text-align: right;
text-decoration: none;
}
.ui-datepicker .ui-datepicker-buttonpane {
background-image: none;
margin: .7em 0 0 0;
padding: 0 .2em;
border-left: 0;
border-right: 0;
border-bottom: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
float: right;
margin: .5em .2em .4em;
cursor: pointer;
padding: .2em .6em .3em .6em;
width: auto;
overflow: visible;
}
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
float: left;
}
/* with multiple calendars */
.ui-datepicker.ui-datepicker-multi {
width: auto;
}
.ui-datepicker-multi .ui-datepicker-group {
float: left;
}
.ui-datepicker-multi .ui-datepicker-group table {
width: 95%;
margin: 0 auto .4em;
}
.ui-datepicker-multi-2 .ui-datepicker-group {
width: 50%;
}
.ui-datepicker-multi-3 .ui-datepicker-group {
width: 33.3%;
}
.ui-datepicker-multi-4 .ui-datepicker-group {
width: 25%;
}
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
border-left-width: 0;
}
.ui-datepicker-multi .ui-datepicker-buttonpane {
clear: left;
}
.ui-datepicker-row-break {
clear: both;
width: 100%;
font-size: 0;
}
/* RTL support */
.ui-datepicker-rtl {
direction: rtl;
}
.ui-datepicker-rtl .ui-datepicker-prev {
right: 2px;
left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next {
left: 2px;
right: auto;
}
.ui-datepicker-rtl .ui-datepicker-prev:hover {
right: 1px;
left: auto;
}
.ui-datepicker-rtl .ui-datepicker-next:hover {
left: 1px;
right: auto;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane {
clear: right;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
float: left;
}
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
.ui-datepicker-rtl .ui-datepicker-group {
float: right;
}
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
border-right-width: 0;
border-left-width: 1px;
}
/* Component containers
----------------------------------*/
.acf-ui-datepicker .ui-widget {
font-family: inherit;
font-size: 14px;
}
.acf-ui-datepicker .ui-widget .ui-widget {
font-size: 1em;
}
.acf-ui-datepicker .ui-widget input,
.acf-ui-datepicker .ui-widget select,
.acf-ui-datepicker .ui-widget textarea,
.acf-ui-datepicker .ui-widget button {
font-family: inherit;
font-size: 1em;
}
.acf-ui-datepicker .ui-widget-content {
border: 1px solid #E1E1E1;
background: #ffffff;
color: #444444;
}
.acf-ui-datepicker .ui-widget-content a {
color: #444444;
}
.acf-ui-datepicker .ui-widget-header {
border: 1px solid #ffffff;
background: #ffffff url("images/ui-bg_highlight-soft_0_ffffff_1x100.png") 50% 50% repeat-x;
color: #222222;
font-weight: bold;
}
.acf-ui-datepicker .ui-widget-header a {
color: #222222;
}
/* Interaction states
----------------------------------*/
.acf-ui-datepicker .ui-state-default,
.acf-ui-datepicker .ui-widget-content .ui-state-default,
.acf-ui-datepicker .ui-widget-header .ui-state-default {
border: 1px solid #F0F0F0;
background: #F9F9F9;
font-weight: normal;
color: #444444;
}
.acf-ui-datepicker .ui-state-default a,
.acf-ui-datepicker .ui-state-default a:link,
.acf-ui-datepicker .ui-state-default a:visited {
color: #444444;
text-decoration: none;
}
.acf-ui-datepicker .ui-state-hover,
.acf-ui-datepicker .ui-widget-content .ui-state-hover,
.acf-ui-datepicker .ui-widget-header .ui-state-hover,
.acf-ui-datepicker .ui-state-focus,
.acf-ui-datepicker .ui-widget-content .ui-state-focus,
.acf-ui-datepicker .ui-widget-header .ui-state-focus {
border: 1px solid #98b7e8;
background: #98b7e8;
font-weight: normal;
color: #ffffff;
}
.acf-ui-datepicker .ui-state-hover a,
.acf-ui-datepicker .ui-state-hover a:hover,
.acf-ui-datepicker .ui-state-hover a:link,
.acf-ui-datepicker .ui-state-hover a:visited,
.acf-ui-datepicker .ui-state-focus a,
.acf-ui-datepicker .ui-state-focus a:hover,
.acf-ui-datepicker .ui-state-focus a:link,
.acf-ui-datepicker .ui-state-focus a:visited {
color: #ffffff;
text-decoration: none;
}
.acf-ui-datepicker .ui-state-active,
.acf-ui-datepicker .ui-widget-content .ui-state-active,
.acf-ui-datepicker .ui-widget-header .ui-state-active {
border: 1px solid #3875d7;
background: #3875d7;
font-weight: normal;
color: #ffffff;
}
.acf-ui-datepicker .ui-state-active a,
.acf-ui-datepicker .ui-state-active a:link,
.acf-ui-datepicker .ui-state-active a:visited {
color: #ffffff;
text-decoration: none;
}
/* Interaction Cues
----------------------------------*/
.acf-ui-datepicker .ui-state-highlight,
.acf-ui-datepicker .ui-widget-content .ui-state-highlight,
.acf-ui-datepicker .ui-widget-header .ui-state-highlight {
border: 1px solid #aaaaaa;
background: #ffffff;
color: #444444;
}
.acf-ui-datepicker .ui-state-highlight a,
.acf-ui-datepicker .ui-widget-content .ui-state-highlight a,
.acf-ui-datepicker .ui-widget-header .ui-state-highlight a {
color: #444444;
}
.acf-ui-datepicker .ui-state-error,
.acf-ui-datepicker .ui-widget-content .ui-state-error,
.acf-ui-datepicker .ui-widget-header .ui-state-error {
border: 1px solid #E14D43;
background: #E14D43;
color: #ffffff;
}
.acf-ui-datepicker .ui-state-error a,
.acf-ui-datepicker .ui-widget-content .ui-state-error a,
.acf-ui-datepicker .ui-widget-header .ui-state-error a {
color: #ffffff;
}
.acf-ui-datepicker .ui-state-error-text,
.acf-ui-datepicker .ui-widget-content .ui-state-error-text,
.acf-ui-datepicker .ui-widget-header .ui-state-error-text {
color: #ffffff;
}
.acf-ui-datepicker .ui-priority-primary,
.acf-ui-datepicker .ui-widget-content .ui-priority-primary,
.acf-ui-datepicker .ui-widget-header .ui-priority-primary {
font-weight: bold;
}
.acf-ui-datepicker .ui-priority-secondary,
.acf-ui-datepicker .ui-widget-content .ui-priority-secondary,
.acf-ui-datepicker .ui-widget-header .ui-priority-secondary {
opacity: .7;
filter:Alpha(Opacity=70); /* support: IE8 */
font-weight: normal;
}
.acf-ui-datepicker .ui-state-disabled,
.acf-ui-datepicker .ui-widget-content .ui-state-disabled,
.acf-ui-datepicker .ui-widget-header .ui-state-disabled {
opacity: .35;
filter:Alpha(Opacity=35); /* support: IE8 */
background-image: none;
}
.acf-ui-datepicker .ui-state-disabled .ui-icon {
filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
}
/* Icons
----------------------------------*/
/* states and images */
.acf-ui-datepicker .ui-icon {
width: 16px;
height: 16px;
}
.acf-ui-datepicker .ui-icon,
.acf-ui-datepicker .ui-widget-content .ui-icon {
background-image: url("images/ui-icons_444444_256x240.png");
}
.acf-ui-datepicker .ui-widget-header .ui-icon {
background-image: url("images/ui-icons_DDDDDD_256x240.png");
}
.acf-ui-datepicker .ui-state-default .ui-icon {
background-image: url("images/ui-icons_444444_256x240.png");
}
.acf-ui-datepicker .ui-state-hover .ui-icon,
.acf-ui-datepicker .ui-state-focus .ui-icon {
background-image: url("images/ui-icons_ffffff_256x240.png");
}
.acf-ui-datepicker .ui-state-active .ui-icon {
background-image: url("images/ui-icons_ffffff_256x240.png");
}
.acf-ui-datepicker .ui-state-highlight .ui-icon {
background-image: url("images/ui-icons_444444_256x240.png");
}
.acf-ui-datepicker .ui-state-error .ui-icon,
.acf-ui-datepicker .ui-state-error-text .ui-icon {
background-image: url("images/ui-icons_ffffff_256x240.png");
}
/* positioning */
.acf-ui-datepicker .ui-icon-blank { background-position: 16px 16px; }
.acf-ui-datepicker .ui-icon-carat-1-n { background-position: 0 0; }
.acf-ui-datepicker .ui-icon-carat-1-ne { background-position: -16px 0; }
.acf-ui-datepicker .ui-icon-carat-1-e { background-position: -32px 0; }
.acf-ui-datepicker .ui-icon-carat-1-se { background-position: -48px 0; }
.acf-ui-datepicker .ui-icon-carat-1-s { background-position: -64px 0; }
.acf-ui-datepicker .ui-icon-carat-1-sw { background-position: -80px 0; }
.acf-ui-datepicker .ui-icon-carat-1-w { background-position: -96px 0; }
.acf-ui-datepicker .ui-icon-carat-1-nw { background-position: -112px 0; }
.acf-ui-datepicker .ui-icon-carat-2-n-s { background-position: -128px 0; }
.acf-ui-datepicker .ui-icon-carat-2-e-w { background-position: -144px 0; }
.acf-ui-datepicker .ui-icon-triangle-1-n { background-position: 0 -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-ne { background-position: -16px -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-e { background-position: -32px -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-se { background-position: -48px -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-s { background-position: -64px -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-sw { background-position: -80px -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-w { background-position: -96px -16px; }
.acf-ui-datepicker .ui-icon-triangle-1-nw { background-position: -112px -16px; }
.acf-ui-datepicker .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.acf-ui-datepicker .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.acf-ui-datepicker .ui-icon-arrow-1-n { background-position: 0 -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-ne { background-position: -16px -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-e { background-position: -32px -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-se { background-position: -48px -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-s { background-position: -64px -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-sw { background-position: -80px -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-w { background-position: -96px -32px; }
.acf-ui-datepicker .ui-icon-arrow-1-nw { background-position: -112px -32px; }
.acf-ui-datepicker .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.acf-ui-datepicker .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.acf-ui-datepicker .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.acf-ui-datepicker .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.acf-ui-datepicker .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.acf-ui-datepicker .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.acf-ui-datepicker .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.acf-ui-datepicker .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.acf-ui-datepicker .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.acf-ui-datepicker .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.acf-ui-datepicker .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.acf-ui-datepicker .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.acf-ui-datepicker .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.acf-ui-datepicker .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.acf-ui-datepicker .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.acf-ui-datepicker .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.acf-ui-datepicker .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.acf-ui-datepicker .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.acf-ui-datepicker .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.acf-ui-datepicker .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.acf-ui-datepicker .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.acf-ui-datepicker .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.acf-ui-datepicker .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.acf-ui-datepicker .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.acf-ui-datepicker .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.acf-ui-datepicker .ui-icon-arrow-4 { background-position: 0 -80px; }
.acf-ui-datepicker .ui-icon-arrow-4-diag { background-position: -16px -80px; }
.acf-ui-datepicker .ui-icon-extlink { background-position: -32px -80px; }
.acf-ui-datepicker .ui-icon-newwin { background-position: -48px -80px; }
.acf-ui-datepicker .ui-icon-refresh { background-position: -64px -80px; }
.acf-ui-datepicker .ui-icon-shuffle { background-position: -80px -80px; }
.acf-ui-datepicker .ui-icon-transfer-e-w { background-position: -96px -80px; }
.acf-ui-datepicker .ui-icon-transferthick-e-w { background-position: -112px -80px; }
.acf-ui-datepicker .ui-icon-folder-collapsed { background-position: 0 -96px; }
.acf-ui-datepicker .ui-icon-folder-open { background-position: -16px -96px; }
.acf-ui-datepicker .ui-icon-document { background-position: -32px -96px; }
.acf-ui-datepicker .ui-icon-document-b { background-position: -48px -96px; }
.acf-ui-datepicker .ui-icon-note { background-position: -64px -96px; }
.acf-ui-datepicker .ui-icon-mail-closed { background-position: -80px -96px; }
.acf-ui-datepicker .ui-icon-mail-open { background-position: -96px -96px; }
.acf-ui-datepicker .ui-icon-suitcase { background-position: -112px -96px; }
.acf-ui-datepicker .ui-icon-comment { background-position: -128px -96px; }
.acf-ui-datepicker .ui-icon-person { background-position: -144px -96px; }
.acf-ui-datepicker .ui-icon-print { background-position: -160px -96px; }
.acf-ui-datepicker .ui-icon-trash { background-position: -176px -96px; }
.acf-ui-datepicker .ui-icon-locked { background-position: -192px -96px; }
.acf-ui-datepicker .ui-icon-unlocked { background-position: -208px -96px; }
.acf-ui-datepicker .ui-icon-bookmark { background-position: -224px -96px; }
.acf-ui-datepicker .ui-icon-tag { background-position: -240px -96px; }
.acf-ui-datepicker .ui-icon-home { background-position: 0 -112px; }
.acf-ui-datepicker .ui-icon-flag { background-position: -16px -112px; }
.acf-ui-datepicker .ui-icon-calendar { background-position: -32px -112px; }
.acf-ui-datepicker .ui-icon-cart { background-position: -48px -112px; }
.acf-ui-datepicker .ui-icon-pencil { background-position: -64px -112px; }
.acf-ui-datepicker .ui-icon-clock { background-position: -80px -112px; }
.acf-ui-datepicker .ui-icon-disk { background-position: -96px -112px; }
.acf-ui-datepicker .ui-icon-calculator { background-position: -112px -112px; }
.acf-ui-datepicker .ui-icon-zoomin { background-position: -128px -112px; }
.acf-ui-datepicker .ui-icon-zoomout { background-position: -144px -112px; }
.acf-ui-datepicker .ui-icon-search { background-position: -160px -112px; }
.acf-ui-datepicker .ui-icon-wrench { background-position: -176px -112px; }
.acf-ui-datepicker .ui-icon-gear { background-position: -192px -112px; }
.acf-ui-datepicker .ui-icon-heart { background-position: -208px -112px; }
.acf-ui-datepicker .ui-icon-star { background-position: -224px -112px; }
.acf-ui-datepicker .ui-icon-link { background-position: -240px -112px; }
.acf-ui-datepicker .ui-icon-cancel { background-position: 0 -128px; }
.acf-ui-datepicker .ui-icon-plus { background-position: -16px -128px; }
.acf-ui-datepicker .ui-icon-plusthick { background-position: -32px -128px; }
.acf-ui-datepicker .ui-icon-minus { background-position: -48px -128px; }
.acf-ui-datepicker .ui-icon-minusthick { background-position: -64px -128px; }
.acf-ui-datepicker .ui-icon-close { background-position: -80px -128px; }
.acf-ui-datepicker .ui-icon-closethick { background-position: -96px -128px; }
.acf-ui-datepicker .ui-icon-key { background-position: -112px -128px; }
.acf-ui-datepicker .ui-icon-lightbulb { background-position: -128px -128px; }
.acf-ui-datepicker .ui-icon-scissors { background-position: -144px -128px; }
.acf-ui-datepicker .ui-icon-clipboard { background-position: -160px -128px; }
.acf-ui-datepicker .ui-icon-copy { background-position: -176px -128px; }
.acf-ui-datepicker .ui-icon-contact { background-position: -192px -128px; }
.acf-ui-datepicker .ui-icon-image { background-position: -208px -128px; }
.acf-ui-datepicker .ui-icon-video { background-position: -224px -128px; }
.acf-ui-datepicker .ui-icon-script { background-position: -240px -128px; }
.acf-ui-datepicker .ui-icon-alert { background-position: 0 -144px; }
.acf-ui-datepicker .ui-icon-info { background-position: -16px -144px; }
.acf-ui-datepicker .ui-icon-notice { background-position: -32px -144px; }
.acf-ui-datepicker .ui-icon-help { background-position: -48px -144px; }
.acf-ui-datepicker .ui-icon-check { background-position: -64px -144px; }
.acf-ui-datepicker .ui-icon-bullet { background-position: -80px -144px; }
.acf-ui-datepicker .ui-icon-radio-on { background-position: -96px -144px; }
.acf-ui-datepicker .ui-icon-radio-off { background-position: -112px -144px; }
.acf-ui-datepicker .ui-icon-pin-w { background-position: -128px -144px; }
.acf-ui-datepicker .ui-icon-pin-s { background-position: -144px -144px; }
.acf-ui-datepicker .ui-icon-play { background-position: 0 -160px; }
.acf-ui-datepicker .ui-icon-pause { background-position: -16px -160px; }
.acf-ui-datepicker .ui-icon-seek-next { background-position: -32px -160px; }
.acf-ui-datepicker .ui-icon-seek-prev { background-position: -48px -160px; }
.acf-ui-datepicker .ui-icon-seek-end { background-position: -64px -160px; }
.acf-ui-datepicker .ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.acf-ui-datepicker .ui-icon-seek-first { background-position: -80px -160px; }
.acf-ui-datepicker .ui-icon-stop { background-position: -96px -160px; }
.acf-ui-datepicker .ui-icon-eject { background-position: -112px -160px; }
.acf-ui-datepicker .ui-icon-volume-off { background-position: -128px -160px; }
.acf-ui-datepicker .ui-icon-volume-on { background-position: -144px -160px; }
.acf-ui-datepicker .ui-icon-power { background-position: 0 -176px; }
.acf-ui-datepicker .ui-icon-signal-diag { background-position: -16px -176px; }
.acf-ui-datepicker .ui-icon-signal { background-position: -32px -176px; }
.acf-ui-datepicker .ui-icon-battery-0 { background-position: -48px -176px; }
.acf-ui-datepicker .ui-icon-battery-1 { background-position: -64px -176px; }
.acf-ui-datepicker .ui-icon-battery-2 { background-position: -80px -176px; }
.acf-ui-datepicker .ui-icon-battery-3 { background-position: -96px -176px; }
.acf-ui-datepicker .ui-icon-circle-plus { background-position: 0 -192px; }
.acf-ui-datepicker .ui-icon-circle-minus { background-position: -16px -192px; }
.acf-ui-datepicker .ui-icon-circle-close { background-position: -32px -192px; }
.acf-ui-datepicker .ui-icon-circle-triangle-e { background-position: -48px -192px; }
.acf-ui-datepicker .ui-icon-circle-triangle-s { background-position: -64px -192px; }
.acf-ui-datepicker .ui-icon-circle-triangle-w { background-position: -80px -192px; }
.acf-ui-datepicker .ui-icon-circle-triangle-n { background-position: -96px -192px; }
.acf-ui-datepicker .ui-icon-circle-arrow-e { background-position: -112px -192px; }
.acf-ui-datepicker .ui-icon-circle-arrow-s { background-position: -128px -192px; }
.acf-ui-datepicker .ui-icon-circle-arrow-w { background-position: -144px -192px; }
.acf-ui-datepicker .ui-icon-circle-arrow-n { background-position: -160px -192px; }
.acf-ui-datepicker .ui-icon-circle-zoomin { background-position: -176px -192px; }
.acf-ui-datepicker .ui-icon-circle-zoomout { background-position: -192px -192px; }
.acf-ui-datepicker .ui-icon-circle-check { background-position: -208px -192px; }
.acf-ui-datepicker .ui-icon-circlesmall-plus { background-position: 0 -208px; }
.acf-ui-datepicker .ui-icon-circlesmall-minus { background-position: -16px -208px; }
.acf-ui-datepicker .ui-icon-circlesmall-close { background-position: -32px -208px; }
.acf-ui-datepicker .ui-icon-squaresmall-plus { background-position: -48px -208px; }
.acf-ui-datepicker .ui-icon-squaresmall-minus { background-position: -64px -208px; }
.acf-ui-datepicker .ui-icon-squaresmall-close { background-position: -80px -208px; }
.acf-ui-datepicker .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.acf-ui-datepicker .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.acf-ui-datepicker .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.acf-ui-datepicker .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.acf-ui-datepicker .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.acf-ui-datepicker .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.acf-ui-datepicker .ui-corner-all,
.acf-ui-datepicker .ui-corner-top,
.acf-ui-datepicker .ui-corner-left,
.acf-ui-datepicker .ui-corner-tl {
border-top-left-radius: 3;
}
.acf-ui-datepicker .ui-corner-all,
.acf-ui-datepicker .ui-corner-top,
.acf-ui-datepicker .ui-corner-right,
.acf-ui-datepicker .ui-corner-tr {
border-top-right-radius: 3;
}
.acf-ui-datepicker .ui-corner-all,
.acf-ui-datepicker .ui-corner-bottom,
.acf-ui-datepicker .ui-corner-left,
.acf-ui-datepicker .ui-corner-bl {
border-bottom-left-radius: 3;
}
.acf-ui-datepicker .ui-corner-all,
.acf-ui-datepicker .ui-corner-bottom,
.acf-ui-datepicker .ui-corner-right,
.acf-ui-datepicker .ui-corner-br {
border-bottom-right-radius: 3;
}
/* Overlays */
.acf-ui-datepicker .ui-widget-overlay {
background: #ffffff;
opacity: .3;
filter: Alpha(Opacity=30); /* support: IE8 */
}
.acf-ui-datepicker .ui-widget-shadow {
margin: -8px 0 0 -8px;
padding: 8px;
background: #aaaaaa;
opacity: .3;
filter: Alpha(Opacity=30); /* support: IE8 */
border-radius: 8px;
}
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,704 @@
/*
Version: 3.5.2 Timestamp: Sat Nov 1 14:43:36 EDT 2014
*/
.select2-container {
margin: 0;
position: relative;
display: inline-block;
/* inline-block for ie7 */
zoom: 1;
*display: inline;
vertical-align: middle;
}
.select2-container,
.select2-drop,
.select2-search,
.select2-search input {
/*
Force border-box so that % widths fit the parent
container without overlap because of margin/padding.
More Info : http://www.quirksmode.org/css/box.html
*/
-webkit-box-sizing: border-box; /* webkit */
-moz-box-sizing: border-box; /* firefox */
box-sizing: border-box; /* css3 */
}
.select2-container .select2-choice {
display: block;
height: 26px;
padding: 0 0 0 8px;
overflow: hidden;
position: relative;
border: 1px solid #aaa;
white-space: nowrap;
line-height: 26px;
color: #444;
text-decoration: none;
border-radius: 4px;
background-clip: padding-box;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: #fff;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);
background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);
background-image: linear-gradient(to top, #eee 0%, #fff 50%);
}
html[dir="rtl"] .select2-container .select2-choice {
padding: 0 8px 0 0;
}
.select2-container.select2-drop-above .select2-choice {
border-bottom-color: #aaa;
border-radius: 0 0 4px 4px;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);
background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
background-image: linear-gradient(to bottom, #eee 0%, #fff 90%);
}
.select2-container.select2-allowclear .select2-choice .select2-chosen {
margin-right: 42px;
}
.select2-container .select2-choice > .select2-chosen {
margin-right: 26px;
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
float: none;
width: auto;
}
html[dir="rtl"] .select2-container .select2-choice > .select2-chosen {
margin-left: 26px;
margin-right: 0;
}
.select2-container .select2-choice abbr {
display: none;
width: 12px;
height: 12px;
position: absolute;
right: 24px;
top: 8px;
font-size: 1px;
text-decoration: none;
border: 0;
background: url('select2.png') right top no-repeat;
cursor: pointer;
outline: 0;
}
.select2-container.select2-allowclear .select2-choice abbr {
display: inline-block;
}
.select2-container .select2-choice abbr:hover {
background-position: right -11px;
cursor: pointer;
}
.select2-drop-mask {
border: 0;
margin: 0;
padding: 0;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 9998;
/* styles required for IE to work */
background-color: #fff;
filter: alpha(opacity=0);
}
.select2-drop {
width: 100%;
margin-top: -1px;
position: absolute;
z-index: 9999;
top: 100%;
background: #fff;
color: #000;
border: 1px solid #aaa;
border-top: 0;
border-radius: 0 0 4px 4px;
-webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
}
.select2-drop.select2-drop-above {
margin-top: 1px;
border-top: 1px solid #aaa;
border-bottom: 0;
border-radius: 4px 4px 0 0;
-webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
}
.select2-drop-active {
border: 1px solid #5897fb;
border-top: none;
}
.select2-drop.select2-drop-above.select2-drop-active {
border-top: 1px solid #5897fb;
}
.select2-drop-auto-width {
border-top: 1px solid #aaa;
width: auto;
}
.select2-drop-auto-width .select2-search {
padding-top: 4px;
}
.select2-container .select2-choice .select2-arrow {
display: inline-block;
width: 18px;
height: 100%;
position: absolute;
right: 0;
top: 0;
border-left: 1px solid #aaa;
border-radius: 0 4px 4px 0;
background-clip: padding-box;
background: #ccc;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
background-image: linear-gradient(to top, #ccc 0%, #eee 60%);
}
html[dir="rtl"] .select2-container .select2-choice .select2-arrow {
left: 0;
right: auto;
border-left: none;
border-right: 1px solid #aaa;
border-radius: 4px 0 0 4px;
}
.select2-container .select2-choice .select2-arrow b {
display: block;
width: 100%;
height: 100%;
background: url('select2.png') no-repeat 0 1px;
}
html[dir="rtl"] .select2-container .select2-choice .select2-arrow b {
background-position: 2px 1px;
}
.select2-search {
display: inline-block;
width: 100%;
min-height: 26px;
margin: 0;
padding-left: 4px;
padding-right: 4px;
position: relative;
z-index: 10000;
white-space: nowrap;
}
.select2-search input {
width: 100%;
height: auto !important;
min-height: 26px;
padding: 4px 20px 4px 5px;
margin: 0;
outline: 0;
font-family: sans-serif;
font-size: 1em;
border: 1px solid #aaa;
border-radius: 0;
-webkit-box-shadow: none;
box-shadow: none;
background: #fff url('select2.png') no-repeat 100% -22px;
background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
background: url('select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
}
html[dir="rtl"] .select2-search input {
padding: 4px 5px 4px 20px;
background: #fff url('select2.png') no-repeat -37px -22px;
background: url('select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
background: url('select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
background: url('select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
background: url('select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
}
.select2-drop.select2-drop-above .select2-search input {
margin-top: 4px;
}
.select2-search input.select2-active {
background: #fff url('select2-spinner.gif') no-repeat 100%;
background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
}
.select2-container-active .select2-choice,
.select2-container-active .select2-choices {
border: 1px solid #5897fb;
outline: none;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
}
.select2-dropdown-open .select2-choice {
border-bottom-color: transparent;
-webkit-box-shadow: 0 1px 0 #fff inset;
box-shadow: 0 1px 0 #fff inset;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-color: #eee;
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
background-image: linear-gradient(to top, #fff 0%, #eee 50%);
}
.select2-dropdown-open.select2-drop-above .select2-choice,
.select2-dropdown-open.select2-drop-above .select2-choices {
border: 1px solid #5897fb;
border-top-color: transparent;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
background-image: linear-gradient(to bottom, #fff 0%, #eee 50%);
}
.select2-dropdown-open .select2-choice .select2-arrow {
background: transparent;
border-left: none;
filter: none;
}
html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow {
border-right: none;
}
.select2-dropdown-open .select2-choice .select2-arrow b {
background-position: -18px 1px;
}
html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow b {
background-position: -16px 1px;
}
.select2-hidden-accessible {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
/* results */
.select2-results {
max-height: 200px;
padding: 0 0 0 4px;
margin: 4px 4px 4px 0;
position: relative;
overflow-x: hidden;
overflow-y: auto;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
html[dir="rtl"] .select2-results {
padding: 0 4px 0 0;
margin: 4px 0 4px 4px;
}
.select2-results ul.select2-result-sub {
margin: 0;
padding-left: 0;
}
.select2-results li {
list-style: none;
display: list-item;
background-image: none;
}
.select2-results li.select2-result-with-children > .select2-result-label {
font-weight: bold;
}
.select2-results .select2-result-label {
padding: 3px 7px 4px;
margin: 0;
cursor: pointer;
min-height: 1em;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.select2-results-dept-1 .select2-result-label { padding-left: 20px }
.select2-results-dept-2 .select2-result-label { padding-left: 40px }
.select2-results-dept-3 .select2-result-label { padding-left: 60px }
.select2-results-dept-4 .select2-result-label { padding-left: 80px }
.select2-results-dept-5 .select2-result-label { padding-left: 100px }
.select2-results-dept-6 .select2-result-label { padding-left: 110px }
.select2-results-dept-7 .select2-result-label { padding-left: 120px }
.select2-results .select2-highlighted {
background: #3875d7;
color: #fff;
}
.select2-results li em {
background: #feffde;
font-style: normal;
}
.select2-results .select2-highlighted em {
background: transparent;
}
.select2-results .select2-highlighted ul {
background: #fff;
color: #000;
}
.select2-results .select2-no-results,
.select2-results .select2-searching,
.select2-results .select2-ajax-error,
.select2-results .select2-selection-limit {
background: #f4f4f4;
display: list-item;
padding-left: 5px;
}
/*
disabled look for disabled choices in the results dropdown
*/
.select2-results .select2-disabled.select2-highlighted {
color: #666;
background: #f4f4f4;
display: list-item;
cursor: default;
}
.select2-results .select2-disabled {
background: #f4f4f4;
display: list-item;
cursor: default;
}
.select2-results .select2-selected {
display: none;
}
.select2-more-results.select2-active {
background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
}
.select2-results .select2-ajax-error {
background: rgba(255, 50, 50, .2);
}
.select2-more-results {
background: #f4f4f4;
display: list-item;
}
/* disabled styles */
.select2-container.select2-container-disabled .select2-choice {
background-color: #f4f4f4;
background-image: none;
border: 1px solid #ddd;
cursor: default;
}
.select2-container.select2-container-disabled .select2-choice .select2-arrow {
background-color: #f4f4f4;
background-image: none;
border-left: 0;
}
.select2-container.select2-container-disabled .select2-choice abbr {
display: none;
}
/* multiselect */
.select2-container-multi .select2-choices {
height: auto !important;
height: 1%;
margin: 0;
padding: 0 5px 0 0;
position: relative;
border: 1px solid #aaa;
cursor: text;
overflow: hidden;
background-color: #fff;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
background-image: linear-gradient(to bottom, #eee 1%, #fff 15%);
}
html[dir="rtl"] .select2-container-multi .select2-choices {
padding: 0 0 0 5px;
}
.select2-locked {
padding: 3px 5px 3px 5px !important;
}
.select2-container-multi .select2-choices {
min-height: 26px;
}
.select2-container-multi.select2-container-active .select2-choices {
border: 1px solid #5897fb;
outline: none;
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
}
.select2-container-multi .select2-choices li {
float: left;
list-style: none;
}
html[dir="rtl"] .select2-container-multi .select2-choices li
{
float: right;
}
.select2-container-multi .select2-choices .select2-search-field {
margin: 0;
padding: 0;
white-space: nowrap;
}
.select2-container-multi .select2-choices .select2-search-field input {
padding: 5px;
margin: 1px 0;
font-family: sans-serif;
font-size: 100%;
color: #666;
outline: 0;
border: 0;
-webkit-box-shadow: none;
box-shadow: none;
background: transparent !important;
}
.select2-container-multi .select2-choices .select2-search-field input.select2-active {
background: #fff url('select2-spinner.gif') no-repeat 100% !important;
}
.select2-default {
color: #999 !important;
}
.select2-container-multi .select2-choices .select2-search-choice {
padding: 3px 5px 3px 18px;
margin: 3px 0 3px 5px;
position: relative;
line-height: 13px;
color: #333;
cursor: default;
border: 1px solid #aaaaaa;
border-radius: 3px;
-webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
background-clip: padding-box;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: #e4e4e4;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
background-image: linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
}
html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice
{
margin: 3px 5px 3px 0;
padding: 3px 18px 3px 5px;
}
.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
cursor: default;
}
.select2-container-multi .select2-choices .select2-search-choice-focus {
background: #d4d4d4;
}
.select2-search-choice-close {
display: block;
width: 12px;
height: 13px;
position: absolute;
right: 3px;
top: 4px;
font-size: 1px;
outline: none;
background: url('select2.png') right top no-repeat;
}
html[dir="rtl"] .select2-search-choice-close {
right: auto;
left: 3px;
}
.select2-container-multi .select2-search-choice-close {
left: 3px;
}
html[dir="rtl"] .select2-container-multi .select2-search-choice-close {
left: auto;
right: 2px;
}
.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
background-position: right -11px;
}
.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
background-position: right -11px;
}
/* disabled styles */
.select2-container-multi.select2-container-disabled .select2-choices {
background-color: #f4f4f4;
background-image: none;
border: 1px solid #ddd;
cursor: default;
}
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
padding: 3px 5px 3px 5px;
border: 1px solid #ddd;
background-image: none;
background-color: #f4f4f4;
}
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none;
background: none;
}
/* end multiselect */
.select2-result-selectable .select2-match,
.select2-result-unselectable .select2-match {
text-decoration: underline;
}
.select2-offscreen, .select2-offscreen:focus {
clip: rect(0 0 0 0) !important;
width: 1px !important;
height: 1px !important;
border: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
position: absolute !important;
outline: 0 !important;
left: 0px !important;
top: 0px !important;
}
.select2-display-none {
display: none;
}
.select2-measure-scrollbar {
position: absolute;
top: -10000px;
left: -10000px;
width: 100px;
height: 100px;
overflow: scroll;
}
/* Retina-ize icons */
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 2dppx) {
.select2-search input,
.select2-search-choice-close,
.select2-container .select2-choice abbr,
.select2-container .select2-choice .select2-arrow b {
background-image: url('select2x2.png') !important;
background-repeat: no-repeat !important;
background-size: 60px 40px !important;
}
.select2-search input {
background-position: 100% -21px !important;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

@@ -0,0 +1,484 @@
.select2-container {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle; }
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
display: block;
height: 28px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-selection--single .select2-selection__clear {
position: relative; }
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px; }
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline-block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-search--inline {
float: left; }
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin-top: 5px;
padding: 0; }
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-dropdown {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051; }
.select2-results {
display: block; }
.select2-results__options {
list-style: none;
margin: 0;
padding: 0; }
.select2-results__option {
padding: 6px;
user-select: none;
-webkit-user-select: none; }
.select2-results__option[aria-selected] {
cursor: pointer; }
.select2-container--open .select2-dropdown {
left: 0; }
.select2-container--open .select2-dropdown--above {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--open .select2-dropdown--below {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-search--dropdown {
display: block;
padding: 4px; }
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box; }
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-search--dropdown.select2-search--hide {
display: none; }
.select2-close-mask {
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0); }
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important; }
.select2-container--default .select2-selection--single {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--default .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold; }
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px; }
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto; }
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none; }
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 5px;
width: 100%; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none; }
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
color: #999;
margin-top: 5px;
float: left; }
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-top: 5px;
margin-right: 10px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid black 1px;
outline: 0; }
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none; }
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa; }
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield; }
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--default .select2-results__option[role=group] {
padding: 0; }
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999; }
.select2-container--default .select2-results__option[aria-selected=true] {
background-color: #ddd; }
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em; }
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #5897fb;
color: white; }
.select2-container--default .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic .select2-selection--single {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--classic .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-right: 10px; }
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--classic .select2-selection--single .select2-selection__arrow {
background-color: #ddd;
border: none;
border-left: 1px solid #aaa;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto; }
.select2-container--classic.select2-container--open .select2-selection--single {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
background: transparent;
border: none; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
.select2-container--classic .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0; }
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
list-style: none;
margin: 0;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
color: #888;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
float: right; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--classic.select2-container--open .select2-selection--multiple {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--classic .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: 0; }
.select2-container--classic .select2-search--inline .select2-search__field {
outline: 0;
box-shadow: none; }
.select2-container--classic .select2-dropdown {
background-color: white;
border: 1px solid transparent; }
.select2-container--classic .select2-dropdown--above {
border-bottom: none; }
.select2-container--classic .select2-dropdown--below {
border-top: none; }
.select2-container--classic .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--classic .select2-results__option[role=group] {
padding: 0; }
.select2-container--classic .select2-results__option[aria-disabled=true] {
color: grey; }
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
background-color: #3875d7;
color: white; }
.select2-container--classic .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic.select2-container--open .select2-dropdown {
border-color: #5897fb; }
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,30 @@
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
.ui-timepicker-div dl { text-align: left; }
.ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
.ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
.ui-timepicker-div td { font-size: 90%; }
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
.ui-timepicker-div .ui_tpicker_unit_hide{ display: none; }
.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input { background: none; color: inherit; border: none; outline: none; border-bottom: solid 1px #555; width: 95%; }
.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus { border-bottom-color: #aaa; }
.ui-timepicker-rtl{ direction: rtl; }
.ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
.ui-timepicker-rtl dl dt{ float: right; clear: right; }
.ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
/* Shortened version style */
.ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
.ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
.ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
.ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before { content:'.'; display:inline-block; }
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{ display: none; }
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20
* http://trentrichardson.com/examples/timepicker
* Copyright (c) 2016 Trent Richardson; Licensed MIT */
.ui-timepicker-div .ui-widget-header{margin-bottom:8px}.ui-timepicker-div dl{text-align:left}.ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.ui-timepicker-div dl dd{margin:0 10px 10px 40%}.ui-timepicker-div td{font-size:90%}.ui-tpicker-grid-label{background:0 0;border:0;margin:0;padding:0}.ui-timepicker-div .ui_tpicker_unit_hide{display:none}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input{background:0 0;color:inherit;border:0;outline:0;border-bottom:solid 1px #555;width:95%}.ui-timepicker-div .ui_tpicker_time .ui_tpicker_time_input:focus{border-bottom-color:#aaa}.ui-timepicker-rtl{direction:rtl}.ui-timepicker-rtl dl{text-align:right;padding:0 5px 0 0}.ui-timepicker-rtl dl dt{float:right;clear:right}.ui-timepicker-rtl dl dd{margin:0 40% 10px 10px}.ui-timepicker-div.ui-timepicker-oneLine{padding-right:2px}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,.ui-timepicker-div.ui-timepicker-oneLine dt{display:none}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label{display:block;padding-top:2px}.ui-timepicker-div.ui-timepicker-oneLine dl{text-align:right}.ui-timepicker-div.ui-timepicker-oneLine dl dd,.ui-timepicker-div.ui-timepicker-oneLine dl dd>div{display:inline-block;margin:0}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before{content:':';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before{content:'.';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{display:none}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,163 @@
<?php
// Register store for form data.
acf_register_store( 'form' );
/**
* acf_set_form_data
*
* Sets data about the current form.
*
* @date 6/10/13
* @since 5.0.0
*
* @param string $name The store name.
* @param array $data Array of data to start the store with.
* @return ACF_Data
*/
function acf_set_form_data( $name = '', $data = false ) {
return acf_get_store( 'form' )->set( $name, $data );
}
/**
* acf_get_form_data
*
* Gets data about the current form.
*
* @date 6/10/13
* @since 5.0.0
*
* @param string $name The store name.
* @return mixed
*/
function acf_get_form_data( $name = '' ) {
return acf_get_store( 'form' )->get( $name );
}
/**
* acf_form_data
*
* Called within a form to set important information and render hidden inputs.
*
* @date 15/10/13
* @since 5.0.0
*
* @param void
* @return void
*/
function acf_form_data( $data = array() ) {
// Apply defaults.
$data = wp_parse_args($data, array(
/** @type string The current screen (post, user, taxonomy, etc). */
'screen' => 'post',
/** @type int|string The ID of current post being edited. */
'post_id' => 0,
/** @type bool Enables AJAX validation. */
'validation' => true,
));
// Create nonce using screen.
$data['nonce'] = wp_create_nonce( $data['screen'] );
// Append "changed" input used within "_wp_post_revision_fields" action.
$data['changed'] = 0;
// Set data.
acf_set_form_data( $data );
// Render HTML.
?>
<div id="acf-form-data" class="acf-hidden">
<?php
// Create hidden inputs from $data
foreach( $data as $name => $value ) {
acf_hidden_input(array(
'id' => '_acf_' . $name,
'name' => '_acf_' . $name,
'value' => $value
));
}
/**
* Fires within the #acf-form-data element to add extra HTML.
*
* @date 15/10/13
* @since 5.0.0
*
* @param array $data The form data.
*/
do_action( 'acf/form_data', $data );
do_action( 'acf/input/form_data', $data );
?>
</div>
<?php
}
/**
* acf_save_post
*
* Saves the $_POST data.
*
* @date 15/10/13
* @since 5.0.0
*
* @param int|string $post_id The post id.
* @param array $values An array of values to override $_POST.
* @return bool True if save was successful.
*/
function acf_save_post( $post_id = 0, $values = null ) {
// Override $_POST data with $values.
if( $values !== null ) {
$_POST['acf'] = $values;
}
// Bail early if no data to save.
if( empty($_POST['acf']) ) {
return false;
}
// Set form data (useful in various filters/actions).
acf_set_form_data( 'post_id', $post_id );
// Filter $_POST data for users without the 'unfiltered_html' capability.
if( !acf_allow_unfiltered_html() ) {
$_POST['acf'] = wp_kses_post_deep( $_POST['acf'] );
}
// Do generic action.
do_action( 'acf/save_post', $post_id );
// Return true.
return true;
}
/**
* _acf_do_save_post
*
* Private function hooked into 'acf/save_post' to actually save the $_POST data.
* This allows developers to hook in before and after ACF has actually saved the data.
*
* @date 11/1/19
* @since 5.7.10
*
* @param int|string $post_id The post id.
* @return void
*/
function _acf_do_save_post( $post_id = 0 ) {
// Check and update $_POST data.
if( $_POST['acf'] ) {
acf_update_values( $_POST['acf'], $post_id );
}
}
// Run during generic action.
add_action( 'acf/save_post', '_acf_do_save_post' );
@@ -0,0 +1,387 @@
<?php
/*
* acf_is_empty
*
* Returns true if the value provided is considered "empty". Allows numbers such as 0.
*
* @date 6/7/16
* @since 5.4.0
*
* @param mixed $var The value to check.
* @return bool
*/
function acf_is_empty( $var ) {
return ( !$var && !is_numeric($var) );
}
/**
* acf_not_empty
*
* Returns true if the value provided is considered "not empty". Allows numbers such as 0.
*
* @date 15/7/19
* @since 5.8.1
*
* @param mixed $var The value to check.
* @return bool
*/
function acf_not_empty( $var ) {
return ( $var || is_numeric($var) );
}
/**
* acf_uniqid
*
* Returns a unique numeric based id.
*
* @date 9/1/19
* @since 5.7.10
*
* @param string $prefix The id prefix. Defaults to 'acf'.
* @return string
*/
function acf_uniqid( $prefix = 'acf' ) {
// Instantiate global counter.
global $acf_uniqid;
if( !isset($acf_uniqid) ) {
$acf_uniqid = 1;
}
// Return id.
return $prefix . '-' . $acf_uniqid++;
}
/**
* acf_merge_attributes
*
* Merges together two arrays but with extra functionality to append class names.
*
* @date 22/1/19
* @since 5.7.10
*
* @param array $array1 An array of attributes.
* @param array $array2 An array of attributes.
* @return array
*/
function acf_merge_attributes( $array1, $array2 ) {
// Merge together attributes.
$array3 = array_merge( $array1, $array2 );
// Append together special attributes.
foreach( array('class', 'style') as $key ) {
if( isset($array1[$key]) && isset($array2[$key]) ) {
$array3[$key] = trim($array1[$key]) . ' ' . trim($array2[$key]);
}
}
// Return.
return $array3;
}
/**
* acf_cache_key
*
* Returns a filtered cache key.
*
* @date 25/1/19
* @since 5.7.11
*
* @param string $key The cache key.
* @return string
*/
function acf_cache_key( $key = '' ) {
/**
* Filters the cache key.
*
* @date 25/1/19
* @since 5.7.11
*
* @param string $key The cache key.
* @param string $original_key The original cache key.
*/
return apply_filters( "acf/get_cache_key", $key, $key );
}
/**
* acf_request_args
*
* Returns an array of $_REQUEST values using the provided defaults.
*
* @date 28/2/19
* @since 5.7.13
*
* @param array $args An array of args.
* @return array
*/
function acf_request_args( $args = array() ) {
foreach( $args as $k => $v ) {
$args[ $k ] = isset($_REQUEST[ $k ]) ? $_REQUEST[ $k ] : $args[ $k ];
}
return $args;
}
// Register store.
acf_register_store( 'filters' );
/**
* acf_enable_filter
*
* Enables a filter with the given name.
*
* @date 14/7/16
* @since 5.4.0
*
* @param string name The modifer name.
* @return void
*/
function acf_enable_filter( $name = '' ) {
acf_get_store( 'filters' )->set( $name, true );
}
/**
* acf_disable_filter
*
* Disables a filter with the given name.
*
* @date 14/7/16
* @since 5.4.0
*
* @param string name The modifer name.
* @return void
*/
function acf_disable_filter( $name = '' ) {
acf_get_store( 'filters' )->set( $name, false );
}
/**
* acf_is_filter_enabled
*
* Returns the state of a filter for the given name.
*
* @date 14/7/16
* @since 5.4.0
*
* @param string name The modifer name.
* @return array
*/
function acf_is_filter_enabled( $name = '' ) {
return acf_get_store( 'filters' )->get( $name );
}
/**
* acf_get_filters
*
* Returns an array of filters in their current state.
*
* @date 14/7/16
* @since 5.4.0
*
* @param void
* @return array
*/
function acf_get_filters() {
return acf_get_store( 'filters' )->get();
}
/**
* acf_set_filters
*
* Sets an array of filter states.
*
* @date 14/7/16
* @since 5.4.0
*
* @param array $filters An Array of modifers
* @return array
*/
function acf_set_filters( $filters = array() ) {
acf_get_store( 'filters' )->set( $filters );
}
/**
* acf_disable_filters
*
* Disables all filters and returns the previous state.
*
* @date 14/7/16
* @since 5.4.0
*
* @param void
* @return array
*/
function acf_disable_filters() {
// Get state.
$prev_state = acf_get_filters();
// Set all modifers as false.
acf_set_filters( array_map('__return_false', $prev_state) );
// Return prev state.
return $prev_state;
}
/**
* acf_enable_filters
*
* Enables all or an array of specific filters and returns the previous state.
*
* @date 14/7/16
* @since 5.4.0
*
* @param array $filters An Array of modifers
* @return array
*/
function acf_enable_filters( $filters = array() ) {
// Get state.
$prev_state = acf_get_filters();
// Allow specific filters to be enabled.
if( $filters ) {
acf_set_filters( $filters );
// Set all modifers as true.
} else {
acf_set_filters( array_map('__return_true', $prev_state) );
}
// Return prev state.
return $prev_state;
}
/**
* acf_idval
*
* Parses the provided value for an ID.
*
* @date 29/3/19
* @since 5.7.14
*
* @param mixed $value A value to parse.
* @return int
*/
function acf_idval( $value ) {
// Check if value is numeric.
if( is_numeric($value) ) {
return (int) $value;
// Check if value is array.
} elseif( is_array($value) ) {
return (int) isset($value['ID']) ? $value['ID'] : 0;
// Check if value is object.
} elseif( is_object($value) ) {
return (int) isset($value->ID) ? $value->ID : 0;
}
// Return default.
return 0;
}
/**
* acf_maybe_idval
*
* Checks value for potential id value.
*
* @date 6/4/19
* @since 5.7.14
*
* @param mixed $value A value to parse.
* @return mixed
*/
function acf_maybe_idval( $value ) {
if( $id = acf_idval( $value ) ) {
return $id;
}
return $value;
}
/**
* acf_numericval
*
* Casts the provided value as eiter an int or float using a simple hack.
*
* @date 11/4/19
* @since 5.7.14
*
* @param mixed $value A value to parse.
* @return (int|float)
*/
function acf_numval( $value ) {
return ( intval($value) == floatval($value) ) ? intval($value) : floatval($value);
}
/**
* acf_idify
*
* Returns an id attribute friendly string.
*
* @date 24/12/17
* @since 5.6.5
*
* @param string $str The string to convert.
* @return string
*/
function acf_idify( $str = '' ) {
return str_replace(array('][', '[', ']'), array('-', '-', ''), strtolower($str));
}
/**
* acf_slugify
*
* Returns a slug friendly string.
*
* @date 24/12/17
* @since 5.6.5
*
* @param string $str The string to convert.
* @return string
*/
function acf_slugify( $str = '' ) {
return str_replace(array('_', '/', ' '), '-', strtolower($str));
}
/**
* acf_punctify
*
* Returns a string with correct full stop puctuation.
*
* @date 12/7/19
* @since 5.8.2
*
* @param string $str The string to format.
* @return string
*/
function acf_punctify( $str = '' ) {
return trim($str, '.') . '.';
}
/**
* acf_did
*
* Returns true if ACF already did an event.
*
* @date 30/8/19
* @since 5.8.1
*
* @param string $name The name of the event.
* @return bool
*/
function acf_did( $name ) {
// Return true if already did the event (preventing event).
if( acf_get_data("acf_did_$name") ) {
return true;
// Otherwise, update store and return false (alowing event).
} else {
acf_set_data("acf_did_$name", true);
return false;
}
}
@@ -0,0 +1,220 @@
<?php
// Register store.
acf_register_store( 'hook-variations' );
/**
* acf_add_filter_variations
*
* Registers variations for the given filter.
*
* @date 26/1/19
* @since 5.7.11
*
* @param string $filter The filter name.
* @param array $variations An array variation keys.
* @param int $index The param index to find variation values.
* @return void
*/
function acf_add_filter_variations( $filter = '', $variations = array(), $index = 0 ) {
// Store replacement data.
acf_get_store('hook-variations')->set( $filter, array(
'type' => 'filter',
'variations' => $variations,
'index' => $index,
));
// Add generic handler.
// Use a priotiry of 10, and accepted args of 10 (ignored by WP).
add_filter( $filter, '_acf_apply_hook_variations', 10, 10 );
}
/**
* acf_add_action_variations
*
* Registers variations for the given action.
*
* @date 26/1/19
* @since 5.7.11
*
* @param string $action The action name.
* @param array $variations An array variation keys.
* @param int $index The param index to find variation values.
* @return void
*/
function acf_add_action_variations( $action = '', $variations = array(), $index = 0 ) {
// Store replacement data.
acf_get_store('hook-variations')->set( $action, array(
'type' => 'action',
'variations' => $variations,
'index' => $index,
));
// Add generic handler.
// Use a priotiry of 10, and accepted args of 10 (ignored by WP).
add_action( $action, '_acf_apply_hook_variations', 10, 10 );
}
/**
* _acf_apply_hook_variations
*
* Applys hook variations during apply_filters() or do_action().
*
* @date 25/1/19
* @since 5.7.11
*
* @param mixed
* @return mixed
*/
function _acf_apply_hook_variations() {
// Get current filter.
$filter = current_filter();
// Get args provided.
$args = func_get_args();
// Get variation information.
$variations = acf_get_store('hook-variations')->get( $filter );
extract( $variations );
// Find field in args using index.
$field = $args[ $index ];
// Loop over variations and apply filters.
foreach( $variations as $variation ) {
// Get value from field.
// First look for "backup" value ("_name", "_key").
if( isset($field[ "_$variation" ]) ) {
$value = $field[ "_$variation" ];
} elseif( isset($field[ $variation ]) ) {
$value = $field[ $variation ];
} else {
continue;
}
// Apply filters.
if( $type === 'filter' ) {
$args[0] = apply_filters_ref_array( "$filter/$variation=$value", $args );
// Or do action.
} else {
do_action_ref_array( "$filter/$variation=$value", $args );
}
}
// Return first arg.
return $args[0];
}
// Register store.
acf_register_store( 'deprecated-hooks' );
/**
* acf_add_deprecated_filter
*
* Registers a deprecated filter to run during the replacement.
*
* @date 25/1/19
* @since 5.7.11
*
* @param string $deprecated The deprecated hook.
* @param string $version The version this hook was deprecated.
* @param string $replacement The replacement hook.
* @return void
*/
function acf_add_deprecated_filter( $deprecated, $version, $replacement ) {
// Store replacement data.
acf_get_store('deprecated-hooks')->append(array(
'type' => 'filter',
'deprecated' => $deprecated,
'replacement' => $replacement,
'version' => $version
));
// Add generic handler.
// Use a priotiry of 10, and accepted args of 10 (ignored by WP).
add_filter( $replacement, '_acf_apply_deprecated_hook', 10, 10 );
}
/**
* acf_add_deprecated_action
*
* Registers a deprecated action to run during the replacement.
*
* @date 25/1/19
* @since 5.7.11
*
* @param string $deprecated The deprecated hook.
* @param string $version The version this hook was deprecated.
* @param string $replacement The replacement hook.
* @return void
*/
function acf_add_deprecated_action( $deprecated, $version, $replacement ) {
// Store replacement data.
acf_get_store('deprecated-hooks')->append(array(
'type' => 'action',
'deprecated' => $deprecated,
'replacement' => $replacement,
'version' => $version
));
// Add generic handler.
// Use a priotiry of 10, and accepted args of 10 (ignored by WP).
add_filter( $replacement, '_acf_apply_deprecated_hook', 10, 10 );
}
/**
* _acf_apply_deprecated_hook
*
* Applys a deprecated filter during apply_filters() or do_action().
*
* @date 25/1/19
* @since 5.7.11
*
* @param mixed
* @return mixed
*/
function _acf_apply_deprecated_hook() {
// Get current hook.
$hook = current_filter();
// Get args provided.
$args = func_get_args();
// Get deprecated items for this hook.
$items = acf_get_store('deprecated-hooks')->query(array( 'replacement' => $hook ));
// Loop over results.
foreach( $items as $item ) {
// Extract data.
extract( $item );
// Check if anyone is hooked into this deprecated hook.
if( has_filter($deprecated) ) {
// Log warning.
//_deprecated_hook( $deprecated, $version, $hook );
// Apply filters.
if( $type === 'filter' ) {
$args[0] = apply_filters_ref_array( $deprecated, $args );
// Or do action.
} else {
do_action_ref_array( $deprecated, $args );
}
}
}
// Return first arg.
return $args[0];
}
@@ -0,0 +1,472 @@
<?php
/**
* acf_filter_attrs
*
* Filters out empty attrs from the provided array.
*
* @date 11/6/19
* @since 5.8.1
*
* @param array $attrs The array of attrs.
* @return array
*/
function acf_filter_attrs( $attrs ) {
// Filter out empty attrs but allow "0" values.
$filtered = array_filter( $attrs, 'acf_not_empty' );
// Correct specific attributes (required="required").
foreach( array('required', 'readonly', 'disabled', 'multiple') as $key ) {
unset($filtered[ $key ]);
if( !empty($attrs[ $key ]) ) {
$filtered[ $key ] = $key;
}
}
return $filtered;
}
/**
* acf_esc_attrs
*
* Generated valid HTML from an array of attrs.
*
* @date 11/6/19
* @since 5.8.1
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_esc_attrs( $attrs ) {
$html = '';
// Loop over attrs and validate data types.
foreach( $attrs as $k => $v ) {
// String (but don't trim value).
if( is_string($v) && ($k !== 'value') ) {
$v = trim($v);
// Boolean
} elseif( is_bool($v) ) {
$v = $v ? 1 : 0;
// Object
} elseif( is_array($v) || is_object($v) ) {
$v = json_encode($v);
}
// Generate HTML.
$html .= sprintf( ' %s="%s"', esc_attr($k), esc_attr($v) );
}
// Return trimmed.
return trim( $html );
}
/**
* acf_esc_html
*
* Encodes <script> tags for safe HTML output.
*
* @date 12/6/19
* @since 5.8.1
*
* @param string $string
* @return string
*/
function acf_esc_html( $string = '' ) {
$string = strval($string);
// Encode "<script" tags to invalidate DOM elements.
if( strpos($string, '<script') !== false ) {
$string = str_replace('<script', htmlspecialchars('<script'), $string);
$string = str_replace('</script', htmlspecialchars('</script'), $string);
}
return $string;
}
/**
* acf_html_input
*
* Returns the HTML of an input.
*
* @date 13/6/19
* @since 5.8.1
*
* @param array $attrs The array of attrs.
* @return string
*/
//function acf_html_input( $attrs = array() ) {
// return sprintf( '<input %s/>', acf_esc_attrs($attrs) );
//}
/**
* acf_hidden_input
*
* Renders the HTML of a hidden input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_hidden_input( $attrs = array() ) {
echo acf_get_hidden_input( $attrs );
}
/**
* acf_get_hidden_input
*
* Returns the HTML of a hidden input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_hidden_input( $attrs = array() ) {
return sprintf( '<input type="hidden" %s/>', acf_esc_attrs($attrs) );
}
/**
* acf_text_input
*
* Renders the HTML of a text input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_text_input( $attrs = array() ) {
echo acf_get_text_input( $attrs );
}
/**
* acf_get_text_input
*
* Returns the HTML of a text input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_text_input( $attrs = array() ) {
$attrs = wp_parse_args($attrs, array(
'type' => 'text'
));
return sprintf( '<input %s/>', acf_esc_attrs($attrs) );
}
/**
* acf_file_input
*
* Renders the HTML of a file input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_file_input( $attrs = array() ) {
echo acf_get_file_input( $attrs );
}
/**
* acf_get_file_input
*
* Returns the HTML of a file input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_file_input( $attrs = array() ) {
return sprintf( '<input type="file" %s/>', acf_esc_attrs($attrs) );
}
/**
* acf_textarea_input
*
* Renders the HTML of a textarea input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_textarea_input( $attrs = array() ) {
echo acf_get_textarea_input( $attrs );
}
/**
* acf_get_textarea_input
*
* Returns the HTML of a textarea input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_textarea_input( $attrs = array() ) {
$value = '';
if( isset($attrs['value']) ) {
$value = $attrs['value'];
unset( $attrs['value'] );
}
return sprintf( '<textarea %s>%s</textarea>', acf_esc_attrs($attrs), esc_textarea($value) );
}
/**
* acf_checkbox_input
*
* Renders the HTML of a checkbox input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_checkbox_input( $attrs = array() ) {
echo acf_get_checkbox_input( $attrs );
}
/**
* acf_get_checkbox_input
*
* Returns the HTML of a checkbox input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_checkbox_input( $attrs = array() ) {
// Allow radio or checkbox type.
$attrs = wp_parse_args($attrs, array(
'type' => 'checkbox'
));
// Get label.
$label = '';
if( isset($attrs['label']) ) {
$label= $attrs['label'];
unset( $attrs['label'] );
}
// Render.
$checked = isset($attrs['checked']);
return '<label' . ($checked ? ' class="selected"' : '') . '><input ' . acf_esc_attr($attrs) . '/> ' . acf_esc_html($label) . '</label>';
}
/**
* acf_radio_input
*
* Renders the HTML of a radio input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_radio_input( $attrs = array() ) {
echo acf_get_radio_input( $attrs );
}
/**
* acf_get_radio_input
*
* Returns the HTML of a radio input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_radio_input( $attrs = array() ) {
$attrs['type'] = 'radio';
return acf_get_checkbox_input( $attrs );
}
/**
* acf_select_input
*
* Renders the HTML of a select input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_select_input( $attrs = array() ) {
echo acf_get_select_input( $attrs );
}
/**
* acf_select_input
*
* Returns the HTML of a select input.
*
* @date 3/02/2014
* @since 5.0.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_get_select_input( $attrs = array() ) {
$value = (array) acf_extract_var( $attrs, 'value' );
$choices = (array) acf_extract_var( $attrs, 'choices' );
return sprintf(
'<select %s>%s</select>',
acf_esc_attrs($attrs),
acf_walk_select_input($choices, $value)
);
}
/**
* acf_walk_select_input
*
* Returns the HTML of a select input's choices.
*
* @date 27/6/17
* @since 5.6.0
*
* @param array $choices The choices to walk through.
* @param array $values The selected choices.
* @param array $depth The current walk depth.
* @return string
*/
function acf_walk_select_input( $choices = array(), $values = array(), $depth = 0 ) {
$html = '';
// Sanitize values for 'selected' matching (only once).
if( $depth == 0 ) {
$values = array_map('esc_attr', $values);
}
// Loop over choices and append to html.
if( $choices ) {
foreach( $choices as $value => $label ) {
// Multiple (optgroup)
if( is_array($label) ){
$html .= sprintf(
'<optgroup label="%s">%s</optgroup>',
esc_attr($value),
acf_walk_select_input( $label, $values, $depth+1 )
);
// single (option)
} else {
$attrs = array(
'value' => $value
);
// If is selected.
$pos = array_search( esc_attr($value), $values );
if( $pos !== false ) {
$attrs['selected'] = 'selected';
$attrs['data-i'] = $pos;
}
$html .= sprintf( '<option %s>%s</option>', acf_esc_attr($attrs), esc_html($label) );
}
}
}
return $html;
}
/**
* acf_clean_atts
*
* See acf_filter_attrs().
*
* @date 3/10/17
* @since 5.6.3
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_clean_atts( $attrs ) {
return acf_filter_attrs( $attrs );
}
/**
* acf_esc_atts
*
* See acf_esc_attrs().
*
* @date 27/6/17
* @since 5.6.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_esc_atts( $attrs ) {
return acf_esc_attrs( $attrs );
}
/**
* acf_esc_attr
*
* See acf_esc_attrs().
*
* @date 13/6/19
* @since 5.8.1
* @deprecated 5.6.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_esc_attr( $attrs ) {
return acf_esc_attrs( $attrs );
}
/**
* acf_esc_attr_e
*
* See acf_esc_attrs().
*
* @date 13/6/19
* @since 5.8.1
* @deprecated 5.6.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_esc_attr_e( $attrs ) {
echo acf_esc_attrs( $attrs );
}
/**
* acf_esc_atts_e
*
* See acf_esc_attrs().
*
* @date 13/6/19
* @since 5.8.1
* @deprecated 5.6.0
*
* @param array $attrs The array of attrs.
* @return string
*/
function acf_esc_atts_e( $attrs ) {
echo acf_esc_attrs( $attrs );
}
@@ -0,0 +1,441 @@
<?php
/**
* acf_decode_post_id
*
* Returns an array containing the object type and id for the given post_id string.
*
* @date 25/1/19
* @since 5.7.11
*
* @param (int|string) $post_id The post id.
* @return array()
*/
function acf_decode_post_id( $post_id = 0 ) {
// Default data
$data = array(
'type' => 'post',
'id' => 0
);
// Check if is numeric.
if( is_numeric($post_id) ) {
$data['id'] = (int) $post_id;
// Check if is string.
} elseif( is_string($post_id) ) {
// Determine "{$type}_{$id}" from string.
$bits = explode( '_', $post_id );
$id = array_pop( $bits );
$type = implode( '_', $bits );
// Check if is meta type.
if( function_exists("get_{$type}_meta") && is_numeric($id) ) {
$data['type'] = $type;
$data['id'] = (int) $id;
// Check if is taxonomy name.
} elseif( taxonomy_exists($type) && is_numeric($id) ) {
$data['type'] = 'term';
$data['id'] = (int) $id;
// Otherwise, default to option.
} else {
$data['type'] = 'option';
$data['id'] = $post_id;
}
}
/**
* Filters the $data array after it has been decoded.
*
* @date 12/02/2014
* @since 5.0.0
*
* @param array $data The type and id array.
*/
return apply_filters( "acf/decode_post_id", $data, $post_id );
}
/**
* acf_get_meta
*
* Returns an array of "ACF only" meta for the given post_id.
*
* @date 9/10/18
* @since 5.8.0
*
* @param mixed $post_id The post_id for this data.
* @return array
*/
function acf_get_meta( $post_id = 0 ) {
// Allow filter to short-circuit load_value logic.
$null = apply_filters( "acf/pre_load_meta", null, $post_id );
if( $null !== null ) {
return ( $null === '__return_null' ) ? null : $null;
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id($post_id) );
// Use get_$type_meta() function when possible.
if( function_exists("get_{$type}_meta") ) {
$allmeta = call_user_func("get_{$type}_meta", $id, '');
// Default to wp_options.
} else {
$allmeta = acf_get_option_meta( $id );
}
// Loop over meta and check that a reference exists for each value.
$meta = array();
if( $allmeta ) {
foreach( $allmeta as $key => $value ) {
// If a reference exists for this value, add it to the meta array.
if( isset($allmeta["_$key"]) ) {
$meta[ $key ] = $allmeta[ $key ][0];
$meta[ "_$key" ] = $allmeta[ "_$key" ][0];
}
}
}
// Unserialized results (get_metadata does not unserialize if $key is empty).
$meta = array_map('maybe_unserialize', $meta);
/**
* Filters the $meta array after it has been loaded.
*
* @date 25/1/19
* @since 5.7.11
*
* @param array $meta The arary of loaded meta.
* @param string $post_id The $post_id for this meta.
*/
return apply_filters( "acf/load_meta", $meta, $post_id );
}
/**
* acf_get_option_meta
*
* Returns an array of meta for the given wp_option name prefix in the same format as get_post_meta().
*
* @date 9/10/18
* @since 5.8.0
*
* @param string $prefix The wp_option name prefix.
* @return array
*/
function acf_get_option_meta( $prefix = '' ) {
// Globals.
global $wpdb;
// Vars.
$meta = array();
$search = "{$prefix}_%";
$_search = "_{$prefix}_%";
// Escape underscores for LIKE.
$search = str_replace('_', '\_', $search);
$_search = str_replace('_', '\_', $_search);
// Query database for results.
$rows = $wpdb->get_results($wpdb->prepare(
"SELECT *
FROM $wpdb->options
WHERE option_name LIKE %s
OR option_name LIKE %s",
$search,
$_search
), ARRAY_A);
// Loop over results and append meta (removing the $prefix from the option name).
$len = strlen("{$prefix}_");
foreach( $rows as $row ) {
$meta[ substr($row['option_name'], $len) ][] = $row['option_value'];
}
// Return results.
return $meta;
}
/**
* acf_get_metadata
*
* Retrieves specific metadata from the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @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 acf_get_metadata( $post_id = 0, $name = '', $hidden = false ) {
// Allow filter to short-circuit logic.
$null = apply_filters( "acf/pre_load_metadata", null, $post_id, $name, $hidden );
if( $null !== null ) {
return ( $null === '__return_null' ) ? null : $null;
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id($post_id) );
// Hidden meta uses an underscore prefix.
$prefix = $hidden ? '_' : '';
// Bail early if no $id (possible during new acf_form).
if( !$id ) {
return null;
}
// Check option.
if( $type === 'option' ) {
return get_option( "{$prefix}{$id}_{$name}", null );
// Check meta.
} else {
$meta = get_metadata( $type, $id, "{$prefix}{$name}", false );
return isset($meta[0]) ? $meta[0] : null;
}
}
/**
* acf_update_metadata
*
* Updates metadata in the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @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 (int|bool) Meta ID if the key didn't exist, true on successful update, false on failure.
*/
function acf_update_metadata( $post_id = 0, $name = '', $value = '', $hidden = false ) {
// Allow filter to short-circuit logic.
$pre = apply_filters( "acf/pre_update_metadata", null, $post_id, $name, $value, $hidden );
if( $pre !== null ) {
return $pre;
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id($post_id) );
// Hidden meta uses an underscore prefix.
$prefix = $hidden ? '_' : '';
// Bail early if no $id (possible during new acf_form).
if( !$id ) {
return false;
}
// Update option.
if( $type === 'option' ) {
// Unslash value to match update_metadata() functionality.
$value = wp_unslash( $value );
$autoload = (bool) acf_get_setting('autoload');
return update_option( "{$prefix}{$id}_{$name}", $value, $autoload );
// Update meta.
} else {
return update_metadata( $type, $id, "{$prefix}{$name}", $value );
}
}
/**
* acf_delete_metadata
*
* Deletes metadata from the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @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 bool
*/
function acf_delete_metadata( $post_id = 0, $name = '', $hidden = false ) {
// Allow filter to short-circuit logic.
$pre = apply_filters( "acf/pre_delete_metadata", null, $post_id, $name, $hidden );
if( $pre !== null ) {
return $pre;
}
// Decode $post_id for $type and $id.
extract( acf_decode_post_id($post_id) );
// Hidden meta uses an underscore prefix.
$prefix = $hidden ? '_' : '';
// Bail early if no $id (possible during new acf_form).
if( !$id ) {
return false;
}
// Update option.
if( $type === 'option' ) {
$autoload = (bool) acf_get_setting('autoload');
return delete_option( "{$prefix}{$id}_{$name}" );
// Update meta.
} else {
return delete_metadata( $type, $id, "{$prefix}{$name}" );
}
}
/**
* acf_copy_postmeta
*
* Copies meta from one post to another. Useful for saving and restoring revisions.
*
* @date 25/06/2016
* @since 5.3.8
*
* @param (int|string) $from_post_id The post id to copy from.
* @param (int|string) $to_post_id The post id to paste to.
* @return void
*/
function acf_copy_metadata( $from_post_id = 0, $to_post_id = 0 ) {
// Get all postmeta.
$meta = acf_get_meta( $from_post_id );
// Check meta.
if( $meta ) {
// Slash data. WP expects all data to be slashed and will unslash it (fixes '\' character issues).
$meta = wp_slash( $meta );
// Loop over meta.
foreach( $meta as $name => $value ) {
acf_update_metadata( $to_post_id, $name, $value );
}
}
}
/**
* acf_copy_postmeta
*
* Copies meta from one post to another. Useful for saving and restoring revisions.
*
* @date 25/06/2016
* @since 5.3.8
* @deprecated 5.7.11
*
* @param int $from_post_id The post id to copy from.
* @param int $to_post_id The post id to paste to.
* @return void
*/
function acf_copy_postmeta( $from_post_id = 0, $to_post_id = 0 ) {
return acf_copy_metadata( $from_post_id, $to_post_id );
}
/**
* acf_get_meta_field
*
* Returns a field using the provided $id and $post_id parameters.
* Looks for a reference to help loading the correct field via name.
*
* @date 21/1/19
* @since 5.7.10
*
* @param string $key The meta name (field name).
* @param (int|string) $post_id The post_id where this field's value is saved.
* @return (array|false) The field array.
*/
function acf_get_meta_field( $key = 0, $post_id = 0 ) {
// Try reference.
$field_key = acf_get_reference( $key, $post_id );
if( $field_key ) {
$field = acf_get_field( $field_key );
if( $field ) {
$field['name'] = $key;
return $field;
}
}
// Return false.
return false;
}
/**
* acf_get_metaref
*
* Retrieves reference metadata from the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @param (int|string) $post_id The post id.
* @param string type The reference type (fields|groups).
* @param string $name An optional specific name
* @return mixed
*/
function acf_get_metaref( $post_id = 0, $type = 'fields', $name = '' ) {
// Load existing meta.
$meta = acf_get_metadata( $post_id, "_acf_$type" );
// Handle no meta.
if( !$meta ) {
return $name ? '' : array();
}
// Return specific reference.
if( $name ) {
return isset($meta[ $name ]) ? $meta[ $name ] : '';
// Or return all references.
} else {
return $meta;
}
}
/**
* acf_update_metaref
*
* Updates reference metadata in the database.
*
* @date 16/10/2015
* @since 5.2.3
*
* @param (int|string) $post_id The post id.
* @param string type The reference type (fields|groups).
* @param array $references An array of references.
* @return (int|bool) Meta ID if the key didn't exist, true on successful update, false on failure.
*/
function acf_update_metaref( $post_id = 0, $type = 'fields', $references = array() ) {
// Get current references.
$current = acf_get_metaref( $post_id, $type );
// Merge in new references.
$references = array_merge( $current, $references );
// Simplify groups
if( $type === 'groups' ) {
$references = array_values($references);
}
// Remove duplicate references.
$references = array_unique($references);
// Update metadata.
return acf_update_metadata( $post_id, "_acf_$type", $references );
}
@@ -0,0 +1,34 @@
<?php
/**
* acf_get_post_templates
*
* Returns an array of post_type => templates data.
*
* @date 29/8/17
* @since 5.6.2
*
* @param void
* @return array
*/
function acf_get_post_templates() {
// Defaults.
$post_templates = array(
'page' => array()
);
// Loop over post types and append their templates.
if( method_exists('WP_Theme', 'get_page_templates') ) {
$post_types = acf_get_post_types();
foreach( $post_types as $post_type ) {
$templates = wp_get_theme()->get_page_templates( null, $post_type );
if( $templates ) {
$post_templates[ $post_type ] = $templates;
}
}
}
// Return.
return $post_templates;
}
@@ -0,0 +1,116 @@
<?php
/**
* acf_get_users
*
* Similar to the get_users() function but with extra functionality.
*
* @date 9/1/19
* @since 5.7.10
*
* @param array $args The query args.
* @return array
*/
function acf_get_users( $args = array() ) {
// Get users.
$users = get_users( $args );
// Maintain order.
if( $users && $args['include'] ) {
// Generate order array.
$order = array();
foreach( $users as $i => $user ) {
$order[ $i ] = array_search($user->ID, $args['include']);
}
// Sort results.
array_multisort($order, $users);
}
// Return
return $users;
}
/**
* acf_get_user_result
*
* Returns a result containing "id" and "text" for the given user.
*
* @date 21/5/19
* @since 5.8.1
*
* @param WP_User $user The user object.
* @return array
*/
function acf_get_user_result( $user ) {
// Vars.
$id = $user->ID;
$text = $user->user_login;
// Add name.
if( $user->first_name && $user->last_name ) {
$text .= " ({$user->first_name} {$user->last_name})";
} elseif( $user->last_name ) {
$text .= " ({$user->first_name})";
}
return compact('id', 'text');
}
/**
* acf_get_user_role_labels
*
* Returns an array of user roles in the format "name => label".
*
* @date 20/5/19
* @since 5.8.1
*
* @param array $roles A specific array of roles.
* @return array
*/
function acf_get_user_role_labels( $roles = array() ) {
// Load all roles if none provided.
if( !$roles ) {
$roles = get_editable_roles();
}
// Loop over roles and populare labels.
$lables = array();
foreach( $roles as $role ) {
$lables[ $role ] = translate_user_role( $role );
}
// Return labels.
return $lables;
}
/**
* acf_allow_unfiltered_html
*
* Returns true if the current user is allowed to save unfiltered HTML.
*
* @date 9/1/19
* @since 5.7.10
*
* @param void
* @return bool
*/
function acf_allow_unfiltered_html() {
// Check capability.
$allow_unfiltered_html = current_user_can('unfiltered_html');
/**
* Filters whether the current user is allowed to save unfiltered HTML.
*
* @date 9/1/19
* @since 5.7.10
*
* @param bool allow_unfiltered_html The result.
*/
return apply_filters( 'acf/allow_unfiltered_html', $allow_unfiltered_html );
}
@@ -0,0 +1,158 @@
<?php
// Globals.
global $acf_stores, $acf_instances;
// Initialize plaeholders.
$acf_stores = array();
$acf_instances = array();
/**
* acf_new_instance
*
* Creates a new instance of the given class and stores it in the instances data store.
*
* @date 9/1/19
* @since 5.7.10
*
* @param string $class The class name.
* @return object The instance.
*/
function acf_new_instance( $class = '' ) {
global $acf_instances;
return $acf_instances[ $class ] = new $class();
}
/**
* acf_get_instance
*
* Returns an instance for the given class.
*
* @date 9/1/19
* @since 5.7.10
*
* @param string $class The class name.
* @return object The instance.
*/
function acf_get_instance( $class = '' ) {
global $acf_instances;
if( !isset($acf_instances[ $class ]) ) {
$acf_instances[ $class ] = new $class();
}
return $acf_instances[ $class ];
}
/**
* acf_register_store
*
* Registers a data store.
*
* @date 9/1/19
* @since 5.7.10
*
* @param string $name The store name.
* @param array $data Array of data to start the store with.
* @return ACF_Data
*/
function acf_register_store( $name = '', $data = false ) {
// Create store.
$store = new ACF_Data( $data );
// Register store.
global $acf_stores;
$acf_stores[ $name ] = $store;
// Return store.
return $store;
}
/**
* acf_get_store
*
* Returns a data store.
*
* @date 9/1/19
* @since 5.7.10
*
* @param string $name The store name.
* @return ACF_Data
*/
function acf_get_store( $name = '' ) {
global $acf_stores;
return isset( $acf_stores[ $name ] ) ? $acf_stores[ $name ] : false;
}
/**
* acf_switch_stores
*
* 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 acf_switch_stores( $site_id, $prev_site_id ) {
// Loop over stores and call switch_site().
global $acf_stores;
foreach( $acf_stores as $store ) {
$store->switch_site( $site_id, $prev_site_id );
}
}
add_action( 'switch_blog', 'acf_switch_stores', 10, 2 );
/**
* acf_get_path
*
* Returns the plugin path to a specified file.
*
* @date 28/9/13
* @since 5.0.0
*
* @param string $filename The specified file.
* @return string
*/
function acf_get_path( $filename = '' ) {
return ACF_PATH . ltrim($filename, '/');
}
/**
* acf_get_url
*
* Returns the plugin url to a specified file.
* This function also defines the ACF_URL constant.
*
* @date 12/12/17
* @since 5.6.8
*
* @param string $filename The specified file.
* @return string
*/
function acf_get_url( $filename = '' ) {
if( !defined('ACF_URL') ) {
define( 'ACF_URL', acf_get_setting('url') );
}
return ACF_URL . ltrim($filename, '/');
}
/*
* acf_include
*
* Includes a file within the ACF plugin.
*
* @date 10/3/14
* @since 5.0.0
*
* @param string $filename The specified file.
* @return void
*/
function acf_include( $filename = '' ) {
$file_path = acf_get_path($filename);
if( file_exists($file_path) ) {
include_once($file_path);
}
}
@@ -0,0 +1,326 @@
<?php
// Register store.
acf_register_store( 'values' )->prop( 'multisite', true );
/**
* acf_get_reference
*
* Retrieves the field key for a given field name and post_id.
*
* @date 26/1/18
* @since 5.6.5
*
* @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 The field key.
*/
function acf_get_reference( $field_name, $post_id ) {
// Allow filter to short-circuit load_value logic.
$reference = apply_filters( "acf/pre_load_reference", null, $field_name, $post_id );
if( $reference !== null ) {
return $reference;
}
// Get hidden meta for this field name.
$reference = acf_get_metadata( $post_id, $field_name, true );
/**
* Filters the reference value.
*
* @date 25/1/19
* @since 5.7.11
*
* @param string $reference The reference value.
* @param string $field_name The field name.
* @param (int|string) $post_id The post ID where meta is stored.
*/
return apply_filters( "acf/load_reference", $reference, $field_name, $post_id );
}
/**
* acf_get_value
*
* Retrieves the value for a given field and post_id.
*
* @date 28/09/13
* @since 5.0.0
*
* @param (int|string) $post_id The post id.
* @param array $field The field array.
* @return mixed.
*/
function acf_get_value( $post_id = 0, $field ) {
// Allow filter to short-circuit load_value logic.
$value = apply_filters( "acf/pre_load_value", null, $post_id, $field );
if( $value !== null ) {
return $value;
}
// Get field name.
$field_name = $field['name'];
// Check store.
$store = acf_get_store( 'values' );
if( $store->has( "$post_id:$field_name" ) ) {
return $store->get( "$post_id:$field_name" );
}
// Load value from database.
$value = acf_get_metadata( $post_id, $field_name );
// Use field's default_value if no meta was found.
if( $value === null && isset($field['default_value']) ) {
$value = $field['default_value'];
}
/**
* Filters the $value after it has been loaded.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The value to preview.
* @param string $post_id The post ID for this value.
* @param array $field The field array.
*/
$value = apply_filters( "acf/load_value", $value, $post_id, $field );
// Update store.
$store->set( "$post_id:$field_name", $value );
// Return value.
return $value;
}
// Register variation.
acf_add_filter_variations( 'acf/load_value', array('type', 'name', 'key'), 2 );
/**
* acf_format_value
*
* Returns a formatted version of the provided value.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The field value.
* @param (int|string) $post_id The post id.
* @param array $field The field array.
* @return mixed.
*/
function acf_format_value( $value, $post_id, $field ) {
// Allow filter to short-circuit load_value logic.
$check = apply_filters( "acf/pre_format_value", null, $value, $post_id, $field );
if( $check !== null ) {
return $check;
}
// Get field name.
$field_name = $field['name'];
// Check store.
$store = acf_get_store( 'values' );
if( $store->has( "$post_id:$field_name:formatted" ) ) {
return $store->get( "$post_id:$field_name:formatted" );
}
/**
* Filters the $value for use in a template function.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The value to preview.
* @param string $post_id The post ID for this value.
* @param array $field The field array.
*/
$value = apply_filters( "acf/format_value", $value, $post_id, $field );
// Update store.
$store->set( "$post_id:$field_name:formatted", $value );
// Return value.
return $value;
}
// Register variation.
acf_add_filter_variations( 'acf/format_value', array('type', 'name', 'key'), 2 );
/**
* acf_update_value
*
* Updates the value for a given field and post_id.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The new value.
* @param (int|string) $post_id The post id.
* @param array $field The field array.
* @return bool.
*/
function acf_update_value( $value = null, $post_id = 0, $field ) {
// Allow filter to short-circuit update_value logic.
$check = apply_filters( "acf/pre_update_value", null, $value, $post_id, $field );
if( $check !== null ) {
return $check;
}
/**
* Filters the $value before it is updated.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The value to update.
* @param string $post_id The post ID for this value.
* @param array $field The field array.
* @param mixed $original The original value before modification.
*/
$value = apply_filters( "acf/update_value", $value, $post_id, $field, $value );
// Allow null to delete value.
if( $value === null ) {
return acf_delete_value( $post_id, $field );
}
// Update meta.
$return = acf_update_metadata( $post_id, $field['name'], $value );
// Update reference.
acf_update_metadata( $post_id, $field['name'], $field['key'], true );
// Delete stored data.
acf_flush_value_cache( $post_id, $field['name'] );
// Return update status.
return $return;
}
// Register variation.
acf_add_filter_variations( 'acf/update_value', array('type', 'name', 'key'), 2 );
/**
* acf_update_values
*
* Updates an array of values.
*
* @date 26/2/19
* @since 5.7.13
*
* @param array values The array of values.
* @param (int|string) $post_id The post id.
* @return void
*/
function acf_update_values( $values = array(), $post_id = 0 ) {
// Loop over values.
foreach( $values as $key => $value ) {
// Get field.
$field = acf_get_field( $key );
// Update value.
if( $field ) {
acf_update_value( $value, $post_id, $field );
}
}
}
/**
* acf_flush_value_cache
*
* Deletes all cached data for this value.
*
* @date 22/1/19
* @since 5.7.10
*
* @param (int|string) $post_id The post id.
* @param string $field_name The field name.
* @return void
*/
function acf_flush_value_cache( $post_id = 0, $field_name = '' ) {
// Delete stored data.
acf_get_store( 'values' )
->remove( "$post_id:$field_name" )
->remove( "$post_id:$field_name:formatted" );
}
/**
* acf_delete_value
*
* Deletes the value for a given field and post_id.
*
* @date 28/09/13
* @since 5.0.0
*
* @param (int|string) $post_id The post id.
* @param array $field The field array.
* @return bool.
*/
function acf_delete_value( $post_id, $field ) {
/**
* Fires before a value is deleted.
*
* @date 28/09/13
* @since 5.0.0
*
* @param string $post_id The post ID for this value.
* @param mixed $name The meta name.
* @param array $field The field array.
*/
do_action( "acf/delete_value", $post_id, $field['name'], $field );
// Delete meta.
$return = acf_delete_metadata( $post_id, $field['name'] );
// Delete reference.
acf_delete_metadata( $post_id, $field['name'], true );
// Delete stored data.
acf_flush_value_cache( $post_id, $field['name'] );
// Return delete status.
return $return;
}
// Register variation.
acf_add_filter_variations( 'acf/delete_value', array('type', 'name', 'key'), 2 );
/**
* acf_preview_value
*
* Return a human friendly 'preview' for a given field value.
*
* @date 28/09/13
* @since 5.0.0
*
* @param mixed $value The new value.
* @param (int|string) $post_id The post id.
* @param array $field The field array.
* @return bool.
*/
function acf_preview_value( $value, $post_id, $field ) {
/**
* Filters the $value before used in HTML.
*
* @date 24/10/16
* @since 5.5.0
*
* @param mixed $value The value to preview.
* @param string $post_id The post ID for this value.
* @param array $field The field array.
*/
return apply_filters( "acf/preview_value", $value, $post_id, $field );
}
// Register variation.
acf_add_filter_variations( 'acf/preview_value', array('type', 'name', 'key'), 2 );
@@ -0,0 +1,834 @@
<?php
/*
* ACF Admin Field Group Class
*
* All the logic for editing a field group
*
* @class acf_admin_field_group
* @package ACF
* @subpackage Admin
*/
if( ! class_exists('acf_admin_field_group') ) :
class acf_admin_field_group {
/*
* __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('current_screen', array($this, 'current_screen'));
add_action('save_post', array($this, 'save_post'), 10, 2);
// ajax
add_action('wp_ajax_acf/field_group/render_field_settings', array($this, 'ajax_render_field_settings'));
add_action('wp_ajax_acf/field_group/render_location_rule', array($this, 'ajax_render_location_rule'));
add_action('wp_ajax_acf/field_group/move_field', array($this, 'ajax_move_field'));
// filters
add_filter('post_updated_messages', array($this, 'post_updated_messages'));
add_filter('use_block_editor_for_post_type', array($this, 'use_block_editor_for_post_type'), 10, 2);
}
/**
* use_block_editor_for_post_type
*
* Prevents the block editor from loading when editing an ACF field group.
*
* @date 7/12/18
* @since 5.8.0
*
* @param bool $use_block_editor Whether the post type can be edited or not. Default true.
* @param string $post_type The post type being checked.
* @return bool
*/
function use_block_editor_for_post_type( $use_block_editor, $post_type ) {
if( $post_type === 'acf-field-group' ) {
return false;
}
return $use_block_editor;
}
/*
* post_updated_messages
*
* This function will customize the message shown when editing a field group
*
* @type action (post_updated_messages)
* @date 30/04/2014
* @since 5.0.0
*
* @param $messages (array)
* @return $messages
*/
function post_updated_messages( $messages ) {
// append to messages
$messages['acf-field-group'] = array(
0 => '', // Unused. Messages start at index 1.
1 => __('Field group updated.', 'acf'),
2 => __('Field group updated.', 'acf'),
3 => __('Field group deleted.', 'acf'),
4 => __('Field group updated.', 'acf'),
5 => false, // field group does not support revisions
6 => __('Field group published.', 'acf'),
7 => __('Field group saved.', 'acf'),
8 => __('Field group submitted.', 'acf'),
9 => __('Field group scheduled for.', 'acf'),
10 => __('Field group draft updated.', 'acf')
);
// return
return $messages;
}
/*
* current_screen
*
* This function is fired when loading the admin page before HTML has been rendered.
*
* @type action (current_screen)
* @date 21/07/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function current_screen() {
// validate screen
if( !acf_is_screen('acf-field-group') ) return;
// disable filters to ensure ACF loads raw data from DB
acf_disable_filters();
// enqueue 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_action('acf/input/form_data', array($this, 'form_data'));
add_action('acf/input/admin_footer', array($this, 'admin_footer'));
add_action('acf/input/admin_footer_js', array($this, 'admin_footer_js'));
// filters
add_filter('acf/input/admin_l10n', array($this, 'admin_l10n'));
}
/*
* 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 30/06/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function admin_enqueue_scripts() {
// no autosave
wp_dequeue_script('autosave');
// custom scripts
wp_enqueue_style('acf-field-group');
wp_enqueue_script('acf-field-group');
// localize text
acf_localize_text(array(
'The string "field_" may not be used at the start of a field name' => __('The string "field_" may not be used at the start of a field name', 'acf'),
'This field cannot be moved until its changes have been saved' => __('This field cannot be moved until its changes have been saved', 'acf'),
'Field group title is required' => __('Field group title is required', 'acf'),
'Move to trash. Are you sure?' => __('Move to trash. Are you sure?', 'acf'),
'No toggle fields available' => __('No toggle fields available', 'acf'),
'Move Custom Field' => __('Move Custom Field', 'acf'),
'Checked' => __('Checked', 'acf'),
'(no label)' => __('(no label)', 'acf'),
'(this field)' => __('(this field)', 'acf'),
'copy' => __('copy', 'acf'),
'or' => __('or', 'acf'),
'Null' => __('Null', 'acf'),
));
// localize data
acf_localize_data(array(
'fieldTypes' => acf_get_field_types_info()
));
// 3rd party hook
do_action('acf/field_group/admin_enqueue_scripts');
}
/*
* admin_head
*
* This function will setup all functionality for the field group edit page to work
*
* @type action (admin_head)
* @date 23/06/12
* @since 3.1.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
function admin_head() {
// global
global $post, $field_group;
// set global var
$field_group = acf_get_field_group( $post->ID );
// metaboxes
add_meta_box('acf-field-group-fields', __("Fields",'acf'), array($this, 'mb_fields'), 'acf-field-group', 'normal', 'high');
add_meta_box('acf-field-group-locations', __("Location",'acf'), array($this, 'mb_locations'), 'acf-field-group', 'normal', 'high');
add_meta_box('acf-field-group-options', __("Settings",'acf'), array($this, 'mb_options'), 'acf-field-group', 'normal', 'high');
// actions
add_action('post_submitbox_misc_actions', array($this, 'post_submitbox_misc_actions'), 10, 0);
add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10, 0);
// filters
add_filter('screen_settings', array($this, 'screen_settings'), 10, 1);
// 3rd party hook
do_action('acf/field_group/admin_head');
}
/*
* edit_form_after_title
*
* This action will allow ACF to render metaboxes after the title
*
* @type action
* @date 17/08/13
*
* @param n/a
* @return n/a
*/
function edit_form_after_title() {
// globals
global $post;
// render post data
acf_form_data(array(
'screen' => 'field_group',
'post_id' => $post->ID,
'delete_fields' => 0,
'validation' => 0
));
}
/*
* form_data
*
* This function will add extra HTML to the acf form data element
*
* @type function
* @date 31/05/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
function form_data( $args ) {
// do action
do_action('acf/field_group/form_data', $args);
}
/*
* admin_l10n
*
* This function will append extra l10n strings to the acf JS object
*
* @type function
* @date 31/05/2016
* @since 5.3.8
*
* @param $l10n (array)
* @return $l10n
*/
function admin_l10n( $l10n ) {
return apply_filters('acf/field_group/admin_l10n', $l10n);
}
/*
* admin_footer
*
* description
*
* @type function
* @date 11/01/2016
* @since 5.3.2
*
* @param $post_id (int)
* @return $post_id (int)
*/
function admin_footer() {
// 3rd party hook
do_action('acf/field_group/admin_footer');
}
/*
* admin_footer_js
*
* description
*
* @type function
* @date 31/05/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
function admin_footer_js() {
// 3rd party hook
do_action('acf/field_group/admin_footer_js');
}
/*
* screen_settings
*
* description
*
* @type function
* @date 26/01/13
* @since 3.6.0
*
* @param $current (string)
* @return $current
*/
function screen_settings( $html ) {
// vars
$checked = acf_get_user_setting('show_field_keys') ? 'checked="checked"' : '';
// append
$html .= '<div id="acf-append-show-on-screen" class="acf-hidden">';
$html .= '<label for="acf-field-key-hide"><input id="acf-field-key-hide" type="checkbox" value="1" name="show_field_keys" ' . $checked . ' /> ' . __('Field Keys','acf') . '</label>';
$html .= '</div>';
// return
return $html;
}
/*
* post_submitbox_misc_actions
*
* This function will customize the publish metabox
*
* @type function
* @date 17/07/2015
* @since 5.2.9
*
* @param n/a
* @return n/a
*/
function post_submitbox_misc_actions() {
// global
global $field_group;
// vars
$status = $field_group['active'] ? __("Active",'acf') : __("Inactive",'acf');
?>
<script type="text/javascript">
(function($) {
// modify status
$('#post-status-display').html('<?php echo $status; ?>');
// remove edit links
$('#misc-publishing-actions a').remove();
})(jQuery);
</script>
<?php
}
/*
* 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;
}
// bail early if not acf-field-group
if( $post->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 );
}
}
// 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;
}
/*
* 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_');
}
// 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();
// 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);
// message
$a = '<a href="' . admin_url("post.php?post={$field_group['ID']}&action=edit") . '" target="_blank">' . $field_group['title'] . '</a>';
echo '<p><strong>' . __('Move Complete.', 'acf') . '</strong></p>';
echo '<p>' . sprintf( __('The %s field can now be found in the %s field group', 'acf'), $field['label'], $a ). '</p>';
echo '<a href="#" class="button button-primary acf-close-popup">' . __("Close Window",'acf') . '</a>';
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 '<p>' . __('Please select the destination for this field', 'acf') . '</p>';
echo '<form id="acf-move-field-form">';
// render
acf_render_field_wrap( $field );
echo '<button type="submit" class="button button-primary">' . __("Move Field",'acf') . '</button>';
echo '</form>';
// die
die();
}
}
// initialize
new acf_admin_field_group();
endif;
?>
@@ -0,0 +1,830 @@
<?php
/*
* ACF Admin Field Groups Class
*
* All the logic for editing a list of field groups
*
* @class acf_admin_field_groups
* @package ACF
* @subpackage Admin
*/
if( ! class_exists('acf_admin_field_groups') ) :
class acf_admin_field_groups {
// vars
var $url = 'edit.php?post_type=acf-field-group',
$sync = 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() {
// actions
add_action('current_screen', array($this, 'current_screen'));
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_action('load-edit.php', array($this, 'maybe_redirect_edit'));
}
/**
* maybe_redirect_edit
*
* Redirects the user from the old ACF4 edit page to the new ACF5 edit page
*
* @date 17/9/18
* @since 5.7.6
*
* @param void
* @return void
*/
function maybe_redirect_edit() {
if( acf_maybe_get_GET('post_type') == 'acf' ) {
wp_redirect( admin_url($this->url) );
exit;
}
}
/*
* current_screen
*
* This function is fired when loading the admin page before HTML has been rendered.
*
* @type action (current_screen)
* @date 21/07/2014
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function current_screen() {
// validate screen
if( !acf_is_screen('edit-acf-field-group') ) {
return;
}
// customize post_status
global $wp_post_statuses;
// modify publish post status
$wp_post_statuses['publish']->label_count = _n_noop( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', 'acf' );
// reorder trash to end
$wp_post_statuses['trash'] = acf_extract_var( $wp_post_statuses, 'trash' );
// check stuff
$this->check_duplicate();
$this->check_sync();
// actions
add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
add_action('admin_footer', array($this, 'admin_footer'));
// columns
add_filter('manage_edit-acf-field-group_columns', array($this, 'field_group_columns'), 10, 1);
add_action('manage_acf-field-group_posts_custom_column', array($this, 'field_group_columns_html'), 10, 2);
}
/*
* admin_enqueue_scripts
*
* This function will add the already registered css
*
* @type function
* @date 28/09/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function admin_enqueue_scripts() {
wp_enqueue_script('acf-input');
}
/*
* check_duplicate
*
* This function will check for any $_GET data to duplicate
*
* @type function
* @date 17/10/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function check_duplicate() {
// Display notice
if( $ids = acf_maybe_get_GET('acfduplicatecomplete') ) {
// explode
$ids = explode(',', $ids);
$total = count($ids);
// Generate text.
$text = sprintf( _n( 'Field group duplicated.', '%s field groups duplicated.', $total, 'acf' ), $total );
// Add links to text.
$links = array();
foreach( $ids as $id ) {
$links[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
}
$text .= ' ' . implode( ', ', $links );
// Add notice
acf_add_admin_notice( $text, 'success' );
}
// vars
$ids = array();
// check single
if( $id = acf_maybe_get_GET('acfduplicate') ) {
$ids[] = $id;
// check multiple
} elseif( acf_maybe_get_GET('action2') === 'acfduplicate' ) {
$ids = acf_maybe_get_GET('post');
}
// sync
if( !empty($ids) ) {
// validate
check_admin_referer('bulk-posts');
// vars
$new_ids = array();
// loop
foreach( $ids as $id ) {
// duplicate
$field_group = acf_duplicate_field_group( $id );
// increase counter
$new_ids[] = $field_group['ID'];
}
// redirect
wp_redirect( admin_url( $this->url . '&acfduplicatecomplete=' . implode(',', $new_ids)) );
exit;
}
}
/*
* check_sync
*
* This function will check for any $_GET data to sync
*
* @type function
* @date 9/12/2014
* @since 5.1.5
*
* @param n/a
* @return n/a
*/
function check_sync() {
// Display notice
if( $ids = acf_maybe_get_GET('acfsynccomplete') ) {
// explode
$ids = explode(',', $ids);
$total = count($ids);
// Generate text.
$text = sprintf( _n( 'Field group synchronised.', '%s field groups synchronised.', $total, 'acf' ), $total );
// Add links to text.
$links = array();
foreach( $ids as $id ) {
$links[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
}
$text .= ' ' . implode( ', ', $links );
// Add notice
acf_add_admin_notice( $text, 'success' );
}
// vars
$groups = acf_get_field_groups();
// bail early if no field groups
if( empty($groups) ) return;
// find JSON field groups which have not yet been imported
foreach( $groups as $group ) {
// vars
$local = acf_maybe_get($group, 'local', false);
$modified = acf_maybe_get($group, 'modified', 0);
$private = acf_maybe_get($group, 'private', false);
// Ignore if is private.
if( $private ) {
continue;
// Ignore not local "json".
} elseif( $local !== 'json' ) {
continue;
// Append to sync if not yet in database.
} elseif( !$group['ID'] ) {
$this->sync[ $group['key'] ] = $group;
// Append to sync if "json" modified time is newer than database.
} elseif( $modified && $modified > get_post_modified_time('U', true, $group['ID'], true) ) {
$this->sync[ $group['key'] ] = $group;
}
}
// bail if no sync needed
if( empty($this->sync) ) return;
// maybe sync
$sync_keys = array();
// check single
if( $key = acf_maybe_get_GET('acfsync') ) {
$sync_keys[] = $key;
// check multiple
} elseif( acf_maybe_get_GET('action2') === 'acfsync' ) {
$sync_keys = acf_maybe_get_GET('post');
}
// sync
if( !empty($sync_keys) ) {
// validate
check_admin_referer('bulk-posts');
// disable filters to ensure ACF loads raw data from DB
acf_disable_filters();
acf_enable_filter('local');
// disable JSON
// - this prevents a new JSON file being created and causing a 'change' to theme files - solves git anoyance
acf_update_setting('json', false);
// vars
$new_ids = array();
// loop
foreach( $sync_keys as $key ) {
// Bail early if not found.
if( !isset($this->sync[ $key ]) ) {
continue;
}
// Get field group.
$field_group = $this->sync[ $key ];
// Append fields.
$field_group['fields'] = acf_get_fields( $field_group );
// Import field group.
$field_group = acf_import_field_group( $field_group );
// Append imported ID.
$new_ids[] = $field_group['ID'];
}
// redirect
wp_redirect( admin_url( $this->url . '&acfsynccomplete=' . implode(',', $new_ids)) );
exit;
}
// filters
add_filter('views_edit-acf-field-group', array($this, 'list_table_views'));
}
/*
* list_table_views
*
* This function will add an extra link for JSON in the field group list table
*
* @type function
* @date 3/12/2014
* @since 5.1.5
*
* @param $views (array)
* @return $views
*/
function list_table_views( $views ) {
// vars
$class = '';
$total = count($this->sync);
// active
if( acf_maybe_get_GET('post_status') === 'sync' ) {
// actions
add_action('admin_footer', array($this, 'sync_admin_footer'), 5);
// set active class
$class = ' class="current"';
// global
global $wp_list_table;
// update pagination
$wp_list_table->set_pagination_args( array(
'total_items' => $total,
'total_pages' => 1,
'per_page' => $total
));
}
// add view
$views['json'] = '<a' . $class . ' href="' . admin_url($this->url . '&post_status=sync') . '">' . __('Sync available', 'acf') . ' <span class="count">(' . $total . ')</span></a>';
// return
return $views;
}
/*
* trashed_post
*
* This function is run when a post object is sent to the trash
*
* @type action (trashed_post)
* @date 8/01/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return n/a
*/
function trashed_post( $post_id ) {
// validate post type
if( get_post_type($post_id) != 'acf-field-group' ) {
return;
}
// trash field group
acf_trash_field_group( $post_id );
}
/*
* untrashed_post
*
* This function is run when a post object is restored from the trash
*
* @type action (untrashed_post)
* @date 8/01/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return n/a
*/
function untrashed_post( $post_id ) {
// validate post type
if( get_post_type($post_id) != 'acf-field-group' ) {
return;
}
// trash field group
acf_untrash_field_group( $post_id );
}
/*
* deleted_post
*
* This function is run when a post object is deleted from the trash
*
* @type action (deleted_post)
* @date 8/01/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return n/a
*/
function deleted_post( $post_id ) {
// validate post type
if( get_post_type($post_id) != 'acf-field-group' ) {
return;
}
// trash field group
acf_delete_field_group( $post_id );
}
/*
* field_group_columns
*
* This function will customize the columns for the field group table
*
* @type filter (manage_edit-acf-field-group_columns)
* @date 28/09/13
* @since 5.0.0
*
* @param $columns (array)
* @return $columns (array)
*/
function field_group_columns( $columns ) {
return array(
'cb' => '<input type="checkbox" />',
'title' => __('Title', 'acf'),
'acf-fg-description' => __('Description', 'acf'),
'acf-fg-status' => '<i class="acf-icon -dot-3 small acf-js-tooltip" title="' . esc_attr__('Status', 'acf') . '"></i>',
'acf-fg-count' => __('Fields', 'acf'),
);
}
/*
* field_group_columns_html
*
* This function will render the HTML for each table cell
*
* @type action (manage_acf-field-group_posts_custom_column)
* @date 28/09/13
* @since 5.0.0
*
* @param $column (string)
* @param $post_id (int)
* @return n/a
*/
function field_group_columns_html( $column, $post_id ) {
// vars
$field_group = acf_get_field_group( $post_id );
// render
$this->render_column( $column, $field_group );
}
function render_column( $column, $field_group ) {
// description
if( $column == 'acf-fg-description' ) {
if( $field_group['description'] ) {
echo '<span class="acf-description">' . acf_esc_html($field_group['description']) . '</span>';
}
// status
} elseif( $column == 'acf-fg-status' ) {
if( isset($this->sync[ $field_group['key'] ]) ) {
echo '<i class="acf-icon -sync grey small acf-js-tooltip" title="' . esc_attr__('Sync available', 'acf') .'"></i> ';
}
if( $field_group['active'] ) {
//echo '<i class="acf-icon -check small acf-js-tooltip" title="' . esc_attr__('Active', 'acf') .'"></i> ';
} else {
echo '<i class="acf-icon -minus yellow small acf-js-tooltip" title="' . esc_attr__('Inactive', 'acf') . '"></i> ';
}
// fields
} elseif( $column == 'acf-fg-count' ) {
echo esc_html( acf_get_field_count( $field_group ) );
}
}
/*
* admin_footer
*
* This function will render extra HTML onto the page
*
* @type action (admin_footer)
* @date 23/06/12
* @since 3.1.8
*
* @param n/a
* @return n/a
*/
function admin_footer() {
// vars
$url_home = 'https://www.advancedcustomfields.com';
$icon = '<i aria-hidden="true" class="dashicons dashicons-external"></i>';
?>
<script type="text/html" id="tmpl-acf-column-2">
<div class="acf-column-2">
<div class="acf-box">
<div class="inner">
<h2><?php echo acf_get_setting('name'); ?></h2>
<p><?php _e('Customize WordPress with powerful, professional and intuitive fields.','acf'); ?></p>
<h3><?php _e("Changelog",'acf'); ?></h3>
<p><?php
$acf_changelog = admin_url('edit.php?post_type=acf-field-group&page=acf-settings-info&tab=changelog');
$acf_version = acf_get_setting('version');
printf( __('See what\'s new in <a href="%s">version %s</a>.','acf'), esc_url($acf_changelog), $acf_version );
?></p>
<h3><?php _e("Resources",'acf'); ?></h3>
<ul>
<li><a href="<?php echo esc_url( $url_home ); ?>" target="_blank"><?php echo $icon; ?> <?php _e("Website",'acf'); ?></a></li>
<li><a href="<?php echo esc_url( $url_home . '/resources/' ); ?>" target="_blank"><?php echo $icon; ?> <?php _e("Documentation",'acf'); ?></a></li>
<li><a href="<?php echo esc_url( $url_home . '/support/' ); ?>" target="_blank"><?php echo $icon; ?> <?php _e("Support",'acf'); ?></a></li>
<?php if( !acf_get_setting('pro') ): ?>
<li><a href="<?php echo esc_url( $url_home . '/pro/' ); ?>" target="_blank"><?php echo $icon; ?> <?php _e("Pro",'acf'); ?></a></li>
<?php endif; ?>
</ul>
</div>
<div class="footer">
<p><?php printf( __('Thank you for creating with <a href="%s">ACF</a>.','acf'), esc_url($url_home) ); ?></p>
</div>
</div>
</div>
</script>
<script type="text/javascript">
(function($){
// wrap
$('#wpbody .wrap').attr('id', 'acf-field-group-wrap');
// wrap form
$('#posts-filter').wrap('<div class="acf-columns-2" />');
// add column main
$('#posts-filter').addClass('acf-column-1');
// add column side
$('#posts-filter').after( $('#tmpl-acf-column-2').html() );
// modify row actions
$('#the-list tr').each(function(){
// vars
var $tr = $(this),
id = $tr.attr('id'),
description = $tr.find('.column-acf-fg-description').html();
// replace Quick Edit with Duplicate (sync page has no id attribute)
if( id ) {
// vars
var post_id = id.replace('post-', '');
var url = '<?php echo esc_url( admin_url( $this->url . '&acfduplicate=__post_id__&_wpnonce=' . wp_create_nonce('bulk-posts') ) ); ?>';
var $span = $('<span class="acf-duplicate-field-group"><a title="<?php _e('Duplicate this item', 'acf'); ?>" href="' + url.replace('__post_id__', post_id) + '"><?php _e('Duplicate', 'acf'); ?></a> | </span>');
// replace
$tr.find('.column-title .row-actions .inline').replaceWith( $span );
}
// add description to title
$tr.find('.column-title .row-title').after( description );
});
// modify bulk actions
$('#bulk-action-selector-bottom option[value="edit"]').attr('value','acfduplicate').text('<?php _e( 'Duplicate', 'acf' ); ?>');
// clean up table
$('#adv-settings label[for="acf-fg-description-hide"]').remove();
// mobile compatibility
var status = $('.acf-icon.-dot-3').first().attr('title');
$('td.column-acf-fg-status').attr('data-colname', status);
// no field groups found
$('#the-list tr.no-items td').attr('colspan', 4);
// search
$('.subsubsub').append(' | <li><a href="#" class="acf-toggle-search"><?php _e('Search', 'acf'); ?></a></li>');
// events
$(document).on('click', '.acf-toggle-search', function( e ){
// prevent default
e.preventDefault();
// toggle
$('.search-box').slideToggle();
});
})(jQuery);
</script>
<?php
}
/*
* sync_admin_footer
*
* This function will render extra HTML onto the page
*
* @type action (admin_footer)
* @date 23/06/12
* @since 3.1.8
*
* @param n/a
* @return n/a
*/
function sync_admin_footer() {
// vars
$i = -1;
$columns = array(
'acf-fg-description',
'acf-fg-status',
'acf-fg-count'
);
$nonce = wp_create_nonce('bulk-posts');
?>
<script type="text/html" id="tmpl-acf-json-tbody">
<?php foreach( $this->sync as $field_group ):
// vars
$i++;
$key = $field_group['key'];
$title = $field_group['title'];
$url = admin_url( $this->url . '&post_status=sync&acfsync=' . $key . '&_wpnonce=' . $nonce );
?>
<tr <?php if($i%2 == 0): ?>class="alternate"<?php endif; ?>>
<th class="check-column" scope="row">
<label for="cb-select-<?php echo esc_attr($key); ?>" class="screen-reader-text"><?php echo esc_html(sprintf(__('Select %s', 'acf'), $title)); ?></label>
<input type="checkbox" value="<?php echo esc_attr($key); ?>" name="post[]" id="cb-select-<?php echo esc_attr($key); ?>">
</th>
<td class="post-title page-title column-title">
<strong>
<span class="row-title"><?php echo esc_html($title); ?></span><span class="acf-description"><?php echo esc_html($key); ?>.json</span>
</strong>
<div class="row-actions">
<span class="import"><a title="<?php echo esc_attr( __('Synchronise field group', 'acf') ); ?>" href="<?php echo esc_url($url); ?>"><?php _e( 'Sync', 'acf' ); ?></a></span>
</div>
</td>
<?php foreach( $columns as $column ): ?>
<td class="column-<?php echo esc_attr($column); ?>"><?php $this->render_column( $column, $field_group ); ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</script>
<script type="text/html" id="tmpl-acf-bulk-actions">
<?php // source: bulk_actions() wp-admin/includes/class-wp-list-table.php ?>
<select name="action2" id="bulk-action-selector-bottom"></select>
<?php submit_button( __( 'Apply' ), 'action', '', false, array( 'id' => "doaction2" ) ); ?>
</script>
<script type="text/javascript">
(function($){
// update table HTML
$('#the-list').html( $('#tmpl-acf-json-tbody').html() );
// bulk may not exist if no field groups in DB
if( !$('#bulk-action-selector-bottom').exists() ) {
$('.tablenav.bottom .actions.alignleft').html( $('#tmpl-acf-bulk-actions').html() );
}
// set only options
$('#bulk-action-selector-bottom').html('<option value="-1"><?php _e('Bulk Actions'); ?></option><option value="acfsync"><?php _e('Sync', 'acf'); ?></option>');
})(jQuery);
</script>
<?php
}
}
new acf_admin_field_groups();
endif;
?>
@@ -0,0 +1,146 @@
<?php
/**
* ACF Admin Notices
*
* Functions and classes to manage admin notices.
*
* @date 10/1/19
* @since 5.7.10
*/
// Exit if accessed directly.
if( !defined('ABSPATH') ) exit;
// Register notices store.
acf_register_store( 'notices' );
/**
* ACF_Admin_Notice
*
* Class used to create an admin notice.
*
* @date 10/1/19
* @since 5.7.10
*/
if( ! class_exists('ACF_Admin_Notice') ) :
class ACF_Admin_Notice extends ACF_Data {
/** @var array Storage for data. */
var $data = array(
/** @type string Text displayed in notice. */
'text' => '',
/** @type string Optional HTML alternative to text.
'html' => '', */
/** @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() {
// Ensure text contains punctuation.
// todo: Remove this after updating translations.
$text = $this->get('text');
if( substr($text, -1) !== '.' && substr($text, -1) !== '>' ) {
$text .= '.';
}
// Print HTML.
printf('<div class="acf-admin-notice notice notice-%s %s">%s</div>',
// Type class.
$this->get('type'),
// Dismissible class.
$this->get('dismissible') ? 'is-dismissible' : '',
// InnerHTML
$this->has('html') ? $this->get('html') : wpautop($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
*/
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;
}
/**
* acf_render_admin_notices
*
* Renders all admin notices HTML.
*
* @date 10/1/19
* @since 5.7.10
*
* @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 ) {
$notice->render();
}
}
}
// Render notices during admin action.
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
*
* @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 ) );
}
@@ -0,0 +1,354 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_admin_tools') ) :
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'));
}
/**
* 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();
}
}
}
/**
* 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, $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']);
?>
<form method="post">
<?php $tool->html(); ?>
<?php acf_nonce_input( $tool->name ); ?>
</form>
<?php
}
}
// initialize
acf()->admin_tools = new acf_admin_tools();
endif; // class_exists check
/*
* acf_register_admin_tool
*
* alias of acf()->admin_tools->register_tool()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_register_admin_tool( $class ) {
return acf()->admin_tools->register_tool( $class );
}
/*
* 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
*
* @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');
}
/*
* acf_get_admin_tool_url
*
* This function will return the admin URL to the tools page
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_get_admin_tool_url( $tool = '' ) {
return acf_get_admin_tools_url() . '&tool='.$tool;
}
?>
@@ -0,0 +1,225 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
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 );
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
*
* Setus up logic if DB Upgrade is needed on a multi site.
*
* @date 24/8/18
* @since 5.7.4
*
* @param void
* @return void
*/
function network_admin_menu() {
// vars
$has_upgrade = false;
// loop over sites
$sites = acf_get_sites();
if( $sites ) {
foreach( $sites as $site ) {
// switch blog
switch_to_blog( $site['blog_id'] );
// check for upgrade
if( acf_has_upgrade() ) {
$has_upgrade = true;
}
// restore blog
restore_current_blog();
}}
// check if upgrade is avaialble
if( $has_upgrade ) {
// 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'));
// actions
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'));
// load acf scripts
acf_enqueue_scripts();
}
/**
* 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'));
// load acf scripts
acf_enqueue_scripts();
}
/**
* 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
?>
@@ -0,0 +1,89 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('acf_admin') ) :
class acf_admin {
/*
* __construct
*
* Initialize filters, action, variables and includes
*
* @type function
* @date 23/06/12
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function __construct() {
// actions
add_action('admin_menu', array($this, 'admin_menu'));
add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'), 0);
}
/*
* 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;
// vars
$slug = 'edit.php?post_type=acf-field-group';
$cap = acf_get_setting('capability');
// add parent
add_menu_page(__("Custom Fields",'acf'), __("Custom Fields",'acf'), $cap, $slug, false, 'dashicons-welcome-widgets-menus', '80.025');
// add children
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' );
}
/*
* admin_enqueue_scripts
*
* This function will add the already registered css
*
* @type function
* @date 28/09/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function admin_enqueue_scripts() {
wp_enqueue_style( 'acf-global' );
}
}
// initialize
acf()->admin = new acf_admin();
endif; // class_exists check
?>
@@ -0,0 +1,102 @@
<?php
class acf_settings_info {
/*
* __construct
*
* Initialize filters, action, variables and includes
*
* @type function
* @date 23/06/12
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function __construct() {
// actions
add_action('admin_menu', array($this, 'admin_menu'));
}
/*
* 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
add_submenu_page('edit.php?post_type=acf-field-group', __('Info','acf'), __('Info','acf'), acf_get_setting('capability'),'acf-settings-info', array($this,'html'));
}
/*
* html
*
* description
*
* @type function
* @date 7/01/2014
* @since 5.0.0
*
* @param $post_id (int)
* @return $post_id (int)
*/
function html() {
// vars
$view = array(
'version' => acf_get_setting('version'),
'have_pro' => acf_get_setting('pro'),
'tabs' => array(
'new' => __("What's New", 'acf'),
'changelog' => __("Changelog", 'acf')
),
'active' => 'new'
);
// set active tab
$tab = acf_maybe_get_GET('tab');
if( $tab && isset($view['tabs'][ $tab ]) ) {
$view['active'] = $tab;
}
// load view
acf_get_view('settings-info', $view);
}
}
// initialize
new acf_settings_info();
?>
@@ -0,0 +1,596 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Admin_Tool_Export') ) :
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();
}
}
/**
* 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() {
?>
<div class="acf-panel acf-panel-selection">
<h3 class="acf-panel-title"><?php _e('Select Field Groups', 'acf') ?> <i class="dashicons dashicons-arrow-right"></i></h3>
<div class="acf-panel-inside">
<?php $this->html_field_selection(); ?>
</div>
</div>
<?php
}
/**
* html_panel_settings
*
* description
*
* @date 21/10/17
* @since 5.6.3
*
* @param n/a
* @return n/a
*/
function html_panel_settings() {
?>
<div class="acf-panel acf-panel-settings">
<h3 class="acf-panel-title"><?php _e('Settings', 'acf') ?> <i class="dashicons dashicons-arrow-right"></i></h3>
<div class="acf-panel-inside">
<?php
/*
acf_render_field_wrap(array(
'label' => __('Empty settings', 'acf'),
'type' => 'select',
'name' => 'minimal',
'prefix' => false,
'value' => '',
'choices' => array(
'all' => __('Include all settings', 'acf'),
'minimal' => __('Ignore empty settings', 'acf'),
)
));
*/
?>
</div>
</div>
<?php
}
/**
* html_archive
*
* description
*
* @date 20/10/17
* @since 5.6.3
*
* @param n/a
* @return n/a
*/
function html_archive() {
?>
<p><?php _e('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.', 'acf'); ?></p>
<div class="acf-fields">
<?php $this->html_field_selection(); ?>
</div>
<p class="acf-submit">
<button type="submit" name="action" class="button button-primary" value="download"><?php _e('Export File', 'acf'); ?></button>
<button type="submit" name="action" class="button" value="generate"><?php _e('Generate PHP', 'acf'); ?></button>
</p>
<?php
}
/**
* html_single
*
* description
*
* @date 20/10/17
* @since 5.6.3
*
* @param n/a
* @return n/a
*/
function html_single() {
?>
<div class="acf-postbox-columns">
<div class="acf-postbox-main">
<?php $this->html_generate(); ?>
</div>
<div class="acf-postbox-side">
<?php $this->html_panel_selection(); ?>
<p class="acf-submit">
<button type="submit" name="action" class="button button-primary" value="generate"><?php _e('Generate PHP', 'acf'); ?></button>
</p>
</div>
</div>
<?php
}
/**
* 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'
);
?>
<p><?php _e("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.", 'acf'); ?></p>
<textarea id="acf-export-textarea" readonly="true"><?php
echo "if( function_exists('acf_add_local_field_group') ):" . "\r\n" . "\r\n";
foreach( $json as $field_group ) {
// code
$code = var_export($field_group, true);
// change double spaces to tabs
$code = str_replace( array_keys($str_replace), array_values($str_replace), $code );
// correctly formats "=> array("
$code = preg_replace( array_keys($preg_replace), array_values($preg_replace), $code );
// esc_textarea
$code = esc_textarea( $code );
// echo
echo "acf_add_local_field_group({$code});" . "\r\n" . "\r\n";
}
echo "endif;";
?></textarea>
<p class="acf-submit">
<a class="button" id="acf-export-copy"><?php _e( 'Copy to clipboard', 'acf' ); ?></a>
</p>
<script type="text/javascript">
(function($){
// vars
var $a = $('#acf-export-copy');
var $textarea = $('#acf-export-textarea');
// remove $a if 'copy' is not supported
if( !document.queryCommandSupported('copy') ) {
return $a.remove();
}
// event
$a.on('click', function( e ){
// prevent default
e.preventDefault();
// select
$textarea.get(0).select();
// try
try {
// copy
var copy = document.execCommand('copy');
if( !copy ) return;
// tooltip
acf.newTooltip({
text: "<?php _e('Copied', 'acf' ); ?>",
timeout: 250,
target: $(this),
});
} catch (err) {
// do nothing
}
});
})(jQuery);
</script>
<?php
}
/**
* get_selected_keys
*
* This function will return an array of field group keys that have been selected
*
* @date 20/10/17
* @since 5.6.3
*
* @param n/a
* @return n/a
*/
function get_selected_keys() {
// check $_POST
if( $keys = acf_maybe_get_POST('keys') ) {
return (array) $keys;
}
// check $_GET
if( $keys = acf_maybe_get_GET('keys') ) {
$keys = str_replace(' ', '+', $keys);
return explode('+', $keys);
}
// return
return false;
}
/**
* get_selected
*
* This function will return the JSON data for given $_POST args
*
* @date 17/10/17
* @since 5.6.3
*
* @param n/a
* @return array
*/
function get_selected() {
// vars
$selected = $this->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
?>
@@ -0,0 +1,157 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Admin_Tool_Import') ) :
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() {
?>
<p><?php _e('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.', 'acf'); ?></p>
<div class="acf-fields">
<?php
acf_render_field_wrap(array(
'label' => __('Select File', 'acf'),
'type' => 'file',
'name' => 'acf_import_file',
'value' => false,
'uploader' => 'basic',
));
?>
</div>
<p class="acf-submit">
<input type="submit" class="button button-primary" value="<?php _e('Import File', 'acf'); ?>" />
</p>
<?php
}
/**
* 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() {
// Check file size.
if( empty($_FILES['acf_import_file']['size']) ) {
return acf_add_admin_notice( __("No file selected", 'acf'), 'warning' );
}
// Get file data.
$file = $_FILES['acf_import_file'];
// Check errors.
if( $file['error'] ) {
return acf_add_admin_notice( __("Error uploading file. Please try again", 'acf'), 'warning' );
}
// Check file type.
if( pathinfo($file['name'], PATHINFO_EXTENSION) !== 'json' ) {
return acf_add_admin_notice( __("Incorrect file type", 'acf'), 'warning' );
}
// Read JSON.
$json = file_get_contents( $file['tmp_name'] );
$json = json_decode($json, true);
// Check if empty.
if( !$json || !is_array($json) ) {
return acf_add_admin_notice( __("Import file empty", 'acf'), 'warning' );
}
// Ensure $json is an array of groups.
if( isset($json['key']) ) {
$json = array( $json );
}
// Remeber imported field group ids.
$ids = array();
// Loop over json
foreach( $json as $field_group ) {
// Search database for existing field group.
$post = acf_get_field_group_post( $field_group['key'] );
if( $post ) {
$field_group['ID'] = $post->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[] = '<a href="' . get_edit_post_link( $id ) . '">' . get_the_title( $id ) . '</a>';
}
$text .= ' ' . implode( ', ', $links );
// Add notice
acf_add_admin_notice( $text, 'success' );
}
}
// initialize
acf_register_admin_tool( 'ACF_Admin_Tool_Import' );
endif; // class_exists check
?>
@@ -0,0 +1,195 @@
<?php
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
?>
@@ -0,0 +1,158 @@
<?php
// vars
$disabled = false;
// empty
if( empty($field['conditional_logic']) ) {
$disabled = true;
$field['conditional_logic'] = array(
// group 0
array(
// rule 0
array()
)
);
}
?>
<tr class="acf-field acf-field-true-false acf-field-setting-conditional_logic" data-type="true_false" data-name="conditional_logic">
<td class="acf-label">
<label><?php _e("Conditional Logic",'acf'); ?></label>
</td>
<td class="acf-input">
<?php
acf_render_field(array(
'type' => 'true_false',
'name' => 'conditional_logic',
'prefix' => $field['prefix'],
'value' => $disabled ? 0 : 1,
'ui' => 1,
'class' => 'conditions-toggle',
));
?>
<div class="rule-groups" <?php if($disabled): ?>style="display:none;"<?php endif; ?>>
<?php foreach( $field['conditional_logic'] as $group_id => $group ):
// validate
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');
?>
<div class="rule-group" data-id="<?php echo $group_id; ?>">
<h4><?php echo $h4; ?></h4>
<table class="acf-table -clear">
<tbody>
<?php foreach( $group as $rule_id => $rule ):
// valid rule
$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}]";
// data attributes
$attributes = array(
'data-id' => $rule_id,
'data-field' => $rule['field'],
'data-operator' => $rule['operator'],
'data-value' => $rule['value']
);
?>
<tr class="rule" <?php acf_esc_attr_e($attributes); ?>>
<td class="param">
<?php
acf_render_field(array(
'type' => 'select',
'prefix' => $prefix,
'name' => 'field',
'class' => 'condition-rule-field',
'disabled' => $disabled,
'value' => $rule['field'],
'choices' => array(
$rule['field'] => $rule['field']
)
));
?>
</td>
<td class="operator">
<?php
acf_render_field(array(
'type' => 'select',
'prefix' => $prefix,
'name' => 'operator',
'class' => 'condition-rule-operator',
'disabled' => $disabled,
'value' => $rule['operator'],
'choices' => array(
$rule['operator'] => $rule['operator']
)
));
?>
</td>
<td class="value">
<?php
// create field
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']
)
));
?>
</td>
<td class="add">
<a href="#" class="button add-conditional-rule"><?php _e("and",'acf'); ?></a>
</td>
<td class="remove">
<a href="#" class="acf-icon -minus remove-conditional-rule"></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endforeach; ?>
<h4><?php _e("or",'acf'); ?></h4>
<a href="#" class="button add-conditional-group"><?php _e("Add rule group",'acf'); ?></a>
</div>
</td>
</tr>
@@ -0,0 +1,184 @@
<?php
// vars
$prefix = 'acf_fields[' . $field['ID'] . ']';
$id = acf_idify( $prefix );
// add prefix
$field['prefix'] = $prefix;
// div
$div = array(
'class' => 'acf-field-object acf-field-object-' . acf_slugify($field['type']),
'data-id' => $field['ID'],
'data-key' => $field['key'],
'data-type' => $field['type'],
);
$meta = array(
'ID' => $field['ID'],
'key' => $field['key'],
'parent' => $field['parent'],
'menu_order' => $i,
'save' => ''
);
?>
<div <?php echo acf_esc_attr( $div ); ?>>
<div class="meta">
<?php foreach( $meta as $k => $v ):
acf_hidden_input(array( 'name' => $prefix . '[' . $k . ']', 'value' => $v, 'id' => $id . '-' . $k ));
endforeach; ?>
</div>
<div class="handle">
<ul class="acf-hl acf-tbody">
<li class="li-field-order">
<span class="acf-icon acf-sortable-handle" title="<?php _e('Drag to reorder','acf'); ?>"><?php echo ($i + 1); ?></span>
</li>
<li class="li-field-label">
<strong>
<a class="edit-field" title="<?php _e("Edit field",'acf'); ?>" href="#"><?php echo acf_get_field_label($field, 'admin'); ?></a>
</strong>
<div class="row-options">
<a class="edit-field" title="<?php _e("Edit field",'acf'); ?>" href="#"><?php _e("Edit",'acf'); ?></a>
<a class="duplicate-field" title="<?php _e("Duplicate field",'acf'); ?>" href="#"><?php _e("Duplicate",'acf'); ?></a>
<a class="move-field" title="<?php _e("Move field to another group",'acf'); ?>" href="#"><?php _e("Move",'acf'); ?></a>
<a class="delete-field" title="<?php _e("Delete field",'acf'); ?>" href="#"><?php _e("Delete",'acf'); ?></a>
</div>
</li>
<?php // whitespace before field name looks odd but fixes chrome bug selecting all text in row ?>
<li class="li-field-name"> <?php echo $field['name']; ?></li>
<li class="li-field-key"> <?php echo $field['key']; ?></li>
<li class="li-field-type"> <?php echo acf_get_field_type_label($field['type']); ?></li>
</ul>
</div>
<div class="settings">
<table class="acf-table">
<tbody class="acf-field-settings">
<?php
// label
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);
// 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);
// 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);
// required
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);
// type specific settings
do_action("acf/render_field_settings/type={$field['type']}", $field);
// conditional logic
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');
?>
<tr class="acf-field acf-field-save">
<td class="acf-label"></td>
<td class="acf-input">
<ul class="acf-hl">
<li>
<a class="button edit-field" title="<?php _e("Close Field",'acf'); ?>" href="#"><?php _e("Close Field",'acf'); ?></a>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
</div>
@@ -0,0 +1,52 @@
<div class="acf-field-list-wrap">
<ul class="acf-hl acf-thead">
<li class="li-field-order"><?php _e('Order','acf'); ?></li>
<li class="li-field-label"><?php _e('Label','acf'); ?></li>
<li class="li-field-name"><?php _e('Name','acf'); ?></li>
<li class="li-field-key"><?php _e('Key','acf'); ?></li>
<li class="li-field-type"><?php _e('Type','acf'); ?></li>
</ul>
<div class="acf-field-list<?php if( !$fields ){ echo ' -empty'; } ?>">
<div class="no-fields-message">
<?php _e("No fields. Click the <strong>+ Add Field</strong> button to create your first field.",'acf'); ?>
</div>
<?php if( $fields ):
foreach( $fields as $i => $field ):
acf_get_view('field-group-field', array( 'field' => $field, 'i' => $i ));
endforeach;
endif; ?>
</div>
<ul class="acf-hl acf-tfoot">
<li class="acf-fr">
<a href="#" class="button button-primary button-large add-field"><?php _e('+ Add Field','acf'); ?></a>
</li>
</ul>
<?php if( !$parent ):
// get clone
$clone = acf_get_valid_field(array(
'ID' => 'acfcloneindex',
'key' => 'acfcloneindex',
'label' => __('New Field','acf'),
'name' => 'new_field',
'type' => 'text'
));
?>
<script type="text/html" id="tmpl-acf-field">
<?php acf_get_view('field-group-field', array( 'field' => $clone, 'i' => 0 )); ?>
</script>
<?php endif;?>
</div>
@@ -0,0 +1,45 @@
<?php
// global
global $field_group;
?>
<div class="acf-field">
<div class="acf-label">
<label><?php _e("Rules",'acf'); ?></label>
<p class="description"><?php _e("Create a set of rules to determine which edit screens will use these advanced custom fields",'acf'); ?></p>
</div>
<div class="acf-input">
<div class="rule-groups">
<?php foreach( $field_group['location'] as $i => $group ):
// bail ealry if no group
if( empty($group) ) return;
// view
acf_get_view('html-location-group', array(
'group' => $group,
'group_id' => "group_{$i}"
));
endforeach; ?>
<h4><?php _e("or",'acf'); ?></h4>
<a href="#" class="button add-location-group"><?php _e("Add rule group",'acf'); ?></a>
</div>
</div>
</div>
<script type="text/javascript">
if( typeof acf !== 'undefined' ) {
acf.newPostbox({
'id': 'acf-field-group-locations',
'label': 'left'
});
}
</script>
@@ -0,0 +1,155 @@
<?php
// 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'),
));
// 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'),
)
));
// 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'
));
// 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'),
)
));
// 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'),
)
));
// 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'],
));
// 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'),
);
if( acf_get_setting('remove_wp_meta_box') ) {
unset( $choices['custom_fields'] );
}
acf_render_field_wrap(array(
'label' => __('Hide on screen','acf'),
'instructions' => __('<b>Select</b> items to <b>hide</b> them from the edit screen.','acf') . '<br /><br />' . __("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);
?>
<div class="acf-hidden">
<input type="hidden" name="acf_field_group[key]" value="<?php echo $field_group['key']; ?>" />
</div>
<script type="text/javascript">
if( typeof acf !== 'undefined' ) {
acf.newPostbox({
'id': 'acf-field-group-options',
'label': 'left'
});
}
</script>
@@ -0,0 +1,216 @@
<?php
/**
* Network Admin Database Upgrade
*
* Shows the databse upgrade process.
*
* @date 24/8/18
* @since 5.7.4
* @param void
*/
?>
<style type="text/css">
/* hide steps */
.show-on-complete {
display: none;
}
</style>
<div id="acf-upgrade-wrap" class="wrap">
<h1><?php _e("Upgrade Database", 'acf'); ?></h1>
<p><?php echo sprintf( __("The following sites require a DB upgrade. Check the ones you want to update and then click %s.", 'acf'), '"' . __('Upgrade Sites', 'acf') . '"'); ?></p>
<p><input type="submit" name="upgrade" value="<?php _e('Upgrade Sites', 'acf'); ?>" class="button" id="upgrade-sites"></p>
<table class="wp-list-table widefat">
<thead>
<tr>
<td class="manage-column check-column" scope="col">
<input type="checkbox" id="sites-select-all">
</td>
<th class="manage-column" scope="col" style="width:33%;">
<label for="sites-select-all"><?php _e("Site", 'acf'); ?></label>
</th>
<th><?php _e("Description", 'acf'); ?></th>
</tr>
</thead>
<tfoot>
<tr>
<td class="manage-column check-column" scope="col">
<input type="checkbox" id="sites-select-all-2">
</td>
<th class="manage-column" scope="col">
<label for="sites-select-all-2"><?php _e("Site", 'acf'); ?></label>
</th>
<th><?php _e("Description", 'acf'); ?></th>
</tr>
</tfoot>
<tbody id="the-list">
<?php
$sites = acf_get_sites();
if( $sites ):
foreach( $sites as $i => $site ):
// switch blog
switch_to_blog( $site['blog_id'] );
?>
<tr<?php if( $i % 2 == 0 ): ?> class="alternate"<?php endif; ?>>
<th class="check-column" scope="row">
<?php if( acf_has_upgrade() ): ?>
<input type="checkbox" value="<?php echo $site['blog_id']; ?>" name="checked[]">
<?php endif; ?>
</th>
<td>
<strong><?php echo get_bloginfo('name'); ?></strong><br /><?php echo home_url(); ?>
</td>
<td>
<?php if( acf_has_upgrade() ): ?>
<span class="response"><?php printf(__('Site requires database upgrade from %s to %s', 'acf'), acf_get_db_version(), ACF_VERSION); ?></span>
<?php else: ?>
<?php _e("Site is up to date", 'acf'); ?>
<?php endif; ?>
</td>
</tr>
<?php
// restore
restore_current_blog();
endforeach;
endif;
?>
</tbody>
</table>
<p><input type="submit" name="upgrade" value="<?php _e('Upgrade Sites', 'acf'); ?>" class="button" id="upgrade-sites-2"></p>
<p class="show-on-complete"><?php echo sprintf( __('Database Upgrade complete. <a href="%s">Return to network dashboard</a>', 'acf'), network_admin_url() ); ?></p>
<script type="text/javascript">
(function($) {
var upgrader = new acf.Model({
events: {
'click #upgrade-sites': 'onClick',
'click #upgrade-sites-2': 'onClick'
},
$inputs: function(){
return $('#the-list input:checked');
},
onClick: function( e, $el ){
// prevent default
e.preventDefault();
// bail early if no selection
if( !this.$inputs().length ) {
return alert('<?php _e('Please select at least one site to upgrade.', 'acf'); ?>');
}
// confirm action
if( !confirm("<?php _e('It is strongly recommended that you backup your database before proceeding. Are you sure you wish to run the updater now?', 'acf'); ?>") ) {
return;
}
// upgrade
this.upgrade();
},
upgrade: function(){
// vars
var $inputs = this.$inputs();
// bail early if no sites selected
if( !$inputs.length ) {
return this.complete();
}
// disable buttons
$('.button').prop('disabled', true);
// vars
var $input = $inputs.first();
var $row = $input.closest('tr');
var text = '';
var success = false;
// show loading
$row.find('.response').html('<i class="acf-loading"></i></span> <?php printf(__('Upgrading data to version %s', 'acf'), ACF_VERSION); ?>');
// send ajax request to upgrade DB
$.ajax({
url: acf.get('ajaxurl'),
dataType: 'json',
type: 'post',
data: acf.prepareForAjax({
action: 'acf/ajax/upgrade',
blog_id: $input.val()
}),
success: function( json ){
// success
if( acf.isAjaxSuccess(json) ) {
// update
success = true;
// remove input
$input.remove();
// set response text
text = '<?php _e('Upgrade complete.', 'acf'); ?>';
if( jsonText = acf.getAjaxMessage(json) ) {
text = jsonText;
}
// error
} else {
// set response text
text = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( jsonText = acf.getAjaxError(json) ) {
text += ' <pre>' + jsonText + '</pre>';
}
}
},
error: function( jqXHR, textStatus, errorThrown ){
// set response text
text = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( errorThrown) {
text += ' <pre>' + errorThrown + '</pre>';
}
},
complete: this.proxy(function(){
// display text
$row.find('.response').html( text );
// if successful upgrade, proceed to next site. Otherwise, skip to complete.
if( success ) {
this.upgrade();
} else {
this.complete();
}
})
});
},
complete: function(){
// enable buttons
$('.button').prop('disabled', false);
// show message
$('.show-on-complete').show();
}
});
})(jQuery);
</script>
</div>
@@ -0,0 +1,119 @@
<?php
/**
* Admin Database Upgrade
*
* Shows the databse upgrade process.
*
* @date 24/8/18
* @since 5.7.4
* @param void
*/
?>
<style type="text/css">
/* hide steps */
.step-1,
.step-2,
.step-3 {
display: none;
}
</style>
<div id="acf-upgrade-wrap" class="wrap">
<h1><?php _e("Upgrade Database", 'acf'); ?></h1>
<?php if( acf_has_upgrade() ): ?>
<p><?php _e('Reading upgrade tasks...', 'acf'); ?></p>
<p class="step-1"><i class="acf-loading"></i> <?php printf(__('Upgrading data to version %s', 'acf'), ACF_VERSION); ?></p>
<p class="step-2"></p>
<p class="step-3"><?php echo sprintf( __('Database upgrade complete. <a href="%s">See what\'s new</a>', 'acf' ), admin_url('edit.php?post_type=acf-field-group&page=acf-settings-info') ); ?></p>
<script type="text/javascript">
(function($) {
var upgrader = new acf.Model({
initialize: function(){
// allow user to read message for 1 second
this.setTimeout( this.upgrade, 1000 );
},
upgrade: function(){
// show step 1
$('.step-1').show();
// vars
var response = '';
var success = false;
// send ajax request to upgrade DB
$.ajax({
url: acf.get('ajaxurl'),
dataType: 'json',
type: 'post',
data: acf.prepareForAjax({
action: 'acf/ajax/upgrade'
}),
success: function( json ){
// success
if( acf.isAjaxSuccess(json) ) {
// update
success = true;
// set response text
if( jsonText = acf.getAjaxMessage(json) ) {
response = jsonText;
}
// error
} else {
// set response text
response = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( jsonText = acf.getAjaxError(json) ) {
response += ' <pre>' + jsonText + '</pre>';
}
}
},
error: function( jqXHR, textStatus, errorThrown ){
// set response text
response = '<?php _e('Upgrade failed.', 'acf'); ?>';
if( errorThrown) {
response += ' <pre>' + errorThrown + '</pre>';
}
},
complete: this.proxy(function(){
// remove spinner
$('.acf-loading').hide();
// display response
if( response ) {
$('.step-2').show().html( response );
}
// display success
if( success ) {
$('.step-3').show();
}
})
});
}
});
})(jQuery);
</script>
<?php else: ?>
<p><?php _e('No updates available.', 'acf'); ?></p>
<?php endif; ?>
</div>
@@ -0,0 +1,27 @@
<?php
/**
* html-admin-tools
*
* View to output admin tools for both archive and single
*
* @date 20/10/17
* @since 5.6.3
*
* @param string $screen_id The screen ID used to display metaboxes
* @param string $active The active Tool
* @return n/a
*/
$class = $active ? 'single' : 'grid';
?>
<div class="wrap" id="acf-admin-tools">
<h1><?php _e('Tools', 'acf'); ?> <?php if( $active ): ?><a class="page-title-action" href="<?php echo acf_get_admin_tools_url(); ?>"><?php _e('Back to all tools', 'acf'); ?></a><?php endif; ?></h1>
<div class="acf-meta-box-wrap -<?php echo $class; ?>">
<?php do_meta_boxes( $screen_id, 'normal', '' ); ?>
</div>
</div>
@@ -0,0 +1,25 @@
<div class="rule-group" data-id="<?php echo $group_id; ?>">
<h4><?php echo ($group_id == 'group_0') ? __("Show this field group if",'acf') : __("or",'acf'); ?></h4>
<table class="acf-table -clear">
<tbody>
<?php foreach( $group as $i => $rule ):
// validate rule
$rule = acf_validate_location_rule($rule);
// append id and group
$rule['id'] = "rule_{$i}";
$rule['group'] = $group_id;
// view
acf_get_view('html-location-rule', array(
'rule' => $rule
));
endforeach; ?>
</tbody>
</table>
</div>
@@ -0,0 +1,91 @@
<?php
// vars
$prefix = 'acf_field_group[location]['.$rule['group'].']['.$rule['id'].']';
?>
<tr data-id="<?php echo $rule['id']; ?>">
<td class="param">
<?php
// vars
$choices = acf_get_location_rule_types();
// array
if( is_array($choices) ) {
acf_render_field(array(
'type' => 'select',
'name' => 'param',
'prefix' => $prefix,
'value' => $rule['param'],
'choices' => $choices,
'class' => 'refresh-location-rule'
));
}
?>
</td>
<td class="operator">
<?php
// vars
$choices = acf_get_location_rule_operators( $rule );
// array
if( is_array($choices) ) {
acf_render_field(array(
'type' => 'select',
'name' => 'operator',
'prefix' => $prefix,
'value' => $rule['operator'],
'choices' => $choices
));
// custom
} else {
echo $choices;
}
?>
</td>
<td class="value">
<?php
// vars
$choices = acf_get_location_rule_values( $rule );
// array
if( is_array($choices) ) {
acf_render_field(array(
'type' => 'select',
'name' => 'value',
'prefix' => $prefix,
'value' => $rule['value'],
'choices' => $choices
));
// custom
} else {
echo $choices;
}
?>
</td>
<td class="add">
<a href="#" class="button add-location-rule"><?php _e("and",'acf'); ?></a>
</td>
<td class="remove">
<a href="#" class="acf-icon -minus remove-location-rule"></a>
</td>
</tr>
@@ -0,0 +1,43 @@
<?php
// calculate add-ons (non pro only)
$plugins = array();
if( !acf_get_setting('pro') ) {
if( is_plugin_active('acf-repeater/acf-repeater.php') ) $plugins[] = __("Repeater",'acf');
if( is_plugin_active('acf-flexible-content/acf-flexible-content.php') ) $plugins[] = __("Flexible Content",'acf');
if( is_plugin_active('acf-gallery/acf-gallery.php') ) $plugins[] = __("Gallery",'acf');
if( is_plugin_active('acf-options-page/acf-options-page.php') ) $plugins[] = __("Options Page",'acf');
}
?>
<div id="acf-upgrade-notice" class="notice">
<div class="col-content">
<img src="<?php echo acf_get_url('assets/images/acf-logo.png'); ?>" />
<h2><?php _e("Database Upgrade Required",'acf'); ?></h2>
<p><?php printf(__("Thank you for updating to %s v%s!", 'acf'), acf_get_setting('name'), acf_get_setting('version') ); ?><br /><?php _e("This version contains improvements to your database and requires an upgrade.", 'acf'); ?></p>
<?php if( !empty($plugins) ): ?>
<p><?php printf(__("Please also check all premium add-ons (%s) are updated to the latest version.", 'acf'), implode(', ', $plugins) ); ?></p>
<?php endif; ?>
</div>
<div class="col-actions">
<a id="acf-upgrade-button" href="<?php echo $button_url; ?>" class="button button-primary button-hero"><?php echo $button_text; ?></a>
</div>
</div>
<?php if( $confirm ): ?>
<script type="text/javascript">
(function($) {
$("#acf-upgrade-button").on("click", function(){
return confirm("<?php _e( 'It is strongly recommended that you backup your database before proceeding. Are you sure you wish to run the updater now?', 'acf' ); ?>");
});
})(jQuery);
</script>
<?php endif; ?>
@@ -0,0 +1,54 @@
<div class="wrap acf-settings-wrap">
<h1><?php _e("Add-ons",'acf'); ?></h1>
<div class="add-ons-list">
<?php if( !empty($json) ): ?>
<?php foreach( $json as $addon ):
$addon = wp_parse_args($addon, array(
"title" => "",
"slug" => "",
"description" => "",
"thumbnail" => "",
"url" => "",
"btn" => __("Download & Install",'acf'),
"btn_color" => ""
));
?>
<div class="acf-box add-on add-on-<?php echo $addon['slug']; ?>">
<div class="thumbnail">
<a target="_blank" href="<?php echo $addon['url']; ?>">
<img src="<?php echo $addon['thumbnail']; ?>" />
</a>
</div>
<div class="inner">
<h3><a target="_blank" href="<?php echo $addon['url']; ?>"><?php echo $addon['title']; ?></a></h3>
<p><?php echo $addon['description']; ?></p>
</div>
<div class="footer">
<?php if( apply_filters("acf/is_add_on_active/slug={$addon['slug']}", false ) ): ?>
<a class="button" disabled="disabled"><?php _e("Installed",'acf'); ?></a>
<?php else: ?>
<a class="button <?php echo $addon['btn_color']; ?>" target="_blank" href="<?php echo $addon['url']; ?>" ><?php _e($addon['btn']); ?></a>
<?php endif; ?>
<?php if( !empty($addon['footer']) ): ?>
<p><?php echo $addon['footer']; ?></p>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
@@ -0,0 +1,157 @@
<div class="wrap about-wrap acf-wrap">
<h1><?php _e("Welcome to Advanced Custom Fields",'acf'); ?> <?php echo $version; ?></h1>
<div class="about-text"><?php printf(__("Thank you for updating! ACF %s is bigger and better than ever before. We hope you like it.", 'acf'), $version); ?></div>
<h2 class="nav-tab-wrapper">
<?php foreach( $tabs as $tab_slug => $tab_title ): ?>
<a class="nav-tab<?php if( $active == $tab_slug ): ?> nav-tab-active<?php endif; ?>" href="<?php echo admin_url("edit.php?post_type=acf-field-group&page=acf-settings-info&tab={$tab_slug}"); ?>"><?php echo $tab_title; ?></a>
<?php endforeach; ?>
</h2>
<?php if( $active == 'new' ): ?>
<div class="feature-section">
<h2><?php _e("A Smoother Experience", 'acf'); ?> </h2>
<div class="acf-three-col">
<div>
<h3><?php _e("Improved Usability", 'acf'); ?></h3>
<p><?php _e("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.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Improved Design", 'acf'); ?></h3>
<p><?php _e("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!", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Improved Data", 'acf'); ?></h3>
<p><?php _e("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!", 'acf'); ?></p>
</div>
</div>
</div>
<hr />
<div class="feature-section">
<h2><?php _e("Goodbye Add-ons. Hello PRO", 'acf'); ?> 👋</h2>
<div class="acf-three-col">
<div>
<h3><?php _e("Introducing ACF PRO", 'acf'); ?></h3>
<p><?php _e("We're changing the way premium functionality is delivered in an exciting way!", 'acf'); ?></p>
<p><?php printf(__('All 4 premium add-ons have been combined into a new <a href="%s">Pro version of ACF</a>. With both personal and developer licenses available, premium functionality is more affordable and accessible than ever before!', 'acf'), esc_url('https://www.advancedcustomfields.com/pro')); ?></p>
</div>
<div>
<h3><?php _e("Powerful Features", 'acf'); ?></h3>
<p><?php _e("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!", 'acf'); ?></p>
<p><?php printf(__('Read more about <a href="%s">ACF PRO features</a>.', 'acf'), esc_url('https://www.advancedcustomfields.com/pro')); ?></p>
</div>
<div>
<h3><?php _e("Easy Upgrading", 'acf'); ?></h3>
<p><?php _e('Upgrading to ACF PRO is easy. Simply purchase a license online and download the plugin!', 'acf'); ?></p>
<p><?php printf(__('We also wrote an <a href="%s">upgrade guide</a> to answer any questions, but if you do have one, please contact our support team via the <a href="%s">help desk</a>.', 'acf'), esc_url('https://www.advancedcustomfields.com/resources/upgrade-guide-acf-pro/'), esc_url('https://www.advancedcustomfields.com/support/')); ?></p>
</div>
</div>
</div>
<hr />
<div class="feature-section">
<h2><?php _e("New Features", 'acf'); ?> 🎉</h2>
<div class="acf-three-col">
<div>
<h3><?php _e("Link Field", 'acf'); ?></h3>
<p><?php _e("The Link field provides a simple way to select or define a link (url, title, target).", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Group Field", 'acf'); ?></h3>
<p><?php _e("The Group field provides a simple way to create a group of fields.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("oEmbed Field", 'acf'); ?></h3>
<p><?php _e("The oEmbed field allows an easy way to embed videos, images, tweets, audio, and other content.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Clone Field", 'acf'); ?> <span class="badge"><?php _e('Pro', 'acf'); ?></span></h3>
<p><?php _e("The clone field allows you to select and display existing fields.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("More AJAX", 'acf'); ?></h3>
<p><?php _e("More fields use AJAX powered search to speed up page loading.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Local JSON", 'acf'); ?></h3>
<p><?php _e("New auto export to JSON feature improves speed and allows for syncronisation.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Easy Import / Export", 'acf'); ?></h3>
<p><?php _e("Both import and export can easily be done through a new tools page.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("New Form Locations", 'acf'); ?></h3>
<p><?php _e("Fields can now be mapped to menus, menu items, comments, widgets and all user forms!", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("More Customization", 'acf'); ?></h3>
<p><?php _e("New PHP (and JS) actions and filters have been added to allow for more customization.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Fresh UI", 'acf'); ?></h3>
<p><?php _e("The entire plugin has had a design refresh including new field types, settings and design!", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("New Settings", 'acf'); ?></h3>
<p><?php _e("Field group settings have been added for Active, Label Placement, Instructions Placement and Description.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Better Front End Forms", 'acf'); ?></h3>
<p><?php _e("acf_form() can now create a new post on submission with lots of new settings.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Better Validation", 'acf'); ?></h3>
<p><?php _e("Form validation is now done via PHP + AJAX in favour of only JS.", 'acf'); ?></p>
</div>
<div>
<h3><?php _e("Moving Fields", 'acf'); ?></h3>
<p><?php _e("New field group functionality allows you to move a field between groups & parents.", 'acf'); ?></p>
</div>
<div><?php // intentional empty div for flex alignment ?></div>
</div>
</div>
<?php elseif( $active == 'changelog' ): ?>
<p class="about-description"><?php printf(__("We think you'll love the changes in %s.", 'acf'), $version); ?></p>
<?php
// extract changelog and parse markdown
$readme = file_get_contents( acf_get_path('readme.txt') );
$changelog = '';
if( preg_match( '/(= '.$version.' =)(.+?)(=|$)/s', $readme, $match ) && $match[2] ) {
$changelog = acf_parse_markdown( $match[2] );
}
echo acf_parse_markdown($changelog);
endif; ?>
</div>
@@ -0,0 +1,98 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
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
?>
@@ -0,0 +1,54 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Ajax_Upgrade') ) :
class ACF_Ajax_Upgrade extends ACF_Ajax {
/** @var string The AJAX action name */
var $action = 'acf/ajax/upgrade';
/**
* 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 ) {
// Switch blog.
if( isset($request['blog_id']) ) {
switch_to_blog( $request['blog_id'] );
}
// Bail early if no upgrade avaiable.
if( !acf_has_upgrade() ) {
return new WP_Error( 'upgrade_error', __('No updates available.', 'acf') );
}
// Listen for output.
ob_start();
// Run upgrades.
acf_upgrade_all();
// Store output.
$error = ob_get_clean();
// Return error or success.
if( $error ) {
return new WP_Error( 'upgrade_error', $error );
}
return true;
}
}
acf_new_instance('ACF_Ajax_Upgrade');
endif; // class_exists check
@@ -0,0 +1,41 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
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
@@ -0,0 +1,184 @@
<?php
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;
}
/**
* set
*
* 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 ) {
$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() {
// Verify ajax request
if( !acf_verify_ajax() ) {
wp_send_json_error();
}
// Store data for has() and get() functions.
$this->request = wp_unslash($_REQUEST);
// Send response.
$this->send( $this->get_response( $this->request ) );
}
/**
* 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) ) {
wp_send_json_error(array( 'error' => $response->get_error_message() ));
// Return success.
} else {
wp_send_json_success($response);
}
}
}
endif; // class_exists check
?>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,501 @@
<?php
/*
* acf_get_taxonomies
*
* Returns an array of taxonomy names.
*
* @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.
*/
function acf_get_taxonomies( $args = array() ) {
// vars
$taxonomies = array();
// get taxonomy objects
$objects = get_taxonomies( $args, 'objects' );
// loop
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;
// 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']);
}
// filter
$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
*/
function acf_get_taxonomies_for_post_type( $post_types = 'post' ) {
// vars
$taxonomies = array();
// loop
foreach( (array) $post_types as $post_type ) {
$object_taxonomies = get_object_taxonomies( $post_type );
foreach( (array) $object_taxonomies as $taxonomy ) {
$taxonomies[] = $taxonomy;
}
}
// remove duplicates
$taxonomies = array_unique($taxonomies);
// return
return $taxonomies;
}
/*
* acf_get_taxonomy_labels
*
* Returns an array of taxonomies in the format "name => label" for use in a select field.
*
* @date 3/8/18
* @since 5.7.2
*
* @param array $taxonomies Optional. An array of specific taxonomies to return.
* @return array
*/
function acf_get_taxonomy_labels( $taxonomies = array() ) {
// default
if( empty($taxonomies) ) {
$taxonomies = acf_get_taxonomies();
}
// vars
$ref = array();
$data = array();
// loop
foreach( $taxonomies as $taxonomy ) {
// vars
$object = get_taxonomy( $taxonomy );
$label = $object->labels->singular_name;
// append
$data[ $taxonomy ] = $label;
// increase counter
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 ) {
$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
*/
function acf_get_term_title( $term ) {
// set to term name
$title = $term->name;
// allow for empty name
if( $title === '' ) {
$title = __('(no title)', 'acf');
}
// prepent ancestors indentation
if( is_taxonomy_hierarchical($term->taxonomy) ) {
$ancestors = get_ancestors( $term->term_id, $term->taxonomy );
$title = str_repeat('- ', count($ancestors)) . $title;
}
// return
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
*/
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,
));
// vars
$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);
// add filter to group results by taxonomy
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);
}
// loop
foreach( $taxonomies as $taxonomy => $label ) {
// vars
$this_terms = array();
// populate $this_terms
foreach( $terms as $term ) {
if( $term->taxonomy == $taxonomy ) {
$this_terms[] = $term;
}
}
// bail early if no $items
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'])) {
// get all terms from this taxonomy
$all_terms = get_terms(array_merge($args, array(
'number' => 0,
'offset' => 0,
'taxonomy' => $taxonomy
)));
// vars
$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 ) {
$offset = $i;
break;
}
}
// order terms
$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);
}
}
// populate group
$data[ $label ] = array();
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
*/
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']);
}
// 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
*/
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
*/
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;
}
// 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
*/
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
*/
function acf_decode_term( $string ) {
if( is_string($string) && strpos($string, ':') ) {
list( $taxonomy, $slug ) = explode(':', $string);
return array(
'taxonomy' => $taxonomy,
'slug' => $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
*/
function acf_get_encoded_terms( $values ) {
// vars
$terms = array();
// loop over values
foreach( (array) $values as $value ) {
// find term from string
$term = acf_get_term( $value );
// append
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
*/
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 ) {
$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 );
$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
*/
function acf_get_choices_from_grouped_terms( $value, $format = 'term_id' ) {
// vars
$groups = array();
// loop over values
foreach( $value as $group => $terms ) {
$groups[ $group ] = array();
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
*/
function acf_get_choice_from_term( $term, $format = 'term_id' ) {
// vars
$id = $term->term_id;
$text = acf_get_term_title( $term );
// return format
if( $format == 'slug' ) {
$id = acf_encode_term($term);
}
// return
return array(
'id' => $id,
'text' => $text
);
}
?>
@@ -0,0 +1,482 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('ACF_Assets') ) :
class ACF_Assets {
/** @var array Storage for translations */
var $text = array();
/** @var array Storage for data */
var $data = array();
/**
* __construct
*
* description
*
* @date 10/4/18
* @since 5.6.9
*
* @param void
* @return void
*/
function __construct() {
// actions
add_action('init', array($this, 'register_scripts'));
}
/**
* add_text
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function add_text( $text ) {
foreach( (array) $text as $k => $v ) {
$this->text[ $k ] = $v;
}
}
/**
* add_data
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function add_data( $data ) {
foreach( (array) $data as $k => $v ) {
$this->data[ $k ] = $v;
}
}
/**
* register_scripts
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function register_scripts() {
// vars
$version = acf_get_setting('version');
$min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
// scripts
wp_register_script('acf-input', acf_get_url("assets/js/acf-input{$min}.js"), array('jquery', 'jquery-ui-sortable', 'jquery-ui-resizable'), $version );
wp_register_script('acf-field-group', acf_get_url("assets/js/acf-field-group{$min}.js"), array('acf-input'), $version );
// styles
wp_register_style('acf-global', acf_get_url('assets/css/acf-global.css'), array(), $version );
wp_register_style('acf-input', acf_get_url('assets/css/acf-input.css'), array('acf-global'), $version );
wp_register_style('acf-field-group', acf_get_url('assets/css/acf-field-group.css'), array('acf-input'), $version );
// action
do_action('acf/register_scripts', $version, $min);
}
/**
* enqueue_scripts
*
* Enqueue scripts for input
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function enqueue_scripts( $args = array() ) {
// run only once
if( acf_has_done('enqueue_scripts') ) {
return;
}
// defaults
$args = wp_parse_args($args, array(
// force tinymce editor to be enqueued
'uploader' => false,
// priority used for action callbacks, defaults to 20 which runs after defaults
'priority' => 20,
// action prefix
'context' => is_admin() ? 'admin' : 'wp'
));
// define actions
$actions = array(
'admin_enqueue_scripts' => $args['context'] . '_enqueue_scripts',
'admin_print_scripts' => $args['context'] . '_print_scripts',
'admin_head' => $args['context'] . '_head',
'admin_footer' => $args['context'] . '_footer',
'admin_print_footer_scripts' => $args['context'] . '_print_footer_scripts',
);
// fix customizer actions where head and footer are not available
if( $args['context'] == 'customize_controls' ) {
$actions['admin_head'] = $actions['admin_print_scripts'];
$actions['admin_footer'] = $actions['admin_print_footer_scripts'];
}
// add actions
foreach( $actions as $function => $action ) {
acf_maybe_add_action( $action, array($this, $function), $args['priority'] );
}
// enqueue uploader
// WP requires a lot of JS + inline scripes to create the media modal and should be avoioded when possible.
// - priority must be less than 10 to allow WP to enqueue
if( $args['uploader'] ) {
add_action($actions['admin_footer'], 'acf_enqueue_uploader', 5);
}
// localize text
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'),
// media
'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'),
// 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'),
// tooltip
'Are you sure?' => __('Are you sure?','acf'),
'Yes' => __('Yes','acf'),
'No' => __('No','acf'),
'Remove' => __('Remove','acf'),
'Cancel' => __('Cancel','acf'),
// conditions
'Has any value' => __('Has any value', 'acf'),
'Has no value' => __('Has no value', 'acf'),
'Value is equal to' => __('Value is equal to', 'acf'),
'Value is not equal to' => __('Value is not equal to', 'acf'),
'Value matches pattern' => __('Value matches pattern', 'acf'),
'Value contains' => __('Value contains', 'acf'),
'Value is greater than' => __('Value is greater than', 'acf'),
'Value is less than' => __('Value is less than', 'acf'),
'Selection is greater than' => __('Selection is greater than', 'acf'),
'Selection is less than' => __('Selection is less than', 'acf'),
// misc
'Edit field group' => __('Edit field group', 'acf'),
));
}
/**
* admin_enqueue_scripts
*
* description
*
* @date 16/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_enqueue_scripts() {
// enqueue
wp_enqueue_script('acf-input');
wp_enqueue_style('acf-input');
// vars
$text = array();
// actions
do_action('acf/enqueue_scripts');
do_action('acf/admin_enqueue_scripts');
do_action('acf/input/admin_enqueue_scripts');
// only include translated strings
foreach( $this->text as $k => $v ) {
if( str_replace('.verb', '', $k) !== $v ) {
$text[ $k ] = $v;
}
}
// localize text
if( $text ) {
wp_localize_script( 'acf-input', 'acfL10n', $text );
}
}
/**
* admin_print_scripts
*
* description
*
* @date 18/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_print_scripts() {
do_action('acf/admin_print_scripts');
}
/**
* admin_head
*
* description
*
* @date 16/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_head() {
// actions
do_action('acf/admin_head');
do_action('acf/input/admin_head');
}
/**
* admin_footer
*
* description
*
* @date 16/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_footer() {
// global
global $wp_version;
// get data
$data = wp_parse_args($this->data, array(
'screen' => acf_get_form_data('screen'),
'post_id' => acf_get_form_data('post_id'),
'nonce' => wp_create_nonce( 'acf_nonce' ),
'admin_url' => admin_url(),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'validation' => acf_get_form_data('validation'),
'wp_version' => $wp_version,
'acf_version' => acf_get_setting('version'),
'browser' => acf_get_browser(),
'locale' => acf_get_locale(),
'rtl' => is_rtl(),
'editor' => acf_is_block_editor() ? 'block' : 'classic'
));
// get l10n (old)
$l10n = apply_filters( 'acf/input/admin_l10n', array() );
// todo: force 'acf-input' script enqueue if not yet included
// - fixes potential timing issue if acf_enqueue_assest() was called during body
// localize data
?>
<script type="text/javascript">
acf.data = <?php echo wp_json_encode($data); ?>;
acf.l10n = <?php echo wp_json_encode($l10n); ?>;
</script>
<?php
// actions
do_action('acf/admin_footer');
do_action('acf/input/admin_footer');
// trigger prepare
?>
<script type="text/javascript">
acf.doAction('prepare');
</script>
<?php
}
/**
* admin_print_footer_scripts
*
* description
*
* @date 18/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function admin_print_footer_scripts() {
do_action('acf/admin_print_footer_scripts');
}
/*
* enqueue_uploader
*
* This function will render a WP WYSIWYG and enqueue media
*
* @type function
* @date 27/10/2014
* @since 5.0.9
*
* @param n/a
* @return n/a
*/
function enqueue_uploader() {
// run only once
if( acf_has_done('enqueue_uploader') ) {
return;
}
// bail early if doing ajax
if( acf_is_ajax() ) {
return;
}
// enqueue media if user can upload
if( current_user_can('upload_files') ) {
wp_enqueue_media();
}
// create dummy editor
?>
<div id="acf-hidden-wp-editor" class="acf-hidden">
<?php wp_editor( '', 'acf_content' ); ?>
</div>
<?php
// action
do_action('acf/enqueue_uploader');
}
}
// instantiate
acf_new_instance('ACF_Assets');
endif; // class_exists check
/**
* acf_localize_text
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function acf_localize_text( $text ) {
return acf_get_instance('ACF_Assets')->add_text( $text );
}
/**
* acf_localize_data
*
* description
*
* @date 13/4/18
* @since 5.6.9
*
* @param type $var Description. Default.
* @return type Description.
*/
function acf_localize_data( $data ) {
return acf_get_instance('ACF_Assets')->add_data( $data );
}
/*
* acf_enqueue_scripts
*
*
*
* @type function
* @date 6/10/13
* @since 5.0.0
*
* @param n/a
* @return n/a
*/
function acf_enqueue_scripts( $args = array() ) {
return acf_get_instance('ACF_Assets')->enqueue_scripts( $args );
}
/*
* acf_enqueue_uploader
*
* This function will render a WP WYSIWYG and enqueue media
*
* @type function
* @date 27/10/2014
* @since 5.0.9
*
* @param n/a
* @return n/a
*/
function acf_enqueue_uploader() {
return acf_get_instance('ACF_Assets')->enqueue_uploader();
}
?>
@@ -0,0 +1,354 @@
<?php
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
@@ -0,0 +1,484 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
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
/*
* acf_get_compatibility
*
* Returns true if compatibility is enabled for the given component.
*
* @date 20/1/15
* @since 5.1.5
*
* @param string $name The name of the component to check.
* @return bool
*/
function acf_get_compatibility( $name ) {
return apply_filters( "acf/compatibility/{$name}", false );
}
@@ -0,0 +1,149 @@
<?php
// Register deprecated filters ( $deprecated, $version, $replacement ).
acf_add_deprecated_filter( 'acf/settings/export_textdomain', '5.3.3', 'acf/settings/l10n_textdomain' );
acf_add_deprecated_filter( 'acf/settings/export_translate', '5.3.3', 'acf/settings/l10n_field' );
acf_add_deprecated_filter( 'acf/settings/export_translate', '5.3.3', 'acf/settings/l10n_field_group' );
acf_add_deprecated_filter( 'acf/settings/dir', '5.6.8', 'acf/settings/url' );
acf_add_deprecated_filter( 'acf/get_valid_field', '5.5.6', 'acf/validate_field' );
acf_add_deprecated_filter( 'acf/get_valid_field_group', '5.5.6', 'acf/validate_field_group' );
acf_add_deprecated_filter( 'acf/get_valid_post_id', '5.5.6', 'acf/validate_post_id' );
acf_add_deprecated_filter( 'acf/get_field_reference', '5.6.5', 'acf/load_reference' );
acf_add_deprecated_filter( 'acf/get_field_group', '5.7.11', 'acf/load_field_group' );
acf_add_deprecated_filter( 'acf/get_field_groups', '5.7.11', 'acf/load_field_groups' );
acf_add_deprecated_filter( 'acf/get_fields', '5.7.11', 'acf/load_fields' );
// Register variations for deprecated filters.
acf_add_filter_variations( 'acf/get_valid_field', array('type'), 0 );
/**
* acf_render_field_wrap_label
*
* Renders the field's label.
*
* @date 19/9/17
* @since 5.6.3
* @deprecated 5.6.5
*
* @param array $field The field array.
* @return void
*/
function acf_render_field_wrap_label( $field ) {
// Warning.
_deprecated_function( __FUNCTION__, '5.7.11', 'acf_render_field_label()' );
// Render.
acf_render_field_label( $field );
}
/**
* acf_render_field_wrap_description
*
* Renders the field's instructions.
*
* @date 19/9/17
* @since 5.6.3
* @deprecated 5.6.5
*
* @param array $field The field array.
* @return void
*/
function acf_render_field_wrap_description( $field ) {
// Warning.
_deprecated_function( __FUNCTION__, '5.7.11', 'acf_render_field_instructions()' );
// Render.
acf_render_field_instructions( $field );
}
/*
* acf_get_fields_by_id
*
* Returns and array of fields for the given $parent_id.
*
* @date 27/02/2014
* @since 5.0.0.
* @deprecated 5.7.11
*
* @param int $parent_id The parent ID.
* @return array
*/
function acf_get_fields_by_id( $parent_id = 0 ) {
// Warning.
_deprecated_function( __FUNCTION__, '5.7.11', 'acf_get_fields()' );
// Return fields.
return acf_get_fields(array( 'ID' => $parent_id, 'key' => "group_$parent_id" ));
}
/**
* acf_update_option
*
* 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
*
* @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');
}
return update_option( $option, $value, $autoload );
}
/**
* acf_get_field_reference
*
* Finds the field key for a given field name and post_id.
*
* @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
*/
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 );
}
/**
* acf_get_dir
*
* Returns the plugin url to a specified file.
*
* @date 28/09/13
* @since 5.0.0
* @deprecated 5.6.8
*
* @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 );
}
@@ -0,0 +1,378 @@
<?php
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if( ! class_exists('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
/*
* acf_register_field_type
*
* alias of acf()->fields->register_field_type()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_register_field_type( $class ) {
return acf()->fields->register_field_type( $class );
}
/*
* acf_register_field_type_info
*
* alias of acf()->fields->register_field_type_info()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_register_field_type_info( $info ) {
return acf()->fields->register_field_type_info( $info );
}
/*
* acf_get_field_type
*
* alias of acf()->fields->get_field_type()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_get_field_type( $name ) {
return acf()->fields->get_field_type( $name );
}
/*
* acf_get_field_types
*
* alias of acf()->fields->get_field_types()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_get_field_types( $args = array() ) {
// default
$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 );
}
/**
* 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();
$field_types = acf_get_field_types();
// loop
foreach( $field_types as $type ) {
$data[ $type->name ] = array(
'label' => $type->label,
'name' => $type->name,
'category' => $type->category,
'public' => $type->public
);
}
// return
return $data;
}
/*
* acf_is_field_type
*
* alias of acf()->fields->is_field_type()
*
* @type function
* @date 31/5/17
* @since 5.6.0
*
* @param n/a
* @return n/a
*/
function acf_is_field_type( $name = '' ) {
return acf()->fields->is_field_type( $name );
}
/*
* acf_get_field_type_prop
*
* This function will return a field type's property
*
* @type function
* @date 1/10/13
* @since 5.0.0
*
* @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;
}
/*
* acf_get_field_type_label
*
* This function will return the label of a field type
*
* @type function
* @date 1/10/13
* @since 5.0.0
*
* @param n/a
* @return (array)
*/
function acf_get_field_type_label( $name = '' ) {
$label = acf_get_field_type_prop( $name, 'label' );
return $label ? $label : '<span class="acf-tooltip-js" title="'.__('Field type does not exist', 'acf').'">'.__('Unknown', 'acf').'</span>';
}
/*
* acf_field_type_exists (deprecated)
*
* deprecated in favour of acf_is_field_type()
*
* @type function
* @date 1/10/13
* @since 5.0.0
*
* @param $type (string)
* @return (boolean)
*/
function acf_field_type_exists( $type = '' ) {
return acf_is_field_type( $type );
}
/*
* acf_get_grouped_field_types
*
* Returns an multi-dimentional array of field types "name => label" grouped by category
*
* @type function
* @date 1/10/13
* @since 5.0.0
*
* @param n/a
* @return (array)
*/
function acf_get_grouped_field_types() {
// vars
$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'),
);
// loop
foreach( $types as $type ) {
// translate
$cat = $type->category;
$cat = isset( $l10n[$cat] ) ? $l10n[$cat] : $cat;
// append
$groups[ $cat ][ $type->name ] = $type->label;
}
// filter
$groups = apply_filters('acf/get_field_types', $groups);
// return
return $groups;
}
?>
@@ -0,0 +1,167 @@
<?php
if( ! class_exists('acf_field__accordion') ) :
class acf_field__accordion extends acf_field {
/**
* 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']
);
?>
<div <?php acf_esc_attr_e($atts); ?>></div>
<?php
}
/*
* 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 ) {
/*
// message
$message = '';
$message .= '<p>' . __( 'Accordions help you organize fields into panels that open and close.', 'acf') . '</p>';
$message .= '<p>' . __( 'All fields following this accordion (or until another accordion is defined) will be grouped together.','acf') . '</p>';
// 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
?>
@@ -0,0 +1,292 @@
<?php
if( ! class_exists('acf_field_button_group') ) :
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',
);
}
/**
* 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
);
}
// 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 .= '<div ' . acf_esc_attr($div) . '>';
// loop
foreach( $buttons as $button ) {
// checked
if( $button['checked'] ) {
$button['checked'] = 'checked';
} else {
unset($button['checked']);
}
// append
$html .= acf_get_radio_input( $button );
}
// close
$html .= '</div>';
// 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') . '<br /><br />' . __('For more control, you may specify both a value and label like this:','acf'). '<br /><br />' . __('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
?>
@@ -0,0 +1,580 @@
<?php
if( ! class_exists('acf_field_checkbox') ) :
class acf_field_checkbox 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 = '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 '<ul ' . acf_esc_attr( $ul ) . '>' . "\n" . $li . '</ul>' . "\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 '<li>' . acf_get_checkbox_input($atts) . '</li>' . "\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,
);
// bail ealry if choice already exists
if( in_array( $esc_value, $this->_values ) ) continue;
// append
$html .= '<li><input class="acf-checkbox-custom" type="checkbox" checked="checked" />' . acf_get_text_input($text_input) . '</li>' . "\n";
}
// append button
$html .= '<li><a href="#" class="button acf-add-checkbox">' . esc_attr__('Add new choice', 'acf') . '</a></li>' . "\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 .= '<li>';
// optgroup
if( is_array($label) ){
$html .= '<ul>' . "\n";
$html .= $this->walk( $label, $args, $depth+1 );
$html .= '</ul>';
// 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 .= '</li>' . "\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') . '<br /><br />' . __('For more control, you may specify both a value and label like this:','acf'). '<br /><br />' . __('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 ) {
return acf_get_field_type('select')->update_field( $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, true );
// 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' );
endif; // class_exists check
?>
@@ -0,0 +1,148 @@
<?php
if( ! class_exists('acf_field_color_picker') ) :
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' => '',
);
}
/*
* 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() {
// globals
global $wp_scripts;
// register if not already (on front end)
// http://wordpress.stackexchange.com/questions/82718/how-do-i-implement-the-wordpress-iris-picker-into-my-plugin-on-the-front-end
if( !isset($wp_scripts->registered['iris']) ) {
// styles
wp_register_style('wp-color-picker', admin_url('css/color-picker.css'), array(), '', true);
// scripts
wp_register_script('iris', admin_url('js/iris.min.js'), array('jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch'), '1.0.7', true);
wp_register_script('wp-color-picker', admin_url('js/color-picker.min.js'), array('iris'), '', true);
// localize
wp_localize_script('wp-color-picker', 'wpColorPickerL10n', array(
'clear' => __('Clear', 'acf' ),
'defaultString' => __('Default', 'acf' ),
'pick' => __('Select Color', 'acf' ),
'current' => __('Current Color', 'acf' )
));
}
// 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
?>
<div class="acf-color-picker">
<?php acf_hidden_input( $hidden_input ); ?>
<?php acf_text_input( $text_input ); ?>
</div>
<?php
}
/*
* 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 ) {
// display_format
acf_render_field_setting( $field, array(
'label' => __('Default Value','acf'),
'instructions' => '',
'type' => 'text',
'name' => 'default_value',
'placeholder' => '#FFFFFF'
));
}
}
// initialize
acf_register_field_type( 'acf_field_color_picker' );
endif; // class_exists check
?>
@@ -0,0 +1,276 @@
<?php
if( ! class_exists('acf_field_date_picker') ) :
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
);
}
/*
* 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'] );
}
// 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 ]) ) {
$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
?>
<div <?php acf_esc_attr_e( $div ); ?>>
<?php acf_hidden_input( $hidden_input ); ?>
<?php acf_text_input( $text_input ); ?>
</div>
<?php
}
/*
* 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 ) {
// global
global $wp_locale;
// vars
$d_m_Y = date_i18n('d/m/Y');
$m_d_Y = date_i18n('m/d/Y');
$F_j_Y = date_i18n('F j, Y');
$Ymd = date_i18n('Ymd');
// display_format
acf_render_field_setting( $field, array(
'label' => __('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' => '<span>' . $d_m_Y . '</span><code>d/m/Y</code>',
'm/d/Y' => '<span>' . $m_d_Y . '</span><code>m/d/Y</code>',
'F j, Y' => '<span>' . $F_j_Y . '</span><code>F j, Y</code>',
'other' => '<span>' . __('Custom:','acf') . '</span>'
)
));
// 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' => '<span>' . $d_m_Y . '</span><code>d/m/Y</code>',
'm/d/Y' => '<span>' . $m_d_Y . '</span><code>m/d/Y</code>',
'F j, Y' => '<span>' . $F_j_Y . '</span><code>F j, Y</code>',
'Ymd' => '<span>' . $Ymd . '</span><code>Ymd</code>',
'other' => '<span>' . __('Custom:','acf') . '</span>'
)
));
}
// 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' );
endif; // class_exists check
?>
@@ -0,0 +1,257 @@
<?php
if( ! class_exists('acf_field_date_and_time_picker') ) :
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
);
}
/*
* 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 ) {
// format 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 to date and time
// the letter 'm' is used for date and minute in JS, so this must be done here in PHP
$formats = acf_split_date_time($field['display_format']);
// vars
$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,
);
// html
?>
<div <?php acf_esc_attr_e( $div ); ?>>
<?php acf_hidden_input( $hidden_input ); ?>
<?php acf_text_input( $text_input ); ?>
</div>
<?php
}
/*
* 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 ) {
// global
global $wp_locale;
// vars
$d_m_Y = date_i18n('d/m/Y g:i a');
$m_d_Y = date_i18n('m/d/Y g:i a');
$F_j_Y = date_i18n('F j, Y g:i a');
$Ymd = date_i18n('Y-m-d H:i:s');
// display_format
acf_render_field_setting( $field, array(
'label' => __('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' => '<span>' . $d_m_Y . '</span><code>d/m/Y g:i a</code>',
'm/d/Y g:i a' => '<span>' . $m_d_Y . '</span><code>m/d/Y g:i a</code>',
'F j, Y g:i a' => '<span>' . $F_j_Y . '</span><code>F j, Y g:i a</code>',
'Y-m-d H:i:s' => '<span>' . $Ymd . '</span><code>Y-m-d H:i:s</code>',
'other' => '<span>' . __('Custom:','acf') . '</span>'
)
));
// 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' => '<span>' . $d_m_Y . '</span><code>d/m/Y g:i a</code>',
'm/d/Y g:i a' => '<span>' . $m_d_Y . '</span><code>m/d/Y g:i a</code>',
'F j, Y g:i a' => '<span>' . $F_j_Y . '</span><code>F j, Y g:i a</code>',
'Y-m-d H:i:s' => '<span>' . $Ymd . '</span><code>Y-m-d H:i:s</code>',
'other' => '<span>' . __('Custom:','acf') . '</span>'
)
));
// 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
?>
@@ -0,0 +1,161 @@
<?php
if( ! class_exists('acf_field_email') ) :
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 .= '<div class="acf-input-prepend">' . acf_esc_html($field['prepend']) . '</div>';
}
// append
if( $field['append'] !== '' ) {
$field['class'] .= ' acf-is-appended';
$html .= '<div class="acf-input-append">' . acf_esc_html($field['append']) . '</div>';
}
// 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 .= '<div class="acf-input-wrap">' . acf_get_text_input( $atts ) . '</div>';
// 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',
));
}
}
// initialize
acf_register_field_type( 'acf_field_email' );
endif; // class_exists check
?>
@@ -0,0 +1,438 @@
<?php
if( ! class_exists('acf_field_file') ) :
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'));
}
/*
* 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']);
}
}
}
?>
<div <?php acf_esc_attr_e( $div ); ?>>
<?php acf_hidden_input(array( 'name' => $field['name'], 'value' => $field['value'], 'data-name' => 'id' )); ?>
<div class="show-if-value file-wrap">
<div class="file-icon">
<img data-name="icon" src="<?php echo esc_url($o['icon']); ?>" alt=""/>
</div>
<div class="file-info">
<p>
<strong data-name="title"><?php echo esc_html($o['title']); ?></strong>
</p>
<p>
<strong><?php _e('File name', 'acf'); ?>:</strong>
<a data-name="filename" href="<?php echo esc_url($o['url']); ?>" target="_blank"><?php echo esc_html($o['filename']); ?></a>
</p>
<p>
<strong><?php _e('File size', 'acf'); ?>:</strong>
<span data-name="filesize"><?php echo esc_html($o['filesize']); ?></span>
</p>
</div>
<div class="acf-actions -hover">
<?php
if( $uploader != 'basic' ):
?><a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php _e('Edit', 'acf'); ?>"></a><?php
endif;
?><a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php _e('Remove', 'acf'); ?>"></a>
</div>
</div>
<div class="hide-if-value">
<?php if( $uploader == 'basic' ): ?>
<?php if( $field['value'] && !is_numeric($field['value']) ): ?>
<div class="acf-error-message"><p><?php echo acf_esc_html($field['value']); ?></p></div>
<?php endif; ?>
<label class="acf-basic-uploader">
<?php acf_file_input(array( 'name' => $field['name'], 'id' => $field['id'] )); ?>
</label>
<?php else: ?>
<p><?php _e('No file selected','acf'); ?> <a data-name="add" class="acf-button button" href="#"><?php _e('Add File','acf'); ?></a></p>
<?php endif; ?>
</div>
</div>
<?php
}
/*
* 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 ) {
// clear numeric settings
$clear = array(
'min_size',
'max_size'
);
foreach( $clear as $k ) {
if( empty($field[$k]) ) {
$field[$k] = '';
}
}
// 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) ) {
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' );
endif; // class_exists check
?>
@@ -0,0 +1,314 @@
<?php
if( ! class_exists('acf_field_google_map') ) :
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'
);
}
/*
* 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 ) {
// validate value
if( empty($field['value']) ) {
$field['value'] = array();
}
// value
$field['value'] = wp_parse_args($field['value'], array(
'address' => '',
'lat' => '',
'lng' => ''
));
// default options
foreach( $this->default_values as $k => $v ) {
if( empty($field[ $k ]) ) {
$field[ $k ] = $v;
}
}
// vars
$atts = array(
'id' => $field['id'],
'class' => "acf-google-map {$field['class']}",
'data-lat' => $field['center_lat'],
'data-lng' => $field['center_lng'],
'data-zoom' => $field['zoom'],
);
// has value
if( $field['value']['address'] ) {
$atts['class'] .= ' -value';
}
?>
<div <?php acf_esc_attr_e($atts); ?>>
<div class="acf-hidden">
<?php foreach( $field['value'] as $k => $v ):
acf_hidden_input(array( 'name' => $field['name'].'['.$k.']', 'value' => $v, 'data-name' => $k ));
endforeach; ?>
</div>
<div class="title">
<div class="acf-actions -hover">
<a href="#" data-name="search" class="acf-icon -search grey" title="<?php _e("Search", 'acf'); ?>"></a><?php
?><a href="#" data-name="clear" class="acf-icon -cancel grey" title="<?php _e("Clear location", 'acf'); ?>"></a><?php
?><a href="#" data-name="locate" class="acf-icon -location grey" title="<?php _e("Find current location", 'acf'); ?>"></a>
</div>
<input class="search" type="text" placeholder="<?php _e("Search for address...",'acf'); ?>" value="<?php echo esc_attr($field['value']['address']); ?>" />
<i class="acf-loading"></i>
</div>
<div class="canvas" style="<?php echo esc_attr('height: '.$field['height'].'px'); ?>"></div>
</div>
<?php
}
/*
* 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 ) {
// center_lat
acf_render_field_setting( $field, array(
'label' => __('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']
));
}
/*
* 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;
}
if( empty($value) || empty($value['lat']) || empty($value['lng']) ) {
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['lat']) ) {
$value = "";
}
// return
return $value;
}
}
// initialize
acf_register_field_type( 'acf_field_google_map' );
endif; // class_exists check
?>
@@ -0,0 +1,706 @@
<?php
if( ! class_exists('acf_field__group') ) :
class acf_field__group 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 = '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;
}
/*
* 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 '<div class="acf-fields -' . $label_placement . ' -border">';
foreach( $field['sub_fields'] as $sub_field ) {
acf_render_field_wrap( $sub_field );
}
echo '</div>';
}
/*
* 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 ) {
?>
<table class="acf-table">
<thead>
<tr>
<?php foreach( $field['sub_fields'] as $sub_field ):
// prepare field (allow sub fields to be removed)
$sub_field = acf_prepare_field($sub_field);
// bail ealry if no field
if( !$sub_field ) continue;
// vars
$atts = array();
$atts['class'] = 'acf-th';
$atts['data-name'] = $sub_field['_name'];
$atts['data-type'] = $sub_field['type'];
$atts['data-key'] = $sub_field['key'];
// Add custom width
if( $sub_field['wrapper']['width'] ) {
$atts['data-width'] = $sub_field['wrapper']['width'];
$atts['style'] = 'width: ' . $sub_field['wrapper']['width'] . '%;';
}
?>
<th <?php acf_esc_attr_e( $atts ); ?>>
<?php acf_render_field_label( $sub_field ); ?>
<?php acf_render_field_instructions( $sub_field ); ?>
</th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<tr class="acf-row">
<?php
foreach( $field['sub_fields'] as $sub_field ) {
acf_render_field_wrap( $sub_field, 'td' );
}
?>
</tr>
</tbody>
</table>
<?php
}
/*
* 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
$args = array(
'fields' => $field['sub_fields'],
'parent' => $field['ID']
);
?><tr class="acf-field acf-field-setting-sub_fields" data-setting="group" data-name="sub_fields">
<td class="acf-label">
<label><?php _e("Sub Fields",'acf'); ?></label>
</td>
<td class="acf-input">
<?php
acf_get_view('field-group-fields', $args);
?>
</td>
</tr>
<?php
// 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')
)
));
}
/*
* 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' );
// 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
*
* 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 ) {
// bail early if no sub fields
if( empty($field['sub_fields']) ) return $field;
// prepare
$field['sub_fields'] = acf_prepare_fields_for_export( $field['sub_fields'] );
// 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 sub fields
if( empty($field['sub_fields']) ) return $field;
// vars
$sub_fields = $field['sub_fields'];
// reset field setting
$field['sub_fields'] = array();
// loop
foreach( $sub_fields as &$sub_field ) {
$sub_field['parent'] = $field['key'];
}
// merge
array_unshift($sub_fields, $field);
// return
return $sub_fields;
}
/*
* 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
?>
@@ -0,0 +1,429 @@
<?php
if( ! class_exists('acf_field_image') ) :
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'),
));
}
/*
* 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');
// enqueue
if( $uploader == 'wp' ) {
acf_enqueue_uploader();
}
// vars
$url = '';
$alt = '';
$div = array(
'class' => 'acf-image-uploader',
'data-preview_size' => $field['preview_size'],
'data-library' => $field['library'],
'data-mime_types' => $field['mime_types'],
'data-uploader' => $uploader
);
// has value?
if( $field['value'] ) {
// update vars
$url = wp_get_attachment_image_src($field['value'], $field['preview_size']);
$alt = get_post_meta($field['value'], '_wp_attachment_image_alt', true);
// url exists
if( $url ) $url = $url[0];
// url exists
if( $url ) {
$div['class'] .= ' has-value';
}
}
// get size of preview value
$size = acf_get_image_size($field['preview_size']);
?>
<div <?php acf_esc_attr_e( $div ); ?>>
<?php acf_hidden_input(array( 'name' => $field['name'], 'value' => $field['value'] )); ?>
<div class="show-if-value image-wrap" <?php if( $size['width'] ): ?>style="<?php echo esc_attr('max-width: '.$size['width'].'px'); ?>"<?php endif; ?>>
<img data-name="image" src="<?php echo esc_url($url); ?>" alt="<?php echo esc_attr($alt); ?>"/>
<div class="acf-actions -hover">
<?php
if( $uploader != 'basic' ):
?><a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php _e('Edit', 'acf'); ?>"></a><?php
endif;
?><a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php _e('Remove', 'acf'); ?>"></a>
</div>
</div>
<div class="hide-if-value">
<?php if( $uploader == 'basic' ): ?>
<?php if( $field['value'] && !is_numeric($field['value']) ): ?>
<div class="acf-error-message"><p><?php echo acf_esc_html($field['value']); ?></p></div>
<?php endif; ?>
<label class="acf-basic-uploader">
<?php acf_file_input(array( 'name' => $field['name'], 'id' => $field['id'] )); ?>
</label>
<?php else: ?>
<p><?php _e('No image selected','acf'); ?> <a data-name="add" class="acf-button button" href="#"><?php _e('Add Image','acf'); ?></a></p>
<?php endif; ?>
</div>
</div>
<?php
}
/*
* 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 ) {
// clear numeric settings
$clear = array(
'min_width',
'min_height',
'min_size',
'max_width',
'max_height',
'max_size'
);
foreach( $clear as $k ) {
if( empty($field[$k]) ) {
$field[$k] = '';
}
}
// 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' );
endif; // class_exists check
?>

Some files were not shown because too many files have changed in this diff Show More