Make WordPress Core

Changeset 37166


Ignore:
Timestamp:
04/07/2016 08:58:56 PM (8 years ago)
Author:
ocean90
Message:

Customize: Harden assignment of Customizer settings transports for selective refreshable widgets

Theme support for customize-selective-refresh-widgets can be added _after_ the logic for registering the settings for incoming widgets that have been changed. This is due to themes adding the theme support in after_setup_theme which is also the action where WP_Customize_Widgets::register_settings() is called. If these both happen at priority 10, which one is called first depends on which one was added first. The other issue is that at the time that WP_Customize_Widgets::register_settings() is called at after_setup_theme, it is called before widgets_init and thus no widgets are yet registered. This means that any settings registered at this point will always have a refresh transport even if the theme supports customize-selective-refresh-widgets, since the WP_Widget instance is not visible yet to see if it supports selective refresh.

The fix: Defer WP_Customize_Widgets::register_settings() from after_setup_theme to widgets_init at priority 95 when the widget objects have all been registered. Also, ensure that the preview filter for sidebars_widgets is added before the sidebars are iterated for adding the controls.

Props westonruter.
Fixes #36389.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-setting.php

    r36645 r37166  
    205205            $this->is_multidimensional_aggregated = true;
    206206        }
     207    }
     208
     209    /**
     210     * Reset `$aggregated_multidimensionals` static variable.
     211     *
     212     * This is intended only for use by unit tests.
     213     *
     214     * @since 4.5.0
     215     * @access public
     216     * @ignore
     217     */
     218    static public function reset_aggregated_multidimensionals() {
     219        self::$aggregated_multidimensionals = array();
    207220    }
    208221
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r37040 r37166  
    100100
    101101        add_filter( 'customize_dynamic_setting_args',          array( $this, 'filter_customize_dynamic_setting_args' ), 10, 2 );
    102         add_action( 'after_setup_theme',                       array( $this, 'register_settings' ) );
     102        add_action( 'widgets_init',                            array( $this, 'register_settings' ), 95 );
    103103        add_action( 'wp_loaded',                               array( $this, 'override_sidebars_widgets_for_theme_switch' ) );
    104104        add_action( 'customize_controls_init',                 array( $this, 'customize_controls_init' ) );
     
    376376    public function customize_register() {
    377377        global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_sidebars;
     378
     379        add_filter( 'sidebars_widgets', array( $this, 'preview_sidebars_widgets' ), 1 );
    378380
    379381        $sidebars_widgets = array_merge(
     
    510512            }
    511513        }
    512 
    513         add_filter( 'sidebars_widgets', array( $this, 'preview_sidebars_widgets' ), 1 );
    514514    }
    515515
  • trunk/tests/phpunit/tests/customize/widgets.php

    r37040 r37166  
    4747
    4848        $this->backup_registered_sidebars = $GLOBALS['wp_registered_sidebars'];
     49
     50        // Reset protected static var on class.
     51        WP_Customize_Setting::reset_aggregated_multidimensionals();
    4952    }
    5053
     
    7174    function set_customized_post_data( $customized ) {
    7275        $_POST['customized'] = wp_slash( wp_json_encode( $customized ) );
     76        if ( $this->manager ) {
     77            foreach ( $customized as $id => $value ) {
     78                $this->manager->set_post_value( $id, $value );
     79            }
     80        }
    7381    }
    7482
     
    151159
    152160    /**
    153      * Test WP_Customize_Widgets::register_settings()
     161     * Test WP_Customize_Widgets::register_settings() with selective refresh enabled.
    154162     *
    155163     * @ticket 30988
     164     * @ticket 36389
    156165     */
    157166    function test_register_settings() {
     167        add_theme_support( 'customize-selective-refresh-widgets' );
    158168
    159169        $raw_widget_customized = array(
     
    177187        $this->assertTrue( is_customize_preview() );
    178188
    179         $this->assertNotEmpty( $this->manager->get_setting( 'widget_categories[2]' ), 'Expected setting for pre-existing widget category-2, being customized.' );
    180         $this->assertNotEmpty( $this->manager->get_setting( 'widget_search[2]' ), 'Expected setting for pre-existing widget search-2, not being customized.' );
    181         $this->assertNotEmpty( $this->manager->get_setting( 'widget_search[3]' ), 'Expected dynamic setting for non-existing widget search-3, being customized.' );
     189        if ( current_theme_supports( 'customize-selective-refresh-widgets' ) ) {
     190            $expected_transport = 'postMessage';
     191            $this->assertNotEmpty( $this->manager->widgets->get_selective_refreshable_widgets() );
     192        } else {
     193            $expected_transport = 'refresh';
     194            $this->assertEmpty( $this->manager->widgets->get_selective_refreshable_widgets() );
     195        }
     196
     197        $setting = $this->manager->get_setting( 'widget_categories[2]' );
     198        $this->assertNotEmpty( $setting, 'Expected setting for pre-existing widget category-2, being customized.' );
     199        $this->assertEquals( $expected_transport, $setting->transport );
     200
     201        $setting = $this->manager->get_setting( 'widget_search[2]' );
     202        $this->assertNotEmpty( $setting, 'Expected setting for pre-existing widget search-2, not being customized.' );
     203        $this->assertEquals( $expected_transport, $setting->transport );
     204
     205        $setting = $this->manager->get_setting( 'widget_search[3]' );
     206        $this->assertNotEmpty( $setting, 'Expected dynamic setting for non-existing widget search-3, being customized.' );
     207        $this->assertEquals( $expected_transport, $setting->transport );
    182208
    183209        $widget_categories = get_option( 'widget_categories' );
    184210        $this->assertEquals( $raw_widget_customized['widget_categories[2]'], $widget_categories[2], 'Expected $wp_customize->get_setting(widget_categories[2])->preview() to have been called.' );
     211    }
     212
     213    /**
     214     * Test registering settings without selective refresh enabled.
     215     *
     216     * @ticket 36389
     217     */
     218    function test_register_settings_without_selective_refresh() {
     219        remove_theme_support( 'customize-selective-refresh-widgets' );
     220        $this->test_register_settings();
     221    }
     222
     223    /**
     224     * Test registering settings with selective refresh enabled at a late after_setup_theme action.
     225     *
     226     * @ticket 36389
     227     */
     228    function test_register_settings_with_late_theme_support_added() {
     229        remove_theme_support( 'customize-selective-refresh-widgets' );
     230        add_action( 'after_setup_theme', array( $this, 'add_customize_selective_refresh_theme_support' ), 100 );
     231        $this->test_register_settings();
     232    }
     233
     234    /**
     235     * Add customize-selective-refresh-widgets theme support.
     236     */
     237    function add_customize_selective_refresh_theme_support() {
     238        add_theme_support( 'customize-selective-refresh-widgets' );
    185239    }
    186240
Note: See TracChangeset for help on using the changeset viewer.