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 1/7] 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(); From 2e1c4a8c746fac7d2b7608b0f9a30d7275a3dbef Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Mon, 3 Oct 2022 12:37:57 +1100 Subject: [PATCH 2/7] Attempt to clear cache whenever blocks are registered --- .../class-wp-theme-json-resolver.php | 33 +------------------ src/wp-includes/class-wp-theme-json.php | 31 ++++------------- src/wp-includes/default-filters.php | 1 + src/wp-includes/theme.php | 12 +++++++ 4 files changed, 20 insertions(+), 57 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index c9dee35c79bcf..e5c473681fc7e 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -36,15 +36,6 @@ 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. * @@ -99,25 +90,6 @@ 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. * @@ -206,10 +178,8 @@ public static function get_theme_data( $deprecated = array(), $options = array() } $options = wp_parse_args( $options, array( 'with_supports' => true ) ); - $new_cache_key = static::get_new_theme_cache_key(); - if ( null === static::$theme || $new_cache_key !== static::$theme_cache_key ) { - static::$theme_cache_key = $new_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' ) ); /** @@ -591,7 +561,6 @@ 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 1ddcdf5d02590..0cc8999fdd0a7 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -37,15 +37,6 @@ 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. * @@ -700,22 +691,12 @@ protected static function append_to_selector( $selector, $to_append, $position = } /** - * Generates a new cache key to determine when to clear blocks cache. + * Cleans the cached data so it can be recalculated. * * @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 ); + public static function clean_cached_data() { + static::$blocks_metadata = null; } /** @@ -749,12 +730,12 @@ protected static function get_new_blocks_cache_key() { * @return array Block metadata. */ protected static function get_blocks_metadata() { - $new_cache_key = static::get_new_blocks_cache_key(); - if ( null !== static::$blocks_metadata && $new_cache_key === static::$blocks_cache_key ) { + // $new_cache_key = static::get_new_blocks_cache_key(); + if ( null !== static::$blocks_metadata ) { return static::$blocks_metadata; } - static::$blocks_cache_key = $new_cache_key; + // static::$blocks_cache_key = $new_cache_key; static::$blocks_metadata = array(); $registry = WP_Block_Type_Registry::get_instance(); diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 725f5ef3cbce5..17097124bfc60 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -231,6 +231,7 @@ add_filter( 'widget_block_content', 'do_shortcode', 11 ); add_filter( 'block_type_metadata', 'wp_migrate_old_typography_shape' ); +add_filter( 'register_block_type_args', 'wp_clean_theme_json_cache' ); add_filter( 'wp_get_custom_css', 'wp_replace_insecure_home_url' ); diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 84077a5d2c28b..d1045e5eb89f5 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -147,6 +147,18 @@ function wp_clean_themes_cache( $clear_update_cache = true ) { } } +/** + * Clears the cache held by WP_Theme_JSON and WP_Theme_JSON_Resolver classes. + * + * @since 6.1.0 + * @param array $args Arguments to be returned when this function is used in a filter. + */ +function wp_clean_theme_json_cache( $args ) { + WP_Theme_JSON::clean_cached_data(); + WP_Theme_JSON_Resolver::clean_cached_data(); + return $args; +} + /** * Whether a child theme is in use. * From 2002af59f07a26481e884386fb9a16e2c49127d3 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Mon, 3 Oct 2022 12:39:55 +1100 Subject: [PATCH 3/7] Tidy up --- src/wp-includes/class-wp-theme-json-resolver.php | 7 +++---- src/wp-includes/class-wp-theme-json.php | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index e5c473681fc7e..a92f5c1e09f4f 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -162,7 +162,6 @@ 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 { @@ -177,11 +176,11 @@ 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 ) ); 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' ) ); + $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. * diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 0cc8999fdd0a7..4ba43ecccc14c 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -730,13 +730,11 @@ public static function clean_cached_data() { * @return array Block metadata. */ protected static function get_blocks_metadata() { - // $new_cache_key = static::get_new_blocks_cache_key(); if ( null !== static::$blocks_metadata ) { return static::$blocks_metadata; } - // static::$blocks_cache_key = $new_cache_key; - static::$blocks_metadata = array(); + static::$blocks_metadata = array(); $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered(); From 953f9699475c0465452287c9e8b3ce9025672a93 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Mon, 3 Oct 2022 16:11:25 +1100 Subject: [PATCH 4/7] Try: Add registered_block_type actions --- src/wp-includes/blocks.php | 26 ++++++++++++++++++++++++-- src/wp-includes/default-filters.php | 2 +- src/wp-includes/theme.php | 4 +--- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index d6db591bc6fcf..daa38f69f0c8e 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -497,10 +497,21 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $metadata ); - return WP_Block_Type_Registry::get_instance()->register( + $block = WP_Block_Type_Registry::get_instance()->register( $metadata['name'], $settings ); + + /** + * Fires after a block type is registered. + * + * @since 6.1.0 + * + * @param WP_Block_Type|false $block The registered block type on success, or false on failure. + */ + do_action( 'registered_block_type', $block ); + + return $block; } /** @@ -526,7 +537,18 @@ function register_block_type( $block_type, $args = array() ) { return register_block_type_from_metadata( $block_type, $args ); } - return WP_Block_Type_Registry::get_instance()->register( $block_type, $args ); + $block = WP_Block_Type_Registry::get_instance()->register( $block_type, $args ); + + /** + * Fires after a block type is registered. + * + * @since 6.1.0 + * + * @param WP_Block_Type|false $block The registered block type on success, or false on failure. + */ + do_action( 'registered_block_type', $block ); + + return $block; } /** diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 17097124bfc60..13d9a41a3ba9b 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -231,7 +231,6 @@ add_filter( 'widget_block_content', 'do_shortcode', 11 ); add_filter( 'block_type_metadata', 'wp_migrate_old_typography_shape' ); -add_filter( 'register_block_type_args', 'wp_clean_theme_json_cache' ); add_filter( 'wp_get_custom_css', 'wp_replace_insecure_home_url' ); @@ -353,6 +352,7 @@ add_action( 'after_switch_theme', '_wp_sidebars_changed' ); add_action( 'wp_print_styles', 'print_emoji_styles' ); add_action( 'plugins_loaded', '_wp_theme_json_webfonts_handler' ); +add_filter( 'registered_block_type', 'wp_clean_theme_json_cache' ); if ( isset( $_GET['replytocom'] ) ) { add_filter( 'wp_robots', 'wp_robots_no_robots' ); diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index d1045e5eb89f5..4342fad6c6302 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -151,12 +151,10 @@ function wp_clean_themes_cache( $clear_update_cache = true ) { * Clears the cache held by WP_Theme_JSON and WP_Theme_JSON_Resolver classes. * * @since 6.1.0 - * @param array $args Arguments to be returned when this function is used in a filter. */ -function wp_clean_theme_json_cache( $args ) { +function wp_clean_theme_json_cache() { WP_Theme_JSON::clean_cached_data(); WP_Theme_JSON_Resolver::clean_cached_data(); - return $args; } /** From 76fdfe7c721a6e89c8224e112fa8076ef4aec2c9 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Tue, 4 Oct 2022 11:02:04 +1100 Subject: [PATCH 5/7] Move actions to the registry class --- src/wp-includes/blocks.php | 26 ++----------------- .../class-wp-block-type-registry.php | 18 +++++++++++++ 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index daa38f69f0c8e..d6db591bc6fcf 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -497,21 +497,10 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $metadata ); - $block = WP_Block_Type_Registry::get_instance()->register( + return WP_Block_Type_Registry::get_instance()->register( $metadata['name'], $settings ); - - /** - * Fires after a block type is registered. - * - * @since 6.1.0 - * - * @param WP_Block_Type|false $block The registered block type on success, or false on failure. - */ - do_action( 'registered_block_type', $block ); - - return $block; } /** @@ -537,18 +526,7 @@ function register_block_type( $block_type, $args = array() ) { return register_block_type_from_metadata( $block_type, $args ); } - $block = WP_Block_Type_Registry::get_instance()->register( $block_type, $args ); - - /** - * Fires after a block type is registered. - * - * @since 6.1.0 - * - * @param WP_Block_Type|false $block The registered block type on success, or false on failure. - */ - do_action( 'registered_block_type', $block ); - - return $block; + return WP_Block_Type_Registry::get_instance()->register( $block_type, $args ); } /** diff --git a/src/wp-includes/class-wp-block-type-registry.php b/src/wp-includes/class-wp-block-type-registry.php index 84adecd5d0774..cee5c3252b8ae 100644 --- a/src/wp-includes/class-wp-block-type-registry.php +++ b/src/wp-includes/class-wp-block-type-registry.php @@ -96,6 +96,15 @@ public function register( $name, $args = array() ) { $this->registered_block_types[ $name ] = $block_type; + /** + * Fires after a block type is registered. + * + * @since 6.1.0 + * + * @param WP_Block_Type|false $block_type The registered block type on success, or false on failure. + */ + do_action( 'registered_block_type', $block_type ); + return $block_type; } @@ -126,6 +135,15 @@ public function unregister( $name ) { $unregistered_block_type = $this->registered_block_types[ $name ]; unset( $this->registered_block_types[ $name ] ); + /** + * Fires after a block type is unregistered. + * + * @since 6.1.0 + * + * @param WP_Block_Type|false $block_type The unregistered block type on success, or false on failure. + */ + do_action( 'unregistered_block_type', $unregistered_block_type ); + return $unregistered_block_type; } From 5782aa355170fc6c7dd584e2e078b079036b386f Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Tue, 4 Oct 2022 11:13:35 +1100 Subject: [PATCH 6/7] Empty commit to restart tests From a7b702197259f8a01b7d7a06fede7fe591d0fd8d Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Tue, 4 Oct 2022 15:36:53 +1100 Subject: [PATCH 7/7] Update comments --- src/wp-includes/class-wp-block-type-registry.php | 8 ++++---- src/wp-includes/theme.php | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-block-type-registry.php b/src/wp-includes/class-wp-block-type-registry.php index cee5c3252b8ae..2b9cb46728feb 100644 --- a/src/wp-includes/class-wp-block-type-registry.php +++ b/src/wp-includes/class-wp-block-type-registry.php @@ -97,11 +97,11 @@ public function register( $name, $args = array() ) { $this->registered_block_types[ $name ] = $block_type; /** - * Fires after a block type is registered. + * Fires after a block type is registered with the WP_Block_Type_Registry class. * * @since 6.1.0 * - * @param WP_Block_Type|false $block_type The registered block type on success, or false on failure. + * @param WP_Block_Type $block_type The registered block type on success. */ do_action( 'registered_block_type', $block_type ); @@ -136,11 +136,11 @@ public function unregister( $name ) { unset( $this->registered_block_types[ $name ] ); /** - * Fires after a block type is unregistered. + * Fires after a block type is unregistered with the WP_Block_Type_Registry class. * * @since 6.1.0 * - * @param WP_Block_Type|false $block_type The unregistered block type on success, or false on failure. + * @param WP_Block_Type $block_type The unregistered block type on success. */ do_action( 'unregistered_block_type', $unregistered_block_type ); diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 4342fad6c6302..ffb672a3c6aa5 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -150,6 +150,8 @@ function wp_clean_themes_cache( $clear_update_cache = true ) { /** * Clears the cache held by WP_Theme_JSON and WP_Theme_JSON_Resolver classes. * + * Ensures that subsequent calls to either class generate fresh core, theme, user, and block data. + * * @since 6.1.0 */ function wp_clean_theme_json_cache() {