+
+
+
+
+
+ __("Search...",'acf'), 'data-filter' => 's') ); ?>
+
+
+
-
-
-
- " type="text" />
-
-
-
-
-
-
-
-
-
- $v ): ?>
-
-
-
-
-
-
-
-
-
-
-
-
- $v_opt ): ?>
-
- $v ): ?>
-
-
-
-
-
-
-
-
-
+ /* post_type */
+ if( $filters['post_type'] ): ?>
+
+
+ $filters['post_type'], 'data-filter' => 'post_type') ); ?>
+
+
+
+
+
+ $filters['taxonomy'], 'data-filter' => 'taxonomy') ); ?>
+
+
+
-
-
+
-
-
-
- $field['value'],
- 'post_type' => $field['post_type']
- ));
-
-
- // set choices
- if( !empty($posts) ):
-
- foreach( array_keys($posts) as $i ):
-
- // vars
- $post = acf_extract_var( $posts, $i );
-
-
- ?>
-
-
- get_post_title( $post, $field ); ?>
-
-
-
+ // get posts
+ $posts = acf_get_posts(array(
+ 'post__in' => $field['value'],
+ 'post_type' => $field['post_type']
+ ));
+
+ // loop
+ foreach( $posts as $post ): ?>
+
+ $field['name'].'[]', 'value' => $post->ID) ); ?>
+
+ get_post_title( $post, $field ); ?>
+
+
+
+
+
-
-
-
-
-
name = 'select';
@@ -64,10 +53,6 @@ class acf_field_select extends acf_field {
// ajax
add_action('wp_ajax_acf/fields/select/query', array($this, 'ajax_query'));
add_action('wp_ajax_nopriv_acf/fields/select/query', array($this, 'ajax_query'));
-
-
- // do not delete!
- parent::__construct();
}
@@ -194,29 +179,26 @@ class acf_field_select extends acf_field {
if( !$field ) return false;
+ // get choices
+ $choices = acf_get_array($field['choices']);
+ if( empty($field['choices']) ) return false;
+
+
// vars
$results = array();
- $s = false;
- $is_search = false;
+ $s = null;
// search
if( $options['s'] !== '' ) {
// strip slashes (search may be integer)
- $s = wp_unslash( strval($options['s']) );
-
-
- // update vars
- $is_search = true;
+ $s = strval( $options['s'] );
+ $s = wp_unslash( $s );
}
- // bail ealry if no choices
- if( empty($field['choices']) ) return false;
-
-
// loop
foreach( $field['choices'] as $k => $v ) {
@@ -225,7 +207,7 @@ class acf_field_select extends acf_field {
// if searching, but doesn't exist
- if( $is_search && stripos($v, $s) === false ) continue;
+ if( is_string($s) && stripos($v, $s) === false ) continue;
// append
@@ -264,23 +246,19 @@ class acf_field_select extends acf_field {
function render_field( $field ) {
// convert
- $field['value'] = acf_get_array($field['value'], false);
- $field['choices'] = acf_get_array($field['choices']);
+ $value = acf_get_array($field['value']);
+ $choices = acf_get_array($field['choices']);
// placeholder
if( empty($field['placeholder']) ) {
-
$field['placeholder'] = _x('Select', 'verb', 'acf');
-
}
// add empty value (allows '' to be selected)
- if( empty($field['value']) ) {
-
- $field['value'] = array('');
-
+ if( empty($value) ) {
+ $value = array('');
}
@@ -289,13 +267,13 @@ class acf_field_select extends acf_field {
if( $field['allow_null'] && !$field['multiple'] ) {
$prepend = array('' => '- ' . $field['placeholder'] . ' -');
- $field['choices'] = $prepend + $field['choices'];
+ $choices = $prepend + $choices;
}
// vars
- $atts = array(
+ $select = array(
'id' => $field['id'],
'class' => $field['class'],
'name' => $field['name'],
@@ -310,33 +288,23 @@ class acf_field_select extends acf_field {
// multiple
if( $field['multiple'] ) {
- $atts['multiple'] = 'multiple';
- $atts['size'] = 5;
- $atts['name'] .= '[]';
+ $select['multiple'] = 'multiple';
+ $select['size'] = 5;
+ $select['name'] .= '[]';
}
// special atts
- foreach( array( 'readonly', 'disabled' ) as $k ) {
-
- if( !empty($field[ $k ]) ) $atts[ $k ] = $k;
-
- }
-
-
- // custom ajax action
- if( !empty($field['ajax_action']) ) {
-
- $atts['data-ajax_action'] = $field['ajax_action'];
-
- }
+ if( !empty($field['readonly']) ) $select['readonly'] = 'readonly';
+ if( !empty($field['disabled']) ) $select['disabled'] = 'disabled';
+ if( !empty($field['ajax_action']) ) $select['data-ajax_action'] = $field['ajax_action'];
// hidden input
if( $field['ui'] ) {
- $v = $field['value'];
+ $v = $value;
if( $field['multiple'] ) {
@@ -364,86 +332,16 @@ class acf_field_select extends acf_field {
}
-
- // open
- echo '
';
+ // append
+ $select['value'] = $value;
+ $select['choices'] = $choices;
- // walk
- $this->walk( $field['choices'], $field['value'] );
-
-
- // close
- echo ' ';
+ // render
+ acf_select_input( $select );
}
-
-
- /*
- * walk
- *
- * description
- *
- * @type function
- * @date 22/12/2015
- * @since 5.3.2
- *
- * @param $post_id (int)
- * @return $post_id (int)
- */
-
- function walk( $choices, $values ) {
- // bail ealry if no choices
- if( empty($choices) ) return;
-
-
- // loop
- foreach( $choices as $k => $v ) {
-
- // optgroup
- if( is_array($v) ){
-
- // optgroup
- echo '
';
-
-
- // walk
- $this->walk( $v, $values );
-
-
- // close optgroup
- echo ' ';
-
-
- // break
- continue;
-
- }
-
-
- // vars
- $search = html_entity_decode($k);
- $pos = array_search($search, $values);
- $atts = array( 'value' => $k );
-
-
- // validate selected
- if( $pos !== false ) {
-
- $atts['selected'] = 'selected';
- $atts['data-i'] = $pos;
-
- }
-
-
- // option
- echo '
' . $v . ' ';
-
- }
-
- }
-
/*
* render_field_settings()
@@ -737,7 +635,7 @@ class acf_field_select extends acf_field {
// initialize
-acf_register_field_type( new acf_field_select() );
+acf_register_field_type( 'acf_field_select' );
endif; // class_exists check
diff --git a/includes/fields/class-acf-field-separator.php b/includes/fields/class-acf-field-separator.php
new file mode 100644
index 0000000..e2cee33
--- /dev/null
+++ b/includes/fields/class-acf-field-separator.php
@@ -0,0 +1,91 @@
+name = 'separator';
+ $this->label = __("Separator",'acf');
+ $this->category = 'layout';
+
+ }
+
+
+ /*
+ * render_field()
+ *
+ * Create the HTML interface for your field
+ *
+ * @param $field - an array holding all the field's data
+ *
+ * @type action
+ * @since 3.6
+ * @date 23/01/13
+ */
+
+ function render_field( $field ) {
+
+ /* do nothing */
+
+ }
+
+
+ /*
+ * load_field()
+ *
+ * This filter is appied to the $field after it is loaded from the database
+ *
+ * @type filter
+ * @since 3.6
+ * @date 23/01/13
+ *
+ * @param $field - the field array holding all the field options
+ *
+ * @return $field - the field array holding all the field options
+ */
+
+ function load_field( $field ) {
+
+ // remove name to avoid caching issue
+ $field['name'] = '';
+
+
+ // remove required to avoid JS issues
+ $field['required'] = 0;
+
+
+ // set value other than 'null' to avoid ACF loading / caching issue
+ $field['value'] = false;
+
+
+ // return
+ return $field;
+
+ }
+
+}
+
+
+// initialize
+acf_register_field_type( 'acf_field_separator' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/fields/tab.php b/includes/fields/class-acf-field-tab.php
similarity index 89%
rename from fields/tab.php
rename to includes/fields/class-acf-field-tab.php
index df213c4..268ff90 100644
--- a/fields/tab.php
+++ b/includes/fields/class-acf-field-tab.php
@@ -1,16 +1,5 @@
name = 'tab';
@@ -40,9 +29,6 @@ class acf_field_tab extends acf_field {
'endpoint' => 0 // added in 5.2.8
);
-
- // do not delete!
- parent::__construct();
}
@@ -68,7 +54,7 @@ class acf_field_tab extends acf_field {
);
?>
-
>
+
>
name = 'taxonomy';
@@ -54,13 +46,8 @@ class acf_field_taxonomy extends acf_field {
add_action('wp_ajax_acf/fields/taxonomy/add_term', array($this, 'ajax_add_term'));
- // custom set_terms
- $this->save_post_terms = array();
+ // actions
add_action('acf/save_post', array($this, 'save_post'), 15, 1);
-
-
- // do not delete!
- parent::__construct();
}
@@ -709,6 +696,10 @@ class acf_field_taxonomy extends acf_field {
$taxonomy_obj = get_taxonomy($field['taxonomy']);
+ // include walker
+ acf_include('includes/walkers/class-acf-walker-taxonomy-field.php');
+
+
// vars
$args = array(
'taxonomy' => $field['taxonomy'],
@@ -1009,60 +1000,8 @@ class acf_field_taxonomy extends acf_field {
// initialize
-acf_register_field_type( new acf_field_taxonomy() );
+acf_register_field_type( 'acf_field_taxonomy' );
endif; // class_exists check
-
-
-if( ! class_exists('acf_taxonomy_field_walker') ) :
-
-class acf_taxonomy_field_walker extends Walker {
-
- var $field = null,
- $tree_type = 'category',
- $db_fields = array ( 'parent' => 'parent', 'id' => 'term_id' );
-
- function __construct( $field ) {
-
- $this->field = $field;
-
- }
-
- function start_el( &$output, $term, $depth = 0, $args = array(), $current_object_id = 0) {
-
- // vars
- $selected = in_array( $term->term_id, $this->field['value'] );
-
-
- // append
- $output .= '
' . $term->name . ' ';
-
- }
-
- function end_el( &$output, $term, $depth = 0, $args = array() ) {
-
- // append
- $output .= '' . "\n";
-
- }
-
- function start_lvl( &$output, $depth = 0, $args = array() ) {
-
- // append
- $output .= '
' . "\n";
-
- }
-
- function end_lvl( &$output, $depth = 0, $args = array() ) {
-
- // append
- $output .= ' ' . "\n";
-
- }
-
-}
-
-endif;
-
?>
\ No newline at end of file
diff --git a/fields/text.php b/includes/fields/class-acf-field-text.php
similarity index 74%
rename from fields/text.php
rename to includes/fields/class-acf-field-text.php
index 1b7716d..ca4d91f 100644
--- a/fields/text.php
+++ b/includes/fields/class-acf-field-text.php
@@ -1,23 +1,12 @@
name = 'text';
@@ -42,9 +31,6 @@ class acf_field_text extends acf_field {
'append' => ''
);
-
- // do not delete!
- parent::__construct();
}
@@ -64,24 +50,16 @@ class acf_field_text extends acf_field {
// vars
$atts = array();
- $o = array( 'type', 'id', 'class', 'name', 'value', 'placeholder' );
- $s = array( 'readonly', 'disabled' );
- $e = '';
-
-
- // maxlength
- if( $field['maxlength'] ) {
-
- $o[] = 'maxlength';
-
- }
+ $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'maxlength', 'pattern' );
+ $keys2 = array( 'readonly', 'disabled' );
+ $html = '';
// prepend
if( $field['prepend'] !== '' ) {
$field['class'] .= ' acf-is-prepended';
- $e .= '
' . $field['prepend'] . '
';
+ $html .= '
' . acf_esc_html($field['prepend']) . '
';
}
@@ -90,35 +68,30 @@ class acf_field_text extends acf_field {
if( $field['append'] !== '' ) {
$field['class'] .= ' acf-is-appended';
- $e .= '
' . $field['append'] . '
';
+ $html .= '
' . acf_esc_html($field['append']) . '
';
}
- // append atts
- foreach( $o as $k ) {
-
- $atts[ $k ] = $field[ $k ];
-
+ // atts
+ foreach( $keys as $k ) {
+ if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ];
}
- // append special atts
- foreach( $s as $k ) {
-
+ // atts2
+ foreach( $keys2 as $k ) {
if( !empty($field[ $k ]) ) $atts[ $k ] = $k;
-
}
// render
- $e .= '
';
- $e .= ' ';
- $e .= '
';
+ $html .= '
' . acf_get_text_input( $atts ) . '
';
// return
- echo $e;
+ echo $html;
+
}
@@ -187,7 +160,7 @@ class acf_field_text extends acf_field {
// initialize
-acf_register_field_type( new acf_field_text() );
+acf_register_field_type( 'acf_field_text' );
endif; // class_exists check
diff --git a/fields/textarea.php b/includes/fields/class-acf-field-textarea.php
similarity index 79%
rename from fields/textarea.php
rename to includes/fields/class-acf-field-textarea.php
index 408b30a..f5244ac 100644
--- a/fields/textarea.php
+++ b/includes/fields/class-acf-field-textarea.php
@@ -1,23 +1,12 @@
name = 'textarea';
@@ -42,9 +31,6 @@ class acf_field_textarea extends acf_field {
'rows' => ''
);
-
- // do not delete!
- parent::__construct();
}
@@ -64,53 +50,34 @@ class acf_field_textarea extends acf_field {
// vars
$atts = array();
- $o = array( 'id', 'class', 'name', 'placeholder', 'rows' );
- $s = array( 'readonly', 'disabled' );
- $e = '';
-
-
- // maxlength
- if( $field['maxlength'] ) {
-
- $o[] = 'maxlength';
-
- }
+ $keys = array( 'id', 'class', 'name', 'value', 'placeholder', 'rows', 'maxlength' );
+ $keys2 = array( 'readonly', 'disabled' );
// rows
- if( empty($field['rows']) ) {
-
+ if( !$field['rows'] ) {
$field['rows'] = 8;
-
}
- // append atts
- foreach( $o as $k ) {
-
- $atts[ $k ] = $field[ $k ];
-
+ // atts
+ foreach( $keys as $k ) {
+ if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ];
}
- // append special atts
- foreach( $s as $k ) {
-
+ // atts2
+ foreach( $keys2 as $k ) {
if( !empty($field[ $k ]) ) $atts[ $k ] = $k;
-
}
-
- $e .= '
';
-
// return
- echo $e;
+ echo acf_get_textarea_input( $atts );
}
+
/*
* render_field_settings()
*
@@ -126,14 +93,6 @@ class acf_field_textarea extends acf_field {
function render_field_settings( $field ) {
- // ACF4 migration
- if( empty($field['ID']) ) {
-
- $field['new_lines'] = 'wpautop';
-
- }
-
-
// default_value
acf_render_field_setting( $field, array(
'label' => __('Default Value','acf'),
@@ -233,7 +192,7 @@ class acf_field_textarea extends acf_field {
// initialize
-acf_register_field_type( new acf_field_textarea() );
+acf_register_field_type( 'acf_field_textarea' );
endif; // class_exists check
diff --git a/fields/time_picker.php b/includes/fields/class-acf-field-time_picker.php
similarity index 86%
rename from fields/time_picker.php
rename to includes/fields/class-acf-field-time_picker.php
index bd19505..efdaf27 100644
--- a/fields/time_picker.php
+++ b/includes/fields/class-acf-field-time_picker.php
@@ -1,16 +1,5 @@
name = 'time_picker';
@@ -40,9 +29,6 @@ class acf_field_time_picker extends acf_field {
'return_format' => 'g:i a'
);
-
- // do not delete!
- parent::__construct();
}
@@ -64,26 +50,23 @@ class acf_field_time_picker extends acf_field {
$display_value = '';
if( $field['value'] ) {
-
$display_value = acf_format_date( $field['value'], $field['display_format'] );
-
}
// vars
- $e = '';
$div = array(
'class' => 'acf-time-picker acf-input-wrap',
'data-time_format' => acf_convert_time_to_js($field['display_format'])
);
- $hidden = array(
+ $hidden_input = array(
'id' => $field['id'],
'class' => 'input-alt',
'type' => 'hidden',
'name' => $field['name'],
'value' => $field['value'],
);
- $input = array(
+ $text_input = array(
'class' => 'input',
'type' => 'text',
'value' => $display_value,
@@ -91,14 +74,13 @@ class acf_field_time_picker extends acf_field {
// html
- $e .= '
';
- $e .= ' ';
- $e .= ' ';
- $e .= '
';
+ ?>
+
>
+
+
+
+ name = 'true_false';
@@ -42,10 +31,6 @@ class acf_field_true_false extends acf_field {
'ui_on_text' => '',
'ui_off_text' => '',
);
-
-
- // do not delete!
- parent::__construct();
}
@@ -277,7 +262,7 @@ class acf_field_true_false extends acf_field {
// initialize
-acf_register_field_type( new acf_field_true_false() );
+acf_register_field_type( 'acf_field_true_false' );
endif; // class_exists check
diff --git a/fields/url.php b/includes/fields/class-acf-field-url.php
similarity index 75%
rename from fields/url.php
rename to includes/fields/class-acf-field-url.php
index 283a6e7..a0715a4 100644
--- a/fields/url.php
+++ b/includes/fields/class-acf-field-url.php
@@ -1,23 +1,12 @@
name = 'url';
@@ -39,9 +28,6 @@ class acf_field_url extends acf_field {
'placeholder' => '',
);
-
- // do not delete!
- parent::__construct();
}
@@ -61,35 +47,31 @@ class acf_field_url extends acf_field {
// vars
$atts = array();
- $o = array( 'type', 'id', 'class', 'name', 'value', 'placeholder' );
- $s = array( 'readonly', 'disabled' );
- $e = '';
+ $keys = array( 'type', 'id', 'class', 'name', 'value', 'placeholder', 'pattern' );
+ $keys2 = array( 'readonly', 'disabled' );
+ $html = '';
- // append atts
- foreach( $o as $k ) {
-
- $atts[ $k ] = $field[ $k ];
-
+ // atts
+ foreach( $keys as $k ) {
+ if( isset($field[ $k ]) ) $atts[ $k ] = $field[ $k ];
}
- // append special atts
- foreach( $s as $k ) {
-
+ // atts2
+ foreach( $keys2 as $k ) {
if( !empty($field[ $k ]) ) $atts[ $k ] = $k;
-
}
// render
- $e .= '
';
- $e .= ' ';
- $e .= '
';
+ $html .= '
';
+ $html .= ' ' . acf_get_text_input( $atts ) ;
+ $html .= '
';
// return
- echo $e;
+ echo $html;
}
@@ -176,7 +158,7 @@ class acf_field_url extends acf_field {
// initialize
-acf_register_field_type( new acf_field_url() );
+acf_register_field_type( 'acf_field_url' );
endif; // class_exists check
diff --git a/fields/user.php b/includes/fields/class-acf-field-user.php
similarity index 97%
rename from fields/user.php
rename to includes/fields/class-acf-field-user.php
index 1a4bd40..d45ea02 100644
--- a/fields/user.php
+++ b/includes/fields/class-acf-field-user.php
@@ -1,16 +1,5 @@
name = 'user';
@@ -45,10 +34,6 @@ class acf_field_user extends acf_field {
// extra
add_action('wp_ajax_acf/fields/user/query', array($this, 'ajax_query'));
add_action('wp_ajax_nopriv_acf/fields/user/query', array($this, 'ajax_query'));
-
-
- // do not delete!
- parent::__construct();
}
@@ -594,7 +579,7 @@ class acf_field_user extends acf_field {
// initialize
-acf_register_field_type( new acf_field_user() );
+acf_register_field_type( 'acf_field_user' );
endif; // class_exists check
diff --git a/fields/wysiwyg.php b/includes/fields/class-acf-field-wysiwyg.php
similarity index 97%
rename from fields/wysiwyg.php
rename to includes/fields/class-acf-field-wysiwyg.php
index bf2bdb4..da62d35 100644
--- a/fields/wysiwyg.php
+++ b/includes/fields/class-acf-field-wysiwyg.php
@@ -1,16 +1,5 @@
name = 'wysiwyg';
@@ -46,10 +35,6 @@ class acf_field_wysiwyg extends acf_field {
// add acf_the_content filters
$this->add_filters();
-
-
- // do not delete!
- parent::__construct();
}
@@ -527,7 +512,7 @@ class acf_field_wysiwyg extends acf_field {
// initialize
-acf_register_field_type( new acf_field_wysiwyg() );
+acf_register_field_type( 'acf_field_wysiwyg' );
endif; // class_exists check
diff --git a/core/field.php b/includes/fields/class-acf-field.php
similarity index 68%
rename from core/field.php
rename to includes/fields/class-acf-field.php
index 913d57e..117f019 100644
--- a/core/field.php
+++ b/includes/fields/class-acf-field.php
@@ -16,7 +16,7 @@ class acf_field {
/*
* __construct
*
- * This construcor registeres many actions and filters
+ * This function will initialize the field type
*
* @type function
* @date 5/03/2014
@@ -28,8 +28,17 @@ class acf_field {
function __construct() {
- // info
- $this->add_filter('acf/get_field_types', array($this, 'get_field_types'), 10, 1);
+ // initialize
+ $this->initialize();
+
+
+ // register info
+ acf_register_field_type_info(array(
+ 'label' => $this->label,
+ 'name' => $this->name,
+ 'category' => $this->category,
+ 'public' => $this->public
+ ));
// value
@@ -68,6 +77,26 @@ class acf_field {
}
+ /*
+ * initialize
+ *
+ * This function will initialize the field type
+ *
+ * @type function
+ * @date 27/6/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function initialize() {
+
+ /* do nothing */
+
+ }
+
+
/*
* add_filter
*
@@ -180,36 +209,6 @@ class acf_field {
}
- /*
- * get_field_types()
- *
- * This function will append the current field type to the list of available field types
- *
- * @type function
- * @since 3.6
- * @date 23/01/13
- *
- * @param $fields (array)
- * @return $fields
- */
-
- function get_field_types( $types ) {
-
- // append
- $types[ $this->name ] = array(
- 'label' => $this->label,
- 'name' => $this->name,
- 'category' => $this->category,
- 'public' => $this->public
- );
-
-
- // return
- return $types;
-
- }
-
-
/*
* validate_field
*
@@ -275,157 +274,4 @@ class acf_field {
endif; // class_exists check
-
-/*
-* acf_get_field_types
-*
-* This function will return an array containing info about all field types
-*
-* @type function
-* @date 22/10/16
-* @since 5.5.0
-*
-* @param n/a
-* @return (array)
-*/
-
-function acf_get_field_types() {
-
- // vars
- $cache_key = 'acf_get_field_types';
-
-
- // check cache
- if( acf_isset_cache($cache_key) ) return acf_get_cache($cache_key);
-
-
- // get types
- $types = apply_filters('acf/get_field_types', array());
-
-
- // update cache
- acf_set_cache($cache_key, $types);
-
-
- // return
- return $types;
-
-}
-
-
-/*
-* acf_get_grouped_field_types
-*
-* This function will return a grouped array of fields types (category => name)
-*
-* @type function
-* @date 1/10/13
-* @since 5.0.0
-*
-* @param n/a
-* @return (array)
-*/
-
-function acf_get_grouped_field_types() {
-
- // vars
- $types = array();
- $l10n = array(
- 'basic' => __('Basic', 'acf'),
- 'content' => __('Content', 'acf'),
- 'choice' => __('Choice', 'acf'),
- 'relational' => __('Relational', 'acf'),
- 'jquery' => __('jQuery', 'acf'),
- 'layout' => __('Layout', 'acf'),
- );
-
-
- // get field type information
- $types_info = acf_get_field_types();
-
-
- // loop
- foreach( $types_info as $info ) {
-
- // bail early if not public
- if( !$info['public'] ) continue;
-
-
- // vars
- $cat = $info['category'];
-
-
- // default to basic
- if( !$cat ) $cat = 'basic';
-
-
- // translate
- $cat = isset($l10n[ $cat ]) ? $l10n[ $cat ] : $cat;
-
-
- // append
- $types[ $cat ][ $info['name'] ] = $info['label'];
-
- }
-
-
- // return
- return $types;
-
-}
-
-
-/*
-* 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( $type = '' ) {
-
- // vars
- $types = acf_get_field_types();
-
-
- // bail early if doesn't exist
- if( !isset($types[ $type ]) ) return '';
-
-
- // return
- return $types[ $type ]['label'];
-
-}
-
-
-/*
-* acf_field_type_exists
-*
-* This function will check if the field_type exists
-*
-* @type function
-* @date 1/10/13
-* @since 5.0.0
-*
-* @param $type (string)
-* @return (boolean)
-*/
-
-function acf_field_type_exists( $type = '' ) {
-
- // vars
- $types = acf_get_field_types();
-
-
- // return
- return isset($types[ $type ]);
-
-}
-
?>
\ No newline at end of file
diff --git a/forms/attachment.php b/includes/forms/form-attachment.php
similarity index 100%
rename from forms/attachment.php
rename to includes/forms/form-attachment.php
diff --git a/forms/comment.php b/includes/forms/form-comment.php
similarity index 100%
rename from forms/comment.php
rename to includes/forms/form-comment.php
diff --git a/includes/forms/form-customizer.php b/includes/forms/form-customizer.php
new file mode 100644
index 0000000..83a3d4b
--- /dev/null
+++ b/includes/forms/form-customizer.php
@@ -0,0 +1,470 @@
+preview_values = array();
+ $this->preview_fields = array();
+ $this->preview_errors = array();
+
+
+ // actions
+ add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
+ add_action('customize_preview_init', array($this, 'customize_preview_init'), 1, 1);
+ add_action('customize_save', array($this, 'customize_save'), 1, 1);
+
+
+ // save
+ add_filter('widget_update_callback', array($this, 'save_widget'), 10, 4);
+
+ }
+
+
+ /*
+ * admin_enqueue_scripts
+ *
+ * This action is run after post query but before any admin script / head actions.
+ * It is a good place to register all actions.
+ *
+ * @type action (admin_enqueue_scripts)
+ * @date 26/01/13
+ * @since 3.6.0
+ *
+ * @param N/A
+ * @return N/A
+ */
+
+ function admin_enqueue_scripts() {
+
+ // validate screen
+ if( !acf_is_screen('customize') ) return;
+
+
+ // load acf scripts
+ acf_enqueue_scripts();
+
+
+ // actions
+ add_action('acf/input/admin_footer', array($this, 'admin_footer'), 1);
+
+ }
+
+
+ /*
+ * save_widget
+ *
+ * This function will hook into the widget update filter and save ACF data
+ *
+ * @type function
+ * @date 27/05/2015
+ * @since 5.2.3
+ *
+ * @param $instance (array) widget settings
+ * @param $new_instance (array) widget settings
+ * @param $old_instance (array) widget settings
+ * @param $widget (object) widget info
+ * @return $instance
+ */
+
+ function save_widget( $instance, $new_instance, $old_instance, $widget ) {
+
+ // bail ealry if not valid (customize + acf values + nonce)
+ if( !isset($_POST['wp_customize']) || !isset($new_instance['acf']) || !acf_verify_nonce('widget') ) return $instance;
+
+
+ // vars
+ $data = array(
+ 'post_id' => "widget_{$widget->id}",
+ 'values' => array(),
+ 'fields' => array()
+ );
+
+
+ // append values
+ $data['values'] = $new_instance['acf'];
+
+
+ // append fields (name => key relationship) - used later in 'acf/get_field_reference' for customizer previews
+ foreach( $data['values'] as $k => $v ) {
+
+ // get field
+ $field = acf_get_field( $k );
+
+
+ // continue if no field
+ if( !$field ) continue;
+
+
+ // update
+ $data['fields'][ $field['name'] ] = $field['key'];
+
+ }
+
+
+ // append data to instance
+ $instance['acf'] = $data;
+
+
+
+ // return
+ return $instance;
+
+ }
+
+
+ /*
+ * get_customizer_widgets
+ *
+ * This function will return an array of widget settings
+ *
+ * @type function
+ * @date 22/03/2016
+ * @since 5.3.2
+ *
+ * @param $customizer (object)
+ * @return $value (mixed)
+ */
+
+ function get_customizer_widgets( $customizer ) {
+
+ // vars
+ $widgets = array();
+ $settings = $customizer->settings();
+
+
+ // bail ealry if no settings
+ if( empty($settings) ) return false;
+
+
+ // loop over settings
+ foreach( array_keys($settings) as $i ) {
+
+ // vars
+ $setting = $settings[ $i ];
+
+
+ // bail ealry if not widget
+ if( substr($setting->id, 0, 7) !== 'widget_' ) continue;
+
+
+ // get value
+ $value = $setting->post_value();
+
+
+ // set data
+ $setting->acf = acf_maybe_get($value, 'acf');
+
+
+ // append
+ $widgets[] = $setting;
+
+ }
+
+
+ // bail ealry if no preview values
+ if( empty($widgets) ) return false;
+
+
+ // return
+ return $widgets;
+
+ }
+
+
+ /*
+ * customize_preview_init
+ *
+ * This function is called when customizer preview is initialized
+ *
+ * @type function
+ * @date 22/03/2016
+ * @since 5.3.2
+ *
+ * @param $customizer (object)
+ * @return n/a
+ */
+
+ function customize_preview_init( $customizer ) {
+
+ // get customizer settings (widgets)
+ $settings = $customizer->settings();
+
+
+ // bail ealry if no settings
+ if( empty($settings) ) return;
+
+
+ // append values
+ foreach( $settings as $setting ) {
+
+ // get $_POST value
+ $value = $setting->post_value();
+
+
+ // bail early if no acf
+ if( !isset($value['acf']) ) continue;
+
+
+ // append acf_value to preview_values
+ $this->preview_values[ $value['acf']['post_id'] ] = $value['acf']['values'];
+ $this->preview_fields[ $value['acf']['post_id'] ] = $value['acf']['fields'];
+
+ }
+
+
+ // bail ealry if no preview_values
+ if( empty($this->preview_values) ) return;
+
+
+ // add filter
+ add_filter('acf/get_field_reference', array($this, 'get_field_reference'), 10, 3);
+
+ }
+
+
+ /*
+ * get_field_reference
+ *
+ * This function will return a field_key for a given field name + post_id
+ * Normally, ACF would lookup the DB fro this connection, but a new preview widget has not yet saved anything to the DB
+ *
+ * @type function
+ * @date 12/05/2016
+ * @since 5.3.8
+ *
+ * @param $field_key (string)
+ * @param $field_name (string)
+ * @param $post_id (mixed)
+ * @return $field_key
+ */
+
+ function get_field_reference( $field_key, $field_name, $post_id ) {
+
+ // look for reference
+ if( isset($this->preview_fields[ $post_id ][ $field_name ]) ) {
+
+ // update key
+ $field_key = $this->preview_fields[ $post_id ][ $field_name ];
+ $field_value = $this->preview_values[ $post_id ][ $field_key ];
+
+
+ // cache value
+ acf_set_cache("get_value/post_id={$post_id}/name={$field_name}", $field_value);
+
+ }
+
+
+ // return
+ return $field_key;
+
+ }
+
+
+ /*
+ * customize_save
+ *
+ * This function is called when customizer saves a widget.
+ * Normally, the widget_update_callback filter would be used, but the customizer disables this and runs a custom action
+ * class-customizer-settings.php will save the widget data via the function set_root_value which uses update_option
+ *
+ * @type function
+ * @date 22/03/2016
+ * @since 5.3.2
+ *
+ * @param $customizer (object)
+ * @return n/a
+ */
+
+ function customize_save( $customizer ) {
+
+ // get customizer settings (widgets)
+ $settings = $customizer->settings();
+
+
+ // bail ealry if no settings
+ if( empty($settings) ) return;
+
+
+ // append values
+ foreach( $settings as $setting ) {
+
+ // get $_POST value
+ $value = $setting->post_value();
+
+
+ // bail early if no acf
+ if( !isset($value['acf']) ) continue;
+
+
+ // save acf data
+ acf_save_post( $value['acf']['post_id'], $value['acf']['values'] );
+
+
+ // remove [acf] data from saved widget array
+ $id_data = $setting->id_data();
+ add_filter('pre_update_option_' . $id_data['base'], array($this, 'pre_update_option'), 10, 3);
+
+ }
+
+ }
+
+
+ /*
+ * pre_update_option
+ *
+ * this function will remove the [acf] data from widget insance
+ *
+ * @type function
+ * @date 22/03/2016
+ * @since 5.3.2
+ *
+ * @param $post_id (int)
+ * @return $post_id (int)
+ */
+
+ function pre_update_option( $value, $option, $old_value ) {
+
+ // bail ealry if no value
+ if( empty($value) ) return $value;
+
+
+ // loop over widgets
+ // WP saves all widgets (of the same type) as an array of widgets
+ foreach( $value as $i => $widget ) {
+
+ // bail ealry if no acf
+ if( !isset($widget['acf']) ) continue;
+
+
+ // remove widget
+ unset($value[ $i ]['acf']);
+
+ }
+
+
+ // return
+ return $value;
+
+ }
+
+
+ /*
+ * admin_footer
+ *
+ * This function will add some custom HTML to the footer of the edit page
+ *
+ * @type function
+ * @date 11/06/2014
+ * @since 5.0.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function admin_footer() {
+
+?>
+
+
\ No newline at end of file
diff --git a/core/form.php b/includes/forms/form-front.php
similarity index 95%
rename from core/form.php
rename to includes/forms/form-front.php
index e846a68..3b0bf59 100644
--- a/core/form.php
+++ b/includes/forms/form-front.php
@@ -2,13 +2,15 @@
if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
-if( ! class_exists('acf_form') ) :
+if( ! class_exists('acf_form_front') ) :
-class acf_form {
+class acf_form_front {
- // vars
- var $forms = array(),
- $fields = array();
+ /** @var array An array of registered form settings */
+ private $forms = array();
+
+ /** @var array An array of default fields */
+ public $fields = array();
/*
@@ -357,7 +359,7 @@ class acf_form {
function check_submit_form() {
// bail ealry if form not submit
- if( !isset($_POST['_acfform']) ) return;
+ if( !isset($_POST['_acf_form']) ) return;
// verify nonce
@@ -390,7 +392,7 @@ class acf_form {
function submit_form() {
// vars
- $form = @json_decode(acf_decrypt($_POST['_acfform']), true);
+ $form = @json_decode(acf_decrypt($_POST['_acf_form']), true);
// bail ealry if form is corrupt
@@ -610,7 +612,7 @@ class acf_form {
acf_form_data(array(
'post_id' => $args['post_id'],
'nonce' => 'acf_form',
- '_acfform' => acf_encrypt(json_encode($args))
+ 'form' => acf_encrypt(json_encode($args))
));
?>
@@ -651,7 +653,7 @@ class acf_form {
}
// initialize
-acf()->form = new acf_form();
+acf()->form_front = new acf_form_front();
endif; // class_exists check
@@ -672,25 +674,25 @@ endif; // class_exists check
function acf_form_head() {
- acf()->form->enqueue_form();
+ acf()->form_front->enqueue_form();
}
function acf_form( $args = array() ) {
- acf()->form->render_form( $args );
+ acf()->form_front->render_form( $args );
}
function acf_get_form( $id = '' ) {
- acf()->form->get_form( $id );
+ acf()->form_front->get_form( $id );
}
function acf_register_form( $args ) {
- acf()->form->add_form( $args );
+ acf()->form_front->add_form( $args );
}
diff --git a/includes/forms/form-nav-menu.php b/includes/forms/form-nav-menu.php
new file mode 100644
index 0000000..24b094c
--- /dev/null
+++ b/includes/forms/form-nav-menu.php
@@ -0,0 +1,285 @@
+update_nav_menu_items( $menu_id );
+
+ }
+
+
+ /*
+ * update_nav_menu_items
+ *
+ * description
+ *
+ * @type function
+ * @date 26/5/17
+ * @since 5.6.0
+ *
+ * @param $post_id (int)
+ * @return $post_id (int)
+ */
+
+ function update_nav_menu_items( $menu_id ) {
+
+ // bail ealry if not set
+ if( empty($_POST['menu-item-acf']) ) return;
+
+
+ // loop
+ foreach( $_POST['menu-item-acf'] as $post_id => $values ) {
+
+ acf_save_post( $post_id, $values );
+
+ }
+
+ }
+
+
+ /*
+ * wp_edit_nav_menu_walker
+ *
+ * description
+ *
+ * @type function
+ * @date 26/5/17
+ * @since 5.6.0
+ *
+ * @param $post_id (int)
+ * @return $post_id (int)
+ */
+
+ function wp_edit_nav_menu_walker( $class, $menu_id = 0 ) {
+
+ // global
+ global $acf_menu;
+
+
+ // set var
+ $acf_menu = $menu_id;
+
+
+ // include walker
+ if( class_exists('Walker_Nav_Menu_Edit') ) {
+ acf_include('includes/walkers/class-acf-walker-nav-menu-edit.php');
+ }
+
+
+ // return
+ return 'ACF_Walker_Nav_Menu_Edit';
+
+ }
+
+
+ /*
+ * acf_validate_save_post
+ *
+ * This function will loop over $_POST data and validate
+ *
+ * @type action 'acf/validate_save_post' 5
+ * @date 7/09/2016
+ * @since 5.4.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function acf_validate_save_post() {
+
+ // bail ealry if not set
+ if( empty($_POST['menu-item-acf']) ) return;
+
+
+ // loop
+ foreach( $_POST['menu-item-acf'] as $post_id => $values ) {
+
+ // vars
+ $prefix = 'menu-item-acf['.$post_id.']';
+
+
+ // validate
+ acf_validate_values( $values, $prefix );
+
+ }
+
+ }
+
+
+ /*
+ * admin_footer
+ *
+ * This function will add some custom HTML to the footer of the edit page
+ *
+ * @type function
+ * @date 11/06/2014
+ * @since 5.0.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function admin_footer() {
+
+ // global
+ global $acf_menu;
+
+
+ // vars
+ $post_id = acf_get_term_post_id( 'nav_menu', $acf_menu );
+
+
+ // get field groups
+ $field_groups = acf_get_field_groups(array(
+ 'nav_menu' => $acf_menu
+ ));
+
+
+?>
+
+
+
\ No newline at end of file
diff --git a/forms/post.php b/includes/forms/form-post.php
similarity index 93%
rename from forms/post.php
rename to includes/forms/form-post.php
index 8636dc7..febefa9 100644
--- a/forms/post.php
+++ b/includes/forms/form-post.php
@@ -479,7 +479,7 @@ if( typeof acf !== 'undefined' ) {
function wp_insert_post_empty_content( $maybe_empty, $postarr ) {
- if( $maybe_empty && !empty($_POST['_acfchanged']) ) {
+ if( $maybe_empty && acf_maybe_get_POST('_acf_changed') ) {
$maybe_empty = false;
@@ -508,18 +508,31 @@ if( typeof acf !== 'undefined' ) {
// vars
$allow = true;
- $reject = array( 'auto-draft', 'revision', 'acf-field', 'acf-field-group' );
- $wp_preview = acf_maybe_get($_POST, 'wp-preview');
- // check post type
- if( in_array($post->post_type, $reject) ) $allow = false;
+ // disallow if is post type
+ $post_types = array( 'auto-draft', 'revision', 'acf-field', 'acf-field-group' );
+ if( in_array($post->post_type, $post_types) ) $allow = false;
- // allow preview
- if( $post->post_type == 'revision' && $wp_preview == 'dopreview' ) $allow = true;
+ // disallow if not the form post
+ $form_post_id = (int) acf_maybe_get_POST('post_ID');
+ if( $form_post_id && $form_post_id !== $post->ID ) $allow = false;
+ // revision (preview)
+ if( $post->post_type == 'revision' ) {
+
+ // allow if doing preview
+ if( acf_maybe_get_POST('wp-preview') == 'dopreview' ) $allow = true;
+
+
+ // disallow if not a revision of the form post
+ if( $form_post_id && $form_post_id !== $post->post_parent ) $allow = false;
+
+ }
+
+
// return
return $allow;
@@ -545,8 +558,8 @@ if( typeof acf !== 'undefined' ) {
if( !$this->allow_save_post($post) ) return $post_id;
- // ensure saving to the correct post
- if( !acf_verify_nonce('post', $post_id) ) return $post_id;
+ // verify nonce
+ if( !acf_verify_nonce('post') ) return $post_id;
// validate for published post (allow draft to save without validation)
diff --git a/forms/taxonomy.php b/includes/forms/form-taxonomy.php
similarity index 100%
rename from forms/taxonomy.php
rename to includes/forms/form-taxonomy.php
diff --git a/forms/user.php b/includes/forms/form-user.php
similarity index 100%
rename from forms/user.php
rename to includes/forms/form-user.php
diff --git a/includes/forms/form-widget.php b/includes/forms/form-widget.php
new file mode 100644
index 0000000..3d8c483
--- /dev/null
+++ b/includes/forms/form-widget.php
@@ -0,0 +1,385 @@
+preview_values = array();
+ $this->preview_reference = array();
+ $this->preview_errors = array();
+
+
+ // actions
+ add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
+ add_action('in_widget_form', array($this, 'edit_widget'), 10, 3);
+ add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5);
+
+
+ // filters
+ add_filter('widget_update_callback', array($this, 'save_widget'), 10, 4);
+
+ }
+
+
+ /*
+ * admin_enqueue_scripts
+ *
+ * This action is run after post query but before any admin script / head actions.
+ * It is a good place to register all actions.
+ *
+ * @type action (admin_enqueue_scripts)
+ * @date 26/01/13
+ * @since 3.6.0
+ *
+ * @param N/A
+ * @return N/A
+ */
+
+ function admin_enqueue_scripts() {
+
+ // validate screen
+ if( acf_is_screen('widgets') || acf_is_screen('customize') ) {
+
+ // valid
+
+ } else {
+
+ return;
+
+ }
+
+
+ // load acf scripts
+ acf_enqueue_scripts();
+
+
+ // actions
+ add_action('acf/input/admin_footer', array($this, 'admin_footer'), 1);
+
+ }
+
+
+ /*
+ * acf_validate_save_post
+ *
+ * This function will loop over $_POST data and validate
+ *
+ * @type action 'acf/validate_save_post' 5
+ * @date 7/09/2016
+ * @since 5.4.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function acf_validate_save_post() {
+
+ // bai lealry if not widget
+ if( !isset($_POST['_acf_widget_id']) ) return;
+
+
+ // vars
+ $id = $_POST['_acf_widget_id'];
+ $number = $_POST['_acf_widget_number'];
+ $prefix = $_POST['_acf_widget_prefix'];
+
+
+ // validate
+ acf_validate_values( $_POST[ $id ][ $number ]['acf'], $prefix );
+
+ }
+
+
+ /*
+ * edit_widget
+ *
+ * This function will render the fields for a widget form
+ *
+ * @type function
+ * @date 11/06/2014
+ * @since 5.0.0
+ *
+ * @param $widget (object)
+ * @param $return (null)
+ * @param $instance (object)
+ * @return $post_id (int)
+ */
+
+ function edit_widget( $widget, $return, $instance ) {
+
+ // vars
+ $post_id = 0;
+ $prefix = 'widget-' . $widget->id_base . '[' . $widget->number . '][acf]';
+
+
+ // get id
+ if( $widget->number !== '__i__' ) {
+
+ $post_id = "widget_{$widget->id}";
+
+ }
+
+
+ // get field groups
+ $field_groups = acf_get_field_groups(array(
+ 'widget' => $widget->id_base
+ ));
+
+
+ // render
+ if( !empty($field_groups) ) {
+
+ // render post data
+ acf_form_data(array(
+ 'post_id' => $post_id,
+ 'nonce' => 'widget',
+ 'widget_id' => 'widget-' . $widget->id_base,
+ 'widget_number' => $widget->number,
+ 'widget_prefix' => $prefix
+ ));
+
+
+ // loop
+ foreach( $field_groups as $field_group ) {
+
+ // load fields
+ $fields = acf_get_fields( $field_group );
+
+
+ // bail if not fields
+ if( empty($fields) ) continue;
+
+
+ // change prefix
+ foreach( $fields as &$field ) $field['prefix'] = $prefix;
+
+
+ // render
+ acf_render_fields( $post_id, $fields, 'div', $field_group['instruction_placement'] );
+
+ }
+
+
+ // jQuery selector looks odd, but is necessary due to WP adding an incremental number into the ID
+ // - not possible to find number via PHP parameters
+ if( $widget->updated ): ?>
+
+ id}", $new_instance['acf'] );
+
+
+ // return
+ return $instance;
+
+ }
+
+
+ /*
+ * admin_footer
+ *
+ * This function will add some custom HTML to the footer of the edit page
+ *
+ * @type function
+ * @date 11/06/2014
+ * @since 5.0.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function admin_footer() {
+
+?>
+
+
\ No newline at end of file
diff --git a/core/input.php b/includes/input.php
similarity index 90%
rename from core/input.php
rename to includes/input.php
index db9df89..3bed9d5 100644
--- a/core/input.php
+++ b/includes/input.php
@@ -31,7 +31,7 @@ class acf_input {
// actions
- add_action('acf/save_post', array($this, 'save_post'), 10, 1);
+ add_action('acf/save_post', array($this, 'save_post'), 10, 2);
}
@@ -90,6 +90,7 @@ class acf_input {
'nonce' => 'post', // nonce used for $_POST validation
'validation' => 1, // runs AJAX validation
'ajax' => 0, // fetches new field groups via AJAX
+ 'changed' => 0,
));
@@ -261,7 +262,11 @@ class acf_input {
'validation_failed' => __('Validation failed', 'acf'),
'validation_failed_1' => __('1 field requires attention', 'acf'),
'validation_failed_2' => __('%d fields require attention', 'acf'),
- 'restricted' => __('Restricted','acf')
+ 'restricted' => __('Restricted','acf'),
+ 'yes' => __('Yes','acf'),
+ 'no' => __('No','acf'),
+ 'remove' => __('Remove','acf'),
+ 'cancel' => __('Cancel','acf')
));
@@ -302,14 +307,10 @@ do_action('acf/input/admin_footer');
* @return n/a
*/
- function save_post( $post_id ) {
+ function save_post( $post_id, $values ) {
- // bail early if empty
- if( empty($_POST['acf']) ) return;
-
-
- // save $_POST data
- foreach( $_POST['acf'] as $k => $v ) {
+ // loop
+ foreach( $values as $k => $v ) {
// get field
$field = acf_get_field( $k );
@@ -457,24 +458,13 @@ function acf_form_data( $args = array() ) {
// hidden inputs
- $inputs = array(
- '_acfnonce' => wp_create_nonce($args['nonce']),
- '_acfchanged' => 0
- );
-
-
- // append custom
- foreach( $args as $k => $v ) {
-
- if( substr($k, 0, 4) === '_acf' ) $inputs[ $k ] = $v;
-
- }
-
+ $inputs = $args;
+ $inputs['nonce'] = wp_create_nonce($inputs['nonce']);
?>
$v ): ?>
-
+
@@ -496,10 +486,15 @@ function acf_form_data( $args = array() ) {
* @return $post_id (int)
*/
-function acf_save_post( $post_id = 0 ) {
+function acf_save_post( $post_id = 0, $values = null ) {
- // bail early if no acf values
- if( empty($_POST['acf']) ) return false;
+ // default
+ if( $values === null )
+ $values = acf_maybe_get_POST('acf');
+
+
+ // bail early if no values
+ if( empty($values) ) return false;
// set form data
@@ -509,7 +504,7 @@ function acf_save_post( $post_id = 0 ) {
// hook for 3rd party customization
- do_action('acf/save_post', $post_id);
+ do_action('acf/save_post', $post_id, $values);
// return
diff --git a/core/json.php b/includes/json.php
similarity index 100%
rename from core/json.php
rename to includes/json.php
diff --git a/core/local.php b/includes/local.php
similarity index 100%
rename from core/local.php
rename to includes/local.php
diff --git a/includes/locations.php b/includes/locations.php
new file mode 100644
index 0000000..3998709
--- /dev/null
+++ b/includes/locations.php
@@ -0,0 +1,356 @@
+locations[ $instance->name ] = $instance;
+
+ }
+
+
+ /*
+ * get_rule
+ *
+ * This function will return a location rule class
+ *
+ * @type function
+ * @date 6/07/2016
+ * @since 5.4.0
+ *
+ * @param $name (string)
+ * @return (mixed)
+ */
+
+ function get_location( $name ) {
+
+ return isset( $this->locations[$name] ) ? $this->locations[$name] : null;
+
+ }
+
+
+ /*
+ * get_rules
+ *
+ * This function will return a grouped array of location rules (category => name => label)
+ *
+ * @type function
+ * @date 6/07/2016
+ * @since 5.4.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function get_locations() {
+
+ // vars
+ $groups = array();
+ $l10n = array(
+ 'post' => __('Post', 'acf'),
+ 'page' => __('Page', 'acf'),
+ 'user' => __('User', 'acf'),
+ 'forms' => __('Forms', 'acf'),
+ );
+
+
+ // loop
+ foreach( $this->locations as $location ) {
+
+ // bail ealry if not public
+ if( !$location->public ) continue;
+
+
+ // translate
+ $cat = $location->category;
+ $cat = isset( $l10n[$cat] ) ? $l10n[$cat] : $cat;
+
+
+ // append
+ $groups[ $cat ][ $location->name ] = $location->label;
+
+ }
+
+
+ // filter
+ $groups = apply_filters('acf/location/rule_types', $groups);
+
+
+ // return
+ return $groups;
+
+ }
+
+}
+
+// initialize
+acf()->locations = new acf_locations();
+
+endif; // class_exists check
+
+
+/*
+* acf_register_location_rule
+*
+* alias of acf()->locations->register_location()
+*
+* @type function
+* @date 31/5/17
+* @since 5.6.0
+*
+* @param n/a
+* @return n/a
+*/
+
+function acf_register_location_rule( $class ) {
+
+ return acf()->locations->register_location( $class );
+
+}
+
+
+/*
+* acf_get_location_rule
+*
+* alias of acf()->locations->get_location()
+*
+* @type function
+* @date 31/5/17
+* @since 5.6.0
+*
+* @param n/a
+* @return n/a
+*/
+
+function acf_get_location_rule( $name ) {
+
+ return acf()->locations->get_location( $name );
+
+}
+
+
+/*
+* acf_get_location_rule_types
+*
+* alias of acf()->locations->get_locations()
+*
+* @type function
+* @date 31/5/17
+* @since 5.6.0
+*
+* @param n/a
+* @return n/a
+*/
+
+function acf_get_location_rule_types() {
+
+ return acf()->locations->get_locations();
+
+}
+
+
+/*
+* acf_get_valid_location_rule
+*
+* This function will return a valid location rule array
+*
+* @type function
+* @date 30/5/17
+* @since 5.6.0
+*
+* @param $rule (array)
+* @return (array)
+*/
+
+function acf_get_valid_location_rule( $rule ) {
+
+ // defaults
+ $rule = wp_parse_args( $rule, array(
+ 'id' => '',
+ 'group' => '',
+ 'param' => '',
+ 'operator' => '==',
+ 'value' => '',
+ ));
+
+
+ // prefix for inputs
+ $rule['prefix'] = 'acf_field_group[location]['.$rule['group'].']['.$rule['id'].']';
+
+
+ // return
+ return $rule;
+
+}
+
+
+/*
+* acf_get_location_rule_operators
+*
+* This function will return the operators for a given rule
+*
+* @type function
+* @date 30/5/17
+* @since 5.6.0
+*
+* @param $rule (array)
+* @return (array)
+*/
+
+function acf_get_location_rule_operators( $rule ) {
+
+ // vars
+ $operators = array(
+ '==' => __("is equal to",'acf'),
+ '!=' => __("is not equal to",'acf'),
+ );
+
+
+ // filter
+ $operators = apply_filters( "acf/location/rule_operators/{$rule['param']}", $operators, $rule );
+ $operators = apply_filters( "acf/location/rule_operators", $operators, $rule );
+
+
+ // return
+ return $operators;
+
+}
+
+
+/*
+* acf_get_location_rule_values
+*
+* This function will return the values for a given rule
+*
+* @type function
+* @date 30/5/17
+* @since 5.6.0
+*
+* @param $rule (array)
+* @return (array)
+*/
+
+function acf_get_location_rule_values( $rule ) {
+
+ // vars
+ $values = array();
+
+
+ // filter
+ $values = apply_filters( "acf/location/rule_values/{$rule['param']}", $values, $rule );
+ $values = apply_filters( "acf/location/rule_values", $values, $rule );
+
+
+ // return
+ return $values;
+
+}
+
+
+/*
+* acf_match_location_rule
+*
+* This function will match a given rule to the $screen
+*
+* @type function
+* @date 30/5/17
+* @since 5.6.0
+*
+* @param $rule (array)
+* @param $screen (array)
+* @return (boolean)
+*/
+
+function acf_match_location_rule( $rule, $screen ) {
+
+ // vars
+ $result = false;
+
+
+ // filter
+ $result = apply_filters( "acf/location/rule_match/{$rule['param']}", $result, $rule, $screen );
+ $result = apply_filters( "acf/location/rule_match", $result, $rule, $screen );
+
+
+ // return
+ return $result;
+
+}
+
+
+/*
+* acf_get_location_screen
+*
+* This function will return a valid location screen array
+*
+* @type function
+* @date 30/5/17
+* @since 5.6.0
+*
+* @param $screen (array)
+* @param $field_group (array)
+* @return (array)
+*/
+
+function acf_get_location_screen( $screen, $field_group ) {
+
+ // vars
+ $screen = wp_parse_args($screen, array(
+ 'lang' => acf_get_setting('current_language'),
+ 'ajax' => false
+ ));
+
+
+ // filter for 3rd party customization
+ $screen = apply_filters('acf/location/screen', $screen, $field_group);
+
+
+ // return
+ return $screen;
+
+}
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-attachment.php b/includes/locations/class-acf-location-attachment.php
new file mode 100644
index 0000000..9abb20d
--- /dev/null
+++ b/includes/locations/class-acf-location-attachment.php
@@ -0,0 +1,127 @@
+name = 'attachment';
+ $this->label = __("Attachment",'acf');
+ $this->category = 'forms';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $attachment = acf_maybe_get( $screen, 'attachment' );
+
+
+ // validate
+ if( !$attachment ) return false;
+
+
+ // get attachment mime type
+ $mime_type = get_post_mime_type( $attachment );
+
+
+ // no specific mime
+ if( !strpos($rule['value'], '/') ) {
+
+ // explode into [0] => type, [1] => mime
+ $bits = explode('/', $mime_type);
+
+
+ // if type matches, fake the $mime_type to match
+ if( $rule['value'] === $bits[0] ) {
+
+ $mime_type = $rule['value'];
+
+ }
+ }
+
+
+ // match
+ return $this->compare( $mime_type, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // vars
+ $mimes = get_allowed_mime_types();
+ $choices = array(
+ 'all' => __('All', 'acf')
+ );
+
+
+ // loop
+ foreach( $mimes as $type => $mime ) {
+
+ $group = current( explode('/', $mime) );
+ $choices[ $group ][ $group ] = sprintf( __('All %s formats', 'acf'), $group);
+ $choices[ $group ][ $mime ] = "$type ($mime)";
+
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_attachment' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-comment.php b/includes/locations/class-acf-location-comment.php
new file mode 100644
index 0000000..b4a353e
--- /dev/null
+++ b/includes/locations/class-acf-location-comment.php
@@ -0,0 +1,95 @@
+name = 'comment';
+ $this->label = __("Comment",'acf');
+ $this->category = 'forms';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $comment = acf_maybe_get( $screen, 'comment' );
+
+
+ // bail early if not comment
+ if( !$comment ) return false;
+
+
+ // return
+ return $this->compare( $comment, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // vars
+ $choices = array( 'all' => __('All', 'acf') );
+ $choices = array_merge( $choices, acf_get_pretty_post_types() );
+ // change this to post types that support comments
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_comment' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-current-user-role.php b/includes/locations/class-acf-location-current-user-role.php
new file mode 100644
index 0000000..8cc38d5
--- /dev/null
+++ b/includes/locations/class-acf-location-current-user-role.php
@@ -0,0 +1,128 @@
+name = 'current_user_role';
+ $this->label = __("Current User Role",'acf');
+ $this->category = 'user';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // bail early if not logged in
+ if( !is_user_logged_in() ) return false;
+
+
+ // vars
+ $user = wp_get_current_user();
+
+
+ // super_admin
+ if( $rule['value'] == 'super_admin' ) {
+
+ $result = is_super_admin( $user->ID );
+
+ // role
+ } else {
+
+ $result = in_array( $rule['value'], $user->roles );
+
+ }
+
+
+ // reverse if 'not equal to'
+ if( $rule['operator'] == '!=' ) {
+
+ $result = !$result;
+
+ }
+
+
+ // return
+ return $result;
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // global
+ global $wp_roles;
+
+
+ // specific roles
+ $choices = $wp_roles->get_names();
+
+
+ // multi-site
+ if( is_multisite() ) {
+
+ $prepend = array( 'super_admin' => __('Super Admin', 'acf') );
+ $choices = array_merge( $prepend, $choices );
+
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_current_user_role' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-current-user.php b/includes/locations/class-acf-location-current-user.php
new file mode 100644
index 0000000..c6753c3
--- /dev/null
+++ b/includes/locations/class-acf-location-current-user.php
@@ -0,0 +1,111 @@
+name = 'current_user';
+ $this->label = __("Current User",'acf');
+ $this->category = 'user';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // logged in
+ if( $rule['value'] == 'logged_in' ) {
+
+ $result = is_user_logged_in();
+
+ // viewing_front
+ } elseif( $rule['value'] == 'viewing_front' ) {
+
+ $result = !is_admin();
+
+ // viewing_back
+ } elseif( $rule['value'] == 'viewing_back' ) {
+
+ $result = is_admin();
+
+ }
+
+
+ // reverse if 'not equal to'
+ if( $rule['operator'] == '!=' ) {
+
+ $result = !$result;
+
+ }
+
+
+ // return
+ return $result;
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ return array(
+ 'logged_in' => __('Logged in', 'acf'),
+ 'viewing_front' => __('Viewing front end', 'acf'),
+ 'viewing_back' => __('Viewing back end', 'acf')
+ );
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_current_user' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-nav-menu-item.php b/includes/locations/class-acf-location-nav-menu-item.php
new file mode 100644
index 0000000..302db63
--- /dev/null
+++ b/includes/locations/class-acf-location-nav-menu-item.php
@@ -0,0 +1,106 @@
+name = 'nav_menu_item';
+ $this->label = __("Menu Item",'acf');
+ $this->category = 'forms';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $nav_menu_item = acf_maybe_get( $screen, 'nav_menu_item' );
+
+
+ // bail early if not nav_menu_item
+ if( !$nav_menu_item ) return false;
+
+
+ // global
+ global $acf_menu;
+
+
+ // append nav_menu data
+ $screen['nav_menu'] = $acf_menu;
+
+
+ // return
+ return acf_get_location_rule('nav_menu')->rule_match( $result, $rule, $screen );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // get menu choices
+ $choices = acf_get_location_rule('nav_menu')->rule_values( $choices, $rule );
+
+
+ // append item types?
+ // dificult to get these details
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_nav_menu_item' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-nav-menu.php b/includes/locations/class-acf-location-nav-menu.php
new file mode 100644
index 0000000..a25543a
--- /dev/null
+++ b/includes/locations/class-acf-location-nav-menu.php
@@ -0,0 +1,138 @@
+name = 'nav_menu';
+ $this->label = __("Menu",'acf');
+ $this->category = 'forms';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $nav_menu = acf_maybe_get( $screen, 'nav_menu' );
+
+
+ // bail early if not nav_menu
+ if( !$nav_menu ) return false;
+
+
+ // location
+ if( substr($rule['value'], 0, 9) === 'location/' ) {
+
+ // vars
+ $location = substr($rule['value'], 9);
+ $menu_locations = get_nav_menu_locations();
+
+
+ // bail ealry if no location
+ if( !isset($menu_locations[$location]) ) return false;
+
+
+ // if location matches, update value
+ if( $menu_locations[$location] === $nav_menu ) {
+
+ $nav_menu = $rule['value'];
+
+ }
+
+ }
+
+
+ // return
+ return $this->compare( $nav_menu, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // all
+ $choices = array(
+ 'all' => __('All', 'acf'),
+ );
+
+
+ // locations
+ $nav_locations = get_registered_nav_menus();
+ if( !empty($nav_locations) ) {
+ $cat = __('Menu Locations', 'acf');
+ foreach( $nav_locations as $slug => $title ) {
+ $choices[ $cat ][ 'location/'.$slug ] = $title;
+ }
+ }
+
+
+ // specific menus
+ $nav_menus = wp_get_nav_menus();
+ if( !empty($nav_menus) ) {
+ $cat = __('Menus', 'acf');
+ foreach( $nav_menus as $nav_menu ) {
+ $choices[ $cat ][ $nav_menu->term_id ] = $nav_menu->name;
+ }
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_nav_menu' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-page-parent.php b/includes/locations/class-acf-location-page-parent.php
new file mode 100644
index 0000000..8420dfa
--- /dev/null
+++ b/includes/locations/class-acf-location-page-parent.php
@@ -0,0 +1,100 @@
+name = 'page_parent';
+ $this->label = __("Page Parent",'acf');
+ $this->category = 'page';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $page_parent = acf_maybe_get( $screen, 'page_parent' );
+
+
+ // no page parent
+ if( $page_parent === null ) {
+
+ // bail early if no post id
+ if( !$post_id ) return false;
+
+
+ // get post parent
+ $post = get_post( $post_id );
+ $page_parent = $post->post_parent;
+
+ }
+
+
+ // compare
+ return $this->compare( $page_parent, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ return acf_get_location_rule('page')->rule_values( $choices, $rule );
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_page_parent' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-page-template.php b/includes/locations/class-acf-location-page-template.php
new file mode 100644
index 0000000..6b384f7
--- /dev/null
+++ b/includes/locations/class-acf-location-page-template.php
@@ -0,0 +1,119 @@
+name = 'page_template';
+ $this->label = __("Page Template",'acf');
+ $this->category = 'page';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_type = acf_maybe_get( $screen, 'post_type' );
+
+
+ // lookup post_type
+ if( !$post_type ) {
+
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+
+ if( !$post_id ) return false;
+
+ $post_type = get_post_type( $post_id );
+
+ }
+
+
+ // page template 'default' rule is only for 'page' post type
+ // prevents 'Default Template' field groups appearing on all post types that allow for post templates (WP 4.7)
+ if( $rule['value'] === 'default' ) {
+
+ // bail ealry if not page
+ if( $post_type !== 'page' ) return false;
+
+ }
+
+
+ // return
+ return acf_get_location_rule('post_template')->rule_match( $result, $rule, $screen );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // vars
+ $choices = array(
+ 'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') )
+ );
+
+
+ // get templates and merge them in
+ $templates = wp_get_theme()->get_page_templates();
+ $choices = array_merge($choices, $templates);
+
+
+ // return choices
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_page_template' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-page-type.php b/includes/locations/class-acf-location-page-type.php
new file mode 100644
index 0000000..6822039
--- /dev/null
+++ b/includes/locations/class-acf-location-page-type.php
@@ -0,0 +1,161 @@
+name = 'page_type';
+ $this->label = __("Page Type",'acf');
+ $this->category = 'page';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+
+
+ // bail early if no post id
+ if( !$post_id ) return false;
+
+
+ // get post
+ $post = get_post( $post_id );
+
+
+ // compare
+ if( $rule['value'] == 'front_page') {
+
+ // vars
+ $front_page = (int) get_option('page_on_front');
+
+
+ // compare
+ $match = ( $front_page === $post->ID );
+
+ } elseif( $rule['value'] == 'posts_page') {
+
+ // vars
+ $posts_page = (int) get_option('page_for_posts');
+
+
+ // compare
+ $match = ( $posts_page === $post->ID );
+
+ } elseif( $rule['value'] == 'top_level') {
+
+ // vars
+ $page_parent = acf_maybe_get( $screen, 'page_parent', $post->post_parent );
+
+
+ // compare
+ $match = ( $page_parent == 0 );
+
+ } elseif( $rule['value'] == 'parent' ) {
+
+ // get children
+ $children = get_posts(array(
+ 'post_type' => $post->post_type,
+ 'post_parent' => $post->ID,
+ 'posts_per_page' => 1,
+ 'fields' => 'ids',
+ ));
+
+
+ // compare
+ $match = !empty( $children );
+
+ } elseif( $rule['value'] == 'child') {
+
+ // vars
+ $page_parent = acf_maybe_get( $screen, 'page_parent', $post->post_parent );
+
+
+ // compare
+ $match = ( $page_parent > 0 );
+
+ }
+
+
+ // reverse if 'not equal to'
+ if( $rule['operator'] === '!=' ) {
+
+ $match = !$match;
+
+ }
+
+
+ // return
+ return $match;
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ return array(
+ 'front_page' => __("Front Page",'acf'),
+ 'posts_page' => __("Posts Page",'acf'),
+ 'top_level' => __("Top Level Page (no parent)",'acf'),
+ 'parent' => __("Parent Page (has children)",'acf'),
+ 'child' => __("Child Page (has parent)",'acf'),
+ );
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_page_type' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-page.php b/includes/locations/class-acf-location-page.php
new file mode 100644
index 0000000..732fee9
--- /dev/null
+++ b/includes/locations/class-acf-location-page.php
@@ -0,0 +1,99 @@
+name = 'page';
+ $this->label = __("Page",'acf');
+ $this->category = 'page';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ return acf_get_location_rule('post')->rule_match( $result, $rule, $screen );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // get posts grouped by post type
+ $groups = acf_get_grouped_posts(array(
+ 'post_type' => 'page'
+ ));
+
+
+ // pop
+ $choices = array_pop( $groups );
+
+
+ // convert posts to titles
+ foreach( $choices as &$item ) {
+
+ $item = acf_get_post_title( $item );
+
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_page' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post-category.php b/includes/locations/class-acf-location-post-category.php
new file mode 100644
index 0000000..a88146a
--- /dev/null
+++ b/includes/locations/class-acf-location-post-category.php
@@ -0,0 +1,88 @@
+name = 'post_category';
+ $this->label = __("Post Category",'acf');
+ $this->category = 'post';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ return acf_get_location_rule('post_taxonomy')->rule_match( $result, $rule, $screen );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ $terms = acf_get_taxonomy_terms( 'category' );
+
+ if( !empty($terms) ) {
+
+ $choices = array_pop($terms);
+
+ }
+
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post_category' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post-format.php b/includes/locations/class-acf-location-post-format.php
new file mode 100644
index 0000000..0508533
--- /dev/null
+++ b/includes/locations/class-acf-location-post-format.php
@@ -0,0 +1,143 @@
+name = 'post_format';
+ $this->label = __("Post Format",'acf');
+ $this->category = 'post';
+
+ }
+
+
+ /*
+ * get_post_type
+ *
+ * This function will return the current post_type
+ *
+ * @type function
+ * @date 25/11/16
+ * @since 5.5.0
+ *
+ * @param $options (int)
+ * @return (mixed)
+ */
+
+ function get_post_type( $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $post_type = acf_maybe_get( $screen, 'post_type' );
+
+
+ // post_type
+ if( $post_type ) return $post_type;
+
+
+ // $post_id
+ if( $post_id ) return get_post_type( $post_id );
+
+
+ // return
+ return false;
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_format = acf_maybe_get( $screen, 'post_format' );
+
+
+ // find post format
+ if( !$post_format ) {
+
+ // get post id
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $post_type = $this->get_post_type( $screen );
+
+
+ // bail early if not a post
+ if( !$post_id || !$post_type ) return false;
+
+
+ // does post_type support 'post-format'
+ if( post_type_supports($post_type, 'post-formats') ) {
+
+ // update
+ $post_format = get_post_format($post_id);
+ $post_format = $post_format ? $post_format : 'standard';
+
+ }
+
+ }
+
+
+ // compare
+ return $this->compare( $post_format, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ return get_post_format_strings();
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post_format' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post-status.php b/includes/locations/class-acf-location-post-status.php
new file mode 100644
index 0000000..52a998a
--- /dev/null
+++ b/includes/locations/class-acf-location-post-status.php
@@ -0,0 +1,161 @@
+name = 'post_status';
+ $this->label = __("Post Status",'acf');
+ $this->category = 'post';
+
+ }
+
+
+ /*
+ * get_post_type
+ *
+ * This function will return the current post_type
+ *
+ * @type function
+ * @date 25/11/16
+ * @since 5.5.0
+ *
+ * @param $options (int)
+ * @return (mixed)
+ */
+
+ function get_post_type( $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $post_type = acf_maybe_get( $screen, 'post_type' );
+
+
+ // post_type
+ if( $post_type ) return $post_type;
+
+
+ // $post_id
+ if( $post_id ) return get_post_type( $post_id );
+
+
+ // return
+ return false;
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_status = acf_maybe_get( $screen, 'post_status' );
+
+
+ // find post format
+ if( !$post_status ) {
+
+ // get post id
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+
+
+ // bail early if not a post
+ if( !$post_id ) return false;
+
+
+ // update
+ $post_status = get_post_status( $post_id );
+
+ }
+
+
+ // auto-draft = draft
+ if( $post_status == 'auto-draft' ) {
+
+ $post_status = 'draft';
+
+ }
+
+
+ // match
+ return $this->compare( $post_status, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // globals
+ global $wp_post_statuses;
+
+
+ // append
+ if( !empty($wp_post_statuses) ) {
+
+ foreach( $wp_post_statuses as $status ) {
+
+ $choices[ $status->name ] = $status->label;
+
+ }
+
+ }
+
+
+ // return choices
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post_status' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post-taxonomy.php b/includes/locations/class-acf-location-post-taxonomy.php
new file mode 100644
index 0000000..441ada5
--- /dev/null
+++ b/includes/locations/class-acf-location-post-taxonomy.php
@@ -0,0 +1,161 @@
+name = 'post_taxonomy';
+ $this->label = __("Post Taxonomy",'acf');
+ $this->category = 'post';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $terms = acf_maybe_get( $screen, 'post_taxonomy' );
+
+
+ // bail early if not a post
+ if( !$post_id ) return false;
+
+
+ // get term data
+ $data = acf_decode_taxonomy_term( $rule['value'] );
+ $term = get_term_by( 'slug', $data['term'], $data['taxonomy'] );
+
+
+ // attempt get term via ID (ACF4 uses ID)
+ if( !$term && is_numeric($data['term']) ) {
+
+ $term = get_term_by( 'id', $data['term'], $data['taxonomy'] );
+
+ }
+
+
+ // bail early if no term
+ if( !$term ) return false;
+
+
+ // not ajax, load real post's terms
+ if( !$screen['ajax'] ) {
+
+ $terms = wp_get_post_terms( $post_id, $term->taxonomy, array('fields' => 'ids') );
+
+ }
+
+
+ // If no terms, this is a new post and should be treated as if it has the "Uncategorized" (1) category ticked
+ if( empty($terms) ) {
+
+ // get post type
+ $post_type = get_post_type( $post_id );
+
+
+ // if is category
+ if( is_object_in_taxonomy($post_type, 'category') ) {
+
+ $terms = array( 1 );
+
+ }
+
+ }
+
+
+ // match
+ if( !empty($terms) ) {
+
+ $result = in_array( $term->term_id, $terms );
+
+ }
+
+
+ // reverse if 'not equal to'
+ if( $rule['operator'] === '!=' ) {
+
+ $result = !$result;
+
+ }
+
+
+ // return
+ return $result;
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // get
+ $choices = acf_get_taxonomy_terms();
+
+
+ // unset post_format
+ if( isset($choices['post_format']) ) {
+
+ unset( $choices['post_format']) ;
+
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post_taxonomy' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post-template.php b/includes/locations/class-acf-location-post-template.php
new file mode 100644
index 0000000..8f31a06
--- /dev/null
+++ b/includes/locations/class-acf-location-post-template.php
@@ -0,0 +1,176 @@
+name = 'post_template';
+ $this->label = __("Post Template",'acf');
+ $this->category = 'post';
+ $this->public = acf_version_compare('wp', '>=', '4.7');
+
+ }
+
+
+ /*
+ * get_post_type
+ *
+ * This function will return the current post_type
+ *
+ * @type function
+ * @date 25/11/16
+ * @since 5.5.0
+ *
+ * @param $options (int)
+ * @return (mixed)
+ */
+
+ function get_post_type( $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $post_type = acf_maybe_get( $screen, 'post_type' );
+
+
+ // post_type
+ if( $post_type ) return $post_type;
+
+
+ // $post_id
+ if( $post_id ) return get_post_type( $post_id );
+
+
+ // return
+ return false;
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $templates = array();
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $page_template = acf_maybe_get( $screen, 'page_template' );
+ $post_type = $this->get_post_type( $screen );
+
+
+ // bail early if no post_type found (not a post)
+ if( !$post_type ) return false;
+
+
+ // get templates (WP 4.7)
+ if( acf_version_compare('wp', '>=', '4.7') ) {
+
+ $templates = wp_get_theme()->get_post_templates();
+
+ }
+
+
+ // 'page' is always a valid pt even if no templates exist in the theme
+ // allows scenario where page_template = 'default' and no templates exist
+ if( !isset($templates['page']) ) {
+
+ $templates['page'] = array();
+
+ }
+
+
+ // bail early if this post type does not allow for templates
+ if( !isset($templates[ $post_type ]) ) return false;
+
+
+ // get page template
+ if( !$page_template ) {
+
+ $page_template = get_post_meta( $post_id, '_wp_page_template', true );
+
+ }
+
+
+ // new post - no page template
+ if( !$page_template ) $page_template = "default";
+
+
+ // match
+ return $this->compare( $page_template, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // vars
+ $choices = array(
+ 'default' => apply_filters( 'default_page_template_title', __('Default Template', 'acf') )
+ );
+
+
+ // get templates (WP 4.7)
+ if( acf_version_compare('wp', '>=', '4.7') ) {
+
+ $templates = wp_get_theme()->get_post_templates();
+ $choices = array_merge($choices, $templates);
+
+ }
+
+
+ // return choices
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post_template' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post-type.php b/includes/locations/class-acf-location-post-type.php
new file mode 100644
index 0000000..8c9f9a4
--- /dev/null
+++ b/includes/locations/class-acf-location-post-type.php
@@ -0,0 +1,132 @@
+name = 'post_type';
+ $this->label = __("Post Type",'acf');
+ $this->category = 'post';
+
+ }
+
+
+ /*
+ * get_post_type
+ *
+ * This function will return the current post_type
+ *
+ * @type function
+ * @date 25/11/16
+ * @since 5.5.0
+ *
+ * @param $options (int)
+ * @return (mixed)
+ */
+
+ function get_post_type( $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+ $post_type = acf_maybe_get( $screen, 'post_type' );
+
+
+ // post_type
+ if( $post_type ) return $post_type;
+
+
+ // $post_id
+ if( $post_id ) return get_post_type( $post_id );
+
+
+ // return
+ return false;
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_type = $this->get_post_type( $screen );
+
+
+ // bail early if no post_type found (not a post)
+ if( !$post_type ) return false;
+
+
+ // match
+ return $this->compare( $post_type, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // get post types
+ // - removed show_ui to allow 3rd party code to register a post type using a custom admin edit page
+ $post_types = acf_get_post_types(array(
+ //'show_ui' => 1,
+ 'exclude' => array('attachment')
+ ));
+
+
+ // return choices
+ return acf_get_pretty_post_types( $post_types );
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post_type' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-post.php b/includes/locations/class-acf-location-post.php
new file mode 100644
index 0000000..346e4e7
--- /dev/null
+++ b/includes/locations/class-acf-location-post.php
@@ -0,0 +1,123 @@
+name = 'post';
+ $this->label = __("Post",'acf');
+ $this->category = 'post';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $post_id = acf_maybe_get( $screen, 'post_id' );
+
+
+ // compare
+ return $this->compare( $post_id, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // get post types
+ $post_types = acf_get_post_types(array(
+ 'exclude' => array('page', 'attachment')
+ ));
+
+
+ // get posts grouped by post type
+ $groups = acf_get_grouped_posts(array(
+ 'post_type' => $post_types
+ ));
+
+
+ if( !empty($groups) ) {
+
+ foreach( array_keys($groups) as $group_title ) {
+
+ // vars
+ $posts = acf_extract_var( $groups, $group_title );
+
+
+ // override post data
+ foreach( array_keys($posts) as $post_id ) {
+
+ // update
+ $posts[ $post_id ] = acf_get_post_title( $posts[ $post_id ] );
+
+ };
+
+
+ // append to $choices
+ $choices[ $group_title ] = $posts;
+
+ }
+
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_post' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-taxonomy.php b/includes/locations/class-acf-location-taxonomy.php
new file mode 100644
index 0000000..8bec37f
--- /dev/null
+++ b/includes/locations/class-acf-location-taxonomy.php
@@ -0,0 +1,95 @@
+name = 'taxonomy';
+ $this->label = __("Taxonomy Term",'acf');
+ $this->category = 'forms';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $taxonomy = acf_maybe_get( $screen, 'taxonomy' );
+
+
+ // bail early if not taxonomy
+ if( !$taxonomy ) return false;
+
+
+ // return
+ return $this->compare( $taxonomy, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // vars
+ $choices = array( 'all' => __('All', 'acf') );
+ $choices = array_merge( $choices, acf_get_taxonomies() );
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_taxonomy' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-user-form.php b/includes/locations/class-acf-location-user-form.php
new file mode 100644
index 0000000..cf24a44
--- /dev/null
+++ b/includes/locations/class-acf-location-user-form.php
@@ -0,0 +1,116 @@
+name = 'user_form';
+ $this->label = __("User Form",'acf');
+ $this->category = 'user';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $user_form = acf_maybe_get( $screen, 'user_form' );
+
+
+ // bail early if no user form
+ if( !$user_form ) return false;
+
+
+ // add is treated the same as edit
+ if( $user_form === 'add' ) {
+
+ $user_form = 'edit';
+
+ }
+
+
+ // match
+ return $this->compare( $user_form, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ return array(
+ 'all' => __('All', 'acf'),
+ 'edit' => __('Add / Edit', 'acf'),
+ 'register' => __('Register', 'acf')
+ );
+
+/*
+
+ // global
+ global $wp_roles;
+
+
+ // vars
+ $choices = array( 'all' => __('All', 'acf') );
+ $choices = array_merge( $choices, $wp_roles->get_names() );
+
+
+ // return
+ return $choices;
+*/
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_user_form' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-user-role.php b/includes/locations/class-acf-location-user-role.php
new file mode 100644
index 0000000..f049742
--- /dev/null
+++ b/includes/locations/class-acf-location-user-role.php
@@ -0,0 +1,120 @@
+name = 'user_role';
+ $this->label = __("User Role",'acf');
+ $this->category = 'user';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $user_id = acf_maybe_get( $screen, 'user_id' );
+ $user_role = acf_maybe_get( $screen, 'user_role' );
+
+
+ // not a user
+ if( !$user_id ) return false;
+
+
+ // new user
+ if( $user_id == 'new' ) {
+
+ $result = ( $rule['value'] == get_option('default_role') );
+
+ } else {
+
+ $result = ( user_can($user_id, $rule['value']) );
+
+ }
+
+
+ // reverse if 'not equal to'
+ if( $rule['operator'] === '!=' ) {
+
+ $result = !$result;
+
+ }
+
+
+ // match
+ return $result;
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // global
+ global $wp_roles;
+
+
+ // vars
+ $choices = array( 'all' => __('All', 'acf') );
+ $choices = array_merge( $choices, $wp_roles->get_names() );
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_user_role' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location-widget.php b/includes/locations/class-acf-location-widget.php
new file mode 100644
index 0000000..4b02040
--- /dev/null
+++ b/includes/locations/class-acf-location-widget.php
@@ -0,0 +1,110 @@
+name = 'widget';
+ $this->label = __("Widget",'acf');
+ $this->category = 'forms';
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+ function rule_match( $result, $rule, $screen ) {
+
+ // vars
+ $widget = acf_maybe_get( $screen, 'widget' );
+
+
+ // bail early if not widget
+ if( !$widget ) return false;
+
+
+ // return
+ return $this->compare( $widget, $rule );
+
+ }
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+ function rule_values( $choices, $rule ) {
+
+ // global
+ global $wp_widget_factory;
+
+
+ // vars
+ $choices = array( 'all' => __('All', 'acf') );
+
+
+ // loop
+ if( !empty( $wp_widget_factory->widgets ) ) {
+
+ foreach( $wp_widget_factory->widgets as $widget ) {
+
+ $choices[ $widget->id_base ] = $widget->name;
+
+ }
+
+ }
+
+
+ // return
+ return $choices;
+
+ }
+
+}
+
+// initialize
+acf_register_location_rule( 'acf_location_widget' );
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/includes/locations/class-acf-location.php b/includes/locations/class-acf-location.php
new file mode 100644
index 0000000..3f8e422
--- /dev/null
+++ b/includes/locations/class-acf-location.php
@@ -0,0 +1,263 @@
+initialize();
+
+
+ // filters
+ $this->add_filter('acf/location/rule_match', true, array($this, 'rule_match'), 10, 3);
+ $this->add_filter('acf/location/rule_operators', true, array($this, 'rule_operators'), 10, 2);
+ $this->add_filter('acf/location/rule_values', true, array($this, 'rule_values'), 10, 2);
+
+ }
+
+
+ /*
+ * initialize
+ *
+ * This function will initialize the location rule
+ *
+ * @type function
+ * @date 27/6/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return n/a
+ */
+
+ function initialize() {
+
+ /* do nothing */
+
+ }
+
+
+ /*
+ * add_filter
+ *
+ * This function checks if the function is_callable before adding the filter
+ *
+ * @type function
+ * @date 5/03/2014
+ * @since 5.0.0
+ *
+ * @param $tag (string)
+ * @param $function_to_add (string)
+ * @param $priority (int)
+ * @param $accepted_args (int)
+ * @return n/a
+ */
+
+ function add_filter( $tag = '', $specific = false, $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
+
+ // specific
+ if( $specific ) {
+
+ $tag .= '/' . $this->name;
+
+ }
+
+
+ // add
+ if( is_callable($function_to_add) ) {
+
+ add_filter( $tag, $function_to_add, $priority, $accepted_args );
+
+ }
+
+ }
+
+
+ /*
+ * add_action
+ *
+ * This function checks if the function is_callable before adding the action
+ *
+ * @type function
+ * @date 5/03/2014
+ * @since 5.0.0
+ *
+ * @param $tag (string)
+ * @param $function_to_add (string)
+ * @param $priority (int)
+ * @param $accepted_args (int)
+ * @return n/a
+ */
+
+ function add_action( $tag = '', $specific = false, $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
+
+ // specific
+ if( $specific ) {
+
+ $tag .= '/' . $this->name;
+
+ }
+
+
+ // add
+ if( is_callable($function_to_add) ) {
+
+ add_action( $tag, $function_to_add, $priority, $accepted_args );
+
+ }
+
+ }
+
+
+ /*
+ * compare
+ *
+ * This function will compare a value to a location rule and return a boolean result
+ *
+ * @type function
+ * @date 25/11/16
+ * @since 5.5.0
+ *
+ * @param $value (mixed)
+ * @param rule (array)
+ * @return (boolean)
+ */
+
+ function compare( $value, $rule ) {
+
+ // match
+ $match = ( $value == $rule['value'] );
+
+
+ // override for "all"
+ if( $rule['value'] == 'all' ) $match = true;
+
+
+ // reverse if 'not equal to'
+ if( $rule['operator'] == '!=' ) {
+
+ $match = !$match;
+
+ }
+
+
+ // return
+ return $match;
+
+ }
+
+
+ /*
+ * rule_match
+ *
+ * This function is used to match this location $rule to the current $screen
+ *
+ * @type function
+ * @date 3/01/13
+ * @since 3.5.7
+ *
+ * @param $match (boolean)
+ * @param $rule (array)
+ * @return $options (array)
+ */
+
+/*
+ function rule_match( $result, $rule, $screen ) {
+
+ return $result;
+
+ }
+*/
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available operators for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+/*
+ function rule_operators( $operators, $rule ) {
+
+ return $operators;
+
+ }
+*/
+
+
+ /*
+ * rule_operators
+ *
+ * This function returns the available values for this rule type
+ *
+ * @type function
+ * @date 30/5/17
+ * @since 5.6.0
+ *
+ * @param n/a
+ * @return (array)
+ */
+
+/*
+ function rule_values( $values, $rule ) {
+
+ return $values;
+
+ }
+*/
+
+
+/*
+ function rule_listeners() {
+
+ // js
+
+ }
+*/
+
+
+}
+
+endif; // class_exists check
+
+?>
\ No newline at end of file
diff --git a/core/loop.php b/includes/loop.php
similarity index 92%
rename from core/loop.php
rename to includes/loop.php
index 2fae579..655ac36 100644
--- a/core/loop.php
+++ b/includes/loop.php
@@ -132,9 +132,26 @@ class acf_loop {
));
+ // ensure array
+ $loop['value'] = acf_get_array( $loop['value'] );
+
+
+ // Re-index values if this loop starts from index 0.
+ // This allows ajax previews to work ($_POST data contains random unique array keys)
+ if( $loop['i'] == -1 ) {
+
+ $loop['value'] = array_values($loop['value']);
+
+ }
+
+
// append
$this->loops[] = $loop;
+
+ // return
+ return $loop;
+
}
diff --git a/core/media.php b/includes/media.php
similarity index 100%
rename from core/media.php
rename to includes/media.php
diff --git a/core/revisions.php b/includes/revisions.php
similarity index 95%
rename from core/revisions.php
rename to includes/revisions.php
index 70dc9eb..4dcb8e7 100644
--- a/core/revisions.php
+++ b/includes/revisions.php
@@ -54,18 +54,14 @@ class acf_revisions {
function wp_preview_post_fields( $fields ) {
- // vars
- $wp_preview = acf_maybe_get($_POST, 'wp-preview');
-
-
// bail early if not previewing a post
- if( $wp_preview !== 'dopreview' ) return $fields;
+ if( acf_maybe_get_POST('wp-preview') !== 'dopreview' ) return $fields;
// add to fields if ACF has changed
- if( !empty($_POST['_acfchanged']) ) {
+ if( acf_maybe_get_POST('_acf_changed') ) {
- $fields['_acfchanged'] = 'different than 1';
+ $fields['_acf_changed'] = 'different than 1';
}
@@ -93,13 +89,8 @@ class acf_revisions {
function wp_save_post_revision_check_for_changes( $return, $last_revision, $post ) {
-
- // look for _acfchanged
- if( acf_maybe_get($_POST, '_acfchanged') === '1' ) {
-
- $return = false;
-
- }
+ // if acf has changed, return false and prevent WP from performing 'compare' logic
+ if( acf_maybe_get_POST('_acf_changed') ) return false;
// return
@@ -127,6 +118,9 @@ class acf_revisions {
// validate page
if( acf_is_screen('revision') || acf_is_ajax('get-revision-diffs') ) {
+ // bail early if is restoring
+ if( acf_maybe_get_GET('action') === 'restore' ) return $fields;
+
// allow
} else {
diff --git a/core/third_party.php b/includes/third_party.php
similarity index 100%
rename from core/third_party.php
rename to includes/third_party.php
diff --git a/core/updates.php b/includes/updates.php
similarity index 100%
rename from core/updates.php
rename to includes/updates.php
diff --git a/core/validation.php b/includes/validation.php
similarity index 56%
rename from core/validation.php
rename to includes/validation.php
index 98671ce..99e01da 100644
--- a/core/validation.php
+++ b/includes/validation.php
@@ -29,10 +29,7 @@ class acf_validation {
// ajax
add_action('wp_ajax_acf/validate_save_post', array($this, 'ajax_validate_save_post'));
add_action('wp_ajax_nopriv_acf/validate_save_post', array($this, 'ajax_validate_save_post'));
-
-
- // filters
- add_filter('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5);
+ add_action('acf/validate_save_post', array($this, 'acf_validate_save_post'), 5);
}
@@ -185,77 +182,12 @@ class acf_validation {
}
- /*
- * validate_value
- *
- * This function will validate a field's value
- *
- * @type function
- * @date 27/10/2014
- * @since 5.0.9
- *
- * @param $value (mixed)
- * @param $field (array)
- * @param $input (string) name attribute of DOM elmenet
- * @return (boolean)
- */
-
- function validate_value( $value, $field, $input ) {
-
- // vars
- $valid = true;
- $message = sprintf( __( '%s value is required', 'acf' ), $field['label'] );
-
-
- // valid
- if( $field['required'] ) {
-
- // valid is set to false if the value is empty, but allow 0 as a valid value
- if( empty($value) && !is_numeric($value) ) {
-
- $valid = false;
-
- }
-
- }
-
-
- // filter for 3rd party customization
- $valid = apply_filters( "acf/validate_value", $valid, $value, $field, $input );
- $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input );
- $valid = apply_filters( "acf/validate_value/name={$field['name']}", $valid, $value, $field, $input );
- $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input );
-
-
- // allow $valid to be a custom error message
- if( !empty($valid) && is_string($valid) ) {
-
- $message = $valid;
- $valid = false;
-
- }
-
-
- if( !$valid ) {
-
- acf_add_validation_error( $input, $message );
- return false;
-
- }
-
-
- // return
- return true;
-
- }
-
-
/*
* acf_validate_save_post
*
* This function will loop over $_POST data and validate
*
- * @type action 'acf/validate_save_post' 5
+ * @type function
* @date 7/09/2016
* @since 5.4.0
*
@@ -269,75 +201,9 @@ class acf_validation {
if( empty($_POST['acf']) ) return;
- // loop
- foreach( $_POST['acf'] as $field_key => $value ) {
-
- // get field
- $field = acf_get_field( $field_key );
- $input = 'acf[' . $field_key . ']';
-
-
- // bail early if not found
- if( !$field ) continue;
-
-
- // validate
- acf_validate_value( $value, $field, $input );
-
- }
-
- }
-
-
- /*
- * validate_save_post
- *
- * This function will validate $_POST data and add errors
- *
- * @type function
- * @date 25/11/2013
- * @since 5.0.0
- *
- * @param $show_errors (boolean) if true, errors will be shown via a wp_die screen
- * @return (boolean)
- */
-
- function validate_save_post( $show_errors = false ) {
-
- // action
- do_action('acf/validate_save_post');
-
-
- // vars
- $errors = acf_get_validation_errors();
-
-
- // bail ealry if no errors
- if( !$errors ) return true;
-
-
- // show errors
- if( $show_errors ) {
+ // validate
+ acf_validate_values( $_POST['acf'], 'acf' );
- $message = '
' . __('Validation failed', 'acf') . ' ';
- $message .= '
';
- foreach( $errors as $error ) {
-
- $message .= '' . $error['message'] . ' ';
-
- }
- $message .= ' ';
-
-
- // die
- wp_die( $message, 'Validation failed' );
-
- }
-
-
- // return
- return false;
-
}
}
@@ -348,12 +214,10 @@ acf()->validation = new acf_validation();
endif; // class_exists check
-
-
/*
-* acf_add_validation_error
+* Public functions
*
-* alias of acf()->validation->add_error()
+* alias of acf()->validation->function()
*
* @type function
* @date 6/10/13
@@ -369,39 +233,17 @@ function acf_add_validation_error( $input, $message = '' ) {
}
-
-/*
-* acf_get_validation_errors
-*
-* alias of acf()->validation->get_errors()
-*
-* @type function
-* @date 6/10/13
-* @since 5.0.0
-*
-* @param n/a
-* @return n/a
-*/
-
function acf_get_validation_errors() {
return acf()->validation->get_errors();
}
-
-/*
-* acf_reset_validation_errors
-*
-* alias of acf()->validation->reset_errors()
-*
-* @type function
-* @date 6/10/13
-* @since 5.0.0
-*
-* @param n/a
-* @return n/a
-*/
+function acf_get_validation_error() {
+
+ return acf()->validation->get_error( $input );
+
+}
function acf_reset_validation_errors() {
@@ -413,19 +255,91 @@ function acf_reset_validation_errors() {
/*
* acf_validate_save_post
*
-* alias of acf()->validation->validate_save_post()
+* This function will validate $_POST data and add errors
+*
+* @type function
+* @date 25/11/2013
+* @since 5.0.0
+*
+* @param $show_errors (boolean) if true, errors will be shown via a wp_die screen
+* @return (boolean)
+*/
+
+function acf_validate_save_post( $show_errors = false ) {
+
+ // action
+ do_action('acf/validate_save_post');
+
+
+ // vars
+ $errors = acf_get_validation_errors();
+
+
+ // bail ealry if no errors
+ if( !$errors ) return true;
+
+
+ // show errors
+ if( $show_errors ) {
+
+ $message = '
' . __('Validation failed', 'acf') . ' ';
+ $message .= '
';
+ foreach( $errors as $error ) {
+
+ $message .= '' . $error['message'] . ' ';
+
+ }
+ $message .= ' ';
+
+
+ // die
+ wp_die( $message, __('Validation failed', 'acf') );
+
+ }
+
+
+ // return
+ return false;
+
+}
+
+
+/*
+* acf_validate_values
+*
+* This function will validate an array of field values
*
* @type function
* @date 6/10/13
* @since 5.0.0
*
-* @param n/a
+* @param values (array)
+* @param $input_prefix (string)
* @return n/a
*/
-function acf_validate_save_post( $show_errors = false ) {
+function acf_validate_values( $values, $input_prefix = '' ) {
- return acf()->validation->validate_save_post( $show_errors );
+ // bail early if empty
+ if( empty($values) ) return;
+
+
+ // loop
+ foreach( $values as $key => $value ) {
+
+ // vars
+ $field = acf_get_field( $key );
+ $input = $input_prefix . '[' . $key . ']';
+
+
+ // bail early if not found
+ if( !$field ) continue;
+
+
+ // validate
+ acf_validate_value( $value, $field, $input );
+
+ }
}
@@ -433,7 +347,7 @@ function acf_validate_save_post( $show_errors = false ) {
/*
* acf_validate_value
*
-* alias of acf()->validation->validate_value()
+* This function will validate a field's value
*
* @type function
* @date 6/10/13
@@ -445,6 +359,49 @@ function acf_validate_save_post( $show_errors = false ) {
function acf_validate_value( $value, $field, $input ) {
- return acf()->validation->validate_value( $value, $field, $input );
+ // vars
+ $valid = true;
+ $message = sprintf( __( '%s value is required', 'acf' ), $field['label'] );
+
+
+ // valid
+ if( $field['required'] ) {
+
+ // valid is set to false if the value is empty, but allow 0 as a valid value
+ if( empty($value) && !is_numeric($value) ) {
+
+ $valid = false;
+
+ }
+
+ }
+
+
+ // filter for 3rd party customization
+ $valid = apply_filters( "acf/validate_value", $valid, $value, $field, $input );
+ $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input );
+ $valid = apply_filters( "acf/validate_value/name={$field['name']}", $valid, $value, $field, $input );
+ $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input );
+
+
+ // allow $valid to be a custom error message
+ if( !empty($valid) && is_string($valid) ) {
+
+ $message = $valid;
+ $valid = false;
+
+ }
+
+
+ if( !$valid ) {
+
+ acf_add_validation_error( $input, $message );
+ return false;
+
+ }
+
+
+ // return
+ return true;
}
diff --git a/includes/walkers/class-acf-walker-nav-menu-edit.php b/includes/walkers/class-acf-walker-nav-menu-edit.php
new file mode 100644
index 0000000..7b368b4
--- /dev/null
+++ b/includes/walkers/class-acf-walker-nav-menu-edit.php
@@ -0,0 +1,136 @@
+
+ $search = '
';
+
+ }
+
+
+ // return
+ return ob_get_clean();
+
+ }
+
+}
+
+endif;
+
+ ?>
\ No newline at end of file
diff --git a/includes/walkers/class-acf-walker-taxonomy-field.php b/includes/walkers/class-acf-walker-taxonomy-field.php
new file mode 100644
index 0000000..b1a1188
--- /dev/null
+++ b/includes/walkers/class-acf-walker-taxonomy-field.php
@@ -0,0 +1,55 @@
+ 'parent', 'id' => 'term_id' );
+
+ function __construct( $field ) {
+
+ $this->field = $field;
+
+ }
+
+ function start_el( &$output, $term, $depth = 0, $args = array(), $current_object_id = 0) {
+
+ // vars
+ $selected = in_array( $term->term_id, $this->field['value'] );
+
+
+ // append
+ $output .= '
' . "\n";
+
+ }
+
+ function start_lvl( &$output, $depth = 0, $args = array() ) {
+
+ // append
+ $output .= '
' . "\n";
+
+ }
+
+}
+
+endif;
+
+ ?>
\ No newline at end of file
diff --git a/core/wpml.php b/includes/wpml.php
similarity index 97%
rename from core/wpml.php
rename to includes/wpml.php
index e0f2c66..9ffc97a 100644
--- a/core/wpml.php
+++ b/includes/wpml.php
@@ -25,11 +25,7 @@ class acf_wpml_compatibility {
// vars
- $this->lang = ICL_LANGUAGE_CODE;
-
-
- // check for custom lang
- if( isset($_POST['_acflang']) ) $this->lang = $_POST['_acflang'];
+ $this->lang = acf_maybe_get_POST('_acf_lang', ICL_LANGUAGE_CODE);
// update settings
@@ -40,6 +36,7 @@ class acf_wpml_compatibility {
// actions
add_action('acf/verify_ajax', array($this, 'verify_ajax'));
add_action('acf/input/admin_footer', array($this, 'admin_footer'));
+ add_action('acf/input/form_data', array($this, 'acf_input_form_data'), 10, 1);
// bail early if not transaltable
@@ -51,7 +48,6 @@ class acf_wpml_compatibility {
add_action('acf/update_500_field_group', array($this, 'update_500_field_group'), 10, 2);
add_action('acf/update_field_group', array($this, 'update_field_group'), 2, 1);
add_action('icl_make_duplicate', array($this, 'icl_make_duplicate'), 10, 4);
- add_action('acf/input/form_data', array($this, 'acf_input_form_data'), 10, 1);
// filters
@@ -473,7 +469,7 @@ class acf_wpml_compatibility {
// add hidden input
- acf_hidden_input(array('name' => '_acflang', 'value' => $this->lang));
+ acf_hidden_input(array('id' => '_acf_lang', 'name' => '_acf_lang', 'value' => $this->lang));
}
diff --git a/lang/acf-ar.mo b/lang/acf-ar.mo
index 869556e..9b4c580 100644
Binary files a/lang/acf-ar.mo and b/lang/acf-ar.mo differ
diff --git a/lang/acf-ar.po b/lang/acf-ar.po
index f5d0a94..abc35d7 100644
--- a/lang/acf-ar.po
+++ b/lang/acf-ar.po
@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: Advanced Custom Fields Pro\n"
-"POT-Creation-Date: 2016-05-19 15:59+0200\n"
-"PO-Revision-Date: 2016-11-03 17:07+1000\n"
+"POT-Creation-Date: 2017-06-27 15:37+1000\n"
+"PO-Revision-Date: 2017-06-27 15:37+1000\n"
"Last-Translator: Elliot Condon