Make WordPress Core

Changeset 57516


Ignore:
Timestamp:
02/01/2024 07:03:55 PM (10 months ago)
Author:
swissspidy
Message:

I18N: Support loading .l10n.php translation files on their own.

Adjusts the translation file lookup in WP_Textdomain_Registry so that just-in-time translation loading
works even if there is only a .l10n.php translation file without a corresponding .mo file.

While language packs continue to contain both file types, this makes it easier to use translations in a project
without having to deal with .mo or .po files.

Props Chrystl.
See #59656.

Location:
trunk
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-textdomain-registry.php

    r57344 r57516  
    151151
    152152    /**
    153      * Retrieves .mo files from the specified path.
     153     * Retrieves translation files from the specified path.
    154154     *
    155155     * Allows early retrieval through the {@see 'pre_get_mo_files_from_path'} filter to optimize
     
    158158     * @since 6.5.0
    159159     *
    160      * @param string $path The directory path to search for .mo files.
    161      * @return array Array of .mo file paths.
     160     * @param string $path The directory path to search for translation files.
     161     * @return array Array of translation file paths. Can contain .mo and .l10n.php files.
    162162     */
    163163    public function get_language_files_from_path( $path ) {
     
    165165
    166166        /**
    167          * Filters the .mo files retrieved from a specified path before the actual lookup.
     167         * Filters the translation files retrieved from a specified path before the actual lookup.
    168168         *
    169169         * Returning a non-null value from the filter will effectively short-circuit
     
    175175         * @since 6.5.0
    176176         *
    177          * @param null|array $mo_files List of .mo files. Default null.
    178          * @param string $path The path from which .mo files are being fetched.
     177         * @param null|array $files List of translation files. Default null.
     178         * @param string $path The path from which translation files are being fetched.
    179179         **/
    180         $mo_files = apply_filters( 'pre_get_language_files_from_path', null, $path );
    181 
    182         if ( null !== $mo_files ) {
    183             return $mo_files;
     180        $files = apply_filters( 'pre_get_language_files_from_path', null, $path );
     181
     182        if ( null !== $files ) {
     183            return $files;
    184184        }
    185185
    186186        $cache_key = 'cached_mo_files_' . md5( $path );
    187         $mo_files  = wp_cache_get( $cache_key, 'translations' );
    188 
    189         if ( false === $mo_files ) {
    190             $mo_files = glob( $path . '*.mo' );
    191             if ( false === $mo_files ) {
    192                 $mo_files = array();
     187        $files     = wp_cache_get( $cache_key, 'translations' );
     188
     189        if ( false === $files ) {
     190            $files = glob( $path . '*.mo' );
     191            if ( false === $files ) {
     192                $files = array();
    193193            }
    194             wp_cache_set( $cache_key, $mo_files, 'translations' );
    195         }
    196 
    197         return $mo_files;
     194
     195            $php_files = glob( $path . '*.l10n.php' );
     196            if ( is_array( $php_files ) ) {
     197                $files = array_merge( $files, $php_files );
     198            }
     199
     200            wp_cache_set( $cache_key, $files, 'translations' );
     201        }
     202
     203        return $files;
    198204    }
    199205
     
    296302            $files = $this->get_language_files_from_path( $location );
    297303
    298             $path = "$location/$domain-$locale.mo";
    299 
    300             foreach ( $files as $mo_path ) {
     304            $mo_path  = "$location/$domain-$locale.mo";
     305            $php_path = "$location/$domain-$locale.l10n.php";
     306
     307            foreach ( $files as $file_path ) {
    301308                if (
    302309                    ! in_array( $domain, $this->domains_with_translations, true ) &&
    303                     str_starts_with( str_replace( "$location/", '', $mo_path ), "$domain-" )
     310                    str_starts_with( str_replace( "$location/", '', $file_path ), "$domain-" )
    304311                ) {
    305312                    $this->domains_with_translations[] = $domain;
    306313                }
    307314
    308                 if ( $mo_path === $path ) {
     315                if ( $file_path === $mo_path || $file_path === $php_path ) {
    309316                    $found_location = rtrim( $location, '/' ) . '/';
    310317                }
  • trunk/src/wp-includes/l10n.php

    r57350 r57516  
    790790    $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );
    791791
    792     if ( ! is_readable( $mofile ) ) {
    793         return false;
    794     }
    795 
    796792    if ( ! $locale ) {
    797793        $locale = determine_locale();
     
    818814    }
    819815
    820     $translation_files = array( $mofile );
     816    $translation_files = array();
     817
    821818    if ( 'mo' !== $preferred_format ) {
    822         array_unshift(
    823             $translation_files,
    824             substr_replace( $mofile, ".l10n.$preferred_format", - strlen( '.mo' ) )
    825         );
    826     }
     819        $translation_files[] = substr_replace( $mofile, ".l10n.$preferred_format", - strlen( '.mo' ) );
     820    }
     821
     822    $translation_files[] = $mofile;
    827823
    828824    foreach ( $translation_files as $file ) {
     
    858854    }
    859855
    860     return true;
     856    return false;
    861857}
    862858
  • trunk/tests/phpunit/tests/l10n/loadTextdomainJustInTime.php

    r57337 r57516  
    5050
    5151        unload_textdomain( 'internationalized-plugin' );
     52        unload_textdomain( 'internationalized-plugin-2' );
    5253        unload_textdomain( 'internationalized-theme' );
    5354
     
    7980        $actual_output               = i18n_plugin_test();
    8081        $is_textdomain_loaded_after  = is_textdomain_loaded( 'internationalized-plugin' );
     82
     83        remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
     84
     85        $this->assertFalse( $is_textdomain_loaded_before );
     86        $this->assertSame( 'Das ist ein Dummy Plugin', $actual_output );
     87        $this->assertTrue( $is_textdomain_loaded_after );
     88    }
     89
     90    /**
     91     * @ticket 59656
     92     *
     93     * @covers ::is_textdomain_loaded
     94     */
     95    public function test_plugin_translation_should_be_translated_with_only_an_l10n_php_file() {
     96        add_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
     97
     98        require_once DIR_TESTDATA . '/plugins/internationalized-plugin-2.php';
     99
     100        $is_textdomain_loaded_before = is_textdomain_loaded( 'internationalized-plugin-2' );
     101        $actual_output               = i18n_plugin_2_test();
     102        $is_textdomain_loaded_after  = is_textdomain_loaded( 'internationalized-plugin-2' );
    81103
    82104        remove_filter( 'locale', array( $this, 'filter_set_locale_to_german' ) );
  • trunk/tests/phpunit/tests/l10n/wpTextdomainRegistry.php

    r57299 r57516  
    152152    public function data_domains_locales() {
    153153        return array(
    154             'Non-existent plugin'            => array(
     154            'Non-existent plugin'                      => array(
    155155                'unknown-plugin',
    156156                'en_US',
    157157                false,
    158158            ),
    159             'Non-existent plugin with de_DE' => array(
     159            'Non-existent plugin with de_DE'           => array(
    160160                'unknown-plugin',
    161161                'de_DE',
    162162                false,
    163163            ),
    164             'Available de_DE translations'   => array(
     164            'Available de_DE translations'             => array(
    165165                'internationalized-plugin',
    166166                'de_DE',
    167167                WP_LANG_DIR . '/plugins/',
    168168            ),
    169             'Available es_ES translations'   => array(
     169            'Available es_ES translations'             => array(
    170170                'internationalized-plugin',
    171171                'es_ES',
    172172                WP_LANG_DIR . '/plugins/',
    173173            ),
    174             'Unavailable fr_FR translations' => array(
     174            'Unavailable fr_FR translations'           => array(
    175175                'internationalized-plugin',
    176176                'fr_FR',
    177177                false,
    178178            ),
    179             'Unavailable en_US translations' => array(
     179            'Unavailable en_US translations'           => array(
    180180                'internationalized-plugin',
    181181                'en_US',
    182182                false,
    183183            ),
     184            'Available de_DE translations (.l10n.php)' => array(
     185                'internationalized-plugin-2',
     186                'de_DE',
     187                WP_LANG_DIR . '/plugins/',
     188            ),
     189            'Available es_ES translations (.l10n.php)' => array(
     190                'internationalized-plugin-2',
     191                'es_ES',
     192                WP_LANG_DIR . '/plugins/',
     193            ),
    184194        );
    185195    }
Note: See TracChangeset for help on using the changeset viewer.