Make WordPress Core


Ignore:
Timestamp:
12/20/2022 03:10:35 PM (17 months ago)
Author:
swissspidy
Message:

I18N: Change how WP_Textdomain_Registry caches translation information.

WP_Textdomain_Registry was introduced in [53874] and later adjusted in [54682] to store text domains and their language directory paths, addressing issues with just-in-time loading of textdomains when using locale switching and load_*_textdomain() functions.

This change improves how the class stores information about all existing MO files on the site, addressing an issue where translations are not loaded after calling switch_to_locale().

Props johnbillion, ocean90, SergeyBiryukov.
Fixes #57116.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/l10n/wpLocaleSwitcher.php

    r54669 r55010  
    2525        unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
    2626
    27         /** @var WP_Textdomain_Registry $wp_textdomain_registry */
    28         global $wp_textdomain_registry;
     27        global $wp_textdomain_registry, $wp_locale_switcher;
    2928
    3029        $wp_textdomain_registry = new WP_Textdomain_Registry();
     30
     31        remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
     32        $wp_locale_switcher = new WP_Locale_Switcher();
     33        $wp_locale_switcher->init();
    3134    }
    3235
     
    3437        unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
    3538
    36         /** @var WP_Textdomain_Registry $wp_textdomain_registry */
    37         global $wp_textdomain_registry;
     39        global $wp_textdomain_registry, $wp_locale_switcher;
    3840
    3941        $wp_textdomain_registry = new WP_Textdomain_Registry();
     42
     43        remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
     44        $wp_locale_switcher = new WP_Locale_Switcher();
     45        $wp_locale_switcher->init();
    4046
    4147        parent::tear_down();
     
    337343        set_current_screen( 'dashboard' );
    338344
    339         $locale_switcher = clone $wp_locale_switcher;
    340 
     345        // Reset $wp_locale_switcher so it thinks es_ES is the original locale.
     346        remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
    341347        $wp_locale_switcher = new WP_Locale_Switcher();
    342348        $wp_locale_switcher->init();
     
    357363
    358364        $language_header_after_restore = $l10n['default']->headers['Language']; // de_DE
    359 
    360         $wp_locale_switcher = $locale_switcher;
    361365
    362366        $this->assertFalse( $locale_switched_user_locale );
     
    389393        set_current_screen( 'dashboard' );
    390394
    391         $locale_switcher = clone $wp_locale_switcher;
    392 
     395        // Reset $wp_locale_switcher so it thinks es_ES is the original locale.
     396        remove_filter( 'locale', array( $wp_locale_switcher, 'filter_locale' ) );
    393397        $wp_locale_switcher = new WP_Locale_Switcher();
    394398        $wp_locale_switcher->init();
     
    409413
    410414        $language_header_after_restore = $l10n['default']->headers['Language']; // de_DE
    411 
    412         $wp_locale_switcher = $locale_switcher;
    413415
    414416        remove_filter( 'locale', array( $this, 'filter_locale' ) );
     
    427429     */
    428430    public function test_multiple_switches_to_site_locale_and_user_locale() {
    429         global $wp_locale_switcher;
    430 
    431431        $site_locale = get_locale();
    432432
     
    441441        set_current_screen( 'dashboard' );
    442442
    443         $locale_switcher = clone $wp_locale_switcher;
    444 
    445         $wp_locale_switcher = new WP_Locale_Switcher();
    446         $wp_locale_switcher->init();
    447 
    448443        $user_locale = get_user_locale();
    449444
     
    458453
    459454        restore_current_locale();
    460 
    461         $wp_locale_switcher = $locale_switcher;
    462455
    463456        $this->assertSame( 'en_US', get_locale() );
     
    470463    public function test_switch_reloads_plugin_translations_outside_wp_lang_dir() {
    471464        /** @var WP_Textdomain_Registry $wp_textdomain_registry */
    472         global $wp_locale_switcher, $wp_textdomain_registry;
    473 
    474         $locale_switcher = clone $wp_locale_switcher;
    475 
    476         $wp_locale_switcher = new WP_Locale_Switcher();
    477         $wp_locale_switcher->init();
     465        global $wp_textdomain_registry;
    478466
    479467        require_once DIR_TESTDATA . '/plugins/custom-internationalized-plugin/custom-internationalized-plugin.php';
     
    494482
    495483        restore_current_locale();
    496 
    497         $wp_locale_switcher = $locale_switcher;
    498484
    499485        $this->assertSame( 'This is a dummy plugin', $actual );
     
    504490
    505491    /**
     492     * @ticket 57116
     493     */
     494    public function test_switch_reloads_plugin_translations() {
     495        /** @var WP_Textdomain_Registry $wp_textdomain_registry */
     496        global $wp_textdomain_registry;
     497
     498        $has_translations_1 = $wp_textdomain_registry->has( 'internationalized-plugin' );
     499
     500        require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
     501
     502        $actual = i18n_plugin_test();
     503
     504        switch_to_locale( 'es_ES' );
     505
     506        $lang_path_es_es = $wp_textdomain_registry->get( 'internationalized-plugin', determine_locale() );
     507
     508        switch_to_locale( 'de_DE' );
     509
     510        $actual_de_de = i18n_plugin_test();
     511
     512        $has_translations_3 = $wp_textdomain_registry->has( 'internationalized-plugin' );
     513
     514        restore_previous_locale();
     515
     516        $actual_es_es = i18n_plugin_test();
     517
     518        restore_current_locale();
     519
     520        $lang_path_en_us = $wp_textdomain_registry->get( 'internationalized-plugin', determine_locale() );
     521
     522        $this->assertSame( 'This is a dummy plugin', $actual );
     523        $this->assertSame( 'Das ist ein Dummy Plugin', $actual_de_de );
     524        $this->assertSame( 'Este es un plugin dummy', $actual_es_es );
     525        $this->assertTrue( $has_translations_1 );
     526        $this->assertTrue( $has_translations_3 );
     527        $this->assertSame( WP_LANG_DIR . '/plugins/', $lang_path_es_es );
     528        $this->assertFalse( $lang_path_en_us );
     529    }
     530
     531    /**
    506532     * @ticket 39210
    507533     */
    508534    public function test_switch_reloads_theme_translations_outside_wp_lang_dir() {
    509535        /** @var WP_Textdomain_Registry $wp_textdomain_registry */
    510         global $wp_locale_switcher, $wp_textdomain_registry;
    511 
    512         $locale_switcher = clone $wp_locale_switcher;
    513 
    514         $wp_locale_switcher = new WP_Locale_Switcher();
    515         $wp_locale_switcher->init();
     536        global $wp_textdomain_registry;
    516537
    517538        switch_theme( 'custom-internationalized-theme' );
     
    534555
    535556        restore_current_locale();
    536 
    537         $wp_locale_switcher = $locale_switcher;
    538557
    539558        $this->assertSame( get_template_directory() . '/languages/', $registry_value );
     
    543562    }
    544563
     564    /**
     565     * @ticket 57116
     566     */
     567    public function test_switch_to_locale_should_work() {
     568        global $wp_textdomain_registry;
     569        require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
     570
     571        $has_translations = $wp_textdomain_registry->has( 'internationalized-plugin' );
     572        $path             = $wp_textdomain_registry->get( 'internationalized-plugin', 'es_ES' );
     573
     574        $actual = i18n_plugin_test();
     575
     576        switch_to_locale( 'es_ES' );
     577
     578        $actual_es_es = i18n_plugin_test();
     579
     580        $this->assertTrue( $has_translations );
     581        $this->assertNotEmpty( $path );
     582        $this->assertSame( 'This is a dummy plugin', $actual );
     583        $this->assertSame( 'Este es un plugin dummy', $actual_es_es );
     584    }
     585
    545586    public function filter_locale() {
    546587        return 'es_ES';
Note: See TracChangeset for help on using the changeset viewer.