Ticket #26511: 26511.4.diff
File 26511.4.diff, 14.5 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..0ab6f9b
- + 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 * @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 * Hooks into the {@see 'locale'} filter to change the locale on the fly. 48 * 49 * @since 4.7.0 50 */ 51 public function __construct() { 52 $this->original_locale = get_locale(); 53 $this->available_languages = get_available_languages(); 54 55 add_filter( 'locale', array( $this, 'filter_locale' ) ); 56 } 57 58 /** 59 * Switches the translations according to the given locale. 60 * 61 * @since 4.7.0 62 * 63 * @global WP_Locale $wp_locale The WordPress date and time locale object. 64 * 65 * @param string $locale The locale to switch to. 66 * @return bool True on success, false on failure. 67 */ 68 public function switch_to_locale( $locale ) { 69 if ( $locale === get_locale() || ( is_admin() && $locale === get_user_locale() ) ) { 70 return false; 71 } 72 73 if ( ! in_array( $locale, $this->available_languages ) ) { 74 return false; 75 } 76 77 $this->locales[] = $locale; 78 79 $this->load_translations( $locale ); 80 81 /** 82 * Fires when the locale is switched. 83 * 84 * @since 4.7.0 85 * 86 * @param string $locale The new locale. 87 */ 88 do_action( 'switch_locale', $locale ); 89 90 $GLOBALS['wp_locale'] = new WP_Locale(); 91 92 return true; 93 } 94 95 /** 96 * Restores the translations according to the previous locale. 97 * 98 * @since 4.7.0 99 * 100 * @global WP_Locale $wp_locale The WordPress date and time locale object. 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->load_translations( $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 $GLOBALS['wp_locale'] = new WP_Locale(); 132 133 return $locale; 134 } 135 136 /** 137 * Filters the WordPress install's locale. 138 * 139 * @since 4.7.0 140 * 141 * @param string $locale The WordPress install's locale. 142 * @return string The locale currently being switched to. 143 */ 144 public function filter_locale( $locale ) { 145 $switched_locale = end( $this->locales ); 146 147 if ( $switched_locale ) { 148 return $switched_locale; 149 } 150 151 return $locale; 152 } 153 154 /** 155 * Load translations for a given locale. 156 * 157 * When switching to a locale, translations for this locale must be loaded from scratch. 158 * 159 * @since 4.7.0 160 * 161 * @global Mo[] $l10n An array of all currently loaded text domains. 162 * 163 * @param string $locale The locale to load translations for. 164 */ 165 private function load_translations( $locale ) { 166 global $l10n; 167 168 if ( ! $l10n ) { 169 $l10n = array(); 170 } 171 172 load_default_textdomain( $locale ); 173 174 /* @var MO $mo */ 175 foreach ( $l10n as $domain => $mo ) { 176 if ( 'default' === $domain ) { 177 continue; 178 } 179 180 unload_textdomain( $domain ); 181 182 if ( $mo->get_filename() ) { 183 load_textdomain( $domain, $mo->get_filename() ); 184 } 185 186 get_translations_for_domain( $domain ); 187 } 188 } 189 } -
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..63dab0d 100644
function get_current_network_id() { 851 851 * @staticvar bool $loaded 852 852 */ 853 853 function wp_load_translations_early() { 854 global $text_direction, $wp_locale ;854 global $text_direction, $wp_locale, $wp_locale_switcher; 855 855 856 856 static $loaded = false; 857 857 if ( $loaded ) … … 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'; … … function wp_load_translations_early() { 919 920 } 920 921 921 922 $wp_locale = new WP_Locale(); 923 $wp_locale_switcher = new WP_Locale_Switcher(); 922 924 } 923 925 924 926 /** -
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..755ac88 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' ) ) -
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..77e84ac
- + 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( 'foo_BAR' ) ); 25 } 26 27 public function test_switch_to_non_existent_locale_does_not_change_locale() { 28 switch_to_locale( 'foo_BAR' ); 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 $expected = array( 68 'thousands_sep' => '.', 69 'decimal_point' => ',', 70 ); 71 72 switch_to_locale( 'de_DE' ); 73 74 $wp_locale_de_DE = clone $wp_locale; 75 76 // Cleanup. 77 restore_previous_locale(); 78 79 $this->assertEqualSetsWithIndex( $expected, $wp_locale_de_DE->number_format ); 80 } 81 82 public function test_switch_to_locale_multiple_times() { 83 switch_to_locale( 'en_GB' ); 84 switch_to_locale( 'es_ES' ); 85 $locale = get_locale(); 86 87 // Cleanup. 88 restore_previous_locale(); 89 restore_previous_locale(); 90 91 $this->assertSame( 'es_ES', $locale ); 92 } 93 94 public function test_switch_to_locale_multiple_times_loads_translation() { 95 switch_to_locale( 'en_GB' ); 96 switch_to_locale( 'de_DE' ); 97 switch_to_locale( 'es_ES' ); 98 99 $actual = __( 'Invalid parameter.' ); 100 101 // Cleanup. 102 restore_previous_locale(); 103 restore_previous_locale(); 104 restore_previous_locale(); 105 106 $this->assertSame( 'Parámetro no válido. ', $actual ); 107 } 108 109 public function test_restore_previous_locale_without_switching() { 110 $this->assertFalse( restore_previous_locale() ); 111 } 112 113 public function test_restore_previous_locale_changes_the_locale_back() { 114 switch_to_locale( 'en_GB' ); 115 116 // Cleanup. 117 restore_previous_locale(); 118 119 $this->assertSame( 'en_US', get_locale() ); 120 } 121 122 public function test_restore_previous_locale_after_switching_multiple_times() { 123 switch_to_locale( 'en_GB' ); 124 switch_to_locale( 'es_ES' ); 125 restore_previous_locale(); 126 127 $locale = get_locale(); 128 129 // Cleanup. 130 restore_previous_locale(); 131 132 $this->assertSame( 'en_GB', $locale ); 133 } 134 135 public function test_restore_previous_locale_restores_translation() { 136 switch_to_locale( 'es_ES' ); 137 restore_previous_locale(); 138 139 $actual = __( 'Invalid parameter.' ); 140 141 $this->assertSame( 'Invalid parameter.', $actual ); 142 } 143 144 public function test_restore_previous_locale_action_passes_previous_locale() { 145 switch_to_locale( 'en_GB' ); 146 switch_to_locale( 'es_ES' ); 147 148 add_action( 'restore_previous_locale', array( $this, 'store_locale' ), 10, 2 ); 149 150 restore_previous_locale(); 151 152 $previous_locale = $this->previous_locale; 153 154 // Cleanup. 155 restore_previous_locale(); 156 157 $this->assertSame( 'es_ES', $previous_locale ); 158 } 159 160 public function test_restore_previous_locale_restores_wp_locale_global() { 161 global $wp_locale; 162 163 $expected = array( 164 'thousands_sep' => ',', 165 'decimal_point' => '.', 166 ); 167 168 switch_to_locale( 'de_DE' ); 169 restore_previous_locale(); 170 171 $this->assertEqualSetsWithIndex( $expected, $wp_locale->number_format ); 172 } 173 174 public function store_locale( $locale, $previous_locale ) { 175 $this->locale = $locale; 176 $this->previous_locale = $previous_locale; 177 } 178 } -
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 {