From 423bb7822f340d409154fc8fadaf613402edb2d1 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 15 Jul 2021 13:11:21 +0200 Subject: [PATCH 01/13] Blocks: Add support for `variations in `block.json` file --- src/wp-includes/blocks.php | 25 ++++++++++++++++-- tests/phpunit/data/blocks/notice/block.json | 7 +++++ .../data/languages/plugins/notice-pl_PL.mo | Bin 986 -> 1131 bytes .../data/languages/plugins/notice-pl_PL.po | 12 +++++++-- tests/phpunit/tests/blocks/register.php | 20 ++++++++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 96b897aeec5f8..e96564db15803 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -191,7 +191,8 @@ function register_block_style_handle( $metadata, $field_name ) { * Registers a block type from the metadata stored in the `block.json` file. * * @since 5.5.0 - * @since 5.9.0 Added support for the `viewScript` field. + * @since 5.7.0 Added support for `textdomain` field and i18n handling for all translatable fields. + * @since 5.9.0 Added support for `variations` and `viewScript` fields. * * @param string $file_or_folder Path to the JSON file with metadata definition for * the block or path to the folder where the `block.json` file is located. @@ -238,6 +239,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $settings = array(); $property_mappings = array( + 'apiVersion' => 'api_version', 'title' => 'title', 'category' => 'category', 'parent' => 'parent', @@ -249,8 +251,8 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 'usesContext' => 'uses_context', 'supports' => 'supports', 'styles' => 'styles', + 'variations' => 'variations', 'example' => 'example', - 'apiVersion' => 'api_version', ); foreach ( $property_mappings as $key => $mapped_key ) { @@ -293,6 +295,25 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { $settings[ $mapped_key ][] = $style; } + break; + case 'variations': + $settings[ $mapped_key ] = array(); + if ( ! is_array( $value ) ) { + continue 2; + } + + foreach ( $value as $variation ) { + if ( ! empty( $variation['title'] ) ) { + // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain + $variation['title'] = translate_with_gettext_context( $variation['title'], 'block variation title', $textdomain ); + } + if ( ! empty( $variation['description'] ) ) { + // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain + $variation['description'] = translate_with_gettext_context( $variation['description'], 'block variation description', $textdomain ); + } + $settings[ $mapped_key ][] = $variation; + } + break; default: $settings[ $mapped_key ] = $value; diff --git a/tests/phpunit/data/blocks/notice/block.json b/tests/phpunit/data/blocks/notice/block.json index 610a96099f90a..a39ad6fa4271b 100644 --- a/tests/phpunit/data/blocks/notice/block.json +++ b/tests/phpunit/data/blocks/notice/block.json @@ -41,6 +41,13 @@ "label": "Other" } ], + "variations": [ + { + "name": "alert", + "title": "Alert", + "description": "Shows alert." + } + ], "example": { "attributes": { "message": "This is a notice!" diff --git a/tests/phpunit/data/languages/plugins/notice-pl_PL.mo b/tests/phpunit/data/languages/plugins/notice-pl_PL.mo index 284872cf6f88ad9f36ae6ac347cd0372d56b5d04..e749899ffd6fac18936ae4a4b9b311a3a0ff057c 100644 GIT binary patch delta 369 zcmcb`{+gryo)F7a1|Z-BVi_P#0b*VtUIWA+@BoNyfcPO03j?tnBLjmdkTwF+l0e!6 zNQ(pMBp@vWq^p3m29WLr($YYB8<743#Fv2B9>_n>%)r0{r1@DG7`Pc2;uvIr43Om- zKpKb`jDQ5l0p>tj0!X_8X^@6EAPqEwfenZ`fEWaTW-+jWSr9Xrplo(1%`$Q82A8Cq z{N!wfvc#gy#FEVXJcX3h;^d;t0uY-eI3vHjSRpYdwWvgo0bOB9W=T#eiz7&Katfm! zueq+Fse+-Am8qe&fzjmojE&63dIpjg;yS(U7nd*l9Q;AUtCgDm3nkfYF=il K9)mv;j{yJ#YD10y delta 223 zcmaFOaf`kFo)F7a1|VPuVi_O~0b*_-?g3&D*a5^gK)e%(g@O1R5Q_pa7b63MB#>4B z(&9kc3P=k9=^!Be4~SEN*dEAFVP;_90n$r=G|1eIK$;Us?*-B<3=C!r$AJu9puia* z4b;QH1jMXB43vZeHXsWq4F~KK?{1iUiBXr=P}k5z!O+6W$V}V7a54{5Bdd{~iJsBs I2~1lV0T28cLI3~& diff --git a/tests/phpunit/data/languages/plugins/notice-pl_PL.po b/tests/phpunit/data/languages/plugins/notice-pl_PL.po index 22ca6ef12914f..2554549829048 100644 --- a/tests/phpunit/data/languages/plugins/notice-pl_PL.po +++ b/tests/phpunit/data/languages/plugins/notice-pl_PL.po @@ -2,12 +2,12 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: 2015-12-31 16:31+0100\n" -"PO-Revision-Date: 2021-01-14 18:26+0100\n" +"PO-Revision-Date: 2021-07-15 12:51+0200\n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.4.2\n" +"X-Generator: Poedit 3.0\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;" @@ -41,3 +41,11 @@ msgstr "Domyślny" msgctxt "block style label" msgid "Other" msgstr "Inny" + +msgctxt "block variation title" +msgid "Alert" +msgstr "Ostrzeżenie" + +msgctxt "block variation description" +msgid "Shows alert." +msgstr "Wyświetla ostrzeżenie." diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php index 8778c95f991f1..9316b1726ae1e 100644 --- a/tests/phpunit/tests/blocks/register.php +++ b/tests/phpunit/tests/blocks/register.php @@ -370,6 +370,16 @@ function test_block_registers_with_metadata_fixture() { ), $result->styles ); + $this->assertSame( + array( + array( + 'name' => 'alert', + 'title' => 'Alert', + 'description' => 'Shows alert.', + ), + ), + $result->variations + ); $this->assertSame( array( 'attributes' => array( @@ -439,6 +449,16 @@ function filter_set_locale_to_polish() { ), $result->styles ); + $this->assertSame( + array( + array( + 'name' => 'alert', + 'title' => 'Ostrzeżenie', + 'description' => 'Wyświetla ostrzeżenie.', + ), + ), + $result->variations + ); } /** From 549caabd6550e37831e8b0b19032a85d2c6ef3aa Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Thu, 15 Jul 2021 13:37:14 +0200 Subject: [PATCH 02/13] Make block variation keywords translatable --- src/wp-includes/blocks.php | 9 +++++++++ tests/phpunit/data/blocks/notice/block.json | 7 ++++--- .../data/languages/plugins/notice-pl_PL.mo | Bin 1131 -> 1181 bytes .../data/languages/plugins/notice-pl_PL.po | 14 +++++++++----- tests/phpunit/tests/blocks/register.php | 14 ++++++++------ 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index e96564db15803..5af7861367ae8 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -311,6 +311,15 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain $variation['description'] = translate_with_gettext_context( $variation['description'], 'block variation description', $textdomain ); } + if ( ! empty( $variation['keywords'] ) && is_array( $variation['keywords'] ) ) { + $keywords = array(); + foreach ( $variation['keywords'] as $keyword ) { + // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain + $keywords[] = translate_with_gettext_context( $keyword, 'block variation keyword', $textdomain ); + } + $variation['keywords'] = $keywords; + } + $settings[ $mapped_key ][] = $variation; } diff --git a/tests/phpunit/data/blocks/notice/block.json b/tests/phpunit/data/blocks/notice/block.json index a39ad6fa4271b..d448a49c5c8dd 100644 --- a/tests/phpunit/data/blocks/notice/block.json +++ b/tests/phpunit/data/blocks/notice/block.json @@ -43,9 +43,10 @@ ], "variations": [ { - "name": "alert", - "title": "Alert", - "description": "Shows alert." + "name": "error", + "title": "Error", + "description": "Shows error.", + "keywords": [ "failure" ] } ], "example": { diff --git a/tests/phpunit/data/languages/plugins/notice-pl_PL.mo b/tests/phpunit/data/languages/plugins/notice-pl_PL.mo index e749899ffd6fac18936ae4a4b9b311a3a0ff057c..439c6786a4c6e3f036645f524c204081628ffd58 100644 GIT binary patch delta 345 zcmZY3u}i~16vy$`cuG@ssYsD3c67>8aS)*p5EuV|u1Rys(a@74wdf)Ug1Cw3*1y8l zQQi9wbad%rccFeSxcSI0pL_4POJ>z^cr&f5XQ66jo8)Ajyb)jD-d0sIL2N4#3p{>4+#R14*goRqgn0)B;zx~1# pxmL&i@YAHSuiA(0gV!)P33k$t+xNRHl7Z0|c4V__%}U~OD!_n>%)r0{r1@DG7`Pc2f*53g43Om- zKpKb`jDQ5l0p>tj0!X_8X^@6EAPqEwfenZ`fEWaTW-+jWSr9XrKWCub{^B^G5SmSpDVDU@WE`BSUtCgD Nm3nkfYF=h40|3&}C&>T+ diff --git a/tests/phpunit/data/languages/plugins/notice-pl_PL.po b/tests/phpunit/data/languages/plugins/notice-pl_PL.po index 2554549829048..2e7448b75853a 100644 --- a/tests/phpunit/data/languages/plugins/notice-pl_PL.po +++ b/tests/phpunit/data/languages/plugins/notice-pl_PL.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: 2015-12-31 16:31+0100\n" -"PO-Revision-Date: 2021-07-15 12:51+0200\n" +"PO-Revision-Date: 2021-07-15 13:36+0200\n" "Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -43,9 +43,13 @@ msgid "Other" msgstr "Inny" msgctxt "block variation title" -msgid "Alert" -msgstr "Ostrzeżenie" +msgid "Error" +msgstr "Błąd" msgctxt "block variation description" -msgid "Shows alert." -msgstr "Wyświetla ostrzeżenie." +msgid "Shows error." +msgstr "Wyświetla błąd." + +msgctxt "block variation keyword" +msgid "failure" +msgstr "niepowodzenie" diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php index 9316b1726ae1e..11184e2a0c149 100644 --- a/tests/phpunit/tests/blocks/register.php +++ b/tests/phpunit/tests/blocks/register.php @@ -373,9 +373,10 @@ function test_block_registers_with_metadata_fixture() { $this->assertSame( array( array( - 'name' => 'alert', - 'title' => 'Alert', - 'description' => 'Shows alert.', + 'name' => 'error', + 'title' => 'Error', + 'description' => 'Shows error.', + 'keywords' => array( 'failure' ), ), ), $result->variations @@ -452,9 +453,10 @@ function filter_set_locale_to_polish() { $this->assertSame( array( array( - 'name' => 'alert', - 'title' => 'Ostrzeżenie', - 'description' => 'Wyświetla ostrzeżenie.', + 'name' => 'error', + 'title' => 'Błąd', + 'description' => 'Wyświetla błąd.', + 'keywords' => array( 'niepowodzenie' ), ), ), $result->variations From b502e46c74fd34af64df5a00504535ac1dcc12e3 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 16 Jul 2021 10:37:47 +0200 Subject: [PATCH 03/13] Introduce translate_setting_using_i18n_schema helper function --- src/wp-includes/blocks.php | 142 +++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 69 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 5af7861367ae8..d958e9ed54f2f 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -187,6 +187,74 @@ function register_block_style_handle( $metadata, $field_name ) { return $result ? $style_handle : false; } +/** + * Gets i18n schema for block's metadata read from `block.json` file. + * + * @since 5.9.0 + * + * @return array The schema for block's metadata. + */ +function get_i18n_block_metadata_schema() { + return array( + 'title' => 'block title', + 'description' => 'block description', + 'keywords' => array( 'block keyword' ), + 'styles' => array( + (object) array( + 'label' => 'block style label', + ), + ), + 'variations' => array( + (object) array( + 'title' => 'block variation title', + 'description' => 'block variation description', + 'keywords' => array( 'block variation keyword' ), + ), + ), + ); +} + +/** + * Translates the provided setting value using its i18n schema. + * + * @since 5.9.0 + * + * @param string|string[]|array[] $i18n_schema I18n schema for the setting. + * @param string|string[]|array[] $setting_value Value for the setting. + * @param string $textdomain Textdomain to use with translations. + * + * @return string|string[]|array[] Translated setting. + */ +function translate_setting_using_i18n_schema( $i18n_schema, $setting_value, $textdomain ) { + if ( empty( $i18n_schema ) || empty( $setting_value ) ) { + return $setting_value; + } + + if ( is_string( $i18n_schema ) && is_string( $setting_value ) ) { + // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain + return translate_with_gettext_context( $setting_value, $i18n_schema, $textdomain ); + } + if ( is_array( $i18n_schema ) && is_array( $setting_value ) ) { + $translated_settings = array(); + foreach ( $setting_value as $value ) { + $translated_settings[] = translate_setting_using_i18n_schema( $i18n_schema[0], $value, $textdomain ); + } + return $translated_settings; + } + if ( is_object( $i18n_schema ) && is_array( $setting_value ) ) { + $translated_settings = array(); + foreach ( $setting_value as $key => $value ) { + if ( ! isset( $i18n_schema->$key ) ) { + $translated_settings[ $key ] = $value; + continue; + } + $translated_settings[ $key ] = translate_setting_using_i18n_schema( $i18n_schema->$key, $value, $textdomain ); + } + return $translated_settings; + } + return $setting_value; +} + /** * Registers a block type from the metadata stored in the `block.json` file. * @@ -254,78 +322,14 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 'variations' => 'variations', 'example' => 'example', ); + $textdomain = ! empty( $metadata['textdomain'] ) ? $metadata['textdomain'] : null; + $i18n_schema = get_i18n_block_metadata_schema(); foreach ( $property_mappings as $key => $mapped_key ) { if ( isset( $metadata[ $key ] ) ) { - $value = $metadata[ $key ]; - if ( empty( $metadata['textdomain'] ) ) { - $settings[ $mapped_key ] = $value; - continue; - } - $textdomain = $metadata['textdomain']; - switch ( $key ) { - case 'title': - case 'description': - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain - $settings[ $mapped_key ] = translate_with_gettext_context( $value, sprintf( 'block %s', $key ), $textdomain ); - break; - case 'keywords': - $settings[ $mapped_key ] = array(); - if ( ! is_array( $value ) ) { - continue 2; - } - - foreach ( $value as $keyword ) { - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain - $settings[ $mapped_key ][] = translate_with_gettext_context( $keyword, 'block keyword', $textdomain ); - } - - break; - case 'styles': - $settings[ $mapped_key ] = array(); - if ( ! is_array( $value ) ) { - continue 2; - } - - foreach ( $value as $style ) { - if ( ! empty( $style['label'] ) ) { - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain - $style['label'] = translate_with_gettext_context( $style['label'], 'block style label', $textdomain ); - } - $settings[ $mapped_key ][] = $style; - } - - break; - case 'variations': - $settings[ $mapped_key ] = array(); - if ( ! is_array( $value ) ) { - continue 2; - } - - foreach ( $value as $variation ) { - if ( ! empty( $variation['title'] ) ) { - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain - $variation['title'] = translate_with_gettext_context( $variation['title'], 'block variation title', $textdomain ); - } - if ( ! empty( $variation['description'] ) ) { - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain - $variation['description'] = translate_with_gettext_context( $variation['description'], 'block variation description', $textdomain ); - } - if ( ! empty( $variation['keywords'] ) && is_array( $variation['keywords'] ) ) { - $keywords = array(); - foreach ( $variation['keywords'] as $keyword ) { - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain - $keywords[] = translate_with_gettext_context( $keyword, 'block variation keyword', $textdomain ); - } - $variation['keywords'] = $keywords; - } - - $settings[ $mapped_key ][] = $variation; - } - - break; - default: - $settings[ $mapped_key ] = $value; + $settings[ $mapped_key ] = $metadata[ $key ]; + if ( $textdomain && isset( $i18n_schema[ $key ] ) ) { + $settings[ $mapped_key ] = translate_setting_using_i18n_schema( $i18n_schema[ $key ], $settings[ $key ], $textdomain ); } } } From 6d487f5895469f2ea575661a4a49e1426a6fdadb Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 20 Jul 2021 18:30:15 +0200 Subject: [PATCH 04/13] Introduce wp_json_file_decode helper method --- src/wp-includes/block-i18n.json | 17 ++++++++++ src/wp-includes/blocks.php | 30 ++++++---------- .../class-wp-theme-json-resolver.php | 12 +------ src/wp-includes/functions.php | 34 +++++++++++++++++++ tests/phpunit/tests/functions.php | 25 ++++++++++++++ 5 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 src/wp-includes/block-i18n.json diff --git a/src/wp-includes/block-i18n.json b/src/wp-includes/block-i18n.json new file mode 100644 index 0000000000000..3d31f78592eaa --- /dev/null +++ b/src/wp-includes/block-i18n.json @@ -0,0 +1,17 @@ +{ + "title": "block title", + "description": "block description", + "keywords": [ "block keyword" ], + "styles": [ + { + "label": "block style label" + } + ], + "variations": [ + { + "title": "block variation title", + "description": "block variation description", + "keywords": [ "block variation keyword" ] + } + ] +} diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index d958e9ed54f2f..5614f157fff75 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -195,23 +195,13 @@ function register_block_style_handle( $metadata, $field_name ) { * @return array The schema for block's metadata. */ function get_i18n_block_metadata_schema() { - return array( - 'title' => 'block title', - 'description' => 'block description', - 'keywords' => array( 'block keyword' ), - 'styles' => array( - (object) array( - 'label' => 'block style label', - ), - ), - 'variations' => array( - (object) array( - 'title' => 'block variation title', - 'description' => 'block variation description', - 'keywords' => array( 'block variation keyword' ), - ), - ), - ); + static $i18n_block_schema; + + if ( ! isset( $i18n_block_schema ) ) { + $i18n_block_schema = wp_json_file_decode( __DIR__ . '/block-i18n.json' ); + } + + return $i18n_block_schema; } /** @@ -278,7 +268,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { return false; } - $metadata = json_decode( file_get_contents( $metadata_file ), true ); + $metadata = wp_json_file_decode( $metadata_file, array( 'associative' => true ) ); if ( ! is_array( $metadata ) || empty( $metadata['name'] ) ) { return false; } @@ -328,8 +318,8 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { foreach ( $property_mappings as $key => $mapped_key ) { if ( isset( $metadata[ $key ] ) ) { $settings[ $mapped_key ] = $metadata[ $key ]; - if ( $textdomain && isset( $i18n_schema[ $key ] ) ) { - $settings[ $mapped_key ] = translate_setting_using_i18n_schema( $i18n_schema[ $key ], $settings[ $key ], $textdomain ); + if ( $textdomain && isset( $i18n_schema->$key ) ) { + $settings[ $mapped_key ] = translate_setting_using_i18n_schema( $i18n_schema->$key, $settings[ $key ], $textdomain ); } } } diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 39354106f2506..9376d78d8e9d0 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -59,17 +59,7 @@ class WP_Theme_JSON_Resolver { private static function read_json_file( $file_path ) { $config = array(); if ( $file_path ) { - $decoded_file = json_decode( - file_get_contents( $file_path ), - true - ); - - $json_decoding_error = json_last_error(); - if ( JSON_ERROR_NONE !== $json_decoding_error ) { - trigger_error( "Error when decoding a theme.json schema at path $file_path " . json_last_error_msg() ); - return $config; - } - + $decoded_file = wp_json_file_decode( $file_path, array( 'associative' => true ) ); if ( is_array( $decoded_file ) ) { $config = $decoded_file; } diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 2b75cfea034cd..72faee2d94f6f 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -4267,6 +4267,40 @@ function wp_check_jsonp_callback( $callback ) { return 0 === $illegal_char_count; } +/** + * Reads and decodes a JSON file. + * + * @since 5.9.0 + * + * @param string $filename Path to the JSON file. + * @param array $options { + * Optional. Options to be used with `json_decode()`. + * + * @type bool associative Optional. When `true`, JSON objects will be returned as associative arrays. + * When `false`, JSON objects will be returned as objects. + * } + * + * @return mixed Returns the value encoded in JSON in appropriate PHP type. + * `null` is returned if the file is not found, or its content can't be decoded. + */ +function wp_json_file_decode( $filename, $options = array() ) { + $result = null; + if ( ! file_exists( $filename ) ) { + trigger_error( "File $filename doesn't exist!" ); + return $result; + } + + $options = wp_parse_args( $options, array( 'associative' => false ) ); + $decoded_file = json_decode( file_get_contents( $filename ), $options['associative'] ); + + if ( JSON_ERROR_NONE !== json_last_error() ) { + trigger_error( "Error when decoding a JSON file at path $filename: " . json_last_error_msg() ); + return $result; + } + + return $decoded_file; +} + /** * Retrieve the WordPress home page URL. * diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index d85ad1af4008c..2c9d6474fbd8a 100644 --- a/tests/phpunit/tests/functions.php +++ b/tests/phpunit/tests/functions.php @@ -1037,6 +1037,31 @@ function test_wp_json_encode_depth() { $this->assertFalse( $json ); } + /** + * @ticket 53238 + */ + function test_wp_json_file_decode() { + $result = wp_json_file_decode( + DIR_TESTDATA . '/blocks/notice/block.json' + ); + + $this->assertInternalType( 'object', $result ); + $this->assertSame( 'tests/notice', $result->name ); + } + + /** + * @ticket 53238 + */ + function test_wp_json_file_decode_associative_array() { + $result = wp_json_file_decode( + DIR_TESTDATA . '/blocks/notice/block.json', + array( 'associative' => true ) + ); + + $this->assertInternalType( 'array', $result ); + $this->assertSame( 'tests/notice', $result['name'] ); + } + /** * @ticket 36054 * @dataProvider datetime_provider From b0241ab9c0bc04932aaacd6ff1b177734cc6165d Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Tue, 27 Jul 2021 18:35:25 +0200 Subject: [PATCH 05/13] Address feedback from code review --- src/wp-includes/blocks.php | 4 ++-- src/wp-includes/functions.php | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 5614f157fff75..b2ba8c6a3a722 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -194,7 +194,7 @@ function register_block_style_handle( $metadata, $field_name ) { * * @return array The schema for block's metadata. */ -function get_i18n_block_metadata_schema() { +function get_block_metadata_i18n_schema() { static $i18n_block_schema; if ( ! isset( $i18n_block_schema ) ) { @@ -313,7 +313,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { 'example' => 'example', ); $textdomain = ! empty( $metadata['textdomain'] ) ? $metadata['textdomain'] : null; - $i18n_schema = get_i18n_block_metadata_schema(); + $i18n_schema = get_block_metadata_i18n_schema(); foreach ( $property_mappings as $key => $mapped_key ) { if ( isset( $metadata[ $key ] ) ) { diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 72faee2d94f6f..33344f31532d3 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -4284,9 +4284,16 @@ function wp_check_jsonp_callback( $callback ) { * `null` is returned if the file is not found, or its content can't be decoded. */ function wp_json_file_decode( $filename, $options = array() ) { - $result = null; + $result = null; + $filename = wp_normalize_path( realpath( $filename ) ); if ( ! file_exists( $filename ) ) { - trigger_error( "File $filename doesn't exist!" ); + trigger_error( + sprintf( + /* translators: %s: Path to the JSON file. */ + __( "File %s doesn't exist!" ), + $filename + ) + ); return $result; } @@ -4294,7 +4301,14 @@ function wp_json_file_decode( $filename, $options = array() ) { $decoded_file = json_decode( file_get_contents( $filename ), $options['associative'] ); if ( JSON_ERROR_NONE !== json_last_error() ) { - trigger_error( "Error when decoding a JSON file at path $filename: " . json_last_error_msg() ); + trigger_error( + sprintf( + /* translators: 1: Path to the JSON file, 2: Error message. */ + __( 'Error when decoding a JSON file at path %1$s: %2$s' ), + $filename, + json_last_error_msg() + ) + ); return $result; } From 3cee73ed4dd06190574e20db65c308edb96f2db0 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 30 Jul 2021 12:57:25 +0200 Subject: [PATCH 06/13] Refactoring for translate_settings_using_i18n_schema --- src/wp-includes/blocks.php | 43 +------------------------------------- src/wp-includes/l10n.php | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index b2ba8c6a3a722..5351ab94aaa4c 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -204,47 +204,6 @@ function get_block_metadata_i18n_schema() { return $i18n_block_schema; } -/** - * Translates the provided setting value using its i18n schema. - * - * @since 5.9.0 - * - * @param string|string[]|array[] $i18n_schema I18n schema for the setting. - * @param string|string[]|array[] $setting_value Value for the setting. - * @param string $textdomain Textdomain to use with translations. - * - * @return string|string[]|array[] Translated setting. - */ -function translate_setting_using_i18n_schema( $i18n_schema, $setting_value, $textdomain ) { - if ( empty( $i18n_schema ) || empty( $setting_value ) ) { - return $setting_value; - } - - if ( is_string( $i18n_schema ) && is_string( $setting_value ) ) { - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain - return translate_with_gettext_context( $setting_value, $i18n_schema, $textdomain ); - } - if ( is_array( $i18n_schema ) && is_array( $setting_value ) ) { - $translated_settings = array(); - foreach ( $setting_value as $value ) { - $translated_settings[] = translate_setting_using_i18n_schema( $i18n_schema[0], $value, $textdomain ); - } - return $translated_settings; - } - if ( is_object( $i18n_schema ) && is_array( $setting_value ) ) { - $translated_settings = array(); - foreach ( $setting_value as $key => $value ) { - if ( ! isset( $i18n_schema->$key ) ) { - $translated_settings[ $key ] = $value; - continue; - } - $translated_settings[ $key ] = translate_setting_using_i18n_schema( $i18n_schema->$key, $value, $textdomain ); - } - return $translated_settings; - } - return $setting_value; -} - /** * Registers a block type from the metadata stored in the `block.json` file. * @@ -319,7 +278,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) { if ( isset( $metadata[ $key ] ) ) { $settings[ $mapped_key ] = $metadata[ $key ]; if ( $textdomain && isset( $i18n_schema->$key ) ) { - $settings[ $mapped_key ] = translate_setting_using_i18n_schema( $i18n_schema->$key, $settings[ $key ], $textdomain ); + $settings[ $mapped_key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $settings[ $key ], $textdomain ); } } } diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index f69a24ffd838a..2ee902bff23b9 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1712,3 +1712,43 @@ function is_locale_switched() { return $wp_locale_switcher->is_switched(); } + +/** + * Translates the provided settings value using its i18n schema. + * + * @since 5.9.0 + * + * @param string|string[]|array[]|object $i18n_schema I18n schema for the setting. + * @param string|string[]|array[] $settings Value for the settings. + * @param string $textdomain Textdomain to use with translations. + * + * @return string|string[]|array[] Translated settings. + */ +function translate_settings_using_i18n_schema( $i18n_schema, $settings, $textdomain ) { + if ( empty( $i18n_schema ) || empty( $settings ) ) { + return $settings; + } + + if ( is_string( $i18n_schema ) && is_string( $settings ) ) { + return translate_with_gettext_context( $settings, $i18n_schema, $textdomain ); + } + if ( is_array( $i18n_schema ) && is_array( $settings ) ) { + $translated_settings = array(); + foreach ( $settings as $value ) { + $translated_settings[] = translate_settings_using_i18n_schema( $i18n_schema[0], $value, $textdomain ); + } + return $translated_settings; + } + if ( is_object( $i18n_schema ) && is_array( $settings ) ) { + $translated_settings = array(); + foreach ( $settings as $key => $value ) { + if ( ! isset( $i18n_schema->$key ) ) { + $translated_settings[ $key ] = $value; + continue; + } + $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $value, $textdomain ); + } + return $translated_settings; + } + return $settings; +} From b3d33bb927067cdb55bc873ff456cd5796c5d094 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 30 Jul 2021 13:27:43 +0200 Subject: [PATCH 07/13] Cover translate_settings_using_i18n_schema with unit test --- src/wp-includes/l10n.php | 2 +- .../l10n/translateSettingsUsingI18nSchema.php | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 2ee902bff23b9..45fa2bd5e01a2 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1725,7 +1725,7 @@ function is_locale_switched() { * @return string|string[]|array[] Translated settings. */ function translate_settings_using_i18n_schema( $i18n_schema, $settings, $textdomain ) { - if ( empty( $i18n_schema ) || empty( $settings ) ) { + if ( empty( $i18n_schema ) || empty( $settings ) || empty( $textdomain ) ) { return $settings; } diff --git a/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php b/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php new file mode 100644 index 0000000000000..4a718b9fb60e1 --- /dev/null +++ b/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php @@ -0,0 +1,66 @@ + 'block title', + 'keywords' => array( 'block keyword' ), + 'variations' => array( + (object) array( + 'title' => 'block variation title', + 'description' => 'block variation description', + 'keywords' => array( 'block variation keyword' ), + ), + ), + ); + $settings = array( + 'title' => 'Notice', + 'keywords' => array( + 'alert', + 'message', + ), + 'variations' => array( + array( + 'title' => 'Error', + 'description' => 'Shows error.', + 'keywords' => array( 'failure' ), + ), + ), + ); + $result = translate_settings_using_i18n_schema( + $i18n_schema, + $settings, + $textdomain + ); + + unload_textdomain( $textdomain ); + remove_filter( 'locale', 'filter_set_locale_to_polish' ); + + $this->assertSame( 'Powiadomienie', $result['title'] ); + $this->assertSameSets( array( 'ostrzeżenie', 'wiadomość' ), $result['keywords'] ); + $this->assertSame( + array( + array( + 'title' => 'Błąd', + 'description' => 'Wyświetla błąd.', + 'keywords' => array( 'niepowodzenie' ), + ), + ), + $result['variations'] + ); + } +} From 109ae1e478ff0f1535f9f9d901e6e42c53c383a5 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 30 Jul 2021 14:02:40 +0200 Subject: [PATCH 08/13] Add handling for group key matcher --- src/wp-includes/l10n.php | 9 ++- .../l10n/translateSettingsUsingI18nSchema.php | 56 ++++++++++++++----- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index 45fa2bd5e01a2..b6bb50dbd23c7 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1740,13 +1740,16 @@ function translate_settings_using_i18n_schema( $i18n_schema, $settings, $textdom return $translated_settings; } if ( is_object( $i18n_schema ) && is_array( $settings ) ) { + $group_key = '*'; $translated_settings = array(); foreach ( $settings as $key => $value ) { - if ( ! isset( $i18n_schema->$key ) ) { + if ( isset( $i18n_schema->$key ) ) { + $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $value, $textdomain ); + } elseif ( isset( $i18n_schema->$group_key ) ) { + $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$group_key, $value, $textdomain ); + } else { $translated_settings[ $key ] = $value; - continue; } - $translated_settings[ $key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $value, $textdomain ); } return $translated_settings; } diff --git a/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php b/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php index 4a718b9fb60e1..bb2c82fe03bcb 100644 --- a/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php +++ b/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php @@ -17,27 +17,42 @@ function filter_set_locale_to_polish() { load_textdomain( $textdomain, WP_LANG_DIR . '/plugins/notice-pl_PL.mo' ); $i18n_schema = (object) array( - 'title' => 'block title', - 'keywords' => array( 'block keyword' ), - 'variations' => array( - (object) array( - 'title' => 'block variation title', - 'description' => 'block variation description', - 'keywords' => array( 'block variation keyword' ), + 'title' => 'block title', + 'keywords' => array( 'block keyword' ), + 'styles' => array( + (object) array( 'label' => 'block style label' ), + ), + 'context' => (object) array( + '*' => (object) array( + 'variations' => array( + (object) array( + 'title' => 'block variation title', + 'description' => 'block variation description', + 'keywords' => array( 'block variation keyword' ), + ), + ), ), ), ); $settings = array( - 'title' => 'Notice', - 'keywords' => array( + 'title' => 'Notice', + 'keywords' => array( 'alert', 'message', ), - 'variations' => array( - array( - 'title' => 'Error', - 'description' => 'Shows error.', - 'keywords' => array( 'failure' ), + 'styles' => array( + array( 'label' => 'Default' ), + array( 'label' => 'Other' ), + ), + 'context' => array( + 'namespace' => array( + 'variations' => array( + array( + 'title' => 'Error', + 'description' => 'Shows error.', + 'keywords' => array( 'failure' ), + ), + ), ), ), ); @@ -52,6 +67,17 @@ function filter_set_locale_to_polish() { $this->assertSame( 'Powiadomienie', $result['title'] ); $this->assertSameSets( array( 'ostrzeżenie', 'wiadomość' ), $result['keywords'] ); + $this->assertSame( + array( + array( + 'label' => 'Domyślny', + ), + array( + 'label' => 'Inny', + ), + ), + $result['styles'] + ); $this->assertSame( array( array( @@ -60,7 +86,7 @@ function filter_set_locale_to_polish() { 'keywords' => array( 'niepowodzenie' ), ), ), - $result['variations'] + $result['context']['namespace']['variations'] ); } } From 3cf04e4dd5fe98dfbe260ff89c2147c2f974c70e Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 30 Jul 2021 14:15:33 +0200 Subject: [PATCH 09/13] Fix function redeclared error --- tests/phpunit/tests/blocks/register.php | 16 +++++++++----- .../l10n/translateSettingsUsingI18nSchema.php | 21 ++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php index 11184e2a0c149..1f3104d09b3a6 100644 --- a/tests/phpunit/tests/blocks/register.php +++ b/tests/phpunit/tests/blocks/register.php @@ -69,6 +69,15 @@ function tear_down() { parent::tear_down(); } + /** + * Returns Polish locale string. + * + * @return string + */ + function filter_set_locale_to_polish() { + return 'pl_PL'; + } + /** * @ticket 45109 */ @@ -418,10 +427,7 @@ function test_block_register_block_type_proxy_for_metadata() { * @ticket 52301 */ function test_block_registers_with_metadata_i18n_support() { - function filter_set_locale_to_polish() { - return 'pl_PL'; - } - add_filter( 'locale', 'filter_set_locale_to_polish' ); + add_filter( 'locale', array( $this, 'filter_set_locale_to_polish' ) ); load_textdomain( 'notice', WP_LANG_DIR . '/plugins/notice-pl_PL.mo' ); $result = register_block_type_from_metadata( @@ -429,7 +435,7 @@ function filter_set_locale_to_polish() { ); unload_textdomain( 'notice' ); - remove_filter( 'locale', 'filter_set_locale_to_polish' ); + remove_filter( 'locale', array( $this, 'filter_set_locale_to_polish' ) ); $this->assertInstanceOf( 'WP_Block_Type', $result ); $this->assertSame( 'tests/notice', $result->name ); diff --git a/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php b/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php index bb2c82fe03bcb..e555e6bb386ba 100644 --- a/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php +++ b/tests/phpunit/tests/l10n/translateSettingsUsingI18nSchema.php @@ -6,14 +6,21 @@ */ class Tests_L10n_TranslateSettingsUsingI18nSchema extends WP_UnitTestCase { /** - * @ticket 53238 - */ + * Returns Polish locale string. + * + * @return string + */ + function filter_set_locale_to_polish() { + return 'pl_PL'; + } + + /** + * @ticket 53238 + */ function test_translate_settings_using_i18n_schema() { $textdomain = 'notice'; - function filter_set_locale_to_polish() { - return 'pl_PL'; - } - add_filter( 'locale', 'filter_set_locale_to_polish' ); + + add_filter( 'locale', array( $this, 'filter_set_locale_to_polish' ) ); load_textdomain( $textdomain, WP_LANG_DIR . '/plugins/notice-pl_PL.mo' ); $i18n_schema = (object) array( @@ -63,7 +70,7 @@ function filter_set_locale_to_polish() { ); unload_textdomain( $textdomain ); - remove_filter( 'locale', 'filter_set_locale_to_polish' ); + remove_filter( 'locale', array( $this, 'filter_set_locale_to_polish' ) ); $this->assertSame( 'Powiadomienie', $result['title'] ); $this->assertSameSets( array( 'ostrzeżenie', 'wiadomość' ), $result['keywords'] ); From 2c424a64ec188ec94c61331835be9f096168c63f Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 30 Jul 2021 14:35:21 +0200 Subject: [PATCH 10/13] Remove obsolete logic for get_fields_to_translate public method --- .../class-wp-theme-json-resolver.php | 143 +----------------- .../tests/theme/wpThemeJsonResolver.php | 47 ------ 2 files changed, 8 insertions(+), 182 deletions(-) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 9376d78d8e9d0..2c4e8a0ca02ae 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -40,12 +40,12 @@ class WP_Theme_JSON_Resolver { private static $theme_has_support = null; /** - * Structure to hold i18n metadata. + * Container to keep loaded i18n schema for `theme.json`. * - * @since 5.8.0 + * @since 5.9.0 * @var array */ - private static $theme_json_i18n = null; + private static $i18n_schema = null; /** * Processes a file that adheres to the theme.json schema @@ -67,66 +67,6 @@ private static function read_json_file( $file_path ) { return $config; } - /** - * Converts a tree as in i18n-theme.json into a linear array - * containing metadata to translate a theme.json file. - * - * For example, given this input: - * - * { - * "settings": { - * "*": { - * "typography": { - * "fontSizes": [ { "name": "Font size name" } ], - * "fontStyles": [ { "name": "Font size name" } ] - * } - * } - * } - * } - * - * will return this output: - * - * [ - * 0 => [ - * 'path' => [ 'settings', '*', 'typography', 'fontSizes' ], - * 'key' => 'name', - * 'context' => 'Font size name' - * ], - * 1 => [ - * 'path' => [ 'settings', '*', 'typography', 'fontStyles' ], - * 'key' => 'name', - * 'context' => 'Font style name' - * ] - * ] - * - * @since 5.8.0 - * - * @param array $i18n_partial A tree that follows the format of i18n-theme.json. - * @param array $current_path Optional. Keeps track of the path as we walk down the given tree. - * Default empty array. - * @return array A linear array containing the paths to translate. - */ - private static function extract_paths_to_translate( $i18n_partial, $current_path = array() ) { - $result = array(); - foreach ( $i18n_partial as $property => $partial_child ) { - if ( is_numeric( $property ) ) { - foreach ( $partial_child as $key => $context ) { - $result[] = array( - 'path' => $current_path, - 'key' => $key, - 'context' => $context, - ); - } - return $result; - } - $result = array_merge( - $result, - self::extract_paths_to_translate( $partial_child, array_merge( $current_path, array( $property ) ) ) - ); - } - return $result; - } - /** * Returns a data structure used in theme.json translation. * @@ -135,35 +75,7 @@ private static function extract_paths_to_translate( $i18n_partial, $current_path * @return array An array of theme.json fields that are translatable and the keys that are translatable. */ public static function get_fields_to_translate() { - if ( null === self::$theme_json_i18n ) { - $file_structure = self::read_json_file( __DIR__ . '/theme-i18n.json' ); - self::$theme_json_i18n = self::extract_paths_to_translate( $file_structure ); - } - return self::$theme_json_i18n; - } - - /** - * Translates a chunk of the loaded theme.json structure. - * - * @since 5.8.0 - * - * @param array $array_to_translate The chunk of theme.json to translate. - * @param string $key The key of the field that contains the string to translate. - * @param string $context The context to apply in the translation call. - * @param string $domain Text domain. Unique identifier for retrieving translated strings. - * @return array Returns the modified $theme_json chunk. - */ - private static function translate_theme_json_chunk( array $array_to_translate, $key, $context, $domain ) { - foreach ( $array_to_translate as $item_key => $item_to_translate ) { - if ( empty( $item_to_translate[ $key ] ) ) { - continue; - } - - // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain - $array_to_translate[ $item_key ][ $key ] = translate_with_gettext_context( $array_to_translate[ $item_key ][ $key ], $context, $domain ); - } - - return $array_to_translate; + return array(); } /** @@ -178,50 +90,12 @@ private static function translate_theme_json_chunk( array $array_to_translate, $ * @return array Returns the modified $theme_json_structure. */ private static function translate( $theme_json, $domain = 'default' ) { - $fields = self::get_fields_to_translate(); - foreach ( $fields as $field ) { - $path = $field['path']; - $key = $field['key']; - $context = $field['context']; - - /* - * We need to process the paths that include '*' separately. - * One example of such a path would be: - * [ 'settings', 'blocks', '*', 'color', 'palette' ] - */ - $nodes_to_iterate = array_keys( $path, '*', true ); - if ( ! empty( $nodes_to_iterate ) ) { - /* - * At the moment, we only need to support one '*' in the path, so take it directly. - * - base will be [ 'settings', 'blocks' ] - * - data will be [ 'color', 'palette' ] - */ - $base_path = array_slice( $path, 0, $nodes_to_iterate[0] ); - $data_path = array_slice( $path, $nodes_to_iterate[0] + 1 ); - $base_tree = _wp_array_get( $theme_json, $base_path, array() ); - foreach ( $base_tree as $node_name => $node_data ) { - $array_to_translate = _wp_array_get( $node_data, $data_path, null ); - if ( is_null( $array_to_translate ) ) { - continue; - } - - // Whole path will be [ 'settings', 'blocks', 'core/paragraph', 'color', 'palette' ]. - $whole_path = array_merge( $base_path, array( $node_name ), $data_path ); - $translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain ); - _wp_array_set( $theme_json, $whole_path, $translated_array ); - } - } else { - $array_to_translate = _wp_array_get( $theme_json, $path, null ); - if ( is_null( $array_to_translate ) ) { - continue; - } - - $translated_array = self::translate_theme_json_chunk( $array_to_translate, $key, $context, $domain ); - _wp_array_set( $theme_json, $path, $translated_array ); - } + if ( null === self::$i18n_schema ) { + $i18n_schema = wp_json_file_decode( __DIR__ . '/theme-i18n.json' ); + self::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema; } - return $theme_json; + return translate_settings_using_i18n_schema( self::$i18n_schema, $theme_json, $domain ); } /** @@ -355,7 +229,6 @@ public static function clean_cached_data() { self::$core = null; self::$theme = null; self::$theme_has_support = null; - self::$theme_json_i18n = null; } } diff --git a/tests/phpunit/tests/theme/wpThemeJsonResolver.php b/tests/phpunit/tests/theme/wpThemeJsonResolver.php index 081cb26234bf8..7e4bd37d54d0a 100644 --- a/tests/phpunit/tests/theme/wpThemeJsonResolver.php +++ b/tests/phpunit/tests/theme/wpThemeJsonResolver.php @@ -44,53 +44,6 @@ public function filter_set_locale_to_polish() { return 'pl_PL'; } - /** - * @ticket 52991 - */ - public function test_fields_are_extracted() { - $actual = WP_Theme_JSON_Resolver::get_fields_to_translate(); - - $expected = array( - array( - 'path' => array( 'settings', 'typography', 'fontSizes' ), - 'key' => 'name', - 'context' => 'Font size name', - ), - array( - 'path' => array( 'settings', 'color', 'palette' ), - 'key' => 'name', - 'context' => 'Color name', - ), - array( - 'path' => array( 'settings', 'color', 'gradients' ), - 'key' => 'name', - 'context' => 'Gradient name', - ), - array( - 'path' => array( 'settings', 'color', 'duotone' ), - 'key' => 'name', - 'context' => 'Duotone name', - ), - array( - 'path' => array( 'settings', 'blocks', '*', 'typography', 'fontSizes' ), - 'key' => 'name', - 'context' => 'Font size name', - ), - array( - 'path' => array( 'settings', 'blocks', '*', 'color', 'palette' ), - 'key' => 'name', - 'context' => 'Color name', - ), - array( - 'path' => array( 'settings', 'blocks', '*', 'color', 'gradients' ), - 'key' => 'name', - 'context' => 'Gradient name', - ), - ); - - $this->assertSame( $expected, $actual ); - } - /** * @ticket 52991 */ From 84781d2832efa54cbe905a4ae15e8c637789a5a4 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Sun, 1 Aug 2021 11:43:14 +0200 Subject: [PATCH 11/13] Mark WP_Theme_JSON_Resolver::get_fields_to_translate as deprecated --- src/wp-includes/class-wp-theme-json-resolver.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/class-wp-theme-json-resolver.php b/src/wp-includes/class-wp-theme-json-resolver.php index 2c4e8a0ca02ae..0e5a92698a728 100644 --- a/src/wp-includes/class-wp-theme-json-resolver.php +++ b/src/wp-includes/class-wp-theme-json-resolver.php @@ -71,10 +71,12 @@ private static function read_json_file( $file_path ) { * Returns a data structure used in theme.json translation. * * @since 5.8.0 + * @deprecated 5.9.0 * * @return array An array of theme.json fields that are translatable and the keys that are translatable. */ public static function get_fields_to_translate() { + _deprecated_function( __METHOD__, '5.9.0' ); return array(); } From 0d0f084bf01f396025a436946ec902170c5c45f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Zi=C3=B3=C5=82kowski?= Date: Mon, 9 Aug 2021 13:51:04 +0200 Subject: [PATCH 12/13] Update src/wp-includes/l10n.php --- src/wp-includes/l10n.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/l10n.php b/src/wp-includes/l10n.php index b6bb50dbd23c7..7699d92b1efc9 100644 --- a/src/wp-includes/l10n.php +++ b/src/wp-includes/l10n.php @@ -1717,6 +1717,7 @@ function is_locale_switched() { * Translates the provided settings value using its i18n schema. * * @since 5.9.0 + * @access private * * @param string|string[]|array[]|object $i18n_schema I18n schema for the setting. * @param string|string[]|array[] $settings Value for the settings. From d11f5dd43cc6e1a501fecddd945c35bc2cc81e43 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Wed, 11 Aug 2021 10:33:50 +0200 Subject: [PATCH 13/13] Update assert internal type methods --- tests/phpunit/tests/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index 2c9d6474fbd8a..4ef24d22a1991 100644 --- a/tests/phpunit/tests/functions.php +++ b/tests/phpunit/tests/functions.php @@ -1045,7 +1045,7 @@ function test_wp_json_file_decode() { DIR_TESTDATA . '/blocks/notice/block.json' ); - $this->assertInternalType( 'object', $result ); + $this->assertIsObject( $result ); $this->assertSame( 'tests/notice', $result->name ); } @@ -1058,7 +1058,7 @@ function test_wp_json_file_decode_associative_array() { array( 'associative' => true ) ); - $this->assertInternalType( 'array', $result ); + $this->assertIsArray( $result ); $this->assertSame( 'tests/notice', $result['name'] ); }