From 96c02392797c8062abd1759d3ceea751a3bb9459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:06:19 +0100 Subject: [PATCH 01/30] Backport WP_Theme_JSON_Resolver from core as it is --- lib/class-wp-theme-json-resolver.php | 687 +++++++++++++++++++++++++++ 1 file changed, 687 insertions(+) create mode 100644 lib/class-wp-theme-json-resolver.php diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php new file mode 100644 index 00000000000000..b1f15897b1af56 --- /dev/null +++ b/lib/class-wp-theme-json-resolver.php @@ -0,0 +1,687 @@ + array(), + 'blocks' => array(), + 'theme' => array(), + 'user' => array(), + ); + + /** + * Container for data coming from core. + * + * @since 5.8.0 + * @var WP_Theme_JSON + */ + 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. + * + * @since 5.8.0 + * @var WP_Theme_JSON + */ + protected static $theme = null; + + /** + * Whether or not the theme supports theme.json. + * + * @since 5.8.0 + * @var bool + */ + protected static $theme_has_support = null; + + /** + * Container for data coming from the user. + * + * @since 5.9.0 + * @var WP_Theme_JSON + */ + protected static $user = null; + + /** + * Stores the ID of the custom post type + * that holds the user data. + * + * @since 5.9.0 + * @var int + */ + protected static $user_custom_post_type_id = null; + + /** + * Container to keep loaded i18n schema for `theme.json`. + * + * @since 5.8.0 As `$theme_json_i18n`. + * @since 5.9.0 Renamed from `$theme_json_i18n` to `$i18n_schema`. + * @var array + */ + protected static $i18n_schema = null; + + /** + * `theme.json` file cache. + * + * @since 6.1.0 + * @var array + */ + protected static $theme_json_file_cache = array(); + + /** + * Processes a file that adheres to the theme.json schema + * and returns an array with its contents, or a void array if none found. + * + * @since 5.8.0 + * @since 6.1.0 Added caching. + * + * @param string $file_path Path to file. Empty if no file. + * @return array Contents that adhere to the theme.json schema. + */ + protected static function read_json_file( $file_path ) { + if ( $file_path ) { + if ( array_key_exists( $file_path, static::$theme_json_file_cache ) ) { + return static::$theme_json_file_cache[ $file_path ]; + } + + $decoded_file = wp_json_file_decode( $file_path, array( 'associative' => true ) ); + if ( is_array( $decoded_file ) ) { + static::$theme_json_file_cache[ $file_path ] = $decoded_file; + return static::$theme_json_file_cache[ $file_path ]; + } + } + + return array(); + } + + /** + * Returns a data structure used in theme.json translation. + * + * @since 5.8.0 + * @deprecated 5.9.0 + * + * @return array An array of theme.json fields that are translatable and the keys that are translatable. + */ + public static function get_fields_to_translate() { + _deprecated_function( __METHOD__, '5.9.0' ); + return array(); + } + + /** + * Given a theme.json structure modifies it in place to update certain values + * by its translated strings according to the language set by the user. + * + * @since 5.8.0 + * + * @param array $theme_json The theme.json to translate. + * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. + * Default 'default'. + * @return array Returns the modified $theme_json_structure. + */ + protected static function translate( $theme_json, $domain = 'default' ) { + if ( null === static::$i18n_schema ) { + $i18n_schema = wp_json_file_decode( __DIR__ . '/theme-i18n.json' ); + static::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema; + } + + return translate_settings_using_i18n_schema( static::$i18n_schema, $theme_json, $domain ); + } + + /** + * Returns core's origin config. + * + * @since 5.8.0 + * + * @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 ); + + /** + * Filters the default data provided by WordPress for global styles & settings. + * + * @since 6.1.0 + * + * @param WP_Theme_JSON_Data Class to access and update the underlying data. + */ + $theme_json = apply_filters( 'wp_theme_json_data_default', new WP_Theme_JSON_Data( $config, 'default' ) ); + $config = $theme_json->get_data(); + static::$core = new WP_Theme_JSON( $config, 'default' ); + + 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. + * + * Data from theme.json will be backfilled from existing + * theme supports, if any. Note that if the same data + * is present in theme.json and in theme supports, + * the theme.json takes precedence. + * + * @since 5.8.0 + * @since 5.9.0 Theme supports have been inlined and the `$theme_support_data` argument removed. + * @since 6.0.0 Added an `$options` parameter to allow the theme data to be returned without theme supports. + * + * @param array $deprecated Deprecated. Not used. + * @param array $options { + * Options arguments. + * + * @type bool $with_supports Whether to include theme supports in the data. Default true. + * } + * @return WP_Theme_JSON Entity that holds theme data. + */ + public static function get_theme_data( $deprecated = array(), $options = array() ) { + if ( ! empty( $deprecated ) ) { + _deprecated_argument( __METHOD__, '5.9.0' ); + } + + $options = wp_parse_args( $options, array( 'with_supports' => true ) ); + + if ( null === static::$theme || ! static::has_same_registered_blocks( 'theme' ) ) { + $theme_json_file = static::get_file_path_from_theme( 'theme.json' ); + $wp_theme = wp_get_theme(); + if ( '' !== $theme_json_file ) { + $theme_json_data = static::read_json_file( $theme_json_file ); + $theme_json_data = static::translate( $theme_json_data, $wp_theme->get( 'TextDomain' ) ); + } else { + $theme_json_data = array(); + } + + /** + * 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( 'wp_theme_json_data_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_theme->parent() ) { + // Get parent theme.json. + $parent_theme_json_file = static::get_file_path_from_theme( 'theme.json', true ); + if ( '' !== $parent_theme_json_file ) { + $parent_theme_json_data = static::read_json_file( $parent_theme_json_file ); + $parent_theme_json_data = static::translate( $parent_theme_json_data, $wp_theme->parent()->get( 'TextDomain' ) ); + $parent_theme = new WP_Theme_JSON( $parent_theme_json_data ); + + /* + * Merge the child theme.json into the parent theme.json. + * The child theme takes precedence over the parent. + */ + $parent_theme->merge( static::$theme ); + static::$theme = $parent_theme; + } + } + } + + if ( ! $options['with_supports'] ) { + return static::$theme; + } + + /* + * 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_default_block_editor_settings() ); + if ( ! static::theme_has_support() ) { + if ( ! isset( $theme_support_data['settings']['color'] ) ) { + $theme_support_data['settings']['color'] = array(); + } + + $default_palette = false; + if ( current_theme_supports( 'default-color-palette' ) ) { + $default_palette = true; + } + if ( ! isset( $theme_support_data['settings']['color']['palette'] ) ) { + // If the theme does not have any palette, we still want to show the core one. + $default_palette = true; + } + $theme_support_data['settings']['color']['defaultPalette'] = $default_palette; + + $default_gradients = false; + if ( current_theme_supports( 'default-gradient-presets' ) ) { + $default_gradients = true; + } + if ( ! isset( $theme_support_data['settings']['color']['gradients'] ) ) { + // If the theme does not have any gradients, we still want to show the core ones. + $default_gradients = true; + } + $theme_support_data['settings']['color']['defaultGradients'] = $default_gradients; + + // Classic themes without a theme.json don't support global duotone. + $theme_support_data['settings']['color']['defaultDuotone'] = false; + } + $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); + $with_theme_supports->merge( static::$theme ); + return $with_theme_supports; + } + + /** + * Gets the styles for blocks from the block.json file. + * + * @since 6.1.0 + * + * @return WP_Theme_JSON + */ + 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 ); + 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'] ); + } + + if ( + isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ) && + null === _wp_array_get( $config, array( 'styles', 'blocks', $block_name, 'spacing', 'blockGap' ), null ) + ) { + // Ensure an empty placeholder value exists for the block, if it provides a default blockGap value. + // The real blockGap value to be used will be determined when the styles are rendered for output. + $config['styles']['blocks'][ $block_name ]['spacing']['blockGap'] = null; + } + } + + /** + * Filters the data provided by the blocks for global styles & settings. + * + * @since 6.1.0 + * + * @param WP_Theme_JSON_Data Class to access and update the underlying data. + */ + $theme_json = apply_filters( 'wp_theme_json_data_blocks', new WP_Theme_JSON_Data( $config, 'blocks' ) ); + $config = $theme_json->get_data(); + + static::$blocks = new WP_Theme_JSON( $config, 'blocks' ); + return static::$blocks; + } + + /** + * When given an array, this will remove any keys with the name `//`. + * + * @param array $array The array to filter. + * @return array The filtered array. + */ + private static function remove_json_comments( $array ) { + unset( $array['//'] ); + foreach ( $array as $k => $v ) { + if ( is_array( $v ) ) { + $array[ $k ] = static::remove_json_comments( $v ); + } + } + + return $array; + } + + /** + * Returns the custom post type that contains the user's origin config + * for the active theme or a void array if none are found. + * + * This can also create and return a new draft custom post type. + * + * @since 5.9.0 + * + * @param WP_Theme $theme The theme object. If empty, it + * defaults to the active theme. + * @param bool $create_post Optional. Whether a new custom post + * type should be created if none are + * found. Default false. + * @param array $post_status_filter Optional. Filter custom post type by + * post status. Default `array( 'publish' )`, + * so it only fetches published posts. + * @return array Custom Post Type for the user's origin config. + */ + public static function get_user_data_from_wp_global_styles( $theme, $create_post = false, $post_status_filter = array( 'publish' ) ) { + if ( ! $theme instanceof WP_Theme ) { + $theme = wp_get_theme(); + } + + /* + * Bail early if the theme does not support a theme.json. + * + * Since WP_Theme_JSON_Resolver::theme_has_support() only supports the active + * theme, the extra condition for whether $theme is the active theme is + * present here. + */ + if ( $theme->get_stylesheet() === get_stylesheet() && ! static::theme_has_support() ) { + return array(); + } + + $user_cpt = array(); + $post_type_filter = 'wp_global_styles'; + $stylesheet = $theme->get_stylesheet(); + $args = array( + 'posts_per_page' => 1, + 'orderby' => 'date', + 'order' => 'desc', + 'post_type' => $post_type_filter, + 'post_status' => $post_status_filter, + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + 'tax_query' => array( + array( + 'taxonomy' => 'wp_theme', + 'field' => 'name', + 'terms' => $stylesheet, + ), + ), + ); + + $global_style_query = new WP_Query(); + $recent_posts = $global_style_query->query( $args ); + if ( count( $recent_posts ) === 1 ) { + $user_cpt = get_post( $recent_posts[0], ARRAY_A ); + } elseif ( $create_post ) { + $cpt_post_id = wp_insert_post( + array( + 'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', + 'post_status' => 'publish', + 'post_title' => 'Custom Styles', // Do not make string translatable, see https://core.trac.wordpress.org/ticket/54518. + 'post_type' => $post_type_filter, + 'post_name' => sprintf( 'wp-global-styles-%s', urlencode( $stylesheet ) ), + 'tax_input' => array( + 'wp_theme' => array( $stylesheet ), + ), + ), + true + ); + if ( ! is_wp_error( $cpt_post_id ) ) { + $user_cpt = get_post( $cpt_post_id, ARRAY_A ); + } + } + + return $user_cpt; + } + + /** + * Returns the user's origin config. + * + * @since 5.9.0 + * + * @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() ); + + if ( array_key_exists( 'post_content', $user_cpt ) ) { + $decoded_data = json_decode( $user_cpt['post_content'], true ); + + $json_decoding_error = json_last_error(); + if ( JSON_ERROR_NONE !== $json_decoding_error ) { + trigger_error( 'Error when decoding a theme.json schema for user data. ' . json_last_error_msg() ); + /** + * Filters the data provided by the user for global styles & settings. + * + * @since 6.1.0 + * + * @param WP_Theme_JSON_Data Class to access and update the underlying data. + */ + $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); + $config = $theme_json->get_data(); + return new WP_Theme_JSON( $config, 'custom' ); + } + + // Very important to verify that the flag isGlobalStylesUserThemeJSON is true. + // If it's not true then the content was not escaped and is not safe. + if ( + is_array( $decoded_data ) && + isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) && + $decoded_data['isGlobalStylesUserThemeJSON'] + ) { + unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); + $config = $decoded_data; + } + } + + /** This filter is documented in wp-includes/class-wp-theme-json-resolver.php */ + $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); + $config = $theme_json->get_data(); + static::$user = new WP_Theme_JSON( $config, 'custom' ); + + return static::$user; + } + + /** + * Returns the data merged from multiple origins. + * + * There are three sources of data (origins) for a site: + * default, theme, and custom. The custom's has higher priority + * than the theme's, and the theme's higher than default's. + * + * Unlike the getters + * {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_core_data/ get_core_data}, + * {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_theme_data/ get_theme_data}, + * and {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_user_data/ get_user_data}, + * this method returns data after it has been merged with the previous origins. + * This means that if the same piece of data is declared in different origins + * (user, theme, and core), the last origin overrides the previous. + * + * For example, if the user has set a background color + * for the paragraph block, and the theme has done it as well, + * the user preference wins. + * + * @since 5.8.0 + * @since 5.9.0 Added user data, removed the `$settings` parameter, + * added the `$origin` parameter. + * @since 6.1.0 Added block data and generation of spacingSizes array. + * + * @param string $origin Optional. To what level should we merge data. + * Valid values are 'theme' or 'custom'. Default 'custom'. + * @return WP_Theme_JSON + */ + public static function get_merged_data( $origin = 'custom' ) { + if ( is_array( $origin ) ) { + _deprecated_argument( __FUNCTION__, '5.9.0' ); + } + + $result = static::get_core_data(); + $result->merge( static::get_block_data() ); + $result->merge( static::get_theme_data() ); + + if ( 'custom' === $origin ) { + $result->merge( static::get_user_data() ); + } + + // Generate the default spacingSizes array based on the merged spacingScale settings. + $result->set_spacing_sizes(); + + return $result; + } + + /** + * Returns the ID of the custom post type + * that stores user data. + * + * @since 5.9.0 + * + * @return integer|null + */ + public static function get_user_global_styles_post_id() { + if ( null !== static::$user_custom_post_type_id ) { + return static::$user_custom_post_type_id; + } + + $user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme(), true ); + + if ( array_key_exists( 'ID', $user_cpt ) ) { + static::$user_custom_post_type_id = $user_cpt['ID']; + } + + return static::$user_custom_post_type_id; + } + + /** + * Determines whether the active theme has a theme.json file. + * + * @since 5.8.0 + * @since 5.9.0 Added a check in the parent theme. + * + * @return bool + */ + public static function theme_has_support() { + if ( ! isset( static::$theme_has_support ) ) { + static::$theme_has_support = ( + static::get_file_path_from_theme( 'theme.json' ) !== '' || + static::get_file_path_from_theme( 'theme.json', true ) !== '' + ); + } + + return static::$theme_has_support; + } + + /** + * Builds the path to the given file and checks that it is readable. + * + * If it isn't, returns an empty string, otherwise returns the whole file path. + * + * @since 5.8.0 + * @since 5.9.0 Adapted to work with child themes, added the `$template` argument. + * + * @param string $file_name Name of the file. + * @param bool $template Optional. Use template theme directory. Default false. + * @return string The whole file path or empty if the file doesn't exist. + */ + protected static function get_file_path_from_theme( $file_name, $template = false ) { + $path = $template ? get_template_directory() : get_stylesheet_directory(); + $candidate = $path . '/' . $file_name; + + return is_readable( $candidate ) ? $candidate : ''; + } + + /** + * Cleans the cached data so it can be recalculated. + * + * @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; + static::$theme_has_support = null; + static::$i18n_schema = null; + } + + /** + * Returns the style variations defined by the theme. + * + * @since 6.0.0 + * + * @return array + */ + public static function get_style_variations() { + $variations = array(); + $base_directory = get_stylesheet_directory() . '/styles'; + if ( is_dir( $base_directory ) ) { + $nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) ); + $nested_html_files = iterator_to_array( new RegexIterator( $nested_files, '/^.+\.json$/i', RecursiveRegexIterator::GET_MATCH ) ); + ksort( $nested_html_files ); + foreach ( $nested_html_files as $path => $file ) { + $decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) ); + if ( is_array( $decoded_file ) ) { + $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) ); + $variation = ( new WP_Theme_JSON( $translated ) )->get_raw_data(); + if ( empty( $variation['title'] ) ) { + $variation['title'] = basename( $path, '.json' ); + } + $variations[] = $variation; + } + } + } + return $variations; + } + +} From 13185e2a58976be3e440ea01a0d755a2daefdf13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:11:53 +0100 Subject: [PATCH 02/30] Substitute WP_Theme_JSON by WP_Theme_JSON_Gutenberg --- lib/class-wp-theme-json-resolver.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index b1f15897b1af56..f519cbaa1ef690 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -182,7 +182,7 @@ public static function get_core_data() { */ $theme_json = apply_filters( 'wp_theme_json_data_default', new WP_Theme_JSON_Data( $config, 'default' ) ); $config = $theme_json->get_data(); - static::$core = new WP_Theme_JSON( $config, 'default' ); + static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' ); return static::$core; } @@ -264,7 +264,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() */ $theme_json = apply_filters( 'wp_theme_json_data_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 ); + static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); if ( $wp_theme->parent() ) { // Get parent theme.json. @@ -272,7 +272,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() if ( '' !== $parent_theme_json_file ) { $parent_theme_json_data = static::read_json_file( $parent_theme_json_file ); $parent_theme_json_data = static::translate( $parent_theme_json_data, $wp_theme->parent()->get( 'TextDomain' ) ); - $parent_theme = new WP_Theme_JSON( $parent_theme_json_data ); + $parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); /* * Merge the child theme.json into the parent theme.json. @@ -294,7 +294,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() * 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_default_block_editor_settings() ); + $theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( get_default_block_editor_settings() ); if ( ! static::theme_has_support() ) { if ( ! isset( $theme_support_data['settings']['color'] ) ) { $theme_support_data['settings']['color'] = array(); @@ -323,7 +323,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() // Classic themes without a theme.json don't support global duotone. $theme_support_data['settings']['color']['defaultDuotone'] = false; } - $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); + $with_theme_supports = new WP_Theme_JSON_Gutenberg( $theme_support_data ); $with_theme_supports->merge( static::$theme ); return $with_theme_supports; } @@ -369,7 +369,7 @@ public static function get_block_data() { $theme_json = apply_filters( 'wp_theme_json_data_blocks', new WP_Theme_JSON_Data( $config, 'blocks' ) ); $config = $theme_json->get_data(); - static::$blocks = new WP_Theme_JSON( $config, 'blocks' ); + static::$blocks = new WP_Theme_JSON_Gutenberg( $config, 'blocks' ); return static::$blocks; } @@ -451,7 +451,7 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post } elseif ( $create_post ) { $cpt_post_id = wp_insert_post( array( - 'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', + 'post_content' => '{"version": ' . WP_Theme_JSON_Gutenberg::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', 'post_status' => 'publish', 'post_title' => 'Custom Styles', // Do not make string translatable, see https://core.trac.wordpress.org/ticket/54518. 'post_type' => $post_type_filter, @@ -500,7 +500,7 @@ public static function get_user_data() { */ $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); $config = $theme_json->get_data(); - return new WP_Theme_JSON( $config, 'custom' ); + return new WP_Theme_JSON_Gutenberg( $config, 'custom' ); } // Very important to verify that the flag isGlobalStylesUserThemeJSON is true. @@ -518,7 +518,7 @@ public static function get_user_data() { /** This filter is documented in wp-includes/class-wp-theme-json-resolver.php */ $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); $config = $theme_json->get_data(); - static::$user = new WP_Theme_JSON( $config, 'custom' ); + static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); return static::$user; } @@ -673,7 +673,7 @@ public static function get_style_variations() { $decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) ); if ( is_array( $decoded_file ) ) { $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) ); - $variation = ( new WP_Theme_JSON( $translated ) )->get_raw_data(); + $variation = ( new WP_Theme_JSON_Gutenberg( $translated ) )->get_raw_data(); if ( empty( $variation['title'] ) ) { $variation['title'] = basename( $path, '.json' ); } From 1f5ad2dd897aab3524a413d5f79a141a3eb267fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:18:49 +0100 Subject: [PATCH 03/30] Substitute WP_Theme_JSON_Data by WP_Theme_JSON_Data_Gutenberg --- lib/class-wp-theme-json-resolver.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index f519cbaa1ef690..f44fabe2ddac6c 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -180,7 +180,7 @@ public static function get_core_data() { * * @param WP_Theme_JSON_Data Class to access and update the underlying data. */ - $theme_json = apply_filters( 'wp_theme_json_data_default', new WP_Theme_JSON_Data( $config, 'default' ) ); + $theme_json = apply_filters( 'wp_theme_json_data_default', new WP_Theme_JSON_Data_Gutenberg( $config, 'default' ) ); $config = $theme_json->get_data(); static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' ); @@ -262,7 +262,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() * * @param WP_Theme_JSON_Data Class to access and update the underlying data. */ - $theme_json = apply_filters( 'wp_theme_json_data_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) ); + $theme_json = apply_filters( 'wp_theme_json_data_theme', new WP_Theme_JSON_Data_Gutenberg( $theme_json_data, 'theme' ) ); $theme_json_data = $theme_json->get_data(); static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); @@ -366,7 +366,7 @@ public static function get_block_data() { * * @param WP_Theme_JSON_Data Class to access and update the underlying data. */ - $theme_json = apply_filters( 'wp_theme_json_data_blocks', new WP_Theme_JSON_Data( $config, 'blocks' ) ); + $theme_json = apply_filters( 'wp_theme_json_data_blocks', new WP_Theme_JSON_Data_Gutenberg( $config, 'blocks' ) ); $config = $theme_json->get_data(); static::$blocks = new WP_Theme_JSON_Gutenberg( $config, 'blocks' ); @@ -498,7 +498,7 @@ public static function get_user_data() { * * @param WP_Theme_JSON_Data Class to access and update the underlying data. */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); + $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); $config = $theme_json->get_data(); return new WP_Theme_JSON_Gutenberg( $config, 'custom' ); } @@ -516,7 +516,7 @@ public static function get_user_data() { } /** This filter is documented in wp-includes/class-wp-theme-json-resolver.php */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); + $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); $config = $theme_json->get_data(); static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); From fa996f4e9791c01db282dcdc3ce2a21bca47d02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:23:18 +0100 Subject: [PATCH 04/30] Rename WP_Theme_JSON_Resolver to WP_Theme_JSON_Resolver_Base The goal is to use it as base to inherit from, until we are able to remove all the children. --- lib/class-wp-theme-json-resolver.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index f44fabe2ddac6c..d1b8cb376ec67a 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -2,8 +2,7 @@ /** * WP_Theme_JSON_Resolver class * - * @package WordPress - * @subpackage Theme + * @package gutenberg * @since 5.8.0 */ @@ -18,7 +17,7 @@ * @access private */ #[AllowDynamicProperties] -class WP_Theme_JSON_Resolver { +class WP_Theme_JSON_Resolver_Base { /** * Container for keep track of registered blocks. From a6e00ceff93284cf618329690aaf24c2c0f59626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:26:52 +0100 Subject: [PATCH 05/30] Make WP_Theme_JSON_Resolver_6_1 inherit from WP_Theme_JSON_Resolver_Base --- lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php | 2 +- lib/load.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index 1d4a83e3406fbe..2efed1540f47b7 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -15,7 +15,7 @@ * * @access private */ -class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver { +class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_Base { /** * Container for data coming from core. diff --git a/lib/load.php b/lib/load.php index 4f2a9b42790b10..9c3bbbebfa297e 100644 --- a/lib/load.php +++ b/lib/load.php @@ -111,6 +111,7 @@ function gutenberg_is_experiment_enabled( $name ) { // Plugin specific code. require __DIR__ . '/class-wp-theme-json-gutenberg.php'; +require __DIR__ . '/class-wp-theme-json-resolver.php'; require __DIR__ . '/blocks.php'; require __DIR__ . '/client-assets.php'; require __DIR__ . '/demo.php'; From bd03602b4f10f68ff9ef828d42cbf3024a15999a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:33:09 +0100 Subject: [PATCH 06/30] 6.1: remove field already defined in base class --- .../wordpress-6.1/class-wp-theme-json-resolver-6-1.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index 2efed1540f47b7..d44df5196458a3 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -17,14 +17,6 @@ */ class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_Base { - /** - * Container for data coming from core. - * - * @since 5.8.0 - * @var WP_Theme_JSON - */ - protected static $core = null; - /** * Given a theme.json structure modifies it in place * to update certain values by its translated strings From 3d13fa9947320c223de9e6b9ce55dae446059ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:34:30 +0100 Subject: [PATCH 07/30] 6.1: remove translate, it is equal to base method --- .../class-wp-theme-json-resolver-6-1.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index d44df5196458a3..628bb8a46808a6 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -17,25 +17,6 @@ */ class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_Base { - /** - * Given a theme.json structure modifies it in place - * to update certain values by its translated strings - * according to the language set by the user. - * - * @param array $theme_json The theme.json to translate. - * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. - * Default 'default'. - * @return array Returns the modified $theme_json_structure. - */ - protected static function translate( $theme_json, $domain = 'default' ) { - if ( null === static::$i18n_schema ) { - $i18n_schema = wp_json_file_decode( __DIR__ . '/theme-i18n.json' ); - static::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema; - } - - return translate_settings_using_i18n_schema( static::$i18n_schema, $theme_json, $domain ); - } - /** * Return core's origin config. * From e2d54a4e12a1226822940c8fac5465a837277244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:35:28 +0100 Subject: [PATCH 08/30] 6.1: remove get_core_data, it does not have base changes --- .../class-wp-theme-json-resolver-6-1.php | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index 628bb8a46808a6..151e5b6a8d46fb 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -17,30 +17,6 @@ */ class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_Base { - /** - * Return core's origin config. - * - * @return WP_Theme_JSON_Gutenberg Entity that holds core data. - */ - public static function get_core_data() { - if ( null !== static::$core ) { - return static::$core; - } - - $config = static::read_json_file( __DIR__ . '/theme.json' ); - $config = static::translate( $config ); - /** - * Filters the default data provided by WordPress for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_default', new WP_Theme_JSON_Data_Gutenberg( $config, 'default' ) ); - $config = $theme_json->get_data(); - static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' ); - - return static::$core; - } - /** * Returns the user's origin config. * From 1f0ca1d3a54c2d95df7dd4b1c7ab45835a9496be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:36:27 +0100 Subject: [PATCH 09/30] 6.1: remove get_user_data Missed core changes and does not do anything differently from core. --- .../class-wp-theme-json-resolver-6-1.php | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index 151e5b6a8d46fb..47dc993e6e4df1 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -17,59 +17,6 @@ */ class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_Base { - /** - * Returns the user's origin config. - * - * @return WP_Theme_JSON_Gutenberg Entity that holds styles for user data. - */ - public static function get_user_data() { - if ( null !== static::$user ) { - return static::$user; - } - - $config = array(); - $user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme() ); - - if ( array_key_exists( 'post_content', $user_cpt ) ) { - $decoded_data = json_decode( $user_cpt['post_content'], true ); - - $json_decoding_error = json_last_error(); - if ( JSON_ERROR_NONE !== $json_decoding_error ) { - trigger_error( 'Error when decoding a theme.json schema for user data. ' . json_last_error_msg() ); - /** - * Filters the data provided by the user for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); - $config = $theme_json->get_data(); - return new WP_Theme_JSON_Gutenberg( $config, 'custom' ); - } - - // Very important to verify if the flag isGlobalStylesUserThemeJSON is true. - // If is not true the content was not escaped and is not safe. - if ( - is_array( $decoded_data ) && - isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) && - $decoded_data['isGlobalStylesUserThemeJSON'] - ) { - unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); - $config = $decoded_data; - } - } - - /** - * Filters the data provided by the user for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); - $config = $theme_json->get_data(); - static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); - - return static::$user; - } - /** * Returns the custom post type that contains the user's origin config * for the active theme or a void array if none are found. From 7f48e7debbf6b74c16b970638354133b29eef0e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:37:51 +0100 Subject: [PATCH 10/30] 6.1: remove get_user_data_from_wp_global_styles It misses core changes and does not do anything differently. --- .../class-wp-theme-json-resolver-6-1.php | 67 ------------------- 1 file changed, 67 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php index 47dc993e6e4df1..a8925679feb52d 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php @@ -17,71 +17,4 @@ */ class WP_Theme_JSON_Resolver_6_1 extends WP_Theme_JSON_Resolver_Base { - /** - * Returns the custom post type that contains the user's origin config - * for the active theme or a void array if none are found. - * - * This can also create and return a new draft custom post type. - * - * @since 5.9.0 - * - * @param WP_Theme $theme The theme object. If empty, it - * defaults to the active theme. - * @param bool $create_post Optional. Whether a new custom post - * type should be created if none are - * found. Default false. - * @param array $post_status_filter Optional. Filter custom post type by - * post status. Default `array( 'publish' )`, - * so it only fetches published posts. - * @return array Custom Post Type for the user's origin config. - */ - public static function get_user_data_from_wp_global_styles( $theme, $create_post = false, $post_status_filter = array( 'publish' ) ) { - if ( ! $theme instanceof WP_Theme ) { - $theme = wp_get_theme(); - } - $user_cpt = array(); - $post_type_filter = 'wp_global_styles'; - $stylesheet = $theme->get_stylesheet(); - $args = array( - 'posts_per_page' => 1, - 'orderby' => 'date', - 'order' => 'desc', - 'post_type' => $post_type_filter, - 'post_status' => $post_status_filter, - 'ignore_sticky_posts' => true, - 'no_found_rows' => true, - 'tax_query' => array( - array( - 'taxonomy' => 'wp_theme', - 'field' => 'name', - 'terms' => $stylesheet, - ), - ), - ); - - $global_style_query = new WP_Query(); - $recent_posts = $global_style_query->query( $args ); - if ( count( $recent_posts ) === 1 ) { - $user_cpt = get_post( $recent_posts[0], ARRAY_A ); - } elseif ( $create_post ) { - $cpt_post_id = wp_insert_post( - array( - 'post_content' => '{"version": ' . WP_Theme_JSON_Gutenberg::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', - 'post_status' => 'publish', - 'post_title' => 'Custom Styles', // Do not make string translatable, see https://core.trac.wordpress.org/ticket/54518. - 'post_type' => $post_type_filter, - 'post_name' => sprintf( 'wp-global-styles-%s', urlencode( $stylesheet ) ), - 'tax_input' => array( - 'wp_theme' => array( $stylesheet ), - ), - ), - true - ); - if ( ! is_wp_error( $cpt_post_id ) ) { - $user_cpt = get_post( $cpt_post_id, ARRAY_A ); - } - } - - return $user_cpt; - } } From 6858a77927388c8d0e84d3df2397fc39f6c20a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:39:46 +0100 Subject: [PATCH 11/30] 6.2: inherit from WP_Theme_JSON_Resolver_Base instead of 6.1 This makes the WP_Theme_JSON_Resover_6_1 class unused. --- lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php index 110c8bac7b147c..fa85d34c520730 100644 --- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php +++ b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php @@ -15,7 +15,7 @@ * * @access private */ -class WP_Theme_JSON_Resolver_6_2 extends WP_Theme_JSON_Resolver_6_1 { +class WP_Theme_JSON_Resolver_6_2 extends WP_Theme_JSON_Resolver_Base { /** * Returns the custom post type that contains the user's origin config From 811fc7da34c406646bebd28a37427c8af2c79ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 14:40:30 +0100 Subject: [PATCH 12/30] 6.1: remove class no longer in use --- .../class-wp-theme-json-resolver-6-1.php | 20 ------------------- lib/load.php | 1 - 2 files changed, 21 deletions(-) delete mode 100644 lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php deleted file mode 100644 index a8925679feb52d..00000000000000 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php +++ /dev/null @@ -1,20 +0,0 @@ - Date: Thu, 22 Dec 2022 15:16:15 +0100 Subject: [PATCH 13/30] 6.2: deprecate theme_has_support https://github.com/WordPress/gutenberg/pull/45380/ --- lib/class-wp-theme-json-resolver.php | 19 +++---------------- .../class-wp-theme-json-resolver-6-2.php | 15 --------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index d1b8cb376ec67a..e622e937846e81 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -56,14 +56,6 @@ class WP_Theme_JSON_Resolver_Base { */ protected static $theme = null; - /** - * Whether or not the theme supports theme.json. - * - * @since 5.8.0 - * @var bool - */ - protected static $theme_has_support = null; - /** * Container for data coming from the user. * @@ -596,18 +588,14 @@ public static function get_user_global_styles_post_id() { * * @since 5.8.0 * @since 5.9.0 Added a check in the parent theme. + * @deprecated 6.2.0 Use wp_theme_has_theme_json() instead. * * @return bool */ public static function theme_has_support() { - if ( ! isset( static::$theme_has_support ) ) { - static::$theme_has_support = ( - static::get_file_path_from_theme( 'theme.json' ) !== '' || - static::get_file_path_from_theme( 'theme.json', true ) !== '' - ); - } + _deprecated_function( __METHOD__, '6.2.0', 'wp_theme_has_theme_json()' ); - return static::$theme_has_support; + return wp_theme_has_theme_json(); } /** @@ -650,7 +638,6 @@ public static function clean_cached_data() { static::$theme = null; static::$user = null; static::$user_custom_post_type_id = null; - static::$theme_has_support = null; static::$i18n_schema = null; } diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php index fa85d34c520730..d25d6df090c069 100644 --- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php +++ b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php @@ -97,21 +97,6 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post return $user_cpt; } - /** - * Determines whether the active theme has a theme.json file. - * - * @since 5.8.0 - * @since 5.9.0 Added a check in the parent theme. - * @deprecated 6.2.0 Use wp_theme_has_theme_json() instead. - * - * @return bool - */ - public static function theme_has_support() { - _deprecated_function( __METHOD__, '6.2.0', 'wp_theme_has_theme_json()' ); - - return wp_theme_has_theme_json(); - } - /** * Returns the data merged from multiple origins. * From fc639bc31d4972f5870de8144e46c5ec47b3ffeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:20:58 +0100 Subject: [PATCH 14/30] 6.2: substitute WP_Theme_JSON_Resolver::theme_has_support by wp_theme_has_theme_json() https://github.com/WordPress/gutenberg/pull/45168 --- lib/class-wp-theme-json-resolver.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index e622e937846e81..9f258fe6a0e0ea 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -286,7 +286,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() * and merge the static::$theme upon that. */ $theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( get_default_block_editor_settings() ); - if ( ! static::theme_has_support() ) { + if ( ! wp_theme_has_theme_json() ) { if ( ! isset( $theme_support_data['settings']['color'] ) ) { $theme_support_data['settings']['color'] = array(); } @@ -407,11 +407,11 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post /* * Bail early if the theme does not support a theme.json. * - * Since WP_Theme_JSON_Resolver::theme_has_support() only supports the active + * Since wp_theme_has_theme_json() only supports the active * theme, the extra condition for whether $theme is the active theme is * present here. */ - if ( $theme->get_stylesheet() === get_stylesheet() && ! static::theme_has_support() ) { + if ( $theme->get_stylesheet() === get_stylesheet() && ! wp_theme_has_theme_json() ) { return array(); } From fe374938677f004aa8082af4afb9997dd7ab15ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:24:44 +0100 Subject: [PATCH 15/30] 6.2: port changes to get_user_data_from_wp_global_styles https://github.com/WordPress/gutenberg/pull/46043/ --- lib/class-wp-theme-json-resolver.php | 24 +++--- .../class-wp-theme-json-resolver-6-2.php | 80 ------------------- 2 files changed, 13 insertions(+), 91 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 9f258fe6a0e0ea..1d5d9cc1380b2e 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -407,7 +407,7 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post /* * Bail early if the theme does not support a theme.json. * - * Since wp_theme_has_theme_json() only supports the active + * Since wp_theme_has_theme_json only supports the active * theme, the extra condition for whether $theme is the active theme is * present here. */ @@ -419,14 +419,16 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post $post_type_filter = 'wp_global_styles'; $stylesheet = $theme->get_stylesheet(); $args = array( - 'posts_per_page' => 1, - 'orderby' => 'date', - 'order' => 'desc', - 'post_type' => $post_type_filter, - 'post_status' => $post_status_filter, - 'ignore_sticky_posts' => true, - 'no_found_rows' => true, - 'tax_query' => array( + 'posts_per_page' => 1, + 'orderby' => 'date', + 'order' => 'desc', + 'post_type' => $post_type_filter, + 'post_status' => $post_status_filter, + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'tax_query' => array( array( 'taxonomy' => 'wp_theme', 'field' => 'name', @@ -438,7 +440,7 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post $global_style_query = new WP_Query(); $recent_posts = $global_style_query->query( $args ); if ( count( $recent_posts ) === 1 ) { - $user_cpt = get_post( $recent_posts[0], ARRAY_A ); + $user_cpt = get_object_vars( $recent_posts[0] ); } elseif ( $create_post ) { $cpt_post_id = wp_insert_post( array( @@ -454,7 +456,7 @@ public static function get_user_data_from_wp_global_styles( $theme, $create_post true ); if ( ! is_wp_error( $cpt_post_id ) ) { - $user_cpt = get_post( $cpt_post_id, ARRAY_A ); + $user_cpt = get_object_vars( get_post( $cpt_post_id ) ); } } diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php index d25d6df090c069..22707be2f994f4 100644 --- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php +++ b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php @@ -17,86 +17,6 @@ */ class WP_Theme_JSON_Resolver_6_2 extends WP_Theme_JSON_Resolver_Base { - /** - * Returns the custom post type that contains the user's origin config - * for the active theme or a void array if none are found. - * - * This can also create and return a new draft custom post type. - * - * @param WP_Theme $theme The theme object. If empty, it - * defaults to the active theme. - * @param bool $create_post Optional. Whether a new custom post - * type should be created if none are - * found. Default false. - * @param array $post_status_filter Optional. Filter custom post type by - * post status. Default `array( 'publish' )`, - * so it only fetches published posts. - * @return array Custom Post Type for the user's origin config. - */ - public static function get_user_data_from_wp_global_styles( $theme, $create_post = false, $post_status_filter = array( 'publish' ) ) { - if ( ! $theme instanceof WP_Theme ) { - $theme = wp_get_theme(); - } - - /* - * Bail early if the theme does not support a theme.json. - * - * Since wp_theme_has_theme_json only supports the active - * theme, the extra condition for whether $theme is the active theme is - * present here. - */ - if ( $theme->get_stylesheet() === get_stylesheet() && ! wp_theme_has_theme_json() ) { - return array(); - } - - $user_cpt = array(); - $post_type_filter = 'wp_global_styles'; - $stylesheet = $theme->get_stylesheet(); - $args = array( - 'posts_per_page' => 1, - 'orderby' => 'date', - 'order' => 'desc', - 'post_type' => $post_type_filter, - 'post_status' => $post_status_filter, - 'ignore_sticky_posts' => true, - 'no_found_rows' => true, - 'update_post_meta_cache' => false, - 'update_post_term_cache' => false, - 'tax_query' => array( - array( - 'taxonomy' => 'wp_theme', - 'field' => 'name', - 'terms' => $stylesheet, - ), - ), - ); - - $global_style_query = new WP_Query(); - $recent_posts = $global_style_query->query( $args ); - if ( count( $recent_posts ) === 1 ) { - $user_cpt = get_object_vars( $recent_posts[0] ); - } elseif ( $create_post ) { - $cpt_post_id = wp_insert_post( - array( - 'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', - 'post_status' => 'publish', - 'post_title' => 'Custom Styles', // Do not make string translatable, see https://core.trac.wordpress.org/ticket/54518. - 'post_type' => $post_type_filter, - 'post_name' => sprintf( 'wp-global-styles-%s', urlencode( $stylesheet ) ), - 'tax_input' => array( - 'wp_theme' => array( $stylesheet ), - ), - ), - true - ); - if ( ! is_wp_error( $cpt_post_id ) ) { - $user_cpt = get_object_vars( get_post( $cpt_post_id ) ); - } - } - - return $user_cpt; - } - /** * Returns the data merged from multiple origins. * From a5bdc7686d45b301c44cd287381726215fcbcc3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:29:13 +0100 Subject: [PATCH 16/30] 6.2: update get_merged_data https://github.com/WordPress/gutenberg/pull/45969/ --- lib/class-wp-theme-json-resolver.php | 37 ++++++++---- .../class-wp-theme-json-resolver-6-2.php | 57 ------------------- 2 files changed, 26 insertions(+), 68 deletions(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 1d5d9cc1380b2e..e1a22cf3ea489d 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -519,9 +519,15 @@ public static function get_user_data() { /** * Returns the data merged from multiple origins. * - * There are three sources of data (origins) for a site: - * default, theme, and custom. The custom's has higher priority - * than the theme's, and the theme's higher than default's. + * There are four sources of data (origins) for a site: + * + * - default => WordPress + * - blocks => each one of the blocks provides data for itself + * - theme => the active theme + * - custom => data provided by the user + * + * The custom's has higher priority than the theme's, the theme's higher than blocks', + * and block's higher than default's. * * Unlike the getters * {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_core_data/ get_core_data}, @@ -529,7 +535,7 @@ public static function get_user_data() { * and {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_user_data/ get_user_data}, * this method returns data after it has been merged with the previous origins. * This means that if the same piece of data is declared in different origins - * (user, theme, and core), the last origin overrides the previous. + * (default, blocks, theme, custom), the last origin overrides the previous. * * For example, if the user has set a background color * for the paragraph block, and the theme has done it as well, @@ -540,8 +546,9 @@ public static function get_user_data() { * added the `$origin` parameter. * @since 6.1.0 Added block data and generation of spacingSizes array. * - * @param string $origin Optional. To what level should we merge data. - * Valid values are 'theme' or 'custom'. Default 'custom'. + * @param string $origin Optional. To what level should we merge data:'default', 'blocks', 'theme' or 'custom'. + * 'custom' is used as default value as well as fallback value if the origin is unknown. + * * @return WP_Theme_JSON */ public static function get_merged_data( $origin = 'custom' ) { @@ -550,16 +557,24 @@ public static function get_merged_data( $origin = 'custom' ) { } $result = static::get_core_data(); + if ( 'default' === $origin ) { + $result->set_spacing_sizes(); + return $result; + } + $result->merge( static::get_block_data() ); - $result->merge( static::get_theme_data() ); + if ( 'blocks' === $origin ) { + return $result; + } - if ( 'custom' === $origin ) { - $result->merge( static::get_user_data() ); + $result->merge( static::get_theme_data() ); + if ( 'theme' === $origin ) { + $result->set_spacing_sizes(); + return $result; } - // Generate the default spacingSizes array based on the merged spacingScale settings. + $result->merge( static::get_user_data() ); $result->set_spacing_sizes(); - return $result; } diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php index 22707be2f994f4..a66983dfad9b0c 100644 --- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php +++ b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php @@ -17,63 +17,6 @@ */ class WP_Theme_JSON_Resolver_6_2 extends WP_Theme_JSON_Resolver_Base { - /** - * Returns the data merged from multiple origins. - * - * There are four sources of data (origins) for a site: - * - * - default => WordPress - * - blocks => each one of the blocks provides data for itself - * - theme => the active theme - * - custom => data provided by the user - * - * The custom's has higher priority than the theme's, the theme's higher than blocks', - * and block's higher than default's. - * - * Unlike the getters - * {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_core_data/ get_core_data}, - * {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_theme_data/ get_theme_data}, - * and {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_user_data/ get_user_data}, - * this method returns data after it has been merged with the previous origins. - * This means that if the same piece of data is declared in different origins - * (default, blocks, theme, custom), the last origin overrides the previous. - * - * For example, if the user has set a background color - * for the paragraph block, and the theme has done it as well, - * the user preference wins. - * - * @param string $origin Optional. To what level should we merge data:'default', 'blocks', 'theme' or 'custom'. - * 'custom' is used as default value as well as fallback value if the origin is unknown. - * - * @return WP_Theme_JSON - */ - public static function get_merged_data( $origin = 'custom' ) { - if ( is_array( $origin ) ) { - _deprecated_argument( __FUNCTION__, '5.9.0' ); - } - - $result = static::get_core_data(); - if ( 'default' === $origin ) { - $result->set_spacing_sizes(); - return $result; - } - - $result->merge( static::get_block_data() ); - if ( 'blocks' === $origin ) { - return $result; - } - - $result->merge( static::get_theme_data() ); - if ( 'theme' === $origin ) { - $result->set_spacing_sizes(); - return $result; - } - - $result->merge( static::get_user_data() ); - $result->set_spacing_sizes(); - return $result; - } - /** * Returns the user's origin config. * From 897c35502c5d15c5479b9a733112d59af4dc834a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 15:33:03 +0100 Subject: [PATCH 17/30] 6.2: remove get_user_data Same code as core. There's a check for detecting whether the class is an instance of WP_Theme_JSON_Gutenberg that was not ported. This check was introduced to make sure the cache of the core class didn't interfere with the cache of the Gutenberg class, so it's no longer necessary. See https://github.com/WordPress/gutenberg/pull/42756 --- .../class-wp-theme-json-resolver-6-2.php | 58 ------------------- 1 file changed, 58 deletions(-) diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php index a66983dfad9b0c..60aca8e7c75256 100644 --- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php +++ b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php @@ -17,62 +17,4 @@ */ class WP_Theme_JSON_Resolver_6_2 extends WP_Theme_JSON_Resolver_Base { - /** - * Returns the user's origin config. - * - * @since 6.2 Added check for the WP_Theme_JSON_Gutenberg class to prevent $user - * values set in core fron overriding the new custom css values added to VALID_STYLES. - * This does not need to be backported to core as the new VALID_STYLES[css] value will - * be added to core with 6.2. - * - * @return WP_Theme_JSON_Gutenberg Entity that holds styles for user data. - */ - public static function get_user_data() { - if ( null !== static::$user && static::$user instanceof WP_Theme_JSON_Gutenberg ) { - return static::$user; - } - - $config = array(); - $user_cpt = static::get_user_data_from_wp_global_styles( wp_get_theme() ); - - if ( array_key_exists( 'post_content', $user_cpt ) ) { - $decoded_data = json_decode( $user_cpt['post_content'], true ); - - $json_decoding_error = json_last_error(); - if ( JSON_ERROR_NONE !== $json_decoding_error ) { - trigger_error( 'Error when decoding a theme.json schema for user data. ' . json_last_error_msg() ); - /** - * Filters the data provided by the user for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); - $config = $theme_json->get_data(); - return new WP_Theme_JSON_Gutenberg( $config, 'custom' ); - } - - // Very important to verify if the flag isGlobalStylesUserThemeJSON is true. - // If is not true the content was not escaped and is not safe. - if ( - is_array( $decoded_data ) && - isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) && - $decoded_data['isGlobalStylesUserThemeJSON'] - ) { - unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); - $config = $decoded_data; - } - } - - /** - * Filters the data provided by the user for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_user', new WP_Theme_JSON_Data_Gutenberg( $config, 'custom' ) ); - $config = $theme_json->get_data(); - - static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); - - return static::$user; - } } From edf3fb0a3699cd99705c190451c1253e3a3de3e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:50:18 +0100 Subject: [PATCH 18/30] experimental: make it inherit from WP_Theme_JSON_Resolver_Base --- lib/experimental/class-wp-theme-json-resolver-gutenberg.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 566f6c4e4501e6..599871988c04e2 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -15,7 +15,7 @@ * * @access private */ -class WP_Theme_JSON_Resolver_Gutenberg extends WP_Theme_JSON_Resolver_6_2 { +class WP_Theme_JSON_Resolver_Gutenberg extends WP_Theme_JSON_Resolver_Base { /** * Returns the theme's data. * From afb4aa0ec833bd3607d7e54bbae96f6d4bfca90f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:51:03 +0100 Subject: [PATCH 19/30] 6.2: remove class no longer in use --- .../class-wp-theme-json-resolver-6-2.php | 20 ------------------- lib/load.php | 1 - 2 files changed, 21 deletions(-) delete mode 100644 lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php diff --git a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php b/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php deleted file mode 100644 index 60aca8e7c75256..00000000000000 --- a/lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php +++ /dev/null @@ -1,20 +0,0 @@ - Date: Thu, 22 Dec 2022 16:52:59 +0100 Subject: [PATCH 20/30] experimental: delete remove_json_comments It's already part of the base class. --- .../class-wp-theme-json-resolver-gutenberg.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 599871988c04e2..59d1d640663b22 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -157,21 +157,4 @@ public static function get_block_data() { return new WP_Theme_JSON_Gutenberg( $config, 'blocks' ); } - /** - * When given an array, this will remove any keys with the name `//`. - * - * @param array $array The array to filter. - * @return array The filtered array. - */ - private static function remove_JSON_comments( $array ) { - unset( $array['//'] ); - foreach ( $array as $k => $v ) { - if ( is_array( $v ) ) { - $array[ $k ] = static::remove_JSON_comments( $v ); - } - } - - return $array; - } - } From 6551ec88d0e63ba6b72d4b04df5dca2a226255b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:56:20 +0100 Subject: [PATCH 21/30] experimental: remove get_block_data It's already part of the base class and it didn't have the changes from core. --- ...class-wp-theme-json-resolver-gutenberg.php | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 59d1d640663b22..e53b43659d0b49 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -122,39 +122,4 @@ public static function get_theme_data( $deprecated = array(), $settings = array( return $with_theme_supports; } - /** - * Gets the styles for blocks from the block.json file. - * - * @return WP_Theme_JSON - */ - public static function get_block_data() { - $registry = WP_Block_Type_Registry::get_instance(); - $blocks = $registry->get_all_registered(); - $config = array( 'version' => 1 ); - 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'] ); - } - - if ( - isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ) && - null === _wp_array_get( $config, array( 'styles', 'blocks', $block_name, 'spacing', 'blockGap' ), null ) - ) { - // Ensure an empty placeholder value exists for the block, if it provides a default blockGap value. - // The real blockGap value to be used will be determined when the styles are rendered for output. - $config['styles']['blocks'][ $block_name ]['spacing']['blockGap'] = null; - } - } - - /** - * Filters the data provided by the blocks for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_blocks', new WP_Theme_JSON_Data_Gutenberg( $config, 'blocks' ) ); - $config = $theme_json->get_data(); - - return new WP_Theme_JSON_Gutenberg( $config, 'blocks' ); - } - } From 31e4b0088341ca0967af2022ac908dbe501c5616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:59:11 +0100 Subject: [PATCH 22/30] experimental: appearanceTools Port changes to the base class that were meant to be part of 6.1. See https://github.com/WordPress/gutenberg/pull/43337 --- lib/class-wp-theme-json-resolver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index e1a22cf3ea489d..d7638bfb5155d4 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -313,6 +313,11 @@ public static function get_theme_data( $deprecated = array(), $options = array() // Classic themes without a theme.json don't support global duotone. $theme_support_data['settings']['color']['defaultDuotone'] = false; + + // Allow themes to enable appearance tools via theme_support. + if ( current_theme_supports( 'appearance-tools' ) ) { + $theme_support_data['settings']['appearanceTools'] = true; + } } $with_theme_supports = new WP_Theme_JSON_Gutenberg( $theme_support_data ); $with_theme_supports->merge( static::$theme ); From 26bf59946ea220b2efaec5a136a331be4ff6bd4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:04:24 +0100 Subject: [PATCH 23/30] experimental: port webfonts (experimental API) see https://github.com/WordPress/gutenberg/pull/37140 --- lib/class-wp-theme-json-resolver.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index d7638bfb5155d4..581a792878c907 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -245,6 +245,9 @@ public static function get_theme_data( $deprecated = array(), $options = array() } else { $theme_json_data = array(); } + // BEGIN OF EXPERIMENTAL CODE. Not to backport to core. + $theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data ); + // END OF EXPERIMENTAL CODE. /** * Filters the data provided by the theme for global styles and settings. @@ -263,7 +266,10 @@ public static function get_theme_data( $deprecated = array(), $options = array() if ( '' !== $parent_theme_json_file ) { $parent_theme_json_data = static::read_json_file( $parent_theme_json_file ); $parent_theme_json_data = static::translate( $parent_theme_json_data, $wp_theme->parent()->get( 'TextDomain' ) ); - $parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); + // BEGIN OF EXPERIMENTAL CODE. Not to backport to core. + $parent_theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $parent_theme_json_data ); + // END OF EXPERIMENTAL CODE. + $parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); /* * Merge the child theme.json into the parent theme.json. From 78c51b351de4dfdb4bf4eef67d89f5fe8b91b116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:13:32 +0100 Subject: [PATCH 24/30] experimental: use gutenberg_get_legacy_theme_supports_for_theme_json https://github.com/WordPress/gutenberg/pull/46112 --- lib/class-wp-theme-json-resolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 581a792878c907..be442a01b09e79 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -291,7 +291,7 @@ public static function get_theme_data( $deprecated = array(), $options = array() * So we take theme supports, transform it to theme.json shape * and merge the static::$theme upon that. */ - $theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( get_default_block_editor_settings() ); + $theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( gutenberg_get_legacy_theme_supports_for_theme_json() ); if ( ! wp_theme_has_theme_json() ) { if ( ! isset( $theme_support_data['settings']['color'] ) ) { $theme_support_data['settings']['color'] = array(); From f18b7b873db8ba549ab36e9eb9b5e9953617f055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:15:09 +0100 Subject: [PATCH 25/30] experimental: get_theme_data, all code is in the base class --- ...class-wp-theme-json-resolver-gutenberg.php | 106 ------------------ 1 file changed, 106 deletions(-) diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index e53b43659d0b49..cca0cacf85dc4b 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -16,110 +16,4 @@ * @access private */ class WP_Theme_JSON_Resolver_Gutenberg extends WP_Theme_JSON_Resolver_Base { - /** - * Returns the theme's data. - * - * Data from theme.json will be backfilled from existing - * theme supports, if any. Note that if the same data - * is present in theme.json and in theme supports, - * the theme.json takes precedence. - * - * @param array $deprecated Deprecated argument. - * @param array $settings Contains a key called with_supports to determine whether to include theme supports in the data. - * @return WP_Theme_JSON_Gutenberg Entity that holds theme data. - */ - public static function get_theme_data( $deprecated = array(), $settings = array( 'with_supports' => true ) ) { - if ( ! empty( $deprecated ) ) { - _deprecated_argument( __METHOD__, '5.9' ); - } - - // When backporting to core, remove the instanceof Gutenberg class check, as it is only required for the Gutenberg plugin. - if ( null === static::$theme || ! static::has_same_registered_blocks( 'theme' ) ) { - $theme_json_file = static::get_file_path_from_theme( 'theme.json' ); - $wp_theme = wp_get_theme(); - if ( '' !== $theme_json_file ) { - $theme_json_data = static::read_json_file( $theme_json_file ); - $theme_json_data = static::translate( $theme_json_data, $wp_theme->get( 'TextDomain' ) ); - } else { - $theme_json_data = array(); - } - $theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data ); - - /** - * Filters the data provided by the theme for global styles & settings. - * - * @param WP_Theme_JSON_Data_Gutenberg Class to access and update the underlying data. - */ - $theme_json = apply_filters( 'wp_theme_json_data_theme', new WP_Theme_JSON_Data_Gutenberg( $theme_json_data, 'theme' ) ); - $theme_json_data = $theme_json->get_data(); - static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); - - if ( $wp_theme->parent() ) { - // Get parent theme.json. - $parent_theme_json_file = static::get_file_path_from_theme( 'theme.json', true ); - if ( '' !== $parent_theme_json_file ) { - $parent_theme_json_data = static::read_json_file( $parent_theme_json_file ); - $parent_theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $parent_theme_json_data ); - $parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); - - /* - * Merge the child theme.json into the parent theme.json. - * The child theme takes precedence over the parent. - */ - $parent_theme->merge( static::$theme ); - static::$theme = $parent_theme; - } - } - } - - if ( ! $settings['with_supports'] ) { - return static::$theme; - } - - /* - * 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_Gutenberg::get_from_editor_settings( gutenberg_get_legacy_theme_supports_for_theme_json() ); - if ( ! wp_theme_has_theme_json() ) { - if ( ! isset( $theme_support_data['settings']['color'] ) ) { - $theme_support_data['settings']['color'] = array(); - } - - $default_palette = false; - if ( current_theme_supports( 'default-color-palette' ) ) { - $default_palette = true; - } - if ( ! isset( $theme_support_data['settings']['color']['palette'] ) ) { - // If the theme does not have any palette, we still want to show the core one. - $default_palette = true; - } - $theme_support_data['settings']['color']['defaultPalette'] = $default_palette; - - $default_gradients = false; - if ( current_theme_supports( 'default-gradient-presets' ) ) { - $default_gradients = true; - } - if ( ! isset( $theme_support_data['settings']['color']['gradients'] ) ) { - // If the theme does not have any gradients, we still want to show the core ones. - $default_gradients = true; - } - $theme_support_data['settings']['color']['defaultGradients'] = $default_gradients; - - // Classic themes without a theme.json don't support global duotone. - $theme_support_data['settings']['color']['defaultDuotone'] = false; - - // Allow themes to enable appearance tools via theme_support. - if ( current_theme_supports( 'appearance-tools' ) ) { - $theme_support_data['settings']['appearanceTools'] = true; - } - } - $with_theme_supports = new WP_Theme_JSON_Gutenberg( $theme_support_data ); - $with_theme_supports->merge( static::$theme ); - - return $with_theme_supports; - } - } From 9335dbcb8a6b4abfeeae994170bc6490c72ea547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:16:10 +0100 Subject: [PATCH 26/30] experimental: remove empty class --- ...class-wp-theme-json-resolver-gutenberg.php | 19 ------------------- lib/load.php | 1 - 2 files changed, 20 deletions(-) delete mode 100644 lib/experimental/class-wp-theme-json-resolver-gutenberg.php diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php deleted file mode 100644 index cca0cacf85dc4b..00000000000000 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ /dev/null @@ -1,19 +0,0 @@ - Date: Thu, 22 Dec 2022 17:17:15 +0100 Subject: [PATCH 27/30] Rename WP_Theme_JSON_Resolver_Base to WP_Theme_JSON_Resolver_Gutenberg --- lib/class-wp-theme-json-resolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index be442a01b09e79..05d8b56e49727b 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -17,7 +17,7 @@ * @access private */ #[AllowDynamicProperties] -class WP_Theme_JSON_Resolver_Base { +class WP_Theme_JSON_Resolver_Gutenberg { /** * Container for keep track of registered blocks. From 1b16af4beaacd5bd2a094ba06a160a1f8a2d372c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:20:27 +0100 Subject: [PATCH 28/30] Fix lint issue: rename class-wp-theme-json-resolver.php to class-wp-theme-json-resolver-gutenberg.php --- ...-resolver.php => class-wp-theme-json-resolver-gutenberg.php} | 0 lib/load.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/{class-wp-theme-json-resolver.php => class-wp-theme-json-resolver-gutenberg.php} (100%) diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver-gutenberg.php similarity index 100% rename from lib/class-wp-theme-json-resolver.php rename to lib/class-wp-theme-json-resolver-gutenberg.php diff --git a/lib/load.php b/lib/load.php index 3608064c432b89..1b296053965319 100644 --- a/lib/load.php +++ b/lib/load.php @@ -108,7 +108,7 @@ function gutenberg_is_experiment_enabled( $name ) { // Plugin specific code. require __DIR__ . '/class-wp-theme-json-gutenberg.php'; -require __DIR__ . '/class-wp-theme-json-resolver.php'; +require __DIR__ . '/class-wp-theme-json-resolver-gutenberg.php'; require __DIR__ . '/blocks.php'; require __DIR__ . '/client-assets.php'; require __DIR__ . '/demo.php'; From 9938731634bfae2319e6f8c63d9621bd709585e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:53:43 +0100 Subject: [PATCH 29/30] Move theme.json to unversioned lib/ --- lib/{compat/wordpress-6.1 => }/theme.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{compat/wordpress-6.1 => }/theme.json (100%) diff --git a/lib/compat/wordpress-6.1/theme.json b/lib/theme.json similarity index 100% rename from lib/compat/wordpress-6.1/theme.json rename to lib/theme.json From 703ccafd23d8e459860958d345af335b0f641d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:54:16 +0100 Subject: [PATCH 30/30] Move theme-i18n.json to unversioned lib/ --- lib/{compat/wordpress-6.1 => }/theme-i18n.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{compat/wordpress-6.1 => }/theme-i18n.json (100%) diff --git a/lib/compat/wordpress-6.1/theme-i18n.json b/lib/theme-i18n.json similarity index 100% rename from lib/compat/wordpress-6.1/theme-i18n.json rename to lib/theme-i18n.json