From 71b8dcb08cf27f0e221a98459b71fcb0374c2379 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 30 Jan 2024 13:59:46 +0000 Subject: [PATCH] I18N: Improve singular lookup of pluralized strings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensures that looking up a singular that is also used as a pluralized string works as expected. This improves compatibility for cases where for example both `__( 'Product' )` and `_n( 'Product', 'Products’, num )` are used in a project, where both will use the same translation for the singular version. Although such usage is not really recommended nor documented, it must continue to work in the new i18n library in order to maintain backward compatibility and maintain expected behavior. See #59656. git-svn-id: https://develop.svn.wordpress.org/trunk@57386 602fd350-edb4-49c9-b593-d223f7449a82 --- .../l10n/class-wp-translation-file.php | 19 +++++++++++++++++- tests/phpunit/data/l10n/example-simple.mo | Bin 373 -> 467 bytes tests/phpunit/data/l10n/example-simple.php | 1 + tests/phpunit/data/l10n/example-simple.po | 5 ++++- .../tests/l10n/wpTranslationsConvert.php | 5 +++++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/l10n/class-wp-translation-file.php b/src/wp-includes/l10n/class-wp-translation-file.php index 93842bec1066b..f920ab1388005 100644 --- a/src/wp-includes/l10n/class-wp-translation-file.php +++ b/src/wp-includes/l10n/class-wp-translation-file.php @@ -203,7 +203,24 @@ public function translate( string $text ) { $this->parse_file(); } - return $this->entries[ $text ] ?? false; + if ( isset( $this->entries[ $text ] ) ) { + return $this->entries[ $text ]; + } + + /* + * Handle cases where a pluralized string is only used as a singular one. + * For example, when both __( 'Product' ) and _n( 'Product', 'Products' ) + * are used, the entry key will have the format "ProductNULProducts". + * Fall back to looking up just "Product" to support this edge case. + */ + foreach( $this->entries as $key => $value ) { + if ( str_starts_with( $key, $text . "\0" ) ) { + $parts = explode( "\0", $value ); + return $parts[0]; + } + } + + return false; } /** diff --git a/tests/phpunit/data/l10n/example-simple.mo b/tests/phpunit/data/l10n/example-simple.mo index 73fb5f21ab3baaece60f8b000a54f947b51bda07..cf39269a46448c3f5b39edb790705caf56af7fee 100644 GIT binary patch delta 215 zcmey$beXySo)F7a1|VPqVi_Rz0b*_-t^r~YSOLTWK)e!&Wr27X5E}yV4It(KVlGAo z27Vwd45YPzv@(zesrLuc57AOsJ j6f2a?5Kxq#Qkq->ql+izOcMZ$WkbcXOHwB@GL`@U)k+%* delta 139 zcmcc2{FSNxo)F7a1|VPsVi_QI0dasJ2SR~qSs*(Xhz)_b8;Ci8crOt11Mx8+)&}Bh zKr8{oOpFW+#z0ycNOJ>ee;_Rhq@#f}LvnszNoqw2OMX#idS+f?jzamwGtH9|7>faI Cq7-TX diff --git a/tests/phpunit/data/l10n/example-simple.php b/tests/phpunit/data/l10n/example-simple.php index e9c2f73ad6705..4eb71d440572b 100644 --- a/tests/phpunit/data/l10n/example-simple.php +++ b/tests/phpunit/data/l10n/example-simple.php @@ -6,5 +6,6 @@ 'contextoriginal with context' => ['translation with context'], 'plural0' . "\0" . 'plural1' => ['translation0', 'translation1'], 'contextplural0 with context' . "\0" . 'plural1 with context' => ['translation0 with context', 'translation1 with context'], + 'Product' . "\0" . 'Products' => 'Produkt' . "\0" . 'Produkte', ], ]; diff --git a/tests/phpunit/data/l10n/example-simple.po b/tests/phpunit/data/l10n/example-simple.po index b40fcda69bda4..9aff39e1210bb 100644 --- a/tests/phpunit/data/l10n/example-simple.po +++ b/tests/phpunit/data/l10n/example-simple.po @@ -20,4 +20,7 @@ msgid_plural "plural1 with context" msgstr[0] "translation0 with context" msgstr[1] "translation1 with context" - +msgid "Product" +msgid_plural "Products" +msgstr[0] "Produkt" +msgstr[1] "Produkte" diff --git a/tests/phpunit/tests/l10n/wpTranslationsConvert.php b/tests/phpunit/tests/l10n/wpTranslationsConvert.php index 8f3aa41c05bb9..ea318eb329284 100644 --- a/tests/phpunit/tests/l10n/wpTranslationsConvert.php +++ b/tests/phpunit/tests/l10n/wpTranslationsConvert.php @@ -173,6 +173,7 @@ public function test_create_invalid_filetype() { * @covers ::translate_plural * @covers ::locate_translation * @covers ::get_files + * @covers WP_Translation_File::translate * * @dataProvider data_simple_example_files * @@ -198,6 +199,10 @@ public function test_simple_translation_files( string $file ) { $this->assertSame( 'translation1 with context', $controller->translate_plural( array( 'plural0 with context', 'plural1 with context' ), 0, 'context', 'unittest' ) ); $this->assertSame( 'translation0 with context', $controller->translate_plural( array( 'plural0 with context', 'plural1 with context' ), 1, 'context', 'unittest' ) ); $this->assertSame( 'translation1 with context', $controller->translate_plural( array( 'plural0 with context', 'plural1 with context' ), 2, 'context', 'unittest' ) ); + + $this->assertSame( 'Produkt', $controller->translate( 'Product', '', 'unittest' ) ); + $this->assertSame( 'Produkt', $controller->translate_plural( array( 'Product', 'Products' ), 1, '', 'unittest' ) ); + $this->assertSame( 'Produkte', $controller->translate_plural( array( 'Product', 'Products' ), 2, '', 'unittest' ) ); } /**