WordPress.org

Make WordPress Core

Changeset 28124


Ignore:
Timestamp:
04/14/14 22:45:40 (17 months 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.