Make WordPress Core


Ignore:
Timestamp:
11/21/2015 02:51:57 AM (9 years ago)
Author:
westonruter
Message:

Customize: Ensure that a setting (especially a multidimensional one) can still be previewed when the post value to preview is set after preview() is invoked.

  • Introduce customize_post_value_set_{$setting_id} and customize_post_value_set actions which are done when WP_Customize_Manager::set_post_value() is called.
  • Clear the preview_applied flag for aggregated multidimensional settings when a post value is set. This ensures the new value is used instead of a previously-cached previewed value.
  • Move $is_preview property from subclasses to WP_Customize_Setting parent class.
  • Deferred preview: Ensure that when preview() short-circuits due to not being applicable that it will be called again later when the post value is set.
  • Populate post value for updated-widget with the (unsanitized) JS-value in WP_Customize_Widgets::call_widget_update() so that value will be properly sanitized when accessed in WP_Customize_Manager::post_value().

Includes unit tests with assertions to check the reported issues and validate the fixes.

Fixes defect introduced in [35007].
See #32103.
Fixes #34738.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-customize-setting.php

    r35383 r35724  
    8383
    8484    /**
     85     * Whether or not preview() was called.
     86     *
     87     * @since 4.4.0
     88     * @access protected
     89     * @var bool
     90     */
     91    protected $is_previewed = false;
     92
     93    /**
    8594     * Cache of multidimensional values to improve performance.
    8695     *
     
    192201
    193202        if ( ! empty( $this->id_data['keys'] ) ) {
     203            // Note the preview-applied flag is cleared at priority 9 to ensure it is cleared before a deferred-preview runs.
     204            add_action( "customize_post_value_set_{$this->id}", array( $this, '_clear_aggregated_multidimensional_preview_applied_flag' ), 9 );
    194205            $this->is_multidimensional_aggregated = true;
    195206        }
     
    246257            $this->_previewed_blog_id = get_current_blog_id();
    247258        }
     259
     260        // Prevent re-previewing an already-previewed setting.
     261        if ( $this->is_previewed ) {
     262            return true;
     263        }
     264
    248265        $id_base = $this->id_data['base'];
    249266        $is_multidimensional = ! empty( $this->id_data['keys'] );
     
    274291        }
    275292
     293        // If the setting does not need previewing now, defer to when it has a value to preview.
    276294        if ( ! $needs_preview ) {
     295            if ( ! has_action( "customize_post_value_set_{$this->id}", array( $this, 'preview' ) ) ) {
     296                add_action( "customize_post_value_set_{$this->id}", array( $this, 'preview' ) );
     297            }
    277298            return false;
    278299        }
     
    328349                do_action( "customize_preview_{$this->type}", $this );
    329350        }
     351
     352        $this->is_previewed = true;
     353
    330354        return true;
     355    }
     356
     357    /**
     358     * Clear out the previewed-applied flag for a multidimensional-aggregated value whenever its post value is updated.
     359     *
     360     * This ensures that the new value will get sanitized and used the next time
     361     * that <code>WP_Customize_Setting::_multidimensional_preview_filter()</code>
     362     * is called for this setting.
     363     *
     364     * @since 4.4.0
     365     * @access private
     366     * @see WP_Customize_Manager::set_post_value()
     367     * @see WP_Customize_Setting::_multidimensional_preview_filter()
     368     */
     369    final public function _clear_aggregated_multidimensional_preview_applied_flag() {
     370        unset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['preview_applied_instances'][ $this->id ] );
    331371    }
    332372
     
    370410     *
    371411     * @since 4.4.0
    372      * @access public
     412     * @access private
    373413     *
    374414     * @see WP_Customize_Setting::$aggregated_multidimensionals
     
    376416     * @return mixed New or old value.
    377417     */
    378     public function _multidimensional_preview_filter( $original ) {
     418    final public function _multidimensional_preview_filter( $original ) {
    379419        if ( ! $this->is_current_blog_previewed() ) {
    380420            return $original;
Note: See TracChangeset for help on using the changeset viewer.