Make WordPress Core


Ignore:
Timestamp:
08/11/2022 12:37:05 PM (20 months ago)
Author:
swissspidy
Message:

I18N: Introduce WP_Textdomain_Registry to store text domains and their language directory paths.

Previously, when using switch_to_locale() all current loaded text domains were unloaded and added to the $l10n_unloaded global. This prevented the just-in-time loading for text domains after a switch. The just-in-time loading was also only possible if the translations were stored in WP_LANG_DIR. Both issues have been fixed.

  • Adds WP_Textdomain_Registry to keep track of the language directory paths for all plugins and themes.
  • Updates all load_*_textdomain() functions to store the path in WP_Textdomain_Registry.
  • Adds $locale parameter to load_textdomain() to specify the locale the translation file is for.
  • Adds $reloadable parameter to unload_textdomain() to define whether a text domain can be loaded just-in-time again. This is used by WP_Locale_Switcher::load_translations().
  • Extends _load_textdomain_just_in_time() to also support text domains of plugins and themes with custom language directories.
  • Fixes the incorrect test_plugin_translation_after_switching_locale_twice() test which should have caught this issue earlier.
  • Adds a new test plugin and theme to test the loading of translations with a custom language directory.
  • Deprecates the now unused and private _get_path_to_translation() and _get_path_to_translation_from_lang_dir() functions.

Previously added in [49236] and reverted in [49236] to investigate concerns which are now addressed here.

Props yoavf, swissspidy, dd32, ocean90.
See #26511.
Fixes #39210.

File:
1 edited

Legend:

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

    r53866 r53874  
    2323        $this->previous_locale = '';
    2424
    25         unset( $GLOBALS['l10n'] );
    26         unset( $GLOBALS['l10n_unloaded'] );
    27         _get_path_to_translation( null, true );
     25        unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
     26
     27        /** @var WP_Textdomain_Registry $wp_textdomain_registry */
     28        global $wp_textdomain_registry;
     29
     30        $wp_textdomain_registry->reset();
    2831    }
    2932
    3033    public function tear_down() {
    31         unset( $GLOBALS['l10n'] );
    32         unset( $GLOBALS['l10n_unloaded'] );
    33         _get_path_to_translation( null, true );
     34        unset( $GLOBALS['l10n'], $GLOBALS['l10n_unloaded'] );
     35
     36        /** @var WP_Textdomain_Registry $wp_textdomain_registry */
     37        global $wp_textdomain_registry;
     38
     39        $wp_textdomain_registry->reset();
    3440
    3541        parent::tear_down();
     
    459465    }
    460466
     467    /**
     468     * @ticket 39210
     469     */
     470    public function test_switch_reloads_plugin_translations_outside_wp_lang_dir() {
     471        /** @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();
     478
     479        require_once DIR_TESTDATA . '/plugins/custom-internationalized-plugin/custom-internationalized-plugin.php';
     480
     481        $registry_value = $wp_textdomain_registry->get( 'custom-internationalized-plugin', determine_locale() );
     482
     483        $actual = custom_i18n_plugin_test();
     484
     485        switch_to_locale( 'es_ES' );
     486        switch_to_locale( 'de_DE' );
     487
     488        $actual_de_de = custom_i18n_plugin_test();
     489
     490        restore_previous_locale();
     491
     492        $actual_es_es = custom_i18n_plugin_test();
     493
     494        restore_current_locale();
     495
     496        $wp_locale_switcher = $locale_switcher;
     497
     498        $this->assertSame( 'This is a dummy plugin', $actual );
     499        $this->assertSame( WP_PLUGIN_DIR . '/custom-internationalized-plugin/languages/', $registry_value );
     500        $this->assertSame( 'Das ist ein Dummy Plugin', $actual_de_de );
     501        $this->assertSame( 'Este es un plugin dummy', $actual_es_es );
     502    }
     503
     504    /**
     505     * @ticket 39210
     506     */
     507    public function test_switch_reloads_theme_translations_outside_wp_lang_dir() {
     508        /** @var WP_Textdomain_Registry $wp_textdomain_registry */
     509        global $wp_locale_switcher, $wp_textdomain_registry;
     510
     511        $locale_switcher = clone $wp_locale_switcher;
     512
     513        $wp_locale_switcher = new WP_Locale_Switcher();
     514        $wp_locale_switcher->init();
     515
     516        switch_theme( 'custom-internationalized-theme' );
     517
     518        require_once get_stylesheet_directory() . '/functions.php';
     519
     520        $registry_value = $wp_textdomain_registry->get( 'custom-internationalized-theme', determine_locale() );
     521
     522        $actual = custom_i18n_theme_test();
     523
     524        switch_to_locale( 'es_ES' );
     525        switch_to_locale( 'de_DE' );
     526
     527        $actual_de_de = custom_i18n_theme_test();
     528
     529        restore_previous_locale();
     530
     531        $actual_es_es = custom_i18n_theme_test();
     532
     533        restore_current_locale();
     534
     535        $wp_locale_switcher = $locale_switcher;
     536
     537        $this->assertSame( get_template_directory() . '/languages/', $registry_value );
     538        $this->assertSame( 'This is a dummy theme', $actual );
     539        $this->assertSame( 'Das ist ein Dummy Theme', $actual_de_de );
     540        $this->assertSame( 'Este es un tema dummy', $actual_es_es );
     541    }
     542
    461543    public function filter_locale() {
    462544        return 'es_ES';
Note: See TracChangeset for help on using the changeset viewer.