Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,7 @@ public function __construct( $theme_json = array( 'version' => self::LATEST_SCHE
// In addition to presets, spacingScale (which generates presets) is also keyed by origin.
$scale_path = array( 'settings', 'spacing', 'spacingScale' );
$spacing_scale = _wp_array_get( $this->theme_json, $scale_path, null );
if ( null !== $spacing_scale ) {
if ( is_array( $spacing_scale ) ) {
// If the spacingScale is not already keyed by origin.
if ( empty( array_intersect( array_keys( $spacing_scale ), static::VALID_ORIGINS ) ) ) {
_wp_array_set( $this->theme_json, $scale_path, array( $origin => $spacing_scale ) );
Expand Down Expand Up @@ -1214,7 +1214,10 @@ private static function unwrap_shared_block_style_variations( $theme_json, $vali
foreach ( $registered_variations as $variation_name ) {
$block_level_data = $new_theme_json['styles']['blocks'][ $block_type ]['variations'][ $variation_name ] ?? array();
$top_level_data = $variations[ $variation_name ] ?? array();
$merged_data = array_replace_recursive( $top_level_data, $block_level_data );
if ( ! is_array( $block_level_data ) || ! is_array( $top_level_data ) ) {
continue;
}
$merged_data = array_replace_recursive( $top_level_data, $block_level_data );
if ( ! empty( $merged_data ) ) {
_wp_array_set( $new_theme_json, array( 'styles', 'blocks', $block_type, 'variations', $variation_name ), $merged_data );
}
Expand Down Expand Up @@ -1493,7 +1496,7 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n
if ( ! empty( $input['blockTypes'] ) && is_array( $input['blockTypes'] ) ) {
$variation_pseudo_selectors = array();
foreach ( $input['blockTypes'] as $variation_block_type ) {
if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $variation_block_type ] ) ) {
if ( is_string( $variation_block_type ) && isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $variation_block_type ] ) ) {
$variation_pseudo_selectors = array_merge(
$variation_pseudo_selectors,
static::VALID_BLOCK_PSEUDO_SELECTORS[ $variation_block_type ]
Expand Down Expand Up @@ -2101,7 +2104,10 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets'
// Load the custom CSS last so it has the highest specificity.
if ( in_array( 'custom-css', $types, true ) ) {
// Add the global styles root CSS.
$stylesheet .= _wp_array_get( $this->theme_json, array( 'styles', 'css' ) );
$root_css = $this->theme_json['styles']['css'] ?? '';
if ( is_string( $root_css ) ) {
$stylesheet .= $root_css;
}
}

return $stylesheet;
Expand All @@ -2121,7 +2127,7 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets'
public static function process_blocks_custom_css( $css, $selector ) {
$processed_css = '';

if ( empty( $css ) ) {
if ( empty( $css ) || ! is_string( $css ) ) {
return $processed_css;
}

Expand Down Expand Up @@ -3241,7 +3247,7 @@ protected static function get_property_value( $styles, $path, $theme_json = null
* In the case of backgroundImage, if both a ref and a URL are present in the value,
* the URL takes precedence and the ref is ignored.
*/
if ( is_array( $value ) && isset( $value['ref'] ) ) {
if ( is_array( $value ) && isset( $value['ref'] ) && is_string( $value['ref'] ) ) {
$value_path = explode( '.', $value['ref'] );
$ref_value = _wp_array_get( $theme_json, $value_path );
// Background Image refs can refer to a string or an array containing a URL string.
Expand Down Expand Up @@ -4431,11 +4437,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 ) ) {
Comment on lines +4440 to +4446

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continue;
}

Expand Down Expand Up @@ -5569,6 +5577,7 @@ private static function compute_spacing_sizes( $spacing_scale ) {
! isset( $spacing_scale['mediumStep'] ) ||
! is_numeric( $spacing_scale['mediumStep'] ) ||
! isset( $spacing_scale['unit'] ) ||
! is_string( $spacing_scale['unit'] ) ||
! isset( $spacing_scale['operator'] ) ||
( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ||
! isset( $spacing_scale['increment'] ) ||
Expand Down
131 changes: 131 additions & 0 deletions tests/phpunit/tests/theme/wpThemeJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -5896,6 +5896,122 @@ public static function data_sanitize_with_invalid_style_variation() {
);
}

/**
* @ticket 66286
*
* @dataProvider data_get_stylesheet_ignores_values_of_unexpected_types
*
* @param array $theme_json_data The theme.json data, without the version.
*/
public function test_get_stylesheet_ignores_values_of_unexpected_types( $theme_json_data ) {
$theme_json = new WP_Theme_JSON(
array_merge( array( 'version' => WP_Theme_JSON::LATEST_SCHEMA ), $theme_json_data )
);

$this->assertIsString( $theme_json->get_stylesheet( array( 'variables', 'styles', 'presets', 'custom-css' ) ) );
}

/**
* Data provider.
*
* @return array
*/
public static function data_get_stylesheet_ignores_values_of_unexpected_types() {
return array(
'root custom css as an object' => array(
array( 'styles' => array( 'css' => array( 'color' => 'red' ) ) ),
),
'element custom css as an object' => array(
array( 'styles' => array( 'elements' => array( 'link' => array( 'css' => array( 'color' => 'red' ) ) ) ) ),
),
'block custom css as a list' => array(
array( 'styles' => array( 'blocks' => array( 'core/paragraph' => array( 'css' => array( 'color: red;' ) ) ) ) ),
),
'ref as an array' => array(
array( 'styles' => array( 'color' => array( 'text' => array( 'ref' => array( 'styles', 'color' ) ) ) ) ),
),
'spacing scale as a string' => array(
array( 'settings' => array( 'spacing' => array( 'spacingScale' => '1.5' ) ) ),
),
'spacing scale unit as an array' => array(
array(
'settings' => array(
'spacing' => array(
'spacingScale' => array(
'operator' => '*',
'increment' => 1.5,
'steps' => 7,
'mediumStep' => 1.5,
'unit' => array( 'rem' ),
),
),
),
),
),
'shared style variation as a string' => array(
array( 'styles' => array( 'variations' => array( 'plain' => 'red' ) ) ),
),
'block types item as an array' => array(
array( 'blockTypes' => array( array( 'core/button' ) ) ),
),
);
}

/**
* @ticket 66286
*/
public function test_merge_does_not_generate_spacing_sizes_from_a_non_array_per_origin_spacing_scale() {
$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::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(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'settings' => array( 'spacing' => array( 'spacingScale' => array( 'theme' => '1.5' ) ) ),
)
)
);
$spacing_sizes = $theme_json->get_settings()['spacing']['spacingSizes'];

$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.'
);
}

/**
* @ticket 57583
* @ticket 61165
Expand Down Expand Up @@ -7411,6 +7527,7 @@ public static function data_custom_css_for_user_caps() {
/**
* @ticket 61165
* @ticket 61769
* @ticket 66286
*
* @dataProvider data_process_blocks_custom_css
*
Expand Down Expand Up @@ -7447,6 +7564,20 @@ public static function data_process_blocks_custom_css() {
),
'expected' => '',
),
'css as an object' => array(
'input' => array(
'selector' => '.foo',
'css' => array( 'color' => 'red' ),
),
'expected' => '',
),
'css as a list of strings' => array(
'input' => array(
'selector' => '.foo',
'css' => array( 'color: red;' ),
),
'expected' => '',
),
'no nested selectors' => array(
'input' => array(
'selector' => '.foo',
Expand Down
Loading