WordPress.org

Make WordPress Core

Changeset 39330


Ignore:
Timestamp:
11/21/16 16:06:38 (8 months ago)
Author:
ocean90
Message:

I18N: Add an additional caching layer for _load_textdomain_just_in_time().

Previously, if no translation files exist for a text domain, _load_textdomain_just_in_time() went through the entire process each time it was called. This results in an increased call to get_locale() and its locale filter.
This change splits the logic into _get_path_to_translation() and _get_path_to_translation_from_lang_dir(). The former, which is used by _load_textdomain_just_in_time(), caches the result of the latter. It also removes some non-working code from WP_Locale_Switcher::load_translations().

Props jrf, swissspidy, sharkomatic, ocean90.
Fixes #37997.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-locale-switcher.php

    r38961 r39330  
    203203            } 
    204204 
    205             $mofile = $l10n[ $domain ]->get_filename(); 
    206  
    207205            unload_textdomain( $domain ); 
    208  
    209             if ( $mofile ) { 
    210                 load_textdomain( $domain, $mofile ); 
    211             } 
    212  
    213206            get_translations_for_domain( $domain ); 
    214207        } 
     
    229222     */ 
    230223    private function change_locale( $locale ) { 
     224        // Reset translation availability information. 
     225        _get_path_to_translation( null, true ); 
     226 
    231227        $this->load_translations( $locale ); 
    232228 
  • trunk/src/wp-includes/l10n.php

    r39244 r39330  
    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 
     
    843841 
    844842    $l10n_unloaded = (array) $l10n_unloaded; 
    845  
    846     static $cached_mofiles = null; 
    847843 
    848844    // Short-circuit if domain is 'default' which is reserved for core. 
     
    850846        return false; 
    851847    } 
     848 
     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 for loading a textdomain just in time. 
     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 the current locale. 
     887 * 
     888 * Holds a cached list of available .mo files to improve performance. 
     889 * 
     890 * @since 4.7.0 
     891 * @access private 
     892 * 
     893 * @see _get_path_to_translation() 
     894 * 
     895 * @param string $domain Text domain. Unique identifier for retrieving translated strings. 
     896 * @return string|false The path to the translation file or false if no translation file was found. 
     897 */ 
     898function _get_path_to_translation_from_lang_dir( $domain ) { 
     899    static $cached_mofiles = null; 
    852900 
    853901    if ( null === $cached_mofiles ) { 
     
    870918    $mofile = "{$domain}-{$locale}.mo"; 
    871919 
    872     if ( in_array( WP_LANG_DIR . '/plugins/' . $mofile, $cached_mofiles ) ) { 
    873         return load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ); 
    874     } 
    875  
    876     if ( in_array( WP_LANG_DIR . '/themes/' . $mofile, $cached_mofiles ) ) { 
    877         return load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile ); 
     920    $path = WP_LANG_DIR . '/plugins/' . $mofile; 
     921    if ( in_array( $path, $cached_mofiles ) ) { 
     922        return $path; 
     923    } 
     924 
     925    $path = WP_LANG_DIR . '/themes/' . $mofile; 
     926    if ( in_array( $path, $cached_mofiles ) ) { 
     927        return $path; 
    878928    } 
    879929 
  • trunk/tests/phpunit/tests/l10n/loadTextdomainJustInTime.php

    r39127 r39330  
    99    protected $theme_root; 
    1010    protected static $user_id; 
     11    private $locale_count; 
    1112 
    1213    public static function wpSetUpBeforeClass( $factory ) { 
     
    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. 
     
    3234        unset( $GLOBALS['l10n'] ); 
    3335        unset( $GLOBALS['l10n_unloaded'] ); 
     36        _get_path_to_translation( null, true ); 
    3437    } 
    3538 
     
    4346        unset( $GLOBALS['l10n'] ); 
    4447        unset( $GLOBALS['l10n_unloaded'] ); 
     48        _get_path_to_translation( null, true ); 
    4549 
    4650        parent::tearDown(); 
     
    161165 
    162166        $this->assertSame( 'Das ist ein Dummy Plugin', $expected ); 
     167    } 
     168 
     169    /** 
     170     * @ticket 37997 
     171     */ 
     172    public function test_plugin_translation_after_switching_locale_twice() { 
     173        require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php'; 
     174 
     175        switch_to_locale( 'de_DE' ); 
     176        $expected_de_DE = i18n_plugin_test(); 
     177 
     178        switch_to_locale( 'es_ES' ); 
     179        $expected_es_ES = i18n_plugin_test(); 
     180 
     181        restore_current_locale(); 
     182 
     183        $this->assertSame( 'Das ist ein Dummy Plugin', $expected_de_DE ); 
     184        $this->assertSame( 'This is a dummy plugin', $expected_es_ES ); 
    163185    } 
    164186 
     
    213235        $this->assertSame( 'Das ist ein Dummy Theme', $expected ); 
    214236    } 
     237 
     238    /** 
     239     * @ticket 37997 
     240     */ 
     241    public function test_get_locale_is_called_only_once_per_textdomain() { 
     242        $textdomain = 'foo-bar-baz'; 
     243 
     244        add_filter( 'locale', array( $this, '_filter_locale_count' ) ); 
     245 
     246        __( 'Foo', $textdomain ); 
     247        __( 'Bar', $textdomain ); 
     248        __( 'Baz', $textdomain ); 
     249        __( 'Foo Bar', $textdomain ); 
     250        __( 'Foo Bar Baz', $textdomain ); 
     251 
     252        remove_filter( 'locale', array( $this, '_filter_locale_count' ) ); 
     253 
     254        $this->assertFalse( is_textdomain_loaded( $textdomain ) ); 
     255        $this->assertSame( 1, $this->locale_count ); 
     256    } 
     257 
     258    public function _filter_locale_count( $locale ) { 
     259        ++$this->locale_count; 
     260 
     261        return $locale; 
     262    } 
    215263} 
  • trunk/tests/phpunit/tests/l10n/localeSwitcher.php

    r38961 r39330  
    2525        unset( $GLOBALS['l10n'] ); 
    2626        unset( $GLOBALS['l10n_unloaded'] ); 
     27        _get_path_to_translation( null, true ); 
    2728    } 
    2829 
     
    3031        unset( $GLOBALS['l10n'] ); 
    3132        unset( $GLOBALS['l10n_unloaded'] ); 
     33        _get_path_to_translation( null, true ); 
    3234 
    3335        parent::tearDown(); 
Note: See TracChangeset for help on using the changeset viewer.