WordPress 4.7
[autoinstalls/wordpress.git] / wp-includes / class-wp-locale-switcher.php
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     = is_admin() ? get_user_locale() : get_locale();
52                 $this->available_languages = array_merge( array( 'en_US' ), 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                 $current_locale = is_admin() ? get_user_locale() : get_locale();
74                 if ( $current_locale === $locale ) {
75                         return false;
76                 }
77
78                 if ( ! in_array( $locale, $this->available_languages, true ) ) {
79                         return false;
80                 }
81
82                 $this->locales[] = $locale;
83
84                 $this->change_locale( $locale );
85
86                 /**
87                  * Fires when the locale is switched.
88                  *
89                  * @since 4.7.0
90                  *
91                  * @param string $locale The new locale.
92                  */
93                 do_action( 'switch_locale', $locale );
94
95                 return true;
96         }
97
98         /**
99          * Restores the translations according to the previous locale.
100          *
101          * @since 4.7.0
102          *
103          * @return string|false Locale on success, false on failure.
104          */
105         public function restore_previous_locale() {
106                 $previous_locale = array_pop( $this->locales );
107
108                 if ( null === $previous_locale ) {
109                         // The stack is empty, bail.
110                         return false;
111                 }
112
113                 $locale = end( $this->locales );
114
115                 if ( ! $locale ) {
116                         // There's nothing left in the stack: go back to the original locale.
117                         $locale = $this->original_locale;
118                 }
119
120                 $this->change_locale( $locale );
121
122                 /**
123                  * Fires when the locale is restored to the previous one.
124                  *
125                  * @since 4.7.0
126                  *
127                  * @param string $locale          The new locale.
128                  * @param string $previous_locale The previous locale.
129                  */
130                 do_action( 'restore_previous_locale', $locale, $previous_locale );
131
132                 return $locale;
133         }
134
135         /**
136          * Restores the translations according to the original locale.
137          *
138          * @since 4.7.0
139          *
140          * @return string|false Locale on success, false on failure.
141          */
142         public function restore_current_locale() {
143                 if ( empty( $this->locales ) ) {
144                         return false;
145                 }
146
147                 $this->locales = array( $this->original_locale );
148
149                 return $this->restore_previous_locale();
150         }
151
152         /**
153          * Whether switch_to_locale() is in effect.
154          *
155          * @since 4.7.0
156          *
157          * @return bool True if the locale has been switched, false otherwise.
158          */
159         public function is_switched() {
160                 return ! empty( $this->locales );
161         }
162
163         /**
164          * Filters the WordPress install's locale.
165          *
166          * @since 4.7.0
167          *
168          * @param string $locale The WordPress install's locale.
169          * @return string The locale currently being switched to.
170          */
171         public function filter_locale( $locale ) {
172                 $switched_locale = end( $this->locales );
173
174                 if ( $switched_locale ) {
175                         return $switched_locale;
176                 }
177
178                 return $locale;
179         }
180
181         /**
182          * Load translations for a given locale.
183          *
184          * When switching to a locale, translations for this locale must be loaded from scratch.
185          *
186          * @since 4.7.0
187          * @access private
188          *
189          * @global Mo[] $l10n An array of all currently loaded text domains.
190          *
191          * @param string $locale The locale to load translations for.
192          */
193         private function load_translations( $locale ) {
194                 global $l10n;
195
196                 $domains = $l10n ? array_keys( $l10n ) : array();
197
198                 load_default_textdomain( $locale );
199
200                 foreach ( $domains as $domain ) {
201                         if ( 'default' === $domain ) {
202                                 continue;
203                         }
204
205                         unload_textdomain( $domain );
206                         get_translations_for_domain( $domain );
207                 }
208         }
209
210         /**
211          * Changes the site's locale to the given one.
212          *
213          * Loads the translations, changes the global `$wp_locale` object and updates
214          * all post type labels.
215          *
216          * @since 4.7.0
217          * @access private
218          *
219          * @global WP_Locale $wp_locale The WordPress date and time locale object.
220          *
221          * @param string $locale The locale to change to.
222          */
223         private function change_locale( $locale ) {
224                 // Reset translation availability information.
225                 _get_path_to_translation( null, true );
226
227                 $this->load_translations( $locale );
228
229                 $GLOBALS['wp_locale'] = new WP_Locale();
230
231                 /**
232                  * Fires when the locale is switched to or restored.
233                  *
234                  * @since 4.7.0
235                  *
236                  * @param string $locale The new locale.
237                  */
238                 do_action( 'change_locale', $locale );
239         }
240 }