From 0002770c9dcb39623700fcc4735cb23c54285935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 10 Oct 2022 22:38:28 +0200 Subject: [PATCH 01/15] Cache theme data if blocks have not changed --- .../class-wp-theme-json-resolver.php | 62 +++++++++++++++---- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index e97c31a4f5ed9..94b174bdf84d5 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -20,6 +20,16 @@ #[AllowDynamicProperties] class WP_Theme_JSON_Resolver { + /** + * Container for keep track of registered blocks. + * + * @since 6.1.0 + * @var array + */ + protected static $blocks_meta = array( + 'theme' => array(), + ); + /** * Container for data coming from core. * @@ -162,6 +172,31 @@ public static function get_core_data() { return static::$core; } + /** + * Checks whether the registered blocks are the same + * as the ones we already processed for this origin. + * + * @since 6.1.0 + * + * @param $origin One of 'core', 'theme'. Source of data we cache blocks for. + * + * @return boolean + */ + protected static function has_same_registered_blocks( $origin ) { + $registry = WP_Block_Type_Registry::get_instance(); + $blocks = $registry->get_all_registered(); + + // Is there metadata for all currently registered blocks? + $block_diff = array_diff_key( $blocks, static::$blocks_meta[ $origin ] ); + if ( empty( $block_diff ) ) { + return true; + } + + static::$blocks_meta[ $origin ] = $blocks; + + return false; + } + /** * Returns the theme's data. * @@ -189,19 +224,21 @@ public static function get_theme_data( $deprecated = array(), $options = array() $options = wp_parse_args( $options, array( 'with_supports' => true ) ); - $theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) ); - $theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); + if ( null === static::$theme || ! static::has_same_registered_blocks( 'theme' ) ) { + $theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) ); + $theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); - /** - * Filters the data provided by the theme for global styles and settings. - * - * @since 6.1.0 - * - * @param WP_Theme_JSON_Data Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'theme_json_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) ); - $theme_json_data = $theme_json->get_data(); - static::$theme = new WP_Theme_JSON( $theme_json_data ); + /** + * Filters the data provided by the theme for global styles and settings. + * + * @since 6.1.0 + * + * @param WP_Theme_JSON_Data Class to access and update the underlying data. + */ + $theme_json = apply_filters( 'theme_json_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) ); + $theme_json_data = $theme_json->get_data(); + static::$theme = new WP_Theme_JSON( $theme_json_data ); + } if ( wp_get_theme()->parent() ) { // Get parent theme.json. @@ -258,7 +295,6 @@ public static function get_theme_data( $deprecated = array(), $options = array() } $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); $with_theme_supports->merge( static::$theme ); - return $with_theme_supports; } From cb15514894fc057f7962df20f2010c3e1f92ca09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 10 Oct 2022 22:44:28 +0200 Subject: [PATCH 02/15] Cache core data if blocks have not changed --- src/wp-includes/class-wp-theme-json-resolver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 94b174bdf84d5..db1506e784185 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -27,6 +27,7 @@ class WP_Theme_JSON_Resolver { * @var array */ protected static $blocks_meta = array( + 'core' => array(), 'theme' => array(), ); @@ -155,6 +156,10 @@ protected static function translate( $theme_json, $domain = 'default' ) { * @return WP_Theme_JSON Entity that holds core data. */ public static function get_core_data() { + if ( null !== static::$core && static::has_same_registered_blocks( 'core' ) ) { + return static::$core; + } + $config = static::read_json_file( __DIR__ . '/theme.json' ); $config = static::translate( $config ); From 3d67b7eb5bd14b0dc694ea810164fd9017fd3a54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 10 Oct 2022 23:56:35 +0200 Subject: [PATCH 03/15] Cache blocks data if blocks have not changed --- .../class-wp-theme-json-resolver.php | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index db1506e784185..4c05992c3e51c 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -27,8 +27,9 @@ class WP_Theme_JSON_Resolver { * @var array */ protected static $blocks_meta = array( - 'core' => array(), - 'theme' => array(), + 'core' => array(), + 'blocks' => array(), + 'theme' => array(), ); /** @@ -39,6 +40,15 @@ class WP_Theme_JSON_Resolver { */ protected static $core = null; + /** + * Container for data coming from the blocks. + * + * @since 6.1.0 + * + * @var WP_Theme_JSON + */ + protected static $blocks = null; + /** * Container for data coming from the theme. * @@ -313,7 +323,12 @@ public static function get_theme_data( $deprecated = array(), $options = array() public static function get_block_data() { $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered(); - $config = array( 'version' => 1 ); + + if ( null !== static::$blocks && static::has_same_registered_blocks( 'blocks' ) ) { + return static::$blocks; + } + + $config = array( 'version' => 1 ); foreach ( $blocks as $block_name => $block_type ) { if ( isset( $block_type->supports['__experimentalStyle'] ) ) { $config['styles']['blocks'][ $block_name ] = static::remove_json_comments( $block_type->supports['__experimentalStyle'] ); @@ -339,7 +354,8 @@ public static function get_block_data() { $theme_json = apply_filters( 'theme_json_blocks', new WP_Theme_JSON_Data( $config, 'blocks' ) ); $config = $theme_json->get_data(); - return new WP_Theme_JSON( $config, 'blocks' ); + static::$blocks = new WP_Theme_JSON( $config, 'blocks' ); + return static::$blocks; } /** @@ -606,6 +622,7 @@ protected static function get_file_path_from_theme( $file_name, $template = fals */ public static function clean_cached_data() { static::$core = null; + static::$blocks = null; static::$theme = null; static::$user = null; static::$user_custom_post_type_id = null; From 481ae787de34994c1cc7fc11ebe01c6a214f9ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 10 Oct 2022 23:57:43 +0200 Subject: [PATCH 04/15] Clean blocks meta upon cache flush --- src/wp-includes/class-wp-theme-json-resolver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 4c05992c3e51c..6b1e0127446c6 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -623,6 +623,11 @@ protected static function get_file_path_from_theme( $file_name, $template = fals public static function clean_cached_data() { static::$core = null; static::$blocks = null; + static::$blocks_meta = array( + 'core' => array(), + 'blocks' => array(), + 'theme' => array(), + ); static::$theme = null; static::$user = null; static::$user_custom_post_type_id = null; From 9e229c3e4f3eb81af574fd18eaa29a5e7a541f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 00:04:59 +0200 Subject: [PATCH 05/15] Better naming --- src/wp-includes/class-wp-theme-json-resolver.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 6b1e0127446c6..e75a614894770 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -26,7 +26,7 @@ class WP_Theme_JSON_Resolver { * @since 6.1.0 * @var array */ - protected static $blocks_meta = array( + protected static $blocks_cache = array( 'core' => array(), 'blocks' => array(), 'theme' => array(), @@ -202,12 +202,12 @@ protected static function has_same_registered_blocks( $origin ) { $blocks = $registry->get_all_registered(); // Is there metadata for all currently registered blocks? - $block_diff = array_diff_key( $blocks, static::$blocks_meta[ $origin ] ); + $block_diff = array_diff_key( $blocks, static::$blocks_cache[ $origin ] ); if ( empty( $block_diff ) ) { return true; } - static::$blocks_meta[ $origin ] = $blocks; + static::$blocks_cache[ $origin ] = $blocks; return false; } @@ -623,7 +623,7 @@ protected static function get_file_path_from_theme( $file_name, $template = fals public static function clean_cached_data() { static::$core = null; static::$blocks = null; - static::$blocks_meta = array( + static::$blocks_cache = array( 'core' => array(), 'blocks' => array(), 'theme' => array(), From 83da1ad6096c106c701fb574c0d30664125b09c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 00:05:11 +0200 Subject: [PATCH 06/15] Use less memory --- src/wp-includes/class-wp-theme-json-resolver.php | 4 +++- 1 file changed, 3 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 e75a614894770..a37461bc134af 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -207,7 +207,9 @@ protected static function has_same_registered_blocks( $origin ) { return true; } - static::$blocks_cache[ $origin ] = $blocks; + foreach( $blocks as $block_name => $block_type ) { + static::$blocks_cache[ $origin ][ $block_name ] = true; + } return false; } From 8e1181dda232511ef39ed77d68fedb28482f5119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 00:13:47 +0200 Subject: [PATCH 07/15] Cache user data if blocks have not changed --- 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 a37461bc134af..6f17885393f00 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -30,6 +30,7 @@ class WP_Theme_JSON_Resolver { 'core' => array(), 'blocks' => array(), 'theme' => array(), + 'user' => array(), ); /** @@ -466,6 +467,10 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post * @return WP_Theme_JSON Entity that holds styles for user data. */ public static function get_user_data() { + if ( null !== static::$user && static::has_same_registered_blocks( 'user' ) ) { + return static::$user; + } + $config = array(); $user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme() ); @@ -629,6 +634,7 @@ public static function clean_cached_data() { 'core' => array(), 'blocks' => array(), 'theme' => array(), + 'user' => array(), ); static::$theme = null; static::$user = null; From 74ad7d0c1ddfd472205df80cd813ddef1cc8e874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 00:41:01 +0200 Subject: [PATCH 08/15] Fix lint issue --- src/wp-includes/class-wp-theme-json-resolver.php | 2 +- 1 file changed, 1 insertion(+), 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 6f17885393f00..5d52d5da586b4 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -208,7 +208,7 @@ protected static function has_same_registered_blocks( $origin ) { return true; } - foreach( $blocks as $block_name => $block_type ) { + foreach ( $blocks as $block_name => $block_type ) { static::$blocks_cache[ $origin ][ $block_name ] = true; } From 875a0bdde94ecbad5e63f53861f8db062b222b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 09:04:51 +0200 Subject: [PATCH 09/15] PHPDoc improvements --- src/wp-includes/class-wp-theme-json-resolver.php | 5 ++++- 1 file changed, 4 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 5d52d5da586b4..f201d8cacc6aa 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -24,6 +24,7 @@ class WP_Theme_JSON_Resolver { * Container for keep track of registered blocks. * * @since 6.1.0 + * * @var array */ protected static $blocks_cache = array( @@ -196,7 +197,7 @@ public static function get_core_data() { * * @param $origin One of 'core', 'theme'. Source of data we cache blocks for. * - * @return boolean + * @return boolean True on success, false otherwise. */ protected static function has_same_registered_blocks( $origin ) { $registry = WP_Block_Type_Registry::get_instance(); @@ -626,6 +627,8 @@ protected static function get_file_path_from_theme( $file_name, $template = fals * @since 5.8.0 * @since 5.9.0 Added the `$user`, `$user_custom_post_type_id`, * and `$i18n_schema` variables to reset. + * @since 6.1.0 Added the `$blocks` and `$blocks_cache` variables + * to reset. */ public static function clean_cached_data() { static::$core = null; From 86694ea847127c95655dd7716ddb6cf6cd883ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 09:06:04 +0200 Subject: [PATCH 10/15] PHPDoc improvements --- src/wp-includes/class-wp-theme-json-resolver.php | 2 +- 1 file changed, 1 insertion(+), 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 f201d8cacc6aa..950d7075bc176 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -195,7 +195,7 @@ public static function get_core_data() { * * @since 6.1.0 * - * @param $origin One of 'core', 'theme'. Source of data we cache blocks for. + * @param $origin One of 'core', 'blocks', 'theme', 'user'. Source of data we cache blocks for. * * @return boolean True on success, false otherwise. */ From 0270b3acd21ffdb1970d7893e009a80fec853498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 11 Oct 2022 09:17:33 +0200 Subject: [PATCH 11/15] PHPDoc improvements --- 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 950d7075bc176..32fb198dc37f6 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -24,7 +24,6 @@ class WP_Theme_JSON_Resolver { * Container for keep track of registered blocks. * * @since 6.1.0 - * * @var array */ protected static $blocks_cache = array( @@ -46,7 +45,6 @@ class WP_Theme_JSON_Resolver { * Container for data coming from the blocks. * * @since 6.1.0 - * * @var WP_Theme_JSON */ protected static $blocks = null; From bad2ba789db72a85645df268c2f2411ac4e6c3c2 Mon Sep 17 00:00:00 2001 From: Tonya Mork Date: Tue, 11 Oct 2022 07:30:21 -0500 Subject: [PATCH 12/15] DocBlock improvements * Removes "we" words * Adds data type to `@param` * Improves readability and consistency --- src/wp-includes/class-wp-theme-json-resolver.php | 6 +++--- 1 file changed, 3 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 32fb198dc37f6..69411caeddc48 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -188,12 +188,12 @@ public static function get_core_data() { } /** - * Checks whether the registered blocks are the same - * as the ones we already processed for this origin. + * Checks whether the registered blocks were already processed for this origin. * * @since 6.1.0 * - * @param $origin One of 'core', 'blocks', 'theme', 'user'. Source of data we cache blocks for. + * @param string $origin Data source for which to cache the blocks. + Valid values are 'core', 'blocks', 'theme', and 'user'. * * @return boolean True on success, false otherwise. */ From 94fa33a7bd6658089337a8409e398a49fb7851c4 Mon Sep 17 00:00:00 2001 From: hellofromtonya Date: Tue, 11 Oct 2022 07:53:29 -0500 Subject: [PATCH 13/15] DocBlock formatting --- src/wp-includes/class-wp-theme-json-resolver.php | 5 ++--- 1 file changed, 2 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 69411caeddc48..b43f7582bd146 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -193,9 +193,8 @@ public static function get_core_data() { * @since 6.1.0 * * @param string $origin Data source for which to cache the blocks. - Valid values are 'core', 'blocks', 'theme', and 'user'. - * - * @return boolean True on success, false otherwise. + * Valid values are 'core', 'blocks', 'theme', and 'user'. + * @return bool True on success, false otherwise. */ protected static function has_same_registered_blocks( $origin ) { $registry = WP_Block_Type_Registry::get_instance(); From 9c3c14ddad32c378a5b0364c16a0bfacd2b15662 Mon Sep 17 00:00:00 2001 From: hellofromtonya Date: Tue, 11 Oct 2022 10:27:34 -0500 Subject: [PATCH 14/15] Adds tests for get_core_data() --- .../tests/theme/wpThemeJsonResolver.php | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) diff --git a/tests/phpunit/tests/theme/wpThemeJsonResolver.php b/tests/phpunit/tests/theme/wpThemeJsonResolver.php index 9b43a4fb33eb1..bbfffde317b31 100644 --- a/tests/phpunit/tests/theme/wpThemeJsonResolver.php +++ b/tests/phpunit/tests/theme/wpThemeJsonResolver.php @@ -33,6 +33,52 @@ class Tests_Theme_wpThemeJsonResolver extends WP_UnitTestCase { */ private $queries = array(); + /** + * WP_Theme_JSON_Resolver::$blocks_cache property. + * + * @var ReflectionProperty + */ + private static $property_blocks_cache; + + /** + * Original value of the WP_Theme_JSON_Resolver::$blocks_cache property. + * + * @var array + */ + private static $property_blocks_cache_orig_value; + + /** + * WP_Theme_JSON_Resolver::$core property. + * + * @var ReflectionProperty + */ + private static $property_core; + + /** + * Original value of the WP_Theme_JSON_Resolver::$core property. + * + * @var WP_Theme_JSON + */ + private static $property_core_orig_value; + + public static function set_up_before_class() { + parent::set_up_before_class(); + + static::$property_blocks_cache = new ReflectionProperty( WP_Theme_JSON_Resolver::class, 'blocks_cache' ); + static::$property_blocks_cache->setAccessible( true ); + static::$property_blocks_cache_orig_value = static::$property_blocks_cache->getValue(); + + static::$property_core = new ReflectionProperty( WP_Theme_JSON_Resolver::class, 'core' ); + static::$property_core->setAccessible( true ); + static::$property_core_orig_value = static::$property_core->getValue(); + } + + public static function tear_down_after_class() { + static::$property_blocks_cache->setValue( WP_Theme_JSON_Resolver::class, static::$property_blocks_cache_orig_value ); + static::$property_core->setValue( WP_Theme_JSON_Resolver::class, static::$property_core_orig_value ); + parent::tear_down_after_class(); + } + public function set_up() { parent::set_up(); $this->theme_root = realpath( DIR_TESTDATA . '/themedir1' ); @@ -55,6 +101,9 @@ public function tear_down() { $GLOBALS['wp_theme_directories'] = $this->orig_theme_dir; wp_clean_themes_cache(); unset( $GLOBALS['wp_themes'] ); + + // Reset data between tests. + WP_Theme_JSON_Resolver::clean_cached_data(); parent::tear_down(); } @@ -190,6 +239,198 @@ public function test_translations_are_applied() { ); } + private function get_registered_block_names( $hard_reset = false ) { + static $expected_block_names; + + if ( ! $hard_reset && ! empty( $expected_block_names ) ) { + return $expected_block_names; + } + + $expected_block_names = array(); + $resolver = WP_Block_Type_Registry::get_instance(); + $blocks = $resolver->get_all_registered(); + foreach ( array_keys( $blocks ) as $block_name ) { + $expected_block_names[ $block_name ] = true; + } + + return $expected_block_names; + } + + /** + * Tests when WP_Theme_JSON_Resolver::$blocks_cache is empty or does not match + * the all registered blocks. + * + * Though this is a non-public method, it is vital to other functionality. + * Therefore, tests are provided to validate it functions as expected. + * + * @dataProvider data_has_same_registered_blocks_when_all_blocks_not_cached + * @ticket 56467 + * + * @param string $origin The origin to test. + */ + public function test_has_same_registered_blocks_when_all_blocks_not_cached( $origin, array $cache = array() ) { + $has_same_registered_blocks = new ReflectionMethod( WP_Theme_JSON_Resolver::class, 'has_same_registered_blocks' ); + $has_same_registered_blocks->setAccessible( true ); + $expected_cache = $this->get_registered_block_names(); + + // Set up the blocks cache for the origin. + $blocks_cache = static::$property_blocks_cache->getValue(); + $blocks_cache[ $origin ] = $cache; + static::$property_blocks_cache->setValue( null, $blocks_cache ); + + $this->assertFalse( $has_same_registered_blocks->invoke( null, $origin ), 'WP_Theme_JSON_Resolver::has_same_registered_blocks() should return false when same blocks are not cached' ); + $blocks_cache = static::$property_blocks_cache->getValue(); + $this->assertSameSets( $expected_cache, $blocks_cache[ $origin ], 'WP_Theme_JSON_Resolver::$blocks_cache should contain all expected block names for the given origin' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_has_same_registered_blocks_when_all_blocks_not_cached() { + return array( + 'origin: core; cache: empty' => array( + 'origin' => 'core', + ), + 'origin: blocks; cache: empty' => array( + 'origin' => 'blocks', + ), + 'origin: theme; cache: empty' => array( + 'origin' => 'theme', + ), + 'origin: user; cache: empty' => array( + 'origin' => 'user', + ), + 'origin: core; cache: not empty' => array( + 'origin' => 'core', + 'cache' => array( + 'core/block' => true, + ), + ), + 'origin: blocks; cache: not empty' => array( + 'origin' => 'blocks', + 'cache' => array( + 'core/block' => true, + 'core/comments' => true, + ), + ), + 'origin: theme; cache: not empty' => array( + 'origin' => 'theme', + 'cache' => array( + 'core/cover' => true, + ), + ), + 'origin: user; cache: not empty' => array( + 'origin' => 'user', + 'cache' => array( + 'core/gallery' => true, + ), + ), + ); + } + + /** + * Tests when WP_Theme_JSON_Resolver::$blocks_cache is empty or does not match + * the all registered blocks. + * + * Though this is a non-public method, it is vital to other functionality. + * Therefore, tests are provided to validate it functions as expected. + * + * @dataProvider data_has_same_registered_blocks_when_all_blocks_are_cached + * @ticket 56467 + * + * @param string $origin The origin to test. + */ + public function test_has_same_registered_blocks_when_all_blocks_are_cached( $origin ) { + $has_same_registered_blocks = new ReflectionMethod( WP_Theme_JSON_Resolver::class, 'has_same_registered_blocks' ); + $has_same_registered_blocks->setAccessible( true ); + $expected_cache = $this->get_registered_block_names(); + + // Set up the cache with all registered blocks. + $blocks_cache = static::$property_blocks_cache->getValue(); + $blocks_cache[ $origin ] = $this->get_registered_block_names(); + static::$property_blocks_cache->setValue( null, $blocks_cache ); + + $this->assertTrue( $has_same_registered_blocks->invoke( null, $origin ), 'WP_Theme_JSON_Resolver::has_same_registered_blocks() should return true when using the cache' ); + $this->assertSameSets( $expected_cache, $blocks_cache[ $origin ], 'WP_Theme_JSON_Resolver::$blocks_cache should contain all expected block names for the given origin' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_has_same_registered_blocks_when_all_blocks_are_cached() { + return array( + 'core' => array( 'core' ), + 'blocks' => array( 'blocks' ), + 'theme' => array( 'theme' ), + 'user' => array( 'user' ), + ); + } + + /** + * @dataProvider data_get_core_data + * @covers WP_Theme_JSON_Resolver::get_core_data + * @ticket 56467 + */ + public function test_get_core_data( $should_fire_filter, $core_is_cached, $blocks_are_cached ) { + WP_Theme_JSON_Resolver::clean_cached_data(); + + // If should cache core, then fire the method to cache it before running the tests. + if ( $core_is_cached ) { + WP_Theme_JSON_Resolver::get_core_data(); + } + + // If should cache registered blocks, then set them up before running the tests. + if ( $blocks_are_cached ) { + $blocks_cache = static::$property_blocks_cache->getValue(); + $blocks_cache['core'] = $this->get_registered_block_names(); + static::$property_blocks_cache->setValue( null, $blocks_cache ); + } + + $expected_filter_count = did_filter( 'theme_json_default' ); + $actual = WP_Theme_JSON_Resolver::get_core_data(); + if ( $should_fire_filter ) { + $expected_filter_count++; + } + + $this->assertSame( $expected_filter_count, did_filter( 'theme_json_default' ), 'The filter "theme_json_default" should fire the given number of times' ); + $this->assertInstanceOf( WP_Theme_JSON::class, $actual, 'WP_Theme_JSON_Resolver::get_core_data() should return instance of WP_Theme_JSON' ); + $this->assertSame( static::$property_core->getValue(), $actual, 'WP_Theme_JSON_Resolver::$core property should be the same object as returned from WP_Theme_JSON_Resolver::get_core_data()' ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_get_core_data() { + return array( + 'When both caches are empty' => array( + 'should_fire_filter' => true, + 'core_is_cached' => false, + 'blocks_are_cached' => false, + ), + 'When the blocks_cache is not empty and matches' => array( + 'should_fire_filter' => true, + 'core_is_cached' => false, + 'blocks_are_cached' => true, + ), + 'When blocks_cache is empty but core cache is not' => array( + 'should_fire_filter' => true, + 'core_is_cached' => true, + 'blocks_are_cached' => false, + ), + 'When both caches are not empty' => array( + 'should_fire_filter' => true, + 'core_is_cached' => true, + 'blocks_are_cached' => false, + ), + ); + } + /** * @ticket 52991 */ From 14c802bb45495dc7b232e0b51ba113844be1b314 Mon Sep 17 00:00:00 2001 From: hellofromtonya Date: Tue, 11 Oct 2022 10:56:13 -0500 Subject: [PATCH 15/15] Guard if the origin is invalid --- src/wp-includes/class-wp-theme-json-resolver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index b43f7582bd146..2d0ad4bf53bd3 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -197,6 +197,11 @@ public static function get_core_data() { * @return bool True on success, false otherwise. */ protected static function has_same_registered_blocks( $origin ) { + // Bail out if the origin is invalid. + if ( ! isset( static::$blocks_cache[ $origin ] ) ) { + return false; + } + $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered();