From 7ad5a560f8669b3a2e35d8dc590b7bcc0d41ddbe Mon Sep 17 00:00:00 2001 From: Ramon Date: Mon, 12 Oct 2026 14:04:06 +1100 Subject: [PATCH 1/3] Global Styles: Ignore per-origin spacingScale values that are not objects A spacingScale keyed by origin with a non-object value, such as { "theme": "1.5" }, passed the constructor and reached array_replace() in merge(), throwing a TypeError. --- lib/class-wp-theme-json-gutenberg.php | 8 +++++--- phpunit/class-wp-theme-json-test.php | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 4921b3acedff46..6765e4a3a3f273 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -4456,11 +4456,13 @@ public function merge( $incoming ) { $scale_path = array( 'settings', 'spacing', 'spacingScale', $origin ); // Apply the base spacing scale to the current layer. - $base_spacing_scale = _wp_array_get( $this->theme_json, $scale_path, array() ); - $flattened_spacing_scale = array_replace( $flattened_spacing_scale, $base_spacing_scale ); + $base_spacing_scale = _wp_array_get( $this->theme_json, $scale_path, array() ); + if ( is_array( $base_spacing_scale ) ) { + $flattened_spacing_scale = array_replace( $flattened_spacing_scale, $base_spacing_scale ); + } $spacing_scale = _wp_array_get( $incoming_data, $scale_path, null ); - if ( ! isset( $spacing_scale ) ) { + if ( ! is_array( $spacing_scale ) ) { continue; } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index c20e7a7389a3a6..9f3f6a7d9a250e 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -5549,6 +5549,20 @@ public function data_get_stylesheet_ignores_values_of_unexpected_types() { ); } + public function test_merge_ignores_spacing_scale_per_origin_value_of_unexpected_type() { + $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ), 'default' ); + $theme_json->merge( + new WP_Theme_JSON_Gutenberg( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'settings' => array( 'spacing' => array( 'spacingScale' => array( 'theme' => '1.5' ) ) ), + ) + ) + ); + + $this->assertIsString( $theme_json->get_stylesheet() ); + } + /** * @dataProvider data_get_styles_for_block_with_style_variations * From b7a59eba3bd78c3d77cb67c00772d8777b4e2136 Mon Sep 17 00:00:00 2001 From: Ramon Date: Mon, 12 Oct 2026 14:04:29 +1100 Subject: [PATCH 2/3] Add PR 84529 to the backport changelog for core PR 14190 --- backport-changelog/7.2/14190.md | 1 + 1 file changed, 1 insertion(+) diff --git a/backport-changelog/7.2/14190.md b/backport-changelog/7.2/14190.md index 596d5a726d9e57..079328b650b843 100644 --- a/backport-changelog/7.2/14190.md +++ b/backport-changelog/7.2/14190.md @@ -1,3 +1,4 @@ https://github.com/WordPress/wordpress-develop/pull/14190 * https://github.com/WordPress/gutenberg/pull/84523 +* https://github.com/WordPress/gutenberg/pull/84529 From ffcda65c7de6c8511f826b275cf5e373b8241e10 Mon Sep 17 00:00:00 2001 From: Ramon Date: Mon, 12 Oct 2026 14:07:32 +1100 Subject: [PATCH 3/3] Assert the spacing sizes merge() produces for a non-array per-origin scale --- phpunit/class-wp-theme-json-test.php | 44 ++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 9f3f6a7d9a250e..9df88e024f15ed 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -5549,8 +5549,24 @@ public function data_get_stylesheet_ignores_values_of_unexpected_types() { ); } - public function test_merge_ignores_spacing_scale_per_origin_value_of_unexpected_type() { - $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA ), 'default' ); + public function test_merge_does_not_generate_spacing_sizes_from_a_non_array_per_origin_spacing_scale() { + $theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'settings' => array( + 'spacing' => array( + 'spacingScale' => array( + 'operator' => '*', + 'increment' => 1.5, + 'steps' => 3, + 'mediumStep' => 1.5, + 'unit' => 'rem', + ), + ), + ), + ), + 'default' + ); $theme_json->merge( new WP_Theme_JSON_Gutenberg( array( @@ -5559,8 +5575,30 @@ public function test_merge_ignores_spacing_scale_per_origin_value_of_unexpected_ ) ) ); + $spacing_sizes = $theme_json->get_settings()['spacing']['spacingSizes']; - $this->assertIsString( $theme_json->get_stylesheet() ); + $this->assertSame( array(), $spacing_sizes['theme'], 'The theme layer with a non-array spacing scale should generate no sizes.' ); + $this->assertSame( + array( + array( + 'name' => 'Small', + 'slug' => '40', + 'size' => '1rem', + ), + array( + 'name' => 'Medium', + 'slug' => '50', + 'size' => '1.5rem', + ), + array( + 'name' => 'Large', + 'slug' => '60', + 'size' => '2.25rem', + ), + ), + $spacing_sizes['default'], + 'The default layer sizes should be unaffected.' + ); } /**