From 3a4e746807d806b4c56fa1c94bbb2ed4a448c2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=83=C2=A9?= Date: Wed, 14 Jun 2023 07:40:50 +0000 Subject: [PATCH] Ignore unregistered block style variations from `theme.json`. This PR makes sure unregistered block style variations declared via `theme.json` are ignored. It fixes an issue by style variations don't work in the editor and CSS rules without a selector are output to the front-end. Props isabel_brison. Fixes #58462. git-svn-id: https://develop.svn.wordpress.org/trunk@55912 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-theme-json.php | 31 ++++- tests/phpunit/tests/theme/wpThemeJson.php | 140 ++++++++-------------- 2 files changed, 74 insertions(+), 97 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 735163553e..174f50c8f0 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -589,8 +589,15 @@ class WP_Theme_JSON { $this->theme_json = WP_Theme_JSON_Schema::migrate( $theme_json ); $valid_block_names = array_keys( static::get_blocks_metadata() ); $valid_element_names = array_keys( static::ELEMENTS ); - $theme_json = static::sanitize( $this->theme_json, $valid_block_names, $valid_element_names ); - $this->theme_json = static::maybe_opt_in_into_settings( $theme_json ); + $valid_variations = array(); + foreach ( self::get_blocks_metadata() as $block_name => $block_meta ) { + if ( ! isset( $block_meta['styleVariations'] ) ) { + continue; + } + $valid_variations[ $block_name ] = array_keys( $block_meta['styleVariations'] ); + } + $theme_json = static::sanitize( $this->theme_json, $valid_block_names, $valid_element_names, $valid_variations ); + $this->theme_json = static::maybe_opt_in_into_settings( $theme_json ); // Internally, presets are keyed by origin. $nodes = static::get_setting_nodes( $this->theme_json ); @@ -668,9 +675,10 @@ class WP_Theme_JSON { * @param array $input Structure to sanitize. * @param array $valid_block_names List of valid block names. * @param array $valid_element_names List of valid element names. + * @param array $valid_variations List of valid variations per block. * @return array The sanitized output. */ - protected static function sanitize( $input, $valid_block_names, $valid_element_names ) { + protected static function sanitize( $input, $valid_block_names, $valid_element_names, $valid_variations ) { $output = array(); @@ -728,9 +736,13 @@ class WP_Theme_JSON { $style_variation_names = array(); if ( ! empty( $input['styles']['blocks'][ $block ]['variations'] ) && - is_array( $input['styles']['blocks'][ $block ]['variations'] ) + is_array( $input['styles']['blocks'][ $block ]['variations'] ) && + isset( $valid_variations[ $block ] ) ) { - $style_variation_names = array_keys( $input['styles']['blocks'][ $block ]['variations'] ); + $style_variation_names = array_intersect( + array_keys( $input['styles']['blocks'][ $block ]['variations'] ), + $valid_variations[ $block ] + ); } $schema_styles_variations = array(); @@ -2852,8 +2864,15 @@ class WP_Theme_JSON { $valid_block_names = array_keys( static::get_blocks_metadata() ); $valid_element_names = array_keys( static::ELEMENTS ); + $valid_variations = array(); + foreach ( self::get_blocks_metadata() as $block_name => $block_meta ) { + if ( ! isset( $block_meta['styleVariations'] ) ) { + continue; + } + $valid_variations[ $block_name ] = array_keys( $block_meta['styleVariations'] ); + } - $theme_json = static::sanitize( $theme_json, $valid_block_names, $valid_element_names ); + $theme_json = static::sanitize( $theme_json, $valid_block_names, $valid_element_names, $valid_variations ); $blocks_metadata = static::get_blocks_metadata(); $style_nodes = static::get_style_nodes( $theme_json, $blocks_metadata ); diff --git a/tests/phpunit/tests/theme/wpThemeJson.php b/tests/phpunit/tests/theme/wpThemeJson.php index ddbceeadd1..8b54960ccf 100644 --- a/tests/phpunit/tests/theme/wpThemeJson.php +++ b/tests/phpunit/tests/theme/wpThemeJson.php @@ -3698,6 +3698,54 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase { $this->assertSame( $expected, $root_rules . $style_rules ); } + /* + * @ticket 58462 + */ + public function test_sanitize_for_unregistered_style_variations() { + $theme_json = new WP_Theme_JSON( + array( + 'version' => 2, + 'styles' => array( + 'blocks' => array( + 'core/quote' => array( + 'variations' => array( + 'unregisteredVariation' => array( + 'color' => array( + 'background' => 'hotpink', + ), + ), + 'plain' => array( + 'color' => array( + 'background' => 'hotpink', + ), + ), + ), + ), + ), + ), + ) + ); + + $sanitized_theme_json = $theme_json->get_raw_data(); + $expected = array( + 'version' => 2, + 'styles' => array( + 'blocks' => array( + 'core/quote' => array( + 'variations' => array( + 'plain' => array( + 'color' => array( + 'background' => 'hotpink', + ), + ), + ), + ), + ), + ), + ); + $this->assertSameSetsWithIndex( $expected, $sanitized_theme_json, 'Sanitized theme.json styles does not match' ); + } + /** * @ticket 57583 * @@ -3732,7 +3780,7 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase { */ public function data_sanitize_for_block_with_style_variations() { return array( - '1 variation with 1 invalid property' => array( + '1 variation with 1 valid property' => array( 'theme_json_variations' => array( 'variations' => array( 'plain' => array( @@ -3782,44 +3830,6 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase { ), ), ), - '2 variations with 1 invalid property' => array( - 'theme_json_variations' => array( - 'variations' => array( - 'plain' => array( - 'color' => array( - 'background' => 'hotpink', - ), - 'invalidProperty1' => 'value1', - ), - 'basic' => array( - 'color' => array( - 'background' => '#ffffff', - 'text' => '#000000', - ), - 'foo' => 'bar', - ), - ), - ), - 'expected_sanitized' => array( - 'blocks' => array( - 'core/quote' => array( - 'variations' => array( - 'plain' => array( - 'color' => array( - 'background' => 'hotpink', - ), - ), - 'basic' => array( - 'color' => array( - 'background' => '#ffffff', - 'text' => '#000000', - ), - ), - ), - ), - ), - ), - ), ); } @@ -3913,13 +3923,6 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase { ), 'styles' => '.is-style-plain.is-style-plain.wp-block-quote{background-color: hotpink;}', ); - $basic = array( - 'metadata' => array( - 'path' => array( 'styles', 'blocks', 'core/quote', 'variations', 'basic' ), - 'selector' => '.is-style-basic.is-style-basic.wp-block-quote', - ), - 'styles' => '.is-style-basic.is-style-basic.wp-block-quote{background-color: #ffffff;color: #000000;}', - ); return array( '1 variation with 1 invalid property' => array( @@ -3950,51 +3953,6 @@ class Tests_Theme_wpThemeJson extends WP_UnitTestCase { 'metadata_variation' => array( $plain['metadata'] ), 'expected' => $plain['styles'], ), - '2 variations with 1 invalid property' => array( - 'theme_json_variations' => array( - 'variations' => array( - 'plain' => array( - 'color' => array( - 'background' => 'hotpink', - ), - 'invalidProperty1' => 'value1', - ), - 'basic' => array( - 'color' => array( - 'background' => '#ffffff', - 'text' => '#000000', - ), - 'foo' => 'bar', - ), - ), - ), - 'metadata_variation' => array( $plain['metadata'], $basic['metadata'] ), - 'expected_styles' => $plain['styles'] . $basic['styles'], - ), - '2 variations with multiple invalid properties' => array( - 'theme_json_variations' => array( - 'variations' => array( - 'plain' => array( - 'color' => array( - 'background' => 'hotpink', - ), - 'invalidProperty1' => 'value1', - 'invalidProperty2' => 'value2', - ), - 'basic' => array( - 'foo' => 'foo', - 'color' => array( - 'background' => '#ffffff', - 'text' => '#000000', - ), - 'bar' => 'bar', - 'baz' => 'baz', - ), - ), - ), - 'metadata_variation' => array( $plain['metadata'], $basic['metadata'] ), - 'expected_styles' => $plain['styles'] . $basic['styles'], - ), ); }