Make WordPress Core

Changeset 27966


Ignore:
Timestamp:
04/06/2014 06:47:46 PM (12 years ago)
Author:
ocean90
Message:

WP_Widget: Introduce is_preview() method.

With the Widget Customizer it's possible that previewed widgets can leak data outside of Customizer, when the widget uses the cache API.
The Customizer calls the regular update callback which should already refresh the cache. Since cache additions aren't blocked yet the cache can be filled with preview data.
To prevent this issue WP_Widget::is_preview() will return true, when $wp_customize->is_preview() returns true. If is_preview() is true, cache additions are suspended via wp_suspend_cache_addition(). Make sure your object cache drop-in has implemented wp_suspend_cache_addition().

is_preview() can/should also be used inside WP_Widget::widget(), see WP_Widget_Recent_Posts or WP_Widget_Recent_Comments for examples.

For more info see IRC logs: http://irclogs.wordpress.org/chanlog.php?channel=wordpress-dev&day=2014-04-02&sort=asc#m824279

props westonruter.
fixes #27538.

Location:
trunk/src/wp-includes
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/default-widgets.php

    r27697 r27966  
    661661
    662662        function widget($args, $instance) {
    663                 $cache = wp_cache_get('widget_recent_posts', 'widget');
    664 
    665                 if ( !is_array($cache) )
     663                $cache = array();
     664                if ( ! $this->is_preview() ) {
     665                        $cache = wp_cache_get( 'widget_recent_posts', 'widget' );
     666                }
     667
     668                if ( ! is_array( $cache ) ) {
    666669                        $cache = array();
    667 
    668                 if ( ! isset( $args['widget_id'] ) )
     670                }
     671
     672                if ( ! isset( $args['widget_id'] ) ) {
    669673                        $args['widget_id'] = $this->id;
     674                }
    670675
    671676                if ( isset( $cache[ $args['widget_id'] ] ) ) {
     
    724729                endif;
    725730
    726                 $cache[$args['widget_id']] = ob_get_flush();
    727                 wp_cache_set('widget_recent_posts', $cache, 'widget');
     731                if ( ! $this->is_preview() ) {
     732                        $cache[ $args['widget_id'] ] = ob_get_flush();
     733                        wp_cache_set( 'widget_recent_posts', $cache, 'widget' );
     734                } else {
     735                        ob_flush();
     736                }
    728737        }
    729738
     
    808817                global $comments, $comment;
    809818
    810                 $cache = wp_cache_get('widget_recent_comments', 'widget');
    811 
    812                 if ( ! is_array( $cache ) )
     819                $cache = array();
     820                if ( ! $this->is_preview() ) {
     821                        $cache = wp_cache_get('widget_recent_comments', 'widget');
     822                }
     823                if ( ! is_array( $cache ) ) {
    813824                        $cache = array();
     825                }
    814826
    815827                if ( ! isset( $args['widget_id'] ) )
     
    866878
    867879                echo $output;
    868                 $cache[$args['widget_id']] = $output;
    869                 wp_cache_set('widget_recent_comments', $cache, 'widget');
     880
     881                if ( ! $this->is_preview() ) {
     882                        $cache[ $args['widget_id'] ] = $output;
     883                        wp_cache_set( 'widget_recent_comments', $cache, 'widget' );
     884                }
    870885        }
    871886
  • trunk/src/wp-includes/widgets.php

    r27870 r27966  
    162162        function _get_form_callback() {
    163163                return array($this, 'form_callback');
     164        }
     165
     166        /**
     167         * Determine if we're in the Customizer; if true, then the object cache gets
     168         * suspended and widgets should check this to decide whether they should
     169         * store anything persistently to the object cache, to transients, or
     170         * anywhere else.
     171         *
     172         * @since 3.9.0
     173         *
     174         * @return bool True if Customizer is on, false if not.
     175         */
     176        function is_preview() {
     177                global $wp_customize;
     178                return ( isset( $wp_customize ) && $wp_customize->is_preview() ) ;
    164179        }
    165180
     
    190205                         */
    191206                        $instance = apply_filters( 'widget_display_callback', $instance, $this, $args );
    192                         if ( false !== $instance )
    193                                 $this->widget($args, $instance);
     207
     208                        if ( false === $instance ) {
     209                                return;
     210                        }
     211
     212                        $was_cache_addition_suspended = wp_suspend_cache_addition();
     213                        if ( $this->is_preview() && ! $was_cache_addition_suspended ) {
     214                                wp_suspend_cache_addition( true );
     215                        }
     216
     217                        $this->widget( $args, $instance );
     218
     219                        if ( $this->is_preview() ) {
     220                                wp_suspend_cache_addition( $was_cache_addition_suspended );
     221                        }
    194222                }
    195223        }
     
    242270                                $old_instance = isset($all_instances[$number]) ? $all_instances[$number] : array();
    243271
    244                                 $instance = $this->update($new_instance, $old_instance);
     272                                $was_cache_addition_suspended = wp_suspend_cache_addition();
     273                                if ( $this->is_preview() && ! $was_cache_addition_suspended ) {
     274                                        wp_suspend_cache_addition( true );
     275                                }
     276
     277                                $instance = $this->update( $new_instance, $old_instance );
     278
     279                                if ( $this->is_preview() ) {
     280                                        wp_suspend_cache_addition( $was_cache_addition_suspended );
     281                                }
    245282
    246283                                /**
     
    258295                                 */
    259296                                $instance = apply_filters( 'widget_update_callback', $instance, $new_instance, $old_instance, $this );
    260                                 if ( false !== $instance )
     297                                if ( false !== $instance ) {
    261298                                        $all_instances[$number] = $instance;
     299                                }
    262300
    263301                                break; // run only once
Note: See TracChangeset for help on using the changeset viewer.