2012-02-24 23:12:43 -05:00
< ? php
/**
2015-02-25 03:07:24 -05:00
* WordPress Customize Manager classes
*
* @ package WordPress
* @ subpackage Customize
* @ since 3.4 . 0
*/
/**
* Customize Manager class .
2012-02-24 23:12:43 -05:00
*
2014-03-04 15:21:14 -05:00
* Bootstraps the Customize experience on the server - side .
*
* Sets up the theme - switching process if a theme other than the active one is
* being previewed and customized .
*
* Serves as a factory for Customize Controls and Settings , and
* instantiates default Customize Controls and Settings .
*
2012-02-24 23:12:43 -05:00
* @ since 3.4 . 0
*/
2012-05-23 13:56:42 -04:00
final class WP_Customize_Manager {
2014-03-04 15:21:14 -05:00
/**
2014-08-08 19:31:15 -04:00
* An instance of the theme being previewed .
2014-03-04 15:21:14 -05:00
*
2015-09-19 02:40:26 -04:00
* @ since 3.4 . 0
* @ access protected
2014-03-04 15:21:14 -05:00
* @ var WP_Theme
*/
2012-04-17 17:43:47 -04:00
protected $theme ;
2014-03-04 15:21:14 -05:00
/**
* The directory name of the previously active theme ( within the theme_root ) .
*
2015-09-19 02:40:26 -04:00
* @ since 3.4 . 0
* @ access protected
2014-03-04 15:21:14 -05:00
* @ var string
*/
2012-04-17 16:49:39 -04:00
protected $original_stylesheet ;
2014-03-04 15:21:14 -05:00
/**
2014-08-08 19:31:15 -04:00
* Whether this is a Customizer pageload .
2014-03-04 15:21:14 -05:00
*
2015-09-19 02:40:26 -04:00
* @ since 3.4 . 0
* @ access protected
2015-06-26 21:03:25 -04:00
* @ var bool
2014-03-04 15:21:14 -05:00
*/
2012-02-24 23:12:43 -05:00
protected $previewing = false ;
2014-03-28 10:07:14 -04:00
/**
2015-09-19 02:40:26 -04:00
* Methods and properties dealing with managing widgets in the Customizer .
2014-03-28 10:07:14 -04:00
*
2015-09-19 02:40:26 -04:00
* @ since 3.9 . 0
* @ access public
2014-03-28 10:07:14 -04:00
* @ var WP_Customize_Widgets
*/
public $widgets ;
Add menu management to the Customizer.
This brings in the Menu Customizer plugin: https://wordpress.org/plugins/menu-customizer/.
props celloexpressions, westonruter, valendesigns, voldemortensen, ocean90, adamsilverstein, kucrut, jorbin, designsimply, afercia, davidakennedy, obenland.
see #32576.
Built from https://develop.svn.wordpress.org/trunk@32806
git-svn-id: http://core.svn.wordpress.org/trunk@32777 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2015-06-16 18:08:26 -04:00
/**
2015-09-19 02:40:26 -04:00
* Methods and properties dealing with managing nav menus in the Customizer .
Add menu management to the Customizer.
This brings in the Menu Customizer plugin: https://wordpress.org/plugins/menu-customizer/.
props celloexpressions, westonruter, valendesigns, voldemortensen, ocean90, adamsilverstein, kucrut, jorbin, designsimply, afercia, davidakennedy, obenland.
see #32576.
Built from https://develop.svn.wordpress.org/trunk@32806
git-svn-id: http://core.svn.wordpress.org/trunk@32777 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2015-06-16 18:08:26 -04:00
*
2015-09-19 02:40:26 -04:00
* @ since 4.3 . 0
* @ access public
Add menu management to the Customizer.
This brings in the Menu Customizer plugin: https://wordpress.org/plugins/menu-customizer/.
props celloexpressions, westonruter, valendesigns, voldemortensen, ocean90, adamsilverstein, kucrut, jorbin, designsimply, afercia, davidakennedy, obenland.
see #32576.
Built from https://develop.svn.wordpress.org/trunk@32806
git-svn-id: http://core.svn.wordpress.org/trunk@32777 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2015-06-16 18:08:26 -04:00
* @ var WP_Customize_Nav_Menus
*/
public $nav_menus ;
2015-09-19 02:40:26 -04:00
/**
* Registered instances of WP_Customize_Setting .
*
* @ since 3.4 . 0
* @ access protected
* @ var array
*/
protected $settings = array ();
/**
* Sorted top - level instances of WP_Customize_Panel and WP_Customize_Section .
*
* @ since 4.0 . 0
* @ access protected
* @ var array
*/
2014-08-14 00:43:16 -04:00
protected $containers = array ();
2012-02-24 23:12:43 -05:00
2015-09-19 02:40:26 -04:00
/**
* Registered instances of WP_Customize_Panel .
*
* @ since 4.0 . 0
* @ access protected
* @ var array
*/
protected $panels = array ();
2012-06-26 14:48:18 -04:00
2015-09-19 02:40:26 -04:00
/**
* Registered instances of WP_Customize_Section .
*
* @ since 3.4 . 0
* @ access protected
* @ var array
*/
protected $sections = array ();
/**
* Registered instances of WP_Customize_Control .
*
* @ since 3.4 . 0
* @ access protected
* @ var array
*/
protected $controls = array ();
/**
* Return value of check_ajax_referer () in customize_preview_init () method .
*
* @ since 3.5 . 0
* @ access protected
* @ var false | int
*/
protected $nonce_tick ;
2012-04-30 11:46:17 -04:00
2014-03-04 15:21:14 -05:00
/**
2015-05-29 20:03:30 -04:00
* Panel types that may be rendered from JS templates .
*
* @ since 4.3 . 0
* @ access protected
* @ var array
*/
protected $registered_panel_types = array ();
/**
* Section types that may be rendered from JS templates .
*
* @ since 4.3 . 0
* @ access protected
* @ var array
*/
protected $registered_section_types = array ();
/**
* Control types that may be rendered from JS templates .
2014-10-24 12:32:18 -04:00
*
* @ since 4.1 . 0
2014-11-28 05:52:22 -05:00
* @ access protected
* @ var array
2014-10-24 12:32:18 -04:00
*/
protected $registered_control_types = array ();
2015-09-17 15:42:26 -04:00
/**
* Initial URL being previewed .
*
* @ since 4.4 . 0
* @ access protected
* @ var string
*/
protected $preview_url ;
/**
* URL to link the user to when closing the Customizer .
*
* @ since 4.4 . 0
* @ access protected
* @ var string
*/
protected $return_url ;
/**
* Mapping of 'panel' , 'section' , 'control' to the ID which should be autofocused .
*
* @ since 4.4 . 0
* @ access protected
* @ var array
*/
protected $autofocus = array ();
2014-11-30 18:33:23 -05:00
/**
2015-02-03 05:15:21 -05:00
* Unsanitized values for Customize Settings parsed from $_POST [ 'customized' ] .
2014-03-04 15:21:14 -05:00
*
2015-02-08 18:11:25 -05:00
* @ var array
2014-03-04 15:21:14 -05:00
*/
2012-04-30 11:46:17 -04:00
private $_post_values ;
2012-02-24 23:12:43 -05:00
/**
* Constructor .
*
* @ since 3.4 . 0
*/
public function __construct () {
2015-02-03 05:15:21 -05:00
require_once ( ABSPATH . WPINC . '/class-wp-customize-setting.php' );
require_once ( ABSPATH . WPINC . '/class-wp-customize-panel.php' );
require_once ( ABSPATH . WPINC . '/class-wp-customize-section.php' );
require_once ( ABSPATH . WPINC . '/class-wp-customize-control.php' );
2014-03-05 15:41:14 -05:00
2015-11-20 02:24:30 -05:00
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-themes-section.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-setting.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-setting.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-setting.php' );
require_once ( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-setting.php' );
2015-10-20 18:16:25 -04:00
/**
* Filter the core Customizer components to load .
*
* This allows Core components to be excluded from being instantiated by
* filtering them out of the array . Note that this filter generally runs
* during the < code > plugins_loaded </ code > action , so it cannot be added
* in a theme .
*
* @ since 4.4 . 0
*
* @ see WP_Customize_Manager :: __construct ()
*
* @ param array $components List of core components to load .
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
$components = apply_filters ( 'customize_loaded_components' , array ( 'widgets' , 'nav_menus' ), $this );
if ( in_array ( 'widgets' , $components ) ) {
require_once ( ABSPATH . WPINC . '/class-wp-customize-widgets.php' );
$this -> widgets = new WP_Customize_Widgets ( $this );
}
if ( in_array ( 'nav_menus' , $components ) ) {
require_once ( ABSPATH . WPINC . '/class-wp-customize-nav-menus.php' );
$this -> nav_menus = new WP_Customize_Nav_Menus ( $this );
}
2012-02-24 23:12:43 -05:00
2012-06-08 15:22:11 -04:00
add_filter ( 'wp_die_handler' , array ( $this , 'wp_die_handler' ) );
2015-04-06 11:10:27 -04:00
add_action ( 'setup_theme' , array ( $this , 'setup_theme' ) );
add_action ( 'wp_loaded' , array ( $this , 'wp_loaded' ) );
2012-02-24 23:12:43 -05:00
2012-05-23 21:48:32 -04:00
// Run wp_redirect_status late to make sure we override the status last.
add_action ( 'wp_redirect_status' , array ( $this , 'wp_redirect_status' ), 1000 );
2014-10-15 13:21:19 -04:00
// Do not spawn cron (especially the alternate cron) while running the Customizer.
2012-05-25 23:52:14 -04:00
remove_action ( 'init' , 'wp_cron' );
// Do not run update checks when rendering the controls.
remove_action ( 'admin_init' , '_maybe_update_core' );
remove_action ( 'admin_init' , '_maybe_update_plugins' );
remove_action ( 'admin_init' , '_maybe_update_themes' );
2015-04-06 11:10:27 -04:00
add_action ( 'wp_ajax_customize_save' , array ( $this , 'save' ) );
add_action ( 'wp_ajax_customize_refresh_nonces' , array ( $this , 'refresh_nonces' ) );
2012-04-30 11:46:17 -04:00
2012-03-21 18:55:43 -04:00
add_action ( 'customize_register' , array ( $this , 'register_controls' ) );
2015-02-08 18:11:25 -05:00
add_action ( 'customize_register' , array ( $this , 'register_dynamic_settings' ), 11 ); // allow code to create settings first
2012-03-21 18:55:43 -04:00
add_action ( 'customize_controls_init' , array ( $this , 'prepare_controls' ) );
add_action ( 'customize_controls_enqueue_scripts' , array ( $this , 'enqueue_control_scripts' ) );
2015-09-17 15:42:26 -04:00
// Render Panel, Section, and Control templates.
add_action ( 'customize_controls_print_footer_scripts' , array ( $this , 'render_panel_templates' ), 1 );
add_action ( 'customize_controls_print_footer_scripts' , array ( $this , 'render_section_templates' ), 1 );
add_action ( 'customize_controls_print_footer_scripts' , array ( $this , 'render_control_templates' ), 1 );
// Export the settings to JS via the _wpCustomizeSettings variable.
add_action ( 'customize_controls_print_footer_scripts' , array ( $this , 'customize_pane_settings' ), 1000 );
2012-02-24 23:12:43 -05:00
}
2012-07-26 17:45:33 -04:00
/**
2012-06-08 15:22:11 -04:00
* Return true if it ' s an AJAX request .
*
* @ since 3.4 . 0
2015-04-05 11:00:27 -04:00
* @ since 4.2 . 0 Added `$action` param .
2015-04-05 11:03:29 -04:00
* @ access public
2012-07-26 17:45:33 -04:00
*
2015-04-05 11:00:27 -04:00
* @ param string | null $action Whether the supplied AJAX action is being run .
* @ return bool True if it ' s an AJAX request , false otherwise .
2012-06-08 15:22:11 -04:00
*/
2015-02-08 18:11:25 -05:00
public function doing_ajax ( $action = null ) {
$doing_ajax = ( defined ( 'DOING_AJAX' ) && DOING_AJAX );
if ( ! $doing_ajax ) {
return false ;
}
if ( ! $action ) {
return true ;
} else {
2015-04-05 11:00:27 -04:00
/*
* Note : we can ' t just use doing_action ( " wp_ajax_ { $action } " ) because we need
* to check before admin - ajax . php gets to that point .
*/
2015-02-08 18:11:25 -05:00
return isset ( $_REQUEST [ 'action' ] ) && wp_unslash ( $_REQUEST [ 'action' ] ) === $action ;
}
2012-06-08 15:22:11 -04:00
}
/**
* Custom wp_die wrapper . Returns either the standard message for UI
* or the AJAX message .
*
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ param mixed $ajax_message AJAX return
2012-11-17 10:11:29 -05:00
* @ param mixed $message UI message
2012-06-08 15:22:11 -04:00
*/
2012-06-12 14:39:16 -04:00
protected function wp_die ( $ajax_message , $message = null ) {
2015-02-11 17:13:25 -05:00
if ( $this -> doing_ajax () || isset ( $_POST [ 'customized' ] ) ) {
2012-06-08 15:22:11 -04:00
wp_die ( $ajax_message );
2015-02-11 17:13:25 -05:00
}
2012-06-08 15:22:11 -04:00
2015-02-11 17:13:25 -05:00
if ( ! $message ) {
2012-06-12 14:39:16 -04:00
$message = __ ( 'Cheatin’ uh?' );
2015-02-11 17:13:25 -05:00
}
2012-06-12 14:39:16 -04:00
2012-06-08 15:22:11 -04:00
wp_die ( $message );
}
2012-02-24 23:12:43 -05:00
/**
2012-06-08 15:22:11 -04:00
* Return the AJAX wp_die () handler if it ' s a customized request .
2012-04-17 17:43:47 -04:00
*
2012-06-08 15:22:11 -04:00
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ return string
2012-06-08 15:22:11 -04:00
*/
public function wp_die_handler () {
2015-02-11 17:13:25 -05:00
if ( $this -> doing_ajax () || isset ( $_POST [ 'customized' ] ) ) {
2012-06-08 15:22:11 -04:00
return '_ajax_wp_die_handler' ;
2015-02-11 17:13:25 -05:00
}
2012-06-08 15:22:11 -04:00
return '_default_wp_die_handler' ;
}
2012-11-17 10:11:29 -05:00
2012-06-08 15:22:11 -04:00
/**
2012-07-26 17:45:33 -04:00
* Start preview and customize theme .
*
* Check if customize query variable exist . Init filters to filter the current theme .
2012-02-24 23:12:43 -05:00
*
* @ since 3.4 . 0
*/
2012-04-25 11:44:06 -04:00
public function setup_theme () {
2012-06-12 14:39:16 -04:00
send_origin_headers ();
2015-02-11 17:13:25 -05:00
$doing_ajax_or_is_customized = ( $this -> doing_ajax () || isset ( $_POST [ 'customized' ] ) );
if ( is_admin () && ! $doing_ajax_or_is_customized ) {
auth_redirect ();
} elseif ( $doing_ajax_or_is_customized && ! is_user_logged_in () ) {
2015-09-03 14:37:23 -04:00
$this -> wp_die ( 0 , __ ( 'You must be logged in to complete this action.' ) );
2015-02-11 17:13:25 -05:00
}
2012-06-07 11:25:45 -04:00
2012-06-12 14:39:16 -04:00
show_admin_bar ( false );
2014-07-14 15:01:16 -04:00
if ( ! current_user_can ( 'customize' ) ) {
2015-09-03 14:37:23 -04:00
$this -> wp_die ( - 1 , __ ( 'You are not allowed to customize the appearance of this site.' ) );
2014-07-14 15:01:16 -04:00
}
2012-05-08 16:13:34 -04:00
2012-06-06 16:34:24 -04:00
$this -> original_stylesheet = get_stylesheet ();
$this -> theme = wp_get_theme ( isset ( $_REQUEST [ 'theme' ] ) ? $_REQUEST [ 'theme' ] : null );
2012-06-12 14:39:16 -04:00
if ( $this -> is_theme_active () ) {
// Once the theme is loaded, we'll validate it.
add_action ( 'after_setup_theme' , array ( $this , 'after_setup_theme' ) );
} else {
2014-03-04 15:21:14 -05:00
// If the requested theme is not the active theme and the user doesn't have the
// switch_themes cap, bail.
2015-02-11 17:13:25 -05:00
if ( ! current_user_can ( 'switch_themes' ) ) {
2015-09-03 14:37:23 -04:00
$this -> wp_die ( - 1 , __ ( 'You are not allowed to edit theme options on this site.' ) );
2015-02-11 17:13:25 -05:00
}
2012-06-06 16:34:24 -04:00
2014-03-04 15:21:14 -05:00
// If the theme has errors while loading, bail.
2015-02-11 17:13:25 -05:00
if ( $this -> theme () -> errors () ) {
2015-09-03 05:21:23 -04:00
$this -> wp_die ( - 1 , $this -> theme () -> errors () -> get_error_message () );
2015-02-11 17:13:25 -05:00
}
2012-06-06 16:34:24 -04:00
2014-03-04 15:21:14 -05:00
// If the theme isn't allowed per multisite settings, bail.
2015-02-11 17:13:25 -05:00
if ( ! $this -> theme () -> is_allowed () ) {
2015-09-03 14:37:23 -04:00
$this -> wp_die ( - 1 , __ ( 'The requested theme does not exist.' ) );
2015-02-11 17:13:25 -05:00
}
2012-06-12 14:39:16 -04:00
}
2012-06-06 16:34:24 -04:00
2012-04-25 11:44:06 -04:00
$this -> start_previewing_theme ();
2012-06-12 14:39:16 -04:00
}
2012-11-17 10:11:29 -05:00
2012-07-26 17:45:33 -04:00
/**
* Callback to validate a theme once it is loaded
*
* @ since 3.4 . 0
*/
2014-05-19 01:45:16 -04:00
public function after_setup_theme () {
2015-02-11 17:13:25 -05:00
$doing_ajax_or_is_customized = ( $this -> doing_ajax () || isset ( $_SERVER [ 'customized' ] ) );
if ( ! $doing_ajax_or_is_customized && ! validate_current_theme () ) {
2012-06-12 14:39:16 -04:00
wp_redirect ( 'themes.php?broken=true' );
exit ;
}
2012-04-25 11:44:06 -04:00
}
2012-02-24 23:12:43 -05:00
2012-04-25 11:44:06 -04:00
/**
2014-08-08 19:31:15 -04:00
* If the theme to be previewed isn ' t the active theme , add filter callbacks
* to swap it out at runtime .
2012-04-25 11:44:06 -04:00
*
* @ since 3.4 . 0
*/
public function start_previewing_theme () {
2012-06-06 16:34:24 -04:00
// Bail if we're already previewing.
2015-02-11 17:13:25 -05:00
if ( $this -> is_preview () ) {
2012-04-25 11:44:06 -04:00
return ;
2015-02-11 17:13:25 -05:00
}
2012-02-24 23:12:43 -05:00
2012-04-25 11:44:06 -04:00
$this -> previewing = true ;
2012-06-12 14:39:16 -04:00
if ( ! $this -> is_theme_active () ) {
add_filter ( 'template' , array ( $this , 'get_template' ) );
add_filter ( 'stylesheet' , array ( $this , 'get_stylesheet' ) );
add_filter ( 'pre_option_current_theme' , array ( $this , 'current_theme' ) );
2012-06-12 15:27:41 -04:00
2014-09-29 09:28:16 -04:00
// @link: https://core.trac.wordpress.org/ticket/20027
2012-06-12 14:39:16 -04:00
add_filter ( 'pre_option_stylesheet' , array ( $this , 'get_stylesheet' ) );
add_filter ( 'pre_option_template' , array ( $this , 'get_template' ) );
2012-06-12 15:27:41 -04:00
2012-06-12 14:39:16 -04:00
// Handle custom theme roots.
add_filter ( 'pre_option_stylesheet_root' , array ( $this , 'get_stylesheet_root' ) );
add_filter ( 'pre_option_template_root' , array ( $this , 'get_template_root' ) );
}
2012-04-17 17:43:47 -04:00
2014-03-06 09:11:15 -05:00
/**
* Fires once the Customizer theme preview has started .
*
* @ since 3.4 . 0
*
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
2012-04-30 13:20:32 -04:00
do_action ( 'start_previewing_theme' , $this );
2012-04-25 11:44:06 -04:00
}
/**
* Stop previewing the selected theme .
*
* Removes filters to change the current theme .
*
* @ since 3.4 . 0
*/
public function stop_previewing_theme () {
2015-02-11 17:13:25 -05:00
if ( ! $this -> is_preview () ) {
2012-04-25 11:44:06 -04:00
return ;
2015-02-11 17:13:25 -05:00
}
2012-04-25 11:44:06 -04:00
$this -> previewing = false ;
2012-06-12 14:39:16 -04:00
if ( ! $this -> is_theme_active () ) {
remove_filter ( 'template' , array ( $this , 'get_template' ) );
remove_filter ( 'stylesheet' , array ( $this , 'get_stylesheet' ) );
remove_filter ( 'pre_option_current_theme' , array ( $this , 'current_theme' ) );
2012-06-12 15:27:41 -04:00
2014-09-29 09:28:16 -04:00
// @link: https://core.trac.wordpress.org/ticket/20027
2012-06-12 14:39:16 -04:00
remove_filter ( 'pre_option_stylesheet' , array ( $this , 'get_stylesheet' ) );
remove_filter ( 'pre_option_template' , array ( $this , 'get_template' ) );
2012-06-12 15:27:41 -04:00
2012-06-12 14:39:16 -04:00
// Handle custom theme roots.
remove_filter ( 'pre_option_stylesheet_root' , array ( $this , 'get_stylesheet_root' ) );
remove_filter ( 'pre_option_template_root' , array ( $this , 'get_template_root' ) );
}
2012-04-25 11:44:06 -04:00
2014-03-06 09:11:15 -05:00
/**
* Fires once the Customizer theme preview has stopped .
*
* @ since 3.4 . 0
*
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
2012-04-30 13:20:32 -04:00
do_action ( 'stop_previewing_theme' , $this );
2012-02-24 23:12:43 -05:00
}
2012-05-23 13:56:42 -04:00
/**
2012-05-23 17:21:29 -04:00
* Get the theme being customized .
2012-05-23 13:56:42 -04:00
*
* @ since 3.4 . 0
*
* @ return WP_Theme
*/
2012-05-23 17:21:29 -04:00
public function theme () {
2015-02-24 22:54:25 -05:00
if ( ! $this -> theme ) {
$this -> theme = wp_get_theme ();
}
2012-05-23 17:21:29 -04:00
return $this -> theme ;
}
/**
* Get the registered settings .
*
* @ since 3.4 . 0
*
* @ return array
*/
public function settings () {
return $this -> settings ;
}
/**
* Get the registered controls .
*
* @ since 3.4 . 0
*
* @ return array
*/
public function controls () {
return $this -> controls ;
}
2014-08-14 00:43:16 -04:00
/**
* Get the registered containers .
*
* @ since 4.0 . 0
*
* @ return array
*/
public function containers () {
return $this -> containers ;
}
2012-05-23 17:21:29 -04:00
/**
* Get the registered sections .
*
* @ since 3.4 . 0
*
* @ return array
*/
public function sections () {
return $this -> sections ;
2012-05-23 13:56:42 -04:00
}
2014-06-26 16:17:15 -04:00
/**
* Get the registered panels .
*
* @ since 4.0 . 0
2014-07-13 20:36:15 -04:00
* @ access public
2014-06-26 16:17:15 -04:00
*
2014-07-13 20:36:15 -04:00
* @ return array Panels .
2014-06-26 16:17:15 -04:00
*/
public function panels () {
return $this -> panels ;
}
2012-05-16 01:55:54 -04:00
/**
* Checks if the current theme is active .
*
* @ since 3.4 . 0
2012-05-23 13:56:42 -04:00
*
* @ return bool
2012-05-16 01:55:54 -04:00
*/
2012-05-23 13:56:42 -04:00
public function is_theme_active () {
2012-05-16 01:55:54 -04:00
return $this -> get_stylesheet () == $this -> original_stylesheet ;
}
2012-02-24 23:12:43 -05:00
/**
2012-02-29 19:14:51 -05:00
* Register styles / scripts and initialize the preview of each setting
2012-02-24 23:12:43 -05:00
*
* @ since 3.4 . 0
*/
2012-02-29 19:14:51 -05:00
public function wp_loaded () {
2014-03-06 09:11:15 -05:00
/**
* Fires once WordPress has loaded , allowing scripts and styles to be initialized .
*
* @ since 3.4 . 0
*
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
2012-04-30 13:20:32 -04:00
do_action ( 'customize_register' , $this );
2012-02-24 23:12:43 -05:00
2012-03-28 11:04:11 -04:00
if ( $this -> is_preview () && ! is_admin () )
$this -> customize_preview_init ();
2012-03-21 18:55:43 -04:00
}
2012-05-23 21:48:32 -04:00
/**
* Prevents AJAX requests from following redirects when previewing a theme
* by issuing a 200 response instead of a 30 x .
*
* Instead , the JS will sniff out the location header .
*
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ param $status
* @ return int
2012-05-23 21:48:32 -04:00
*/
public function wp_redirect_status ( $status ) {
if ( $this -> is_preview () && ! is_admin () )
return 200 ;
return $status ;
}
2012-04-30 11:46:17 -04:00
/**
2015-02-03 05:15:21 -05:00
* Parse the incoming $_POST [ 'customized' ] JSON data and store the unsanitized
* settings for subsequent post_value () lookups .
2012-04-30 11:46:17 -04:00
*
2015-02-03 05:15:21 -05:00
* @ since 4.1 . 1
2012-07-26 17:45:33 -04:00
*
2015-02-03 05:15:21 -05:00
* @ return array
2012-04-30 11:46:17 -04:00
*/
2015-02-03 05:15:21 -05:00
public function unsanitized_post_values () {
2012-04-30 11:46:17 -04:00
if ( ! isset ( $this -> _post_values ) ) {
2015-02-03 05:15:21 -05:00
if ( isset ( $_POST [ 'customized' ] ) ) {
2013-03-03 11:30:38 -05:00
$this -> _post_values = json_decode ( wp_unslash ( $_POST [ 'customized' ] ), true );
2015-02-03 05:15:21 -05:00
}
2015-02-08 18:11:25 -05:00
if ( empty ( $this -> _post_values ) ) { // if not isset or if JSON error
$this -> _post_values = array ();
2015-02-03 05:15:21 -05:00
}
2012-04-30 11:46:17 -04:00
}
2015-02-03 05:15:21 -05:00
if ( empty ( $this -> _post_values ) ) {
return array ();
} else {
return $this -> _post_values ;
}
}
2012-04-30 11:46:17 -04:00
2015-02-03 05:15:21 -05:00
/**
* Return the sanitized value for a given setting from the request ' s POST data .
*
* @ since 3.4 . 0
2015-02-06 16:14:24 -05:00
* @ since 4.1 . 1 Introduced 'default' parameter .
2015-02-03 05:15:21 -05:00
*
* @ param WP_Customize_Setting $setting A WP_Customize_Setting derived object
* @ param mixed $default value returned $setting has no post value ( added in 4.2 . 0 ) .
* @ return string | mixed $post_value Sanitized value or the $default provided
*/
public function post_value ( $setting , $default = null ) {
$post_values = $this -> unsanitized_post_values ();
if ( array_key_exists ( $setting -> id , $post_values ) ) {
return $setting -> sanitize ( $post_values [ $setting -> id ] );
} else {
return $default ;
}
2012-04-30 11:46:17 -04:00
}
2015-02-08 18:11:25 -05:00
/**
2015-04-05 11:03:29 -04:00
* Override a setting 's (unsanitized) value as found in any incoming $_POST[' customized ' ] .
2015-02-08 18:11:25 -05:00
*
* @ since 4.2 . 0
2015-04-05 11:03:29 -04:00
* @ access public
2015-02-08 18:11:25 -05:00
*
2015-04-05 11:03:29 -04:00
* @ param string $setting_id ID for the WP_Customize_Setting instance .
* @ param mixed $value Post value .
2015-02-08 18:11:25 -05:00
*/
public function set_post_value ( $setting_id , $value ) {
$this -> unsanitized_post_values ();
$this -> _post_values [ $setting_id ] = $value ;
2015-11-20 21:52:27 -05:00
/**
* Announce when a specific setting ' s unsanitized post value has been set .
*
* Fires when the { @ see WP_Customize_Manager :: set_post_value ()} method is called .
*
* The dynamic portion of the hook name , `$setting_id` , refers to the setting ID .
*
* @ since 4.4 . 0
*
* @ param mixed $value Unsanitized setting post value .
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
do_action ( " customize_post_value_set_ { $setting_id } " , $value , $this );
/**
* Announce when any setting ' s unsanitized post value has been set .
*
* Fires when the { @ see WP_Customize_Manager :: set_post_value ()} method is called .
*
* This is useful for < code > WP_Customize_Setting </ code > instances to watch
* in order to update a cached previewed value .
*
* @ since 4.4 . 0
*
* @ param string $setting_id Setting ID .
* @ param mixed $value Unsanitized setting post value .
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
do_action ( 'customize_post_value_set' , $setting_id , $value , $this );
2015-02-08 18:11:25 -05:00
}
2012-03-21 18:55:43 -04:00
/**
2014-12-01 19:31:22 -05:00
* Print JavaScript settings .
2012-03-21 18:55:43 -04:00
*
* @ since 3.4 . 0
*/
public function customize_preview_init () {
2012-06-26 14:48:18 -04:00
$this -> nonce_tick = check_ajax_referer ( 'preview-customize_' . $this -> get_stylesheet (), 'nonce' );
2012-03-21 18:55:43 -04:00
$this -> prepare_controls ();
2012-02-24 23:12:43 -05:00
wp_enqueue_script ( 'customize-preview' );
2014-07-03 12:10:15 -04:00
add_action ( 'wp' , array ( $this , 'customize_preview_override_404_status' ) );
2012-05-23 22:07:16 -04:00
add_action ( 'wp_head' , array ( $this , 'customize_preview_base' ) );
2012-06-05 08:26:57 -04:00
add_action ( 'wp_head' , array ( $this , 'customize_preview_html5' ) );
2015-03-10 11:56:26 -04:00
add_action ( 'wp_head' , array ( $this , 'customize_preview_loading_style' ) );
2012-02-24 23:12:43 -05:00
add_action ( 'wp_footer' , array ( $this , 'customize_preview_settings' ), 20 );
2012-05-26 00:08:44 -04:00
add_action ( 'shutdown' , array ( $this , 'customize_preview_signature' ), 1000 );
2012-05-26 00:34:45 -04:00
add_filter ( 'wp_die_handler' , array ( $this , 'remove_preview_signature' ) );
2012-02-24 23:12:43 -05:00
foreach ( $this -> settings as $setting ) {
$setting -> preview ();
}
2012-03-21 18:55:43 -04:00
2014-03-06 09:11:15 -05:00
/**
* Fires once the Customizer preview has initialized and JavaScript
* settings have been printed .
*
* @ since 3.4 . 0
*
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
2012-04-30 13:20:32 -04:00
do_action ( 'customize_preview_init' , $this );
2012-02-24 23:12:43 -05:00
}
2014-07-03 12:10:15 -04:00
/**
* Prevent sending a 404 status when returning the response for the customize
2014-08-09 15:30:17 -04:00
* preview , since it causes the jQuery AJAX to fail . Send 200 instead .
2014-07-03 12:10:15 -04:00
*
* @ since 4.0 . 0
2014-07-13 20:36:15 -04:00
* @ access public
2014-07-03 12:10:15 -04:00
*/
public function customize_preview_override_404_status () {
if ( is_404 () ) {
status_header ( 200 );
}
}
2012-05-23 22:07:16 -04:00
/**
* Print base element for preview frame .
*
* @ since 3.4 . 0
*/
public function customize_preview_base () {
?> <base href="<?php echo home_url( '/' ); ?>" /><?php
}
2012-03-21 18:55:43 -04:00
2012-06-05 08:26:57 -04:00
/**
2015-03-10 11:56:26 -04:00
* Print a workaround to handle HTML5 tags in IE < 9.
2012-06-05 08:26:57 -04:00
*
* @ since 3.4 . 0
*/
public function customize_preview_html5 () { ?>
<!-- [ if lt IE 9 ] >
< script type = " text/javascript " >
var e = [ 'abbr' , 'article' , 'aside' , 'audio' , 'canvas' , 'datalist' , 'details' ,
'figure' , 'footer' , 'header' , 'hgroup' , 'mark' , 'menu' , 'meter' , 'nav' ,
'output' , 'progress' , 'section' , 'time' , 'video' ];
for ( var i = 0 ; i < e . length ; i ++ ) {
document . createElement ( e [ i ] );
}
</ script >
<! [ endif ] -->< ? php
}
2015-03-10 11:56:26 -04:00
/**
* Print CSS for loading indicators for the Customizer preview .
*
* @ since 4.2 . 0
2015-04-05 11:07:27 -04:00
* @ access public
2015-03-10 11:56:26 -04:00
*/
public function customize_preview_loading_style () {
?> <style>
body . wp - customizer - unloading {
opacity : 0.25 ;
cursor : progress ! important ;
- webkit - transition : opacity 0.5 s ;
transition : opacity 0.5 s ;
}
body . wp - customizer - unloading * {
pointer - events : none ! important ;
}
</ style >< ? php
}
2012-02-24 23:12:43 -05:00
/**
2014-12-01 19:31:22 -05:00
* Print JavaScript settings for preview frame .
2012-02-24 23:12:43 -05:00
*
* @ since 3.4 . 0
*/
public function customize_preview_settings () {
$settings = array (
2014-07-09 19:58:16 -04:00
'channel' => wp_unslash ( $_POST [ 'customize_messenger_channel' ] ),
Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections.
* Introduce API to expand and focus a control, section or panel.
* Allow deep-linking to panels, sections, and controls inside of the Customizer.
* Clean up `accordion.js`, removing all Customizer-specific logic.
* Add initial unit tests for `wp.customize.Class` in `customize-base.js`.
https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API.
props westonruter, celloexpressions, ryankienstra.
see #28032, #28579, #28580, #28650, #28709, #29758.
fixes #29529.
Built from https://develop.svn.wordpress.org/trunk@30102
git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2014-10-29 18:51:22 -04:00
'activePanels' => array (),
'activeSections' => array (),
2014-07-09 19:58:16 -04:00
'activeControls' => array (),
2012-02-24 23:12:43 -05:00
);
2012-03-05 21:49:02 -05:00
2012-06-26 14:48:18 -04:00
if ( 2 == $this -> nonce_tick ) {
2012-07-26 17:45:33 -04:00
$settings [ 'nonce' ] = array (
'save' => wp_create_nonce ( 'save-customize_' . $this -> get_stylesheet () ),
'preview' => wp_create_nonce ( 'preview-customize_' . $this -> get_stylesheet () )
);
}
2012-06-26 14:48:18 -04:00
2015-05-29 20:03:30 -04:00
foreach ( $this -> panels as $panel_id => $panel ) {
if ( $panel -> check_capabilities () ) {
$settings [ 'activePanels' ][ $panel_id ] = $panel -> active ();
foreach ( $panel -> sections as $section_id => $section ) {
if ( $section -> check_capabilities () ) {
$settings [ 'activeSections' ][ $section_id ] = $section -> active ();
}
}
2014-11-13 07:19:23 -05:00
}
Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections.
* Introduce API to expand and focus a control, section or panel.
* Allow deep-linking to panels, sections, and controls inside of the Customizer.
* Clean up `accordion.js`, removing all Customizer-specific logic.
* Add initial unit tests for `wp.customize.Class` in `customize-base.js`.
https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API.
props westonruter, celloexpressions, ryankienstra.
see #28032, #28579, #28580, #28650, #28709, #29758.
fixes #29529.
Built from https://develop.svn.wordpress.org/trunk@30102
git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2014-10-29 18:51:22 -04:00
}
foreach ( $this -> sections as $id => $section ) {
2015-05-29 20:03:30 -04:00
if ( $section -> check_capabilities () ) {
$settings [ 'activeSections' ][ $id ] = $section -> active ();
}
Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections.
* Introduce API to expand and focus a control, section or panel.
* Allow deep-linking to panels, sections, and controls inside of the Customizer.
* Clean up `accordion.js`, removing all Customizer-specific logic.
* Add initial unit tests for `wp.customize.Class` in `customize-base.js`.
https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API.
props westonruter, celloexpressions, ryankienstra.
see #28032, #28579, #28580, #28650, #28709, #29758.
fixes #29529.
Built from https://develop.svn.wordpress.org/trunk@30102
git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2014-10-29 18:51:22 -04:00
}
2014-07-09 19:58:16 -04:00
foreach ( $this -> controls as $id => $control ) {
2015-05-29 20:03:30 -04:00
if ( $control -> check_capabilities () ) {
$settings [ 'activeControls' ][ $id ] = $control -> active ();
}
2014-07-09 19:58:16 -04:00
}
2012-03-05 21:49:02 -05:00
2012-02-24 23:12:43 -05:00
?>
< script type = " text/javascript " >
2014-10-28 14:35:19 -04:00
var _wpCustomizeSettings = < ? php echo wp_json_encode ( $settings ); ?> ;
2015-09-17 15:42:26 -04:00
_wpCustomizeSettings . values = {};
( function ( v ) {
< ? php
/*
* Serialize settings separately from the initial _wpCustomizeSettings
* serialization in order to avoid a peak memory usage spike .
* @ todo We may not even need to export the values at all since the pane syncs them anyway .
*/
foreach ( $this -> settings as $id => $setting ) {
if ( $setting -> check_capabilities () ) {
printf (
" v[%s] = %s; \n " ,
wp_json_encode ( $id ),
wp_json_encode ( $setting -> js_value () )
);
}
}
?>
})( _wpCustomizeSettings . values );
2012-02-24 23:12:43 -05:00
</ script >
< ? php
}
2012-05-26 00:08:44 -04:00
/**
2014-10-15 13:21:19 -04:00
* Prints a signature so we can ensure the Customizer was properly executed .
2012-05-26 00:08:44 -04:00
*
* @ since 3.4 . 0
*/
public function customize_preview_signature () {
echo 'WP_CUSTOMIZER_SIGNATURE' ;
}
2012-05-26 00:34:45 -04:00
/**
2014-10-15 13:21:19 -04:00
* Removes the signature in case we experience a case where the Customizer was not properly executed .
2012-05-26 00:34:45 -04:00
*
* @ since 3.4 . 0
2015-05-21 18:05:24 -04:00
*
2015-09-19 02:40:26 -04:00
* @ param mixed $return Value passed through for wp_die_handler filter .
* @ return mixed Value passed through for wp_die_handler filter .
2012-05-26 00:34:45 -04:00
*/
public function remove_preview_signature ( $return = null ) {
remove_action ( 'shutdown' , array ( $this , 'customize_preview_signature' ), 1000 );
return $return ;
}
2012-02-24 23:12:43 -05:00
/**
* Is it a theme preview ?
*
* @ since 3.4 . 0
*
* @ return bool True if it ' s a preview , false if not .
*/
public function is_preview () {
return ( bool ) $this -> previewing ;
}
/**
* Retrieve the template name of the previewed theme .
*
* @ since 3.4 . 0
*
* @ return string Template name .
*/
public function get_template () {
2012-06-12 14:39:16 -04:00
return $this -> theme () -> get_template ();
2012-02-24 23:12:43 -05:00
}
/**
* Retrieve the stylesheet name of the previewed theme .
*
* @ since 3.4 . 0
*
* @ return string Stylesheet name .
*/
public function get_stylesheet () {
2012-06-12 14:39:16 -04:00
return $this -> theme () -> get_stylesheet ();
2012-02-24 23:12:43 -05:00
}
/**
* Retrieve the template root of the previewed theme .
*
* @ since 3.4 . 0
*
* @ return string Theme root .
*/
public function get_template_root () {
2012-04-17 17:43:47 -04:00
return get_raw_theme_root ( $this -> get_template (), true );
2012-02-24 23:12:43 -05:00
}
/**
* Retrieve the stylesheet root of the previewed theme .
*
* @ since 3.4 . 0
*
* @ return string Theme root .
*/
public function get_stylesheet_root () {
2012-04-17 17:43:47 -04:00
return get_raw_theme_root ( $this -> get_stylesheet (), true );
2012-02-24 23:12:43 -05:00
}
/**
* Filter the current theme and return the name of the previewed theme .
*
* @ since 3.4 . 0
*
2012-07-26 17:45:33 -04:00
* @ param $current_theme { @ internal Parameter is not used }
2012-02-24 23:12:43 -05:00
* @ return string Theme name .
*/
public function current_theme ( $current_theme ) {
2012-06-12 14:39:16 -04:00
return $this -> theme () -> display ( 'Name' );
2012-02-24 23:12:43 -05:00
}
/**
2014-03-04 15:21:14 -05:00
* Switch the theme and trigger the save () method on each setting .
2012-02-24 23:12:43 -05:00
*
* @ since 3.4 . 0
*/
public function save () {
2015-01-06 16:47:23 -05:00
if ( ! $this -> is_preview () ) {
wp_send_json_error ( 'not_preview' );
}
2012-02-24 23:12:43 -05:00
2015-01-06 16:47:23 -05:00
$action = 'save-customize_' . $this -> get_stylesheet ();
if ( ! check_ajax_referer ( $action , 'nonce' , false ) ) {
wp_send_json_error ( 'invalid_nonce' );
}
2012-02-24 23:12:43 -05:00
// Do we have to switch themes?
2012-06-12 14:39:16 -04:00
if ( ! $this -> is_theme_active () ) {
2012-04-25 11:44:06 -04:00
// Temporarily stop previewing the theme to allow switch_themes()
// to operate properly.
$this -> stop_previewing_theme ();
2012-06-26 01:21:04 -04:00
switch_theme ( $this -> get_stylesheet () );
2014-04-14 18:46:16 -04:00
update_option ( 'theme_switched_via_customizer' , true );
2012-04-25 11:44:06 -04:00
$this -> start_previewing_theme ();
2012-02-24 23:12:43 -05:00
}
2014-03-06 09:11:15 -05:00
/**
* Fires once the theme has switched in the Customizer , but before settings
* have been saved .
*
* @ since 3.4 . 0
*
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
2012-04-30 13:20:32 -04:00
do_action ( 'customize_save' , $this );
2012-02-24 23:12:43 -05:00
foreach ( $this -> settings as $setting ) {
$setting -> save ();
}
2014-03-06 09:11:15 -05:00
/**
* Fires after Customize settings have been saved .
*
* @ since 3.6 . 0
*
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
2013-05-24 06:33:30 -04:00
do_action ( 'customize_save_after' , $this );
2015-01-06 16:47:23 -05:00
/**
2015-04-05 11:07:27 -04:00
* Filter response data for a successful customize_save AJAX request .
2015-01-08 00:03:23 -05:00
*
2015-01-06 16:47:23 -05:00
* This filter does not apply if there was a nonce or authentication failure .
*
* @ since 4.2 . 0
*
2015-01-06 20:48:24 -05:00
* @ param array $data Additional information passed back to the 'saved'
* event on `wp.customize` .
2015-01-06 16:47:23 -05:00
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
$response = apply_filters ( 'customize_save_response' , array (), $this );
wp_send_json_success ( $response );
2012-02-24 23:12:43 -05:00
}
2015-04-06 11:10:27 -04:00
/**
* Refresh nonces for the current preview .
*
* @ since 4.2 . 0
*/
public function refresh_nonces () {
if ( ! $this -> is_preview () ) {
wp_send_json_error ( 'not_preview' );
}
$nonces = array (
'save' => wp_create_nonce ( 'save-customize_' . $this -> get_stylesheet () ),
'preview' => wp_create_nonce ( 'preview-customize_' . $this -> get_stylesheet () ),
);
/**
* Filter nonces for a customize_refresh_nonces AJAX request .
*
* @ since 4.2 . 0
*
* @ param array $nonces Array of refreshed nonces for save and
* preview actions .
* @ param WP_Customize_Manager $this WP_Customize_Manager instance .
*/
$nonces = apply_filters ( 'customize_refresh_nonces' , $nonces , $this );
wp_send_json_success ( $nonces );
}
2012-02-24 23:12:43 -05:00
/**
* Add a customize setting .
*
* @ since 3.4 . 0
2015-12-06 13:10:25 -05:00
* @ since 4.5 . 0 Return added WP_Customize_Setting instance .
* @ access public
2012-02-24 23:12:43 -05:00
*
2015-12-06 13:10:25 -05:00
* @ param WP_Customize_Setting | string $id Customize Setting object , or ID .
* @ param array $args Setting arguments ; passed to WP_Customize_Setting
* constructor .
* @ return WP_Customize_Setting The instance of the setting that was added .
2012-02-24 23:12:43 -05:00
*/
public function add_setting ( $id , $args = array () ) {
2015-01-15 20:06:24 -05:00
if ( $id instanceof WP_Customize_Setting ) {
2012-03-28 00:14:09 -04:00
$setting = $id ;
2015-01-15 20:06:24 -05:00
} else {
2015-12-06 18:22:25 -05:00
$class = 'WP_Customize_Setting' ;
/** This filter is documented in wp-includes/class-wp-customize-manager.php */
$args = apply_filters ( 'customize_dynamic_setting_args' , $args , $id );
/** This filter is documented in wp-includes/class-wp-customize-manager.php */
$class = apply_filters ( 'customize_dynamic_setting_class' , $class , $id , $args );
$setting = new $class ( $this , $id , $args );
2015-01-15 20:06:24 -05:00
}
2015-12-06 13:10:25 -05:00
2012-02-24 23:12:43 -05:00
$this -> settings [ $setting -> id ] = $setting ;
2015-12-06 13:10:25 -05:00
return $setting ;
2012-02-24 23:12:43 -05:00
}
2015-02-08 18:11:25 -05:00
/**
2015-04-05 11:07:27 -04:00
* Register any dynamically - created settings , such as those from $_POST [ 'customized' ]
* that have no corresponding setting created .
2015-02-08 18:11:25 -05:00
*
* This is a mechanism to " wake up " settings that have been dynamically created
2015-04-05 11:07:27 -04:00
* on the frontend and have been sent to WordPress in `$_POST['customized']` . When WP
2015-02-08 18:11:25 -05:00
* loads , the dynamically - created settings then will get created and previewed
* even though they are not directly created statically with code .
*
* @ since 4.2 . 0
2015-12-06 13:10:25 -05:00
* @ access public
2015-02-08 18:11:25 -05:00
*
2015-05-21 18:05:24 -04:00
* @ param array $setting_ids The setting IDs to add .
2015-11-04 19:43:24 -05:00
* @ return array The WP_Customize_Setting objects added .
2015-02-08 18:11:25 -05:00
*/
public function add_dynamic_settings ( $setting_ids ) {
$new_settings = array ();
foreach ( $setting_ids as $setting_id ) {
// Skip settings already created
if ( $this -> get_setting ( $setting_id ) ) {
continue ;
}
$setting_args = false ;
$setting_class = 'WP_Customize_Setting' ;
/**
* Filter a dynamic setting ' s constructor args .
*
* For a dynamic setting to be registered , this filter must be employed
* to override the default false value with an array of args to pass to
* the WP_Customize_Setting constructor .
*
* @ since 4.2 . 0
*
2015-04-05 11:07:27 -04:00
* @ param false | array $setting_args The arguments to the WP_Customize_Setting constructor .
* @ param string $setting_id ID for dynamic setting , usually coming from `$_POST['customized']` .
2015-02-08 18:11:25 -05:00
*/
$setting_args = apply_filters ( 'customize_dynamic_setting_args' , $setting_args , $setting_id );
if ( false === $setting_args ) {
continue ;
}
/**
* Allow non - statically created settings to be constructed with custom WP_Customize_Setting subclass .
*
* @ since 4.2 . 0
*
2015-04-05 11:07:27 -04:00
* @ param string $setting_class WP_Customize_Setting or a subclass .
* @ param string $setting_id ID for dynamic setting , usually coming from `$_POST['customized']` .
2015-06-12 18:54:25 -04:00
* @ param array $setting_args WP_Customize_Setting or a subclass .
2015-02-08 18:11:25 -05:00
*/
$setting_class = apply_filters ( 'customize_dynamic_setting_class' , $setting_class , $setting_id , $setting_args );
$setting = new $setting_class ( $this , $setting_id , $setting_args );
2015-04-05 11:07:27 -04:00
2015-02-08 18:11:25 -05:00
$this -> add_setting ( $setting );
$new_settings [] = $setting ;
}
return $new_settings ;
}
2012-02-24 23:12:43 -05:00
/**
* Retrieve a customize setting .
*
* @ since 3.4 . 0
*
2014-03-04 15:21:14 -05:00
* @ param string $id Customize Setting ID .
2015-05-24 01:40:25 -04:00
* @ return WP_Customize_Setting | void The setting , if set .
2012-02-24 23:12:43 -05:00
*/
public function get_setting ( $id ) {
2015-02-08 18:11:25 -05:00
if ( isset ( $this -> settings [ $id ] ) ) {
2012-02-24 23:12:43 -05:00
return $this -> settings [ $id ];
2015-02-08 18:11:25 -05:00
}
2012-02-24 23:12:43 -05:00
}
/**
* Remove a customize setting .
*
* @ since 3.4 . 0
*
2014-03-04 15:21:14 -05:00
* @ param string $id Customize Setting ID .
2012-02-24 23:12:43 -05:00
*/
public function remove_setting ( $id ) {
unset ( $this -> settings [ $id ] );
}
2014-06-26 16:17:15 -04:00
/**
* Add a customize panel .
*
* @ since 4.0 . 0
2015-12-06 13:10:25 -05:00
* @ since 4.5 . 0 Return added WP_Customize_Panel instance .
2014-07-13 20:36:15 -04:00
* @ access public
2014-06-26 16:17:15 -04:00
*
* @ param WP_Customize_Panel | string $id Customize Panel object , or Panel ID .
2014-07-13 20:36:15 -04:00
* @ param array $args Optional . Panel arguments . Default empty array .
2015-12-06 13:10:25 -05:00
*
* @ return WP_Customize_Panel The instance of the panel that was added .
2014-06-26 16:17:15 -04:00
*/
public function add_panel ( $id , $args = array () ) {
2015-01-15 20:06:24 -05:00
if ( $id instanceof WP_Customize_Panel ) {
2014-06-26 16:17:15 -04:00
$panel = $id ;
2015-01-15 20:06:24 -05:00
} else {
2014-06-26 16:17:15 -04:00
$panel = new WP_Customize_Panel ( $this , $id , $args );
}
$this -> panels [ $panel -> id ] = $panel ;
2015-12-06 13:10:25 -05:00
return $panel ;
2014-06-26 16:17:15 -04:00
}
/**
* Retrieve a customize panel .
*
* @ since 4.0 . 0
2014-07-13 20:36:15 -04:00
* @ access public
2014-06-26 16:17:15 -04:00
*
2014-07-13 20:36:15 -04:00
* @ param string $id Panel ID to get .
2015-05-24 01:40:25 -04:00
* @ return WP_Customize_Panel | void Requested panel instance , if set .
2014-06-26 16:17:15 -04:00
*/
public function get_panel ( $id ) {
if ( isset ( $this -> panels [ $id ] ) ) {
return $this -> panels [ $id ];
}
}
/**
* Remove a customize panel .
*
* @ since 4.0 . 0
2014-07-13 20:36:15 -04:00
* @ access public
2014-06-26 16:17:15 -04:00
*
2014-07-13 20:36:15 -04:00
* @ param string $id Panel ID to remove .
2014-06-26 16:17:15 -04:00
*/
public function remove_panel ( $id ) {
2016-01-07 01:06:28 -05:00
$core_panels = array (
'widgets' ,
'nav_menus' ,
);
if ( in_array ( $id , $core_panels , true ) ) {
$url = 'https://core.trac.wordpress.org/ticket/33552#comment:12' ;
_doing_it_wrong (
__METHOD__ ,
sprintf ( __ ( 'Removing %1$s manually will cause PHP warnings. Use the <code>customize_loaded_components</code> filter instead. See <a href="%2$s">%2$s</a>.' ), $id , $url ),
'4.5'
);
}
2014-06-26 16:17:15 -04:00
unset ( $this -> panels [ $id ] );
}
2015-05-29 20:03:30 -04:00
/**
* Register a customize panel type .
*
* Registered types are eligible to be rendered via JS and created dynamically .
*
* @ since 4.3 . 0
* @ access public
*
2015-07-13 16:32:24 -04:00
* @ see WP_Customize_Panel
*
* @ param string $panel Name of a custom panel which is a subclass of WP_Customize_Panel .
2015-05-29 20:03:30 -04:00
*/
public function register_panel_type ( $panel ) {
$this -> registered_panel_types [] = $panel ;
}
/**
* Render JS templates for all registered panel types .
*
* @ since 4.3 . 0
* @ access public
*/
public function render_panel_templates () {
foreach ( $this -> registered_panel_types as $panel_type ) {
$panel = new $panel_type ( $this , 'temp' , array () );
$panel -> print_template ();
}
}
2012-02-24 23:12:43 -05:00
/**
* Add a customize section .
*
* @ since 3.4 . 0
2015-12-06 13:10:25 -05:00
* @ since 4.5 . 0 Return added WP_Customize_Section instance .
* @ access public
2012-02-24 23:12:43 -05:00
*
2014-03-04 15:21:14 -05:00
* @ param WP_Customize_Section | string $id Customize Section object , or Section ID .
* @ param array $args Section arguments .
2015-12-06 13:10:25 -05:00
*
* @ return WP_Customize_Section The instance of the section that was added .
2012-02-24 23:12:43 -05:00
*/
public function add_section ( $id , $args = array () ) {
2015-01-15 20:06:24 -05:00
if ( $id instanceof WP_Customize_Section ) {
2012-03-28 00:14:09 -04:00
$section = $id ;
2015-01-15 20:06:24 -05:00
} else {
2012-03-28 00:14:09 -04:00
$section = new WP_Customize_Section ( $this , $id , $args );
2015-01-15 20:06:24 -05:00
}
2015-12-06 13:10:25 -05:00
2012-02-24 23:12:43 -05:00
$this -> sections [ $section -> id ] = $section ;
2015-12-06 13:10:25 -05:00
return $section ;
2012-02-24 23:12:43 -05:00
}
/**
* Retrieve a customize section .
*
* @ since 3.4 . 0
*
2014-03-04 15:21:14 -05:00
* @ param string $id Section ID .
2015-05-24 01:40:25 -04:00
* @ return WP_Customize_Section | void The section , if set .
2012-02-24 23:12:43 -05:00
*/
public function get_section ( $id ) {
if ( isset ( $this -> sections [ $id ] ) )
return $this -> sections [ $id ];
}
/**
* Remove a customize section .
*
* @ since 3.4 . 0
*
2014-03-04 15:21:14 -05:00
* @ param string $id Section ID .
2012-02-24 23:12:43 -05:00
*/
public function remove_section ( $id ) {
unset ( $this -> sections [ $id ] );
}
2015-05-29 20:03:30 -04:00
/**
* Register a customize section type .
*
* Registered types are eligible to be rendered via JS and created dynamically .
*
* @ since 4.3 . 0
* @ access public
*
2015-07-13 16:32:24 -04:00
* @ see WP_Customize_Section
*
* @ param string $section Name of a custom section which is a subclass of WP_Customize_Section .
2015-05-29 20:03:30 -04:00
*/
public function register_section_type ( $section ) {
$this -> registered_section_types [] = $section ;
}
/**
* Render JS templates for all registered section types .
*
* @ since 4.3 . 0
* @ access public
*/
public function render_section_templates () {
foreach ( $this -> registered_section_types as $section_type ) {
$section = new $section_type ( $this , 'temp' , array () );
$section -> print_template ();
}
}
2012-03-28 00:14:09 -04:00
/**
* Add a customize control .
*
* @ since 3.4 . 0
2015-12-06 13:10:25 -05:00
* @ since 4.5 . 0 Return added WP_Customize_Control instance .
* @ access public
2012-03-28 00:14:09 -04:00
*
2014-03-04 15:21:14 -05:00
* @ param WP_Customize_Control | string $id Customize Control object , or ID .
* @ param array $args Control arguments ; passed to WP_Customize_Control
* constructor .
2015-12-06 13:10:25 -05:00
* @ return WP_Customize_Control The instance of the control that was added .
2012-03-28 00:14:09 -04:00
*/
public function add_control ( $id , $args = array () ) {
2015-01-15 20:06:24 -05:00
if ( $id instanceof WP_Customize_Control ) {
2012-03-28 00:14:09 -04:00
$control = $id ;
2015-01-15 20:06:24 -05:00
} else {
2012-03-28 00:14:09 -04:00
$control = new WP_Customize_Control ( $this , $id , $args );
2015-01-15 20:06:24 -05:00
}
2015-12-06 13:10:25 -05:00
2012-03-28 00:14:09 -04:00
$this -> controls [ $control -> id ] = $control ;
2015-12-06 13:10:25 -05:00
return $control ;
2012-03-28 00:14:09 -04:00
}
/**
* Retrieve a customize control .
*
* @ since 3.4 . 0
*
2014-03-04 15:21:14 -05:00
* @ param string $id ID of the control .
2015-05-24 01:40:25 -04:00
* @ return WP_Customize_Control | void The control object , if set .
2012-03-28 00:14:09 -04:00
*/
public function get_control ( $id ) {
if ( isset ( $this -> controls [ $id ] ) )
return $this -> controls [ $id ];
}
/**
2014-03-04 15:21:14 -05:00
* Remove a customize control .
2012-03-28 00:14:09 -04:00
*
* @ since 3.4 . 0
*
2014-03-04 15:21:14 -05:00
* @ param string $id ID of the control .
2012-03-28 00:14:09 -04:00
*/
public function remove_control ( $id ) {
unset ( $this -> controls [ $id ] );
}
2012-02-24 23:12:43 -05:00
/**
2014-10-24 12:32:18 -04:00
* Register a customize control type .
*
2014-11-28 05:52:22 -05:00
* Registered types are eligible to be rendered via JS and created dynamically .
2014-10-24 12:32:18 -04:00
*
* @ since 4.1 . 0
2014-11-28 05:52:22 -05:00
* @ access public
2014-10-24 12:32:18 -04:00
*
2014-11-28 05:52:22 -05:00
* @ param string $control Name of a custom control which is a subclass of
* { @ see WP_Customize_Control } .
2014-10-24 12:32:18 -04:00
*/
public function register_control_type ( $control ) {
$this -> registered_control_types [] = $control ;
}
/**
* Render JS templates for all registered control types .
*
* @ since 4.1 . 0
2014-11-28 05:52:22 -05:00
* @ access public
2014-10-24 12:32:18 -04:00
*/
public function render_control_templates () {
2014-11-03 16:35:23 -05:00
foreach ( $this -> registered_control_types as $control_type ) {
2014-10-24 12:32:18 -04:00
$control = new $control_type ( $this , 'temp' , array () );
$control -> print_template ();
}
}
2014-11-03 16:35:23 -05:00
/**
* Helper function to compare two objects by priority , ensuring sort stability via instance_number .
2012-02-24 23:12:43 -05:00
*
* @ since 3.4 . 0
*
2015-01-16 13:37:24 -05:00
* @ param WP_Customize_Panel | WP_Customize_Section | WP_Customize_Control $a Object A .
* @ param WP_Customize_Panel | WP_Customize_Section | WP_Customize_Control $b Object B .
2012-07-26 17:45:33 -04:00
* @ return int
2012-02-24 23:12:43 -05:00
*/
2015-01-08 01:10:46 -05:00
protected function _cmp_priority ( $a , $b ) {
2014-11-03 16:35:23 -05:00
if ( $a -> priority === $b -> priority ) {
2015-11-06 01:58:25 -05:00
return $a -> instance_number - $b -> instance_number ;
2014-11-03 16:35:23 -05:00
} else {
return $a -> priority - $b -> priority ;
}
2012-02-24 23:12:43 -05:00
}
/**
2014-06-26 16:17:15 -04:00
* Prepare panels , sections , and controls .
2012-02-24 23:12:43 -05:00
*
2014-03-04 15:21:14 -05:00
* For each , check if required related components exist ,
* whether the user has the necessary capabilities ,
* and sort by priority .
*
2012-02-24 23:12:43 -05:00
* @ since 3.4 . 0
*/
public function prepare_controls () {
2012-03-28 00:14:09 -04:00
$controls = array ();
2014-11-03 16:35:23 -05:00
uasort ( $this -> controls , array ( $this , '_cmp_priority' ) );
2012-03-21 18:55:43 -04:00
2012-03-28 00:14:09 -04:00
foreach ( $this -> controls as $id => $control ) {
2014-06-26 16:17:15 -04:00
if ( ! isset ( $this -> sections [ $control -> section ] ) || ! $control -> check_capabilities () ) {
2012-02-24 23:12:43 -05:00
continue ;
2014-06-26 16:17:15 -04:00
}
2012-02-24 23:12:43 -05:00
2012-03-28 00:14:09 -04:00
$this -> sections [ $control -> section ] -> controls [] = $control ;
$controls [ $id ] = $control ;
2012-02-24 23:12:43 -05:00
}
2012-03-28 00:14:09 -04:00
$this -> controls = $controls ;
2012-03-21 18:55:43 -04:00
2014-03-04 15:21:14 -05:00
// Prepare sections.
2012-03-21 18:55:43 -04:00
uasort ( $this -> sections , array ( $this , '_cmp_priority' ) );
$sections = array ();
2012-02-24 23:12:43 -05:00
foreach ( $this -> sections as $section ) {
2015-06-12 18:54:25 -04:00
if ( ! $section -> check_capabilities () ) {
2012-03-21 18:55:43 -04:00
continue ;
2014-06-26 16:17:15 -04:00
}
2012-03-21 18:55:43 -04:00
2012-03-28 00:14:09 -04:00
usort ( $section -> controls , array ( $this , '_cmp_priority' ) );
2014-06-26 16:17:15 -04:00
if ( ! $section -> panel ) {
// Top-level section.
Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections.
* Introduce API to expand and focus a control, section or panel.
* Allow deep-linking to panels, sections, and controls inside of the Customizer.
* Clean up `accordion.js`, removing all Customizer-specific logic.
* Add initial unit tests for `wp.customize.Class` in `customize-base.js`.
https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API.
props westonruter, celloexpressions, ryankienstra.
see #28032, #28579, #28580, #28650, #28709, #29758.
fixes #29529.
Built from https://develop.svn.wordpress.org/trunk@30102
git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2014-10-29 18:51:22 -04:00
$sections [ $section -> id ] = $section ;
2014-06-26 16:17:15 -04:00
} else {
// This section belongs to a panel.
if ( isset ( $this -> panels [ $section -> panel ] ) ) {
Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections.
* Introduce API to expand and focus a control, section or panel.
* Allow deep-linking to panels, sections, and controls inside of the Customizer.
* Clean up `accordion.js`, removing all Customizer-specific logic.
* Add initial unit tests for `wp.customize.Class` in `customize-base.js`.
https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API.
props westonruter, celloexpressions, ryankienstra.
see #28032, #28579, #28580, #28650, #28709, #29758.
fixes #29529.
Built from https://develop.svn.wordpress.org/trunk@30102
git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2014-10-29 18:51:22 -04:00
$this -> panels [ $section -> panel ] -> sections [ $section -> id ] = $section ;
2014-06-26 16:17:15 -04:00
}
}
2012-03-21 18:55:43 -04:00
}
$this -> sections = $sections ;
2014-06-26 16:17:15 -04:00
// Prepare panels.
uasort ( $this -> panels , array ( $this , '_cmp_priority' ) );
$panels = array ();
foreach ( $this -> panels as $panel ) {
2015-06-12 18:54:25 -04:00
if ( ! $panel -> check_capabilities () ) {
2014-06-26 16:17:15 -04:00
continue ;
}
Improve/introduce Customizer JavaScript models for Controls, Sections, and Panels.
* Introduce models for panels and sections.
* Introduce API to expand and focus a control, section or panel.
* Allow deep-linking to panels, sections, and controls inside of the Customizer.
* Clean up `accordion.js`, removing all Customizer-specific logic.
* Add initial unit tests for `wp.customize.Class` in `customize-base.js`.
https://make.wordpress.org/core/2014/10/27/toward-a-complete-javascript-api-for-the-customizer/ provides an overview of how to use the JavaScript API.
props westonruter, celloexpressions, ryankienstra.
see #28032, #28579, #28580, #28650, #28709, #29758.
fixes #29529.
Built from https://develop.svn.wordpress.org/trunk@30102
git-svn-id: http://core.svn.wordpress.org/trunk@30102 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2014-10-29 18:51:22 -04:00
uasort ( $panel -> sections , array ( $this , '_cmp_priority' ) );
$panels [ $panel -> id ] = $panel ;
2014-06-26 16:17:15 -04:00
}
$this -> panels = $panels ;
2014-08-14 00:43:16 -04:00
// Sort panels and top-level sections together.
$this -> containers = array_merge ( $this -> panels , $this -> sections );
uasort ( $this -> containers , array ( $this , '_cmp_priority' ) );
2012-03-21 18:55:43 -04:00
}
/**
* Enqueue scripts for customize controls .
*
* @ since 3.4 . 0
*/
public function enqueue_control_scripts () {
2012-03-28 00:14:09 -04:00
foreach ( $this -> controls as $control ) {
$control -> enqueue ();
2012-02-24 23:12:43 -05:00
}
}
2015-09-17 15:42:26 -04:00
/**
2015-09-19 02:40:26 -04:00
* Determine whether the user agent is iOS .
2015-09-17 15:42:26 -04:00
*
* @ since 4.4 . 0
* @ access public
*
2015-09-19 02:40:26 -04:00
* @ return bool Whether the user agent is iOS .
2015-09-17 15:42:26 -04:00
*/
public function is_ios () {
return wp_is_mobile () && preg_match ( '/iPad|iPod|iPhone/' , $_SERVER [ 'HTTP_USER_AGENT' ] );
}
/**
* Get the template string for the Customizer pane document title .
*
* @ since 4.4 . 0
* @ access public
*
2015-09-19 02:40:26 -04:00
* @ return string The template string for the document title .
2015-09-17 15:42:26 -04:00
*/
public function get_document_title_template () {
if ( $this -> is_theme_active () ) {
2015-10-07 19:54:24 -04:00
/* translators: %s: document title from the preview */
$document_title_tmpl = __ ( 'Customize: %s' );
2015-09-17 15:42:26 -04:00
} else {
2015-10-07 19:54:24 -04:00
/* translators: %s: document title from the preview */
$document_title_tmpl = __ ( 'Live Preview: %s' );
2015-09-17 15:42:26 -04:00
}
$document_title_tmpl = html_entity_decode ( $document_title_tmpl , ENT_QUOTES , 'UTF-8' ); // Because exported to JS and assigned to document.title.
return $document_title_tmpl ;
}
/**
* Set the initial URL to be previewed .
*
* URL is validated .
*
* @ since 4.4 . 0
* @ access public
*
2015-09-19 02:40:26 -04:00
* @ param string $preview_url URL to be previewed .
2015-09-17 15:42:26 -04:00
*/
public function set_preview_url ( $preview_url ) {
$this -> preview_url = wp_validate_redirect ( $preview_url , home_url ( '/' ) );
}
/**
* Get the initial URL to be previewed .
*
* @ since 4.4 . 0
* @ access public
*
2015-09-19 02:40:26 -04:00
* @ return string URL being previewed .
2015-09-17 15:42:26 -04:00
*/
public function get_preview_url () {
if ( empty ( $this -> preview_url ) ) {
$preview_url = home_url ( '/' );
} else {
$preview_url = $this -> preview_url ;
}
return $preview_url ;
}
/**
* Set URL to link the user to when closing the Customizer .
*
* URL is validated .
*
* @ since 4.4 . 0
* @ access public
*
2015-09-19 02:40:26 -04:00
* @ param string $return_url URL for return link .
2015-09-17 15:42:26 -04:00
*/
public function set_return_url ( $return_url ) {
$return_url = remove_query_arg ( wp_removable_query_args (), $return_url );
$return_url = wp_validate_redirect ( $return_url );
$this -> return_url = $return_url ;
}
/**
* Get URL to link the user to when closing the Customizer .
*
* @ since 4.4 . 0
* @ access public
*
2015-09-19 02:40:26 -04:00
* @ return string URL for link to close Customizer .
2015-09-17 15:42:26 -04:00
*/
public function get_return_url () {
2015-11-01 01:40:28 -05:00
$referer = wp_get_referer ();
2015-09-17 15:42:26 -04:00
if ( $this -> return_url ) {
$return_url = $this -> return_url ;
2015-11-13 00:25:28 -05:00
} else if ( $referer && 'customize.php' !== basename ( parse_url ( $referer , PHP_URL_PATH ) ) ) {
2015-11-01 01:40:28 -05:00
$return_url = $referer ;
2015-09-17 15:42:26 -04:00
} else if ( $this -> preview_url ) {
$return_url = $this -> preview_url ;
} else {
2015-11-01 01:40:28 -05:00
$return_url = home_url ( '/' );
2015-09-17 15:42:26 -04:00
}
return $return_url ;
}
/**
* Set the autofocused constructs .
*
2015-09-19 02:40:26 -04:00
* @ since 4.4 . 0
* @ access public
*
2015-09-17 15:42:26 -04:00
* @ param array $autofocus {
* Mapping of 'panel' , 'section' , 'control' to the ID which should be autofocused .
*
* @ type string [ $control ] ID for control to be autofocused .
* @ type string [ $section ] ID for section to be autofocused .
* @ type string [ $panel ] ID for panel to be autofocused .
* }
*/
public function set_autofocus ( $autofocus ) {
$this -> autofocus = array_filter ( wp_array_slice_assoc ( $autofocus , array ( 'panel' , 'section' , 'control' ) ), 'is_string' );
}
/**
* Get the autofocused constructs .
*
* @ since 4.4 . 0
* @ access public
*
* @ return array {
* Mapping of 'panel' , 'section' , 'control' to the ID which should be autofocused .
*
* @ type string [ $control ] ID for control to be autofocused .
* @ type string [ $section ] ID for section to be autofocused .
* @ type string [ $panel ] ID for panel to be autofocused .
* }
*/
public function get_autofocus () {
return $this -> autofocus ;
}
/**
* Print JavaScript settings for parent window .
*
2015-09-19 02:40:26 -04:00
* @ since 4.4 . 0
2015-09-17 15:42:26 -04:00
*/
public function customize_pane_settings () {
/*
* If the frontend and the admin are served from the same domain , load the
* preview over ssl if the Customizer is being loaded over ssl . This avoids
* insecure content warnings . This is not attempted if the admin and frontend
* are on different domains to avoid the case where the frontend doesn ' t have
* ssl certs . Domain mapping plugins can allow other urls in these conditions
* using the customize_allowed_urls filter .
*/
$allowed_urls = array ( home_url ( '/' ) );
$admin_origin = parse_url ( admin_url () );
$home_origin = parse_url ( home_url () );
$cross_domain = ( strtolower ( $admin_origin [ 'host' ] ) !== strtolower ( $home_origin [ 'host' ] ) );
if ( is_ssl () && ! $cross_domain ) {
$allowed_urls [] = home_url ( '/' , 'https' );
}
/**
* Filter the list of URLs allowed to be clicked and followed in the Customizer preview .
*
* @ since 3.4 . 0
*
* @ param array $allowed_urls An array of allowed URLs .
*/
$allowed_urls = array_unique ( apply_filters ( 'customize_allowed_urls' , $allowed_urls ) );
$login_url = add_query_arg ( array (
'interim-login' => 1 ,
'customize-login' => 1 ,
), wp_login_url () );
// Prepare Customizer settings to pass to JavaScript.
$settings = array (
'theme' => array (
'stylesheet' => $this -> get_stylesheet (),
'active' => $this -> is_theme_active (),
),
'url' => array (
'preview' => esc_url_raw ( $this -> get_preview_url () ),
'parent' => esc_url_raw ( admin_url () ),
'activated' => esc_url_raw ( home_url ( '/' ) ),
'ajax' => esc_url_raw ( admin_url ( 'admin-ajax.php' , 'relative' ) ),
'allowed' => array_map ( 'esc_url_raw' , $allowed_urls ),
'isCrossDomain' => $cross_domain ,
'home' => esc_url_raw ( home_url ( '/' ) ),
'login' => esc_url_raw ( $login_url ),
),
'browser' => array (
'mobile' => wp_is_mobile (),
'ios' => $this -> is_ios (),
),
'panels' => array (),
'sections' => array (),
'nonce' => array (
'save' => wp_create_nonce ( 'save-customize_' . $this -> get_stylesheet () ),
'preview' => wp_create_nonce ( 'preview-customize_' . $this -> get_stylesheet () ),
),
'autofocus' => array (),
'documentTitleTmpl' => $this -> get_document_title_template (),
);
// Prepare Customize Section objects to pass to JavaScript.
foreach ( $this -> sections () as $id => $section ) {
if ( $section -> check_capabilities () ) {
$settings [ 'sections' ][ $id ] = $section -> json ();
}
}
// Prepare Customize Panel objects to pass to JavaScript.
foreach ( $this -> panels () as $panel_id => $panel ) {
if ( $panel -> check_capabilities () ) {
$settings [ 'panels' ][ $panel_id ] = $panel -> json ();
foreach ( $panel -> sections as $section_id => $section ) {
if ( $section -> check_capabilities () ) {
$settings [ 'sections' ][ $section_id ] = $section -> json ();
}
}
}
}
// Pass to frontend the Customizer construct being deeplinked.
foreach ( $this -> get_autofocus () as $type => $id ) {
$can_autofocus = (
( 'control' === $type && $this -> get_control ( $id ) && $this -> get_control ( $id ) -> check_capabilities () )
||
( 'section' === $type && isset ( $settings [ 'sections' ][ $id ] ) )
||
( 'panel' === $type && isset ( $settings [ 'panels' ][ $id ] ) )
);
if ( $can_autofocus ) {
$settings [ 'autofocus' ][ $type ] = $id ;
}
}
?>
< script type = " text/javascript " >
var _wpCustomizeSettings = < ? php echo wp_json_encode ( $settings ); ?> ;
_wpCustomizeSettings . controls = {};
_wpCustomizeSettings . settings = {};
< ? php
// Serialize settings one by one to improve memory usage.
echo " (function ( s ) { \n " ;
foreach ( $this -> settings () as $setting ) {
if ( $setting -> check_capabilities () ) {
printf (
" s[%s] = %s; \n " ,
wp_json_encode ( $setting -> id ),
wp_json_encode ( array (
'value' => $setting -> js_value (),
'transport' => $setting -> transport ,
'dirty' => $setting -> dirty ,
) )
);
}
}
echo " })( _wpCustomizeSettings.settings ); \n " ;
// Serialize controls one by one to improve memory usage.
echo " (function ( c ) { \n " ;
foreach ( $this -> controls () as $control ) {
if ( $control -> check_capabilities () ) {
printf (
" c[%s] = %s; \n " ,
wp_json_encode ( $control -> id ),
wp_json_encode ( $control -> json () )
);
}
}
echo " })( _wpCustomizeSettings.controls ); \n " ;
?>
</ script >
< ? php
}
2012-02-24 23:12:43 -05:00
/**
* Register some default controls .
*
* @ since 3.4 . 0
*/
public function register_controls () {
2015-05-29 20:03:30 -04:00
/* Panel, Section, and Control Types */
$this -> register_panel_type ( 'WP_Customize_Panel' );
$this -> register_section_type ( 'WP_Customize_Section' );
$this -> register_section_type ( 'WP_Customize_Sidebar_Section' );
2014-10-24 12:32:18 -04:00
$this -> register_control_type ( 'WP_Customize_Color_Control' );
2015-03-10 14:02:28 -04:00
$this -> register_control_type ( 'WP_Customize_Media_Control' );
2014-11-11 18:52:22 -05:00
$this -> register_control_type ( 'WP_Customize_Upload_Control' );
$this -> register_control_type ( 'WP_Customize_Image_Control' );
2014-12-15 18:28:23 -05:00
$this -> register_control_type ( 'WP_Customize_Background_Image_Control' );
2015-07-10 17:33:24 -04:00
$this -> register_control_type ( 'WP_Customize_Cropped_Image_Control' );
$this -> register_control_type ( 'WP_Customize_Site_Icon_Control' );
2015-02-24 15:31:24 -05:00
$this -> register_control_type ( 'WP_Customize_Theme_Control' );
/* Themes */
$this -> add_section ( new WP_Customize_Themes_Section ( $this , 'themes' , array (
2015-04-01 18:51:27 -04:00
'title' => $this -> theme () -> display ( 'Name' ),
2015-02-24 15:31:24 -05:00
'capability' => 'switch_themes' ,
2015-04-01 18:51:27 -04:00
'priority' => 0 ,
2015-02-24 15:31:24 -05:00
) ) );
// Themes Setting (unused - the theme is considerably more fundamental to the Customizer experience).
$this -> add_setting ( new WP_Customize_Filter_Setting ( $this , 'active_theme' , array (
'capability' => 'switch_themes' ,
) ) );
require_once ( ABSPATH . 'wp-admin/includes/theme.php' );
// Theme Controls.
2015-04-22 12:15:27 -04:00
// Add a control for the active/original theme.
if ( ! $this -> is_theme_active () ) {
$themes = wp_prepare_themes_for_js ( array ( wp_get_theme ( $this -> original_stylesheet ) ) );
$active_theme = current ( $themes );
$active_theme [ 'isActiveTheme' ] = true ;
$this -> add_control ( new WP_Customize_Theme_Control ( $this , $active_theme [ 'id' ], array (
'theme' => $active_theme ,
'section' => 'themes' ,
'settings' => 'active_theme' ,
) ) );
}
2015-02-24 15:31:24 -05:00
$themes = wp_prepare_themes_for_js ();
foreach ( $themes as $theme ) {
2015-04-22 12:15:27 -04:00
if ( $theme [ 'active' ] || $theme [ 'id' ] === $this -> original_stylesheet ) {
2015-04-01 18:51:27 -04:00
continue ;
}
2015-02-24 15:31:24 -05:00
$theme_id = 'theme_' . $theme [ 'id' ];
2015-04-22 12:15:27 -04:00
$theme [ 'isActiveTheme' ] = false ;
2015-02-24 15:31:24 -05:00
$this -> add_control ( new WP_Customize_Theme_Control ( $this , $theme_id , array (
2015-04-01 18:51:27 -04:00
'theme' => $theme ,
'section' => 'themes' ,
2015-02-24 15:31:24 -05:00
'settings' => 'active_theme' ,
) ) );
}
2015-07-10 17:33:24 -04:00
/* Site Identity */
2012-02-24 23:12:43 -05:00
2012-05-25 15:52:54 -04:00
$this -> add_section ( 'title_tagline' , array (
2015-07-10 17:33:24 -04:00
'title' => __ ( 'Site Identity' ),
2012-05-25 15:52:54 -04:00
'priority' => 20 ,
) );
$this -> add_setting ( 'blogname' , array (
'default' => get_option ( 'blogname' ),
'type' => 'option' ,
'capability' => 'manage_options' ,
) );
$this -> add_control ( 'blogname' , array (
'label' => __ ( 'Site Title' ),
'section' => 'title_tagline' ,
) );
$this -> add_setting ( 'blogdescription' , array (
'default' => get_option ( 'blogdescription' ),
'type' => 'option' ,
'capability' => 'manage_options' ,
) );
$this -> add_control ( 'blogdescription' , array (
'label' => __ ( 'Tagline' ),
'section' => 'title_tagline' ,
) );
2015-07-10 17:33:24 -04:00
$this -> add_setting ( 'site_icon' , array (
'type' => 'option' ,
'capability' => 'manage_options' ,
'transport' => 'postMessage' , // Previewed with JS in the Customizer controls window.
) );
$this -> add_control ( new WP_Customize_Site_Icon_Control ( $this , 'site_icon' , array (
'label' => __ ( 'Site Icon' ),
2015-12-14 07:54:27 -05:00
'description' => sprintf (
/* translators: %s: site icon size in pixels */
__ ( 'The Site Icon is used as a browser and app icon for your site. Icons must be square, and at least %s pixels wide and tall.' ),
'<strong>512</strong>'
),
2015-07-10 17:33:24 -04:00
'section' => 'title_tagline' ,
'priority' => 60 ,
'height' => 512 ,
'width' => 512 ,
) ) );
2012-05-25 15:52:54 -04:00
/* Colors */
$this -> add_section ( 'colors' , array (
'title' => __ ( 'Colors' ),
'priority' => 40 ,
2012-02-24 23:12:43 -05:00
) );
$this -> add_setting ( 'header_textcolor' , array (
2012-03-28 00:14:09 -04:00
'theme_supports' => array ( 'custom-header' , 'header-text' ),
'default' => get_theme_support ( 'custom-header' , 'default-text-color' ),
2012-05-26 14:44:31 -04:00
'sanitize_callback' => array ( $this , '_sanitize_header_textcolor' ),
'sanitize_js_callback' => 'maybe_hash_hex_color' ,
2012-03-28 00:14:09 -04:00
) );
2012-05-25 15:52:54 -04:00
// Input type: checkbox
// With custom value
2012-03-28 00:14:09 -04:00
$this -> add_control ( 'display_header_text' , array (
'settings' => 'header_textcolor' ,
2015-12-13 12:50:28 -05:00
'label' => __ ( 'Display Site Title and Tagline' ),
2012-05-25 15:52:54 -04:00
'section' => 'title_tagline' ,
2012-03-28 00:14:09 -04:00
'type' => 'checkbox' ,
2015-07-10 17:33:24 -04:00
'priority' => 40 ,
2012-02-24 23:12:43 -05:00
) );
2012-04-25 17:03:29 -04:00
$this -> add_control ( new WP_Customize_Color_Control ( $this , 'header_textcolor' , array (
2012-05-26 11:24:42 -04:00
'label' => __ ( 'Header Text Color' ),
2012-05-25 15:52:54 -04:00
'section' => 'colors' ,
2012-04-25 17:03:29 -04:00
) ) );
2012-02-24 23:12:43 -05:00
// Input type: Color
// With sanitize_callback
$this -> add_setting ( 'background_color' , array (
2012-05-26 14:44:31 -04:00
'default' => get_theme_support ( 'custom-background' , 'default-color' ),
'theme_supports' => 'custom-background' ,
'sanitize_callback' => 'sanitize_hex_color_no_hash' ,
'sanitize_js_callback' => 'maybe_hash_hex_color' ,
2012-03-28 00:14:09 -04:00
) );
2012-04-25 17:03:29 -04:00
$this -> add_control ( new WP_Customize_Color_Control ( $this , 'background_color' , array (
2012-03-28 00:14:09 -04:00
'label' => __ ( 'Background Color' ),
2012-05-25 15:52:54 -04:00
'section' => 'colors' ,
2012-04-25 17:03:29 -04:00
) ) );
2012-03-15 00:14:05 -04:00
2012-05-25 15:52:54 -04:00
/* Custom Header */
$this -> add_section ( 'header_image' , array (
'title' => __ ( 'Header Image' ),
'theme_supports' => 'custom-header' ,
'priority' => 60 ,
) );
2012-06-09 20:32:19 -04:00
$this -> add_setting ( new WP_Customize_Filter_Setting ( $this , 'header_image' , array (
2012-05-25 15:52:54 -04:00
'default' => get_theme_support ( 'custom-header' , 'default-image' ),
'theme_supports' => 'custom-header' ,
2012-06-09 20:32:19 -04:00
) ) );
$this -> add_setting ( new WP_Customize_Header_Image_Setting ( $this , 'header_image_data' , array (
// 'default' => get_theme_support( 'custom-header', 'default-image' ),
'theme_supports' => 'custom-header' ,
) ) );
2012-05-25 15:52:54 -04:00
$this -> add_control ( new WP_Customize_Header_Image_Control ( $this ) );
/* Custom Background */
$this -> add_section ( 'background_image' , array (
'title' => __ ( 'Background Image' ),
'theme_supports' => 'custom-background' ,
'priority' => 80 ,
) );
2012-03-15 00:14:05 -04:00
$this -> add_setting ( 'background_image' , array (
2012-03-23 21:02:29 -04:00
'default' => get_theme_support ( 'custom-background' , 'default-image' ),
2012-03-28 00:14:09 -04:00
'theme_supports' => 'custom-background' ,
) );
2012-06-11 16:49:45 -04:00
$this -> add_setting ( new WP_Customize_Background_Image_Setting ( $this , 'background_image_thumb' , array (
'theme_supports' => 'custom-background' ,
) ) );
2012-05-25 16:26:25 -04:00
$this -> add_control ( new WP_Customize_Background_Image_Control ( $this ) );
2012-03-22 04:07:44 -04:00
$this -> add_setting ( 'background_repeat' , array (
2014-07-11 16:27:14 -04:00
'default' => get_theme_support ( 'custom-background' , 'default-repeat' ),
2012-03-28 00:14:09 -04:00
'theme_supports' => 'custom-background' ,
) );
$this -> add_control ( 'background_repeat' , array (
'label' => __ ( 'Background Repeat' ),
2012-05-25 15:52:54 -04:00
'section' => 'background_image' ,
2012-03-28 00:14:09 -04:00
'type' => 'radio' ,
2012-03-22 04:07:44 -04:00
'choices' => array (
'no-repeat' => __ ( 'No Repeat' ),
'repeat' => __ ( 'Tile' ),
'repeat-x' => __ ( 'Tile Horizontally' ),
'repeat-y' => __ ( 'Tile Vertically' ),
),
) );
$this -> add_setting ( 'background_position_x' , array (
2014-07-11 16:27:14 -04:00
'default' => get_theme_support ( 'custom-background' , 'default-position-x' ),
2012-03-28 00:14:09 -04:00
'theme_supports' => 'custom-background' ,
) );
$this -> add_control ( 'background_position_x' , array (
'label' => __ ( 'Background Position' ),
2012-05-25 15:52:54 -04:00
'section' => 'background_image' ,
2012-03-28 00:14:09 -04:00
'type' => 'radio' ,
2012-03-22 04:07:44 -04:00
'choices' => array (
'left' => __ ( 'Left' ),
'center' => __ ( 'Center' ),
'right' => __ ( 'Right' ),
),
) );
$this -> add_setting ( 'background_attachment' , array (
2014-07-11 16:27:14 -04:00
'default' => get_theme_support ( 'custom-background' , 'default-attachment' ),
2012-03-28 00:14:09 -04:00
'theme_supports' => 'custom-background' ,
) );
$this -> add_control ( 'background_attachment' , array (
'label' => __ ( 'Background Attachment' ),
2012-05-25 15:52:54 -04:00
'section' => 'background_image' ,
2012-03-28 00:14:09 -04:00
'type' => 'radio' ,
2012-03-22 04:07:44 -04:00
'choices' => array (
'scroll' => __ ( 'Scroll' ),
2014-07-11 16:27:14 -04:00
'fixed' => __ ( 'Fixed' ),
2012-03-22 04:07:44 -04:00
),
2012-02-24 23:12:43 -05:00
) );
2012-05-25 14:41:22 -04:00
// If the theme is using the default background callback, we can update
// the background CSS using postMessage.
if ( get_theme_support ( 'custom-background' , 'wp-head-callback' ) === '_custom_background_cb' ) {
foreach ( array ( 'color' , 'image' , 'position_x' , 'repeat' , 'attachment' ) as $prop ) {
$this -> get_setting ( 'background_' . $prop ) -> transport = 'postMessage' ;
}
}
2012-02-24 23:12:43 -05:00
/* Static Front Page */
// #WP19627
2015-01-18 01:01:24 -05:00
// Replicate behavior from options-reading.php and hide front page options if there are no pages
if ( get_pages () ) {
$this -> add_section ( 'static_front_page' , array (
'title' => __ ( 'Static Front Page' ),
// 'theme_supports' => 'static-front-page',
'priority' => 120 ,
'description' => __ ( 'Your theme supports a static front page.' ),
) );
$this -> add_setting ( 'show_on_front' , array (
'default' => get_option ( 'show_on_front' ),
'capability' => 'manage_options' ,
'type' => 'option' ,
// 'theme_supports' => 'static-front-page',
) );
$this -> add_control ( 'show_on_front' , array (
'label' => __ ( 'Front page displays' ),
'section' => 'static_front_page' ,
'type' => 'radio' ,
'choices' => array (
'posts' => __ ( 'Your latest posts' ),
'page' => __ ( 'A static page' ),
),
) );
$this -> add_setting ( 'page_on_front' , array (
'type' => 'option' ,
'capability' => 'manage_options' ,
// 'theme_supports' => 'static-front-page',
) );
$this -> add_control ( 'page_on_front' , array (
'label' => __ ( 'Front page' ),
'section' => 'static_front_page' ,
'type' => 'dropdown-pages' ,
) );
$this -> add_setting ( 'page_for_posts' , array (
'type' => 'option' ,
'capability' => 'manage_options' ,
// 'theme_supports' => 'static-front-page',
) );
$this -> add_control ( 'page_for_posts' , array (
'label' => __ ( 'Posts page' ),
'section' => 'static_front_page' ,
'type' => 'dropdown-pages' ,
) );
}
2012-02-24 23:12:43 -05:00
}
2012-05-23 11:36:27 -04:00
2015-02-08 18:11:25 -05:00
/**
* Add settings from the POST data that were not added with code , e . g . dynamically - created settings for Widgets
*
* @ since 4.2 . 0
2015-04-05 11:07:27 -04:00
* @ access public
*
* @ see add_dynamic_settings ()
2015-02-08 18:11:25 -05:00
*/
public function register_dynamic_settings () {
$this -> add_dynamic_settings ( array_keys ( $this -> unsanitized_post_values () ) );
}
2012-05-26 14:44:31 -04:00
/**
* Callback for validating the header_textcolor value .
*
* Accepts 'blank' , and otherwise uses sanitize_hex_color_no_hash () .
2013-07-12 16:41:46 -04:00
* Returns default text color if hex color is empty .
2012-05-26 14:44:31 -04:00
*
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ param string $color
2015-05-21 18:05:24 -04:00
* @ return mixed
2012-05-26 14:44:31 -04:00
*/
public function _sanitize_header_textcolor ( $color ) {
2013-07-12 16:41:46 -04:00
if ( 'blank' === $color )
return 'blank' ;
$color = sanitize_hex_color_no_hash ( $color );
if ( empty ( $color ) )
$color = get_theme_support ( 'custom-header' , 'default-text-color' );
return $color ;
2012-05-26 14:44:31 -04:00
}
2014-05-22 15:01:15 -04:00
}
2012-05-23 11:36:27 -04:00
2012-05-26 14:44:31 -04:00
/**
2014-03-04 15:21:14 -05:00
* Sanitizes a hex color .
2012-05-26 14:44:31 -04:00
*
2015-05-24 01:40:25 -04:00
* Returns either '' , a 3 or 6 digit hex color ( with #), or nothing.
2014-03-04 15:21:14 -05:00
* For sanitizing values without a #, see sanitize_hex_color_no_hash().
2012-05-26 14:44:31 -04:00
*
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ param string $color
2015-05-24 01:40:25 -04:00
* @ return string | void
2012-05-26 14:44:31 -04:00
*/
function sanitize_hex_color ( $color ) {
if ( '' === $color )
return '' ;
2012-02-24 23:12:43 -05:00
2012-05-25 16:58:49 -04:00
// 3 or 6 hex digits, or the empty string.
2012-05-26 14:44:31 -04:00
if ( preg_match ( '|^#([A-Fa-f0-9]{3}){1,2}$|' , $color ) )
2012-02-24 23:12:43 -05:00
return $color ;
2012-05-23 13:56:42 -04:00
}
2012-05-26 14:44:31 -04:00
/**
* Sanitizes a hex color without a hash . Use sanitize_hex_color () when possible .
*
* Saving hex colors without a hash puts the burden of adding the hash on the
* UI , which makes it difficult to use or upgrade to other color types such as
* rgba , hsl , rgb , and html color names .
*
* Returns either '' , a 3 or 6 digit hex color ( without a #), or null.
*
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ param string $color
* @ return string | null
2012-05-26 14:44:31 -04:00
*/
function sanitize_hex_color_no_hash ( $color ) {
$color = ltrim ( $color , '#' );
if ( '' === $color )
return '' ;
return sanitize_hex_color ( '#' . $color ) ? $color : null ;
}
/**
* Ensures that any hex color is properly hashed .
* Otherwise , returns value untouched .
*
* This method should only be necessary if using sanitize_hex_color_no_hash () .
*
* @ since 3.4 . 0
2012-07-26 17:45:33 -04:00
*
* @ param string $color
* @ return string
2012-05-26 14:44:31 -04:00
*/
function maybe_hash_hex_color ( $color ) {
if ( $unhashed = sanitize_hex_color_no_hash ( $color ) )
return '#' . $unhashed ;
return $color ;
2012-06-08 15:22:11 -04:00
}