Ticket #26511: 26511.3.diff
File 26511.3.diff, 12.2 KB (added by , 8 years 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..4343733
- + 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 */ 15 class WP_Locale_Switcher { 16 /** 17 * Locale stack. 18 * 19 * @since 4.7.0 20 * @acess private 21 * @var string[] 22 */ 23 private $locales = array(); 24 25 /** 26 * Original locale. 27 * 28 * @since 4.7.0 29 * @access private 30 * @var string 31 */ 32 private $original_locale; 33 34 /** 35 * Translation objects. 36 * 37 * @since 4.7.0 38 * @access private 39 * @var NOOP_Translations[][] 40 */ 41 private $translations = array(); 42 43 /** 44 * Holds all available languages. 45 * 46 * @since 4.7.0 47 * @access private 48 * @var array An array of language codes (file names without the .mo extension) 49 */ 50 private $available_languages = array(); 51 52 /** 53 * Constructor. 54 * 55 * Stores the original locale. 56 * 57 * @since 4.7.0 58 */ 59 public function __construct() { 60 $this->original_locale = get_locale(); 61 $this->available_languages = get_available_languages(); 62 63 add_filter( 'locale', array( $this, 'filter_locale' ) ); 64 } 65 66 /** 67 * Switches the translations according to the given locale. 68 * 69 * @since 4.7.0 70 * 71 * @global Mo[] $l10n An array of available translations. 72 * @global WP_Locale $wp_locale The WordPress date and time locale object. 73 * 74 * @param string $locale The locale to switch to. 75 * @return bool True on success, false on failure. 76 */ 77 public function switch_to_locale( $locale ) { 78 global $l10n; 79 80 $current_locale = get_locale(); 81 82 if ( $locale === $current_locale ) { 83 return false; 84 } 85 86 if ( ! in_array( $locale, $this->available_languages ) ) { 87 return false; 88 } 89 90 $GLOBALS['wp_locale'] = new WP_Locale(); 91 92 $this->locales[] = $locale; 93 94 if ( ! $l10n ) { 95 $l10n = array(); 96 load_default_textdomain( $locale ); 97 } 98 99 if ( empty( $this->translations[ $current_locale ] ) ) { 100 foreach ( array_keys( $l10n ) as $textdomain ) { 101 $this->translations[ $current_locale ][ $textdomain ] = get_translations_for_domain( $textdomain ); 102 } 103 } 104 105 if ( ! empty( $this->translations[ $locale ] ) ) { 106 foreach ( array_keys( $l10n ) as $textdomain ) { 107 if ( isset( $this->translations[ $locale ][ $textdomain ] ) ) { 108 $l10n[ $textdomain ] = $this->translations[ $locale ][ $textdomain ]; 109 } 110 } 111 } else { 112 /* @var MO $mo */ 113 foreach ( $l10n as $textdomain => $mo ) { 114 if ( 'default' === $textdomain ) { 115 load_default_textdomain(); 116 117 continue; 118 } 119 120 unload_textdomain( $textdomain ); 121 122 if ( $mofile = $mo->get_filename() ) { 123 load_textdomain( $textdomain, $mofile ); 124 } 125 126 $this->translations[ $locale ][ $textdomain ] = get_translations_for_domain( $textdomain ); 127 } 128 } 129 130 /** 131 * Fires when the locale is switched. 132 * 133 * @since 4.7.0 134 * 135 * @param string $locale The new locale. 136 */ 137 do_action( 'switch_locale', $locale ); 138 139 return true; 140 } 141 142 /** 143 * Restores the translations according to the previous locale. 144 * 145 * @since 4.7.0 146 * 147 * @global Mo[] $l10n An array of available translations. 148 * @global WP_Locale $wp_locale The WordPress date and time locale object. 149 * 150 * @return string|false Locale on success, false on failure. 151 */ 152 public function restore_previous_locale() { 153 global $l10n; 154 155 $previous_locale = array_pop( $this->locales ); 156 157 if ( null === $previous_locale ) { 158 // The stack is empty, bail. 159 return false; 160 } 161 162 if ( null === $l10n ) { 163 $l10n = array(); 164 } 165 166 $locale = end( $this->locales ); 167 168 if ( ! $locale ) { 169 // There's nothing left in the stack: go back to the original locale. 170 $locale = $this->original_locale; 171 } 172 173 foreach ( array_keys( $l10n ) as $textdomain ) { 174 if ( isset( $this->translations[ $locale ][ $textdomain ] ) ) { 175 $l10n[ $textdomain ] = $this->translations[ $locale ][ $textdomain ]; 176 } 177 } 178 179 /** 180 * Fires when the locale is restored to the previous one. 181 * 182 * @since 4.7.0 183 * 184 * @param string $locale The new locale. 185 * @param string $previous_locale The previous locale. 186 */ 187 do_action( 'restore_previous_locale', $locale, $previous_locale ); 188 189 $GLOBALS['wp_locale'] = new WP_Locale(); 190 191 return $locale; 192 } 193 194 /** 195 * Filters the WordPress install's locale. 196 * 197 * @since 4.7.0 198 * 199 * @param string $locale The WordPress install's locale. 200 * @return string The locale currently being switched to. 201 */ 202 public function filter_locale( $locale ) { 203 $switched_locale = end( $this->locales ); 204 205 if ( $switched_locale ) { 206 return $switched_locale; 207 } 208 209 return $locale; 210 } 211 } -
src/wp-includes/l10n.php
diff --git src/wp-includes/l10n.php src/wp-includes/l10n.php index aaa7611..c0b2a96 100644
function is_rtl() { 1148 1148 return false; 1149 1149 } 1150 1150 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 */ 1163 function 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 */ 1179 function restore_previous_locale() { 1180 /* @var WP_Locale_Switcher $wp_locale_switcher */ 1181 global $wp_locale_switcher; 1182 1183 return $wp_locale_switcher->restore_previous_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() { 868 868 require_once ABSPATH . WPINC . '/pomo/mo.php'; 869 869 require_once ABSPATH . WPINC . '/l10n.php'; 870 870 require_once ABSPATH . WPINC . '/class-wp-locale.php'; 871 require_once ABSPATH . WPINC . '/class-wp-locale-switcher.php'; 871 872 872 873 // General libraries 873 874 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..47e9b6a 100644
class MO extends Gettext_Translations { 16 16 var $_nplurals = 2; 17 17 18 18 /** 19 * Loaded MO file. 20 * 21 * @var string 22 */ 23 private $filename = ''; 24 25 /** 26 * Returns the loaded MO file. 27 * 28 * @return string The loaded MO file. 29 */ 30 public function get_filename() { 31 return $this->filename; 32 } 33 34 /** 19 35 * Fills up with the entries from MO file $filename 20 36 * 21 37 * @param string $filename MO file to load 22 38 */ 23 39 function import_from_file($filename) { 24 $reader = new POMO_FileReader($filename); 25 if (!$reader->is_resource()) 40 $reader = new POMO_FileReader( $filename ); 41 42 if ( ! $reader->is_resource() ) { 26 43 return false; 27 return $this->import_from_reader($reader); 44 } 45 46 $this->filename = (string) $filename; 47 48 return $this->import_from_reader( $reader ); 28 49 } 29 50 30 51 /** … … class MO extends Gettext_Translations { 299 320 return $this->_nplurals; 300 321 } 301 322 } 302 endif; 303 No newline at end of file 323 endif; -
src/wp-settings.php
diff --git src/wp-settings.php src/wp-settings.php index 80f556c..ccf0396 100644
if ( SHORTINIT ) 131 131 // Load the L10n library. 132 132 require_once( ABSPATH . WPINC . '/l10n.php' ); 133 133 require_once( ABSPATH . WPINC . '/class-wp-locale.php' ); 134 require_once( ABSPATH . WPINC . '/class-wp-locale-switcher.php' ); 134 135 135 136 // Run the installer if WordPress is not installed. 136 137 wp_not_installed(); … … unset( $locale_file ); 384 385 */ 385 386 $GLOBALS['wp_locale'] = new WP_Locale(); 386 387 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 387 397 // Load the functions for the active theme, for both parent and child theme if applicable. 388 398 if ( ! wp_installing() || 'wp-activate.php' === $pagenow ) { 389 399 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..0416d17
- + 1 <?php 2 3 /** 4 * @group l10n 5 * @group i18n 6 */ 7 class Tests_Locale_Switcher extends WP_UnitTestCase { 8 /** 9 * @var string 10 */ 11 protected $locale = ''; 12 13 /** 14 * @var string 15 */ 16 protected $previous_locale = ''; 17 18 public function setUp() { 19 $this->locale = ''; 20 $this->previous_locale = ''; 21 } 22 23 public function test_switch_to_non_existent_locale_returns_false() { 24 $this->assertFalse( switch_to_locale( 'de_DE' ) ); 25 } 26 27 public function test_switch_to_non_existent_locale_does_not_change_locale() { 28 switch_to_locale( 'de_DE' ); 29 30 $this->assertSame( 'en_US', get_locale() ); 31 } 32 33 public function test_switch_to_locale_returns_true() { 34 $expected = switch_to_locale( 'en_GB' ); 35 36 // Cleanup. 37 restore_previous_locale(); 38 39 $this->assertTrue( $expected ); 40 } 41 42 public function test_switch_to_locale_changes_the_locale() { 43 switch_to_locale( 'en_GB' ); 44 45 $locale = get_locale(); 46 47 // Cleanup. 48 restore_previous_locale(); 49 50 $this->assertSame( 'en_GB', $locale ); 51 } 52 53 public function test_switch_to_locale_loads_translation() { 54 switch_to_locale( 'es_ES' ); 55 56 $actual = __( 'Invalid parameter.' ); 57 58 // Cleanup. 59 restore_previous_locale(); 60 61 $this->assertSame( 'Parámetro no válido. ', $actual ); 62 } 63 64 public function test_switch_to_locale_changes_wp_locale_global() { 65 global $wp_locale; 66 67 switch_to_locale( 'es_ES' ); 68 69 $wp_locale_es_ES = clone $wp_locale; 70 71 // Cleanup. 72 restore_previous_locale(); 73 74 $this->markTestIncomplete( 'No es_ES translation available that would change the WP_Locale object.'); 75 } 76 77 public function test_switch_to_locale_multiple_times() { 78 switch_to_locale( 'en_GB' ); 79 switch_to_locale( 'es_ES' ); 80 $locale = get_locale(); 81 82 // Cleanup. 83 restore_previous_locale(); 84 restore_previous_locale(); 85 86 $this->assertSame( 'es_ES', $locale ); 87 } 88 89 public function test_restore_locale_without_switching() { 90 $this->assertFalse( restore_previous_locale() ); 91 } 92 93 public function test_restore_locale_changes_the_locale_back() { 94 switch_to_locale( 'en_GB' ); 95 96 // Cleanup. 97 restore_previous_locale(); 98 99 $this->assertSame( 'en_US', get_locale() ); 100 } 101 102 public function test_restore_locale_after_switching_multiple_times() { 103 switch_to_locale( 'en_GB' ); 104 switch_to_locale( 'es_ES' ); 105 restore_previous_locale(); 106 107 $locale = get_locale(); 108 109 // Cleanup. 110 restore_previous_locale(); 111 112 $this->assertSame( 'en_GB', $locale ); 113 } 114 115 public function test_restore_locale_restores_translation() { 116 switch_to_locale( 'es_ES' ); 117 restore_previous_locale(); 118 119 $actual = __( 'Invalid parameter.' ); 120 121 $this->assertSame( 'Invalid parameter.', $actual ); 122 } 123 124 public function test_restore_locale_action_passes_previous_locale() { 125 switch_to_locale( 'en_GB' ); 126 switch_to_locale( 'es_ES' ); 127 128 add_action( 'restore_previous_locale', array( $this, 'store_locale' ), 10, 2 ); 129 130 restore_previous_locale(); 131 132 $previous_locale = $this->previous_locale; 133 134 // Cleanup. 135 restore_previous_locale(); 136 137 $this->assertSame( 'es_ES', $previous_locale ); 138 } 139 140 public function store_locale( $locale, $previous_locale ) { 141 $this->locale = $locale; 142 $this->previous_locale = $previous_locale; 143 } 144 } -
tests/phpunit/tests/locale.php
diff --git tests/phpunit/tests/locale.php tests/phpunit/tests/locale.php index 1c335f4..79372d6 100644
1 1 <?php 2 2 3 3 /** 4 * @group l ocale4 * @group l10n 5 5 * @group i18n 6 6 */ 7 7 class Tests_Locale extends WP_UnitTestCase {