From b98ac474fd798cf1bc09d70a231a3de44436c631 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Wed, 2 Aug 2023 12:02:51 -0400 Subject: [PATCH 1/9] Add additional keys to valid typography.fontFamily settings. --- lib/class-wp-theme-json-gutenberg.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 8c2857fa89d0c..8623a0fc4b093 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -412,7 +412,30 @@ class WP_Theme_JSON_Gutenberg { 'fluid' => null, 'customFontSize' => null, 'dropCap' => null, - 'fontFamilies' => null, + 'fontFamilies' => array( + array( + 'name' => null, + 'slug' => null, + 'fontFamily' => null, + 'fontFace' => array( + array( + 'ascentOverride' => null, + 'descentOverride' => null, + 'fontDisplay' => null, + 'fontFamily' => null, + 'fontFeatureSettings' => null, + 'fontStyle' => null, + 'fontStretch' => null, + 'fontVariationSettings' => null, + 'fontWeight' => null, + 'lineGapOverride' => null, + 'sizeAdjust' => null, + 'src' => null, + 'unicodeRange' => null, + ), + ), + ), + ), 'fontSizes' => null, 'fontStyle' => null, 'fontWeight' => null, From 2e2589ed7d2736bd5d73396c4dcf387f7109c723 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Fri, 4 Aug 2023 14:56:57 -0400 Subject: [PATCH 2/9] Expand sanitization logic for fontFamilies and fontFaces. --- lib/class-wp-theme-json-gutenberg.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 8623a0fc4b093..abd72bf7dfd88 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -819,6 +819,19 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n $schema['settings'] = static::VALID_SETTINGS; $schema['settings']['blocks'] = $schema_settings_blocks; + // For settings.typography.fontFamilies, make the $schema have all indexes present in the $input. + if ( isset( $input['settings']['typography']['fontFamilies'] )){ + foreach( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ){ + $schema['settings']['typography']['fontFamilies'][$font_family_key] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; + // Do the same for fontFace. + if ( isset( $input['settings']['typography']['fontFamilies'][$font_family_key]['fontFace']) ){ + foreach( $input['settings']['typography']['fontFamilies'][$font_family_key]['fontFace'] as $font_face_key => $value2 ){ + $schema['settings']['typography']['fontFamilies'][$font_family_key]['fontFace'][$font_face_key] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0]; + } + } + } + } + // Remove anything that's not present in the schema. foreach ( array( 'styles', 'settings' ) as $subtree ) { if ( ! isset( $input[ $subtree ] ) ) { From 128566c26e84599b0e2ea3374a4a8c51e88e98e4 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Fri, 4 Aug 2023 15:00:20 -0400 Subject: [PATCH 3/9] Add test for typography sanitization. --- phpunit/class-wp-theme-json-test.php | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 6ccbe2fb1d03b..42f22647b37c5 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -896,6 +896,62 @@ public function test_remove_invalid_element_pseudo_selectors() { $this->assertEqualSetsWithIndex( $expected, $actual ); } + public function test_sanitize_invalid_typography_settings(){ + $theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, + 'settings' => array( + 'typography' => array( + 'fontFamilies' => array( + 'badKey' => 'I am invalid', + array( + 'name' => 'Piazzolla', + 'slug' => 'piazzolla', + 'badKey' => 'I am invalid', + 'fontFamily' => 'Piazzolla', + 'fontFace' => array( + array( + 'anotherKey' => 'I am invalid', + 'fontFamily' => 'Piazzolla', + 'fontStyle' => 'italic', + 'fontWeight' => '400', + 'src' => 'https://example.com/font.ttf', + ), + ), + ), + ), + 'src' => 'https://example.com/font.ttf', + ), + ), + ) + ); + + $sanitized_theme_json = $theme_json->get_data(); + $expected = array( + 'version' => 2, + 'settings' => array( + 'typography' => array( + 'fontFamilies' => array( + array( + 'fontFace' => array( + array( + 'fontFamily' => 'Piazzolla', + 'fontStyle' => 'italic', + 'fontWeight' => '400', + 'src' => 'https://example.com/font.ttf', + ), + ), + 'fontFamily' => 'Piazzolla', + 'name' => 'Piazzolla', + 'slug' => 'piazzolla', + ), + ), + ) + ) + ); + $this->assertSameSetsWithIndex( $expected, $sanitized_theme_json, 'Sanitized theme.json settings do not match.' ); + } + public function test_get_element_class_name_button() { $expected = 'wp-element-button'; $actual = WP_Theme_JSON_Gutenberg::get_element_class_name( 'button' ); From 01a284f81b0244196e7a438626eac6f4832a20e0 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Fri, 4 Aug 2023 15:03:49 -0400 Subject: [PATCH 4/9] Format php. --- lib/class-wp-theme-json-gutenberg.php | 12 ++++++------ phpunit/class-wp-theme-json-test.php | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index abd72bf7dfd88..c11a69b060c15 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -820,13 +820,13 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n $schema['settings']['blocks'] = $schema_settings_blocks; // For settings.typography.fontFamilies, make the $schema have all indexes present in the $input. - if ( isset( $input['settings']['typography']['fontFamilies'] )){ - foreach( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ){ - $schema['settings']['typography']['fontFamilies'][$font_family_key] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; + if ( isset( $input['settings']['typography']['fontFamilies'] ) ) { + foreach ( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ) { + $schema['settings']['typography']['fontFamilies'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; // Do the same for fontFace. - if ( isset( $input['settings']['typography']['fontFamilies'][$font_family_key]['fontFace']) ){ - foreach( $input['settings']['typography']['fontFamilies'][$font_family_key]['fontFace'] as $font_face_key => $value2 ){ - $schema['settings']['typography']['fontFamilies'][$font_family_key]['fontFace'][$font_face_key] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0]; + if ( isset( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] ) ) { + foreach ( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] as $font_face_key => $value2 ) { + $schema['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'][ $font_face_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0]; } } } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 42f22647b37c5..2837182b85633 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -896,7 +896,7 @@ public function test_remove_invalid_element_pseudo_selectors() { $this->assertEqualSetsWithIndex( $expected, $actual ); } - public function test_sanitize_invalid_typography_settings(){ + public function test_sanitize_invalid_typography_settings() { $theme_json = new WP_Theme_JSON_Gutenberg( array( 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA, @@ -907,7 +907,7 @@ public function test_sanitize_invalid_typography_settings(){ array( 'name' => 'Piazzolla', 'slug' => 'piazzolla', - 'badKey' => 'I am invalid', + 'badKey' => 'I am invalid', 'fontFamily' => 'Piazzolla', 'fontFace' => array( array( @@ -920,7 +920,7 @@ public function test_sanitize_invalid_typography_settings(){ ), ), ), - 'src' => 'https://example.com/font.ttf', + 'src' => 'https://example.com/font.ttf', ), ), ) @@ -946,8 +946,8 @@ public function test_sanitize_invalid_typography_settings(){ 'slug' => 'piazzolla', ), ), - ) - ) + ), + ), ); $this->assertSameSetsWithIndex( $expected, $sanitized_theme_json, 'Sanitized theme.json settings do not match.' ); } From 108e6fac5fda585b117577bbff17a513ee9656a3 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Mon, 18 Sep 2023 17:30:38 -0700 Subject: [PATCH 5/9] Fix case where a source is set. --- lib/class-wp-theme-json-gutenberg.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index c11a69b060c15..965e9f545e243 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -819,8 +819,13 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n $schema['settings'] = static::VALID_SETTINGS; $schema['settings']['blocks'] = $schema_settings_blocks; + // For settings.typography.fontFamilies, make the $schema have all indexes present in the $input. if ( isset( $input['settings']['typography']['fontFamilies'] ) ) { + // Do not handle the cases where the sanitization is called before font families are merged, since it will be handled again later. + if ( isset( $input['settings']['typography']['fontFamilies']['theme']) || isset( $input['settings']['typography']['fontFamilies']['custom'] ) ) { + return $output; + } foreach ( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ) { $schema['settings']['typography']['fontFamilies'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; // Do the same for fontFace. From a6502ee9f9a2f9d7763aad18a1a24359ade52b91 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Mon, 18 Sep 2023 17:37:05 -0700 Subject: [PATCH 6/9] Format php. --- lib/class-wp-theme-json-gutenberg.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 965e9f545e243..b9d75816ccc5c 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -819,11 +819,10 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n $schema['settings'] = static::VALID_SETTINGS; $schema['settings']['blocks'] = $schema_settings_blocks; - // For settings.typography.fontFamilies, make the $schema have all indexes present in the $input. if ( isset( $input['settings']['typography']['fontFamilies'] ) ) { // Do not handle the cases where the sanitization is called before font families are merged, since it will be handled again later. - if ( isset( $input['settings']['typography']['fontFamilies']['theme']) || isset( $input['settings']['typography']['fontFamilies']['custom'] ) ) { + if ( isset( $input['settings']['typography']['fontFamilies']['theme'] ) || isset( $input['settings']['typography']['fontFamilies']['custom'] ) ) { return $output; } foreach ( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ) { From 222fa331fc1596cf47e9d5d74e6924e60eb93f06 Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Mon, 2 Oct 2023 13:52:07 -0400 Subject: [PATCH 7/9] Fix bug in flattening function and expand test case. --- lib/class-wp-theme-json-gutenberg.php | 33 +++++++++++++++------------ phpunit/class-wp-theme-json-test.php | 28 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index b9d75816ccc5c..e2d4ccc1c5b12 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -822,15 +822,14 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n // For settings.typography.fontFamilies, make the $schema have all indexes present in the $input. if ( isset( $input['settings']['typography']['fontFamilies'] ) ) { // Do not handle the cases where the sanitization is called before font families are merged, since it will be handled again later. - if ( isset( $input['settings']['typography']['fontFamilies']['theme'] ) || isset( $input['settings']['typography']['fontFamilies']['custom'] ) ) { - return $output; - } - foreach ( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ) { - $schema['settings']['typography']['fontFamilies'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; - // Do the same for fontFace. - if ( isset( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] ) ) { - foreach ( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] as $font_face_key => $value2 ) { - $schema['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'][ $font_face_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0]; + if ( ! isset( $input['settings']['typography']['fontFamilies']['theme'] ) || ! isset( $input['settings']['typography']['fontFamilies']['custom'] ) ) { + foreach ( $input['settings']['typography']['fontFamilies'] as $font_family_key => $value ) { + $schema['settings']['typography']['fontFamilies'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; + // Do the same for fontFace. + if ( isset( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] ) ) { + foreach ( $input['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'] as $font_face_key => $value2 ) { + $schema['settings']['typography']['fontFamilies'][ $font_family_key ]['fontFace'][ $font_face_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0]; + } } } } @@ -3318,16 +3317,20 @@ public function get_data() { $items = array(); if ( isset( $preset['theme'] ) ) { foreach ( $preset['theme'] as $item ) { - $slug = $item['slug']; - unset( $item['slug'] ); - $items[ $slug ] = $item; + if ( is_array( $item ) ){ + $slug = $item['slug']; + unset( $item['slug'] ); + $items[ $slug ] = $item; + } } } if ( isset( $preset['custom'] ) ) { foreach ( $preset['custom'] as $item ) { - $slug = $item['slug']; - unset( $item['slug'] ); - $items[ $slug ] = $item; + if ( is_array( $item ) ){ + $slug = $item['slug']; + unset( $item['slug'] ); + $items[ $slug ] = $item; + } } } $flattened_preset = array(); diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index 2837182b85633..e5cf057de5700 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -904,6 +904,21 @@ public function test_sanitize_invalid_typography_settings() { 'typography' => array( 'fontFamilies' => array( 'badKey' => 'I am invalid', + 'theme' => array( + 'name' => 'Inter', + 'slug' => 'inter', + 'badKey' => 'I am invalid', + 'fontFamily' => 'Inter', + 'fontFace' => array( + array( + 'anotherKey' => 'I am invalid', + 'fontFamily' => 'Inter', + 'fontStyle' => 'normal', + 'fontWeight' => '400', + 'src' => 'https://example.com/inter.ttf', + ), + ), + ), array( 'name' => 'Piazzolla', 'slug' => 'piazzolla', @@ -932,6 +947,19 @@ public function test_sanitize_invalid_typography_settings() { 'settings' => array( 'typography' => array( 'fontFamilies' => array( + array( + 'fontFace' => array( + array( + 'fontFamily' => 'Inter', + 'fontStyle' => 'normal', + 'fontWeight' => '400', + 'src' => 'https://example.com/inter.ttf', + ), + ), + 'fontFamily' => 'Inter', + 'name' => 'Inter', + 'slug' => 'inter', + ), array( 'fontFace' => array( array( From 2493483c56471ac07467191dbb7e05259cbde995 Mon Sep 17 00:00:00 2001 From: Vicente Canales Date: Mon, 2 Oct 2023 14:56:09 -0300 Subject: [PATCH 8/9] Run phpcbf on changes --- lib/class-wp-theme-json-gutenberg.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index e2d4ccc1c5b12..52fa967b9f5eb 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -3317,7 +3317,7 @@ public function get_data() { $items = array(); if ( isset( $preset['theme'] ) ) { foreach ( $preset['theme'] as $item ) { - if ( is_array( $item ) ){ + if ( is_array( $item ) ) { $slug = $item['slug']; unset( $item['slug'] ); $items[ $slug ] = $item; @@ -3326,7 +3326,7 @@ public function get_data() { } if ( isset( $preset['custom'] ) ) { foreach ( $preset['custom'] as $item ) { - if ( is_array( $item ) ){ + if ( is_array( $item ) ) { $slug = $item['slug']; unset( $item['slug'] ); $items[ $slug ] = $item; From 6d8091964dd8ab6fdea3c0259f91c297b50a726b Mon Sep 17 00:00:00 2001 From: Jeff Ong Date: Tue, 14 Nov 2023 15:30:08 -0500 Subject: [PATCH 9/9] Handle case where fontFamilies have an origin e.g. theme or custom. --- lib/class-wp-theme-json-gutenberg.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 52fa967b9f5eb..1e5e8b538f8c7 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -724,7 +724,7 @@ protected static function do_opt_in_into_settings( &$context ) { unset( $context['appearanceTools'] ); } - + /** * Sanitizes the input according to the schemas. * @@ -832,6 +832,19 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n } } } + } else { + foreach ( $input['settings']['typography']['fontFamilies']['theme'] as $font_family_key => $value ) { + $schema['settings']['typography']['fontFamilies']['theme'][ $font_family_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]; + // Do the same for fontFace. + if ( isset( $input['settings']['typography']['fontFamilies']['theme'][ $font_family_key ]['fontFace'] ) ) { + foreach ( $input['settings']['typography']['fontFamilies']['theme'][ $font_family_key ]['fontFace'] as $font_face_key => $value2 ) { + $schema['settings']['typography']['fontFamilies']['theme'][ $font_family_key ]['fontFace'][ $font_face_key ] = static::VALID_SETTINGS['typography']['fontFamilies'][0]['fontFace'][0]; + } + } + } + if ( array_key_exists( 0, $schema['settings']['typography']['fontFamilies'] ) ) { + unset( $schema['settings']['typography']['fontFamilies'][0] ); + } } }