Ticket #26511: 26511.6.diff
File 26511.6.diff, 16.5 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..57c9e0c
- + 1 <?php 2 /** 3 * Locale API: WP_Locale_Switcher class 4 * 5 * @package WordPress 6 * @subpackage i18n 7 * @since 4.7.0 8 */ 9 10 /** 11 * Core class used 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 * @access 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 * Holds all available languages. 36 * 37 * @since 4.7.0 38 * @access private 39 * @var array An array of language codes (file names without the .mo extension). 40 */ 41 private $available_languages = array(); 42 43 /** 44 * Constructor. 45 * 46 * Stores the original locale as well as a list of all available languages. 47 * 48 * @since 4.7.0 49 */ 50 public function __construct() { 51 $this->original_locale = get_locale(); 52 $this->available_languages = get_available_languages(); 53 } 54 55 /** 56 * Initializes the locale switcher. 57 * 58 * Hooks into the {@see 'locale'} filter to change the locale on the fly. 59 */ 60 public function init() { 61 add_filter( 'locale', array( $this, 'filter_locale' ) ); 62 } 63 64 /** 65 * Switches the translations according to the given locale. 66 * 67 * @since 4.7.0 68 * 69 * @param string $locale The locale to switch to. 70 * @return bool True on success, false on failure. 71 */ 72 public function switch_to_locale( $locale ) { 73 if ( $locale === get_locale() ) { 74 return false; 75 } 76 77 if ( ! in_array( $locale, $this->available_languages ) ) { 78 return false; 79 } 80 81 $this->locales[] = $locale; 82 83 $this->change_locale( $locale ); 84 85 /** 86 * Fires when the locale is switched. 87 * 88 * @since 4.7.0 89 * 90 * @param string $locale The new locale. 91 */ 92 do_action( 'switch_locale', $locale ); 93 94 return true; 95 } 96 97 /** 98 * Restores the translations according to the previous locale. 99 * 100 * @since 4.7.0 101 * 102 * @return string|false Locale on success, false on failure. 103 */ 104 public function restore_previous_locale() { 105 $previous_locale = array_pop( $this->locales ); 106 107 if ( null === $previous_locale ) { 108 // The stack is empty, bail. 109 return false; 110 } 111 112 $locale = end( $this->locales ); 113 114 if ( ! $locale ) { 115 // There's nothing left in the stack: go back to the original locale. 116 $locale = $this->original_locale; 117 } 118 119 $this->change_locale( $locale ); 120 121 /** 122 * Fires when the locale is restored to the previous one. 123 * 124 * @since 4.7.0 125 * 126 * @param string $locale The new locale. 127 * @param string $previous_locale The previous locale. 128 */ 129 do_action( 'restore_previous_locale', $locale, $previous_locale ); 130 131 return $locale; 132 } 133 134 /** 135 * Restores the translations according to the original locale. 136 * 137 * @since 4.7.0 138 * 139 * @return string|false Locale on success, false on failure. 140 */ 141 public function restore_current_locale() { 142 $this->locales = array( $this->original_locale ); 143 144 return $this->restore_previous_locale(); 145 } 146 147 /** 148 * Filters the WordPress install's locale. 149 * 150 * @since 4.7.0 151 * 152 * @param string $locale The WordPress install's locale. 153 * @return string The locale currently being switched to. 154 */ 155 public function filter_locale( $locale ) { 156 $switched_locale = end( $this->locales ); 157 158 if ( $switched_locale ) { 159 return $switched_locale; 160 } 161 162 return $locale; 163 } 164 165 /** 166 * Load translations for a given locale. 167 * 168 * When switching to a locale, translations for this locale must be loaded from scratch. 169 * 170 * @since 4.7.0 171 * @access private 172 * 173 * @global Mo[] $l10n An array of all currently loaded text domains. 174 * 175 * @param string $locale The locale to load translations for. 176 */ 177 private function load_translations( $locale ) { 178 global $l10n; 179 180 if ( ! $l10n ) { 181 $l10n = array(); 182 } 183 184 load_default_textdomain( $locale ); 185 186 /* @var MO $mo */ 187 foreach ( $l10n as $domain => $mo ) { 188 if ( 'default' === $domain ) { 189 continue; 190 } 191 192 unload_textdomain( $domain ); 193 194 if ( $mo->get_filename() ) { 195 load_textdomain( $domain, $mo->get_filename() ); 196 } 197 198 get_translations_for_domain( $domain ); 199 } 200 } 201 202 /** 203 * Changes the site's locale to the given one. 204 * 205 * Loads the translations, changes the global `$wp_locale` object and updates 206 * all post type labels. 207 * 208 * @since 4.7.0 209 * @access private 210 * 211 * @global WP_Locale $wp_locale The WordPress date and time locale object. 212 * 213 * @param string $locale The locale to change to. 214 */ 215 private function change_locale( $locale ) { 216 $this->load_translations( $locale ); 217 218 $GLOBALS['wp_locale'] = new WP_Locale(); 219 220 foreach ( get_post_types( array(), 'objects' ) as $post_type ) { 221 $post_type->labels = array(); 222 $post_type->labels = get_post_type_labels( $post_type ); 223 $post_type->label = $post_type->labels->name; 224 } 225 } 226 } -
src/wp-includes/l10n.php
diff --git src/wp-includes/l10n.php src/wp-includes/l10n.php index aaa7611..e551d6a 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 } 1185 1186 /** 1187 * Restores the translations according to the original locale. 1188 * 1189 * @since 4.7.0 1190 * 1191 * @global WP_Locale_Switcher $wp_locale_switcher 1192 * 1193 * @return string|false Locale on success, false on error. 1194 */ 1195 function restore_current_locale() { 1196 /* @var WP_Locale_Switcher $wp_locale_switcher */ 1197 global $wp_locale_switcher; 1198 1199 return $wp_locale_switcher->restore_current_locale(); 1200 } -
src/wp-includes/load.php
diff --git src/wp-includes/load.php src/wp-includes/load.php index 2aa4451..6932f83 100644
function get_current_network_id() { 845 845 * @since 3.4.0 846 846 * @access private 847 847 * 848 * @global string $text_direction 849 * @global WP_Locale $wp_locale The WordPress date and time locale object. 848 * @global string $text_direction 849 * @global WP_Locale $wp_locale The WordPress date and time locale object. 850 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. 850 851 * 851 852 * @staticvar bool $loaded 852 853 */ 853 854 function wp_load_translations_early() { 854 global $text_direction, $wp_locale ;855 global $text_direction, $wp_locale, $wp_locale_switcher; 855 856 856 857 static $loaded = false; 857 858 if ( $loaded ) … … function wp_load_translations_early() { 868 869 require_once ABSPATH . WPINC . '/pomo/mo.php'; 869 870 require_once ABSPATH . WPINC . '/l10n.php'; 870 871 require_once ABSPATH . WPINC . '/class-wp-locale.php'; 872 require_once ABSPATH . WPINC . '/class-wp-locale-switcher.php'; 871 873 872 874 // General libraries 873 875 require_once ABSPATH . WPINC . '/plugin.php'; … … function wp_load_translations_early() { 919 921 } 920 922 921 923 $wp_locale = new WP_Locale(); 924 $wp_locale_switcher = new WP_Locale_Switcher(); 925 $wp_locale_switcher->init(); 922 926 } 923 927 924 928 /** -
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..4292f5c 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 WordPress locale switcher object. 394 */ 395 $GLOBALS['wp_locale_switcher'] = new WP_Locale_Switcher(); 396 $GLOBALS['wp_locale_switcher']->init(); 397 387 398 // Load the functions for the active theme, for both parent and child theme if applicable. 388 399 if ( ! wp_installing() || 'wp-activate.php' === $pagenow ) { 389 400 if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) ) -
tests/phpunit/tests/l10n.php
diff --git tests/phpunit/tests/l10n.php tests/phpunit/tests/l10n.php index f1048aa..d7fe894 100644
class Tests_L10n extends WP_UnitTestCase { 85 85 $this->assertEmpty( $array ); 86 86 87 87 $array = get_available_languages( DIR_TESTDATA . '/languages/' ); 88 $this->assertEquals( array( ' en_GB', 'es_ES' ), $array );88 $this->assertEquals( array( 'de_DE', 'en_GB', 'es_ES' ), $array ); 89 89 } 90 90 91 91 /** -
tests/phpunit/tests/l10n/loadTextdomainJustInTime.php
diff --git tests/phpunit/tests/l10n/loadTextdomainJustInTime.php tests/phpunit/tests/l10n/loadTextdomainJustInTime.php index f73cfd5..1d39868 100644
class Tests_L10n_loadTextdomainJustInTime extends WP_UnitTestCase { 141 141 $this->assertSame( 'Das ist ein Dummy Plugin', $expected_output_final ); 142 142 $this->assertTrue( $is_textdomain_loaded_final ); 143 143 } 144 145 /** 146 * @ticket 26511 147 */ 148 public function test_plugin_translation_after_switching_locale() { 149 require_once DIR_TESTDATA . '/plugins/internationalized-plugin.php'; 150 151 switch_to_locale( 'de_DE' ); 152 $expected = i18n_plugin_test(); 153 restore_previous_locale(); 154 155 $this->assertSame( 'Das ist ein Dummy Plugin', $expected ); 156 } 157 158 /** 159 * @ticket 26511 160 */ 161 public function test_theme_translation_after_switching_locale() { 162 switch_theme( 'internationalized-theme' ); 163 164 require_once get_stylesheet_directory() . '/functions.php'; 165 166 switch_to_locale( 'de_DE' ); 167 $expected = i18n_theme_test(); 168 restore_previous_locale(); 169 170 $this->assertSame( 'Das ist ein Dummy Theme', $expected ); 171 } 144 172 } -
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..8a714c8
- + 1 <?php 2 3 /** 4 * @group l10n 5 * @group i18n 6 * @group 26511 7 */ 8 class Tests_Locale_Switcher extends WP_UnitTestCase { 9 /** 10 * @var string 11 */ 12 protected $locale = ''; 13 14 /** 15 * @var string 16 */ 17 protected $previous_locale = ''; 18 19 public function setUp() { 20 $this->locale = ''; 21 $this->previous_locale = ''; 22 } 23 24 public function test_switch_to_non_existent_locale_returns_false() { 25 $this->assertFalse( switch_to_locale( 'foo_BAR' ) ); 26 } 27 28 public function test_switch_to_non_existent_locale_does_not_change_locale() { 29 switch_to_locale( 'foo_BAR' ); 30 31 $this->assertSame( 'en_US', get_locale() ); 32 } 33 34 public function test_switch_to_locale_returns_true() { 35 $expected = switch_to_locale( 'en_GB' ); 36 37 // Cleanup. 38 restore_previous_locale(); 39 40 $this->assertTrue( $expected ); 41 } 42 43 public function test_switch_to_locale_changes_the_locale() { 44 switch_to_locale( 'en_GB' ); 45 46 $locale = get_locale(); 47 48 // Cleanup. 49 restore_previous_locale(); 50 51 $this->assertSame( 'en_GB', $locale ); 52 } 53 54 public function test_switch_to_locale_loads_translation() { 55 switch_to_locale( 'es_ES' ); 56 57 $actual = __( 'Invalid parameter.' ); 58 59 // Cleanup. 60 restore_previous_locale(); 61 62 $this->assertSame( 'Parámetro no válido. ', $actual ); 63 } 64 65 public function test_switch_to_locale_changes_wp_locale_global() { 66 global $wp_locale; 67 68 $expected = array( 69 'thousands_sep' => '.', 70 'decimal_point' => ',', 71 ); 72 73 switch_to_locale( 'de_DE' ); 74 75 $wp_locale_de_DE = clone $wp_locale; 76 77 // Cleanup. 78 restore_previous_locale(); 79 80 $this->assertEqualSetsWithIndex( $expected, $wp_locale_de_DE->number_format ); 81 } 82 83 public function test_switch_to_locale_multiple_times() { 84 switch_to_locale( 'en_GB' ); 85 switch_to_locale( 'es_ES' ); 86 $locale = get_locale(); 87 88 // Cleanup. 89 restore_previous_locale(); 90 restore_previous_locale(); 91 92 $this->assertSame( 'es_ES', $locale ); 93 } 94 95 public function test_switch_to_locale_multiple_times_loads_translation() { 96 switch_to_locale( 'en_GB' ); 97 switch_to_locale( 'de_DE' ); 98 switch_to_locale( 'es_ES' ); 99 100 $actual = __( 'Invalid parameter.' ); 101 102 // Cleanup. 103 restore_previous_locale(); 104 restore_previous_locale(); 105 restore_previous_locale(); 106 107 $this->assertSame( 'Parámetro no válido. ', $actual ); 108 } 109 110 public function test_restore_previous_locale_without_switching() { 111 $this->assertFalse( restore_previous_locale() ); 112 } 113 114 public function test_restore_previous_locale_changes_the_locale_back() { 115 switch_to_locale( 'en_GB' ); 116 117 // Cleanup. 118 restore_previous_locale(); 119 120 $this->assertSame( 'en_US', get_locale() ); 121 } 122 123 public function test_restore_previous_locale_after_switching_multiple_times() { 124 switch_to_locale( 'en_GB' ); 125 switch_to_locale( 'es_ES' ); 126 restore_previous_locale(); 127 128 $locale = get_locale(); 129 130 // Cleanup. 131 restore_previous_locale(); 132 133 $this->assertSame( 'en_GB', $locale ); 134 } 135 136 public function test_restore_previous_locale_restores_translation() { 137 switch_to_locale( 'es_ES' ); 138 restore_previous_locale(); 139 140 $actual = __( 'Invalid parameter.' ); 141 142 $this->assertSame( 'Invalid parameter.', $actual ); 143 } 144 145 public function test_restore_previous_locale_action_passes_previous_locale() { 146 switch_to_locale( 'en_GB' ); 147 switch_to_locale( 'es_ES' ); 148 149 add_action( 'restore_previous_locale', array( $this, 'store_locale' ), 10, 2 ); 150 151 restore_previous_locale(); 152 153 $previous_locale = $this->previous_locale; 154 155 // Cleanup. 156 restore_previous_locale(); 157 158 $this->assertSame( 'es_ES', $previous_locale ); 159 } 160 161 public function test_restore_previous_locale_restores_wp_locale_global() { 162 global $wp_locale; 163 164 $expected = array( 165 'thousands_sep' => ',', 166 'decimal_point' => '.', 167 ); 168 169 switch_to_locale( 'de_DE' ); 170 restore_previous_locale(); 171 172 $this->assertEqualSetsWithIndex( $expected, $wp_locale->number_format ); 173 } 174 175 public function test_restore_current_locale_after_switching_multiple_times() { 176 switch_to_locale( 'en_GB' ); 177 switch_to_locale( 'nl_NL' ); 178 switch_to_locale( 'es_ES' ); 179 180 restore_current_locale(); 181 182 $this->assertSame( 'en_US', get_locale() ); 183 } 184 185 public function store_locale( $locale, $previous_locale ) { 186 $this->locale = $locale; 187 $this->previous_locale = $previous_locale; 188 } 189 } -
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 {