diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index e7f4f6bd56..a6b47f9c17 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -1588,7 +1588,8 @@ function wp_ajax_save_widget() { } function wp_ajax_update_widget() { - WP_Customize_Widgets::wp_ajax_update_widget(); + global $wp_customize; + $wp_customize->widgets->wp_ajax_update_widget(); } function wp_ajax_upload_attachment() { diff --git a/wp-includes/class-wp-customize-control.php b/wp-includes/class-wp-customize-control.php index cce91951da..e520b6de65 100644 --- a/wp-includes/class-wp-customize-control.php +++ b/wp-includes/class-wp-customize-control.php @@ -1080,7 +1080,7 @@ class WP_Widget_Form_Customize_Control extends WP_Customize_Control { ); $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) ); - echo WP_Customize_Widgets::get_widget_control( $args ); + echo $this->manager->widgets->get_widget_control( $args ); } } diff --git a/wp-includes/class-wp-customize-manager.php b/wp-includes/class-wp-customize-manager.php index 7f337f5f62..18a1d761c8 100644 --- a/wp-includes/class-wp-customize-manager.php +++ b/wp-includes/class-wp-customize-manager.php @@ -37,6 +37,13 @@ final class WP_Customize_Manager { */ protected $previewing = false; + /** + * Methods and properties deailing with managing widgets in the customizer. + * + * @var WP_Customize_Widgets + */ + public $widgets; + protected $settings = array(); protected $sections = array(); protected $controls = array(); @@ -63,7 +70,7 @@ final class WP_Customize_Manager { require( ABSPATH . WPINC . '/class-wp-customize-control.php' ); require( ABSPATH . WPINC . '/class-wp-customize-widgets.php' ); - WP_Customize_Widgets::setup(); // This should be integrated. + $this->widgets = new WP_Customize_Widgets( $this ); add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) ); diff --git a/wp-includes/class-wp-customize-widgets.php b/wp-includes/class-wp-customize-widgets.php index 7034e84909..18ffb468f8 100644 --- a/wp-includes/class-wp-customize-widgets.php +++ b/wp-includes/class-wp-customize-widgets.php @@ -4,23 +4,28 @@ * * Implements widget management in the Customizer. * - * @since 3.9.0 * @package WordPress * @subpackage Customize + * @since 3.9.0 */ -class WP_Customize_Widgets { +final class WP_Customize_Widgets { const UPDATE_WIDGET_AJAX_ACTION = 'update-widget'; const UPDATE_WIDGET_NONCE_POST_KEY = 'update-sidebar-widgets-nonce'; + /** + * @access public + * @var WP_Customize_Manager + */ + public $manager; + /** * All id_bases for widgets defined in core * * @since 3.9.0 - * @static * @access protected * @var array */ - protected static $core_widget_id_bases = array( + protected $core_widget_id_bases = array( 'archives', 'calendar', 'categories', @@ -38,54 +43,51 @@ class WP_Customize_Widgets { /** * @since 3.9.0 - * @static * @access protected * @var */ - protected static $_customized; + protected $_customized; /** * @since 3.9.0 - * @static * @access protected * @var array */ - protected static $_prepreview_added_filters = array(); + protected $_prepreview_added_filters = array(); /** * @since 3.9.0 - * @static * @access protected * @var array */ - static protected $rendered_sidebars = array(); + protected $rendered_sidebars = array(); /** * @since 3.9.0 - * @static * @access protected * @var array */ - static protected $rendered_widgets = array(); + protected $rendered_widgets = array(); /** * Initial loader. * * @since 3.9.0 - * @static * @access public */ - static function setup() { - add_action( 'after_setup_theme', array( __CLASS__, 'setup_widget_addition_previews' ) ); - add_action( 'customize_controls_init', array( __CLASS__, 'customize_controls_init' ) ); - add_action( 'customize_register', array( __CLASS__, 'schedule_customize_register' ), 1 ); - add_action( 'customize_controls_enqueue_scripts', array( __CLASS__, 'customize_controls_enqueue_deps' ) ); - add_action( 'customize_controls_print_footer_scripts', array( __CLASS__, 'output_widget_control_templates' ) ); - add_action( 'customize_preview_init', array( __CLASS__, 'customize_preview_init' ) ); + public function __construct( WP_Customize_Manager $manager ) { + $this->manager = $manager; - add_action( 'dynamic_sidebar', array( __CLASS__, 'tally_rendered_widgets' ) ); - add_filter( 'is_active_sidebar', array( __CLASS__, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 ); - add_filter( 'dynamic_sidebar_has_widgets', array( __CLASS__, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 ); + add_action( 'after_setup_theme', array( $this, 'setup_widget_addition_previews' ) ); + add_action( 'customize_controls_init', array( $this, 'customize_controls_init' ) ); + add_action( 'customize_register', array( $this, 'schedule_customize_register' ), 1 ); + add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue_deps' ) ); + add_action( 'customize_controls_print_footer_scripts', array( $this, 'output_widget_control_templates' ) ); + add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) ); + + add_action( 'dynamic_sidebar', array( $this, 'tally_rendered_widgets' ) ); + add_filter( 'is_active_sidebar', array( $this, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 ); + add_filter( 'dynamic_sidebar_has_widgets', array( $this, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 ); } /** @@ -93,17 +95,17 @@ class WP_Customize_Widgets { * * @since 3.9.0 * - * @static - * @access public + * @access protected * * @param string $name Post value. * @param mixed $default Default post value. * @return mixed Unslashed post value or default value. */ - static function get_post_value( $name, $default = null ) { + protected function get_post_value( $name, $default = null ) { if ( ! isset( $_POST[ $name ] ) ) { return $default; } + return wp_unslash( $_POST[$name] ); } @@ -115,26 +117,24 @@ class WP_Customize_Widgets { * * @since 3.9.0 * - * @static * @access public * @global WP_Customize_Manager $wp_customize */ - static function setup_widget_addition_previews() { - global $wp_customize; + public function setup_widget_addition_previews() { $is_customize_preview = ( - ( ! empty( $wp_customize ) ) + ( ! empty( $this->manager ) ) && ( ! is_admin() ) && - ( 'on' === self::get_post_value( 'wp_customize' ) ) + ( 'on' === $this->get_post_value( 'wp_customize' ) ) && - check_ajax_referer( 'preview-customize_' . $wp_customize->get_stylesheet(), 'nonce', false ) + check_ajax_referer( 'preview-customize_' . $this->manager->get_stylesheet(), 'nonce', false ) ); $is_ajax_widget_update = ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && - self::get_post_value( 'action' ) === self::UPDATE_WIDGET_AJAX_ACTION + $this->get_post_value( 'action' ) === self::UPDATE_WIDGET_AJAX_ACTION && check_ajax_referer( self::UPDATE_WIDGET_AJAX_ACTION, self::UPDATE_WIDGET_NONCE_POST_KEY, false ) ); @@ -142,9 +142,9 @@ class WP_Customize_Widgets { $is_ajax_customize_save = ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && - self::get_post_value( 'action' ) === 'customize_save' + $this->get_post_value( 'action' ) === 'customize_save' && - check_ajax_referer( 'save-customize_' . $wp_customize->get_stylesheet(), 'nonce' ) + check_ajax_referer( 'save-customize_' . $this->manager->get_stylesheet(), 'nonce' ) ); $is_valid_request = ( $is_ajax_widget_update || $is_customize_preview || $is_ajax_customize_save ); @@ -154,14 +154,14 @@ class WP_Customize_Widgets { // Input from customizer preview. if ( isset( $_POST['customized'] ) ) { - $customized = json_decode( self::get_post_value( 'customized' ), true ); + $customized = json_decode( $this->get_post_value( 'customized' ), true ); } // Input from ajax widget update request. else { $customized = array(); - $id_base = self::get_post_value( 'id_base' ); - $widget_number = (int) self::get_post_value( 'widget_number' ); + $id_base = $this->get_post_value( 'id_base' ); + $widget_number = (int) $this->get_post_value( 'widget_number' ); $option_name = 'widget_' . $id_base; $customized[$option_name] = array(); if ( false !== $widget_number ) { @@ -170,29 +170,35 @@ class WP_Customize_Widgets { } } - $function = array( __CLASS__, 'prepreview_added_sidebars_widgets' ); + $function = array( $this, 'prepreview_added_sidebars_widgets' ); $hook = 'option_sidebars_widgets'; add_filter( $hook, $function ); - self::$_prepreview_added_filters[] = compact( 'hook', 'function' ); + $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); $hook = 'default_option_sidebars_widgets'; add_filter( $hook, $function ); - self::$_prepreview_added_filters[] = compact( 'hook', 'function' ); + $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); foreach ( $customized as $setting_id => $value ) { if ( preg_match( '/^(widget_.+?)(\[(\d+)\])?$/', $setting_id, $matches ) ) { - $body = sprintf( 'return %s::prepreview_added_widget_instance( $value, %s );', __CLASS__, var_export( $setting_id, true ) ); + $body = sprintf( 'global $wp_customize; return $wp_customize->widgets->prepreview_added_widget_instance( $value, %s );', var_export( $setting_id, true ) ); $function = create_function( '$value', $body ); + // @todo replace above two lines with following once PHP 5.3 happens in WordPress + // $self = $this; // not needed in PHP 5.4 + // $function = function ( $value ) use ( $self, $setting_id ) { + // return $self->manager->widgets->prepreview_added_widget_instance( $value, $setting_id ); + //}; + $option = $matches[1]; $hook = sprintf( 'option_%s', $option ); add_filter( $hook, $function ); - self::$_prepreview_added_filters[] = compact( 'hook', 'function' ); + $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); $hook = sprintf( 'default_option_%s', $option ); add_filter( $hook, $function ); - self::$_prepreview_added_filters[] = compact( 'hook', 'function' ); + $this->_prepreview_added_filters[] = compact( 'hook', 'function' ); /** * Make sure the option is registered so that the update_option won't fail due to @@ -202,7 +208,7 @@ class WP_Customize_Widgets { } } - self::$_customized = $customized; + $this->_customized = $customized; } /** @@ -213,14 +219,13 @@ class WP_Customize_Widgets { * which is too late for the widgets to be set up properly. * * @since 3.9.0 - * @static * @access public * * @param array $sidebars_widgets Array of * @return array */ - static function prepreview_added_sidebars_widgets( $sidebars_widgets ) { - foreach ( self::$_customized as $setting_id => $value ) { + public function prepreview_added_sidebars_widgets( $sidebars_widgets ) { + foreach ( $this->_customized as $setting_id => $value ) { if ( preg_match( '/^sidebars_widgets\[(.+?)\]$/', $setting_id, $matches ) ) { $sidebar_id = $matches[1]; $sidebars_widgets[$sidebar_id] = $value; @@ -237,16 +242,15 @@ class WP_Customize_Widgets { * which is too late for the widgets to be set up properly. * * @since 3.9.0 - * @static * @access public * * @param array $instance Widget instance. * @param string $setting_id Widget setting ID. * @return array Parsed widget instance. */ - static function prepreview_added_widget_instance( $instance, $setting_id ) { - if ( isset( self::$_customized[$setting_id] ) ) { - $parsed_setting_id = self::parse_widget_setting_id( $setting_id ); + public function prepreview_added_widget_instance( $instance, $setting_id ) { + if ( isset( $this->_customized[$setting_id] ) ) { + $parsed_setting_id = $this->parse_widget_setting_id( $setting_id ); $widget_number = $parsed_setting_id['number']; // Single widget @@ -273,24 +277,22 @@ class WP_Customize_Widgets { * widgets are populating the options during widgets_init * * @since 3.9.0 - * @static * @access public */ - static function remove_prepreview_filters() { - foreach ( self::$_prepreview_added_filters as $prepreview_added_filter ) { + public function remove_prepreview_filters() { + foreach ( $this->_prepreview_added_filters as $prepreview_added_filter ) { remove_filter( $prepreview_added_filter['hook'], $prepreview_added_filter['function'] ); } - self::$_prepreview_added_filters = array(); + $this->_prepreview_added_filters = array(); } /** * Make sure that all widgets get loaded into customizer; these actions are also done in the wp_ajax_save_widget() * * @since 3.9.0 - * @static * @access public */ - static function customize_controls_init() { + public function customize_controls_init() { do_action( 'load-widgets.php' ); do_action( 'widgets.php' ); do_action( 'sidebar_admin_setup' ); @@ -301,16 +303,13 @@ class WP_Customize_Widgets { * loaded so that all filters have been initialized (e.g. Widget Visibility) * * @since 3.9.0 - * @static * @access public - * - * @param WP_Customize_Manager $wp_customize Customizer instance. */ - static function schedule_customize_register( $wp_customize ) { + public function schedule_customize_register() { if ( is_admin() ) { // @todo for some reason, $wp_customize->is_preview() is true here? - self::customize_register( $wp_customize ); + $this->customize_register(); } else { - add_action( 'wp', array( __CLASS__, 'customize_register' ) ); + add_action( 'wp', array( $this, 'customize_register' ) ); } } @@ -318,16 +317,10 @@ class WP_Customize_Widgets { * Register customizer settings and controls for all sidebars and widgets * * @since 3.9.0 - * @static * @access public - * - * @param WP_Customize_Manager $wp_customize Customizer instance. */ - static function customize_register( $wp_customize = null ) { + public function customize_register() { global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_sidebars; - if ( ! ( $wp_customize instanceof WP_Customize_Manager ) ) { - $wp_customize = $GLOBALS['wp_customize']; - } $sidebars_widgets = array_merge( array( 'wp_inactive_widgets' => array() ), @@ -342,11 +335,11 @@ class WP_Customize_Widgets { * since a widget may get suppressed from a sidebar via a plugin (like Widget Visibility). */ foreach ( array_keys( $wp_registered_widgets ) as $widget_id ) { - $setting_id = self::get_setting_id( $widget_id ); - $setting_args = self::get_setting_args( $setting_id ); - $setting_args['sanitize_callback'] = array( __CLASS__, 'sanitize_widget_instance' ); - $setting_args['sanitize_js_callback'] = array( __CLASS__, 'sanitize_widget_js_instance' ); - $wp_customize->add_setting( $setting_id, $setting_args ); + $setting_id = $this->get_setting_id( $widget_id ); + $setting_args = $this->get_setting_args( $setting_id ); + $setting_args['sanitize_callback'] = array( $this, 'sanitize_widget_instance' ); + $setting_args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' ); + $this->manager->add_setting( $setting_id, $setting_args ); $new_setting_ids[] = $setting_id; } @@ -363,10 +356,10 @@ class WP_Customize_Widgets { */ if ( $is_registered_sidebar || $is_inactive_widgets ) { $setting_id = sprintf( 'sidebars_widgets[%s]', $sidebar_id ); - $setting_args = self::get_setting_args( $setting_id ); - $setting_args['sanitize_callback'] = array( __CLASS__, 'sanitize_sidebar_widgets' ); - $setting_args['sanitize_js_callback'] = array( __CLASS__, 'sanitize_sidebar_widgets_js_instance' ); - $wp_customize->add_setting( $setting_id, $setting_args ); + $setting_args = $this->get_setting_args( $setting_id ); + $setting_args['sanitize_callback'] = array( $this, 'sanitize_sidebar_widgets' ); + $setting_args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' ); + $this->manager->add_setting( $setting_id, $setting_args ); $new_setting_ids[] = $setting_id; /** @@ -381,10 +374,10 @@ class WP_Customize_Widgets { 'priority' => 1000 + array_search( $sidebar_id, array_keys( $wp_registered_sidebars ) ), ); $section_args = apply_filters( 'customizer_widgets_section_args', $section_args, $section_id, $sidebar_id ); - $wp_customize->add_section( $section_id, $section_args ); + $this->manager->add_section( $section_id, $section_args ); $control = new WP_Widget_Area_Customize_Control( - $wp_customize, + $this->manager, $setting_id, array( 'section' => $section_id, @@ -393,7 +386,7 @@ class WP_Customize_Widgets { ) ); $new_setting_ids[] = $setting_id; - $wp_customize->add_control( $control ); + $this->manager->add_control( $control ); } } @@ -405,11 +398,11 @@ class WP_Customize_Widgets { continue; } $registered_widget = $GLOBALS['wp_registered_widgets'][$widget_id]; - $setting_id = self::get_setting_id( $widget_id ); + $setting_id = $this->get_setting_id( $widget_id ); $id_base = $GLOBALS['wp_registered_widget_controls'][$widget_id]['id_base']; assert( false !== is_active_widget( $registered_widget['callback'], $registered_widget['id'], false, false ) ); $control = new WP_Widget_Form_Customize_Control( - $wp_customize, + $this->manager, $setting_id, array( 'label' => $registered_widget['name'], @@ -420,10 +413,10 @@ class WP_Customize_Widgets { 'priority' => $i, 'width' => $wp_registered_widget_controls[$widget_id]['width'], 'height' => $wp_registered_widget_controls[$widget_id]['height'], - 'is_wide' => self::is_wide_widget( $widget_id ), + 'is_wide' => $this->is_wide_widget( $widget_id ), ) ); - $wp_customize->add_control( $control ); + $this->manager->add_control( $control ); } } @@ -433,25 +426,24 @@ class WP_Customize_Widgets { */ if ( did_action( 'customize_preview_init' ) ) { foreach ( $new_setting_ids as $new_setting_id ) { - $wp_customize->get_setting( $new_setting_id )->preview(); + $this->manager->get_setting( $new_setting_id )->preview(); } } - self::remove_prepreview_filters(); + $this->remove_prepreview_filters(); } /** * Covert a widget_id into its corresponding customizer setting id (option name) * * @since 3.9.0 - * @static * @access public * * @param string $widget_id Widget ID. * @return string Maybe-parsed widget ID. */ - static function get_setting_id( $widget_id ) { - $parsed_widget_id = self::parse_widget_id( $widget_id ); + public function get_setting_id( $widget_id ) { + $parsed_widget_id = $this->parse_widget_id( $widget_id ); $setting_id = sprintf( 'widget_%s', $parsed_widget_id['id_base'] ); if ( ! is_null( $parsed_widget_id['number'] ) ) { $setting_id .= sprintf( '[%d]', $parsed_widget_id['number'] ); @@ -468,17 +460,16 @@ class WP_Customize_Widgets { * filter. * * @since 3.9.0 - * @static * @access public * * @param string $widget_id Widget ID. * @return bool Whether or not the widget is a "wide" widget. */ - static function is_wide_widget( $widget_id ) { + public function is_wide_widget( $widget_id ) { global $wp_registered_widget_controls; - $parsed_widget_id = self::parse_widget_id( $widget_id ); + $parsed_widget_id = $this->parse_widget_id( $widget_id ); $width = $wp_registered_widget_controls[$widget_id]['width']; - $is_core = in_array( $parsed_widget_id['id_base'], self::$core_widget_id_bases ); + $is_core = in_array( $parsed_widget_id['id_base'], $this->core_widget_id_bases ); $is_wide = ( $width > 250 && ! $is_core ); /** @@ -497,13 +488,12 @@ class WP_Customize_Widgets { * Covert a widget ID into its id_base and number components. * * @since 3.9.0 - * @static * @access public * * @param string $widget_id Widget ID. * @return array Array containing a widget's id_base and number components. */ - static function parse_widget_id( $widget_id ) { + public function parse_widget_id( $widget_id ) { $parsed = array( 'number' => null, 'id_base' => null, @@ -522,14 +512,13 @@ class WP_Customize_Widgets { * Convert a widget setting ID (option path) to its id_base and number components. * * @since 3.9.0 - * @static * @access public * * @param string $setting_id Widget setting ID. * @return WP_Error|array Array contain a widget's id_base and number components, * or a WP_Error object. */ - static function parse_widget_setting_id( $setting_id ) { + public function parse_widget_setting_id( $setting_id ) { if ( ! preg_match( '/^(widget_(.+?))(?:\[(\d+)\])?$/', $setting_id, $matches ) ) { return new WP_Error( 'invalid_setting_id', 'Invalid widget setting ID' ); } @@ -543,17 +532,16 @@ class WP_Customize_Widgets { * Enqueue scripts and styles for customizer panel and export data to JS. * * @since 3.9.0 - * @static * @access public */ - static function customize_controls_enqueue_deps() { + public function customize_controls_enqueue_deps() { wp_enqueue_style( 'customize-widgets' ); wp_enqueue_script( 'customize-widgets' ); // Export available widgets with control_tpl removed from model // since plugins need templates to be in the DOM $available_widgets = array(); - foreach ( self::get_available_widgets() as $available_widget ) { + foreach ( $this->get_available_widgets() as $available_widget ) { unset( $available_widget['control_tpl'] ); $available_widgets[] = $available_widget; } @@ -601,7 +589,7 @@ class WP_Customize_Widgets { 'save_btn_tooltip' => ( 'Save and preview changes before publishing them.' ), 'remove_btn_label' => __( 'Remove' ), 'remove_btn_tooltip' => ( 'Trash widget by moving it to the inactive widgets sidebar.' ), - 'error' => __('An error has occurred. Please reload the page and try again.'), + 'error' => __( 'An error has occurred. Please reload the page and try again.' ), ), 'tpl' => array( 'widget_reorder_nav' => $widget_reorder_nav_tpl, @@ -623,17 +611,16 @@ class WP_Customize_Widgets { * Render the widget form control templates into the DOM so that plugin scripts can manipulate them * * @since 3.9.0 - * @static * @access public */ - static function output_widget_control_templates() { + public function output_widget_control_templates() { ?>