WordPress.org

Make WordPress Core

Ticket #26511: 26511.diff

File 26511.diff, 10.9 KB (added by swissspidy, 17 months ago)
  • new file src/wp-includes/class-wp-locale-switcher.php

    diff --git src/wp-includes/class-wp-locale-switcher.php src/wp-includes/class-wp-locale-switcher.php
    new file mode 100644
    index 0000000..d36db2b
    - +  
     1<?php 
     2/** 
     3 * Locale switcher object. 
     4 * 
     5 * @package    WordPress 
     6 * @subpackage i18n 
     7 * @since      4.7.0 
     8 */ 
     9 
     10/** 
     11 * Class for switching locales. 
     12 * 
     13 * @since 4.7.0 
     14 */ 
     15class WP_Locale_Switcher { 
     16        /** 
     17         * Locale stack. 
     18         * 
     19         * @since 4.7.0 
     20         * @var string[] 
     21         */ 
     22        private $locales = array(); 
     23 
     24        /** 
     25         * Original locale. 
     26         * 
     27         * @since 4.7.0 
     28         * @var string 
     29         */ 
     30        private $original_locale; 
     31 
     32        /** 
     33         * Translation objects. 
     34         * 
     35         * @since 4.7.0 
     36         * @var NOOP_Translations[][] 
     37         */ 
     38        private $translations = array(); 
     39 
     40        /** 
     41         * Holds all available languages. 
     42         * @var array An array of language codes (file names without the .mo extension) 
     43         */ 
     44        private $available_languages = array(); 
     45 
     46        /** 
     47         * Constructor. 
     48         * 
     49         * Stores the original locale. 
     50         * 
     51         * @since 4.7.0 
     52         */ 
     53        public function __construct() { 
     54                $this->original_locale = get_locale(); 
     55                $this->available_languages = get_available_languages(); 
     56 
     57                add_filter( 'locale', array( $this, 'filter_locale' ) ); 
     58        } 
     59 
     60        /** 
     61         * Switches the translations according to the given locale. 
     62         * 
     63         * @since 4.7.0 
     64         * 
     65         * @global Mo[]      $l10n      An array of available translations. 
     66         * @global WP_Locale $wp_locale The WordPress date and time locale object. 
     67         * 
     68         * @param string $locale The locale. 
     69         * @return bool True on success, false on failure. 
     70         */ 
     71        public function switch_to_locale( $locale ) { 
     72                global $l10n; 
     73 
     74                $current_locale = get_locale(); 
     75 
     76                if ( $current_locale === $locale ) { 
     77                        return false; 
     78                } 
     79 
     80                if ( ! in_array( $locale, $this->available_languages ) ) { 
     81                        return false; 
     82                } 
     83 
     84                $GLOBALS['wp_locale'] = new WP_Locale(); 
     85 
     86                $this->locales[] = $locale; 
     87 
     88                if ( null === $l10n ) { 
     89                        $l10n = array(); 
     90                } 
     91 
     92                if ( empty( $l10n ) ) { 
     93                        load_default_textdomain(); 
     94                } 
     95 
     96                if ( ! $this->has_translations_for_locale( $current_locale ) ) { 
     97                        foreach ( array_keys( $l10n ) as $textdomain ) { 
     98                                $this->translations[ $current_locale ][ $textdomain ] = get_translations_for_domain( $textdomain ); 
     99                        } 
     100                } 
     101 
     102                if ( $this->has_translations_for_locale( $locale ) ) { 
     103                        foreach ( array_keys( $l10n ) as $textdomain ) { 
     104                                if ( isset( $this->translations[ $locale ][ $textdomain ] ) ) { 
     105                                        $l10n[ $textdomain ] = $this->translations[ $locale ][ $textdomain ]; 
     106                                } 
     107                        } 
     108                } else { 
     109                        /* @var MO $mo */ 
     110                        foreach ( $l10n as $textdomain => $mo ) { 
     111                                if ( 'default' === $textdomain ) { 
     112                                        load_default_textdomain(); 
     113 
     114                                        continue; 
     115                                } 
     116 
     117                                unload_textdomain( $textdomain ); 
     118 
     119                                if ( $mofile = $mo->get_filename() ) { 
     120                                        load_textdomain( $textdomain, $mofile ); 
     121                                } 
     122 
     123                                $this->translations[ $locale ][ $textdomain ] = get_translations_for_domain( $textdomain ); 
     124                        } 
     125                } 
     126 
     127                /** 
     128                 * Fires when the locale is switched. 
     129                 * 
     130                 * @since 4.7.0 
     131                 * 
     132                 * @param string $locale The new locale. 
     133                 */ 
     134                do_action( 'switch_locale', $locale ); 
     135 
     136                return true; 
     137        } 
     138 
     139        /** 
     140         * Restores the translations according to the previous locale. 
     141         * 
     142         * @since 4.7.0 
     143         * 
     144         * @global Mo[]      $l10n      An array of available translations. 
     145         * @global WP_Locale $wp_locale The WordPress date and time locale object. 
     146         * 
     147         * @return string|false Locale on success, false on failure. 
     148         */ 
     149        public function restore_locale() { 
     150                global $l10n; 
     151 
     152                $previous_locale = end( $this->locales ); 
     153 
     154                if ( ! array_pop( $this->locales ) ) { 
     155                        // The stack is empty, bail. 
     156                        return false; 
     157                } 
     158 
     159                if ( null === $l10n ) { 
     160                        $l10n = array(); 
     161                } 
     162 
     163                $locale = end( $this->locales ); 
     164 
     165                if ( ! $locale ) { 
     166                        // There's nothing left in the stack: go back to the original locale. 
     167                        $locale = $this->original_locale; 
     168                } 
     169 
     170                foreach ( array_keys( $l10n ) as $textdomain ) { 
     171                        if ( isset( $this->translations[ $locale ][ $textdomain ] ) ) { 
     172                                $l10n[ $textdomain ] = $this->translations[ $locale ][ $textdomain ]; 
     173                        } 
     174                } 
     175 
     176                $GLOBALS['wp_locale'] = new WP_Locale(); 
     177 
     178                /** 
     179                 * Fires when the locale is restored to the previous one. 
     180                 * 
     181                 * @since 4.7.0 
     182                 * 
     183                 * @param string $locale The new locale. 
     184                 * @param string $previous_locale The previous locale. 
     185                 */ 
     186                do_action( 'restore_locale', $locale, $previous_locale ); 
     187 
     188                return $locale; 
     189        } 
     190 
     191        /** 
     192         * Filters the WordPress install's locale. 
     193         * 
     194         * @param string $locale The WordPress install's locale. 
     195         * @return string The locale currently being switched to. 
     196         */ 
     197        public function filter_locale( $locale ) { 
     198                $switched_locale = end( $this->locales ); 
     199 
     200                if ( $switched_locale ) { 
     201                        return $switched_locale; 
     202                } 
     203 
     204                return $locale; 
     205        } 
     206 
     207        /** 
     208         * Checks if there are cached translations for the given locale. 
     209         * 
     210         * @since 4.7.0 
     211         * 
     212         * @param string $locale The locale. 
     213         * @return bool True if there are cached translations for the given locale, false otherwise. 
     214         */ 
     215        private function has_translations_for_locale( $locale ) { 
     216                return ! empty( $this->translations[ $locale ] ); 
     217        } 
     218} 
  • src/wp-includes/l10n.php

    diff --git src/wp-includes/l10n.php src/wp-includes/l10n.php
    index aaa7611..d253fa6 100644
    function is_rtl() { 
    11481148                return false; 
    11491149        } 
    11501150        return $wp_locale->is_rtl(); 
    1151 } 
    1152  No newline at end of file 
     1151} 
     1152 
     1153/** 
     1154 * Switches the translations according to the given locale. 
     1155 * 
     1156 * @since 4.7.0 
     1157 * 
     1158 * @global WP_Locale_Switcher $wp_locale_switcher 
     1159 * 
     1160 * @param string $locale The locale. 
     1161 * @return bool True on success, false on failure. 
     1162 */ 
     1163function switch_to_locale( $locale ) { 
     1164        /* @var WP_Locale_Switcher $wp_locale_switcher */ 
     1165        global $wp_locale_switcher; 
     1166 
     1167        return $wp_locale_switcher->switch_to_locale( $locale ); 
     1168} 
     1169 
     1170/** 
     1171 * Restores the translations according to the previous locale. 
     1172 * 
     1173 * @since 4.7.0 
     1174 * 
     1175 * @global WP_Locale_Switcher $wp_locale_switcher 
     1176 * 
     1177 * @return string|false Locale on success, false on error. 
     1178 */ 
     1179function restore_locale() { 
     1180        /* @var WP_Locale_Switcher $wp_locale_switcher */ 
     1181        global $wp_locale_switcher; 
     1182 
     1183        return $wp_locale_switcher->restore_locale(); 
     1184} 
  • src/wp-includes/load.php

    diff --git src/wp-includes/load.php src/wp-includes/load.php
    index ae32c7a..6084c00 100644
    function wp_load_translations_early() { 
    868868        require_once ABSPATH . WPINC . '/pomo/mo.php'; 
    869869        require_once ABSPATH . WPINC . '/l10n.php'; 
    870870        require_once ABSPATH . WPINC . '/class-wp-locale.php'; 
     871        require_once ABSPATH . WPINC . '/class-wp-locale-switcher.php'; 
    871872 
    872873        // General libraries 
    873874        require_once ABSPATH . WPINC . '/plugin.php'; 
  • src/wp-includes/pomo/mo.php

    diff --git src/wp-includes/pomo/mo.php src/wp-includes/pomo/mo.php
    index 6bc44d6..6188a7a 100644
    class MO extends Gettext_Translations { 
    1616        var $_nplurals = 2; 
    1717 
    1818        /** 
     19         * Loaded MO file. 
     20         * 
     21         * @since 4.7.0 
     22         * @var string 
     23         */ 
     24        private $filename = ''; 
     25 
     26        /** 
     27         * Returns the loaded MO file. 
     28         * 
     29         * @since 4.7.0 
     30         * 
     31         * @return string The loaded MO file. 
     32         */ 
     33        public function get_filename() { 
     34                return $this->filename; 
     35        } 
     36 
     37        /** 
    1938         * Fills up with the entries from MO file $filename 
    2039         * 
    2140         * @param string $filename MO file to load 
    2241         */ 
    2342        function import_from_file($filename) { 
    24                 $reader = new POMO_FileReader($filename); 
    25                 if (!$reader->is_resource()) 
     43                $reader = new POMO_FileReader( $filename ); 
     44 
     45                if ( ! $reader->is_resource() ) { 
    2646                        return false; 
    27                 return $this->import_from_reader($reader); 
     47                } 
     48 
     49                $this->filename = (string) $filename; 
     50 
     51                return $this->import_from_reader( $reader ); 
    2852        } 
    2953 
    3054        /** 
    class MO extends Gettext_Translations { 
    299323                return $this->_nplurals; 
    300324        } 
    301325} 
    302 endif; 
    303  No newline at end of file 
     326endif; 
  • src/wp-settings.php

    diff --git src/wp-settings.php src/wp-settings.php
    index 80f556c..ccf0396 100644
    if ( SHORTINIT ) 
    131131// Load the L10n library. 
    132132require_once( ABSPATH . WPINC . '/l10n.php' ); 
    133133require_once( ABSPATH . WPINC . '/class-wp-locale.php' ); 
     134require_once( ABSPATH . WPINC . '/class-wp-locale-switcher.php' ); 
    134135 
    135136// Run the installer if WordPress is not installed. 
    136137wp_not_installed(); 
    unset( $locale_file ); 
    384385 */ 
    385386$GLOBALS['wp_locale'] = new WP_Locale(); 
    386387 
     388/** 
     389 * WordPress Locale Switcher object for switching locales. 
     390 * 
     391 * @since 4.7.0 
     392 * 
     393 * @global WP_Locale_Switcher $wp_locale_switcher 
     394 */ 
     395$GLOBALS['wp_locale_switcher'] = new WP_Locale_Switcher(); 
     396 
    387397// Load the functions for the active theme, for both parent and child theme if applicable. 
    388398if ( ! wp_installing() || 'wp-activate.php' === $pagenow ) { 
    389399        if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) 
  • new file tests/phpunit/tests/l10n/localeSwitcher.php

    diff --git tests/phpunit/tests/l10n/localeSwitcher.php tests/phpunit/tests/l10n/localeSwitcher.php
    new file mode 100644
    index 0000000..30fc24d
    - +  
     1<?php 
     2 
     3/** 
     4 * @group l10n 
     5 * @group i18n 
     6 */ 
     7class Tests_Locale_Switcher extends WP_UnitTestCase { 
     8        function test_switch_to_non_existent_locale_returns_false() { 
     9                $this->assertFalse( switch_to_locale( 'de_DE' ) ); 
     10        } 
     11 
     12        function test_switch_to_non_existent_locale_does_not_change_locale() { 
     13                switch_to_locale( 'de_DE' ); 
     14 
     15                $this->assertSame( 'en_US', get_locale() ); 
     16        } 
     17 
     18        function test_switch_to_locale_returns_true() { 
     19                $expected = switch_to_locale( 'en_GB' ); 
     20 
     21                // Cleanup. 
     22                restore_locale(); 
     23 
     24                $this->assertTrue( $expected ); 
     25        } 
     26 
     27        function test_switch_to_locale_changes_the_locale() { 
     28                switch_to_locale( 'en_GB' ); 
     29 
     30                $locale = get_locale(); 
     31 
     32                // Cleanup. 
     33                restore_locale(); 
     34 
     35                $this->assertSame( 'en_GB', $locale ); 
     36        } 
     37 
     38        function test_switch_to_locale_loads_translation() { 
     39                switch_to_locale( 'es_ES' ); 
     40 
     41                $actual = __( 'Invalid parameter.' ); 
     42 
     43                // Cleanup. 
     44                restore_locale(); 
     45 
     46                $this->assertSame( 'Parámetro no válido. ', $actual ); 
     47        } 
     48 
     49        function test_restore_locale_without_switching() { 
     50                $this->assertFalse( restore_locale() ); 
     51        } 
     52 
     53        function test_restore_locale_changes_the_locale_back() { 
     54                switch_to_locale( 'en_GB' ); 
     55 
     56                // Cleanup. 
     57                restore_locale(); 
     58 
     59                $this->assertSame( 'en_US', get_locale() ); 
     60        } 
     61 
     62        function test_switch_to_locale_multiple_times() { 
     63                switch_to_locale( 'en_GB' ); 
     64                switch_to_locale( 'es_ES' ); 
     65                $locale = get_locale(); 
     66 
     67                // Cleanup. 
     68                restore_locale(); 
     69                restore_locale(); 
     70 
     71                $this->assertSame( 'es_ES', $locale ); 
     72        } 
     73 
     74        function test_restore_locale_after_switching_multiple_times() { 
     75                switch_to_locale( 'en_GB' ); 
     76                switch_to_locale( 'es_ES' ); 
     77                restore_locale(); 
     78 
     79                $locale = get_locale(); 
     80 
     81                // Cleanup. 
     82                restore_locale(); 
     83 
     84                $this->assertSame( 'en_GB', $locale ); 
     85        } 
     86 
     87        function test_restore_locale_restores_translation() { 
     88                switch_to_locale( 'es_ES' ); 
     89                restore_locale(); 
     90 
     91                $actual = __( 'Invalid parameter.' ); 
     92 
     93                $this->assertSame( 'Invalid parameter.', $actual ); 
     94        } 
     95}