From 4d160b0f24daee32885841c0cb9fd995f9acebda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Sep 2022 10:02:46 +0200 Subject: [PATCH 01/10] Make global styles data filterable --- lib/experimental/class-wp-theme-json-resolver-gutenberg.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 138f9b8b865b4c..cfb28a7009fb64 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -182,9 +182,9 @@ public static function get_merged_data( $origin = 'custom' ) { } $result = new WP_Theme_JSON_Gutenberg(); - $result->merge( static::get_core_data() ); - $result->merge( static::get_block_data() ); - $result->merge( static::get_theme_data() ); + $result->merge( apply_filters( 'global_styles_core', static::get_core_data() ) ); + $result->merge( apply_filters( 'global_styles_blocks', static::get_block_data() ) ); + $result->merge( apply_filters( 'global_styles_theme', static::get_theme_data() ) ); if ( 'custom' === $origin ) { $result->merge( static::get_user_data() ); } From 7fcbf75280fdf55f22952ffa3cc6395b90f55bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Sep 2022 13:43:27 +0200 Subject: [PATCH 02/10] Add new gutenberg_merge_theme_json function to act as public API --- lib/compat/wordpress-6.1/merge-theme-json.php | 9 +++++++++ lib/load.php | 1 + 2 files changed, 10 insertions(+) create mode 100644 lib/compat/wordpress-6.1/merge-theme-json.php diff --git a/lib/compat/wordpress-6.1/merge-theme-json.php b/lib/compat/wordpress-6.1/merge-theme-json.php new file mode 100644 index 00000000000000..5b8aa8d19fd959 --- /dev/null +++ b/lib/compat/wordpress-6.1/merge-theme-json.php @@ -0,0 +1,9 @@ +merge( $incoming ); + + return $existing->get_raw_data(); +} diff --git a/lib/load.php b/lib/load.php index 367e24fdc5e51d..55a1747a0d684b 100644 --- a/lib/load.php +++ b/lib/load.php @@ -83,6 +83,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.1/block-editor-settings.php'; require __DIR__ . '/compat/wordpress-6.1/persisted-preferences.php'; require __DIR__ . '/compat/wordpress-6.1/get-global-styles-and-settings.php'; +require __DIR__ . '/compat/wordpress-6.1/merge-theme-json.php'; require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-6-1.php'; require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php'; require __DIR__ . '/compat/wordpress-6.1/block-template-utils.php'; From 6e7a6c39f97d4c426707c28cc218763a86a98a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Sep 2022 13:45:37 +0200 Subject: [PATCH 03/10] Filter: make them to use raw theme.json data instead of a WP_Theme_JSON object --- .../class-wp-theme-json-resolver-6-1.php | 1 + .../class-wp-theme-json-resolver-gutenberg.php | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 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 f704daaffafb1d..ae0e734224b2ec 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 @@ -55,6 +55,7 @@ public static function get_core_data() { } $config = static::read_json_file( __DIR__ . '/theme.json' ); + $config = apply_filters( 'global_styles_default', $config ); $config = static::translate( $config ); static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' ); diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index cfb28a7009fb64..ce7537fb5e517a 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -38,6 +38,15 @@ public static function get_theme_data( $deprecated = array(), $settings = array( $theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) ); $theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); $theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data ); + + /** + * TODO: + * - should webfonts be filterable as well? + * - make sure the new data gets translated + * - verify all the paths (with and without supports, etc) + */ + $theme_json_data = apply_filters( 'global_styles_theme', $theme_json_data ); + static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); if ( wp_get_theme()->parent() ) { @@ -128,6 +137,8 @@ public static function get_block_data() { } } + apply_filters( 'global_styles_blocks', $config ); + // Core here means it's the lower level part of the styles chain. // It can be a core or a third-party block. return new WP_Theme_JSON_Gutenberg( $config, 'core' ); @@ -182,9 +193,9 @@ public static function get_merged_data( $origin = 'custom' ) { } $result = new WP_Theme_JSON_Gutenberg(); - $result->merge( apply_filters( 'global_styles_core', static::get_core_data() ) ); - $result->merge( apply_filters( 'global_styles_blocks', static::get_block_data() ) ); - $result->merge( apply_filters( 'global_styles_theme', static::get_theme_data() ) ); + $result->merge( 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() ); } From e80c7b66d22556f6301d83391538af7f345f1f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 9 Sep 2022 15:05:28 +0200 Subject: [PATCH 04/10] Provide smart defaults for when the function runs in a filter --- lib/compat/wordpress-6.1/merge-theme-json.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.1/merge-theme-json.php b/lib/compat/wordpress-6.1/merge-theme-json.php index 5b8aa8d19fd959..92d45e105b2b36 100644 --- a/lib/compat/wordpress-6.1/merge-theme-json.php +++ b/lib/compat/wordpress-6.1/merge-theme-json.php @@ -1,6 +1,16 @@ merge( $incoming ); From a923703ae0826aa2d2d03186004ed436da2b95cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 12 Sep 2022 12:48:01 +0200 Subject: [PATCH 05/10] Document helper function --- lib/compat/wordpress-6.1/merge-theme-json.php | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/compat/wordpress-6.1/merge-theme-json.php b/lib/compat/wordpress-6.1/merge-theme-json.php index 92d45e105b2b36..7ec1ee1dc6c583 100644 --- a/lib/compat/wordpress-6.1/merge-theme-json.php +++ b/lib/compat/wordpress-6.1/merge-theme-json.php @@ -1,13 +1,30 @@ Date: Mon, 12 Sep 2022 13:20:21 +0200 Subject: [PATCH 06/10] Fix blocks data --- 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 ce7537fb5e517a..ba308328067142 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -137,7 +137,7 @@ public static function get_block_data() { } } - apply_filters( 'global_styles_blocks', $config ); + $config = apply_filters( 'global_styles_blocks', $config ); // Core here means it's the lower level part of the styles chain. // It can be a core or a third-party block. From 60de8c865c5abd4a54b2471816e212cc646b7dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 12 Sep 2022 15:59:27 +0200 Subject: [PATCH 07/10] Clear comment --- .../class-wp-theme-json-resolver-gutenberg.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index ba308328067142..495dbe3789709c 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -39,14 +39,7 @@ public static function get_theme_data( $deprecated = array(), $settings = array( $theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); $theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data ); - /** - * TODO: - * - should webfonts be filterable as well? - * - make sure the new data gets translated - * - verify all the paths (with and without supports, etc) - */ $theme_json_data = apply_filters( 'global_styles_theme', $theme_json_data ); - static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); if ( wp_get_theme()->parent() ) { From a5dddc3d6bc576a69d2c76e4ba8df3821b27087d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 12 Sep 2022 16:03:47 +0200 Subject: [PATCH 08/10] Add global_styles_user filter --- .../class-wp-theme-json-resolver-6-1.php | 43 ++++++++++++++++++- 1 file changed, 42 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 ae0e734224b2ec..e17a6be5252f59 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 @@ -55,10 +55,51 @@ public static function get_core_data() { } $config = static::read_json_file( __DIR__ . '/theme.json' ); - $config = apply_filters( 'global_styles_default', $config ); $config = static::translate( $config ); + $config = apply_filters( 'global_styles_default', $config ); static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' ); return static::$core; } + + /** + * 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() ); + $config = apply_filters( 'global_styles_user', $config ); + 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; + } + } + + $config = apply_filters( 'global_styles_user', $config ); + static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); + + return static::$user; + } } From c340a37dbcfce4fdfcf13c950fa0ac3b2fe74feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 12 Sep 2022 19:57:28 +0200 Subject: [PATCH 09/10] Create a WP_Theme_JSON_Data structure that replaces the use of gutenberg_theme_json_merge( $existing, $incoming ) People have to use this object instance to filter the theme.json by doing $theme_json->update_with( $new_data ) The reason for doing this is that we don't want people to interact directly with the theme.json array, as it may change, forcing consumers to update their code. --- .../class-wp-theme-json-data.php | 60 +++++++++++++++++++ .../class-wp-theme-json-resolver-6-1.php | 12 ++-- lib/compat/wordpress-6.1/merge-theme-json.php | 36 ----------- ...class-wp-theme-json-resolver-gutenberg.php | 8 +-- lib/load.php | 2 +- 5 files changed, 71 insertions(+), 47 deletions(-) create mode 100644 lib/compat/wordpress-6.1/class-wp-theme-json-data.php delete mode 100644 lib/compat/wordpress-6.1/merge-theme-json.php diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-data.php b/lib/compat/wordpress-6.1/class-wp-theme-json-data.php new file mode 100644 index 00000000000000..cbd2656677f143 --- /dev/null +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-data.php @@ -0,0 +1,60 @@ +origin = $origin; + $this->theme_json = new WP_Theme_JSON_Gutenberg( $data, $this->origin ); + } + + /** + * Updates the theme.json with the the given data. + * + * @param array $new_data Array following the theme.json specification. + * + * @return WP_Theme_JSON_Data the modified data. + */ + public function update_with( $new_data ) { + $this->theme_json->merge( new WP_Theme_JSON_Gutenberg( $new_data, $this->origin ) ); + + return $this; + } + + /** + * Returns the underlying data. + * + * @return array + */ + public function get_data() { + return $this->theme_json->get_raw_data(); + } + +} 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 e17a6be5252f59..d210fa16d23108 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 @@ -56,8 +56,8 @@ public static function get_core_data() { $config = static::read_json_file( __DIR__ . '/theme.json' ); $config = static::translate( $config ); - $config = apply_filters( 'global_styles_default', $config ); - static::$core = new WP_Theme_JSON_Gutenberg( $config, 'default' ); + $config = apply_filters( 'global_styles_default', new WP_Theme_JSON_Data( $config, 'default' ) ); + static::$core = new WP_Theme_JSON_Gutenberg( $config->get_data(), 'default' ); return static::$core; } @@ -81,8 +81,8 @@ public static function get_user_data() { $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() ); - $config = apply_filters( 'global_styles_user', $config ); - return new WP_Theme_JSON_Gutenberg( $config, 'custom' ); + $config = apply_filters( 'global_styles_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); + return new WP_Theme_JSON_Gutenberg( $config->get_data(), 'custom' ); } // Very important to verify if the flag isGlobalStylesUserThemeJSON is true. @@ -97,8 +97,8 @@ public static function get_user_data() { } } - $config = apply_filters( 'global_styles_user', $config ); - static::$user = new WP_Theme_JSON_Gutenberg( $config, 'custom' ); + $config = apply_filters( 'global_styles_user', new WP_Theme_JSON_Data( $config, 'custom' ) ); + static::$user = new WP_Theme_JSON_Gutenberg( $config->get_data(), 'custom' ); return static::$user; } diff --git a/lib/compat/wordpress-6.1/merge-theme-json.php b/lib/compat/wordpress-6.1/merge-theme-json.php deleted file mode 100644 index 7ec1ee1dc6c583..00000000000000 --- a/lib/compat/wordpress-6.1/merge-theme-json.php +++ /dev/null @@ -1,36 +0,0 @@ -merge( $incoming ); - - return $existing->get_raw_data(); -} diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 495dbe3789709c..042eff6407c96c 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -39,8 +39,8 @@ public static function get_theme_data( $deprecated = array(), $settings = array( $theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); $theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data ); - $theme_json_data = apply_filters( 'global_styles_theme', $theme_json_data ); - static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); + $theme_json_data = apply_filters( 'global_styles_theme', new WP_Theme_JSON_Data( $theme_json_data, 'theme' ) ); + static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data->get_data() ); if ( wp_get_theme()->parent() ) { // Get parent theme.json. @@ -130,11 +130,11 @@ public static function get_block_data() { } } - $config = apply_filters( 'global_styles_blocks', $config ); + $config = apply_filters( 'global_styles_blocks', new WP_Theme_JSON_Data( $config , 'core' ) ); // Core here means it's the lower level part of the styles chain. // It can be a core or a third-party block. - return new WP_Theme_JSON_Gutenberg( $config, 'core' ); + return new WP_Theme_JSON_Gutenberg( $config->get_data(), 'core' ); } /** diff --git a/lib/load.php b/lib/load.php index 55a1747a0d684b..81a63b49769b66 100644 --- a/lib/load.php +++ b/lib/load.php @@ -83,7 +83,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.1/block-editor-settings.php'; require __DIR__ . '/compat/wordpress-6.1/persisted-preferences.php'; require __DIR__ . '/compat/wordpress-6.1/get-global-styles-and-settings.php'; -require __DIR__ . '/compat/wordpress-6.1/merge-theme-json.php'; +require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-data.php'; require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-6-1.php'; require __DIR__ . '/compat/wordpress-6.1/class-wp-theme-json-resolver-6-1.php'; require __DIR__ . '/compat/wordpress-6.1/block-template-utils.php'; From 23df722598ed6ce46013584c96b5adecc52c7d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Mon, 12 Sep 2022 20:07:47 +0200 Subject: [PATCH 10/10] Fix lint issues --- lib/compat/wordpress-6.1/class-wp-theme-json-data.php | 2 +- lib/experimental/class-wp-theme-json-resolver-gutenberg.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-data.php b/lib/compat/wordpress-6.1/class-wp-theme-json-data.php index cbd2656677f143..d03b2227558ead 100644 --- a/lib/compat/wordpress-6.1/class-wp-theme-json-data.php +++ b/lib/compat/wordpress-6.1/class-wp-theme-json-data.php @@ -27,7 +27,7 @@ class WP_Theme_JSON_Data { /** * Constructor. * - * @param array $data Array following the theme.json specification. + * @param array $data Array following the theme.json specification. * @param string $origin The origin of the data: default, theme, user. */ public function __construct( $data = array(), $origin = 'theme' ) { diff --git a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php index 042eff6407c96c..30b93d85e698eb 100644 --- a/lib/experimental/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/experimental/class-wp-theme-json-resolver-gutenberg.php @@ -130,7 +130,7 @@ public static function get_block_data() { } } - $config = apply_filters( 'global_styles_blocks', new WP_Theme_JSON_Data( $config , 'core' ) ); + $config = apply_filters( 'global_styles_blocks', new WP_Theme_JSON_Data( $config, 'core' ) ); // Core here means it's the lower level part of the styles chain. // It can be a core or a third-party block.