From 59ded0e074e3bd3ba9e1ed3f6013f2c51be0aefa Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Thu, 19 Jan 2023 08:10:14 +0100 Subject: [PATCH 1/2] Re-add caching to wp_theme_has_theme_json(), but only when not in a WP Admin request. --- .../global-styles-and-settings.php | 50 ++++++++++++++++++- src/wp-includes/load.php | 2 +- src/wp-includes/ms-blogs.php | 4 +- tests/phpunit/includes/abstract-testcase.php | 2 +- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/global-styles-and-settings.php b/src/wp-includes/global-styles-and-settings.php index c625166524b63..adc189ddaa033 100644 --- a/src/wp-includes/global-styles-and-settings.php +++ b/src/wp-includes/global-styles-and-settings.php @@ -264,6 +264,48 @@ function ( $item ) { * @return bool Returns true if theme or its parent has a theme.json file, false otherwise. */ function wp_theme_has_theme_json() { + /* + * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme + * developer's workflow. Also ignore it when in a WP Admin request, to prevent + * errors when used in the limited load-styles.php request. + * + * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. + */ + $can_use_cache = ! WP_DEBUG && ! is_admin(); + + if ( $can_use_cache ) { + /* + * By using the 'theme_json' group, this data is marked to be non-persistent across requests. + * @see `wp_cache_add_non_persistent_groups()`. + * + * The rationale for this is to make sure derived data from theme.json + * is always fresh from the potential modifications done via hooks + * that can use dynamic data (modify the stylesheet depending on some option, + * settings depending on user permissions, etc.). + * For some of the existing hooks to modify theme.json behavior: + * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ + * + * A different alternative considered was to invalidate the cache upon certain + * events such as options add/update/delete, user meta, etc. + * It was judged not enough, hence this approach. + * @see https://github.com/WordPress/gutenberg/pull/45372 + */ + $cache_group = 'theme_json'; + $cache_key = 'wp_theme_has_theme_json'; + $theme_has_support = wp_cache_get( $cache_key, $cache_group ); + + /* + * $theme_has_support is stored as an 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 + * @see https://developer.wordpress.org/reference/functions/wp_cache_get/ + */ + if ( is_int( $theme_has_support ) ) { + return (bool) $theme_has_support; + } + } + // Does the theme have its own theme.json? $theme_has_support = is_readable( get_stylesheet_directory() . '/theme.json' ); @@ -272,7 +314,12 @@ function wp_theme_has_theme_json() { $theme_has_support = is_readable( get_template_directory() . '/theme.json' ); } - return $theme_has_support; + if ( $can_use_cache ) { + $theme_has_support = $theme_has_support ? 1 : 0; + wp_cache_set( $cache_key, $theme_has_support, $cache_group ); + } + + return (bool) $theme_has_support; } /** @@ -281,5 +328,6 @@ function wp_theme_has_theme_json() { * @since 6.2.0 */ function wp_clean_theme_json_cache() { + wp_cache_delete( 'wp_theme_has_theme_json', 'theme_json' ); WP_Theme_JSON_Resolver::clean_cached_data(); } diff --git a/src/wp-includes/load.php b/src/wp-includes/load.php index 4c212086df34e..c2450e582f958 100644 --- a/src/wp-includes/load.php +++ b/src/wp-includes/load.php @@ -753,7 +753,7 @@ function wp_start_object_cache() { ) ); - wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); + wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } $first_init = false; diff --git a/src/wp-includes/ms-blogs.php b/src/wp-includes/ms-blogs.php index 0ea6f85627dcb..7ff830e930863 100644 --- a/src/wp-includes/ms-blogs.php +++ b/src/wp-includes/ms-blogs.php @@ -575,7 +575,7 @@ function switch_to_blog( $new_blog_id, $deprecated = null ) { ); } - wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); + wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } } @@ -666,7 +666,7 @@ function restore_current_blog() { ); } - wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); + wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } } diff --git a/tests/phpunit/includes/abstract-testcase.php b/tests/phpunit/includes/abstract-testcase.php index bae787a42dee3..fa048cdfa703a 100644 --- a/tests/phpunit/includes/abstract-testcase.php +++ b/tests/phpunit/includes/abstract-testcase.php @@ -401,7 +401,7 @@ public static function flush_cache() { ) ); - wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); + wp_cache_add_non_persistent_groups( array( 'counts', 'plugins', 'theme_json' ) ); } /** From d45b55bebdf1791c7e24d9617a43961ac895c409 Mon Sep 17 00:00:00 2001 From: hellofromtonya Date: Thu, 19 Jan 2023 05:24:27 -0600 Subject: [PATCH 2/2] Fix comment alignment --- .../global-styles-and-settings.php | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/wp-includes/global-styles-and-settings.php b/src/wp-includes/global-styles-and-settings.php index adc189ddaa033..167ae2be657d5 100644 --- a/src/wp-includes/global-styles-and-settings.php +++ b/src/wp-includes/global-styles-and-settings.php @@ -275,32 +275,32 @@ function wp_theme_has_theme_json() { if ( $can_use_cache ) { /* - * By using the 'theme_json' group, this data is marked to be non-persistent across requests. - * @see `wp_cache_add_non_persistent_groups()`. - * - * The rationale for this is to make sure derived data from theme.json - * is always fresh from the potential modifications done via hooks - * that can use dynamic data (modify the stylesheet depending on some option, - * settings depending on user permissions, etc.). - * For some of the existing hooks to modify theme.json behavior: - * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ - * - * A different alternative considered was to invalidate the cache upon certain - * events such as options add/update/delete, user meta, etc. - * It was judged not enough, hence this approach. - * @see https://github.com/WordPress/gutenberg/pull/45372 - */ + * By using the 'theme_json' group, this data is marked to be non-persistent across requests. + * @see `wp_cache_add_non_persistent_groups()`. + * + * The rationale for this is to make sure derived data from theme.json + * is always fresh from the potential modifications done via hooks + * that can use dynamic data (modify the stylesheet depending on some option, + * settings depending on user permissions, etc.). + * For some of the existing hooks to modify theme.json behavior: + * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ + * + * A different alternative considered was to invalidate the cache upon certain + * events such as options add/update/delete, user meta, etc. + * It was judged not enough, hence this approach. + * @see https://github.com/WordPress/gutenberg/pull/45372 + */ $cache_group = 'theme_json'; $cache_key = 'wp_theme_has_theme_json'; $theme_has_support = wp_cache_get( $cache_key, $cache_group ); /* - * $theme_has_support is stored as an 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 - * @see https://developer.wordpress.org/reference/functions/wp_cache_get/ - */ + * $theme_has_support is stored as an 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 + * @see https://developer.wordpress.org/reference/functions/wp_cache_get/ + */ if ( is_int( $theme_has_support ) ) { return (bool) $theme_has_support; }