-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
theme.json: theme_has_support() might cache wrong value #30478
Comments
The most straight-forward remedy is to add a cache key -- the theme slug comes to mind: diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php
index 6815dc68ec..e312fe8b38 100644
--- a/lib/class-wp-theme-json-resolver.php
+++ b/lib/class-wp-theme-json-resolver.php
@@ -31,7 +31,7 @@ class WP_Theme_JSON_Resolver {
*
* @var boolean
*/
- private static $theme_has_support = null;
+ private static $theme_has_support = array();
/**
* Container for data coming from the user.
@@ -503,11 +503,12 @@ class WP_Theme_JSON_Resolver {
* @return boolean
*/
public static function theme_has_support() {
- if ( ! isset( self::$theme_has_support ) ) {
- self::$theme_has_support = (bool) self::get_file_path_from_theme( 'experimental-theme.json' );
+ $theme_slug = get_stylesheet();
+ if ( ! isset( self::$theme_has_support[ $theme_slug ] ) ) {
+ self::$theme_has_support[ $theme_slug ] = (bool) self::get_file_path_from_theme( 'experimental-theme.json' );
}
- return self::$theme_has_support;
+ return self::$theme_has_support[ $theme_slug ];
}
/**
diff --git a/lib/full-site-editing/block-templates.php b/lib/full-site-editing/block-templates.php
index d0bcab00c9..324570b30d 100644
--- a/lib/full-site-editing/block-templates.php
+++ b/lib/full-site-editing/block-templates.php
@@ -124,7 +124,7 @@ function _gutenberg_get_template_files( $template_type ) {
* @return array Template.
*/
function _gutenberg_add_template_part_area_info( $template_info ) {
- if ( WP_Theme_JSON_Resolver::theme_has_support() ) {
+ if ( WP_Theme_JSON_Resolver::theme_has_support( $template_info['slug'] ) ) {
$theme_data = WP_Theme_JSON_Resolver::get_theme_data()->get_template_parts();
}
I'll file a PR. |
Hi @ockham Sounds like a good approach to me. In efforts of improving things that are touched, I've got a related question; Is there a reason the cache property is not defined in the method itself? private static $theme_has_support = array(); vs public static function theme_has_support() {
static $theme_has_support = array();
...
} It would keep property close by, which shouldn't be used anywhere else, as you want the method to be the one source of truth. This paradigm is also used elsewhere in the file: https://github.com/WordPress/gutenberg/blob/trunk/lib/class-wp-theme-json-resolver.php#L145-L146 |
I left at #30045 (comment) another thread to look at, in case it's related to that issue.
How can I test this? I mean, in isolation, not by running this. I'd like to understand how to break this code before changing it. For testing, this is what I've done: hook into an action that runs before the theme is setup: Also, by looking at the code of |
Yeah, apologies for that -- I didn't see the relevant info being rendered anywhere else, so it was a bit hard to repro otherwise 😅 Here's a way to repro (albeit through running a unit test -- so there's potentially a chance that the unit test is flawed): Apply the following diff, and run diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php
index 31ecb553a2..8b2248a0cb 100644
--- a/lib/class-wp-theme-json-resolver.php
+++ b/lib/class-wp-theme-json-resolver.php
@@ -460,10 +460,12 @@ class WP_Theme_JSON_Resolver {
* @return boolean
*/
public static function theme_has_support() {
+ debug_print_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
+ echo get_stylesheet_directory() . "\n";
if ( ! isset( self::$theme_has_support ) ) {
self::$theme_has_support = (bool) self::get_file_path_from_theme( 'experimental-theme.json' );
}
-
+ echo "theme_has_support: " . self::$theme_has_support . "\n";
return self::$theme_has_support;
}
That gives me:
Yeah, so in the tests above, it seems to return the default theme (during tests setup?), sets that as the cache value for |
So judging from those call stacks, it seems the relevant callsites for gutenberg/lib/client-assets.php Line 364 in b6272d9
and gutenberg/lib/global-styles.php Line 163 in b6272d9
|
If I load WP in the browser with the above patch, both "early" callsites ( |
I tracked the stacktrace for those two back a bit further: It goes back to gutenberg/phpunit/bootstrap.php Line 84 in 2aefc5b
wordpress-develop : https://github.com/WordPress/wordpress-develop/blob/234c2b52ccf584cb93dce0eaf17431310b1d7458/tests/phpunit/includes/bootstrap.php
Edit: The latter file comes from |
This could be relevant? gutenberg/packages/env/lib/wordpress.js Lines 86 to 110 in 2aefc5b
|
I wonder if that means that the phpunit container isn't using the
cc/ @noahtallen Can you weigh in if that's the expected behavior? |
Ah no, that seems unrelated: |
Default theme fallback set here: https://github.com/wp-phpunit/wp-phpunit/blob/fefaaf8d086c0401d887661e21dc9e9afdfc0411/includes/bootstrap.php#L138-L145 |
Maybe this could help? https://github.com/wp-phpunit/wp-phpunit/blob/fefaaf8d086c0401d887661e21dc9e9afdfc0411/includes/bootstrap.php#L177-L188 I.e. using the gutenberg/phpunit/bootstrap.php Lines 73 to 78 in 3da717b
|
Yeah, so this seems to do the trick: diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php
index 8315c12292..1767a33748 100644
--- a/phpunit/bootstrap.php
+++ b/phpunit/bootstrap.php
@@ -75,6 +75,8 @@ $GLOBALS['wp_tests_options'] = array(
'gutenberg-widget-experiments' => '1',
'gutenberg-full-site-editing' => 1,
),
+ 'stylesheet' => 'tt1-blocks',
+ 'template' => 'tt1-blocks'
);
// Enable the widget block editor. However, that'd mean we'd hard-wire the theme (initially) used for testing to TT1 Blocks. I'm not totally sure that's okay, but I guess it is? |
PR: #30686 |
Updated the issue description to reflect the findings, and to provide better instructions for reproducing. |
It's definitely weird because we're using the phpunit library instead of the one from core. But it sounds like you figured it out. Related issue about improving phpunit: #23171 |
Thanks for the instructions, Bernie. If I understood this correctly, it looks like there's an issue when a theme is switched programatically but doesn't happen on a normal WordPress request. I understand this can be an issue beyond unit tests theoretically, although I'm not sure under what practical conditions. Anyway, it sounds like what we need to do is cleaning all the cached values upon a theme switch so they can be recalculated. Prepared #30830 |
Discovered here: #30045 (comment). See that PR for instructions on how to repro.
Since #28786 (and later #28788, which renamed and moved the relevant function), we've been caching the return value of
WP_Theme_JSON_Resolver::theme_has_support()
:gutenberg/lib/class-wp-theme-json-resolver.php
Lines 500 to 511 in ddccfab
This makes sense at first glance, since, as was stated in #28786:
This seems to work fine in a "normal" WordPress environment; however, it seems to pose a problem for unit tests:
WP_Theme_JSON_Resolver::theme_has_support()
is first called while the current theme is still set to the default theme -- which of course doesn't have anexperimental-theme.json
file -- so we're erroneously cachingfalse
as return value forWP_Theme_JSON_Resolver::theme_has_support()
.Even if an individual unit test later sets the current theme to one that has an
experimental-theme.json
,WP_Theme_JSON_Resolver::theme_has_support()
will continue to return the cachedfalse
value.Steps to reproduce
Check out
trunk
, and apply the following patch on top of it:Then, run
This should give something like
Output
Note that for the first two callsites of
theme_has_support
, which happen during bootstrapping --lib/client-assets.php:364
andlib/global-styles.php:163
-- the output forecho get_stylesheet_directory() . "\n";
isi.e., the default theme.
In later calls, it is
/var/www/html/wp-content/themes/tt1-blocks
; but in all cases, the return value oftheme_has_support()
isfalse
.cc/ @moorscode @nosolosw @Addison-Stavlo @david-szabo97 @WordPress/gutenberg-core
The text was updated successfully, but these errors were encountered: