Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
61.90% |
13 / 21 |
CRAP | |
91.63% |
208 / 227 |
WP_Customize_Setting | |
0.00% |
0 / 1 |
|
65.22% |
15 / 23 |
97.31 | |
91.44% |
203 / 222 |
__construct | |
100.00% |
1 / 1 |
10 | |
100.00% |
27 / 27 |
|||
id_data | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
aggregate_multidimensional | |
100.00% |
1 / 1 |
4 | |
100.00% |
15 / 15 |
|||
is_current_blog_previewed | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
preview | |
100.00% |
1 / 1 |
13 | |
100.00% |
53 / 53 |
|||
_clear_aggregated_multidimensional_preview_applied_flag | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
_preview_filter | |
100.00% |
1 / 1 |
3 | |
100.00% |
9 / 9 |
|||
_multidimensional_preview_filter | |
0.00% |
0 / 1 |
5.06 | |
86.67% |
13 / 15 |
|||
save | |
100.00% |
1 / 1 |
3 | |
100.00% |
6 / 6 |
|||
post_value | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
sanitize | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
get_root_value | |
0.00% |
0 / 1 |
3.04 | |
83.33% |
5 / 6 |
|||
set_root_value | |
0.00% |
0 / 1 |
4.77 | |
63.64% |
7 / 11 |
|||
update | |
100.00% |
1 / 1 |
4 | |
100.00% |
10 / 10 |
|||
_update_theme_mod | |
100.00% |
1 / 1 |
1 | |
100.00% |
0 / 0 |
|||
_update_option | |
100.00% |
1 / 1 |
1 | |
100.00% |
0 / 0 |
|||
value | |
100.00% |
1 / 1 |
5 | |
100.00% |
11 / 11 |
|||
js_value | |
0.00% |
0 / 1 |
2.06 | |
75.00% |
3 / 4 |
|||
check_capabilities | |
100.00% |
1 / 1 |
5 | |
100.00% |
5 / 5 |
|||
multidimensional | |
0.00% |
0 / 1 |
17.42 | |
74.07% |
20 / 27 |
|||
multidimensional_replace | |
0.00% |
0 / 1 |
4.03 | |
87.50% |
7 / 8 |
|||
multidimensional_get | |
100.00% |
1 / 1 |
4 | |
100.00% |
4 / 4 |
|||
multidimensional_isset | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
<?php | |
/** | |
* WordPress Customize Setting classes | |
* | |
* @package WordPress | |
* @subpackage Customize | |
* @since 3.4.0 | |
*/ | |
/** | |
* Customize Setting class. | |
* | |
* Handles saving and sanitizing of settings. | |
* | |
* @since 3.4.0 | |
* | |
* @see WP_Customize_Manager | |
*/ | |
class WP_Customize_Setting { | |
/** | |
* @access public | |
* @var WP_Customize_Manager | |
*/ | |
public $manager; | |
/** | |
* Unique string identifier for the setting. | |
* | |
* @access public | |
* @var string | |
*/ | |
public $id; | |
/** | |
* @access public | |
* @var string | |
*/ | |
public $type = 'theme_mod'; | |
/** | |
* Capability required to edit this setting. | |
* | |
* @var string | |
*/ | |
public $capability = 'edit_theme_options'; | |
/** | |
* Feature a theme is required to support to enable this setting. | |
* | |
* @access public | |
* @var string | |
*/ | |
public $theme_supports = ''; | |
public $default = ''; | |
public $transport = 'refresh'; | |
/** | |
* Server-side sanitization callback for the setting's value. | |
* | |
* @var callback | |
*/ | |
public $sanitize_callback = ''; | |
public $sanitize_js_callback = ''; | |
/** | |
* Whether or not the setting is initially dirty when created. | |
* | |
* This is used to ensure that a setting will be sent from the pane to the | |
* preview when loading the Customizer. Normally a setting only is synced to | |
* the preview if it has been changed. This allows the setting to be sent | |
* from the start. | |
* | |
* @since 4.2.0 | |
* @access public | |
* @var bool | |
*/ | |
public $dirty = false; | |
/** | |
* @var array | |
*/ | |
protected $id_data = array(); | |
/** | |
* Whether or not preview() was called. | |
* | |
* @since 4.4.0 | |
* @access protected | |
* @var bool | |
*/ | |
protected $is_previewed = false; | |
/** | |
* Cache of multidimensional values to improve performance. | |
* | |
* @since 4.4.0 | |
* @access protected | |
* @var array | |
* @static | |
*/ | |
protected static $aggregated_multidimensionals = array(); | |
/** | |
* Whether the multidimensional setting is aggregated. | |
* | |
* @since 4.4.0 | |
* @access protected | |
* @var bool | |
*/ | |
protected $is_multidimensional_aggregated = false; | |
/** | |
* Constructor. | |
* | |
* Any supplied $args override class property defaults. | |
* | |
* @since 3.4.0 | |
* | |
* @param WP_Customize_Manager $manager | |
* @param string $id An specific ID of the setting. Can be a | |
* theme mod or option name. | |
* @param array $args Setting arguments. | |
*/ | |
public function __construct( $manager, $id, $args = array() ) { | |
$keys = array_keys( get_object_vars( $this ) ); | |
foreach ( $keys as $key ) { | |
if ( isset( $args[ $key ] ) ) { | |
$this->$key = $args[ $key ]; | |
} | |
} | |
$this->manager = $manager; | |
$this->id = $id; | |
// Parse the ID for array keys. | |
$this->id_data['keys'] = preg_split( '/\[/', str_replace( ']', '', $this->id ) ); | |
$this->id_data['base'] = array_shift( $this->id_data['keys'] ); | |
// Rebuild the ID. | |
$this->id = $this->id_data[ 'base' ]; | |
if ( ! empty( $this->id_data[ 'keys' ] ) ) { | |
$this->id .= '[' . implode( '][', $this->id_data['keys'] ) . ']'; | |
} | |
if ( $this->sanitize_callback ) { | |
add_filter( "customize_sanitize_{$this->id}", $this->sanitize_callback, 10, 2 ); | |
} | |
if ( $this->sanitize_js_callback ) { | |
add_filter( "customize_sanitize_js_{$this->id}", $this->sanitize_js_callback, 10, 2 ); | |
} | |
if ( 'option' === $this->type || 'theme_mod' === $this->type ) { | |
// Other setting types can opt-in to aggregate multidimensional explicitly. | |
$this->aggregate_multidimensional(); | |
// Allow option settings to indicate whether they should be autoloaded. | |
if ( 'option' === $this->type && isset( $args['autoload'] ) ) { | |
self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] = $args['autoload']; | |
} | |
} | |
} | |
/** | |
* Get parsed ID data for multidimensional setting. | |
* | |
* @since 4.4.0 | |
* @access public | |
* | |
* @return array { | |
* ID data for multidimensional setting. | |
* | |
* @type string $base ID base | |
* @type array $keys Keys for multidimensional array. | |
* } | |
*/ | |
final public function id_data() { | |
return $this->id_data; | |
} | |
/** | |
* Set up the setting for aggregated multidimensional values. | |
* | |
* When a multidimensional setting gets aggregated, all of its preview and update | |
* calls get combined into one call, greatly improving performance. | |
* | |
* @since 4.4.0 | |
* @access protected | |
*/ | |
protected function aggregate_multidimensional() { | |
$id_base = $this->id_data['base']; | |
if ( ! isset( self::$aggregated_multidimensionals[ $this->type ] ) ) { | |
self::$aggregated_multidimensionals[ $this->type ] = array(); | |
} | |
if ( ! isset( self::$aggregated_multidimensionals[ $this->type ][ $id_base ] ) ) { | |
self::$aggregated_multidimensionals[ $this->type ][ $id_base ] = array( | |
'previewed_instances' => array(), // Calling preview() will add the $setting to the array. | |
'preview_applied_instances' => array(), // Flags for which settings have had their values applied. | |
'root_value' => $this->get_root_value( array() ), // Root value for initial state, manipulated by preview and update calls. | |
); | |
} | |
if ( ! empty( $this->id_data['keys'] ) ) { | |
// Note the preview-applied flag is cleared at priority 9 to ensure it is cleared before a deferred-preview runs. | |
add_action( "customize_post_value_set_{$this->id}", array( $this, '_clear_aggregated_multidimensional_preview_applied_flag' ), 9 ); | |
$this->is_multidimensional_aggregated = true; | |
} | |
} | |
/** | |
* The ID for the current blog when the preview() method was called. | |
* | |
* @since 4.2.0 | |
* @access protected | |
* @var int | |
*/ | |
protected $_previewed_blog_id; | |
/** | |
* Return true if the current blog is not the same as the previewed blog. | |
* | |
* @since 4.2.0 | |
* @access public | |
* | |
* @return bool If preview() has been called. | |
*/ | |
public function is_current_blog_previewed() { | |
if ( ! isset( $this->_previewed_blog_id ) ) { | |
return false; | |
} | |
return ( get_current_blog_id() === $this->_previewed_blog_id ); | |
} | |
/** | |
* Original non-previewed value stored by the preview method. | |
* | |
* @see WP_Customize_Setting::preview() | |
* @since 4.1.1 | |
* @var mixed | |
*/ | |
protected $_original_value; | |
/** | |
* Add filters to supply the setting's value when accessed. | |
* | |
* If the setting already has a pre-existing value and there is no incoming | |
* post value for the setting, then this method will short-circuit since | |
* there is no change to preview. | |
* | |
* @since 3.4.0 | |
* @since 4.4.0 Added boolean return value. | |
* @access public | |
* | |
* @return bool False when preview short-circuits due no change needing to be previewed. | |
*/ | |
public function preview() { | |
if ( ! isset( $this->_previewed_blog_id ) ) { | |
$this->_previewed_blog_id = get_current_blog_id(); | |
} | |
// Prevent re-previewing an already-previewed setting. | |
if ( $this->is_previewed ) { | |
return true; | |
} | |
$id_base = $this->id_data['base']; | |
$is_multidimensional = ! empty( $this->id_data['keys'] ); | |
$multidimensional_filter = array( $this, '_multidimensional_preview_filter' ); | |
/* | |
* Check if the setting has a pre-existing value (an isset check), | |
* and if doesn't have any incoming post value. If both checks are true, | |
* then the preview short-circuits because there is nothing that needs | |
* to be previewed. | |
*/ | |
$undefined = new stdClass(); | |
$needs_preview = ( $undefined !== $this->post_value( $undefined ) ); | |
$value = null; | |
// Since no post value was defined, check if we have an initial value set. | |
if ( ! $needs_preview ) { | |
if ( $this->is_multidimensional_aggregated ) { | |
$root = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value']; | |
$value = $this->multidimensional_get( $root, $this->id_data['keys'], $undefined ); | |
} else { | |
$default = $this->default; | |
$this->default = $undefined; // Temporarily set default to undefined so we can detect if existing value is set. | |
$value = $this->value(); | |
$this->default = $default; | |
} | |
$needs_preview = ( $undefined === $value ); // Because the default needs to be supplied. | |
} | |
// If the setting does not need previewing now, defer to when it has a value to preview. | |
if ( ! $needs_preview ) { | |
if ( ! has_action( "customize_post_value_set_{$this->id}", array( $this, 'preview' ) ) ) { | |
add_action( "customize_post_value_set_{$this->id}", array( $this, 'preview' ) ); | |
} | |
return false; | |
} | |
switch ( $this->type ) { | |
case 'theme_mod' : | |
if ( ! $is_multidimensional ) { | |
add_filter( "theme_mod_{$id_base}", array( $this, '_preview_filter' ) ); | |
} else { | |
if ( empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] ) ) { | |
// Only add this filter once for this ID base. | |
add_filter( "theme_mod_{$id_base}", $multidimensional_filter ); | |
} | |
self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'][ $this->id ] = $this; | |
} | |
break; | |
case 'option' : | |
if ( ! $is_multidimensional ) { | |
add_filter( "pre_option_{$id_base}", array( $this, '_preview_filter' ) ); | |
} else { | |
if ( empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] ) ) { | |
// Only add these filters once for this ID base. | |
add_filter( "option_{$id_base}", $multidimensional_filter ); | |
add_filter( "default_option_{$id_base}", $multidimensional_filter ); | |
} | |
self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'][ $this->id ] = $this; | |
} | |
break; | |
default : | |
/** | |
* Fires when the {@see WP_Customize_Setting::preview()} method is called for settings | |
* not handled as theme_mods or options. | |
* | |
* The dynamic portion of the hook name, `$this->id`, refers to the setting ID. | |
* | |
* @since 3.4.0 | |
* | |
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance. | |
*/ | |
do_action( "customize_preview_{$this->id}", $this ); | |
/** | |
* Fires when the {@see WP_Customize_Setting::preview()} method is called for settings | |
* not handled as theme_mods or options. | |
* | |
* The dynamic portion of the hook name, `$this->type`, refers to the setting type. | |
* | |
* @since 4.1.0 | |
* | |
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance. | |
*/ | |
do_action( "customize_preview_{$this->type}", $this ); | |
} | |
$this->is_previewed = true; | |
return true; | |
} | |
/** | |
* Clear out the previewed-applied flag for a multidimensional-aggregated value whenever its post value is updated. | |
* | |
* This ensures that the new value will get sanitized and used the next time | |
* that <code>WP_Customize_Setting::_multidimensional_preview_filter()</code> | |
* is called for this setting. | |
* | |
* @since 4.4.0 | |
* @access private | |
* @see WP_Customize_Manager::set_post_value() | |
* @see WP_Customize_Setting::_multidimensional_preview_filter() | |
*/ | |
final public function _clear_aggregated_multidimensional_preview_applied_flag() { | |
unset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['preview_applied_instances'][ $this->id ] ); | |
} | |
/** | |
* Callback function to filter non-multidimensional theme mods and options. | |
* | |
* If switch_to_blog() was called after the preview() method, and the current | |
* blog is now not the same blog, then this method does a no-op and returns | |
* the original value. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $original Old value. | |
* @return mixed New or old value. | |
*/ | |
public function _preview_filter( $original ) { | |
if ( ! $this->is_current_blog_previewed() ) { | |
return $original; | |
} | |
$undefined = new stdClass(); // Symbol hack. | |
$post_value = $this->post_value( $undefined ); | |
if ( $undefined !== $post_value ) { | |
$value = $post_value; | |
} else { | |
/* | |
* Note that we don't use $original here because preview() will | |
* not add the filter in the first place if it has an initial value | |
* and there is no post value. | |
*/ | |
$value = $this->default; | |
} | |
return $value; | |
} | |
/** | |
* Callback function to filter multidimensional theme mods and options. | |
* | |
* For all multidimensional settings of a given type, the preview filter for | |
* the first setting previewed will be used to apply the values for the others. | |
* | |
* @since 4.4.0 | |
* @access private | |
* | |
* @see WP_Customize_Setting::$aggregated_multidimensionals | |
* @param mixed $original Original root value. | |
* @return mixed New or old value. | |
*/ | |
final public function _multidimensional_preview_filter( $original ) { | |
if ( ! $this->is_current_blog_previewed() ) { | |
return $original; | |
} | |
$id_base = $this->id_data['base']; | |
// If no settings have been previewed yet (which should not be the case, since $this is), just pass through the original value. | |
if ( empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] ) ) { | |
return $original; | |
} | |
foreach ( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] as $previewed_setting ) { | |
// Skip applying previewed value for any settings that have already been applied. | |
if ( ! empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['preview_applied_instances'][ $previewed_setting->id ] ) ) { | |
continue; | |
} | |
// Do the replacements of the posted/default sub value into the root value. | |
$value = $previewed_setting->post_value( $previewed_setting->default ); | |
$root = self::$aggregated_multidimensionals[ $previewed_setting->type ][ $id_base ]['root_value']; | |
$root = $previewed_setting->multidimensional_replace( $root, $previewed_setting->id_data['keys'], $value ); | |
self::$aggregated_multidimensionals[ $previewed_setting->type ][ $id_base ]['root_value'] = $root; | |
// Mark this setting having been applied so that it will be skipped when the filter is called again. | |
self::$aggregated_multidimensionals[ $previewed_setting->type ][ $id_base ]['preview_applied_instances'][ $previewed_setting->id ] = true; | |
} | |
return self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value']; | |
} | |
/** | |
* Check user capabilities and theme supports, and then save | |
* the value of the setting. | |
* | |
* @since 3.4.0 | |
* | |
* @return false|void False if cap check fails or value isn't set. | |
*/ | |
final public function save() { | |
$value = $this->post_value(); | |
if ( ! $this->check_capabilities() || ! isset( $value ) ) | |
return false; | |
/** | |
* Fires when the WP_Customize_Setting::save() method is called. | |
* | |
* The dynamic portion of the hook name, `$this->id_data['base']` refers to | |
* the base slug of the setting name. | |
* | |
* @since 3.4.0 | |
* | |
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance. | |
*/ | |
do_action( 'customize_save_' . $this->id_data[ 'base' ], $this ); | |
$this->update( $value ); | |
} | |
/** | |
* Fetch and sanitize the $_POST value for the setting. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $default A default value which is used as a fallback. Default is null. | |
* @return mixed The default value on failure, otherwise the sanitized value. | |
*/ | |
final public function post_value( $default = null ) { | |
return $this->manager->post_value( $this, $default ); | |
} | |
/** | |
* Sanitize an input. | |
* | |
* @since 3.4.0 | |
* | |
* @param string|array $value The value to sanitize. | |
* @return string|array|null Null if an input isn't valid, otherwise the sanitized value. | |
*/ | |
public function sanitize( $value ) { | |
$value = wp_unslash( $value ); | |
/** | |
* Filter a Customize setting value in un-slashed form. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $value Value of the setting. | |
* @param WP_Customize_Setting $this WP_Customize_Setting instance. | |
*/ | |
return apply_filters( "customize_sanitize_{$this->id}", $value, $this ); | |
} | |
/** | |
* Get the root value for a setting, especially for multidimensional ones. | |
* | |
* @since 4.4.0 | |
* @access protected | |
* | |
* @param mixed $default Value to return if root does not exist. | |
* @return mixed | |
*/ | |
protected function get_root_value( $default = null ) { | |
$id_base = $this->id_data['base']; | |
if ( 'option' === $this->type ) { | |
return get_option( $id_base, $default ); | |
} else if ( 'theme_mod' ) { | |
return get_theme_mod( $id_base, $default ); | |
} else { | |
/* | |
* Any WP_Customize_Setting subclass implementing aggregate multidimensional | |
* will need to override this method to obtain the data from the appropriate | |
* location. | |
*/ | |
return $default; | |
} | |
} | |
/** | |
* Set the root value for a setting, especially for multidimensional ones. | |
* | |
* @since 4.4.0 | |
* @access protected | |
* | |
* @param mixed $value Value to set as root of multidimensional setting. | |
* @return bool Whether the multidimensional root was updated successfully. | |
*/ | |
protected function set_root_value( $value ) { | |
$id_base = $this->id_data['base']; | |
if ( 'option' === $this->type ) { | |
$autoload = true; | |
if ( isset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] ) ) { | |
$autoload = self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload']; | |
} | |
return update_option( $id_base, $value, $autoload ); | |
} else if ( 'theme_mod' ) { | |
set_theme_mod( $id_base, $value ); | |
return true; | |
} else { | |
/* | |
* Any WP_Customize_Setting subclass implementing aggregate multidimensional | |
* will need to override this method to obtain the data from the appropriate | |
* location. | |
*/ | |
return false; | |
} | |
} | |
/** | |
* Save the value of the setting, using the related API. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $value The value to update. | |
* @return bool The result of saving the value. | |
*/ | |
protected function update( $value ) { | |
$id_base = $this->id_data['base']; | |
if ( 'option' === $this->type || 'theme_mod' === $this->type ) { | |
if ( ! $this->is_multidimensional_aggregated ) { | |
return $this->set_root_value( $value ); | |
} else { | |
$root = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value']; | |
$root = $this->multidimensional_replace( $root, $this->id_data['keys'], $value ); | |
self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value'] = $root; | |
return $this->set_root_value( $root ); | |
} | |
} else { | |
/** | |
* Fires when the {@see WP_Customize_Setting::update()} method is called for settings | |
* not handled as theme_mods or options. | |
* | |
* The dynamic portion of the hook name, `$this->type`, refers to the type of setting. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $value Value of the setting. | |
* @param WP_Customize_Setting $this WP_Customize_Setting instance. | |
*/ | |
do_action( "customize_update_{$this->type}", $value, $this ); | |
return has_action( "customize_update_{$this->type}" ); | |
} | |
} | |
/** | |
* Deprecated method. | |
* | |
* @since 3.4.0 | |
* @deprecated 4.4.0 Deprecated in favor of update() method. | |
*/ | |
protected function _update_theme_mod() { | |
_deprecated_function( __METHOD__, '4.4.0', __CLASS__ . '::update()' ); | |
} | |
/** | |
* Deprecated method. | |
* | |
* @since 3.4.0 | |
* @deprecated 4.4.0 Deprecated in favor of update() method. | |
*/ | |
protected function _update_option() { | |
_deprecated_function( __METHOD__, '4.4.0', __CLASS__ . '::update()' ); | |
} | |
/** | |
* Fetch the value of the setting. | |
* | |
* @since 3.4.0 | |
* | |
* @return mixed The value. | |
*/ | |
public function value() { | |
$id_base = $this->id_data['base']; | |
$is_core_type = ( 'option' === $this->type || 'theme_mod' === $this->type ); | |
if ( ! $is_core_type && ! $this->is_multidimensional_aggregated ) { | |
$value = $this->get_root_value( $this->default ); | |
/** | |
* Filter a Customize setting value not handled as a theme_mod or option. | |
* | |
* The dynamic portion of the hook name, `$this->id_date['base']`, refers to | |
* the base slug of the setting name. | |
* | |
* For settings handled as theme_mods or options, see those corresponding | |
* functions for available hooks. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $default The setting default value. Default empty. | |
*/ | |
$value = apply_filters( "customize_value_{$id_base}", $value ); | |
} else if ( $this->is_multidimensional_aggregated ) { | |
$root_value = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value']; | |
$value = $this->multidimensional_get( $root_value, $this->id_data['keys'], $this->default ); | |
} else { | |
$value = $this->get_root_value( $this->default ); | |
} | |
return $value; | |
} | |
/** | |
* Sanitize the setting's value for use in JavaScript. | |
* | |
* @since 3.4.0 | |
* | |
* @return mixed The requested escaped value. | |
*/ | |
public function js_value() { | |
/** | |
* Filter a Customize setting value for use in JavaScript. | |
* | |
* The dynamic portion of the hook name, `$this->id`, refers to the setting ID. | |
* | |
* @since 3.4.0 | |
* | |
* @param mixed $value The setting value. | |
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance. | |
*/ | |
$value = apply_filters( "customize_sanitize_js_{$this->id}", $this->value(), $this ); | |
if ( is_string( $value ) ) | |
return html_entity_decode( $value, ENT_QUOTES, 'UTF-8'); | |
return $value; | |
} | |
/** | |
* Validate user capabilities whether the theme supports the setting. | |
* | |
* @since 3.4.0 | |
* | |
* @return bool False if theme doesn't support the setting or user can't change setting, otherwise true. | |
*/ | |
final public function check_capabilities() { | |
if ( $this->capability && ! call_user_func_array( 'current_user_can', (array) $this->capability ) ) | |
return false; | |
if ( $this->theme_supports && ! call_user_func_array( 'current_theme_supports', (array) $this->theme_supports ) ) | |
return false; | |
return true; | |
} | |
/** | |
* Multidimensional helper function. | |
* | |
* @since 3.4.0 | |
* | |
* @param $root | |
* @param $keys | |
* @param bool $create Default is false. | |
* @return array|void Keys are 'root', 'node', and 'key'. | |
*/ | |
final protected function multidimensional( &$root, $keys, $create = false ) { | |
if ( $create && empty( $root ) ) | |
$root = array(); | |
if ( ! isset( $root ) || empty( $keys ) ) | |
return; | |
$last = array_pop( $keys ); | |
$node = &$root; | |
foreach ( $keys as $key ) { | |
if ( $create && ! isset( $node[ $key ] ) ) | |
$node[ $key ] = array(); | |
if ( ! is_array( $node ) || ! isset( $node[ $key ] ) ) | |
return; | |
$node = &$node[ $key ]; | |
} | |
if ( $create ) { | |
if ( ! is_array( $node ) ) { | |
// account for an array overriding a string or object value | |
$node = array(); | |
} | |
if ( ! isset( $node[ $last ] ) ) { | |
$node[ $last ] = array(); | |
} | |
} | |
if ( ! isset( $node[ $last ] ) ) | |
return; | |
return array( | |
'root' => &$root, | |
'node' => &$node, | |
'key' => $last, | |
); | |
} | |
/** | |
* Will attempt to replace a specific value in a multidimensional array. | |
* | |
* @since 3.4.0 | |
* | |
* @param $root | |
* @param $keys | |
* @param mixed $value The value to update. | |
* @return mixed | |
*/ | |
final protected function multidimensional_replace( $root, $keys, $value ) { | |
if ( ! isset( $value ) ) | |
return $root; | |
elseif ( empty( $keys ) ) // If there are no keys, we're replacing the root. | |
return $value; | |
$result = $this->multidimensional( $root, $keys, true ); | |
if ( isset( $result ) ) | |
$result['node'][ $result['key'] ] = $value; | |
return $root; | |
} | |
/** | |
* Will attempt to fetch a specific value from a multidimensional array. | |
* | |
* @since 3.4.0 | |
* | |
* @param $root | |
* @param $keys | |
* @param mixed $default A default value which is used as a fallback. Default is null. | |
* @return mixed The requested value or the default value. | |
*/ | |
final protected function multidimensional_get( $root, $keys, $default = null ) { | |
if ( empty( $keys ) ) // If there are no keys, test the root. | |
return isset( $root ) ? $root : $default; | |
$result = $this->multidimensional( $root, $keys ); | |
return isset( $result ) ? $result['node'][ $result['key'] ] : $default; | |
} | |
/** | |
* Will attempt to check if a specific value in a multidimensional array is set. | |
* | |
* @since 3.4.0 | |
* | |
* @param $root | |
* @param $keys | |
* @return bool True if value is set, false if not. | |
*/ | |
final protected function multidimensional_isset( $root, $keys ) { | |
$result = $this->multidimensional_get( $root, $keys ); | |
return isset( $result ); | |
} | |
} | |
/** WP_Customize_Filter_Setting class */ | |
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php' ); | |
/** WP_Customize_Header_Image_Setting class */ | |
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-setting.php' ); | |
/** WP_Customize_Background_Image_Setting class */ | |
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-setting.php' ); | |
/** WP_Customize_Nav_Menu_Item_Setting class */ | |
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-setting.php' ); | |
/** WP_Customize_Nav_Menu_Setting class */ | |
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-setting.php' ); |