diff --git a/lib/class-wp-theme-json-resolver.php b/lib/class-wp-theme-json-resolver.php index 7719dbf9ddf15d..15902895b1e1d7 100644 --- a/lib/class-wp-theme-json-resolver.php +++ b/lib/class-wp-theme-json-resolver.php @@ -205,7 +205,7 @@ private static function translate( $theme_json, $domain = 'default' ) { * * @return WP_Theme_JSON Entity that holds core data. */ - public static function get_core_data() { + private static function get_core_data() { if ( null !== self::$core ) { return self::$core; } @@ -310,6 +310,122 @@ public static function get_theme_data( $theme_support_data = array() ) { return $with_theme_supports; } + /** + * Returns the editor settings. + * + * @param array $theme_support_data Existing block editor settings. + * Empty array by default. + * + * @return array + */ + public static function get_settings( $theme_support_data = array() ) { + $tree = WP_Theme_JSON_Resolver::get_merged_data( $theme_support_data, 'theme' ); + return $tree->get( array( 'settings' ) ); + } + + /** + * Takes a tree adhering to the theme.json schema and generates + * the corresponding stylesheet. + * + * @param WP_Theme_JSON $tree Input tree. + * @param string $type Type of stylesheet we want accepts 'all', 'block_styles', and 'css_variables'. + * + * @return string Stylesheet. + */ + private static function tree_to_styles( $tree, $type = 'all' ) { + // Check if we can use cached. + $can_use_cached = ( + ( 'all' === $type ) && + ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) && + ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) && + ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) && + ! is_admin() + ); + + if ( $can_use_cached ) { + // Check if we have the styles already cached. + $cached = get_transient( 'global_styles' ); + if ( $cached ) { + return $cached; + } + } + + $stylesheet = $tree->get_stylesheet( $type ); + + if ( ( 'all' === $type || 'block_styles' === $type ) && WP_Theme_JSON_Resolver::theme_has_support() ) { + // To support all themes, we added in the block-library stylesheet + // a style rule such as .has-link-color a { color: var(--wp--style--color--link, #00e); } + // so that existing link colors themes used didn't break. + // We add this here to make it work for themes that opt-in to theme.json + // In the future, we may do this differently. + $stylesheet .= 'a{color:var(--wp--style--color--link, #00e);}'; + } + + if ( $can_use_cached ) { + // Cache for a minute. + // This cache doesn't need to be any longer, we only want to avoid spikes on high-traffic sites. + set_transient( 'global_styles', $stylesheet, MINUTE_IN_SECONDS ); + } + + return $stylesheet; + } + + /** + * Returs the stylesheet for global styles. + * + * @param array $theme_support_data Existing block editor settings. + * Empty array by default. + * @param string $type Type of stylesheet we want accepts 'all', 'block_styles', and 'css_variables'. + * + * @return string + */ + public static function get_stylesheet( $theme_support_data = array(), $type = 'all' ) { + $origin = 'theme'; + if ( + WP_Theme_JSON_Resolver::theme_has_support() && + gutenberg_is_fse_theme() + ) { + // Only lookup for the user data if we need it. + $origin = 'user'; + } + $tree = WP_Theme_JSON_Resolver::get_merged_data( $theme_support_data, $origin ); + return WP_Theme_JSON_Resolver::tree_to_styles( $tree, $type ); + } + + /** + * Returns the template part data of current theme. + * + * @return array + */ + public static function get_template_parts() { + return WP_Theme_JSON_Resolver::get_theme_data()->get( array( 'templateParts' ) ); + } + + /** + * Returns the page templates of the current theme. + * + * @return array + */ + public static function get_custom_templates() { + return WP_Theme_JSON_Resolver::get_theme_data()->get( array( 'customTemplates' ) ); + } + + /** + * Returns the settings & styles from the theme. + * + * @param array $theme_support_data Existing block editor settings. + * Empty array by default. + * + * @return array + */ + public static function get_theme_styles_and_settings( $theme_support_data = array() ) { + $raw_data = WP_Theme_JSON_Resolver::get_merged_data( $theme_support_data, 'theme' )->get(); + return array( + 'settings' => $raw_data['settings'], + 'styles' => $raw_data['styles'], + ); + } + /** * Returns the CPT that contains the user's origin config * for the current theme or a void array if none found. @@ -361,7 +477,7 @@ private static function get_user_data_from_custom_post_type( $should_create_cpt * * @return WP_Theme_JSON Entity that holds user data. */ - public static function get_user_data() { + private static function get_user_data() { if ( null !== self::$user ) { return self::$user; } @@ -417,7 +533,7 @@ public static function get_user_data() { * * @return WP_Theme_JSON */ - public static function get_merged_data( $theme_support_data = array(), $origin = 'user' ) { + private static function get_merged_data( $theme_support_data = array(), $origin = 'user' ) { if ( 'theme' === $origin ) { $result = new WP_Theme_JSON(); $result->merge( self::get_core_data() ); diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index d967e1681acf18..4d1407055d2871 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -1018,56 +1018,19 @@ private function get_block_styles() { } /** - * Returns the existing settings for each block. + * Helper to get the tree or any of its subtrees. * - * Example: - * - * { - * 'root': { - * 'color': { - * 'custom': true - * } - * }, - * 'core/paragraph': { - * 'spacing': { - * 'customPadding': true - * } - * } - * } - * - * @return array Settings per block. - */ - public function get_settings() { - if ( ! isset( $this->theme_json['settings'] ) ) { - return array(); - } else { - return $this->theme_json['settings']; - } - } - - /** - * Returns the page templates of the current theme. + * @param array $path Array of keys to get. If it's null, it'll return the whole theme.json. + * @param any $default The return value if the path does not exist within the array or if $path is not array. Default: empty array. * * @return array */ - public function get_custom_templates() { - if ( ! isset( $this->theme_json['customTemplates'] ) ) { - return array(); - } else { - return $this->theme_json['customTemplates']; + public function get( $path = null, $default = array() ) { + if ( null === $path ) { + return $this->theme_json; } - } - /** - * Returns the template part data of current theme. - * - * @return array - */ - public function get_template_parts() { - if ( ! isset( $this->theme_json['templateParts'] ) ) { - return array(); - } - return $this->theme_json['templateParts']; + return _wp_array_get( $this->theme_json, $path, $default ); } /** @@ -1094,7 +1057,7 @@ public function get_stylesheet( $type = 'all' ) { * @param WP_Theme_JSON $incoming Data to merge. */ public function merge( $incoming ) { - $incoming_data = $incoming->get_raw_data(); + $incoming_data = $incoming->get(); $this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data ); // The array_replace_recursive algorithm merges at the leaf level. @@ -1219,13 +1182,4 @@ public function remove_insecure_properties() { } } - /** - * Returns the raw data. - * - * @return array Raw data. - */ - public function get_raw_data() { - return $this->theme_json; - } - } diff --git a/lib/full-site-editing/block-templates.php b/lib/full-site-editing/block-templates.php index b1ee167d999619..bbc1131ffe8a27 100644 --- a/lib/full-site-editing/block-templates.php +++ b/lib/full-site-editing/block-templates.php @@ -125,7 +125,7 @@ function _gutenberg_get_template_files( $template_type ) { */ function _gutenberg_add_template_part_area_info( $template_info ) { if ( WP_Theme_JSON_Resolver::theme_has_support() ) { - $theme_data = WP_Theme_JSON_Resolver::get_theme_data()->get_template_parts(); + $theme_data = WP_Theme_JSON_Resolver::get_template_parts(); } if ( isset( $theme_data[ $template_info['slug'] ]['area'] ) ) { diff --git a/lib/full-site-editing/page-templates.php b/lib/full-site-editing/page-templates.php index 6c5a11c8a40e23..1153d8c983f49f 100644 --- a/lib/full-site-editing/page-templates.php +++ b/lib/full-site-editing/page-templates.php @@ -19,7 +19,7 @@ function gutenberg_load_block_page_templates( $templates, $theme, $post, $post_t return $templates; } - $data = WP_Theme_JSON_Resolver::get_theme_data()->get_custom_templates(); + $data = WP_Theme_JSON_Resolver::get_custom_templates(); $custom_templates = array(); if ( isset( $data ) ) { foreach ( $data as $key => $template ) { diff --git a/lib/global-styles.php b/lib/global-styles.php index 9a935de29145eb..feb5680ae1c769 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -106,53 +106,6 @@ function gutenberg_experimental_global_styles_get_theme_support_settings( $setti return $theme_settings; } -/** - * Takes a tree adhering to the theme.json schema and generates - * the corresponding stylesheet. - * - * @param WP_Theme_JSON $tree Input tree. - * @param string $type Type of stylesheet we want accepts 'all', 'block_styles', and 'css_variables'. - * - * @return string Stylesheet. - */ -function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = 'all' ) { - // Check if we can use cached. - $can_use_cached = ( - ( 'all' === $type ) && - ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) && - ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) && - ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) && - ! is_admin() - ); - - if ( $can_use_cached ) { - // Check if we have the styles already cached. - $cached = get_transient( 'global_styles' ); - if ( $cached ) { - return $cached; - } - } - - $stylesheet = $tree->get_stylesheet( $type ); - - if ( ( 'all' === $type || 'block_styles' === $type ) && WP_Theme_JSON_Resolver::theme_has_support() ) { - // To support all themes, we added in the block-library stylesheet - // a style rule such as .has-link-color a { color: var(--wp--style--color--link, #00e); } - // so that existing link colors themes used didn't break. - // We add this here to make it work for themes that opt-in to theme.json - // In the future, we may do this differently. - $stylesheet .= 'a{color:var(--wp--style--color--link, #00e);}'; - } - - if ( $can_use_cached ) { - // Cache for a minute. - // This cache doesn't need to be any longer, we only want to avoid spikes on high-traffic sites. - set_transient( 'global_styles', $stylesheet, MINUTE_IN_SECONDS ); - } - - return $stylesheet; -} - /** * Fetches the preferences for each origin (core, theme, user) * and enqueues the resulting stylesheet. @@ -164,10 +117,7 @@ function gutenberg_experimental_global_styles_enqueue_assets() { $settings = gutenberg_get_common_block_editor_settings(); $theme_support_data = gutenberg_experimental_global_styles_get_theme_support_settings( $settings ); - - $all = WP_Theme_JSON_Resolver::get_merged_data( $theme_support_data ); - - $stylesheet = gutenberg_experimental_global_styles_get_stylesheet( $all ); + $stylesheet = WP_Theme_JSON_Resolver::get_stylesheet( $theme_support_data ); if ( empty( $stylesheet ) ) { return; } @@ -195,23 +145,13 @@ function gutenberg_experimental_global_styles_settings( $settings ) { unset( $settings['fontSizes'] ); unset( $settings['gradients'] ); - $origin = 'theme'; - if ( - WP_Theme_JSON_Resolver::theme_has_support() && - gutenberg_is_fse_theme() - ) { - // Only lookup for the user data if we need it. - $origin = 'user'; - } - $tree = WP_Theme_JSON_Resolver::get_merged_data( $theme_support_data, $origin ); - // STEP 1: ADD FEATURES // // These need to be always added to the editor settings, // even for themes that don't support theme.json. // An example of this is that the presets are configured // from the theme support data. - $settings['__experimentalFeatures'] = $tree->get_settings(); + $settings['__experimentalFeatures'] = WP_Theme_JSON_Resolver::get_settings( $theme_support_data ); // STEP 2 - IF EDIT-SITE, ADD DATA REQUIRED FOR GLOBAL STYLES SIDEBAR // @@ -227,7 +167,7 @@ function_exists( 'gutenberg_is_edit_site_page' ) && gutenberg_is_fse_theme() ) { $user_cpt_id = WP_Theme_JSON_Resolver::get_user_custom_post_type_id(); - $base_styles = WP_Theme_JSON_Resolver::get_merged_data( $theme_support_data, 'theme' )->get_raw_data(); + $base_styles = WP_Theme_JSON_Resolver::get_theme_styles_and_settings( $theme_support_data ); $settings['__experimentalGlobalStylesUserEntityId'] = $user_cpt_id; $settings['__experimentalGlobalStylesBaseStyles'] = $base_styles; @@ -239,11 +179,11 @@ function_exists( 'gutenberg_is_edit_site_page' ) && // some of these should be added the wrapper class, // as if they were added via add_editor_styles. $settings['styles'][] = array( - 'css' => gutenberg_experimental_global_styles_get_stylesheet( $tree, 'css_variables' ), + 'css' => WP_Theme_JSON_Resolver::get_stylesheet( $theme_support_data, 'css_variables' ), '__experimentalNoWrapper' => true, ); $settings['styles'][] = array( - 'css' => gutenberg_experimental_global_styles_get_stylesheet( $tree, 'block_styles' ), + 'css' => WP_Theme_JSON_Resolver::get_stylesheet( $theme_support_data, 'block_styles' ), ); } @@ -286,7 +226,7 @@ function gutenberg_global_styles_filter_post( $content ) { unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); $theme_json = new WP_Theme_JSON( $decoded_data ); $theme_json->remove_insecure_properties(); - $data_to_encode = $theme_json->get_raw_data(); + $data_to_encode = $theme_json->get(); $data_to_encode['isGlobalStylesUserThemeJSON'] = true; return wp_json_encode( $data_to_encode ); } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 81e77bcb234692..8fa4588926aac9 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -37,7 +37,7 @@ function test_schema_validation_subtree_is_removed_if_key_invalid() { ), ) ); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $expected = array( 'styles' => array( @@ -85,7 +85,7 @@ function test_schema_validation_subtree_is_removed_if_not_array() { ) ); - $actual = $theme_json->get_raw_data(); + $actual = $theme_json->get(); $expected = array( 'styles' => array( 'core/group' => array( @@ -130,7 +130,7 @@ function test_schema_validation_subtree_is_removed_if_empty() { ), ) ); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $expected = array( 'styles' => array( @@ -167,7 +167,7 @@ function test_schema_validation_subtree_is_removed_if_style_not_supported_by_blo ) ); - $actual = $theme_json->get_raw_data(); + $actual = $theme_json->get(); $expected = array( 'styles' => array( $root_name => array( @@ -203,7 +203,7 @@ function test_get_settings() { ) ); - $result = $theme_json->get_settings(); + $result = $theme_json->get( array( 'settings' ) ); $expected = array( $root_name => array( @@ -585,7 +585,7 @@ public function test_merge_incoming_data() { $theme_json->merge( new WP_Theme_JSON( $add_key_in_styles ) ); $theme_json->merge( new WP_Theme_JSON( $add_invalid_context ) ); $theme_json->merge( new WP_Theme_JSON( $update_presets ) ); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $this->assertEqualSetsWithIndex( $expected, $result ); } @@ -608,7 +608,7 @@ function test_remove_insecure_properties_removes_unsafe_styles() { true ); $theme_json->remove_insecure_properties(); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $expected = array( 'styles' => array( 'core/group' => array( @@ -640,7 +640,7 @@ function test_remove_insecure_properties_removes_unsafe_styles_sub_properties() true ); $theme_json->remove_insecure_properties(); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $expected = array( 'styles' => array( 'core/group' => array( @@ -692,7 +692,7 @@ function test_remove_insecure_properties_removes_non_preset_settings() { true ); $theme_json->remove_insecure_properties(); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $expected = array( 'settings' => array( $root_name => array( @@ -781,7 +781,7 @@ function test_remove_insecure_properties_removes_unsafe_preset_settings() { true ); $theme_json->remove_insecure_properties(); - $result = $theme_json->get_raw_data(); + $result = $theme_json->get(); $expected = array( 'settings' => array( $root_name => array( @@ -820,7 +820,7 @@ function test_get_custom_templates() { ) ); - $page_templates = $theme_json->get_custom_templates(); + $page_templates = $theme_json->get( array( 'customTemplates' ) ); $this->assertEqualSetsWithIndex( $page_templates, @@ -843,7 +843,7 @@ function test_get_template_parts() { ) ); - $template_parts = $theme_json->get_template_parts(); + $template_parts = $theme_json->get( array( 'templateParts' ) ); $this->assertEqualSetsWithIndex( $template_parts,