Make WordPress Core


Ignore:
Timestamp:
01/15/2024 07:03:27 PM (2 years ago)
Author:
swissspidy
Message:

I18N: Cache list of language file paths in WP_Textdomain_Registry.

Loading a list of language file paths using glob() can be expensive if involving thousands of files.

Expands scope of WP_Textdomain_Registry to cache list of language file paths in object cache and provides a way to invalidate that cache upon translation updates. Plugins can clear the cache using calls such as wp_cache_delete( 'cached_mo_files_' . md5( $path ), 'translations' );

Props mreishus, swissspidy
Fixes #58919

File:
1 edited

Legend:

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

    r55010 r57287  
    1919    }
    2020
     21    public function tear_down() {
     22        wp_cache_delete( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/foobar/' ), 'translations' );
     23        wp_cache_delete( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/plugins/' ), 'translations' );
     24        wp_cache_delete( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/themes/' ), 'translations' );
     25        wp_cache_delete( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) ), 'translations' );
     26
     27        parent::tear_down();
     28    }
     29
    2130    /**
    2231     * @covers ::has
     
    2534     */
    2635    public function test_set_custom_path() {
    27         $reflection          = new ReflectionClass( $this->instance );
    28         $reflection_property = $reflection->getProperty( 'cached_mo_files' );
    29         $reflection_property->setAccessible( true );
    30 
    31         $this->assertEmpty(
    32             $reflection_property->getValue( $this->instance ),
    33             'Cache not empty by default'
    34         );
    35 
    3636        $this->instance->set_custom_path( 'foo', WP_LANG_DIR . '/bar' );
    3737
     
    4949            'Custom path for textdomain not returned'
    5050        );
    51         $this->assertArrayHasKey(
    52             WP_LANG_DIR . '/bar',
    53             $reflection_property->getValue( $this->instance ),
    54             'Custom path missing from cache'
     51        $this->assertNotFalse(
     52            wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . 'bar/' ), 'translations' ),
     53            'List of files in custom path not cached'
    5554        );
    5655    }
     
    6160     */
    6261    public function test_get( $domain, $locale, $expected ) {
    63         $reflection          = new ReflectionClass( $this->instance );
    64         $reflection_property = $reflection->getProperty( 'cached_mo_files' );
    65         $reflection_property->setAccessible( true );
    66 
    6762        $actual = $this->instance->get( $domain, $locale );
    6863        $this->assertSame(
     
    7065            $actual,
    7166            'Expected languages directory path not matching actual one'
    72         );
    73 
    74         $this->assertArrayHasKey(
    75             WP_LANG_DIR . '/plugins',
    76             $reflection_property->getValue( $this->instance ),
    77             'Default plugins path missing from cache'
    7867        );
    7968    }
     
    9079            $this->instance->get( 'foo-plugin', 'de_DE' )
    9180        );
     81    }
     82
     83    /**
     84     * @covers ::get_language_files_from_path
     85     */
     86    public function test_get_language_files_from_path_caches_results() {
     87        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) . '/foobar/' );
     88        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) . '/plugins/' );
     89        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) . '/themes/' );
     90        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) );
     91
     92        $this->assertNotFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/plugins/' ), 'translations' ) );
     93        $this->assertNotFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/themes/' ), 'translations' ) );
     94        $this->assertNotFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/foobar/' ), 'translations' ) );
     95        $this->assertNotFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) ), 'translations' ) );
     96    }
     97
     98    /**
     99     * @covers ::get_language_files_from_path
     100     */
     101    public function test_get_language_files_from_path_short_circuit() {
     102        add_filter( 'pre_get_language_files_from_path', '__return_empty_array' );
     103        $result = $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) . '/plugins/' );
     104        remove_filter( 'pre_get_language_files_from_path', '__return_empty_array' );
     105
     106        $cache = wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/plugins/' ), 'translations' );
     107
     108        $this->assertEmpty( $result );
     109        $this->assertFalse( $cache );
     110    }
     111
     112    /**
     113     * @covers ::invalidate_mo_files_cache
     114     */
     115    public function test_invalidate_mo_files_cache() {
     116        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) . '/plugins/' );
     117        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) . '/themes/' );
     118        $this->instance->get_language_files_from_path( trailingslashit( WP_LANG_DIR ) );
     119
     120        $this->instance->invalidate_mo_files_cache(
     121            null,
     122            array(
     123                'type'         => 'translation',
     124                'translations' => array(
     125                    (object) array(
     126                        'type'     => 'plugin',
     127                        'slug'     => 'internationalized-plugin',
     128                        'language' => 'de_DE',
     129                        'version'  => '99.9.9',
     130                    ),
     131                    (object) array(
     132                        'type'     => 'theme',
     133                        'slug'     => 'internationalized-theme',
     134                        'language' => 'de_DE',
     135                        'version'  => '99.9.9',
     136                    ),
     137                    (object) array(
     138                        'type'     => 'core',
     139                        'slug'     => 'default',
     140                        'language' => 'es_ES',
     141                        'version'  => '99.9.9',
     142                    ),
     143                ),
     144            )
     145        );
     146
     147        $this->assertFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/plugins/' ), 'translations' ) );
     148        $this->assertFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) . '/themes/' ), 'translations' ) );
     149        $this->assertFalse( wp_cache_get( 'cached_mo_files_' . md5( trailingslashit( WP_LANG_DIR ) ), 'translations' ) );
    92150    }
    93151
Note: See TracChangeset for help on using the changeset viewer.