Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 91 additions & 14 deletions src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
#[AllowDynamicProperties]
class WP_Theme_JSON_Resolver {

/**
* Container for keep track of registered blocks.
*
* @since 6.1.0
* @var array
*/
protected static $blocks_cache = array(
'core' => array(),
'blocks' => array(),
'theme' => array(),
'user' => array(),
);

/**
* Container for data coming from core.
*
Expand All @@ -28,6 +41,14 @@ class WP_Theme_JSON_Resolver {
*/
protected static $core = null;

/**
* Container for data coming from the blocks.
*
* @since 6.1.0
* @var WP_Theme_JSON
*/
protected static $blocks = null;

/**
* Container for data coming from the theme.
*
Expand Down Expand Up @@ -145,6 +166,10 @@ protected static function translate( $theme_json, $domain = 'default' ) {
* @return WP_Theme_JSON Entity that holds core data.
*/
public static function get_core_data() {
if ( null !== static::$core && static::has_same_registered_blocks( 'core' ) ) {
return static::$core;
}

$config = static::read_json_file( __DIR__ . '/theme.json' );
$config = static::translate( $config );

Expand All @@ -162,6 +187,37 @@ public static function get_core_data() {
return static::$core;
}

/**
* Checks whether the registered blocks were already processed for this origin.
*
* @since 6.1.0
*
* @param string $origin Data source for which to cache the blocks.
* Valid values are 'core', 'blocks', 'theme', and 'user'.
* @return bool True on success, false otherwise.
*/
protected static function has_same_registered_blocks( $origin ) {
// Bail out if the origin is invalid.
if ( ! isset( static::$blocks_cache[ $origin ] ) ) {
return false;
}

$registry = WP_Block_Type_Registry::get_instance();
$blocks = $registry->get_all_registered();

// Is there metadata for all currently registered blocks?
$block_diff = array_diff_key( $blocks, static::$blocks_cache[ $origin ] );
if ( empty( $block_diff ) ) {
return true;
}

foreach ( $blocks as $block_name => $block_type ) {
static::$blocks_cache[ $origin ][ $block_name ] = true;
}

return false;
}

/**
* Returns the theme's data.
*
Expand Down Expand Up @@ -189,19 +245,21 @@ public static function get_theme_data( $deprecated = array(), $options = array()

$options = wp_parse_args( $options, array( 'with_supports' => true ) );

$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 || ! static::has_same_registered_blocks( 'theme' ) ) {
Copy link
Member Author

@oandregal oandregal Oct 11, 2022

Choose a reason for hiding this comment

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

The only change here is running this code conditionally. The code within has not changed, it's only tabbed.

$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 and settings.
*
* @since 6.1.0
*
* @param WP_Theme_JSON_Data Class to access and update the underlying data.
*/
$theme_json = apply_filters( 'theme_json_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) );
$theme_json_data = $theme_json->get_data();
static::$theme = new WP_Theme_JSON( $theme_json_data );
/**
* Filters the data provided by the theme for global styles and settings.
*
* @since 6.1.0
*
* @param WP_Theme_JSON_Data Class to access and update the underlying data.
*/
$theme_json = apply_filters( 'theme_json_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) );
$theme_json_data = $theme_json->get_data();
static::$theme = new WP_Theme_JSON( $theme_json_data );
}

if ( wp_get_theme()->parent() ) {
// Get parent theme.json.
Expand Down Expand Up @@ -258,7 +316,6 @@ public static function get_theme_data( $deprecated = array(), $options = array()
}
$with_theme_supports = new WP_Theme_JSON( $theme_support_data );
$with_theme_supports->merge( static::$theme );

return $with_theme_supports;
}

Expand All @@ -272,7 +329,13 @@ public static function get_theme_data( $deprecated = array(), $options = array()
public static function get_block_data() {
$registry = WP_Block_Type_Registry::get_instance();
$blocks = $registry->get_all_registered();

if ( null !== static::$blocks && static::has_same_registered_blocks( 'blocks' ) ) {
return static::$blocks;
}

$config = array( 'version' => 2 );
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain this change?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bug I found while working in this PR. I can prepare a different PR if that's preferred but thought it was so minor it didn't merit one.

This sets the version of the theme.json schema used by the data stored in the blocks. We introduced version 2 in WordPress 5.9 and blocks only gained this functionality in this release, so we should be using the latest. In practice, because we're using the version 2 to store data in the blocks, probably we won't notice anything. Though this is still a dormant bug waiting to happen, and I rather do the right thing now. See docs.


foreach ( $blocks as $block_name => $block_type ) {
if ( isset( $block_type->supports['__experimentalStyle'] ) ) {
$config['styles']['blocks'][ $block_name ] = static::remove_json_comments( $block_type->supports['__experimentalStyle'] );
Expand All @@ -298,7 +361,8 @@ public static function get_block_data() {
$theme_json = apply_filters( 'theme_json_blocks', new WP_Theme_JSON_Data( $config, 'blocks' ) );
$config = $theme_json->get_data();

return new WP_Theme_JSON( $config, 'blocks' );
static::$blocks = new WP_Theme_JSON( $config, 'blocks' );
return static::$blocks;
}

/**
Expand Down Expand Up @@ -407,6 +471,10 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post
* @return WP_Theme_JSON Entity that holds styles for user data.
*/
public static function get_user_data() {
if ( null !== static::$user && static::has_same_registered_blocks( 'user' ) ) {
return static::$user;
}

$config = array();
$user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme() );

Expand Down Expand Up @@ -562,9 +630,18 @@ protected static function get_file_path_from_theme( $file_name, $template = fals
* @since 5.8.0
* @since 5.9.0 Added the `$user`, `$user_custom_post_type_id`,
* and `$i18n_schema` variables to reset.
* @since 6.1.0 Added the `$blocks` and `$blocks_cache` variables
* to reset.
*/
public static function clean_cached_data() {
static::$core = null;
static::$blocks = null;
static::$blocks_cache = array(
'core' => array(),
'blocks' => array(),
'theme' => array(),
'user' => array(),
);
static::$theme = null;
static::$user = null;
static::$user_custom_post_type_id = null;
Expand Down
Loading