Skip to content

Commit cf3cbd8

Browse files
oandregalanton-vlasenkoglendaviesnz
authored
Merged data should consider origin to return early (#45969)
Co-authored-by: Anton Vlasenko <[email protected]> Co-authored-by: Glen Davies <[email protected]>
1 parent 15610be commit cf3cbd8

4 files changed

+188
-43
lines changed

lib/compat/wordpress-6.2/class-wp-theme-json-resolver-6-2.php

+56
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,60 @@ public static function _clean_cached_data_upon_upgrading( $upgrader, $options )
5757
}
5858
}
5959

60+
/**
61+
* Returns the data merged from multiple origins.
62+
*
63+
* There are four sources of data (origins) for a site:
64+
*
65+
* - default => WordPress
66+
* - blocks => each one of the blocks provides data for itself
67+
* - theme => the active theme
68+
* - custom => data provided by the user
69+
*
70+
* The custom's has higher priority than the theme's, the theme's higher than blocks',
71+
* and block's higher than default's.
72+
*
73+
* Unlike the getters
74+
* {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_core_data/ get_core_data},
75+
* {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_theme_data/ get_theme_data},
76+
* and {@link https://developer.wordpress.org/reference/classes/wp_theme_json_resolver/get_user_data/ get_user_data},
77+
* this method returns data after it has been merged with the previous origins.
78+
* This means that if the same piece of data is declared in different origins
79+
* (default, blocks, theme, custom), the last origin overrides the previous.
80+
*
81+
* For example, if the user has set a background color
82+
* for the paragraph block, and the theme has done it as well,
83+
* the user preference wins.
84+
*
85+
* @param string $origin Optional. To what level should we merge data:'default', 'blocks', 'theme' or 'custom'.
86+
* 'custom' is used as default value as well as fallback value if the origin is unknown.
87+
*
88+
* @return WP_Theme_JSON
89+
*/
90+
public static function get_merged_data( $origin = 'custom' ) {
91+
if ( is_array( $origin ) ) {
92+
_deprecated_argument( __FUNCTION__, '5.9.0' );
93+
}
94+
95+
$result = static::get_core_data();
96+
if ( 'default' === $origin ) {
97+
$result->set_spacing_sizes();
98+
return $result;
99+
}
100+
101+
$result->merge( static::get_block_data() );
102+
if ( 'blocks' === $origin ) {
103+
return $result;
104+
}
105+
106+
$result->merge( static::get_theme_data() );
107+
if ( 'theme' === $origin ) {
108+
$result->set_spacing_sizes();
109+
return $result;
110+
}
111+
112+
$result->merge( static::get_user_data() );
113+
$result->set_spacing_sizes();
114+
return $result;
115+
}
60116
}

lib/compat/wordpress-6.2/default-filters.php

+2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
*/
1919

2020
add_action( 'switch_theme', 'wp_theme_has_theme_json_clean_cache' );
21+
add_action( 'switch_theme', array( 'WP_Theme_JSON_Resolver_Gutenberg', 'clean_cached_data' ) );
2122
add_action( 'start_previewing_theme', 'wp_theme_has_theme_json_clean_cache' );
23+
add_action( 'start_previewing_theme', array( 'WP_Theme_JSON_Resolver_Gutenberg', 'clean_cached_data' ) );
2224
add_action( 'upgrader_process_complete', '_wp_theme_has_theme_json_clean_cache_upon_upgrading_active_theme', 10, 2 );
2325
add_action( 'save_post_wp_global_styles', array( 'WP_Theme_JSON_Resolver_Gutenberg', 'clean_cached_data' ) );
2426
add_action( 'activated_plugin', array( 'WP_Theme_JSON_Resolver_Gutenberg', 'clean_cached_data' ) );

lib/experimental/class-wp-theme-json-resolver-gutenberg.php

-43
Original file line numberDiff line numberDiff line change
@@ -165,47 +165,4 @@ private static function remove_JSON_comments( $array ) {
165165
return $array;
166166
}
167167

168-
/**
169-
* Returns the data merged from multiple origins.
170-
*
171-
* There are three sources of data (origins) for a site:
172-
* default, theme, and custom. The custom's has higher priority
173-
* than the theme's, and the theme's higher than default's.
174-
*
175-
* Unlike the getters {@link get_core_data},
176-
* {@link get_theme_data}, and {@link get_user_data},
177-
* this method returns data after it has been merged
178-
* with the previous origins. This means that if the same piece of data
179-
* is declared in different origins (user, theme, and core),
180-
* the last origin overrides the previous.
181-
*
182-
* For example, if the user has set a background color
183-
* for the paragraph block, and the theme has done it as well,
184-
* the user preference wins.
185-
*
186-
* @since 5.8.0
187-
* @since 5.9.0 Added user data, removed the `$settings` parameter,
188-
* added the `$origin` parameter.
189-
*
190-
* @param string $origin Optional. To what level should we merge data.
191-
* Valid values are 'theme' or 'custom'. Default 'custom'.
192-
* @return WP_Theme_JSON
193-
*/
194-
public static function get_merged_data( $origin = 'custom' ) {
195-
if ( is_array( $origin ) ) {
196-
_deprecated_argument( __FUNCTION__, '5.9' );
197-
}
198-
199-
$result = new WP_Theme_JSON_Gutenberg();
200-
$result->merge( static::get_core_data() );
201-
$result->merge( static::get_block_data() );
202-
$result->merge( static::get_theme_data() );
203-
if ( 'custom' === $origin ) {
204-
$result->merge( static::get_user_data() );
205-
}
206-
// Generate the default spacing sizes presets.
207-
$result->set_spacing_sizes();
208-
209-
return $result;
210-
}
211168
}

