Make WordPress Core

Changeset 57518


Ignore:
Timestamp:
02/01/2024 08:57:03 PM (4 weeks ago)
Author:
swissspidy
Message:

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.

Location:
trunk
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/l10n/class-wp-translation-file.php

    r57505 r57518  
    208208
    209209    /**
    210      * Returns the plural form for a count.
     210     * Returns the plural form for a given number.
    211211     *
    212212     * @since 6.5.0
     
    220220        }
    221221
    222         // In case a plural form is specified as a header, but no function included, build one.
    223222        if ( null === $this->plural_forms && isset( $this->headers['plural-forms'] ) ) {
    224             $this->plural_forms = $this->make_plural_form_function( $this->headers['plural-forms'] );
     223            $expression         = $this->get_plural_expression_from_header( $this->headers['plural-forms'] );
     224            $this->plural_forms = $this->make_plural_form_function( $expression );
    225225        }
    226226
     
    232232             */
    233233            $result = call_user_func( $this->plural_forms, $number );
     234
    234235            return $result;
    235236        }
     
    240241
    241242    /**
     243     * Returns the plural forms expression as a tuple.
     244     *
     245     * @since 6.5.0
     246     *
     247     * @param string $header Plural-Forms header string.
     248     * @return string Plural forms expression.
     249     */
     250    protected function get_plural_expression_from_header( $header ) {
     251        if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) {
     252            return trim( $matches[2] );
     253        }
     254
     255        return 'n != 1';
     256    }
     257
     258    /**
    242259     * Makes a function, which will return the right translation index, according to the
    243260     * plural forms header.
     
    248265     * @return callable(int $num): int Plural forms function.
    249266     */
    250     public function make_plural_form_function( string $expression ): callable {
     267    protected function make_plural_form_function( string $expression ): callable {
    251268        try {
    252269            $handler = new Plural_Forms( rtrim( $expression, ';' ) );
  • trunk/tests/phpunit/tests/l10n/wpTranslations.php

    r57513 r57518  
    222222    /**
    223223     * @covers ::translate_plural
     224     * @covers WP_Translation_File::get_plural_form
     225     */
     226    public function test_translate_plural_complex() {
     227        load_textdomain( 'wp-tests-domain', DIR_TESTDATA . '/l10n/plural-complex.mo' );
     228
     229        $this->assertSame( '%s razpoložljiva posodobitev', _n( '%s update available', '%s updates available', 101, 'wp-tests-domain' ) ); // 1, 101, 201
     230        $this->assertSame( '%s razpoložljivi posodobitvi', _n( '%s update available', '%s updates available', 102, 'wp-tests-domain' ) ); // 2, 102, 202
     231        $this->assertSame( '%s razpoložljive posodobitve', _n( '%s update available', '%s updates available', 103, 'wp-tests-domain' ) ); // 3, 4, 103
     232        $this->assertSame( '%s razpoložljivih posodobitev', _n( '%s update available', '%s updates available', 5, 'wp-tests-domain' ) ); // 0, 5, 6
     233    }
     234
     235    /**
     236     * @covers ::translate_plural
     237     * @covers WP_Translation_File::get_plural_form
     238     */
     239    public function test_translate_plural_complex_php() {
     240        load_textdomain( 'wp-tests-domain', DIR_TESTDATA . '/l10n/plural-complex.php' );
     241
     242        $this->assertSame( '%s razpoložljiva posodobitev', _n( '%s update available', '%s updates available', 101, 'wp-tests-domain' ) ); // 1, 101, 201
     243        $this->assertSame( '%s razpoložljivi posodobitvi', _n( '%s update available', '%s updates available', 102, 'wp-tests-domain' ) ); // 2, 102, 202
     244        $this->assertSame( '%s razpoložljive posodobitve', _n( '%s update available', '%s updates available', 103, 'wp-tests-domain' ) ); // 3, 4, 103
     245        $this->assertSame( '%s razpoložljivih posodobitev', _n( '%s update available', '%s updates available', 5, 'wp-tests-domain' ) ); // 0, 5, 6
     246    }
     247
     248    /**
     249     * @covers WP_Translation_File::get_plural_form
     250     */
     251    public function test_get_plural_form() {
     252        $moe = WP_Translation_File::create( DIR_TESTDATA . '/l10n/plural-complex.mo' );
     253
     254        $this->assertSame( 0, $moe->get_plural_form( 1 ) );
     255        $this->assertSame( 0, $moe->get_plural_form( 101 ) );
     256        $this->assertSame( 0, $moe->get_plural_form( 201 ) );
     257        $this->assertSame( 1, $moe->get_plural_form( 2 ) );
     258        $this->assertSame( 1, $moe->get_plural_form( 102 ) );
     259        $this->assertSame( 1, $moe->get_plural_form( 202 ) );
     260        $this->assertSame( 2, $moe->get_plural_form( 3 ) );
     261        $this->assertSame( 2, $moe->get_plural_form( 4 ) );
     262        $this->assertSame( 2, $moe->get_plural_form( 103 ) );
     263        $this->assertSame( 3, $moe->get_plural_form( 0 ) );
     264        $this->assertSame( 3, $moe->get_plural_form( 5 ) );
     265        $this->assertSame( 3, $moe->get_plural_form( 6 ) );
     266    }
     267
     268    /**
     269     * @covers ::translate_plural
    224270     */
    225271    public function test_translate_plural_missing() {
Note: See TracChangeset for help on using the changeset viewer.