|
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 * @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 * Holds all available languages. |
|
34 * |
|
35 * @since 4.7.0 |
|
36 * @var array An array of language codes (file names without the .mo extension). |
|
37 */ |
|
38 private $available_languages = array(); |
|
39 |
|
40 /** |
|
41 * Constructor. |
|
42 * |
|
43 * Stores the original locale as well as a list of all available languages. |
|
44 * |
|
45 * @since 4.7.0 |
|
46 */ |
|
47 public function __construct() { |
|
48 $this->original_locale = is_admin() ? get_user_locale() : get_locale(); |
|
49 $this->available_languages = array_merge( array( 'en_US' ), get_available_languages() ); |
|
50 } |
|
51 |
|
52 /** |
|
53 * Initializes the locale switcher. |
|
54 * |
|
55 * Hooks into the {@see 'locale'} filter to change the locale on the fly. |
|
56 */ |
|
57 public function init() { |
|
58 add_filter( 'locale', array( $this, 'filter_locale' ) ); |
|
59 } |
|
60 |
|
61 /** |
|
62 * Switches the translations according to the given locale. |
|
63 * |
|
64 * @since 4.7.0 |
|
65 * |
|
66 * @param string $locale The locale to switch to. |
|
67 * @return bool True on success, false on failure. |
|
68 */ |
|
69 public function switch_to_locale( $locale ) { |
|
70 $current_locale = is_admin() ? get_user_locale() : get_locale(); |
|
71 if ( $current_locale === $locale ) { |
|
72 return false; |
|
73 } |
|
74 |
|
75 if ( ! in_array( $locale, $this->available_languages, true ) ) { |
|
76 return false; |
|
77 } |
|
78 |
|
79 $this->locales[] = $locale; |
|
80 |
|
81 $this->change_locale( $locale ); |
|
82 |
|
83 /** |
|
84 * Fires when the locale is switched. |
|
85 * |
|
86 * @since 4.7.0 |
|
87 * |
|
88 * @param string $locale The new locale. |
|
89 */ |
|
90 do_action( 'switch_locale', $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 * @return string|false Locale on success, false on failure. |
|
101 */ |
|
102 public function restore_previous_locale() { |
|
103 $previous_locale = array_pop( $this->locales ); |
|
104 |
|
105 if ( null === $previous_locale ) { |
|
106 // The stack is empty, bail. |
|
107 return false; |
|
108 } |
|
109 |
|
110 $locale = end( $this->locales ); |
|
111 |
|
112 if ( ! $locale ) { |
|
113 // There's nothing left in the stack: go back to the original locale. |
|
114 $locale = $this->original_locale; |
|
115 } |
|
116 |
|
117 $this->change_locale( $locale ); |
|
118 |
|
119 /** |
|
120 * Fires when the locale is restored to the previous one. |
|
121 * |
|
122 * @since 4.7.0 |
|
123 * |
|
124 * @param string $locale The new locale. |
|
125 * @param string $previous_locale The previous locale. |
|
126 */ |
|
127 do_action( 'restore_previous_locale', $locale, $previous_locale ); |
|
128 |
|
129 return $locale; |
|
130 } |
|
131 |
|
132 /** |
|
133 * Restores the translations according to the original locale. |
|
134 * |
|
135 * @since 4.7.0 |
|
136 * |
|
137 * @return string|false Locale on success, false on failure. |
|
138 */ |
|
139 public function restore_current_locale() { |
|
140 if ( empty( $this->locales ) ) { |
|
141 return false; |
|
142 } |
|
143 |
|
144 $this->locales = array( $this->original_locale ); |
|
145 |
|
146 return $this->restore_previous_locale(); |
|
147 } |
|
148 |
|
149 /** |
|
150 * Whether switch_to_locale() is in effect. |
|
151 * |
|
152 * @since 4.7.0 |
|
153 * |
|
154 * @return bool True if the locale has been switched, false otherwise. |
|
155 */ |
|
156 public function is_switched() { |
|
157 return ! empty( $this->locales ); |
|
158 } |
|
159 |
|
160 /** |
|
161 * Filters the locale of the WordPress installation. |
|
162 * |
|
163 * @since 4.7.0 |
|
164 * |
|
165 * @param string $locale The locale of the WordPress installation. |
|
166 * @return string The locale currently being switched to. |
|
167 */ |
|
168 public function filter_locale( $locale ) { |
|
169 $switched_locale = end( $this->locales ); |
|
170 |
|
171 if ( $switched_locale ) { |
|
172 return $switched_locale; |
|
173 } |
|
174 |
|
175 return $locale; |
|
176 } |
|
177 |
|
178 /** |
|
179 * Load translations for a given locale. |
|
180 * |
|
181 * When switching to a locale, translations for this locale must be loaded from scratch. |
|
182 * |
|
183 * @since 4.7.0 |
|
184 * |
|
185 * @global Mo[] $l10n An array of all currently loaded text domains. |
|
186 * |
|
187 * @param string $locale The locale to load translations for. |
|
188 */ |
|
189 private function load_translations( $locale ) { |
|
190 global $l10n; |
|
191 |
|
192 $domains = $l10n ? array_keys( $l10n ) : array(); |
|
193 |
|
194 load_default_textdomain( $locale ); |
|
195 |
|
196 foreach ( $domains as $domain ) { |
|
197 if ( 'default' === $domain ) { |
|
198 continue; |
|
199 } |
|
200 |
|
201 unload_textdomain( $domain ); |
|
202 get_translations_for_domain( $domain ); |
|
203 } |
|
204 } |
|
205 |
|
206 /** |
|
207 * Changes the site's locale to the given one. |
|
208 * |
|
209 * Loads the translations, changes the global `$wp_locale` object and updates |
|
210 * all post type labels. |
|
211 * |
|
212 * @since 4.7.0 |
|
213 * |
|
214 * @global WP_Locale $wp_locale The WordPress date and time locale object. |
|
215 * |
|
216 * @param string $locale The locale to change to. |
|
217 */ |
|
218 private function change_locale( $locale ) { |
|
219 // Reset translation availability information. |
|
220 _get_path_to_translation( null, true ); |
|
221 |
|
222 $this->load_translations( $locale ); |
|
223 |
|
224 $GLOBALS['wp_locale'] = new WP_Locale(); |
|
225 |
|
226 /** |
|
227 * Fires when the locale is switched to or restored. |
|
228 * |
|
229 * @since 4.7.0 |
|
230 * |
|
231 * @param string $locale The new locale. |
|
232 */ |
|
233 do_action( 'change_locale', $locale ); |
|
234 } |
|
235 } |