From 8f3fbcdeff32d609f2e475d098e92d0f732cde92 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Thu, 17 Aug 2023 17:12:06 -0500 Subject: [PATCH 1/7] Store merged data in memory --- .../class-wp-theme-json-resolver.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 50d6e09443b2a..a1bd15634efc5 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -65,6 +65,19 @@ class WP_Theme_JSON_Resolver { */ protected static $user = null; + /** + * Container for merged data. + * + * @since n.e.x.t + * @var WP_Theme_JSON + */ + protected static $merged = array( + 'default' => null, + 'blocks' => null, + 'theme' => null, + 'custom' => null, + ); + /** * Stores the ID of the custom post type * that holds the user data. @@ -576,6 +589,14 @@ public static function get_merged_data( $origin = 'custom' ) { _deprecated_argument( __FUNCTION__, '5.9.0' ); } + if ( ! in_array( $origin, WP_Theme_JSON::VALID_ORIGINS, true ) ) { + $origin = 'custom'; + } + + if ( null !== static::$merged[ $origin ] ) { + return static::$merged[ $origin ]; + } + $result = new WP_Theme_JSON(); $result->merge( static::get_core_data() ); if ( 'default' === $origin ) { @@ -597,6 +618,8 @@ public static function get_merged_data( $origin = 'custom' ) { $result->merge( static::get_user_data() ); $result->set_spacing_sizes(); + static::$merged[ $origin ] = $result; + return $result; } From b9cd9c88c8a0cf6320e8dd555da9771dd4782c03 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Thu, 17 Aug 2023 17:16:16 -0500 Subject: [PATCH 2/7] Allow cached merged data to be cleaned --- src/wp-includes/class-wp-theme-json-resolver.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index a1bd15634efc5..5af901347feec 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -697,6 +697,12 @@ public static function clean_cached_data() { 'theme' => array(), 'user' => array(), ); + static::$merged = array( + 'default' => null, + 'blocks' => null, + 'theme' => null, + 'custom' => null, + ); static::$theme = null; static::$user = null; static::$user_custom_post_type_id = null; From d1319a1ba7f1cc42b6626d69895ce65ddc1472c2 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Fri, 18 Aug 2023 13:52:31 -0500 Subject: [PATCH 3/7] Validate block registration for merged data --- src/wp-includes/class-wp-theme-json-resolver.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 5af901347feec..3bce76448f0d0 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -593,7 +593,18 @@ public static function get_merged_data( $origin = 'custom' ) { $origin = 'custom'; } - if ( null !== static::$merged[ $origin ] ) { + // Map origins to block cache values. + $cache_map = array( + 'default' => 'core', + 'blocks' => 'blocks', + 'theme' => 'theme', + 'custom' => 'user', + ); + + if ( + null !== static::$merged[ $origin ] + && static::has_same_registered_blocks( $cache_map[ $origin ] ) + ) { return static::$merged[ $origin ]; } From 6811e6d1c22ade5dcb9be77f83c130674a7cf9ed Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Mon, 18 Sep 2023 16:14:31 -0500 Subject: [PATCH 4/7] Cache theme supports data for use when caching merged data --- .../class-wp-theme-json-resolver.php | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 3bce76448f0d0..118f88bc336f2 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -57,6 +57,13 @@ class WP_Theme_JSON_Resolver { */ protected static $theme = null; + /** + * Container to cache theme support data. + * + * @since n.e.x.t + */ + protected static $theme_support_data = null; + /** * Container for data coming from the user. * @@ -293,6 +300,29 @@ public static function get_theme_data( $deprecated = array(), $options = array() return static::$theme; } + $theme_support_data = self::get_theme_supports_data(); + + // If no support data has changed, return the previously cached object. + if ( $theme_support_data === static::$theme_support_data ) { + return static::$theme; + } + + // Cache the merged theme support data for future use. + static::$theme_support_data = $theme_support_data; + + $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); + $with_theme_supports->merge( static::$theme ); + return $with_theme_supports; + } + + /** + * Get merged theme supports data + * + * @since n.e.x.t + * + * @return array Config that adheres to the theme.json schema. + */ + private static function get_theme_supports_data() { /* * We want the presets and settings declared in theme.json * to override the ones declared via theme supports. @@ -300,6 +330,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() * and merge the static::$theme upon that. */ $theme_support_data = WP_Theme_JSON::get_from_editor_settings( get_classic_theme_supports_block_editor_settings() ); + if ( ! wp_theme_has_theme_json() ) { if ( ! isset( $theme_support_data['settings']['color'] ) ) { $theme_support_data['settings']['color'] = array(); @@ -341,9 +372,8 @@ public static function get_theme_data( $deprecated = array(), $options = array() $theme_support_data['settings']['border']['width'] = true; } } - $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); - $with_theme_supports->merge( static::$theme ); - return $with_theme_supports; + + return $theme_support_data; } /** @@ -585,6 +615,8 @@ public static function get_user_data() { * @return WP_Theme_JSON */ public static function get_merged_data( $origin = 'custom' ) { + global $_wp_theme_features; + if ( is_array( $origin ) ) { _deprecated_argument( __FUNCTION__, '5.9.0' ); } @@ -604,6 +636,7 @@ public static function get_merged_data( $origin = 'custom' ) { if ( null !== static::$merged[ $origin ] && static::has_same_registered_blocks( $cache_map[ $origin ] ) + && static::get_theme_supports_data() === static::$theme_support_data ) { return static::$merged[ $origin ]; } From b477c3de6a2045fef38cd8e997071b5a63cd564a Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Mon, 18 Sep 2023 16:17:06 -0500 Subject: [PATCH 5/7] Remove unused global var --- src/wp-includes/class-wp-theme-json-resolver.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 118f88bc336f2..83b7ef7090620 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -615,8 +615,6 @@ public static function get_user_data() { * @return WP_Theme_JSON */ public static function get_merged_data( $origin = 'custom' ) { - global $_wp_theme_features; - if ( is_array( $origin ) ) { _deprecated_argument( __FUNCTION__, '5.9.0' ); } From a5922fe8d41cf470ed67a8f42bc4cda10b3600fa Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Mon, 18 Sep 2023 16:37:20 -0500 Subject: [PATCH 6/7] Don't return early in get_theme_data --- src/wp-includes/class-wp-theme-json-resolver.php | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 83b7ef7090620..d5bcbd0b397f4 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -300,17 +300,10 @@ public static function get_theme_data( $deprecated = array(), $options = array() return static::$theme; } - $theme_support_data = self::get_theme_supports_data(); + // Save theme supports data for future use. + static::$theme_support_data = self::get_theme_supports_data(); - // If no support data has changed, return the previously cached object. - if ( $theme_support_data === static::$theme_support_data ) { - return static::$theme; - } - - // Cache the merged theme support data for future use. - static::$theme_support_data = $theme_support_data; - - $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); + $with_theme_supports = new WP_Theme_JSON( static::$theme_support_data ); $with_theme_supports->merge( static::$theme ); return $with_theme_supports; } From 372770980f626feb3aef115b314a723393fb6476 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Fri, 22 Sep 2023 11:57:50 -0500 Subject: [PATCH 7/7] Apply PR feedback --- src/wp-includes/class-wp-theme-json-resolver.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index d5bcbd0b397f4..215b6b764e053 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -61,6 +61,7 @@ class WP_Theme_JSON_Resolver { * Container to cache theme support data. * * @since n.e.x.t + * @var array */ protected static $theme_support_data = null; @@ -627,7 +628,8 @@ public static function get_merged_data( $origin = 'custom' ) { if ( null !== static::$merged[ $origin ] && static::has_same_registered_blocks( $cache_map[ $origin ] ) - && static::get_theme_supports_data() === static::$theme_support_data + // Ensure theme supports data is fresh before returning cached data for theme and custom origins. + && ( ! in_array( $origin, array( 'theme', 'custom' ), true ) || static::get_theme_supports_data() === static::$theme_support_data ) ) { return static::$merged[ $origin ]; } @@ -636,17 +638,25 @@ public static function get_merged_data( $origin = 'custom' ) { $result->merge( static::get_core_data() ); if ( 'default' === $origin ) { $result->set_spacing_sizes(); + + static::$merged[ $origin ] = $result; + return $result; } $result->merge( static::get_block_data() ); if ( 'blocks' === $origin ) { + static::$merged[ $origin ] = $result; + return $result; } $result->merge( static::get_theme_data() ); if ( 'theme' === $origin ) { $result->set_spacing_sizes(); + + static::$merged[ $origin ] = $result; + return $result; }