Skip to content
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

Store merged data in memory #5024

Closed
80 changes: 77 additions & 3 deletions src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ class WP_Theme_JSON_Resolver {
*/
protected static $theme = null;

/**
* Container to cache theme support data.
*
* @since n.e.x.t
* @var array
*/
protected static $theme_support_data = null;

/**
* Container for data coming from the user.
*
Expand All @@ -65,6 +73,19 @@ class WP_Theme_JSON_Resolver {
*/
protected static $user = null;

/**
* Container for merged data.
*
* @since n.e.x.t
* @var WP_Theme_JSON
*/
protected static $merged = array(
'default' => null,
'blocks' => null,
'theme' => null,
'custom' => null,
);

/**
* Stores the ID of the custom post type
* that holds the user data.
Expand Down Expand Up @@ -280,13 +301,30 @@ public static function get_theme_data( $deprecated = array(), $options = array()
return static::$theme;
}

// Save theme supports data for future use.
static::$theme_support_data = self::get_theme_supports_data();

$with_theme_supports = new WP_Theme_JSON( static::$theme_support_data );
$with_theme_supports->merge( static::$theme );
return $with_theme_supports;
}

/**
* Get merged theme supports data
*
* @since n.e.x.t
*
* @return array Config that adheres to the theme.json schema.
*/
private static function get_theme_supports_data() {
/*
* We want the presets and settings declared in theme.json
* to override the ones declared via theme supports.
* So we take theme supports, transform it to theme.json shape
* and merge the static::$theme upon that.
*/
$theme_support_data = WP_Theme_JSON::get_from_editor_settings( get_classic_theme_supports_block_editor_settings() );

if ( ! wp_theme_has_theme_json() ) {
if ( ! isset( $theme_support_data['settings']['color'] ) ) {
$theme_support_data['settings']['color'] = array();
Expand Down Expand Up @@ -328,9 +366,8 @@ public static function get_theme_data( $deprecated = array(), $options = array()
$theme_support_data['settings']['border']['width'] = true;
}
}
$with_theme_supports = new WP_Theme_JSON( $theme_support_data );
$with_theme_supports->merge( static::$theme );
return $with_theme_supports;

return $theme_support_data;
}

/**
Expand Down Expand Up @@ -576,27 +613,58 @@ public static function get_merged_data( $origin = 'custom' ) {
_deprecated_argument( __FUNCTION__, '5.9.0' );
}

if ( ! in_array( $origin, WP_Theme_JSON::VALID_ORIGINS, true ) ) {
$origin = 'custom';
}

// Map origins to block cache values.
$cache_map = array(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the advantage of declaring this map over just using the origin?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see. The existing calls to has_same_registered_blocks do not use the origin. It's clear if they do, that'd be a little nice change before this PR (or as part of it).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. I did this because keys used to store the $blocks_cache values don't match the $origin values used by WP_Theme_JSON. If they did, then this mapping wouldn't be necessary. Not sure if we can make that update in a backwards compatible way, but it would be nice if these were stored using the same keys so it's obvious how one relates to the other.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's unfortunate that the names don't match, but I also think we shouldn't make a change to that at this point due to backward compatibility risk. If we want to update them, that should be in its own decoupled issue due to the additional considerations.

'default' => 'core',
'blocks' => 'blocks',
'theme' => 'theme',
'custom' => 'user',
);

if (
null !== static::$merged[ $origin ]
&& static::has_same_registered_blocks( $cache_map[ $origin ] )
// Ensure theme supports data is fresh before returning cached data for theme and custom origins.
&& ( ! in_array( $origin, array( 'theme', 'custom' ), true ) || static::get_theme_supports_data() === static::$theme_support_data )
) {
return static::$merged[ $origin ];
}

$result = new WP_Theme_JSON();
$result->merge( static::get_core_data() );
if ( 'default' === $origin ) {
$result->set_spacing_sizes();

static::$merged[ $origin ] = $result;

return $result;
}

$result->merge( static::get_block_data() );
if ( 'blocks' === $origin ) {
static::$merged[ $origin ] = $result;

return $result;
}

$result->merge( static::get_theme_data() );
if ( 'theme' === $origin ) {
$result->set_spacing_sizes();

static::$merged[ $origin ] = $result;

return $result;
}

$result->merge( static::get_user_data() );
$result->set_spacing_sizes();

static::$merged[ $origin ] = $result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are early returns above, so I think this needs to be added to all those clauses as well, otherwise only the custom origin will ever have cached values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually wonder if there's any value in storing anything other than the completed merged data. I'll raise that question as part of the PR to the Gutenberg repo, but this is good feedback!


return $result;
}

Expand Down Expand Up @@ -674,6 +742,12 @@ public static function clean_cached_data() {
'theme' => array(),
'user' => array(),
);
static::$merged = array(
'default' => null,
'blocks' => null,
'theme' => null,
'custom' => null,
);
static::$theme = null;
static::$user = null;
static::$user_custom_post_type_id = null;
Expand Down
Loading