From f0009b26dac39e7cd8be2685e6c212c3b52923dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 17 Nov 2022 04:11:34 -0700 Subject: [PATCH] Update `wp_theme_has_theme_json` to use `WP_Object_Cache` (#45543) Co-authored-by: Felix Arntz Co-authored-by: Miguel Torres Co-authored-by: Jonny Harris --- lib/compat/wordpress-6.2/default-filters.php | 11 +--- .../get-global-styles-and-settings.php | 66 ++++++++++++++----- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/lib/compat/wordpress-6.2/default-filters.php b/lib/compat/wordpress-6.2/default-filters.php index ac1ce19b425512..860cf9a8bf412a 100644 --- a/lib/compat/wordpress-6.2/default-filters.php +++ b/lib/compat/wordpress-6.2/default-filters.php @@ -17,11 +17,6 @@ * @package gutenberg */ -/** - * Note for backport: we should also remove the existing filters: - * - * > add_action( 'switch_theme', array( 'WP_Theme_JSON_Resolver', 'clean_cached_data' ) ); - * > add_action( 'start_previewing_theme', array( 'WP_Theme_JSON_Resolver', 'clean_cached_data' ) ); - */ -add_action( 'switch_theme', 'wp_theme_clean_theme_json_cached_data' ); -add_action( 'start_previewing_theme', 'wp_theme_clean_theme_json_cached_data' ); +add_action( 'switch_theme', 'wp_theme_has_theme_json_clean_cache' ); +add_action( 'start_previewing_theme', 'wp_theme_has_theme_json_clean_cache' ); +add_action( 'upgrader_process_complete', '_wp_theme_has_theme_json_clean_cache_upon_upgrading_active_theme' ); diff --git a/lib/compat/wordpress-6.2/get-global-styles-and-settings.php b/lib/compat/wordpress-6.2/get-global-styles-and-settings.php index 4dbd9d0ba8bde1..b2637969fd8ef6 100644 --- a/lib/compat/wordpress-6.2/get-global-styles-and-settings.php +++ b/lib/compat/wordpress-6.2/get-global-styles-and-settings.php @@ -9,39 +9,69 @@ /** * Whether a theme or its parent have a theme.json file. * - * @param boolean $clear_cache Whether the cache should be cleared and theme support recomputed. Default is false. + * The result would be cached via the WP_Object_Cache. + * It can be cleared by calling wp_theme_has_theme_json_clean_cache(). * * @return boolean */ - function wp_theme_has_theme_json( $clear_cache = false ) { - static $theme_has_support = null; + function wp_theme_has_theme_json() { + $cache_group = 'theme_json'; + $cache_key = 'wp_theme_has_theme_json'; + $theme_has_support = wp_cache_get( $cache_key, $cache_group ); - if ( true === $clear_cache ) { - $theme_has_support = null; - } - - if ( null !== $theme_has_support ) { - return $theme_has_support; + /** + * $theme_has_support is stored as a int in the cache. + * + * The reason not to store it as a boolean is to avoid working + * with the $found parameter which apparently had some issues in some implementations + * https://developer.wordpress.org/reference/functions/wp_cache_get/ + */ + if ( 0 === $theme_has_support || 1 === $theme_has_support ) { + return (bool) $theme_has_support; } // Has the own theme a theme.json? - $theme_has_support = is_readable( get_stylesheet_directory() . '/theme.json' ); + $theme_has_support = is_readable( get_stylesheet_directory() . '/theme.json' ) ? 1 : 0; // Look up the parent if the child does not have a theme.json. - if ( ! $theme_has_support ) { - $theme_has_support = is_readable( get_template_directory() . '/theme.json' ); + if ( 0 === $theme_has_support ) { + $theme_has_support = is_readable( get_template_directory() . '/theme.json' ) ? 1 : 0; } - return $theme_has_support; + wp_cache_set( $cache_key, $theme_has_support, $cache_group ); + + return (bool) $theme_has_support; + } +} + +if ( ! function_exists( 'wp_theme_has_theme_json_clean_cache' ) ) { + /** + * Function to clean the cache used by wp_theme_has_theme_json method. + */ + function wp_theme_has_theme_json_clean_cache() { + wp_cache_delete( 'wp_theme_has_theme_json', 'theme_json' ); } } -if ( ! function_exists( 'wp_theme_clean_theme_json_cached_data' ) ) { +if ( ! function_exists( '_wp_theme_has_theme_json_clean_cache_upon_upgrading_active_theme' ) ) { /** - * Clean theme.json related cached data. + * Private function to clean the cache used by wp_theme_has_theme_json method. + * + * It is hooked into the `upgrader_process_complete` action. + * + * @see default-filters.php + * + * @param WP_Upgrader $upgrader Instance of WP_Upgrader class. + * @param array $options Metadata that identifies the data that is updated. */ - function wp_theme_clean_theme_json_cached_data() { - wp_theme_has_theme_json( true ); - WP_Theme_JSON_Resolver_Gutenberg::clean_cached_data(); + function _wp_theme_has_theme_json_clean_cache_upon_upgrading_active_theme( $upgrader, $options ) { + // The cache only needs cleaning when the active theme was updated. + if ( + 'update' === $options['action'] && + 'theme' === $options['type'] && + ( isset( $options['themes'][ get_stylesheet() ] ) || isset( $options['themes'][ get_template() ] ) ) + ) { + wp_theme_has_theme_json_clean_cache(); + } } }