Changeset 57496
- Timestamp:
- 01/31/2024 10:53:48 AM (12 months ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-theme-json.php
r57491 r57496 430 430 ); 431 431 432 /* 433 * The valid properties for fontFamilies under settings key. 434 * 435 * @since 6.5.0 436 * 437 * @var array 438 */ 439 const FONT_FAMILY_SCHEMA = array( 440 array( 441 'fontFamily' => null, 442 'name' => null, 443 'slug' => null, 444 'fontFace' => array( 445 array( 446 'ascentOverride' => null, 447 'descentOverride' => null, 448 'fontDisplay' => null, 449 'fontFamily' => null, 450 'fontFeatureSettings' => null, 451 'fontStyle' => null, 452 'fontStretch' => null, 453 'fontVariationSettings' => null, 454 'fontWeight' => null, 455 'lineGapOverride' => null, 456 'sizeAdjust' => null, 457 'src' => null, 458 'unicodeRange' => null, 459 ), 460 ), 461 ), 462 ); 463 432 464 /** 433 465 * The valid properties under the styles key. … … 558 590 559 591 /** 592 * Return the input schema at the root and per origin. 593 * 594 * @since 6.5.0 595 * 596 * @param array $schema The base schema. 597 * @return array The schema at the root and per origin. 598 * 599 * Example: 600 * schema_in_root_and_per_origin( 601 * array( 602 * 'fontFamily' => null, 603 * 'slug' => null, 604 * ) 605 * ) 606 * 607 * Returns: 608 * array( 609 * 'fontFamily' => null, 610 * 'slug' => null, 611 * 'default' => array( 612 * 'fontFamily' => null, 613 * 'slug' => null, 614 * ), 615 * 'blocks' => array( 616 * 'fontFamily' => null, 617 * 'slug' => null, 618 * ), 619 * 'theme' => array( 620 * 'fontFamily' => null, 621 * 'slug' => null, 622 * ), 623 * 'custom' => array( 624 * 'fontFamily' => null, 625 * 'slug' => null, 626 * ), 627 * ) 628 */ 629 protected static function schema_in_root_and_per_origin( $schema ) { 630 $schema_in_root_and_per_origin = $schema; 631 foreach ( static::VALID_ORIGINS as $origin ) { 632 $schema_in_root_and_per_origin[ $origin ] = $schema; 633 } 634 return $schema_in_root_and_per_origin; 635 } 636 637 /** 560 638 * Returns a class name by an element name. 561 639 * … … 798 876 } 799 877 800 $schema['styles'] = static::VALID_STYLES; 801 $schema['styles']['blocks'] = $schema_styles_blocks; 802 $schema['styles']['elements'] = $schema_styles_elements; 803 $schema['settings'] = static::VALID_SETTINGS; 804 $schema['settings']['blocks'] = $schema_settings_blocks; 878 $schema['styles'] = static::VALID_STYLES; 879 $schema['styles']['blocks'] = $schema_styles_blocks; 880 $schema['styles']['elements'] = $schema_styles_elements; 881 $schema['settings'] = static::VALID_SETTINGS; 882 $schema['settings']['blocks'] = $schema_settings_blocks; 883 $schema['settings']['typography']['fontFamilies'] = static::schema_in_root_and_per_origin( static::FONT_FAMILY_SCHEMA ); 805 884 806 885 // Remove anything that's not present in the schema. … … 975 1054 */ 976 1055 protected static function remove_keys_not_in_schema( $tree, $schema ) { 977 $tree = array_intersect_key( $tree, $schema ); 978 979 foreach ( $schema as $key => $data ) { 980 if ( ! isset( $tree[ $key ] ) ) { 1056 if ( ! is_array( $tree ) ) { 1057 return $tree; 1058 } 1059 1060 foreach ( $tree as $key => $value ) { 1061 // Remove keys not in the schema or with null/empty values. 1062 if ( ! array_key_exists( $key, $schema ) ) { 1063 unset( $tree[ $key ] ); 981 1064 continue; 982 1065 } 983 1066 984 if ( is_array( $schema[ $key ] ) && is_array( $tree[ $key ] ) ) { 985 $tree[ $key ] = static::remove_keys_not_in_schema( $tree[ $key ], $schema[ $key ] ); 986 987 if ( empty( $tree[ $key ] ) ) { 988 unset( $tree[ $key ] ); 1067 // Check if the value is an array and requires further processing. 1068 if ( is_array( $value ) && is_array( $schema[ $key ] ) ) { 1069 // Determine if it is an associative or indexed array. 1070 $schema_is_assoc = self::is_assoc( $value ); 1071 1072 if ( $schema_is_assoc ) { 1073 // If associative, process as a single object. 1074 $tree[ $key ] = self::remove_keys_not_in_schema( $value, $schema[ $key ] ); 1075 1076 if ( empty( $tree[ $key ] ) ) { 1077 unset( $tree[ $key ] ); 1078 } 1079 } else { 1080 // If indexed, process each item in the array. 1081 foreach ( $value as $item_key => $item_value ) { 1082 if ( isset( $schema[ $key ][0] ) && is_array( $schema[ $key ][0] ) ) { 1083 $tree[ $key ][ $item_key ] = self::remove_keys_not_in_schema( $item_value, $schema[ $key ][0] ); 1084 } else { 1085 // If the schema does not define a further structure, keep the value as is. 1086 $tree[ $key ][ $item_key ] = $item_value; 1087 } 1088 } 989 1089 } 990 1090 } elseif ( is_array( $schema[ $key ] ) && ! is_array( $tree[ $key ] ) ) { … … 994 1094 995 1095 return $tree; 1096 } 1097 1098 /** 1099 * Checks if the given array is associative. 1100 * 1101 * @since 6.5.0 1102 * @param array $data The array to check. 1103 * @return bool True if the array is associative, false otherwise. 1104 */ 1105 protected static function is_assoc( $data ) { 1106 if ( array() === $data ) { 1107 return false; 1108 } 1109 return array_keys( $data ) !== range( 0, count( $data ) - 1 ); 996 1110 } 997 1111 -
trunk/tests/phpunit/tests/theme/wpThemeJson.php
r57491 r57496 4979 4979 ); 4980 4980 } 4981 4982 /** 4983 * Tests that invalid properties are removed from the theme.json inside indexed arrays as settings.typography.fontFamilies. 4984 * 4985 * @ticket 60360 4986 */ 4987 public function test_sanitize_indexed_arrays() { 4988 $theme_json = new WP_Theme_JSON( 4989 array( 4990 'version' => '2', 4991 'badKey2' => 'I am Evil!', 4992 'settings' => array( 4993 'badKey3' => 'I am Evil!', 4994 'typography' => array( 4995 'badKey4' => 'I am Evil!', 4996 'fontFamilies' => array( 4997 'custom' => array( 4998 array( 4999 'badKey4' => 'I am Evil!', 5000 'name' => 'Arial', 5001 'slug' => 'arial', 5002 'fontFamily' => 'Arial, sans-serif', 5003 ), 5004 ), 5005 'theme' => array( 5006 array( 5007 'badKey5' => 'I am Evil!', 5008 'name' => 'Piazzolla', 5009 'slug' => 'piazzolla', 5010 'fontFamily' => 'Piazzolla', 5011 'fontFace' => array( 5012 array( 5013 'badKey6' => 'I am Evil!', 5014 'fontFamily' => 'Piazzolla', 5015 'fontStyle' => 'italic', 5016 'fontWeight' => '400', 5017 'src' => 'https://example.com/font.ttf', 5018 ), 5019 array( 5020 'badKey7' => 'I am Evil!', 5021 'fontFamily' => 'Piazzolla', 5022 'fontStyle' => 'italic', 5023 'fontWeight' => '400', 5024 'src' => 'https://example.com/font.ttf', 5025 ), 5026 ), 5027 ), 5028 array( 5029 'badKey8' => 'I am Evil!', 5030 'name' => 'Inter', 5031 'slug' => 'Inter', 5032 'fontFamily' => 'Inter', 5033 'fontFace' => array( 5034 array( 5035 'badKey9' => 'I am Evil!', 5036 'fontFamily' => 'Inter', 5037 'fontStyle' => 'italic', 5038 'fontWeight' => '400', 5039 'src' => 'https://example.com/font.ttf', 5040 ), 5041 array( 5042 'badKey10' => 'I am Evil!', 5043 'fontFamily' => 'Inter', 5044 'fontStyle' => 'italic', 5045 'fontWeight' => '400', 5046 'src' => 'https://example.com/font.ttf', 5047 ), 5048 ), 5049 ), 5050 ), 5051 ), 5052 ), 5053 ), 5054 ) 5055 ); 5056 5057 $expected_sanitized = array( 5058 'version' => '2', 5059 'settings' => array( 5060 'typography' => array( 5061 'fontFamilies' => array( 5062 'custom' => array( 5063 array( 5064 'name' => 'Arial', 5065 'slug' => 'arial', 5066 'fontFamily' => 'Arial, sans-serif', 5067 ), 5068 ), 5069 'theme' => array( 5070 array( 5071 'name' => 'Piazzolla', 5072 'slug' => 'piazzolla', 5073 'fontFamily' => 'Piazzolla', 5074 'fontFace' => array( 5075 array( 5076 'fontFamily' => 'Piazzolla', 5077 'fontStyle' => 'italic', 5078 'fontWeight' => '400', 5079 'src' => 'https://example.com/font.ttf', 5080 ), 5081 array( 5082 'fontFamily' => 'Piazzolla', 5083 'fontStyle' => 'italic', 5084 'fontWeight' => '400', 5085 'src' => 'https://example.com/font.ttf', 5086 ), 5087 ), 5088 ), 5089 array( 5090 'name' => 'Inter', 5091 'slug' => 'Inter', 5092 'fontFamily' => 'Inter', 5093 'fontFace' => array( 5094 array( 5095 'fontFamily' => 'Inter', 5096 'fontStyle' => 'italic', 5097 'fontWeight' => '400', 5098 'src' => 'https://example.com/font.ttf', 5099 ), 5100 array( 5101 'fontFamily' => 'Inter', 5102 'fontStyle' => 'italic', 5103 'fontWeight' => '400', 5104 'src' => 'https://example.com/font.ttf', 5105 ), 5106 ), 5107 ), 5108 ), 5109 ), 5110 ), 5111 ), 5112 ); 5113 $sanitized_theme_json = $theme_json->get_raw_data(); 5114 $this->assertSameSetsWithIndex( $expected_sanitized, $sanitized_theme_json, 'Sanitized theme.json does not match' ); 5115 } 4981 5116 }
Note: See TracChangeset
for help on using the changeset viewer.