changeset 21 | 48c4eec2b7e6 |
parent 19 | 3d72ae0968f4 |
child 22 | 8c2e4d02f4ef |
20:7b1b88e27a20 | 21:48c4eec2b7e6 |
---|---|
86 * If the user has a locale set to a non-empty string then it will be |
86 * If the user has a locale set to a non-empty string then it will be |
87 * returned. Otherwise it returns the locale of get_locale(). |
87 * returned. Otherwise it returns the locale of get_locale(). |
88 * |
88 * |
89 * @since 4.7.0 |
89 * @since 4.7.0 |
90 * |
90 * |
91 * @param int|WP_User $user_id User's ID or a WP_User object. Defaults to current user. |
91 * @param int|WP_User $user User's ID or a WP_User object. Defaults to current user. |
92 * @return string The locale of the user. |
92 * @return string The locale of the user. |
93 */ |
93 */ |
94 function get_user_locale( $user_id = 0 ) { |
94 function get_user_locale( $user = 0 ) { |
95 $user = false; |
95 $user_object = false; |
96 if ( 0 === $user_id && function_exists( 'wp_get_current_user' ) ) { |
96 |
97 $user = wp_get_current_user(); |
97 if ( 0 === $user && function_exists( 'wp_get_current_user' ) ) { |
98 } elseif ( $user_id instanceof WP_User ) { |
98 $user_object = wp_get_current_user(); |
99 $user = $user_id; |
99 } elseif ( $user instanceof WP_User ) { |
100 } elseif ( $user_id && is_numeric( $user_id ) ) { |
100 $user_object = $user; |
101 $user = get_user_by( 'id', $user_id ); |
101 } elseif ( $user && is_numeric( $user ) ) { |
102 } |
102 $user_object = get_user_by( 'id', $user ); |
103 |
103 } |
104 if ( ! $user ) { |
104 |
105 if ( ! $user_object ) { |
|
105 return get_locale(); |
106 return get_locale(); |
106 } |
107 } |
107 |
108 |
108 $locale = $user->locale; |
109 $locale = $user_object->locale; |
110 |
|
109 return $locale ? $locale : get_locale(); |
111 return $locale ? $locale : get_locale(); |
110 } |
112 } |
111 |
113 |
112 /** |
114 /** |
113 * Determine the current locale desired for the request. |
115 * Determines the current locale desired for the request. |
114 * |
116 * |
115 * @since 5.0.0 |
117 * @since 5.0.0 |
116 * |
118 * |
117 * @global string $pagenow The filename of the current screen. |
119 * @global string $pagenow The filename of the current screen. |
118 * |
120 * |
128 * |
130 * |
129 * @param string|null $locale The locale to return and short-circuit. Default null. |
131 * @param string|null $locale The locale to return and short-circuit. Default null. |
130 */ |
132 */ |
131 $determined_locale = apply_filters( 'pre_determine_locale', null ); |
133 $determined_locale = apply_filters( 'pre_determine_locale', null ); |
132 |
134 |
133 if ( ! empty( $determined_locale ) && is_string( $determined_locale ) ) { |
135 if ( $determined_locale && is_string( $determined_locale ) ) { |
134 return $determined_locale; |
136 return $determined_locale; |
135 } |
137 } |
136 |
138 |
137 $determined_locale = get_locale(); |
139 if ( |
138 |
140 isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] && |
139 if ( is_admin() ) { |
141 ( ! empty( $_GET['wp_lang'] ) || ! empty( $_COOKIE['wp_lang'] ) ) |
142 ) { |
|
143 if ( ! empty( $_GET['wp_lang'] ) ) { |
|
144 $determined_locale = sanitize_locale_name( $_GET['wp_lang'] ); |
|
145 } else { |
|
146 $determined_locale = sanitize_locale_name( $_COOKIE['wp_lang'] ); |
|
147 } |
|
148 } elseif ( |
|
149 is_admin() || |
|
150 ( isset( $_GET['_locale'] ) && 'user' === $_GET['_locale'] && wp_is_json_request() ) |
|
151 ) { |
|
140 $determined_locale = get_user_locale(); |
152 $determined_locale = get_user_locale(); |
141 } |
153 } elseif ( |
142 |
154 ( ! empty( $_REQUEST['language'] ) || isset( $GLOBALS['wp_local_package'] ) ) |
143 if ( isset( $_GET['_locale'] ) && 'user' === $_GET['_locale'] && wp_is_json_request() ) { |
155 && wp_installing() |
144 $determined_locale = get_user_locale(); |
156 ) { |
145 } |
157 if ( ! empty( $_REQUEST['language'] ) ) { |
146 |
158 $determined_locale = sanitize_locale_name( $_REQUEST['language'] ); |
147 $wp_lang = ''; |
159 } else { |
148 |
160 $determined_locale = $GLOBALS['wp_local_package']; |
149 if ( ! empty( $_GET['wp_lang'] ) ) { |
161 } |
150 $wp_lang = sanitize_text_field( $_GET['wp_lang'] ); |
162 } |
151 } elseif ( ! empty( $_COOKIE['wp_lang'] ) ) { |
163 |
152 $wp_lang = sanitize_text_field( $_COOKIE['wp_lang'] ); |
164 if ( ! $determined_locale ) { |
153 } |
165 $determined_locale = get_locale(); |
154 |
|
155 if ( ! empty( $wp_lang ) && ! empty( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] ) { |
|
156 $determined_locale = $wp_lang; |
|
157 } |
166 } |
158 |
167 |
159 /** |
168 /** |
160 * Filters the locale for the current request. |
169 * Filters the locale for the current request. |
161 * |
170 * |
162 * @since 5.0.0 |
171 * @since 5.0.0 |
163 * |
172 * |
164 * @param string $locale The locale. |
173 * @param string $determined_locale The locale. |
165 */ |
174 */ |
166 return apply_filters( 'determine_locale', $determined_locale ); |
175 return apply_filters( 'determine_locale', $determined_locale ); |
167 } |
176 } |
168 |
177 |
169 /** |
178 /** |
170 * Retrieve the translation of $text. |
179 * Retrieves the translation of $text. |
171 * |
180 * |
172 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
181 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
173 * |
182 * |
174 * *Note:* Don't use translate() directly, use __() or related functions. |
183 * *Note:* Don't use translate() directly, use __() or related functions. |
175 * |
184 * |
176 * @since 2.2.0 |
185 * @since 2.2.0 |
177 * @since 5.5.0 Introduced gettext-{$domain} filter. |
186 * @since 5.5.0 Introduced `gettext-{$domain}` filter. |
178 * |
187 * |
179 * @param string $text Text to translate. |
188 * @param string $text Text to translate. |
180 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
189 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
181 * Default 'default'. |
190 * Default 'default'. |
182 * @return string Translated text. |
191 * @return string Translated text. |
211 |
220 |
212 return $translation; |
221 return $translation; |
213 } |
222 } |
214 |
223 |
215 /** |
224 /** |
216 * Remove last item on a pipe-delimited string. |
225 * Removes last item on a pipe-delimited string. |
217 * |
226 * |
218 * Meant for removing the last item in a string, such as 'Role name|User role'. The original |
227 * Meant for removing the last item in a string, such as 'Role name|User role'. The original |
219 * string will be returned if no pipe '|' characters are found in the string. |
228 * string will be returned if no pipe '|' characters are found in the string. |
220 * |
229 * |
221 * @since 2.8.0 |
230 * @since 2.8.0 |
222 * |
231 * |
223 * @param string $string A pipe-delimited string. |
232 * @param string $text A pipe-delimited string. |
224 * @return string Either $string or everything before the last pipe. |
233 * @return string Either $text or everything before the last pipe. |
225 */ |
234 */ |
226 function before_last_bar( $string ) { |
235 function before_last_bar( $text ) { |
227 $last_bar = strrpos( $string, '|' ); |
236 $last_bar = strrpos( $text, '|' ); |
228 if ( false === $last_bar ) { |
237 if ( false === $last_bar ) { |
229 return $string; |
238 return $text; |
230 } else { |
239 } else { |
231 return substr( $string, 0, $last_bar ); |
240 return substr( $text, 0, $last_bar ); |
232 } |
241 } |
233 } |
242 } |
234 |
243 |
235 /** |
244 /** |
236 * Retrieve the translation of $text in the context defined in $context. |
245 * Retrieves the translation of $text in the context defined in $context. |
237 * |
246 * |
238 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
247 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
239 * |
248 * |
240 * *Note:* Don't use translate_with_gettext_context() directly, use _x() or related functions. |
249 * *Note:* Don't use translate_with_gettext_context() directly, use _x() or related functions. |
241 * |
250 * |
242 * @since 2.8.0 |
251 * @since 2.8.0 |
243 * @since 5.5.0 Introduced gettext_with_context-{$domain} filter. |
252 * @since 5.5.0 Introduced `gettext_with_context-{$domain}` filter. |
244 * |
253 * |
245 * @param string $text Text to translate. |
254 * @param string $text Text to translate. |
246 * @param string $context Context information for the translators. |
255 * @param string $context Context information for the translators. |
247 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
256 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
248 * Default 'default'. |
257 * Default 'default'. |
280 |
289 |
281 return $translation; |
290 return $translation; |
282 } |
291 } |
283 |
292 |
284 /** |
293 /** |
285 * Retrieve the translation of $text. |
294 * Retrieves the translation of $text. |
286 * |
295 * |
287 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
296 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
288 * |
297 * |
289 * @since 2.1.0 |
298 * @since 2.1.0 |
290 * |
299 * |
296 function __( $text, $domain = 'default' ) { |
305 function __( $text, $domain = 'default' ) { |
297 return translate( $text, $domain ); |
306 return translate( $text, $domain ); |
298 } |
307 } |
299 |
308 |
300 /** |
309 /** |
301 * Retrieve the translation of $text and escapes it for safe use in an attribute. |
310 * Retrieves the translation of $text and escapes it for safe use in an attribute. |
302 * |
311 * |
303 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
312 * If there is no translation, or the text domain isn't loaded, the original text is returned. |
304 * |
313 * |
305 * @since 2.8.0 |
314 * @since 2.8.0 |
306 * |
315 * |
312 function esc_attr__( $text, $domain = 'default' ) { |
321 function esc_attr__( $text, $domain = 'default' ) { |
313 return esc_attr( translate( $text, $domain ) ); |
322 return esc_attr( translate( $text, $domain ) ); |
314 } |
323 } |
315 |
324 |
316 /** |
325 /** |
317 * Retrieve the translation of $text and escapes it for safe use in HTML output. |
326 * Retrieves the translation of $text and escapes it for safe use in HTML output. |
318 * |
327 * |
319 * If there is no translation, or the text domain isn't loaded, the original text |
328 * If there is no translation, or the text domain isn't loaded, the original text |
320 * is escaped and returned. |
329 * is escaped and returned. |
321 * |
330 * |
322 * @since 2.8.0 |
331 * @since 2.8.0 |
329 function esc_html__( $text, $domain = 'default' ) { |
338 function esc_html__( $text, $domain = 'default' ) { |
330 return esc_html( translate( $text, $domain ) ); |
339 return esc_html( translate( $text, $domain ) ); |
331 } |
340 } |
332 |
341 |
333 /** |
342 /** |
334 * Display translated text. |
343 * Displays translated text. |
335 * |
344 * |
336 * @since 1.2.0 |
345 * @since 1.2.0 |
337 * |
346 * |
338 * @param string $text Text to translate. |
347 * @param string $text Text to translate. |
339 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
348 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
342 function _e( $text, $domain = 'default' ) { |
351 function _e( $text, $domain = 'default' ) { |
343 echo translate( $text, $domain ); |
352 echo translate( $text, $domain ); |
344 } |
353 } |
345 |
354 |
346 /** |
355 /** |
347 * Display translated text that has been escaped for safe use in an attribute. |
356 * Displays translated text that has been escaped for safe use in an attribute. |
348 * |
357 * |
349 * Encodes `< > & " '` (less than, greater than, ampersand, double quote, single quote). |
358 * Encodes `< > & " '` (less than, greater than, ampersand, double quote, single quote). |
350 * Will never double encode entities. |
359 * Will never double encode entities. |
351 * |
360 * |
352 * If you need the value for use in PHP, use esc_attr__(). |
361 * If you need the value for use in PHP, use esc_attr__(). |
360 function esc_attr_e( $text, $domain = 'default' ) { |
369 function esc_attr_e( $text, $domain = 'default' ) { |
361 echo esc_attr( translate( $text, $domain ) ); |
370 echo esc_attr( translate( $text, $domain ) ); |
362 } |
371 } |
363 |
372 |
364 /** |
373 /** |
365 * Display translated text that has been escaped for safe use in HTML output. |
374 * Displays translated text that has been escaped for safe use in HTML output. |
366 * |
375 * |
367 * If there is no translation, or the text domain isn't loaded, the original text |
376 * If there is no translation, or the text domain isn't loaded, the original text |
368 * is escaped and displayed. |
377 * is escaped and displayed. |
369 * |
378 * |
370 * If you need the value for use in PHP, use esc_html__(). |
379 * If you need the value for use in PHP, use esc_html__(). |
378 function esc_html_e( $text, $domain = 'default' ) { |
387 function esc_html_e( $text, $domain = 'default' ) { |
379 echo esc_html( translate( $text, $domain ) ); |
388 echo esc_html( translate( $text, $domain ) ); |
380 } |
389 } |
381 |
390 |
382 /** |
391 /** |
383 * Retrieve translated string with gettext context. |
392 * Retrieves translated string with gettext context. |
384 * |
393 * |
385 * Quite a few times, there will be collisions with similar translatable text |
394 * Quite a few times, there will be collisions with similar translatable text |
386 * found in more than two places, but with different translated context. |
395 * found in more than two places, but with different translated context. |
387 * |
396 * |
388 * By including the context in the pot file, translators can translate the two |
397 * By including the context in the pot file, translators can translate the two |
399 function _x( $text, $context, $domain = 'default' ) { |
408 function _x( $text, $context, $domain = 'default' ) { |
400 return translate_with_gettext_context( $text, $context, $domain ); |
409 return translate_with_gettext_context( $text, $context, $domain ); |
401 } |
410 } |
402 |
411 |
403 /** |
412 /** |
404 * Display translated string with gettext context. |
413 * Displays translated string with gettext context. |
405 * |
414 * |
406 * @since 3.0.0 |
415 * @since 3.0.0 |
407 * |
416 * |
408 * @param string $text Text to translate. |
417 * @param string $text Text to translate. |
409 * @param string $context Context information for the translators. |
418 * @param string $context Context information for the translators. |
413 function _ex( $text, $context, $domain = 'default' ) { |
422 function _ex( $text, $context, $domain = 'default' ) { |
414 echo _x( $text, $context, $domain ); |
423 echo _x( $text, $context, $domain ); |
415 } |
424 } |
416 |
425 |
417 /** |
426 /** |
418 * Translate string with gettext context, and escapes it for safe use in an attribute. |
427 * Translates string with gettext context, and escapes it for safe use in an attribute. |
419 * |
428 * |
420 * If there is no translation, or the text domain isn't loaded, the original text |
429 * If there is no translation, or the text domain isn't loaded, the original text |
421 * is escaped and returned. |
430 * is escaped and returned. |
422 * |
431 * |
423 * @since 2.8.0 |
432 * @since 2.8.0 |
431 function esc_attr_x( $text, $context, $domain = 'default' ) { |
440 function esc_attr_x( $text, $context, $domain = 'default' ) { |
432 return esc_attr( translate_with_gettext_context( $text, $context, $domain ) ); |
441 return esc_attr( translate_with_gettext_context( $text, $context, $domain ) ); |
433 } |
442 } |
434 |
443 |
435 /** |
444 /** |
436 * Translate string with gettext context, and escapes it for safe use in HTML output. |
445 * Translates string with gettext context, and escapes it for safe use in HTML output. |
437 * |
446 * |
438 * If there is no translation, or the text domain isn't loaded, the original text |
447 * If there is no translation, or the text domain isn't loaded, the original text |
439 * is escaped and returned. |
448 * is escaped and returned. |
440 * |
449 * |
441 * @since 2.9.0 |
450 * @since 2.9.0 |
459 * Example: |
468 * Example: |
460 * |
469 * |
461 * printf( _n( '%s person', '%s people', $count, 'text-domain' ), number_format_i18n( $count ) ); |
470 * printf( _n( '%s person', '%s people', $count, 'text-domain' ), number_format_i18n( $count ) ); |
462 * |
471 * |
463 * @since 2.8.0 |
472 * @since 2.8.0 |
464 * @since 5.5.0 Introduced ngettext-{$domain} filter. |
473 * @since 5.5.0 Introduced `ngettext-{$domain}` filter. |
465 * |
474 * |
466 * @param string $single The text to be used if the number is singular. |
475 * @param string $single The text to be used if the number is singular. |
467 * @param string $plural The text to be used if the number is plural. |
476 * @param string $plural The text to be used if the number is plural. |
468 * @param int $number The number to compare against to use either the singular or plural form. |
477 * @param int $number The number to compare against to use either the singular or plural form. |
469 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
478 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
480 * @since 2.2.0 |
489 * @since 2.2.0 |
481 * |
490 * |
482 * @param string $translation Translated text. |
491 * @param string $translation Translated text. |
483 * @param string $single The text to be used if the number is singular. |
492 * @param string $single The text to be used if the number is singular. |
484 * @param string $plural The text to be used if the number is plural. |
493 * @param string $plural The text to be used if the number is plural. |
485 * @param string $number The number to compare against to use either the singular or plural form. |
494 * @param int $number The number to compare against to use either the singular or plural form. |
486 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
495 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
487 */ |
496 */ |
488 $translation = apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain ); |
497 $translation = apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain ); |
489 |
498 |
490 /** |
499 /** |
495 * @since 5.5.0 |
504 * @since 5.5.0 |
496 * |
505 * |
497 * @param string $translation Translated text. |
506 * @param string $translation Translated text. |
498 * @param string $single The text to be used if the number is singular. |
507 * @param string $single The text to be used if the number is singular. |
499 * @param string $plural The text to be used if the number is plural. |
508 * @param string $plural The text to be used if the number is plural. |
500 * @param string $number The number to compare against to use either the singular or plural form. |
509 * @param int $number The number to compare against to use either the singular or plural form. |
501 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
510 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
502 */ |
511 */ |
503 $translation = apply_filters( "ngettext_{$domain}", $translation, $single, $plural, $number, $domain ); |
512 $translation = apply_filters( "ngettext_{$domain}", $translation, $single, $plural, $number, $domain ); |
504 |
513 |
505 return $translation; |
514 return $translation; |
517 * |
526 * |
518 * printf( _nx( '%s group', '%s groups', $people, 'group of people', 'text-domain' ), number_format_i18n( $people ) ); |
527 * printf( _nx( '%s group', '%s groups', $people, 'group of people', 'text-domain' ), number_format_i18n( $people ) ); |
519 * printf( _nx( '%s group', '%s groups', $animals, 'group of animals', 'text-domain' ), number_format_i18n( $animals ) ); |
528 * printf( _nx( '%s group', '%s groups', $animals, 'group of animals', 'text-domain' ), number_format_i18n( $animals ) ); |
520 * |
529 * |
521 * @since 2.8.0 |
530 * @since 2.8.0 |
522 * @since 5.5.0 Introduced ngettext_with_context-{$domain} filter. |
531 * @since 5.5.0 Introduced `ngettext_with_context-{$domain}` filter. |
523 * |
532 * |
524 * @param string $single The text to be used if the number is singular. |
533 * @param string $single The text to be used if the number is singular. |
525 * @param string $plural The text to be used if the number is plural. |
534 * @param string $plural The text to be used if the number is plural. |
526 * @param int $number The number to compare against to use either the singular or plural form. |
535 * @param int $number The number to compare against to use either the singular or plural form. |
527 * @param string $context Context information for the translators. |
536 * @param string $context Context information for the translators. |
539 * @since 2.8.0 |
548 * @since 2.8.0 |
540 * |
549 * |
541 * @param string $translation Translated text. |
550 * @param string $translation Translated text. |
542 * @param string $single The text to be used if the number is singular. |
551 * @param string $single The text to be used if the number is singular. |
543 * @param string $plural The text to be used if the number is plural. |
552 * @param string $plural The text to be used if the number is plural. |
544 * @param string $number The number to compare against to use either the singular or plural form. |
553 * @param int $number The number to compare against to use either the singular or plural form. |
545 * @param string $context Context information for the translators. |
554 * @param string $context Context information for the translators. |
546 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
555 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
547 */ |
556 */ |
548 $translation = apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain ); |
557 $translation = apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain ); |
549 |
558 |
555 * @since 5.5.0 |
564 * @since 5.5.0 |
556 * |
565 * |
557 * @param string $translation Translated text. |
566 * @param string $translation Translated text. |
558 * @param string $single The text to be used if the number is singular. |
567 * @param string $single The text to be used if the number is singular. |
559 * @param string $plural The text to be used if the number is plural. |
568 * @param string $plural The text to be used if the number is plural. |
560 * @param string $number The number to compare against to use either the singular or plural form. |
569 * @param int $number The number to compare against to use either the singular or plural form. |
561 * @param string $context Context information for the translators. |
570 * @param string $context Context information for the translators. |
562 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
571 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
563 */ |
572 */ |
564 $translation = apply_filters( "ngettext_with_context_{$domain}", $translation, $single, $plural, $number, $context, $domain ); |
573 $translation = apply_filters( "ngettext_with_context_{$domain}", $translation, $single, $plural, $number, $context, $domain ); |
565 |
574 |
585 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
594 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. |
586 * Default null. |
595 * Default null. |
587 * @return array { |
596 * @return array { |
588 * Array of translation information for the strings. |
597 * Array of translation information for the strings. |
589 * |
598 * |
590 * @type string $0 Singular form to be localized. No longer used. |
599 * @type string $0 Singular form to be localized. No longer used. |
591 * @type string $1 Plural form to be localized. No longer used. |
600 * @type string $1 Plural form to be localized. No longer used. |
592 * @type string $singular Singular form to be localized. |
601 * @type string $singular Singular form to be localized. |
593 * @type string $plural Plural form to be localized. |
602 * @type string $plural Plural form to be localized. |
594 * @type null $context Context information for the translators. |
603 * @type null $context Context information for the translators. |
595 * @type string $domain Text domain. |
604 * @type string|null $domain Text domain. |
596 * } |
605 * } |
597 */ |
606 */ |
598 function _n_noop( $singular, $plural, $domain = null ) { |
607 function _n_noop( $singular, $plural, $domain = null ) { |
599 return array( |
608 return array( |
600 0 => $singular, |
609 0 => $singular, |
652 'domain' => $domain, |
661 'domain' => $domain, |
653 ); |
662 ); |
654 } |
663 } |
655 |
664 |
656 /** |
665 /** |
657 * Translates and retrieves the singular or plural form of a string that's been registered |
666 * Translates and returns the singular or plural form of a string that's been registered |
658 * with _n_noop() or _nx_noop(). |
667 * with _n_noop() or _nx_noop(). |
659 * |
668 * |
660 * Used when you want to use a translatable plural string once the number is known. |
669 * Used when you want to use a translatable plural string once the number is known. |
661 * |
670 * |
662 * Example: |
671 * Example: |
665 * ... |
674 * ... |
666 * printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) ); |
675 * printf( translate_nooped_plural( $message, $count, 'text-domain' ), number_format_i18n( $count ) ); |
667 * |
676 * |
668 * @since 3.1.0 |
677 * @since 3.1.0 |
669 * |
678 * |
670 * @param array $nooped_plural Array with singular, plural, and context keys, usually the result of _n_noop() or _nx_noop(). |
679 * @param array $nooped_plural { |
680 * Array that is usually a return value from _n_noop() or _nx_noop(). |
|
681 * |
|
682 * @type string $singular Singular form to be localized. |
|
683 * @type string $plural Plural form to be localized. |
|
684 * @type string|null $context Context information for the translators. |
|
685 * @type string|null $domain Text domain. |
|
686 * } |
|
671 * @param int $count Number of objects. |
687 * @param int $count Number of objects. |
672 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. If $nooped_plural contains |
688 * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings. If $nooped_plural contains |
673 * a text domain passed to _n_noop() or _nx_noop(), it will override this value. Default 'default'. |
689 * a text domain passed to _n_noop() or _nx_noop(), it will override this value. Default 'default'. |
674 * @return string Either $single or $plural translated text. |
690 * @return string Either $singular or $plural translated text. |
675 */ |
691 */ |
676 function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) { |
692 function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) { |
677 if ( $nooped_plural['domain'] ) { |
693 if ( $nooped_plural['domain'] ) { |
678 $domain = $nooped_plural['domain']; |
694 $domain = $nooped_plural['domain']; |
679 } |
695 } |
684 return _n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain ); |
700 return _n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain ); |
685 } |
701 } |
686 } |
702 } |
687 |
703 |
688 /** |
704 /** |
689 * Load a .mo file into the text domain $domain. |
705 * Loads a .mo file into the text domain $domain. |
690 * |
706 * |
691 * If the text domain already exists, the translations will be merged. If both |
707 * If the text domain already exists, the translations will be merged. If both |
692 * sets have the same string, the translation from the original value will be taken. |
708 * sets have the same string, the translation from the original value will be taken. |
693 * |
709 * |
694 * On success, the .mo file will be placed in the $l10n global by $domain |
710 * On success, the .mo file will be placed in the $l10n global by $domain |
695 * and will be a MO object. |
711 * and will be a MO object. |
696 * |
712 * |
697 * @since 1.5.0 |
713 * @since 1.5.0 |
714 * @since 6.1.0 Added the `$locale` parameter. |
|
715 * |
|
716 * @global MO[] $l10n An array of all currently loaded text domains. |
|
717 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again. |
|
718 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. |
|
719 * |
|
720 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
721 * @param string $mofile Path to the .mo file. |
|
722 * @param string $locale Optional. Locale. Default is the current locale. |
|
723 * @return bool True on success, false on failure. |
|
724 */ |
|
725 function load_textdomain( $domain, $mofile, $locale = null ) { |
|
726 /** @var WP_Textdomain_Registry $wp_textdomain_registry */ |
|
727 global $l10n, $l10n_unloaded, $wp_textdomain_registry; |
|
728 |
|
729 $l10n_unloaded = (array) $l10n_unloaded; |
|
730 |
|
731 if ( ! is_string( $domain ) ) { |
|
732 return false; |
|
733 } |
|
734 |
|
735 /** |
|
736 * Filters whether to short-circuit loading .mo file. |
|
737 * |
|
738 * Returning a non-null value from the filter will effectively short-circuit |
|
739 * the loading, returning the passed value instead. |
|
740 * |
|
741 * @since 6.3.0 |
|
742 * |
|
743 * @param bool|null $loaded The result of loading a .mo file. Default null. |
|
744 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
745 * @param string $mofile Path to the MO file. |
|
746 * @param string|null $locale Locale. |
|
747 */ |
|
748 $loaded = apply_filters( 'pre_load_textdomain', null, $domain, $mofile, $locale ); |
|
749 if ( null !== $loaded ) { |
|
750 if ( true === $loaded ) { |
|
751 unset( $l10n_unloaded[ $domain ] ); |
|
752 } |
|
753 |
|
754 return $loaded; |
|
755 } |
|
756 |
|
757 /** |
|
758 * Filters whether to override the .mo file loading. |
|
759 * |
|
760 * @since 2.9.0 |
|
761 * @since 6.2.0 Added the `$locale` parameter. |
|
762 * |
|
763 * @param bool $override Whether to override the .mo file loading. Default false. |
|
764 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
765 * @param string $mofile Path to the MO file. |
|
766 * @param string|null $locale Locale. |
|
767 */ |
|
768 $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile, $locale ); |
|
769 |
|
770 if ( true === (bool) $plugin_override ) { |
|
771 unset( $l10n_unloaded[ $domain ] ); |
|
772 |
|
773 return true; |
|
774 } |
|
775 |
|
776 /** |
|
777 * Fires before the MO translation file is loaded. |
|
778 * |
|
779 * @since 2.9.0 |
|
780 * |
|
781 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
782 * @param string $mofile Path to the .mo file. |
|
783 */ |
|
784 do_action( 'load_textdomain', $domain, $mofile ); |
|
785 |
|
786 /** |
|
787 * Filters MO file path for loading translations for a specific text domain. |
|
788 * |
|
789 * @since 2.9.0 |
|
790 * |
|
791 * @param string $mofile Path to the MO file. |
|
792 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
793 */ |
|
794 $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain ); |
|
795 |
|
796 if ( ! $locale ) { |
|
797 $locale = determine_locale(); |
|
798 } |
|
799 |
|
800 $i18n_controller = WP_Translation_Controller::get_instance(); |
|
801 |
|
802 // Ensures the correct locale is set as the current one, in case it was filtered. |
|
803 $i18n_controller->set_locale( $locale ); |
|
804 |
|
805 /** |
|
806 * Filters the preferred file format for translation files. |
|
807 * |
|
808 * Can be used to disable the use of PHP files for translations. |
|
809 * |
|
810 * @since 6.5.0 |
|
811 * |
|
812 * @param string $preferred_format Preferred file format. Possible values: 'php', 'mo'. Default: 'php'. |
|
813 * @param string $domain The text domain. |
|
814 */ |
|
815 $preferred_format = apply_filters( 'translation_file_format', 'php', $domain ); |
|
816 if ( ! in_array( $preferred_format, array( 'php', 'mo' ), true ) ) { |
|
817 $preferred_format = 'php'; |
|
818 } |
|
819 |
|
820 $translation_files = array(); |
|
821 |
|
822 if ( 'mo' !== $preferred_format ) { |
|
823 $translation_files[] = substr_replace( $mofile, ".l10n.$preferred_format", - strlen( '.mo' ) ); |
|
824 } |
|
825 |
|
826 $translation_files[] = $mofile; |
|
827 |
|
828 foreach ( $translation_files as $file ) { |
|
829 /** |
|
830 * Filters the file path for loading translations for the given text domain. |
|
831 * |
|
832 * Similar to the {@see 'load_textdomain_mofile'} filter with the difference that |
|
833 * the file path could be for an MO or PHP file. |
|
834 * |
|
835 * @since 6.5.0 |
|
836 * @since 6.6.0 Added the `$locale` parameter. |
|
837 * |
|
838 * @param string $file Path to the translation file to load. |
|
839 * @param string $domain The text domain. |
|
840 * @param string $locale The locale. |
|
841 */ |
|
842 $file = (string) apply_filters( 'load_translation_file', $file, $domain, $locale ); |
|
843 |
|
844 $success = $i18n_controller->load_file( $file, $domain, $locale ); |
|
845 |
|
846 if ( $success ) { |
|
847 if ( isset( $l10n[ $domain ] ) && $l10n[ $domain ] instanceof MO ) { |
|
848 $i18n_controller->load_file( $l10n[ $domain ]->get_filename(), $domain, $locale ); |
|
849 } |
|
850 |
|
851 // Unset NOOP_Translations reference in get_translations_for_domain(). |
|
852 unset( $l10n[ $domain ] ); |
|
853 |
|
854 $l10n[ $domain ] = new WP_Translations( $i18n_controller, $domain ); |
|
855 |
|
856 $wp_textdomain_registry->set( $domain, $locale, dirname( $file ) ); |
|
857 |
|
858 return true; |
|
859 } |
|
860 } |
|
861 |
|
862 return false; |
|
863 } |
|
864 |
|
865 /** |
|
866 * Unloads translations for a text domain. |
|
867 * |
|
868 * @since 3.0.0 |
|
869 * @since 6.1.0 Added the `$reloadable` parameter. |
|
698 * |
870 * |
699 * @global MO[] $l10n An array of all currently loaded text domains. |
871 * @global MO[] $l10n An array of all currently loaded text domains. |
700 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again. |
872 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again. |
701 * |
873 * |
702 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
874 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
703 * @param string $mofile Path to the .mo file. |
875 * @param bool $reloadable Whether the text domain can be loaded just-in-time again. |
704 * @return bool True on success, false on failure. |
876 * @return bool Whether textdomain was unloaded. |
705 */ |
877 */ |
706 function load_textdomain( $domain, $mofile ) { |
878 function unload_textdomain( $domain, $reloadable = false ) { |
707 global $l10n, $l10n_unloaded; |
879 global $l10n, $l10n_unloaded; |
708 |
880 |
709 $l10n_unloaded = (array) $l10n_unloaded; |
881 $l10n_unloaded = (array) $l10n_unloaded; |
710 |
882 |
711 /** |
883 /** |
712 * Filters whether to override the .mo file loading. |
884 * Filters whether to override the text domain unloading. |
713 * |
885 * |
714 * @since 2.9.0 |
886 * @since 3.0.0 |
715 * |
887 * @since 6.1.0 Added the `$reloadable` parameter. |
716 * @param bool $override Whether to override the .mo file loading. Default false. |
888 * |
717 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
889 * @param bool $override Whether to override the text domain unloading. Default false. |
718 * @param string $mofile Path to the MO file. |
890 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
719 */ |
891 * @param bool $reloadable Whether the text domain can be loaded just-in-time again. |
720 $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile ); |
892 */ |
721 |
893 $plugin_override = apply_filters( 'override_unload_textdomain', false, $domain, $reloadable ); |
722 if ( true === (bool) $plugin_override ) { |
894 |
723 unset( $l10n_unloaded[ $domain ] ); |
895 if ( $plugin_override ) { |
896 if ( ! $reloadable ) { |
|
897 $l10n_unloaded[ $domain ] = true; |
|
898 } |
|
724 |
899 |
725 return true; |
900 return true; |
726 } |
901 } |
727 |
902 |
728 /** |
903 /** |
729 * Fires before the MO translation file is loaded. |
904 * Fires before the text domain is unloaded. |
730 * |
905 * |
731 * @since 2.9.0 |
906 * @since 3.0.0 |
732 * |
907 * @since 6.1.0 Added the `$reloadable` parameter. |
733 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
908 * |
734 * @param string $mofile Path to the .mo file. |
909 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
735 */ |
910 * @param bool $reloadable Whether the text domain can be loaded just-in-time again. |
736 do_action( 'load_textdomain', $domain, $mofile ); |
911 */ |
737 |
912 do_action( 'unload_textdomain', $domain, $reloadable ); |
738 /** |
913 |
739 * Filters MO file path for loading translations for a specific text domain. |
914 // Since multiple locales are supported, reloadable text domains don't actually need to be unloaded. |
740 * |
915 if ( ! $reloadable ) { |
741 * @since 2.9.0 |
916 WP_Translation_Controller::get_instance()->unload_textdomain( $domain ); |
742 * |
|
743 * @param string $mofile Path to the MO file. |
|
744 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
745 */ |
|
746 $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain ); |
|
747 |
|
748 if ( ! is_readable( $mofile ) ) { |
|
749 return false; |
|
750 } |
|
751 |
|
752 $mo = new MO(); |
|
753 if ( ! $mo->import_from_file( $mofile ) ) { |
|
754 return false; |
|
755 } |
917 } |
756 |
918 |
757 if ( isset( $l10n[ $domain ] ) ) { |
919 if ( isset( $l10n[ $domain ] ) ) { |
758 $mo->merge_with( $l10n[ $domain ] ); |
920 if ( $l10n[ $domain ] instanceof NOOP_Translations ) { |
759 } |
921 unset( $l10n[ $domain ] ); |
760 |
922 |
761 unset( $l10n_unloaded[ $domain ] ); |
923 return false; |
762 |
924 } |
763 $l10n[ $domain ] = &$mo; |
925 |
764 |
926 unset( $l10n[ $domain ] ); |
765 return true; |
927 |
766 } |
928 if ( ! $reloadable ) { |
767 |
929 $l10n_unloaded[ $domain ] = true; |
768 /** |
930 } |
769 * Unload translations for a text domain. |
|
770 * |
|
771 * @since 3.0.0 |
|
772 * |
|
773 * @global MO[] $l10n An array of all currently loaded text domains. |
|
774 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again. |
|
775 * |
|
776 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
777 * @return bool Whether textdomain was unloaded. |
|
778 */ |
|
779 function unload_textdomain( $domain ) { |
|
780 global $l10n, $l10n_unloaded; |
|
781 |
|
782 $l10n_unloaded = (array) $l10n_unloaded; |
|
783 |
|
784 /** |
|
785 * Filters whether to override the text domain unloading. |
|
786 * |
|
787 * @since 3.0.0 |
|
788 * |
|
789 * @param bool $override Whether to override the text domain unloading. Default false. |
|
790 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
791 */ |
|
792 $plugin_override = apply_filters( 'override_unload_textdomain', false, $domain ); |
|
793 |
|
794 if ( $plugin_override ) { |
|
795 $l10n_unloaded[ $domain ] = true; |
|
796 |
931 |
797 return true; |
932 return true; |
798 } |
933 } |
799 |
934 |
800 /** |
|
801 * Fires before the text domain is unloaded. |
|
802 * |
|
803 * @since 3.0.0 |
|
804 * |
|
805 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
806 */ |
|
807 do_action( 'unload_textdomain', $domain ); |
|
808 |
|
809 if ( isset( $l10n[ $domain ] ) ) { |
|
810 unset( $l10n[ $domain ] ); |
|
811 |
|
812 $l10n_unloaded[ $domain ] = true; |
|
813 |
|
814 return true; |
|
815 } |
|
816 |
|
817 return false; |
935 return false; |
818 } |
936 } |
819 |
937 |
820 /** |
938 /** |
821 * Load default translated strings based on locale. |
939 * Loads default translated strings based on locale. |
822 * |
940 * |
823 * Loads the .mo file in WP_LANG_DIR constant path from WordPress root. |
941 * Loads the .mo file in WP_LANG_DIR constant path from WordPress root. |
824 * The translated (.mo) file is named based on the locale. |
942 * The translated (.mo) file is named based on the locale. |
825 * |
943 * |
826 * @see load_textdomain() |
944 * @see load_textdomain() |
834 if ( null === $locale ) { |
952 if ( null === $locale ) { |
835 $locale = determine_locale(); |
953 $locale = determine_locale(); |
836 } |
954 } |
837 |
955 |
838 // Unload previously loaded strings so we can switch translations. |
956 // Unload previously loaded strings so we can switch translations. |
839 unload_textdomain( 'default' ); |
957 unload_textdomain( 'default', true ); |
840 |
958 |
841 $return = load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo" ); |
959 $return = load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo", $locale ); |
842 |
960 |
843 if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists( WP_LANG_DIR . "/admin-$locale.mo" ) ) { |
961 if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists( WP_LANG_DIR . "/admin-$locale.mo" ) ) { |
844 load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" ); |
962 load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo", $locale ); |
845 return $return; |
963 return $return; |
846 } |
964 } |
847 |
965 |
848 if ( is_admin() || wp_installing() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) ) { |
966 if ( is_admin() || wp_installing() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) ) { |
849 load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" ); |
967 load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo", $locale ); |
850 } |
968 } |
851 |
969 |
852 if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) { |
970 if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) { |
853 load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo" ); |
971 load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo", $locale ); |
854 } |
972 } |
855 |
973 |
856 return $return; |
974 return $return; |
857 } |
975 } |
858 |
976 |
872 * @param string|false $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR where the .mo file resides. |
990 * @param string|false $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR where the .mo file resides. |
873 * Default false. |
991 * Default false. |
874 * @return bool True when textdomain is successfully loaded, false otherwise. |
992 * @return bool True when textdomain is successfully loaded, false otherwise. |
875 */ |
993 */ |
876 function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) { |
994 function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) { |
995 /** @var WP_Textdomain_Registry $wp_textdomain_registry */ |
|
996 global $wp_textdomain_registry; |
|
997 |
|
998 if ( ! is_string( $domain ) ) { |
|
999 return false; |
|
1000 } |
|
1001 |
|
877 /** |
1002 /** |
878 * Filters a plugin's locale. |
1003 * Filters a plugin's locale. |
879 * |
1004 * |
880 * @since 3.0.0 |
1005 * @since 3.0.0 |
881 * |
1006 * |
885 $locale = apply_filters( 'plugin_locale', determine_locale(), $domain ); |
1010 $locale = apply_filters( 'plugin_locale', determine_locale(), $domain ); |
886 |
1011 |
887 $mofile = $domain . '-' . $locale . '.mo'; |
1012 $mofile = $domain . '-' . $locale . '.mo'; |
888 |
1013 |
889 // Try to load from the languages directory first. |
1014 // Try to load from the languages directory first. |
890 if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ) ) { |
1015 if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile, $locale ) ) { |
891 return true; |
1016 return true; |
892 } |
1017 } |
893 |
1018 |
894 if ( false !== $plugin_rel_path ) { |
1019 if ( false !== $plugin_rel_path ) { |
895 $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' ); |
1020 $path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' ); |
898 $path = ABSPATH . trim( $deprecated, '/' ); |
1023 $path = ABSPATH . trim( $deprecated, '/' ); |
899 } else { |
1024 } else { |
900 $path = WP_PLUGIN_DIR; |
1025 $path = WP_PLUGIN_DIR; |
901 } |
1026 } |
902 |
1027 |
903 return load_textdomain( $domain, $path . '/' . $mofile ); |
1028 $wp_textdomain_registry->set_custom_path( $domain, $path ); |
904 } |
1029 |
905 |
1030 return load_textdomain( $domain, $path . '/' . $mofile, $locale ); |
906 /** |
1031 } |
907 * Load the translated strings for a plugin residing in the mu-plugins directory. |
1032 |
1033 /** |
|
1034 * Loads the translated strings for a plugin residing in the mu-plugins directory. |
|
908 * |
1035 * |
909 * @since 3.0.0 |
1036 * @since 3.0.0 |
910 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first. |
1037 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first. |
1038 * |
|
1039 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. |
|
911 * |
1040 * |
912 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1041 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
913 * @param string $mu_plugin_rel_path Optional. Relative to `WPMU_PLUGIN_DIR` directory in which the .mo |
1042 * @param string $mu_plugin_rel_path Optional. Relative to `WPMU_PLUGIN_DIR` directory in which the .mo |
914 * file resides. Default empty string. |
1043 * file resides. Default empty string. |
915 * @return bool True when textdomain is successfully loaded, false otherwise. |
1044 * @return bool True when textdomain is successfully loaded, false otherwise. |
916 */ |
1045 */ |
917 function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { |
1046 function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { |
1047 /** @var WP_Textdomain_Registry $wp_textdomain_registry */ |
|
1048 global $wp_textdomain_registry; |
|
1049 |
|
1050 if ( ! is_string( $domain ) ) { |
|
1051 return false; |
|
1052 } |
|
1053 |
|
918 /** This filter is documented in wp-includes/l10n.php */ |
1054 /** This filter is documented in wp-includes/l10n.php */ |
919 $locale = apply_filters( 'plugin_locale', determine_locale(), $domain ); |
1055 $locale = apply_filters( 'plugin_locale', determine_locale(), $domain ); |
920 |
1056 |
921 $mofile = $domain . '-' . $locale . '.mo'; |
1057 $mofile = $domain . '-' . $locale . '.mo'; |
922 |
1058 |
923 // Try to load from the languages directory first. |
1059 // Try to load from the languages directory first. |
924 if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile ) ) { |
1060 if ( load_textdomain( $domain, WP_LANG_DIR . '/plugins/' . $mofile, $locale ) ) { |
925 return true; |
1061 return true; |
926 } |
1062 } |
927 |
1063 |
928 $path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' ); |
1064 $path = WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' ); |
929 |
1065 |
930 return load_textdomain( $domain, $path . '/' . $mofile ); |
1066 $wp_textdomain_registry->set_custom_path( $domain, $path ); |
931 } |
1067 |
932 |
1068 return load_textdomain( $domain, $path . '/' . $mofile, $locale ); |
933 /** |
1069 } |
934 * Load the theme's translated strings. |
1070 |
1071 /** |
|
1072 * Loads the theme's translated strings. |
|
935 * |
1073 * |
936 * If the current locale exists as a .mo file in the theme's root directory, it |
1074 * If the current locale exists as a .mo file in the theme's root directory, it |
937 * will be included in the translated strings by the $domain. |
1075 * will be included in the translated strings by the $domain. |
938 * |
1076 * |
939 * The .mo files must be named based on the locale exactly. |
1077 * The .mo files must be named based on the locale exactly. |
940 * |
1078 * |
941 * @since 1.5.0 |
1079 * @since 1.5.0 |
942 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first. |
1080 * @since 4.6.0 The function now tries to load the .mo file from the languages directory first. |
1081 * |
|
1082 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. |
|
943 * |
1083 * |
944 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1084 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
945 * @param string|false $path Optional. Path to the directory containing the .mo file. |
1085 * @param string|false $path Optional. Path to the directory containing the .mo file. |
946 * Default false. |
1086 * Default false. |
947 * @return bool True when textdomain is successfully loaded, false otherwise. |
1087 * @return bool True when textdomain is successfully loaded, false otherwise. |
948 */ |
1088 */ |
949 function load_theme_textdomain( $domain, $path = false ) { |
1089 function load_theme_textdomain( $domain, $path = false ) { |
1090 /** @var WP_Textdomain_Registry $wp_textdomain_registry */ |
|
1091 global $wp_textdomain_registry; |
|
1092 |
|
1093 if ( ! is_string( $domain ) ) { |
|
1094 return false; |
|
1095 } |
|
1096 |
|
950 /** |
1097 /** |
951 * Filters a theme's locale. |
1098 * Filters a theme's locale. |
952 * |
1099 * |
953 * @since 3.0.0 |
1100 * @since 3.0.0 |
954 * |
1101 * |
958 $locale = apply_filters( 'theme_locale', determine_locale(), $domain ); |
1105 $locale = apply_filters( 'theme_locale', determine_locale(), $domain ); |
959 |
1106 |
960 $mofile = $domain . '-' . $locale . '.mo'; |
1107 $mofile = $domain . '-' . $locale . '.mo'; |
961 |
1108 |
962 // Try to load from the languages directory first. |
1109 // Try to load from the languages directory first. |
963 if ( load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile ) ) { |
1110 if ( load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile, $locale ) ) { |
964 return true; |
1111 return true; |
965 } |
1112 } |
966 |
1113 |
967 if ( ! $path ) { |
1114 if ( ! $path ) { |
968 $path = get_template_directory(); |
1115 $path = get_template_directory(); |
969 } |
1116 } |
970 |
1117 |
971 return load_textdomain( $domain, $path . '/' . $locale . '.mo' ); |
1118 $wp_textdomain_registry->set_custom_path( $domain, $path ); |
972 } |
1119 |
973 |
1120 return load_textdomain( $domain, $path . '/' . $locale . '.mo', $locale ); |
974 /** |
1121 } |
975 * Load the child themes translated strings. |
1122 |
976 * |
1123 /** |
977 * If the current locale exists as a .mo file in the child themes |
1124 * Loads the child theme's translated strings. |
1125 * |
|
1126 * If the current locale exists as a .mo file in the child theme's |
|
978 * root directory, it will be included in the translated strings by the $domain. |
1127 * root directory, it will be included in the translated strings by the $domain. |
979 * |
1128 * |
980 * The .mo files must be named based on the locale exactly. |
1129 * The .mo files must be named based on the locale exactly. |
981 * |
1130 * |
982 * @since 2.9.0 |
1131 * @since 2.9.0 |
1006 * @param string $domain Optional. Text domain. Default 'default'. |
1155 * @param string $domain Optional. Text domain. Default 'default'. |
1007 * @param string $path Optional. The full file path to the directory containing translation files. |
1156 * @param string $path Optional. The full file path to the directory containing translation files. |
1008 * @return string|false The translated strings in JSON encoding on success, |
1157 * @return string|false The translated strings in JSON encoding on success, |
1009 * false if the script textdomain could not be loaded. |
1158 * false if the script textdomain could not be loaded. |
1010 */ |
1159 */ |
1011 function load_script_textdomain( $handle, $domain = 'default', $path = null ) { |
1160 function load_script_textdomain( $handle, $domain = 'default', $path = '' ) { |
1012 $wp_scripts = wp_scripts(); |
1161 $wp_scripts = wp_scripts(); |
1013 |
1162 |
1014 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) { |
1163 if ( ! isset( $wp_scripts->registered[ $handle ] ) ) { |
1015 return false; |
1164 return false; |
1016 } |
1165 } |
1030 } |
1179 } |
1031 } |
1180 } |
1032 |
1181 |
1033 $src = $wp_scripts->registered[ $handle ]->src; |
1182 $src = $wp_scripts->registered[ $handle ]->src; |
1034 |
1183 |
1035 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && 0 === strpos( $src, $wp_scripts->content_url ) ) ) { |
1184 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $wp_scripts->content_url && str_starts_with( $src, $wp_scripts->content_url ) ) ) { |
1036 $src = $wp_scripts->base_url . $src; |
1185 $src = $wp_scripts->base_url . $src; |
1037 } |
1186 } |
1038 |
1187 |
1039 $relative = false; |
1188 $relative = false; |
1040 $languages_path = WP_LANG_DIR; |
1189 $languages_path = WP_LANG_DIR; |
1044 $plugins_url = wp_parse_url( plugins_url() ); |
1193 $plugins_url = wp_parse_url( plugins_url() ); |
1045 $site_url = wp_parse_url( site_url() ); |
1194 $site_url = wp_parse_url( site_url() ); |
1046 |
1195 |
1047 // If the host is the same or it's a relative URL. |
1196 // If the host is the same or it's a relative URL. |
1048 if ( |
1197 if ( |
1049 ( ! isset( $content_url['path'] ) || strpos( $src_url['path'], $content_url['path'] ) === 0 ) && |
1198 ( ! isset( $content_url['path'] ) || str_starts_with( $src_url['path'], $content_url['path'] ) ) && |
1050 ( ! isset( $src_url['host'] ) || ! isset( $content_url['host'] ) || $src_url['host'] === $content_url['host'] ) |
1199 ( ! isset( $src_url['host'] ) || ! isset( $content_url['host'] ) || $src_url['host'] === $content_url['host'] ) |
1051 ) { |
1200 ) { |
1052 // Make the src relative the specific plugin or theme. |
1201 // Make the src relative the specific plugin or theme. |
1053 if ( isset( $content_url['path'] ) ) { |
1202 if ( isset( $content_url['path'] ) ) { |
1054 $relative = substr( $src_url['path'], strlen( $content_url['path'] ) ); |
1203 $relative = substr( $src_url['path'], strlen( $content_url['path'] ) ); |
1056 $relative = $src_url['path']; |
1205 $relative = $src_url['path']; |
1057 } |
1206 } |
1058 $relative = trim( $relative, '/' ); |
1207 $relative = trim( $relative, '/' ); |
1059 $relative = explode( '/', $relative ); |
1208 $relative = explode( '/', $relative ); |
1060 |
1209 |
1061 $languages_path = WP_LANG_DIR . '/' . $relative[0]; |
1210 $languages_path = WP_LANG_DIR . '/plugins'; |
1062 |
1211 |
1063 $relative = array_slice( $relative, 2 ); // Remove plugins/<plugin name> or themes/<theme name>. |
1212 $relative = array_slice( $relative, 2 ); // Remove plugins/<plugin name> or themes/<theme name>. |
1064 $relative = implode( '/', $relative ); |
1213 $relative = implode( '/', $relative ); |
1065 } elseif ( |
1214 } elseif ( |
1066 ( ! isset( $plugins_url['path'] ) || strpos( $src_url['path'], $plugins_url['path'] ) === 0 ) && |
1215 ( ! isset( $plugins_url['path'] ) || str_starts_with( $src_url['path'], $plugins_url['path'] ) ) && |
1067 ( ! isset( $src_url['host'] ) || ! isset( $plugins_url['host'] ) || $src_url['host'] === $plugins_url['host'] ) |
1216 ( ! isset( $src_url['host'] ) || ! isset( $plugins_url['host'] ) || $src_url['host'] === $plugins_url['host'] ) |
1068 ) { |
1217 ) { |
1069 // Make the src relative the specific plugin. |
1218 // Make the src relative the specific plugin. |
1070 if ( isset( $plugins_url['path'] ) ) { |
1219 if ( isset( $plugins_url['path'] ) ) { |
1071 $relative = substr( $src_url['path'], strlen( $plugins_url['path'] ) ); |
1220 $relative = substr( $src_url['path'], strlen( $plugins_url['path'] ) ); |
1080 $relative = array_slice( $relative, 1 ); // Remove <plugin name>. |
1229 $relative = array_slice( $relative, 1 ); // Remove <plugin name>. |
1081 $relative = implode( '/', $relative ); |
1230 $relative = implode( '/', $relative ); |
1082 } elseif ( ! isset( $src_url['host'] ) || ! isset( $site_url['host'] ) || $src_url['host'] === $site_url['host'] ) { |
1231 } elseif ( ! isset( $src_url['host'] ) || ! isset( $site_url['host'] ) || $src_url['host'] === $site_url['host'] ) { |
1083 if ( ! isset( $site_url['path'] ) ) { |
1232 if ( ! isset( $site_url['path'] ) ) { |
1084 $relative = trim( $src_url['path'], '/' ); |
1233 $relative = trim( $src_url['path'], '/' ); |
1085 } elseif ( ( strpos( $src_url['path'], trailingslashit( $site_url['path'] ) ) === 0 ) ) { |
1234 } elseif ( str_starts_with( $src_url['path'], trailingslashit( $site_url['path'] ) ) ) { |
1086 // Make the src relative to the WP root. |
1235 // Make the src relative to the WP root. |
1087 $relative = substr( $src_url['path'], strlen( $site_url['path'] ) ); |
1236 $relative = substr( $src_url['path'], strlen( $site_url['path'] ) ); |
1088 $relative = trim( $relative, '/' ); |
1237 $relative = trim( $relative, '/' ); |
1089 } |
1238 } |
1090 } |
1239 } |
1103 if ( false === $relative ) { |
1252 if ( false === $relative ) { |
1104 return load_script_translations( false, $handle, $domain ); |
1253 return load_script_translations( false, $handle, $domain ); |
1105 } |
1254 } |
1106 |
1255 |
1107 // Translations are always based on the unminified filename. |
1256 // Translations are always based on the unminified filename. |
1108 if ( substr( $relative, -7 ) === '.min.js' ) { |
1257 if ( str_ends_with( $relative, '.min.js' ) ) { |
1109 $relative = substr( $relative, 0, -7 ) . '.js'; |
1258 $relative = substr( $relative, 0, -7 ) . '.js'; |
1110 } |
1259 } |
1111 |
1260 |
1112 $md5_filename = $file_base . '-' . md5( $relative ) . '.json'; |
1261 $md5_filename = $file_base . '-' . md5( $relative ) . '.json'; |
1113 |
1262 |
1187 */ |
1336 */ |
1188 return apply_filters( 'load_script_translations', $translations, $file, $handle, $domain ); |
1337 return apply_filters( 'load_script_translations', $translations, $file, $handle, $domain ); |
1189 } |
1338 } |
1190 |
1339 |
1191 /** |
1340 /** |
1192 * Loads plugin and theme textdomains just-in-time. |
1341 * Loads plugin and theme text domains just-in-time. |
1193 * |
1342 * |
1194 * When a textdomain is encountered for the first time, we try to load |
1343 * When a textdomain is encountered for the first time, we try to load |
1195 * the translation file from `wp-content/languages`, removing the need |
1344 * the translation file from `wp-content/languages`, removing the need |
1196 * to call load_plugin_texdomain() or load_theme_texdomain(). |
1345 * to call load_plugin_textdomain() or load_theme_textdomain(). |
1197 * |
1346 * |
1198 * @since 4.6.0 |
1347 * @since 4.6.0 |
1199 * @access private |
1348 * @access private |
1200 * |
1349 * |
1201 * @see get_translations_for_domain() |
1350 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again. |
1202 * @global MO[] $l10n_unloaded An array of all text domains that have been unloaded again. |
1351 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. |
1203 * |
1352 * |
1204 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1353 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1205 * @return bool True when the textdomain is successfully loaded, false otherwise. |
1354 * @return bool True when the textdomain is successfully loaded, false otherwise. |
1206 */ |
1355 */ |
1207 function _load_textdomain_just_in_time( $domain ) { |
1356 function _load_textdomain_just_in_time( $domain ) { |
1208 global $l10n_unloaded; |
1357 /** @var WP_Textdomain_Registry $wp_textdomain_registry */ |
1358 global $l10n_unloaded, $wp_textdomain_registry; |
|
1209 |
1359 |
1210 $l10n_unloaded = (array) $l10n_unloaded; |
1360 $l10n_unloaded = (array) $l10n_unloaded; |
1211 |
1361 |
1212 // Short-circuit if domain is 'default' which is reserved for core. |
1362 // Short-circuit if domain is 'default' which is reserved for core. |
1213 if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) { |
1363 if ( 'default' === $domain || isset( $l10n_unloaded[ $domain ] ) ) { |
1214 return false; |
1364 return false; |
1215 } |
1365 } |
1216 |
1366 |
1217 $translation_path = _get_path_to_translation( $domain ); |
1367 if ( ! $wp_textdomain_registry->has( $domain ) ) { |
1218 if ( false === $translation_path ) { |
|
1219 return false; |
1368 return false; |
1220 } |
1369 } |
1221 |
1370 |
1222 return load_textdomain( $domain, $translation_path ); |
|
1223 } |
|
1224 |
|
1225 /** |
|
1226 * Gets the path to a translation file for loading a textdomain just in time. |
|
1227 * |
|
1228 * Caches the retrieved results internally. |
|
1229 * |
|
1230 * @since 4.7.0 |
|
1231 * @access private |
|
1232 * |
|
1233 * @see _load_textdomain_just_in_time() |
|
1234 * |
|
1235 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
1236 * @param bool $reset Whether to reset the internal cache. Used by the switch to locale functionality. |
|
1237 * @return string|false The path to the translation file or false if no translation file was found. |
|
1238 */ |
|
1239 function _get_path_to_translation( $domain, $reset = false ) { |
|
1240 static $available_translations = array(); |
|
1241 |
|
1242 if ( true === $reset ) { |
|
1243 $available_translations = array(); |
|
1244 } |
|
1245 |
|
1246 if ( ! isset( $available_translations[ $domain ] ) ) { |
|
1247 $available_translations[ $domain ] = _get_path_to_translation_from_lang_dir( $domain ); |
|
1248 } |
|
1249 |
|
1250 return $available_translations[ $domain ]; |
|
1251 } |
|
1252 |
|
1253 /** |
|
1254 * Gets the path to a translation file in the languages directory for the current locale. |
|
1255 * |
|
1256 * Holds a cached list of available .mo files to improve performance. |
|
1257 * |
|
1258 * @since 4.7.0 |
|
1259 * @access private |
|
1260 * |
|
1261 * @see _get_path_to_translation() |
|
1262 * |
|
1263 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
|
1264 * @return string|false The path to the translation file or false if no translation file was found. |
|
1265 */ |
|
1266 function _get_path_to_translation_from_lang_dir( $domain ) { |
|
1267 static $cached_mofiles = null; |
|
1268 |
|
1269 if ( null === $cached_mofiles ) { |
|
1270 $cached_mofiles = array(); |
|
1271 |
|
1272 $locations = array( |
|
1273 WP_LANG_DIR . '/plugins', |
|
1274 WP_LANG_DIR . '/themes', |
|
1275 ); |
|
1276 |
|
1277 foreach ( $locations as $location ) { |
|
1278 $mofiles = glob( $location . '/*.mo' ); |
|
1279 if ( $mofiles ) { |
|
1280 $cached_mofiles = array_merge( $cached_mofiles, $mofiles ); |
|
1281 } |
|
1282 } |
|
1283 } |
|
1284 |
|
1285 $locale = determine_locale(); |
1371 $locale = determine_locale(); |
1286 $mofile = "{$domain}-{$locale}.mo"; |
1372 $path = $wp_textdomain_registry->get( $domain, $locale ); |
1287 |
1373 if ( ! $path ) { |
1288 $path = WP_LANG_DIR . '/plugins/' . $mofile; |
1374 return false; |
1289 if ( in_array( $path, $cached_mofiles, true ) ) { |
1375 } |
1290 return $path; |
1376 // Themes with their language directory outside of WP_LANG_DIR have a different file name. |
1291 } |
1377 $template_directory = trailingslashit( get_template_directory() ); |
1292 |
1378 $stylesheet_directory = trailingslashit( get_stylesheet_directory() ); |
1293 $path = WP_LANG_DIR . '/themes/' . $mofile; |
1379 if ( str_starts_with( $path, $template_directory ) || str_starts_with( $path, $stylesheet_directory ) ) { |
1294 if ( in_array( $path, $cached_mofiles, true ) ) { |
1380 $mofile = "{$path}{$locale}.mo"; |
1295 return $path; |
1381 } else { |
1296 } |
1382 $mofile = "{$path}{$domain}-{$locale}.mo"; |
1297 |
1383 } |
1298 return false; |
1384 |
1299 } |
1385 return load_textdomain( $domain, $mofile, $locale ); |
1300 |
1386 } |
1301 /** |
1387 |
1302 * Return the Translations instance for a text domain. |
1388 /** |
1389 * Returns the Translations instance for a text domain. |
|
1303 * |
1390 * |
1304 * If there isn't one, returns empty Translations instance. |
1391 * If there isn't one, returns empty Translations instance. |
1305 * |
1392 * |
1306 * @since 2.8.0 |
1393 * @since 2.8.0 |
1307 * |
1394 * |
1308 * @global MO[] $l10n |
1395 * @global MO[] $l10n An array of all currently loaded text domains. |
1309 * |
1396 * |
1310 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1397 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1311 * @return Translations|NOOP_Translations A Translations instance. |
1398 * @return Translations|NOOP_Translations A Translations instance. |
1312 */ |
1399 */ |
1313 function get_translations_for_domain( $domain ) { |
1400 function get_translations_for_domain( $domain ) { |
1316 return $l10n[ $domain ]; |
1403 return $l10n[ $domain ]; |
1317 } |
1404 } |
1318 |
1405 |
1319 static $noop_translations = null; |
1406 static $noop_translations = null; |
1320 if ( null === $noop_translations ) { |
1407 if ( null === $noop_translations ) { |
1321 $noop_translations = new NOOP_Translations; |
1408 $noop_translations = new NOOP_Translations(); |
1322 } |
1409 } |
1410 |
|
1411 $l10n[ $domain ] = &$noop_translations; |
|
1323 |
1412 |
1324 return $noop_translations; |
1413 return $noop_translations; |
1325 } |
1414 } |
1326 |
1415 |
1327 /** |
1416 /** |
1328 * Whether there are translations for the text domain. |
1417 * Determines whether there are translations for the text domain. |
1329 * |
1418 * |
1330 * @since 3.0.0 |
1419 * @since 3.0.0 |
1331 * |
1420 * |
1332 * @global MO[] $l10n |
1421 * @global MO[] $l10n An array of all currently loaded text domains. |
1333 * |
1422 * |
1334 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1423 * @param string $domain Text domain. Unique identifier for retrieving translated strings. |
1335 * @return bool Whether there are translations. |
1424 * @return bool Whether there are translations. |
1336 */ |
1425 */ |
1337 function is_textdomain_loaded( $domain ) { |
1426 function is_textdomain_loaded( $domain ) { |
1338 global $l10n; |
1427 global $l10n; |
1339 return isset( $l10n[ $domain ] ); |
1428 return isset( $l10n[ $domain ] ) && ! $l10n[ $domain ] instanceof NOOP_Translations; |
1340 } |
1429 } |
1341 |
1430 |
1342 /** |
1431 /** |
1343 * Translates role name. |
1432 * Translates role name. |
1344 * |
1433 * |
1362 function translate_user_role( $name, $domain = 'default' ) { |
1451 function translate_user_role( $name, $domain = 'default' ) { |
1363 return translate_with_gettext_context( before_last_bar( $name ), 'User role', $domain ); |
1452 return translate_with_gettext_context( before_last_bar( $name ), 'User role', $domain ); |
1364 } |
1453 } |
1365 |
1454 |
1366 /** |
1455 /** |
1367 * Get all available languages based on the presence of *.mo files in a given directory. |
1456 * Gets all available languages based on the presence of *.mo and *.l10n.php files in a given directory. |
1368 * |
1457 * |
1369 * The default directory is WP_LANG_DIR. |
1458 * The default directory is WP_LANG_DIR. |
1370 * |
1459 * |
1371 * @since 3.0.0 |
1460 * @since 3.0.0 |
1372 * @since 4.7.0 The results are now filterable with the {@see 'get_available_languages'} filter. |
1461 * @since 4.7.0 The results are now filterable with the {@see 'get_available_languages'} filter. |
1462 * @since 6.5.0 The initial file list is now cached and also takes into account *.l10n.php files. |
|
1463 * |
|
1464 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. |
|
1373 * |
1465 * |
1374 * @param string $dir A directory to search for language files. |
1466 * @param string $dir A directory to search for language files. |
1375 * Default WP_LANG_DIR. |
1467 * Default WP_LANG_DIR. |
1376 * @return string[] An array of language codes or an empty array if no languages are present. Language codes are formed by stripping the .mo extension from the language file names. |
1468 * @return string[] An array of language codes or an empty array if no languages are present. |
1469 * Language codes are formed by stripping the file extension from the language file names. |
|
1377 */ |
1470 */ |
1378 function get_available_languages( $dir = null ) { |
1471 function get_available_languages( $dir = null ) { |
1472 global $wp_textdomain_registry; |
|
1473 |
|
1379 $languages = array(); |
1474 $languages = array(); |
1380 |
1475 |
1381 $lang_files = glob( ( is_null( $dir ) ? WP_LANG_DIR : $dir ) . '/*.mo' ); |
1476 $path = is_null( $dir ) ? WP_LANG_DIR : $dir; |
1477 $lang_files = $wp_textdomain_registry->get_language_files_from_path( $path ); |
|
1478 |
|
1382 if ( $lang_files ) { |
1479 if ( $lang_files ) { |
1383 foreach ( $lang_files as $lang_file ) { |
1480 foreach ( $lang_files as $lang_file ) { |
1384 $lang_file = basename( $lang_file, '.mo' ); |
1481 $lang_file = basename( $lang_file, '.mo' ); |
1385 if ( 0 !== strpos( $lang_file, 'continents-cities' ) && 0 !== strpos( $lang_file, 'ms-' ) && |
1482 $lang_file = basename( $lang_file, '.l10n.php' ); |
1386 0 !== strpos( $lang_file, 'admin-' ) ) { |
1483 |
1484 if ( ! str_starts_with( $lang_file, 'continents-cities' ) && ! str_starts_with( $lang_file, 'ms-' ) && |
|
1485 ! str_starts_with( $lang_file, 'admin-' ) ) { |
|
1387 $languages[] = $lang_file; |
1486 $languages[] = $lang_file; |
1388 } |
1487 } |
1389 } |
1488 } |
1390 } |
1489 } |
1391 |
1490 |
1395 * @since 4.7.0 |
1494 * @since 4.7.0 |
1396 * |
1495 * |
1397 * @param string[] $languages An array of available language codes. |
1496 * @param string[] $languages An array of available language codes. |
1398 * @param string $dir The directory where the language files were found. |
1497 * @param string $dir The directory where the language files were found. |
1399 */ |
1498 */ |
1400 return apply_filters( 'get_available_languages', $languages, $dir ); |
1499 return apply_filters( 'get_available_languages', array_unique( $languages ), $dir ); |
1401 } |
1500 } |
1402 |
1501 |
1403 /** |
1502 /** |
1404 * Get installed translations. |
1503 * Gets installed translations. |
1405 * |
1504 * |
1406 * Looks in the wp-content/languages directory for translations of |
1505 * Looks in the wp-content/languages directory for translations of |
1407 * plugins or themes. |
1506 * plugins or themes. |
1408 * |
1507 * |
1409 * @since 3.7.0 |
1508 * @since 3.7.0 |
1410 * |
1509 * |
1510 * @global WP_Textdomain_Registry $wp_textdomain_registry WordPress Textdomain Registry. |
|
1511 * |
|
1411 * @param string $type What to search for. Accepts 'plugins', 'themes', 'core'. |
1512 * @param string $type What to search for. Accepts 'plugins', 'themes', 'core'. |
1412 * @return array Array of language data. |
1513 * @return array Array of language data. |
1413 */ |
1514 */ |
1414 function wp_get_installed_translations( $type ) { |
1515 function wp_get_installed_translations( $type ) { |
1516 global $wp_textdomain_registry; |
|
1517 |
|
1415 if ( 'themes' !== $type && 'plugins' !== $type && 'core' !== $type ) { |
1518 if ( 'themes' !== $type && 'plugins' !== $type && 'core' !== $type ) { |
1416 return array(); |
1519 return array(); |
1417 } |
1520 } |
1418 |
1521 |
1419 $dir = 'core' === $type ? '' : "/$type"; |
1522 $dir = 'core' === $type ? WP_LANG_DIR : WP_LANG_DIR . "/$type"; |
1420 |
1523 |
1421 if ( ! is_dir( WP_LANG_DIR ) ) { |
1524 if ( ! is_dir( $dir ) ) { |
1422 return array(); |
1525 return array(); |
1423 } |
1526 } |
1424 |
1527 |
1425 if ( $dir && ! is_dir( WP_LANG_DIR . $dir ) ) { |
1528 $files = $wp_textdomain_registry->get_language_files_from_path( $dir ); |
1426 return array(); |
|
1427 } |
|
1428 |
|
1429 $files = scandir( WP_LANG_DIR . $dir ); |
|
1430 if ( ! $files ) { |
1529 if ( ! $files ) { |
1431 return array(); |
1530 return array(); |
1432 } |
1531 } |
1433 |
1532 |
1434 $language_data = array(); |
1533 $language_data = array(); |
1435 |
1534 |
1436 foreach ( $files as $file ) { |
1535 foreach ( $files as $file ) { |
1437 if ( '.' === $file[0] || is_dir( WP_LANG_DIR . "$dir/$file" ) ) { |
1536 if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?)\.(?:mo|l10n\.php)/', basename( $file ), $match ) ) { |
1438 continue; |
|
1439 } |
|
1440 if ( substr( $file, -3 ) !== '.po' ) { |
|
1441 continue; |
|
1442 } |
|
1443 if ( ! preg_match( '/(?:(.+)-)?([a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?).po/', $file, $match ) ) { |
|
1444 continue; |
|
1445 } |
|
1446 if ( ! in_array( substr( $file, 0, -3 ) . '.mo', $files, true ) ) { |
|
1447 continue; |
1537 continue; |
1448 } |
1538 } |
1449 |
1539 |
1450 list( , $textdomain, $language ) = $match; |
1540 list( , $textdomain, $language ) = $match; |
1451 if ( '' === $textdomain ) { |
1541 if ( '' === $textdomain ) { |
1452 $textdomain = 'default'; |
1542 $textdomain = 'default'; |
1453 } |
1543 } |
1454 $language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( WP_LANG_DIR . "$dir/$file" ); |
1544 |
1545 if ( str_ends_with( $file, '.mo' ) ) { |
|
1546 $pofile = substr_replace( $file, '.po', - strlen( '.mo' ) ); |
|
1547 |
|
1548 if ( ! file_exists( $pofile ) ) { |
|
1549 continue; |
|
1550 } |
|
1551 |
|
1552 $language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( $pofile ); |
|
1553 } else { |
|
1554 $pofile = substr_replace( $file, '.po', - strlen( '.l10n.php' ) ); |
|
1555 |
|
1556 // If both a PO and a PHP file exist, prefer the PO file. |
|
1557 if ( file_exists( $pofile ) ) { |
|
1558 continue; |
|
1559 } |
|
1560 |
|
1561 $language_data[ $textdomain ][ $language ] = wp_get_l10n_php_file_data( $file ); |
|
1562 } |
|
1455 } |
1563 } |
1456 return $language_data; |
1564 return $language_data; |
1457 } |
1565 } |
1458 |
1566 |
1459 /** |
1567 /** |
1460 * Extract headers from a PO file. |
1568 * Extracts headers from a PO file. |
1461 * |
1569 * |
1462 * @since 3.7.0 |
1570 * @since 3.7.0 |
1463 * |
1571 * |
1464 * @param string $po_file Path to PO file. |
1572 * @param string $po_file Path to PO file. |
1465 * @return string[] Array of PO file header values keyed by header name. |
1573 * @return string[] Array of PO file header values keyed by header name. |
1480 } |
1588 } |
1481 return $headers; |
1589 return $headers; |
1482 } |
1590 } |
1483 |
1591 |
1484 /** |
1592 /** |
1485 * Language selector. |
1593 * Extracts headers from a PHP translation file. |
1594 * |
|
1595 * @since 6.6.0 |
|
1596 * |
|
1597 * @param string $php_file Path to a `.l10n.php` file. |
|
1598 * @return string[] Array of file header values keyed by header name. |
|
1599 */ |
|
1600 function wp_get_l10n_php_file_data( $php_file ) { |
|
1601 $data = (array) include $php_file; |
|
1602 |
|
1603 unset( $data['messages'] ); |
|
1604 $headers = array( |
|
1605 'POT-Creation-Date' => 'pot-creation-date', |
|
1606 'PO-Revision-Date' => 'po-revision-date', |
|
1607 'Project-Id-Version' => 'project-id-version', |
|
1608 'X-Generator' => 'x-generator', |
|
1609 ); |
|
1610 |
|
1611 $result = array( |
|
1612 'POT-Creation-Date' => '', |
|
1613 'PO-Revision-Date' => '', |
|
1614 'Project-Id-Version' => '', |
|
1615 'X-Generator' => '', |
|
1616 ); |
|
1617 |
|
1618 foreach ( $headers as $po_header => $php_header ) { |
|
1619 if ( isset( $data[ $php_header ] ) ) { |
|
1620 $result[ $po_header ] = $data[ $php_header ]; |
|
1621 } |
|
1622 } |
|
1623 |
|
1624 return $result; |
|
1625 } |
|
1626 |
|
1627 /** |
|
1628 * Displays or returns a Language selector. |
|
1486 * |
1629 * |
1487 * @since 4.0.0 |
1630 * @since 4.0.0 |
1488 * @since 4.3.0 Introduced the `echo` argument. |
1631 * @since 4.3.0 Introduced the `echo` argument. |
1489 * @since 4.7.0 Introduced the `show_option_site_default` argument. |
1632 * @since 4.7.0 Introduced the `show_option_site_default` argument. |
1490 * @since 5.1.0 Introduced the `show_option_en_us` argument. |
1633 * @since 5.1.0 Introduced the `show_option_en_us` argument. |
1496 * @param string|array $args { |
1639 * @param string|array $args { |
1497 * Optional. Array or string of arguments for outputting the language selector. |
1640 * Optional. Array or string of arguments for outputting the language selector. |
1498 * |
1641 * |
1499 * @type string $id ID attribute of the select element. Default 'locale'. |
1642 * @type string $id ID attribute of the select element. Default 'locale'. |
1500 * @type string $name Name attribute of the select element. Default 'locale'. |
1643 * @type string $name Name attribute of the select element. Default 'locale'. |
1501 * @type array $languages List of installed languages, contain only the locales. |
1644 * @type string[] $languages List of installed languages, contain only the locales. |
1502 * Default empty array. |
1645 * Default empty array. |
1503 * @type array $translations List of available translations. Default result of |
1646 * @type array $translations List of available translations. Default result of |
1504 * wp_get_available_translations(). |
1647 * wp_get_available_translations(). |
1505 * @type string $selected Language which should be selected. Default empty. |
1648 * @type string $selected Language which should be selected. Default empty. |
1506 * @type bool|int $echo Whether to echo the generated markup. Accepts 0, 1, or their |
1649 * @type bool|int $echo Whether to echo the generated markup. Accepts 0, 1, or their |
1674 */ |
1817 */ |
1675 function switch_to_locale( $locale ) { |
1818 function switch_to_locale( $locale ) { |
1676 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
1819 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
1677 global $wp_locale_switcher; |
1820 global $wp_locale_switcher; |
1678 |
1821 |
1822 if ( ! $wp_locale_switcher ) { |
|
1823 return false; |
|
1824 } |
|
1825 |
|
1679 return $wp_locale_switcher->switch_to_locale( $locale ); |
1826 return $wp_locale_switcher->switch_to_locale( $locale ); |
1827 } |
|
1828 |
|
1829 /** |
|
1830 * Switches the translations according to the given user's locale. |
|
1831 * |
|
1832 * @since 6.2.0 |
|
1833 * |
|
1834 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. |
|
1835 * |
|
1836 * @param int $user_id User ID. |
|
1837 * @return bool True on success, false on failure. |
|
1838 */ |
|
1839 function switch_to_user_locale( $user_id ) { |
|
1840 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
|
1841 global $wp_locale_switcher; |
|
1842 |
|
1843 if ( ! $wp_locale_switcher ) { |
|
1844 return false; |
|
1845 } |
|
1846 |
|
1847 return $wp_locale_switcher->switch_to_user_locale( $user_id ); |
|
1680 } |
1848 } |
1681 |
1849 |
1682 /** |
1850 /** |
1683 * Restores the translations according to the previous locale. |
1851 * Restores the translations according to the previous locale. |
1684 * |
1852 * |
1690 */ |
1858 */ |
1691 function restore_previous_locale() { |
1859 function restore_previous_locale() { |
1692 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
1860 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
1693 global $wp_locale_switcher; |
1861 global $wp_locale_switcher; |
1694 |
1862 |
1863 if ( ! $wp_locale_switcher ) { |
|
1864 return false; |
|
1865 } |
|
1866 |
|
1695 return $wp_locale_switcher->restore_previous_locale(); |
1867 return $wp_locale_switcher->restore_previous_locale(); |
1696 } |
1868 } |
1697 |
1869 |
1698 /** |
1870 /** |
1699 * Restores the translations according to the original locale. |
1871 * Restores the translations according to the original locale. |
1706 */ |
1878 */ |
1707 function restore_current_locale() { |
1879 function restore_current_locale() { |
1708 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
1880 /* @var WP_Locale_Switcher $wp_locale_switcher */ |
1709 global $wp_locale_switcher; |
1881 global $wp_locale_switcher; |
1710 |
1882 |
1883 if ( ! $wp_locale_switcher ) { |
|
1884 return false; |
|
1885 } |
|
1886 |
|
1711 return $wp_locale_switcher->restore_current_locale(); |
1887 return $wp_locale_switcher->restore_current_locale(); |
1712 } |
1888 } |
1713 |
1889 |
1714 /** |
1890 /** |
1715 * Whether switch_to_locale() is in effect. |
1891 * Determines whether switch_to_locale() is in effect. |
1716 * |
1892 * |
1717 * @since 4.7.0 |
1893 * @since 4.7.0 |
1718 * |
1894 * |
1719 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. |
1895 * @global WP_Locale_Switcher $wp_locale_switcher WordPress locale switcher object. |
1720 * |
1896 * |
1781 * @return string Locale-specific list item separator. |
1957 * @return string Locale-specific list item separator. |
1782 */ |
1958 */ |
1783 function wp_get_list_item_separator() { |
1959 function wp_get_list_item_separator() { |
1784 global $wp_locale; |
1960 global $wp_locale; |
1785 |
1961 |
1962 if ( ! ( $wp_locale instanceof WP_Locale ) ) { |
|
1963 // Default value of WP_Locale::get_list_item_separator(). |
|
1964 /* translators: Used between list items, there is a space after the comma. */ |
|
1965 return __( ', ' ); |
|
1966 } |
|
1967 |
|
1786 return $wp_locale->get_list_item_separator(); |
1968 return $wp_locale->get_list_item_separator(); |
1787 } |
1969 } |
1970 |
|
1971 /** |
|
1972 * Retrieves the word count type based on the locale. |
|
1973 * |
|
1974 * @since 6.2.0 |
|
1975 * |
|
1976 * @global WP_Locale $wp_locale WordPress date and time locale object. |
|
1977 * |
|
1978 * @return string Locale-specific word count type. Possible values are `characters_excluding_spaces`, |
|
1979 * `characters_including_spaces`, or `words`. Defaults to `words`. |
|
1980 */ |
|
1981 function wp_get_word_count_type() { |
|
1982 global $wp_locale; |
|
1983 |
|
1984 if ( ! ( $wp_locale instanceof WP_Locale ) ) { |
|
1985 // Default value of WP_Locale::get_word_count_type(). |
|
1986 return 'words'; |
|
1987 } |
|
1988 |
|
1989 return $wp_locale->get_word_count_type(); |
|
1990 } |