Ticket #26511: 26511.diff
File 26511.diff, 10.9 KB (added by , 9 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..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 */ 15 class 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() { 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_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() { 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..6188a7a 100644
class MO extends Gettext_Translations { 16 16 var $_nplurals = 2; 17 17 18 18 /** 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 /** 19 38 * Fills up with the entries from MO file $filename 20 39 * 21 40 * @param string $filename MO file to load 22 41 */ 23 42 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() ) { 26 46 return false; 27 return $this->import_from_reader($reader); 47 } 48 49 $this->filename = (string) $filename; 50 51 return $this->import_from_reader( $reader ); 28 52 } 29 53 30 54 /** … … class MO extends Gettext_Translations { 299 323 return $this->_nplurals; 300 324 } 301 325 } 302 endif; 303 No newline at end of file 326 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..30fc24d
- + 1 <?php 2 3 /** 4 * @group l10n 5 * @group i18n 6 */ 7 class 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 }