Make WordPress Core

Changeset 27816


Ignore:
Timestamp:
03/28/2014 02:06:10 PM (12 years ago)
Author:
ocean90
Message:

Widget Customizer: Convert static WP_Customize_Widgets class into instantiated class and merge Options_Transaction into WP_Customize_Widgets.

see #27504.
props westonruter.

Location:
trunk/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/ajax-actions.php

    r27576 r27816  
    15891589
    15901590function wp_ajax_update_widget() {
    1591     WP_Customize_Widgets::wp_ajax_update_widget();
     1591    global $wp_customize;
     1592    $wp_customize->widgets->wp_ajax_update_widget();
    15921593}
    15931594
  • trunk/src/wp-includes/class-wp-customize-control.php

    r27722 r27816  
    10811081
    10821082        $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );
    1083         echo WP_Customize_Widgets::get_widget_control( $args );
     1083        echo $this->manager->widgets->get_widget_control( $args );
    10841084    }
    10851085}
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r27433 r27816  
    3838    protected $previewing = false;
    3939
     40    /**
     41     * Methods and properties deailing with managing widgets in the customizer.
     42     *
     43     * @var WP_Customize_Widgets
     44     */
     45    public $widgets;
     46
    4047    protected $settings = array();
    4148    protected $sections = array();
     
    6471        require( ABSPATH . WPINC . '/class-wp-customize-widgets.php' );
    6572
    66         WP_Customize_Widgets::setup(); // This should be integrated.
     73        $this->widgets = new WP_Customize_Widgets( $this );
    6774
    6875        add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) );
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r27814 r27816  
    55 * Implements widget management in the Customizer.
    66 *
    7  * @since 3.9.0
    87 * @package WordPress
    98 * @subpackage Customize
     9 * @since 3.9.0
    1010 */
    11 class WP_Customize_Widgets {
     11final class WP_Customize_Widgets {
    1212    const UPDATE_WIDGET_AJAX_ACTION    = 'update-widget';
    1313    const UPDATE_WIDGET_NONCE_POST_KEY = 'update-sidebar-widgets-nonce';
    1414
    1515    /**
     16     * @access public
     17     * @var WP_Customize_Manager
     18     */
     19    public $manager;
     20
     21    /**
    1622     * All id_bases for widgets defined in core
    1723     *
    1824     * @since 3.9.0
    19      * @static
    2025     * @access protected
    2126     * @var array
    2227     */
    23     protected static $core_widget_id_bases = array(
     28    protected $core_widget_id_bases = array(
    2429        'archives',
    2530        'calendar',
     
    3944    /**
    4045     * @since 3.9.0
    41      * @static
    4246     * @access protected
    4347     * @var
    4448     */
    45     protected static $_customized;
    46 
    47     /**
    48      * @since 3.9.0
    49      * @static
     49    protected $_customized;
     50
     51    /**
     52     * @since 3.9.0
    5053     * @access protected
    5154     * @var array
    5255     */
    53     protected static $_prepreview_added_filters = array();
    54 
    55     /**
    56      * @since 3.9.0
    57      * @static
     56    protected $_prepreview_added_filters = array();
     57
     58    /**
     59     * @since 3.9.0
    5860     * @access protected
    5961     * @var array
    6062     */
    61     static protected $rendered_sidebars = array();
    62 
    63     /**
    64      * @since 3.9.0
    65      * @static
     63    protected $rendered_sidebars = array();
     64
     65    /**
     66     * @since 3.9.0
    6667     * @access protected
    6768     * @var array
    6869     */
    69     static protected $rendered_widgets = array();
     70    protected $rendered_widgets = array();
    7071
    7172    /**
     
    7374     *
    7475     * @since 3.9.0
    75      * @static
    76      * @access public
    77      */
    78     static function setup() {
    79         add_action( 'after_setup_theme',                       array( __CLASS__, 'setup_widget_addition_previews' ) );
    80         add_action( 'customize_controls_init',                 array( __CLASS__, 'customize_controls_init' ) );
    81         add_action( 'customize_register',                      array( __CLASS__, 'schedule_customize_register' ), 1 );
    82         add_action( 'customize_controls_enqueue_scripts',      array( __CLASS__, 'customize_controls_enqueue_deps' ) );
    83         add_action( 'customize_controls_print_footer_scripts', array( __CLASS__, 'output_widget_control_templates' ) );
    84         add_action( 'customize_preview_init',                  array( __CLASS__, 'customize_preview_init' ) );
    85 
    86         add_action( 'dynamic_sidebar',                         array( __CLASS__, 'tally_rendered_widgets' ) );
    87         add_filter( 'is_active_sidebar',                       array( __CLASS__, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 );
    88         add_filter( 'dynamic_sidebar_has_widgets',             array( __CLASS__, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 );
     76     * @access public
     77     */
     78    public function __construct( WP_Customize_Manager $manager ) {
     79        $this->manager = $manager;
     80
     81        add_action( 'after_setup_theme',                       array( $this, 'setup_widget_addition_previews' ) );
     82        add_action( 'customize_controls_init',                 array( $this, 'customize_controls_init' ) );
     83        add_action( 'customize_register',                      array( $this, 'schedule_customize_register' ), 1 );
     84        add_action( 'customize_controls_enqueue_scripts',      array( $this, 'customize_controls_enqueue_deps' ) );
     85        add_action( 'customize_controls_print_footer_scripts', array( $this, 'output_widget_control_templates' ) );
     86        add_action( 'customize_preview_init',                  array( $this, 'customize_preview_init' ) );
     87
     88        add_action( 'dynamic_sidebar',                         array( $this, 'tally_rendered_widgets' ) );
     89        add_filter( 'is_active_sidebar',                       array( $this, 'tally_sidebars_via_is_active_sidebar_calls' ), 10, 2 );
     90        add_filter( 'dynamic_sidebar_has_widgets',             array( $this, 'tally_sidebars_via_dynamic_sidebar_calls' ), 10, 2 );
    8991    }
    9092
     
    9496     * @since 3.9.0
    9597     *
    96      * @static
    97      * @access public
     98     * @access protected
    9899     *
    99100     * @param string $name    Post value.
     
    101102     * @return mixed Unslashed post value or default value.
    102103     */
    103     static function get_post_value( $name, $default = null ) {
     104    protected function get_post_value( $name, $default = null ) {
    104105        if ( ! isset( $_POST[ $name ] ) ) {
    105106            return $default;
    106107        }
     108
    107109        return wp_unslash( $_POST[$name] );
    108110    }
     
    116118     * @since 3.9.0
    117119     *
    118      * @static
    119120     * @access public
    120121     * @global WP_Customize_Manager $wp_customize
    121122     */
    122     static function setup_widget_addition_previews() {
    123         global $wp_customize;
     123    public function setup_widget_addition_previews() {
    124124        $is_customize_preview = (
    125             ( ! empty( $wp_customize ) )
     125            ( ! empty( $this->manager ) )
    126126            &&
    127127            ( ! is_admin() )
    128128            &&
    129             ( 'on' === self::get_post_value( 'wp_customize' ) )
     129            ( 'on' === $this->get_post_value( 'wp_customize' ) )
    130130            &&
    131             check_ajax_referer( 'preview-customize_' . $wp_customize->get_stylesheet(), 'nonce', false )
     131            check_ajax_referer( 'preview-customize_' . $this->manager->get_stylesheet(), 'nonce', false )
    132132        );
    133133
     
    135135            ( defined( 'DOING_AJAX' ) && DOING_AJAX )
    136136            &&
    137             self::get_post_value( 'action' ) === self::UPDATE_WIDGET_AJAX_ACTION
     137            $this->get_post_value( 'action' ) === self::UPDATE_WIDGET_AJAX_ACTION
    138138            &&
    139139            check_ajax_referer( self::UPDATE_WIDGET_AJAX_ACTION, self::UPDATE_WIDGET_NONCE_POST_KEY, false )
     
    143143            ( defined( 'DOING_AJAX' ) && DOING_AJAX )
    144144            &&
    145             self::get_post_value( 'action' ) === 'customize_save'
     145            $this->get_post_value( 'action' ) === 'customize_save'
    146146            &&
    147             check_ajax_referer( 'save-customize_' . $wp_customize->get_stylesheet(), 'nonce' )
     147            check_ajax_referer( 'save-customize_' . $this->manager->get_stylesheet(), 'nonce' )
    148148        );
    149149
     
    155155        // Input from customizer preview.
    156156        if ( isset( $_POST['customized'] ) ) {
    157             $customized = json_decode( self::get_post_value( 'customized' ), true );
     157            $customized = json_decode( $this->get_post_value( 'customized' ), true );
    158158        }
    159159
     
    161161        else {
    162162            $customized    = array();
    163             $id_base       = self::get_post_value( 'id_base' );
    164             $widget_number = (int) self::get_post_value( 'widget_number' );
     163            $id_base       = $this->get_post_value( 'id_base' );
     164            $widget_number = (int) $this->get_post_value( 'widget_number' );
    165165            $option_name   = 'widget_' . $id_base;
    166166            $customized[$option_name] = array();
     
    171171        }
    172172
    173         $function = array( __CLASS__, 'prepreview_added_sidebars_widgets' );
     173        $function = array( $this, 'prepreview_added_sidebars_widgets' );
    174174
    175175        $hook = 'option_sidebars_widgets';
    176176        add_filter( $hook, $function );
    177         self::$_prepreview_added_filters[] = compact( 'hook', 'function' );
     177        $this->_prepreview_added_filters[] = compact( 'hook', 'function' );
    178178
    179179        $hook = 'default_option_sidebars_widgets';
    180180        add_filter( $hook, $function );
    181         self::$_prepreview_added_filters[] = compact( 'hook', 'function' );
     181        $this->_prepreview_added_filters[] = compact( 'hook', 'function' );
    182182
    183183        foreach ( $customized as $setting_id => $value ) {
    184184            if ( preg_match( '/^(widget_.+?)(\[(\d+)\])?$/', $setting_id, $matches ) ) {
    185                 $body     = sprintf( 'return %s::prepreview_added_widget_instance( $value, %s );', __CLASS__, var_export( $setting_id, true ) );
     185                $body     = sprintf( 'global $wp_customize; return $wp_customize->widgets->prepreview_added_widget_instance( $value, %s );', var_export( $setting_id, true ) );
    186186                $function = create_function( '$value', $body );
     187                // @todo replace above two lines with following once PHP 5.3 happens in WordPress
     188                // $self = $this; // not needed in PHP 5.4
     189                // $function = function ( $value ) use ( $self, $setting_id ) {
     190                //  return $self->manager->widgets->prepreview_added_widget_instance( $value, $setting_id );
     191                //};
     192
    187193                $option   = $matches[1];
    188194
    189195                $hook = sprintf( 'option_%s', $option );
    190196                add_filter( $hook, $function );
    191                 self::$_prepreview_added_filters[] = compact( 'hook', 'function' );
     197                $this->_prepreview_added_filters[] = compact( 'hook', 'function' );
    192198
    193199                $hook = sprintf( 'default_option_%s', $option );
    194200                add_filter( $hook, $function );
    195                 self::$_prepreview_added_filters[] = compact( 'hook', 'function' );
     201                $this->_prepreview_added_filters[] = compact( 'hook', 'function' );
    196202
    197203                /**
     
    203209        }
    204210
    205         self::$_customized = $customized;
     211        $this->_customized = $customized;
    206212    }
    207213
     
    214220     *
    215221     * @since 3.9.0
    216      * @static
    217222     * @access public
    218223     *
     
    220225     * @return array
    221226     */
    222     static function prepreview_added_sidebars_widgets( $sidebars_widgets ) {
    223         foreach ( self::$_customized as $setting_id => $value ) {
     227    public function prepreview_added_sidebars_widgets( $sidebars_widgets ) {
     228        foreach ( $this->_customized as $setting_id => $value ) {
    224229            if ( preg_match( '/^sidebars_widgets\[(.+?)\]$/', $setting_id, $matches ) ) {
    225230                $sidebar_id = $matches[1];
     
    238243     *
    239244     * @since 3.9.0
    240      * @static
    241245     * @access public
    242246     *
     
    245249     * @return array Parsed widget instance.
    246250     */
    247     static function prepreview_added_widget_instance( $instance, $setting_id ) {
    248         if ( isset( self::$_customized[$setting_id] ) ) {
    249             $parsed_setting_id = self::parse_widget_setting_id( $setting_id );
     251    public function prepreview_added_widget_instance( $instance, $setting_id ) {
     252        if ( isset( $this->_customized[$setting_id] ) ) {
     253            $parsed_setting_id = $this->parse_widget_setting_id( $setting_id );
    250254            $widget_number     = $parsed_setting_id['number'];
    251255
     
    274278     *
    275279     * @since 3.9.0
    276      * @static
    277      * @access public
    278      */
    279     static function remove_prepreview_filters() {
    280         foreach ( self::$_prepreview_added_filters as $prepreview_added_filter ) {
     280     * @access public
     281     */
     282    public function remove_prepreview_filters() {
     283        foreach ( $this->_prepreview_added_filters as $prepreview_added_filter ) {
    281284            remove_filter( $prepreview_added_filter['hook'], $prepreview_added_filter['function'] );
    282285        }
    283         self::$_prepreview_added_filters = array();
     286        $this->_prepreview_added_filters = array();
    284287    }
    285288
     
    288291     *
    289292     * @since 3.9.0
    290      * @static
    291      * @access public
    292      */
    293     static function customize_controls_init() {
     293     * @access public
     294     */
     295    public function customize_controls_init() {
    294296        do_action( 'load-widgets.php' );
    295297        do_action( 'widgets.php' );
     
    302304     *
    303305     * @since 3.9.0
    304      * @static
    305      * @access public
    306      *
    307      * @param WP_Customize_Manager $wp_customize Customizer instance.
    308      */
    309     static function schedule_customize_register( $wp_customize ) {
     306     * @access public
     307     */
     308    public function schedule_customize_register() {
    310309        if ( is_admin() ) { // @todo for some reason, $wp_customize->is_preview() is true here?
    311             self::customize_register( $wp_customize );
     310            $this->customize_register();
    312311        } else {
    313             add_action( 'wp', array( __CLASS__, 'customize_register' ) );
     312            add_action( 'wp', array( $this, 'customize_register' ) );
    314313        }
    315314    }
     
    319318     *
    320319     * @since 3.9.0
    321      * @static
    322      * @access public
    323      *
    324      * @param WP_Customize_Manager $wp_customize Customizer instance.
    325      */
    326     static function customize_register( $wp_customize = null ) {
     320     * @access public
     321     */
     322    public function customize_register() {
    327323        global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_sidebars;
    328         if ( ! ( $wp_customize instanceof WP_Customize_Manager ) ) {
    329             $wp_customize = $GLOBALS['wp_customize'];
    330         }
    331324
    332325        $sidebars_widgets = array_merge(
     
    343336         */
    344337        foreach ( array_keys( $wp_registered_widgets ) as $widget_id ) {
    345             $setting_id   = self::get_setting_id( $widget_id );
    346             $setting_args = self::get_setting_args( $setting_id );
    347             $setting_args['sanitize_callback']    = array( __CLASS__, 'sanitize_widget_instance' );
    348             $setting_args['sanitize_js_callback'] = array( __CLASS__, 'sanitize_widget_js_instance' );
    349             $wp_customize->add_setting( $setting_id, $setting_args );
     338            $setting_id   = $this->get_setting_id( $widget_id );
     339            $setting_args = $this->get_setting_args( $setting_id );
     340            $setting_args['sanitize_callback']    = array( $this, 'sanitize_widget_instance' );
     341            $setting_args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' );
     342            $this->manager->add_setting( $setting_id, $setting_args );
    350343            $new_setting_ids[] = $setting_id;
    351344        }
     
    364357            if ( $is_registered_sidebar || $is_inactive_widgets ) {
    365358                $setting_id   = sprintf( 'sidebars_widgets[%s]', $sidebar_id );
    366                 $setting_args = self::get_setting_args( $setting_id );
    367                 $setting_args['sanitize_callback']    = array( __CLASS__, 'sanitize_sidebar_widgets' );
    368                 $setting_args['sanitize_js_callback'] = array( __CLASS__, 'sanitize_sidebar_widgets_js_instance' );
    369                 $wp_customize->add_setting( $setting_id, $setting_args );
     359                $setting_args = $this->get_setting_args( $setting_id );
     360                $setting_args['sanitize_callback']    = array( $this, 'sanitize_sidebar_widgets' );
     361                $setting_args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' );
     362                $this->manager->add_setting( $setting_id, $setting_args );
    370363                $new_setting_ids[] = $setting_id;
    371364
     
    382375                    );
    383376                    $section_args = apply_filters( 'customizer_widgets_section_args', $section_args, $section_id, $sidebar_id );
    384                     $wp_customize->add_section( $section_id, $section_args );
     377                    $this->manager->add_section( $section_id, $section_args );
    385378
    386379                    $control = new WP_Widget_Area_Customize_Control(
    387                         $wp_customize,
     380                        $this->manager,
    388381                        $setting_id,
    389382                        array(
     
    394387                    );
    395388                    $new_setting_ids[] = $setting_id;
    396                     $wp_customize->add_control( $control );
     389                    $this->manager->add_control( $control );
    397390                }
    398391            }
     
    406399                }
    407400                $registered_widget = $GLOBALS['wp_registered_widgets'][$widget_id];
    408                 $setting_id = self::get_setting_id( $widget_id );
     401                $setting_id = $this->get_setting_id( $widget_id );
    409402                $id_base = $GLOBALS['wp_registered_widget_controls'][$widget_id]['id_base'];
    410403                assert( false !== is_active_widget( $registered_widget['callback'], $registered_widget['id'], false, false ) );
    411404                $control = new WP_Widget_Form_Customize_Control(
    412                     $wp_customize,
     405                    $this->manager,
    413406                    $setting_id,
    414407                    array(
     
    421414                        'width' => $wp_registered_widget_controls[$widget_id]['width'],
    422415                        'height' => $wp_registered_widget_controls[$widget_id]['height'],
    423                         'is_wide' => self::is_wide_widget( $widget_id ),
     416                        'is_wide' => $this->is_wide_widget( $widget_id ),
    424417                    )
    425418                );
    426                 $wp_customize->add_control( $control );
     419                $this->manager->add_control( $control );
    427420            }
    428421        }
     
    434427        if ( did_action( 'customize_preview_init' ) ) {
    435428            foreach ( $new_setting_ids as $new_setting_id ) {
    436                 $wp_customize->get_setting( $new_setting_id )->preview();
    437             }
    438         }
    439 
    440         self::remove_prepreview_filters();
     429                $this->manager->get_setting( $new_setting_id )->preview();
     430            }
     431        }
     432
     433        $this->remove_prepreview_filters();
    441434    }
    442435
     
    445438     *
    446439     * @since 3.9.0
    447      * @static
    448440     * @access public
    449441     *
     
    451443     * @return string Maybe-parsed widget ID.
    452444     */
    453     static function get_setting_id( $widget_id ) {
    454         $parsed_widget_id = self::parse_widget_id( $widget_id );
     445    public function get_setting_id( $widget_id ) {
     446        $parsed_widget_id = $this->parse_widget_id( $widget_id );
    455447        $setting_id = sprintf( 'widget_%s', $parsed_widget_id['id_base'] );
    456448        if ( ! is_null( $parsed_widget_id['number'] ) ) {
     
    469461     *
    470462     * @since 3.9.0
    471      * @static
    472463     * @access public
    473464     *
     
    475466     * @return bool Whether or not the widget is a "wide" widget.
    476467     */
    477     static function is_wide_widget( $widget_id ) {
     468    public function is_wide_widget( $widget_id ) {
    478469        global $wp_registered_widget_controls;
    479         $parsed_widget_id = self::parse_widget_id( $widget_id );
     470        $parsed_widget_id = $this->parse_widget_id( $widget_id );
    480471        $width = $wp_registered_widget_controls[$widget_id]['width'];
    481         $is_core = in_array( $parsed_widget_id['id_base'], self::$core_widget_id_bases );
     472        $is_core = in_array( $parsed_widget_id['id_base'], $this->core_widget_id_bases );
    482473        $is_wide = ( $width > 250 && ! $is_core );
    483474
     
    498489     *
    499490     * @since 3.9.0
    500      * @static
    501491     * @access public
    502492     *
     
    504494     * @return array Array containing a widget's id_base and number components.
    505495     */
    506     static function parse_widget_id( $widget_id ) {
     496    public function parse_widget_id( $widget_id ) {
    507497        $parsed = array(
    508498            'number' => null,
     
    523513     *
    524514     * @since 3.9.0
    525      * @static
    526515     * @access public
    527516     *
     
    530519     *                        or a WP_Error object.
    531520     */
    532     static function parse_widget_setting_id( $setting_id ) {
     521    public function parse_widget_setting_id( $setting_id ) {
    533522        if ( ! preg_match( '/^(widget_(.+?))(?:\[(\d+)\])?$/', $setting_id, $matches ) ) {
    534523            return new WP_Error( 'invalid_setting_id', 'Invalid widget setting ID' );
     
    544533     *
    545534     * @since 3.9.0
    546      * @static
    547      * @access public
    548      */
    549     static function customize_controls_enqueue_deps() {
     535     * @access public
     536     */
     537    public function customize_controls_enqueue_deps() {
    550538        wp_enqueue_style( 'customize-widgets' );
    551539        wp_enqueue_script( 'customize-widgets' );
     
    554542        // since plugins need templates to be in the DOM
    555543        $available_widgets = array();
    556         foreach ( self::get_available_widgets() as $available_widget ) {
     544        foreach ( $this->get_available_widgets() as $available_widget ) {
    557545            unset( $available_widget['control_tpl'] );
    558546            $available_widgets[] = $available_widget;
     
    602590                'remove_btn_label' => __( 'Remove' ),
    603591                'remove_btn_tooltip' => ( 'Trash widget by moving it to the inactive widgets sidebar.' ),
    604                 'error' => __('An error has occurred. Please reload the page and try again.'),
     592                'error' => __( 'An error has occurred. Please reload the page and try again.' ),
    605593            ),
    606594            'tpl' => array(
     
    624612     *
    625613     * @since 3.9.0
    626      * @static
    627      * @access public
    628      */
    629     static function output_widget_control_templates() {
     614     * @access public
     615     */
     616    public function output_widget_control_templates() {
    630617        ?>
    631618        <div id="widgets-left"><!-- compatibility with JS which looks for widget templates here -->
     
    634621                <input type="search" placeholder="<?php esc_attr_e( 'Find widgets&hellip;' ) ?>">
    635622            </div>
    636             <?php foreach ( self::get_available_widgets() as $available_widget ): ?>
     623            <?php foreach ( $this->get_available_widgets() as $available_widget ): ?>
    637624                <div id="widget-tpl-<?php echo esc_attr( $available_widget['id'] ) ?>" data-widget-id="<?php echo esc_attr( $available_widget['id'] ) ?>" class="widget-tpl <?php echo esc_attr( $available_widget['id'] ) ?>" tabindex="0">
    638625                    <?php echo $available_widget['control_tpl']; // xss ok ?>
     
    648635     *
    649636     * @since 3.9.0
    650      * @static
    651637     * @access public
    652638     *
     
    655641     * @return array Possibly modified setting arguments.
    656642     */
    657     static function get_setting_args( $id, $overrides = array() ) {
     643    public function get_setting_args( $id, $overrides = array() ) {
    658644        $args = array(
    659645            'type' => 'option',
     
    672658     *
    673659     * @since 3.9.0
    674      * @static
    675660     * @access public
    676661     *
     
    678663     * @return array Array of sanitized widget IDs.
    679664     */
    680     static function sanitize_sidebar_widgets( $widget_ids ) {
     665    public function sanitize_sidebar_widgets( $widget_ids ) {
    681666        global $wp_registered_widgets;
    682667        $widget_ids = array_map( 'strval', (array) $widget_ids );
     
    694679     *
    695680     * @since 3.9.0
    696      * @static
    697681     * @access public
    698682     *
     
    700684     * @return array
    701685     */
    702     static function get_available_widgets() {
     686    public function get_available_widgets() {
    703687        static $available_widgets = array();
    704688        if ( ! empty( $available_widgets ) ) {
     
    710694
    711695        $sort = $wp_registered_widgets;
    712         usort( $sort, array( __CLASS__, '_sort_name_callback' ) );
     696        usort( $sort, array( $this, '_sort_name_callback' ) );
    713697        $done = array();
    714698
     
    754738
    755739            $list_widget_controls_args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0] ) );
    756             $control_tpl = self::get_widget_control( $list_widget_controls_args );
     740            $control_tpl = $this->get_widget_control( $list_widget_controls_args );
    757741
    758742            // The properties here are mapped to the Backbone Widget model
     
    769753                    'width' => $wp_registered_widget_controls[$widget['id']]['width'],
    770754                    'height' => $wp_registered_widget_controls[$widget['id']]['height'],
    771                     'is_wide' => self::is_wide_widget( $widget['id'] ),
     755                    'is_wide' => $this->is_wide_widget( $widget['id'] ),
    772756                )
    773757            );
     
    783767     * @since 3.9.0
    784768     * @static
    785      * @access public
     769     * @access protected
    786770     *
    787771     * @param array $widget_a The first widget to compare.
     
    789773     * @return int Reorder position for the current widget comparison.
    790774     */
    791     static function _sort_name_callback( $widget_a, $widget_b ) {
     775    protected function _sort_name_callback( $widget_a, $widget_b ) {
    792776        return strnatcasecmp( $widget_a['name'], $widget_b['name'] );
    793777    }
     
    798782     *
    799783     * @since 3.9.0
    800      * @static
    801784     * @access public
    802785     *
     
    804787     * @return string Widget control form HTML markup.
    805788     */
    806     static function get_widget_control( $args ) {
     789    public function get_widget_control( $args ) {
    807790        ob_start();
    808791        call_user_func_array( 'wp_widget_control', $args );
     
    820803     *
    821804     * @since 3.9.0
    822      * @static
    823      * @access public
    824      */
    825     static function customize_preview_init() {
    826         add_filter( 'sidebars_widgets',   array( __CLASS__, 'preview_sidebars_widgets' ), 1 );
    827         add_action( 'wp_enqueue_scripts', array( __CLASS__, 'customize_preview_enqueue' ) );
    828         add_action( 'wp_print_styles',    array( __CLASS__, 'inject_preview_css' ), 1 );
    829         add_action( 'wp_footer',          array( __CLASS__, 'export_preview_data' ), 20 );
     805     * @access public
     806     */
     807    public function customize_preview_init() {
     808        add_filter( 'sidebars_widgets',   array( $this, 'preview_sidebars_widgets' ), 1 );
     809        add_action( 'wp_enqueue_scripts', array( $this, 'customize_preview_enqueue' ) );
     810        add_action( 'wp_print_styles',    array( $this, 'inject_preview_css' ), 1 );
     811        add_action( 'wp_footer',          array( $this, 'export_preview_data' ), 20 );
    830812    }
    831813
     
    839821     *
    840822     * @since 3.9.0
    841      * @static
    842823     * @access public
    843824     *
    844825     * @param array $sidebars_widgets List of widgets for the current sidebar.
    845826     */
    846     static function preview_sidebars_widgets( $sidebars_widgets ) {
     827    public function preview_sidebars_widgets( $sidebars_widgets ) {
    847828        $sidebars_widgets = get_option( 'sidebars_widgets' );
    848829        unset( $sidebars_widgets['array_version'] );
     
    854835     *
    855836     * @since 3.9.0
    856      * @static
    857      * @access public
    858      */
    859     static function customize_preview_enqueue() {
     837     * @access public
     838     */
     839    public function customize_preview_enqueue() {
    860840        wp_enqueue_script( 'customize-preview-widgets' );
    861         }
     841    }
    862842
    863843    /**
     
    866846     *
    867847     * @since 3.9.0
    868      * @static
    869848     * @access public
    870849     *
    871850     * @action wp_print_styles
    872851     */
    873     static function inject_preview_css() {
     852    public function inject_preview_css() {
    874853        ?>
    875854        <style>
     
    889868     *
    890869     * @since 3.9.0
    891      * @static
    892      * @access public
    893      */
    894     static function export_preview_data() {
     870     * @access public
     871     */
     872    public function export_preview_data() {
    895873        // Prepare customizer settings to pass to Javascript.
    896874        $settings = array(
    897             'renderedSidebars'   => array_fill_keys( array_unique( self::$rendered_sidebars ), true ),
    898             'renderedWidgets'    => array_fill_keys( array_keys( self::$rendered_widgets ), true ),
     875            'renderedSidebars'   => array_fill_keys( array_unique( $this->rendered_sidebars ), true ),
     876            'renderedWidgets'    => array_fill_keys( array_keys( $this->rendered_widgets ), true ),
    899877            'registeredSidebars' => array_values( $GLOBALS['wp_registered_sidebars'] ),
    900878            'registeredWidgets'  => $GLOBALS['wp_registered_widgets'],
     
    918896     *
    919897     * @since 3.9.0
    920      * @static
    921898     * @access public
    922899     *
    923900     * @param array $widget Rendered widget to tally.
    924901     */
    925     static function tally_rendered_widgets( $widget ) {
    926         self::$rendered_widgets[$widget['id']] = true;
     902    public function tally_rendered_widgets( $widget ) {
     903        $this->rendered_widgets[$widget['id']] = true;
    927904    }
    928905
     
    932909     *
    933910     * @since 3.9.0
    934      * @static
    935911     * @access public
    936912     *
     
    938914     * @pasram string $sidebar_id Sidebar ID.
    939915     */
    940     static function tally_sidebars_via_is_active_sidebar_calls( $is_active, $sidebar_id ) {
     916    public function tally_sidebars_via_is_active_sidebar_calls( $is_active, $sidebar_id ) {
    941917        if ( isset( $GLOBALS['wp_registered_sidebars'][$sidebar_id] ) ) {
    942             self::$rendered_sidebars[] = $sidebar_id;
     918            $this->rendered_sidebars[] = $sidebar_id;
    943919        }
    944920        // We may need to force this to true, and also force-true the value for dynamic_sidebar_has_widgets
     
    952928     *
    953929     * @since 3.9.0
    954      * @static
    955930     * @access public
    956931     *
     
    958933     * @param string $sidebar_id  Sidebar ID.
    959934     */
    960     static function tally_sidebars_via_dynamic_sidebar_calls( $has_widgets, $sidebar_id ) {
     935    public function tally_sidebars_via_dynamic_sidebar_calls( $has_widgets, $sidebar_id ) {
    961936        if ( isset( $GLOBALS['wp_registered_sidebars'][$sidebar_id] ) ) {
    962             self::$rendered_sidebars[] = $sidebar_id;
     937            $this->rendered_sidebars[] = $sidebar_id;
    963938        }
    964939        /*
     
    978953     *
    979954     * @since 3.9.0
    980      * @static
    981955     * @access protected
    982956     *
     
    984958     * @return string Widget instance's hash key.
    985959     */
    986     protected static function get_instance_hash_key( $instance ) {
     960    protected function get_instance_hash_key( $instance ) {
    987961        $hash = md5( AUTH_KEY . serialize( $instance ) );
    988962        return $hash;
     
    996970     *
    997971     * @since 3.9.0
    998      * @static
    999972     * @access public
    1000973     *
     
    1004977     * @return array Sanitized widget instance.
    1005978     */
    1006     static function sanitize_widget_instance( $value ) {
     979    public function sanitize_widget_instance( $value ) {
    1007980        if ( $value === array() ) {
    1008981            return $value;
     
    1026999            return null;
    10271000        }
    1028         if ( self::get_instance_hash_key( $instance ) !== $value['instance_hash_key'] ) {
     1001        if ( $this->get_instance_hash_key( $instance ) !== $value['instance_hash_key'] ) {
    10291002            return null;
    10301003        }
     
    10361009     *
    10371010     * @since 3.9.0
    1038      * @static
    10391011     * @access public
    10401012     *
     
    10441016     * @return array JSON-converted widget instance.
    10451017     */
    1046     static function sanitize_widget_js_instance( $value ) {
     1018    public function sanitize_widget_js_instance( $value ) {
    10471019        if ( empty( $value['is_widget_customizer_js_value'] ) ) {
    10481020            $serialized = serialize( $value );
     
    10511023                'title' => empty( $value['title'] ) ? '' : $value['title'],
    10521024                'is_widget_customizer_js_value' => true,
    1053                 'instance_hash_key' => self::get_instance_hash_key( $value ),
     1025                'instance_hash_key' => $this->get_instance_hash_key( $value ),
    10541026            );
    10551027        }
     
    10621034     *
    10631035     * @since 3.9.0
    1064      * @static
    10651036     * @access public
    10661037     *
     
    10681039     * @return array Parsed list of widget IDs.
    10691040     */
    1070     static function sanitize_sidebar_widgets_js_instance( $widget_ids ) {
     1041    public function sanitize_sidebar_widgets_js_instance( $widget_ids ) {
    10711042        global $wp_registered_widgets;
    10721043        $widget_ids = array_values( array_intersect( $widget_ids, array_keys( $wp_registered_widgets ) ) );
     
    10801051     *
    10811052     * @since 3.9.0
    1082      * @static
    10831053     * @access public
    10841054     *
     
    10861056     * @return WP_Error|array Array containing the updated widget information. WP_Error, otherwise.
    10871057     */
    1088     static function call_widget_update( $widget_id ) {
     1058    public function call_widget_update( $widget_id ) {
    10891059        global $wp_registered_widget_updates, $wp_registered_widget_controls;
    10901060
    1091         $options_transaction = new Options_Transaction();
    1092 
    1093         $options_transaction->start();
    1094         $parsed_id   = self::parse_widget_id( $widget_id );
     1061        $this->start_capturing_option_updates();
     1062        $parsed_id   = $this->parse_widget_id( $widget_id );
    10951063        $option_name = 'widget_' . $parsed_id['id_base'];
    10961064
     
    11011069        $added_input_vars = array();
    11021070        if ( ! empty( $_POST['sanitized_widget_setting'] ) ) {
    1103             $sanitized_widget_setting = json_decode( self::get_post_value( 'sanitized_widget_setting' ), true );
     1071            $sanitized_widget_setting = json_decode( $this->get_post_value( 'sanitized_widget_setting' ), true );
    11041072            if ( empty( $sanitized_widget_setting ) ) {
    1105                 $options_transaction->rollback();
     1073                $this->stop_capturing_option_updates();
    11061074                return new WP_Error( 'malformed_data', 'Malformed sanitized_widget_setting' );
    11071075            }
    11081076
    1109             $instance = self::sanitize_widget_instance( $sanitized_widget_setting );
     1077            $instance = $this->sanitize_widget_instance( $sanitized_widget_setting );
    11101078            if ( is_null( $instance ) ) {
    1111                 $options_transaction->rollback();
     1079                $this->stop_capturing_option_updates();
    11121080                return new WP_Error( 'unsanitary_data', 'Unsanitary sanitized_widget_setting' );
    11131081            }
     
    11441112
    11451113        // Make sure the expected option was updated.
    1146         if ( 0 !== $options_transaction->count() ) {
    1147             if ( count( $options_transaction->options ) > 1 ) {
    1148                 $options_transaction->rollback();
     1114        if ( 0 !== $this->count_captured_options() ) {
     1115            if ( $this->count_captured_options() > 1 ) {
     1116                $this->stop_capturing_option_updates();
    11491117                return new WP_Error( 'unexpected_update', 'Widget unexpectedly updated more than one option.' );
    11501118            }
    11511119
    1152             $updated_option_name = key( $options_transaction->options );
     1120            $updated_option_name = key( $this->get_captured_options() );
    11531121            if ( $updated_option_name !== $option_name ) {
    1154                 $options_transaction->rollback();
     1122                $this->stop_capturing_option_updates();
    11551123                return new WP_Error( 'wrong_option', sprintf( 'Widget updated option "%1$s", but expected "%2$s".', $updated_option_name, $option_name ) );
    11561124            }
     
    11731141        }
    11741142
    1175         $options_transaction->rollback();
     1143        $this->stop_capturing_option_updates();
    11761144        return compact( 'instance', 'form' );
    11771145    }
     
    11831151     *
    11841152     * @since 3.9.0
    1185      * @static
    11861153     * @access public
    11871154     *
     
    11901157     * @action wp_ajax_update_widget
    11911158     */
    1192     static function wp_ajax_update_widget() {
     1159    public function wp_ajax_update_widget() {
    11931160
    11941161        if ( ! is_user_logged_in() ) {
     
    12121179        do_action( 'sidebar_admin_setup' );
    12131180
    1214         $widget_id = self::get_post_value( 'widget-id' );
    1215         $parsed_id = self::parse_widget_id( $widget_id );
     1181        $widget_id = $this->get_post_value( 'widget-id' );
     1182        $parsed_id = $this->parse_widget_id( $widget_id );
    12161183        $id_base   = $parsed_id['id_base'];
    12171184
     
    12201187        }
    12211188
    1222         $updated_widget = self::call_widget_update( $widget_id ); // => {instance,form}
     1189        $updated_widget = $this->call_widget_update( $widget_id ); // => {instance,form}
    12231190        if ( is_wp_error( $updated_widget ) ) {
    12241191            wp_send_json_error();
     
    12261193
    12271194        $form = $updated_widget['form'];
    1228         $instance = self::sanitize_widget_js_instance( $updated_widget['instance'] );
     1195        $instance = $this->sanitize_widget_js_instance( $updated_widget['instance'] );
    12291196
    12301197        wp_send_json_success( compact( 'form', 'instance' ) );
    12311198    }
    1232 }
    1233 
    1234 class Options_Transaction {
    1235 
    1236     /**
    1237      * @var array $options values updated while transaction is open
    1238      */
    1239     public $options = array();
    1240 
    1241     protected $_ignore_transients = true;
    1242     protected $_is_current = false;
    1243     protected $_operations = array();
    1244 
    1245     function __construct( $ignore_transients = true ) {
    1246         $this->_ignore_transients = $ignore_transients;
    1247     }
    1248 
    1249     /**
    1250      * Determine whether or not the transaction is open
    1251      * @return bool
    1252      */
    1253     function is_current() {
    1254         return $this->_is_current;
    1255     }
     1199
     1200    /***************************************************************************
     1201     * Option Update Capturing
     1202     ***************************************************************************/
     1203
     1204    /**
     1205     * @var array $_captured_options values updated while capturing is happening
     1206     */
     1207    protected $_captured_options = array();
     1208
     1209    /**
     1210     * @var bool $_is_current whether capturing is currently happening or not
     1211     */
     1212    protected $_is_capturing_option_updates = false;
    12561213
    12571214    /**
     
    12591216     * @return boolean
    12601217     */
    1261     function is_option_ignored( $option_name ) {
    1262         return ( $this->_ignore_transients && 0 === strpos( $option_name, '_transient_' ) );
    1263     }
    1264 
    1265     /**
    1266      * Get the number of operations performed in the transaction
     1218    protected function is_option_capture_ignored( $option_name ) {
     1219        return ( 0 === strpos( $option_name, '_transient_' ) );
     1220    }
     1221
     1222    /**
     1223     * Get options updated
     1224     * @return array
     1225     */
     1226    protected function get_captured_options() {
     1227        return $this->_captured_options;
     1228    }
     1229
     1230    /**
     1231     * Get the number of options updated
    12671232     * @return bool
    12681233     */
    1269     function count() {
    1270         return count( $this->_operations );
     1234    protected function count_captured_options() {
     1235        return count( $this->_captured_options );
    12711236    }
    12721237
     
    12741239     * Start keeping track of changes to options, and cache their new values
    12751240     */
    1276     function start() {
    1277         $this->_is_current = true;
    1278         add_action( 'added_option', array( $this, '_capture_added_option' ), 10, 2 );
    1279         add_action( 'updated_option', array( $this, '_capture_updated_option' ), 10, 3 );
    1280         add_action( 'delete_option', array( $this, '_capture_pre_deleted_option' ), 10, 1 );
    1281         add_action( 'deleted_option', array( $this, '_capture_deleted_option' ), 10, 1 );
    1282     }
    1283 
    1284     /**
    1285      * @action added_option
    1286      * @param $option_name
    1287      * @param $new_value
    1288      */
    1289     function _capture_added_option( $option_name, $new_value ) {
    1290         if ( $this->is_option_ignored( $option_name ) ) {
     1241    protected function start_capturing_option_updates() {
     1242        if ( $this->_is_capturing_option_updates ) {
    12911243            return;
    12921244        }
    1293         $this->options[$option_name] = $new_value;
    1294         $operation = 'add';
    1295         $this->_operations[] = compact( 'operation', 'option_name', 'new_value' );
    1296     }
    1297 
    1298     /**
    1299      * @action updated_option
     1245
     1246        $this->_is_capturing_option_updates = true;
     1247        add_filter( 'pre_update_option', array( $this, '_capture_filter_pre_update_option' ), 10, 3 );
     1248    }
     1249
     1250    /**
     1251     * @access private
     1252     * @param mixed $new_value
    13001253     * @param string $option_name
    13011254     * @param mixed $old_value
    1302      * @param mixed $new_value
    1303      */
    1304     function _capture_updated_option( $option_name, $old_value, $new_value ) {
    1305         if ( $this->is_option_ignored( $option_name ) ) {
     1255     * @return mixed
     1256     */
     1257    public function _capture_filter_pre_update_option( $new_value, $option_name, $old_value ) {
     1258        if ( $this->is_option_capture_ignored( $option_name ) ) {
    13061259            return;
    13071260        }
    1308         $this->options[$option_name] = $new_value;
    1309         $operation = 'update';
    1310         $this->_operations[] = compact( 'operation', 'option_name', 'old_value', 'new_value' );
    1311     }
    1312 
    1313     protected $_pending_delete_option_autoload;
    1314     protected $_pending_delete_option_value;
    1315 
    1316     /**
    1317      * It's too bad the old_value and autoload aren't passed into the deleted_option action
    1318      * @action delete_option
    1319      * @param string $option_name
    1320      */
    1321     function _capture_pre_deleted_option( $option_name ) {
    1322         if ( $this->is_option_ignored( $option_name ) ) {
     1261
     1262        if ( ! isset( $this->_captured_options[$option_name] ) ) {
     1263            add_filter( "pre_option_{$option_name}", array( $this, '_capture_filter_pre_get_option' ) );
     1264        }
     1265
     1266        $this->_captured_options[$option_name] = $new_value;
     1267
     1268        return $old_value;
     1269    }
     1270
     1271    /**
     1272     * @access private
     1273     * @param mixed $value
     1274     * @return mixed
     1275     */
     1276    public function _capture_filter_pre_get_option( $value ) {
     1277        $option_name = preg_replace( '/^pre_option_/', '', current_filter() );
     1278        if ( isset( $this->_captured_options[$option_name] ) ) {
     1279            $value = $this->_captured_options[$option_name];
     1280            $value = apply_filters( 'option_' . $option_name, $value );
     1281        }
     1282
     1283        return $value;
     1284    }
     1285
     1286    /**
     1287     * Undo any changes to the options since start_capturing_option_updates() was called
     1288     */
     1289    protected function stop_capturing_option_updates() {
     1290        if ( ! $this->_is_capturing_option_updates ) {
    13231291            return;
    13241292        }
    1325         global $wpdb;
    1326         $autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s", $option_name ) ); // db call ok; no-cache ok
    1327         $this->_pending_delete_option_autoload = $autoload;
    1328         $this->_pending_delete_option_value    = get_option( $option_name );
    1329     }
    1330 
    1331     /**
    1332      * @action deleted_option
    1333      * @param string $option_name
    1334      */
    1335     function _capture_deleted_option( $option_name ) {
    1336         if ( $this->is_option_ignored( $option_name ) ) {
    1337             return;
    1338         }
    1339         unset( $this->options[$option_name] );
    1340         $operation = 'delete';
    1341         $old_value = $this->_pending_delete_option_value;
    1342         $autoload  = $this->_pending_delete_option_autoload;
    1343         $this->_operations[] = compact( 'operation', 'option_name', 'old_value', 'autoload' );
    1344     }
    1345 
    1346     /**
    1347      * Undo any changes to the options since start() was called
    1348      */
    1349     function rollback() {
    1350         remove_action( 'updated_option', array( $this, '_capture_updated_option' ), 10, 3 );
    1351         remove_action( 'added_option', array( $this, '_capture_added_option' ), 10, 2 );
    1352         remove_action( 'delete_option', array( $this, '_capture_pre_deleted_option' ), 10, 1 );
    1353         remove_action( 'deleted_option', array( $this, '_capture_deleted_option' ), 10, 1 );
    1354         while ( 0 !== count( $this->_operations ) ) {
    1355             $option_operation = array_pop( $this->_operations );
    1356             if ( 'add' === $option_operation['operation'] ) {
    1357                 delete_option( $option_operation['option_name'] );
    1358             }
    1359             else if ( 'delete' === $option_operation['operation'] ) {
    1360                 add_option( $option_operation['option_name'], $option_operation['old_value'], null, $option_operation['autoload'] );
    1361             }
    1362             else if ( 'update' === $option_operation['operation'] ) {
    1363                 update_option( $option_operation['option_name'], $option_operation['old_value'] );
    1364             }
    1365         }
    1366         $this->_is_current = false;
     1293
     1294        remove_filter( '_capture_filter_pre_update_option', array( $this, '_capture_filter_pre_update_option' ), 10, 3 );
     1295        foreach ( array_keys( $this->_captured_options ) as $option_name ) {
     1296            remove_filter( "pre_option_{$option_name}", array( $this, '_capture_filter_pre_get_option' ) );
     1297        }
     1298
     1299        $this->_captured_options = array();
     1300        $this->_is_capturing_option_updates = false;
    13671301    }
    13681302}
Note: See TracChangeset for help on using the changeset viewer.