Ticket #26511: 26511.2.diff
File 26511.2.diff, 12.3 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..b991fc7
- + 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 to switch to. 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 ( $locale === $current_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 ( ! $l10n ) { 89 $l10n = array(); 90 load_default_textdomain(); 91 } 92 93 if ( ! $this->has_translations_for_locale( $current_locale ) ) { 94 foreach ( array_keys( $l10n ) as $textdomain ) { 95 $this->translations[ $current_locale ][ $textdomain ] = get_translations_for_domain( $textdomain ); 96 } 97 } 98 99 if ( $this->has_translations_for_locale( $locale ) ) { 100 foreach ( array_keys( $l10n ) as $textdomain ) { 101 if ( isset( $this->translations[ $locale ][ $textdomain ] ) ) { 102 $l10n[ $textdomain ] = $this->translations[ $locale ][ $textdomain ]; 103 } 104 } 105 } else { 106 /* @var MO $mo */ 107 foreach ( $l10n as $textdomain => $mo ) { 108 if ( 'default' === $textdomain ) { 109 load_default_textdomain(); 110 111 continue; 112 } 113 114 unload_textdomain( $textdomain ); 115 116 if ( $mofile = $mo->get_filename() ) { 117 load_textdomain( $textdomain, $mofile ); 118 } 119 120 $this->translations[ $locale ][ $textdomain ] = get_translations_for_domain( $textdomain ); 121 } 122 } 123 124 /** 125 * Fires when the locale is switched. 126 * 127 * @since 4.7.0 128 * 129 * @param string $locale The new locale. 130 */ 131 do_action( 'switch_locale', $locale ); 132 133 return true; 134 } 135 136 /** 137 * Restores the translations according to the previous locale. 138 * 139 * @since 4.7.0 140 * 141 * @global Mo[] $l10n An array of available translations. 142 * @global WP_Locale $wp_locale The WordPress date and time locale object. 143 * 144 * @return string|false Locale on success, false on failure. 145 */ 146 public function restore_locale() { 147 global $l10n; 148 149 $previous_locale = array_pop( $this->locales ); 150 151 if ( null === $previous_locale ) { 152 // The stack is empty, bail. 153 return false; 154 } 155 156 if ( null === $l10n ) { 157 $l10n = array(); 158 } 159 160 $locale = end( $this->locales ); 161 162 if ( ! $locale ) { 163 // There's nothing left in the stack: go back to the original locale. 164 $locale = $this->original_locale; 165 } 166 167 foreach ( array_keys( $l10n ) as $textdomain ) { 168 if ( isset( $this->translations[ $locale ][ $textdomain ] ) ) { 169 $l10n[ $textdomain ] = $this->translations[ $locale ][ $textdomain ]; 170 } 171 } 172 173 $GLOBALS['wp_locale'] = new WP_Locale(); 174 175 /** 176 * Fires when the locale is restored to the previous one. 177 * 178 * @since 4.7.0 179 * 180 * @param string $locale The new locale. 181 * @param string $previous_locale The previous locale. 182 */ 183 do_action( 'restore_locale', $locale, $previous_locale ); 184 185 return $locale; 186 } 187 188 /** 189 * Filters the WordPress install's locale. 190 * 191 * @since 4.7.0 192 * 193 * @param string $locale The WordPress install's locale. 194 * @return string The locale currently being switched to. 195 */ 196 public function filter_locale( $locale ) { 197 $switched_locale = end( $this->locales ); 198 199 if ( $switched_locale ) { 200 return $switched_locale; 201 } 202 203 return $locale; 204 } 205 206 /** 207 * Checks if there are cached translations for the given locale. 208 * 209 * @since 4.7.0 210 * 211 * @param string $locale The locale. 212 * @return bool True if there are cached translations for the given locale, false otherwise. 213 */ 214 private function has_translations_for_locale( $locale ) { 215 return ! empty( $this->translations[ $locale ] ); 216 } 217 } -
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..e9c7ec6
- + 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_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_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_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_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_locale(); 84 restore_locale(); 85 86 $this->assertSame( 'es_ES', $locale ); 87 } 88 89 public function test_restore_locale_without_switching() { 90 $this->assertFalse( restore_locale() ); 91 } 92 93 public function test_restore_locale_changes_the_locale_back() { 94 switch_to_locale( 'en_GB' ); 95 96 // Cleanup. 97 restore_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_locale(); 106 107 $locale = get_locale(); 108 109 // Cleanup. 110 restore_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_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_locale', array( $this, 'store_locale' ), 10, 2 ); 129 130 restore_locale(); 131 132 $previous_locale = $this->previous_locale; 133 134 // Cleanup. 135 restore_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 {