WordPress.org

Make WordPress Core

Changeset 27966


Ignore:
Timestamp:
04/06/14 18:47:46 (16 months 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.