Make WordPress Core

Changeset 28124


Ignore:
Timestamp:
04/14/2014 10:45:40 PM (10 years ago)
Author:
nacin
Message:

Customizer: Properly handle widget settings when activating a previewed theme.

props westonruter, ocean90, gcorne.
fixes #27767.

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/customize-widgets.js

    r28044 r28124  
    943943            params.wp_customize = 'on';
    944944            params.nonce = api.Widgets.data.nonce;
     945            params.theme = api.settings.theme.stylesheet;
    945946
    946947            data = $.param( params );
     
    16151616            }
    16161617
    1617             controlHtml = $( '#widget-tpl-' + widget.get( 'id' ) ).html();
     1618            controlHtml = $.trim( $( '#widget-tpl-' + widget.get( 'id' ) ).html() );
    16181619            if ( widget.get( 'is_multi' ) ) {
    16191620                controlHtml = controlHtml.replace( /<[^<>]+>/g, function( m ) {
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r27816 r28124  
    576576            $this->stop_previewing_theme();
    577577            switch_theme( $this->get_stylesheet() );
     578            update_option( 'theme_switched_via_customizer', true );
    578579            $this->start_previewing_theme();
    579580        }
  • trunk/src/wp-includes/class-wp-customize-widgets.php

    r28117 r28124  
    6262
    6363    /**
     64     * @since 3.9.0
     65     * @access protected
     66     * @var array
     67     */
     68    protected $old_sidebars_widgets = array();
     69
     70    /**
    6471     * Initial loader.
    6572     *
     
    7380
    7481        add_action( 'after_setup_theme',                       array( $this, 'setup_widget_addition_previews' ) );
     82        add_action( 'wp_loaded',                               array( $this, 'override_sidebars_widgets_for_theme_switch' ) );
    7583        add_action( 'customize_controls_init',                 array( $this, 'customize_controls_init' ) );
    7684        add_action( 'customize_register',                      array( $this, 'schedule_customize_register' ), 1 );
     
    116124     *
    117125     * @access public
    118      * @global WP_Customize_Manager $wp_customize Customizer instance.
    119126     */
    120127    public function setup_widget_addition_previews() {
     
    126133
    127134        $is_ajax_widget_update = false;
    128         if ( defined( 'DOING_AJAX' ) && DOING_AJAX && 'update-widget' === $this->get_post_value( 'action' ) ) {
     135        if ( $this->manager->doing_ajax() && 'update-widget' === $this->get_post_value( 'action' ) ) {
    129136            $is_ajax_widget_update = check_ajax_referer( 'update-widget', 'nonce', false );
    130137        }
    131138
    132139        $is_ajax_customize_save = false;
    133         if ( defined( 'DOING_AJAX' ) && DOING_AJAX && 'customize_save' === $this->get_post_value( 'action' ) ) {
     140        if ( $this->manager->doing_ajax() && 'customize_save' === $this->get_post_value( 'action' ) ) {
    134141            $is_ajax_customize_save = check_ajax_referer( 'save-customize_' . $this->manager->get_stylesheet(), 'nonce', false );
    135142        }
     
    280287
    281288    /**
     289     * Override sidebars_widgets for theme switch.
     290     *
     291     * When switching a theme via the customizer, supply any previously-configured
     292     * sidebars_widgets from the target theme as the initial sidebars_widgets
     293     * setting. Also store the old theme's existing settings so that they can
     294     * be passed along for storing in the sidebars_widgets theme_mod when the
     295     * theme gets switched.
     296     *
     297     * @since 3.9.0
     298     * @access public
     299     */
     300    public function override_sidebars_widgets_for_theme_switch() {
     301        global $sidebars_widgets;
     302
     303        if ( $this->manager->doing_ajax() || $this->manager->is_theme_active() ) {
     304            return;
     305        }
     306
     307        $this->old_sidebars_widgets = wp_get_sidebars_widgets();
     308        add_filter( 'customize_value_old_sidebars_widgets_data', array( $this, 'filter_customize_value_old_sidebars_widgets_data' ) );
     309
     310        // retrieve_widgets() looks at the global $sidebars_widgets
     311        $sidebars_widgets = $this->old_sidebars_widgets;
     312        $sidebars_widgets = retrieve_widgets( 'customize' );
     313        add_filter( 'option_sidebars_widgets', array( $this, 'filter_option_sidebars_widgets_for_theme_switch' ), 1 );
     314    }
     315
     316    /**
     317     * Filter old_sidebars_widgets_data customizer setting.
     318     *
     319     * When switching themes, filter the Customizer setting
     320     * old_sidebars_widgets_data to supply initial $sidebars_widgets before they
     321     * were overridden by retrieve_widgets(). The value for
     322     * old_sidebars_widgets_data gets set in the old theme's sidebars_widgets
     323     * theme_mod.
     324     *
     325     * @see WP_Customize_Widgets::handle_theme_switch()
     326     * @since 3.9.0
     327     * @access public
     328     *
     329     * @param array $sidebars_widgets
     330     */
     331    public function filter_customize_value_old_sidebars_widgets_data( $old_sidebars_widgets ) {
     332        return $this->old_sidebars_widgets;
     333    }
     334
     335    /**
     336     * Filter sidebars_widgets option for theme switch.
     337     *
     338     * When switching themes, the retrieve_widgets() function is run when the
     339     * Customizer initializes, and then the new sidebars_widgets here get
     340     * supplied as the default value for the sidebars_widgets option.
     341     *
     342     * @see WP_Customize_Widgets::handle_theme_switch()
     343     * @since 3.9.0
     344     * @access public
     345     *
     346     * @param array $sidebars_widgets
     347     */
     348    public function filter_option_sidebars_widgets_for_theme_switch( $sidebars_widgets ) {
     349        $sidebars_widgets = $GLOBALS['sidebars_widgets'];
     350        $sidebars_widgets['array_version'] = 3;
     351        return $sidebars_widgets;
     352    }
     353
     354    /**
    282355     * Make sure all widgets get loaded into the Customizer.
    283356     *
     
    348421
    349422            $new_setting_ids[] = $setting_id;
     423        }
     424
     425        /*
     426         * Add a setting which will be supplied for the theme's sidebars_widgets
     427         * theme_mod when the the theme is switched.
     428         */
     429        if ( ! $this->manager->is_theme_active() ) {
     430            $setting_id = 'old_sidebars_widgets_data';
     431            $setting_args = $this->get_setting_args( $setting_id, array(
     432                'type' => 'global_variable',
     433            ) );
     434            $this->manager->add_setting( $setting_id, $setting_args );
    350435        }
    351436
  • trunk/src/wp-includes/theme.php

    r27879 r28124  
    753753 */
    754754function switch_theme( $stylesheet ) {
    755     global $wp_theme_directories, $sidebars_widgets;
    756 
    757     if ( is_array( $sidebars_widgets ) )
    758         set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $sidebars_widgets ) );
     755    global $wp_theme_directories, $wp_customize, $sidebars_widgets;
     756
     757    $_sidebars_widgets = null;
     758    if ( 'wp_ajax_customize_save' === current_action() ) {
     759        $_sidebars_widgets = $wp_customize->post_value( $wp_customize->get_setting( 'old_sidebars_widgets_data' ) );
     760    } elseif ( is_array( $sidebars_widgets ) ) {
     761        $_sidebars_widgets = $sidebars_widgets;
     762    }
     763
     764    if ( is_array( $_sidebars_widgets ) ) {
     765        set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $_sidebars_widgets ) );
     766    }
    759767
    760768    $old_theme  = wp_get_theme();
     
    783791    update_option( 'current_theme', $new_name );
    784792
     793    // Migrate from the old mods_{name} option to theme_mods_{slug}.
    785794    if ( is_admin() && false === get_option( 'theme_mods_' . $stylesheet ) ) {
    786795        $default_theme_mods = (array) get_option( 'mods_' . $new_name );
    787796        add_option( "theme_mods_$stylesheet", $default_theme_mods );
     797    } else {
     798        /*
     799         * Since retrieve_widgets() is called when initializing the customizer theme,
     800         * we need to to remove the theme mods to avoid overwriting changes made via
     801         * the widget customizer when accessing wp-admin/widgets.php.
     802         */
     803        if ( 'wp_ajax_customize_save' === current_action() ) {
     804            remove_theme_mod( 'sidebars_widgets' );
     805        }
    788806    }
    789807
     
    17921810        $old_theme = wp_get_theme( $stylesheet );
    17931811
     1812        // Prevent retrieve_widgets() from running since Customizer already called it up front
     1813        if ( get_option( 'theme_switched_via_customizer' ) ) {
     1814            remove_action( 'after_switch_theme', '_wp_sidebars_changed' );
     1815            update_option( 'theme_switched_via_customizer', false );
     1816        }
     1817
    17941818        if ( $old_theme->exists() ) {
    17951819            /**
  • trunk/src/wp-includes/widgets.php

    r27967 r28124  
    14021402}
    14031403
    1404 // look for "lost" widgets, this has to run at least on each theme change
    1405 function retrieve_widgets($theme_changed = false) {
     1404/**
     1405 * Look for "lost" widgets, this has to run at least on each theme change.
     1406 *
     1407 * @since 2.8.0
     1408 *
     1409 * @param mixed $theme_changed Whether the theme was changed as a boolean. A value
     1410 *                             of 'customize' defers updates for the customizer.
     1411 * @return array
     1412 */
     1413function retrieve_widgets( $theme_changed = false ) {
    14061414    global $wp_registered_sidebars, $sidebars_widgets, $wp_registered_widgets;
    14071415
     
    14131421        // time() that sidebars were stored is in $old_sidebars_widgets['time']
    14141422        $_sidebars_widgets = $old_sidebars_widgets['data'];
    1415         remove_theme_mod( 'sidebars_widgets' );
     1423
     1424        if ( 'customize' === $theme_changed ) {
     1425            remove_theme_mod( 'sidebars_widgets' );
     1426        }
    14161427
    14171428        foreach ( $_sidebars_widgets as $sidebar => $widgets ) {
     
    14961507
    14971508    $sidebars_widgets['wp_inactive_widgets'] = array_merge($lost_widgets, (array) $sidebars_widgets['wp_inactive_widgets']);
    1498     wp_set_sidebars_widgets($sidebars_widgets);
     1509    if ( 'customize' === $theme_changed ) {
     1510        wp_set_sidebars_widgets( $sidebars_widgets );
     1511    }
    14991512
    15001513    return $sidebars_widgets;
Note: See TracChangeset for help on using the changeset viewer.