Skip to content

Commit f4f33b8

Browse files
committed
Introduce SAFE_SETTINGS constant in WP_Theme_JSON to preserve non-preset, non-CSS settings during property removal. Added unit tests to validate the functionality of safe settings and their existence in VALID_SETTINGS.
1 parent 9f0e3b6 commit f4f33b8

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

src/wp-includes/class-wp-theme-json.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,26 @@ class WP_Theme_JSON {
482482
),
483483
);
484484

485+
/**
486+
* Safe settings that should be preserved by ::remove_insecure_settings().
487+
*
488+
* These are non-preset, non-CSS settings that control behavior rather than styling.
489+
* Each entry defines the setting path and its expected type for validation.
490+
* Each entry should also be present in ::VALID_SETTINGS.
491+
*
492+
* @since 7.0.0
493+
*/
494+
const SAFE_SETTINGS = array(
495+
array(
496+
'path' => array( 'lightbox', 'allowEditing' ),
497+
'type' => 'boolean',
498+
),
499+
array(
500+
'path' => array( 'lightbox', 'enabled' ),
501+
'type' => 'boolean',
502+
),
503+
);
504+
485505
/**
486506
* The valid properties for fontFamilies under settings key.
487507
*
@@ -3732,6 +3752,33 @@ protected static function remove_insecure_settings( $input ) {
37323752
// Ensure indirect properties not included in any `PRESETS_METADATA` value are allowed.
37333753
static::remove_indirect_properties( $input, $output );
37343754

3755+
// Preserve all valid settings that aren't presets or indirect properties.
3756+
foreach ( static::SAFE_SETTINGS as $safe_setting ) {
3757+
$path = $safe_setting['path'];
3758+
$type = $safe_setting['type'];
3759+
3760+
// Extract the value from input using the path.
3761+
$value = _wp_array_get( $input, $path, null );
3762+
3763+
// Skip if the setting is not present in the input.
3764+
if ( null === $value ) {
3765+
continue;
3766+
}
3767+
3768+
// Validate the type.
3769+
$is_valid_type = false;
3770+
switch ( $type ) {
3771+
case 'boolean':
3772+
$is_valid_type = is_bool( $value );
3773+
break;
3774+
}
3775+
3776+
// If the type is valid, set it in the output using the path.
3777+
if ( $is_valid_type ) {
3778+
_wp_array_set( $output, $path, $value );
3779+
}
3780+
}
3781+
37353782
return $output;
37363783
}
37373784

tests/phpunit/tests/theme/wpThemeJson.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6623,4 +6623,70 @@ public function test_merge_incoming_data_unique_slugs_always_preserved() {
66236623

66246624
$this->assertEqualSetsWithIndex( $expected, $actual );
66256625
}
6626+
6627+
/**
6628+
* @covers WP_Theme_JSON::remove_insecure_properties
6629+
*/
6630+
public function test_remove_insecure_properties_should_allow_safe_settings() {
6631+
$actual = WP_Theme_JSON::remove_insecure_properties(
6632+
array(
6633+
'version' => WP_Theme_JSON::LATEST_SCHEMA,
6634+
'settings' => array(
6635+
'blocks' => array(
6636+
'core/image' => array(
6637+
'lightbox' => array(
6638+
'enabled' => false,
6639+
'allowEditing' => true,
6640+
),
6641+
),
6642+
),
6643+
),
6644+
)
6645+
);
6646+
6647+
$expected = array(
6648+
'version' => WP_Theme_JSON::LATEST_SCHEMA,
6649+
'settings' => array(
6650+
'blocks' => array(
6651+
'core/image' => array(
6652+
'lightbox' => array(
6653+
'enabled' => false,
6654+
'allowEditing' => true,
6655+
),
6656+
),
6657+
),
6658+
),
6659+
);
6660+
6661+
$this->assertEqualSetsWithIndex( $expected, $actual );
6662+
}
6663+
6664+
/**
6665+
* @covers WP_Theme_JSON::remove_insecure_properties
6666+
*/
6667+
public function test_safe_settings_paths_should_exist_in_valid_settings() {
6668+
// Verify all paths in SAFE_SETTINGS exist in VALID_SETTINGS.
6669+
foreach ( WP_Theme_JSON::SAFE_SETTINGS as $safe_setting ) {
6670+
$path = $safe_setting['path'];
6671+
$data = WP_Theme_JSON::VALID_SETTINGS;
6672+
6673+
// Check if path exists by traversing the nested structure.
6674+
$exists = true;
6675+
foreach ( $path as $key ) {
6676+
if ( ! is_array( $data ) || ! array_key_exists( $key, $data ) ) {
6677+
$exists = false;
6678+
break;
6679+
}
6680+
$data = $data[ $key ];
6681+
}
6682+
6683+
$this->assertTrue(
6684+
$exists,
6685+
sprintf(
6686+
'Path %s from SAFE_SETTINGS should exist in VALID_SETTINGS',
6687+
implode( '.', $path )
6688+
)
6689+
);
6690+
}
6691+
}
66266692
}

0 commit comments

Comments
 (0)