diff --git a/src/wp-includes/class-wp-customize-setting.php b/src/wp-includes/class-wp-customize-setting.php index f5cb1bfcfc..fc78d07cb0 100644 --- a/src/wp-includes/class-wp-customize-setting.php +++ b/src/wp-includes/class-wp-customize-setting.php @@ -711,6 +711,11 @@ class WP_Customize_Setting { } elseif ( $this->is_multidimensional_aggregated ) { $root_value = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value']; $value = $this->multidimensional_get( $root_value, $this->id_data['keys'], $this->default ); + + // Ensure that the post value is used if the setting is previewed, since preview filters aren't applying on cached $root_value. + if ( $this->is_previewed ) { + $value = $this->post_value( $value ); + } } else { $value = $this->get_root_value( $this->default ); } diff --git a/tests/phpunit/tests/customize/setting.php b/tests/phpunit/tests/customize/setting.php index 98990c53e0..94a3fe8a90 100644 --- a/tests/phpunit/tests/customize/setting.php +++ b/tests/phpunit/tests/customize/setting.php @@ -640,5 +640,29 @@ class Tests_WP_Customize_Setting extends WP_UnitTestCase { } return $validity; } + + /** + * Ensure that WP_Customize_Setting::value() can return a previewed value for aggregated multidimensionals. + * + * @ticket 37294 + */ + public function test_multidimensional_value_when_previewed() { + WP_Customize_Setting::reset_aggregated_multidimensionals(); + + $initial_value = 456; + set_theme_mod( 'nav_menu_locations', array( + 'primary' => $initial_value, + ) ); + $setting_id = 'nav_menu_locations[primary]'; + + $setting = new WP_Customize_Setting( $this->manager, $setting_id ); + $this->assertEquals( $initial_value, $setting->value() ); + + $override_value = -123456; + $this->manager->set_post_value( $setting_id, $override_value ); + $setting->preview(); + + $this->assertEquals( $override_value, $setting->value() ); + } }