phpunit/class-wp-theme-json-resolver-test.php

+130
Original file line numberDiff line numberDiff line change
@@ -358,4 +358,134 @@ public function test_get_user_data_from_wp_global_styles_does_not_use_uncached_q
358358
$user_cpt = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( $theme );
359359
$this->assertEmpty( $user_cpt, 'User CPT is expected to be empty.' );
360360
}
361+
362+
/**
363+
* Test that get_merged_data returns the data merged up to the proper origin.
364+
*
365+
* @covers WP_Theme_JSON_Resolver::get_merged_data
366+
*
367+
* @dataProvider data_get_merged_data_returns_origin
368+
*
369+
* @param string $origin What origin to get data from.
370+
* @param bool $core_palette Whether the core palette is present.
371+
* @param string $core_palette_text Message.
372+
* @param string $block_styles Whether the block styles are present.
373+
* @param string $block_styles_text Message.
374+
* @param bool $theme_palette Whether the theme palette is present.
375+
* @param string $theme_palette_text Message.
376+
* @param bool $user_palette Whether the user palette is present.
377+
* @param string $user_palette_text Message.
378+
*/
379+
public function test_get_merged_data_returns_origin( $origin, $core_palette, $core_palette_text, $block_styles, $block_styles_text, $theme_palette, $theme_palette_text, $user_palette, $user_palette_text ) {
380+
// Make sure there is data from the blocks origin.
381+
register_block_type(
382+
'my/block-with-styles',
383+
array(
384+
'api_version' => 2,
385+
'attributes' => array(
386+
'borderColor' => array(
387+
'type' => 'string',
388+
),
389+
'style' => array(
390+
'type' => 'object',
391+
),
392+
),
393+
'supports' => array(
394+
'__experimentalStyle' => array(
395+
'typography' => array(
396+
'fontSize' => '42rem',
397+
),
398+
),
399+
),
400+
)
401+
);
402+
403+
// Make sure there is data from the theme origin.
404+
switch_theme( 'block-theme' );
405+
406+
// Make sure there is data from the user origin.
407+
wp_set_current_user( self::$administrator_id );
408+
$user_cpt = WP_Theme_JSON_Resolver_Gutenberg::get_user_data_from_wp_global_styles( wp_get_theme(), true );
409+
$config = json_decode( $user_cpt['post_content'], true );
410+
$config['settings']['color']['palette']['custom'] = array(
411+
array(
412+
'color' => 'hotpink',
413+
'name' => 'My color',
414+
'slug' => 'my-color',
415+
),
416+
);
417+
$user_cpt['post_content'] = wp_json_encode( $config );
418+
wp_update_post( $user_cpt, true, false );
419+
420+
$theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $origin );
421+
$settings = $theme_json->get_settings();
422+
$styles = $theme_json->get_styles_block_nodes();
423+
$this->assertSame( $core_palette, isset( $settings['color']['palette']['default'] ), $core_palette_text );
424+
$styles = array_filter(
425+
$styles,
426+
static function( $element ) {
427+
return isset( $element['name'] ) && 'my/block-with-styles' === $element['name'];
428+
}
429+
);
430+
$this->assertSame( $block_styles, count( $styles ) === 1, $block_styles_text );
431+
$this->assertSame( $theme_palette, isset( $settings['color']['palette']['theme'] ), $theme_palette_text );
432+
$this->assertSame( $user_palette, isset( $settings['color']['palette']['custom'] ), $user_palette_text );
433+
434+
unregister_block_type( 'my/block-with-styles' );
435+
}
436+
437+
/**
438+
* Data provider for test_get_merged_data_returns_origin
439+
*
440+
* @return array
441+
*/
442+
public function data_get_merged_data_returns_origin() {
443+
return array(
444+
'origin_default' => array(
445+
'origin' => 'default',
446+
'core_palette' => true,
447+
'core_palette_text' => 'Core palette must be present',
448+
'block_styles' => false,
449+
'block_styles_text' => 'Block styles should not be present',
450+
'theme_palette' => false,
451+
'theme_palette_text' => 'Theme palette should not be present',
452+
'user_palette' => false,
453+
'user_palette_text' => 'User palette should not be present',
454+
),
455+
'origin_blocks' => array(
456+
'origin' => 'blocks',
457+
'core_palette' => true,
458+
'core_palette_text' => 'Core palette must be present',
459+
'block_styles' => true,
460+
'block_styles_text' => 'Block styles must be present',
461+
'theme_palette' => false,
462+
'theme_palette_text' => 'Theme palette should not be present',
463+
'user_palette' => false,
464+
'user_palette_text' => 'User palette should not be present',
465+
),
466+
'origin_theme' => array(
467+
'origin' => 'theme',
468+
'core_palette' => true,
469+
'core_palette_text' => 'Core palette must be present',
470+
'block_styles' => true,
471+
'block_styles_text' => 'Block styles must be present',
472+
'theme_palette' => true,
473+
'theme_palette_text' => 'Theme palette must be present',
474+
'user_palette' => false,
475+
'user_palette_text' => 'User palette should not be present',
476+
),
477+
'origin_custom' => array(
478+
'origin' => 'custom',
479+
'core_palette' => true,
480+
'core_palette_text' => 'Core palette must be present',
481+
'block_styles' => true,
482+
'block_styles_text' => 'Block styles must be present',
483+
'theme_palette' => true,
484+
'theme_palette_text' => 'Theme palette must be present',
485+
'user_palette' => true,
486+
'user_palette_text' => 'User palette must be present',
487+
),
488+
);
489+
}
490+
361491
}

0 commit comments

Comments
 (0)