mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2025-10-16 12:05:38 +00:00
I18N: Fix plural forms parsing in WP_Translation_File.
Ensures the plural expression from the translation file header is correctly parsed. Prevents silent failures in the attempt to create the plural form function. Adds additional tests. Props Chouby. See #59656. git-svn-id: https://develop.svn.wordpress.org/trunk@57518 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
9486dc1bec
commit
5e178ff9c9
@ -207,7 +207,7 @@ abstract class WP_Translation_File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the plural form for a count.
|
* Returns the plural form for a given number.
|
||||||
*
|
*
|
||||||
* @since 6.5.0
|
* @since 6.5.0
|
||||||
*
|
*
|
||||||
@ -219,9 +219,9 @@ abstract class WP_Translation_File {
|
|||||||
$this->parse_file();
|
$this->parse_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case a plural form is specified as a header, but no function included, build one.
|
|
||||||
if ( null === $this->plural_forms && isset( $this->headers['plural-forms'] ) ) {
|
if ( null === $this->plural_forms && isset( $this->headers['plural-forms'] ) ) {
|
||||||
$this->plural_forms = $this->make_plural_form_function( $this->headers['plural-forms'] );
|
$expression = $this->get_plural_expression_from_header( $this->headers['plural-forms'] );
|
||||||
|
$this->plural_forms = $this->make_plural_form_function( $expression );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( is_callable( $this->plural_forms ) ) {
|
if ( is_callable( $this->plural_forms ) ) {
|
||||||
@ -231,6 +231,7 @@ abstract class WP_Translation_File {
|
|||||||
* @var int $result Plural form.
|
* @var int $result Plural form.
|
||||||
*/
|
*/
|
||||||
$result = call_user_func( $this->plural_forms, $number );
|
$result = call_user_func( $this->plural_forms, $number );
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,6 +239,22 @@ abstract class WP_Translation_File {
|
|||||||
return ( 1 === $number ? 0 : 1 );
|
return ( 1 === $number ? 0 : 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the plural forms expression as a tuple.
|
||||||
|
*
|
||||||
|
* @since 6.5.0
|
||||||
|
*
|
||||||
|
* @param string $header Plural-Forms header string.
|
||||||
|
* @return string Plural forms expression.
|
||||||
|
*/
|
||||||
|
protected function get_plural_expression_from_header( $header ) {
|
||||||
|
if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) {
|
||||||
|
return trim( $matches[2] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'n != 1';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a function, which will return the right translation index, according to the
|
* Makes a function, which will return the right translation index, according to the
|
||||||
* plural forms header.
|
* plural forms header.
|
||||||
@ -247,7 +264,7 @@ abstract class WP_Translation_File {
|
|||||||
* @param string $expression Plural form expression.
|
* @param string $expression Plural form expression.
|
||||||
* @return callable(int $num): int Plural forms function.
|
* @return callable(int $num): int Plural forms function.
|
||||||
*/
|
*/
|
||||||
public function make_plural_form_function( string $expression ): callable {
|
protected function make_plural_form_function( string $expression ): callable {
|
||||||
try {
|
try {
|
||||||
$handler = new Plural_Forms( rtrim( $expression, ';' ) );
|
$handler = new Plural_Forms( rtrim( $expression, ';' ) );
|
||||||
return array( $handler, 'get' );
|
return array( $handler, 'get' );
|
||||||
|
|||||||
BIN
tests/phpunit/data/l10n/plural-complex.mo
Normal file
BIN
tests/phpunit/data/l10n/plural-complex.mo
Normal file
Binary file not shown.
2
tests/phpunit/data/l10n/plural-complex.php
Normal file
2
tests/phpunit/data/l10n/plural-complex.php
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?php
|
||||||
|
return ['x-generator'=>'GlotPress/4.0.0-beta.2','translation-revision-date'=>'2024-01-18 05:40:05+0000','plural-forms'=>'nplurals=4; plural=(n % 100 == 1) ? 0 : ((n % 100 == 2) ? 1 : ((n % 100 == 3 || n % 100 == 4) ? 2 : 3));','project-id-version'=>'WordPress - 6.4.x - Development','language'=>'sl_SI','messages'=>['%s update available'=>'%s razpoložljiva posodobitev' . "\0" . '%s razpoložljivi posodobitvi' . "\0" . '%s razpoložljive posodobitve' . "\0" . '%s razpoložljivih posodobitev']];
|
||||||
@ -219,6 +219,52 @@ class WP_Translations_Tests extends WP_UnitTestCase {
|
|||||||
$this->assertTrue( $unload_successful, 'Text domain not successfully unloaded' );
|
$this->assertTrue( $unload_successful, 'Text domain not successfully unloaded' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::translate_plural
|
||||||
|
* @covers WP_Translation_File::get_plural_form
|
||||||
|
*/
|
||||||
|
public function test_translate_plural_complex() {
|
||||||
|
load_textdomain( 'wp-tests-domain', DIR_TESTDATA . '/l10n/plural-complex.mo' );
|
||||||
|
|
||||||
|
$this->assertSame( '%s razpoložljiva posodobitev', _n( '%s update available', '%s updates available', 101, 'wp-tests-domain' ) ); // 1, 101, 201
|
||||||
|
$this->assertSame( '%s razpoložljivi posodobitvi', _n( '%s update available', '%s updates available', 102, 'wp-tests-domain' ) ); // 2, 102, 202
|
||||||
|
$this->assertSame( '%s razpoložljive posodobitve', _n( '%s update available', '%s updates available', 103, 'wp-tests-domain' ) ); // 3, 4, 103
|
||||||
|
$this->assertSame( '%s razpoložljivih posodobitev', _n( '%s update available', '%s updates available', 5, 'wp-tests-domain' ) ); // 0, 5, 6
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::translate_plural
|
||||||
|
* @covers WP_Translation_File::get_plural_form
|
||||||
|
*/
|
||||||
|
public function test_translate_plural_complex_php() {
|
||||||
|
load_textdomain( 'wp-tests-domain', DIR_TESTDATA . '/l10n/plural-complex.php' );
|
||||||
|
|
||||||
|
$this->assertSame( '%s razpoložljiva posodobitev', _n( '%s update available', '%s updates available', 101, 'wp-tests-domain' ) ); // 1, 101, 201
|
||||||
|
$this->assertSame( '%s razpoložljivi posodobitvi', _n( '%s update available', '%s updates available', 102, 'wp-tests-domain' ) ); // 2, 102, 202
|
||||||
|
$this->assertSame( '%s razpoložljive posodobitve', _n( '%s update available', '%s updates available', 103, 'wp-tests-domain' ) ); // 3, 4, 103
|
||||||
|
$this->assertSame( '%s razpoložljivih posodobitev', _n( '%s update available', '%s updates available', 5, 'wp-tests-domain' ) ); // 0, 5, 6
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers WP_Translation_File::get_plural_form
|
||||||
|
*/
|
||||||
|
public function test_get_plural_form() {
|
||||||
|
$moe = WP_Translation_File::create( DIR_TESTDATA . '/l10n/plural-complex.mo' );
|
||||||
|
|
||||||
|
$this->assertSame( 0, $moe->get_plural_form( 1 ) );
|
||||||
|
$this->assertSame( 0, $moe->get_plural_form( 101 ) );
|
||||||
|
$this->assertSame( 0, $moe->get_plural_form( 201 ) );
|
||||||
|
$this->assertSame( 1, $moe->get_plural_form( 2 ) );
|
||||||
|
$this->assertSame( 1, $moe->get_plural_form( 102 ) );
|
||||||
|
$this->assertSame( 1, $moe->get_plural_form( 202 ) );
|
||||||
|
$this->assertSame( 2, $moe->get_plural_form( 3 ) );
|
||||||
|
$this->assertSame( 2, $moe->get_plural_form( 4 ) );
|
||||||
|
$this->assertSame( 2, $moe->get_plural_form( 103 ) );
|
||||||
|
$this->assertSame( 3, $moe->get_plural_form( 0 ) );
|
||||||
|
$this->assertSame( 3, $moe->get_plural_form( 5 ) );
|
||||||
|
$this->assertSame( 3, $moe->get_plural_form( 6 ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers ::translate_plural
|
* @covers ::translate_plural
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user