Make WordPress Core

Changeset 28124


Ignore:
Timestamp:
04/14/2014 10:45:40 PM (12 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.