From 02e2600bd59cb49f0a3d5cb33669b8e0afdd441c Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Fri, 30 Sep 2022 12:44:01 +1000 Subject: [PATCH] Theme JSON and Resolver: Update block caching logic to clear based on number of registered blocks --- .../class-wp-theme-json-resolver.php | 40 +++++++++++++++++-- src/wp-includes/class-wp-theme-json.php | 34 +++++++++++++++- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index a92f5c1e09f4f..c9dee35c79bcf 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -36,6 +36,15 @@ class WP_Theme_JSON_Resolver { */ protected static $theme = null; + /** + * Holds a cache key string, to determine when + * to generate fresh theme data. + * + * @since 6.1.0 + * @var string + */ + protected static $theme_cache_key = null; + /** * Whether or not the theme supports theme.json. * @@ -90,6 +99,25 @@ protected static function read_json_file( $file_path ) { return $config; } + /** + * Generates a new cache key to determine when to clear theme cache. + * + * @since 6.1.0 + * + * @return string A cache key. + */ + protected static function get_new_theme_cache_key() { + $registry = WP_Block_Type_Registry::get_instance(); + $blocks = $registry->get_all_registered(); + + /* + * Generate the key based on the current number of blocks registered. + * This ensures that Theme JSON data accessed at registration time + * does not result in stale block data. + */ + return 'registered-blocks-' . count( $blocks ); + } + /** * Returns a data structure used in theme.json translation. * @@ -162,6 +190,7 @@ public static function get_core_data() { * @since 5.8.0 * @since 5.9.0 Theme supports have been inlined and the `$theme_support_data` argument removed. * @since 6.0.0 Added an `$options` parameter to allow the theme data to be returned without theme supports. + * @since 6.1.0 Clear `$theme` cache if number of registered blocks has changed. * * @param array $deprecated Deprecated. Not used. * @param array $options { @@ -176,11 +205,13 @@ public static function get_theme_data( $deprecated = array(), $options = array() _deprecated_argument( __METHOD__, '5.9.0' ); } - $options = wp_parse_args( $options, array( 'with_supports' => true ) ); + $options = wp_parse_args( $options, array( 'with_supports' => true ) ); + $new_cache_key = static::get_new_theme_cache_key(); - if ( null === static::$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' ) ); + if ( null === static::$theme || $new_cache_key !== static::$theme_cache_key ) { + static::$theme_cache_key = $new_cache_key; + $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 & settings. * @@ -560,6 +591,7 @@ protected static function get_file_path_from_theme( $file_name, $template = fals public static function clean_cached_data() { static::$core = null; static::$theme = null; + static::$theme_cache_key = null; static::$user = null; static::$user_custom_post_type_id = null; static::$theme_has_support = null; diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 4f5627a7904b9..1ddcdf5d02590 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -37,6 +37,15 @@ class WP_Theme_JSON { */ protected static $blocks_metadata = null; + /** + * Holds a cache key string, to determine when + * to generate fresh block data. + * + * @since 6.1.0 + * @var string + */ + protected static $blocks_cache_key = null; + /** * The CSS selector for the top-level styles. * @@ -690,6 +699,25 @@ protected static function append_to_selector( $selector, $to_append, $position = return implode( ',', $new_selectors ); } + /** + * Generates a new cache key to determine when to clear blocks cache. + * + * @since 6.1.0 + * + * @return string A cache key. + */ + protected static function get_new_blocks_cache_key() { + $registry = WP_Block_Type_Registry::get_instance(); + $blocks = $registry->get_all_registered(); + + /* + * Generate the key based on the current number of blocks registered. + * This ensures that Theme JSON data accessed at registration time + * does not result in stale block data. + */ + return 'registered-blocks-' . count( $blocks ); + } + /** * Returns the metadata for each block. * @@ -721,11 +749,13 @@ protected static function append_to_selector( $selector, $to_append, $position = * @return array Block metadata. */ protected static function get_blocks_metadata() { - if ( null !== static::$blocks_metadata ) { + $new_cache_key = static::get_new_blocks_cache_key(); + if ( null !== static::$blocks_metadata && $new_cache_key === static::$blocks_cache_key ) { return static::$blocks_metadata; } - static::$blocks_metadata = array(); + static::$blocks_cache_key = $new_cache_key; + static::$blocks_metadata = array(); $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered();