WordPress.org

Make WordPress Core

Ticket #37997: 37997.3.diff

File 37997.3.diff, 7.1 KB (added by ocean90, 3 years ago)
  • src/wp-includes/class-wp-locale-switcher.php

     
    202202                                continue;
    203203                        }
    204204
     205                        // This loads the same .mo file again??
    205206                        $mofile = $l10n[ $domain ]->get_filename();
    206207
    207208                        unload_textdomain( $domain );
     
    228229         * @param string $locale The locale to change to.
    229230         */
    230231        private function change_locale( $locale ) {
     232                // Reset translation availability information.
     233                _get_path_to_translation( null, true );
     234
    231235                $this->load_translations( $locale );
    232236
    233237                $GLOBALS['wp_locale'] = new WP_Locale();
  • src/wp-includes/l10n.php

     
    827827 * the translation file from `wp-content/languages`, removing the need
    828828 * to call load_plugin_texdomain() or load_theme_texdomain().
    829829 *
    830  * Holds a cached list of available .mo files to improve performance.
    831  *
    832830 * @since 4.6.0
    833831 * @access private
    834832 *
     
    841839function _load_textdomain_just_in_time( $domain ) {
    842840        global $l10n_unloaded;
    843841
    844         $l10n_unloaded = (array) $l10n_unloaded;
     842        $l10n_unloaded    = (array) $l10n_unloaded;
    845843
    846         static $cached_mofiles = null;
    847 
    848844        // Short-circuit if domain is 'default' which is reserved for core.
    849845        if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) {
    850846                return false;
    851847        }
    852848
     849        $translation_path = _get_path_to_translation( $domain );
     850        if ( false === $translation_path ) {
     851                return false;
     852        }
     853
     854        return load_textdomain( $domain, $translation_path );
     855}
     856
     857/**
     858 * Gets the path to a translation file in the `wp-content/languages` directory.
     859 *
     860 * Caches the retrieved results internally.
     861 *
     862 * @since 4.7.0
     863 * @access private
     864 *
     865 * @see _load_textdomain_just_in_time()
     866 *
     867 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
     868 * @param bool   $reset  Whether to reset the internal cache. Used by the switch to locale functionality.
     869 * @return string|false The path to the translation file or false if no translation file was found.
     870 */
     871function _get_path_to_translation( $domain, $reset = false ) {
     872        static $available_translations = array();
     873
     874        if ( true === $reset ) {
     875                $available_translations = array();
     876        }
     877
     878        if ( ! isset( $available_translations[ $domain ] ) ) {
     879                $available_translations[ $domain ] = _get_path_to_translation_from_lang_dir( $domain );
     880        }
     881
     882        return $available_translations[ $domain ];
     883}
     884
     885/**
     886 * Gets the path to a translation file in the languages directory for loading
     887 * a textdomain just in time.
     888 *
     889 * Holds a cached list of available .mo files to improve performance.
     890 *
     891 * @since 4.7.0
     892 * @access private
     893 *
     894 * @see _get_path_to_translation()
     895 *
     896 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
     897 * @return string|false The path to the translation file or false if no translation file was found.
     898 */
     899function _get_path_to_translation_from_lang_dir( $domain ) {
     900        static $cached_mofiles = null;
     901
    853902        if ( null === $cached_mofiles ) {
    854903                $cached_mofiles = array();
    855904
     
    869918        $locale = is_admin() ? get_user_locale() : get_locale();
    870919        $mofile = "{$domain}-{$locale}.mo";
    871920
    872         if ( in_array( WP_LANG_DIR . '/plugins/' . $mofile, $cached_mofiles ) ) {
    873                 return load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile );
     921        $path = WP_LANG_DIR . '/plugins/' . $mofile;
     922        if ( in_array( $path, $cached_mofiles ) ) {
     923                return $path;
    874924        }
    875925
    876         if ( in_array( WP_LANG_DIR . '/themes/' . $mofile, $cached_mofiles ) ) {
    877                 return load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile );
     926        $path = WP_LANG_DIR . '/themes/' . $mofile;
     927        if ( in_array( $path, $cached_mofiles ) ) {
     928                return $path;
    878929        }
    879930
    880931        return false;
  • tests/phpunit/tests/l10n/loadTextdomainJustInTime.php

     
    88        protected $orig_theme_dir;
    99        protected $theme_root;
    1010        protected static $user_id;
     11        private $locale_count;
    1112
    1213        public static function wpSetUpBeforeClass( $factory ) {
    1314                self::$user_id = $factory->user->create( array(
     
    2122
    2223                $this->theme_root = DIR_TESTDATA . '/themedir1';
    2324                $this->orig_theme_dir = $GLOBALS['wp_theme_directories'];
     25                $this->locale_count = 0;
    2426
    2527                // /themes is necessary as theme.php functions assume /themes is the root if there is only one root.
    2628                $GLOBALS['wp_theme_directories'] = array( WP_CONTENT_DIR . '/themes', $this->theme_root );
     
    3133                unset( $GLOBALS['wp_themes'] );
    3234                unset( $GLOBALS['l10n'] );
    3335                unset( $GLOBALS['l10n_unloaded'] );
     36                _get_path_to_translation( null, true );
    3437        }
    3538
    3639        public function tearDown() {
     
    4245                unset( $GLOBALS['wp_themes'] );
    4346                unset( $GLOBALS['l10n'] );
    4447                unset( $GLOBALS['l10n_unloaded'] );
     48                _get_path_to_translation( null, true );
    4549
    4650                parent::tearDown();
    4751        }
     
    212216
    213217                $this->assertSame( 'Das ist ein Dummy Theme', $expected );
    214218        }
     219
     220        /**
     221         * @ticket 37997
     222         */
     223        public function test_get_locale_is_called_only_once_per_textdomain() {
     224                $textdomain = 'foo-bar-baz';
     225
     226                add_filter( 'locale', array( $this, '_filter_locale_count' ) );
     227
     228                __( 'Foo', $textdomain );
     229                __( 'Bar', $textdomain );
     230                __( 'Baz', $textdomain );
     231                __( 'Foo Bar', $textdomain );
     232                __( 'Foo Bar Baz', $textdomain );
     233
     234                remove_filter( 'locale', array( $this, '_filter_locale_count' ) );
     235
     236                $this->assertFalse( is_textdomain_loaded( $textdomain ) );
     237                $this->assertSame( 1, $this->locale_count );
     238        }
     239
     240        public function _filter_locale_count( $locale ) {
     241                ++$this->locale_count;
     242
     243                return $locale;
     244        }
    215245}
  • tests/phpunit/tests/l10n/localeSwitcher.php

     
    2424
    2525                unset( $GLOBALS['l10n'] );
    2626                unset( $GLOBALS['l10n_unloaded'] );
     27                _get_path_to_translation( null, true );
    2728        }
    2829
    2930        public function tearDown() {
    3031                unset( $GLOBALS['l10n'] );
    3132                unset( $GLOBALS['l10n_unloaded'] );
     33                _get_path_to_translation( null, true );
    3234
    3335                parent::tearDown();
    3436        }
     
    383385        public function filter_locale() {
    384386                return 'es_ES';
    385387        }
     388
     389        /**
     390         * @ticket 37997
     391         */
     392        public function test_something() {
     393                require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php';
     394
     395                add_filter( 'locale', array( $this, 'filter_locale_de_DE' ) );
     396
     397                $expected_de_DE = i18n_plugin_test();
     398
     399                switch_to_locale( 'es_ES' );
     400                $expected_es_ES = i18n_plugin_test();
     401                restore_current_locale();
     402
     403                remove_filter( 'locale', array( $this, 'filter_locale_de_DE' ) );
     404
     405                $this->assertSame( 'Das ist ein Dummy Plugin', $expected_de_DE );
     406                $this->assertSame( 'This is a dummy plugin', $expected_es_ES );
     407        }
     408
     409        function filter_locale_de_DE() {
     410                return 'de_DE';
     411        }
    386412}