wp/wp-includes/l10n.php
changeset 0 d970ebf37754
child 5 5e2f62d02dcd
equal deleted inserted replaced
-1:000000000000 0:d970ebf37754
       
     1 <?php
       
     2 /**
       
     3  * WordPress Translation API
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage i18n
       
     7  */
       
     8 
       
     9 /**
       
    10  * Get the current locale.
       
    11  *
       
    12  * If the locale is set, then it will filter the locale in the 'locale' filter
       
    13  * hook and return the value.
       
    14  *
       
    15  * If the locale is not set already, then the WPLANG constant is used if it is
       
    16  * defined. Then it is filtered through the 'locale' filter hook and the value
       
    17  * for the locale global set and the locale is returned.
       
    18  *
       
    19  * The process to get the locale should only be done once, but the locale will
       
    20  * always be filtered using the 'locale' hook.
       
    21  *
       
    22  * @since 1.5.0
       
    23  *
       
    24  * @return string The locale of the blog or from the 'locale' hook.
       
    25  */
       
    26 function get_locale() {
       
    27 	global $locale;
       
    28 
       
    29 	if ( isset( $locale ) )
       
    30 		/**
       
    31 		 * Filter WordPress install's locale ID.
       
    32 		 *
       
    33 		 * @since 1.5.2
       
    34 		 *
       
    35 		 * @param string $locale The locale ID.
       
    36 		 */
       
    37 		return apply_filters( 'locale', $locale );
       
    38 
       
    39 	// WPLANG is defined in wp-config.
       
    40 	if ( defined( 'WPLANG' ) )
       
    41 		$locale = WPLANG;
       
    42 
       
    43 	// If multisite, check options.
       
    44 	if ( is_multisite() ) {
       
    45 		// Don't check blog option when installing.
       
    46 		if ( defined( 'WP_INSTALLING' ) || ( false === $ms_locale = get_option( 'WPLANG' ) ) )
       
    47 			$ms_locale = get_site_option('WPLANG');
       
    48 
       
    49 		if ( $ms_locale !== false )
       
    50 			$locale = $ms_locale;
       
    51 	}
       
    52 
       
    53 	if ( empty( $locale ) )
       
    54 		$locale = 'en_US';
       
    55 
       
    56 	// duplicate_hook
       
    57 	return apply_filters( 'locale', $locale );
       
    58 }
       
    59 
       
    60 /**
       
    61  * Retrieve the translation of $text.
       
    62  *
       
    63  * If there is no translation, or the text domain isn't loaded, the original text is returned.
       
    64  *
       
    65  * <strong>Note:</strong> Don't use translate() directly, use __() or related functions.
       
    66  *
       
    67  * @since 2.2.0
       
    68  *
       
    69  * @param string $text   Text to translate.
       
    70  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
    71  * @return string Translated text
       
    72  */
       
    73 function translate( $text, $domain = 'default' ) {
       
    74 	$translations = get_translations_for_domain( $domain );
       
    75 	$translations = $translations->translate( $text );
       
    76 	/**
       
    77 	 * Filter text with its translation.
       
    78 	 *
       
    79 	 * @since 2.0.11
       
    80 	 *
       
    81 	 * @param string $translations Translated text.
       
    82 	 * @param string $text         Text to translate.
       
    83 	 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
       
    84 	 */
       
    85 	return apply_filters( 'gettext', $translations, $text, $domain );
       
    86 }
       
    87 
       
    88 /**
       
    89  * Remove last item on a pipe-delimited string.
       
    90  *
       
    91  * Meant for removing the last item in a string, such as 'Role name|User role'. The original
       
    92  * string will be returned if no pipe '|' characters are found in the string.
       
    93  *
       
    94  * @since 2.8.0
       
    95  *
       
    96  * @param string $string A pipe-delimited string.
       
    97  * @return string Either $string or everything before the last pipe.
       
    98  */
       
    99 function before_last_bar( $string ) {
       
   100 	$last_bar = strrpos( $string, '|' );
       
   101 	if ( false == $last_bar )
       
   102 		return $string;
       
   103 	else
       
   104 		return substr( $string, 0, $last_bar );
       
   105 }
       
   106 
       
   107 /**
       
   108  * Retrieve the translation of $text in the context defined in $context.
       
   109  *
       
   110  * If there is no translation, or the text domain isn't loaded the original
       
   111  * text is returned.
       
   112  *
       
   113  * @since 2.8.0
       
   114  *
       
   115  * @param string $text    Text to translate.
       
   116  * @param string $context Context information for the translators.
       
   117  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   118  * @return string Translated text on success, original text on failure.
       
   119  */
       
   120 function translate_with_gettext_context( $text, $context, $domain = 'default' ) {
       
   121 	$translations = get_translations_for_domain( $domain );
       
   122 	$translations = $translations->translate( $text, $context );
       
   123 	/**
       
   124 	 * Filter text with its translation based on context information.
       
   125 	 *
       
   126 	 * @since 2.8.0
       
   127 	 *
       
   128 	 * @param string $translations Translated text.
       
   129 	 * @param string $text         Text to translate.
       
   130 	 * @param string $context      Context information for the translators.
       
   131 	 * @param string $domain       Text domain. Unique identifier for retrieving translated strings.
       
   132 	 */
       
   133 	return apply_filters( 'gettext_with_context', $translations, $text, $context, $domain );
       
   134 }
       
   135 
       
   136 /**
       
   137  * Retrieve the translation of $text. If there is no translation,
       
   138  * or the text domain isn't loaded, the original text is returned.
       
   139  *
       
   140  * @since 2.1.0
       
   141  *
       
   142  * @param string $text   Text to translate.
       
   143  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   144  * @return string Translated text.
       
   145  */
       
   146 function __( $text, $domain = 'default' ) {
       
   147 	return translate( $text, $domain );
       
   148 }
       
   149 
       
   150 /**
       
   151  * Retrieve the translation of $text and escapes it for safe use in an attribute.
       
   152  *
       
   153  * If there is no translation, or the text domain isn't loaded, the original text is returned.
       
   154  *
       
   155  * @since 2.8.0
       
   156  *
       
   157  * @param string $text   Text to translate.
       
   158  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   159  * @return string Translated text on success, original text on failure.
       
   160  */
       
   161 function esc_attr__( $text, $domain = 'default' ) {
       
   162 	return esc_attr( translate( $text, $domain ) );
       
   163 }
       
   164 
       
   165 /**
       
   166  * Retrieve the translation of $text and escapes it for safe use in HTML output.
       
   167  *
       
   168  * If there is no translation, or the text domain isn't loaded, the original text is returned.
       
   169  *
       
   170  * @since 2.8.0
       
   171  *
       
   172  * @param string $text   Text to translate.
       
   173  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   174  * @return string Translated text
       
   175  */
       
   176 function esc_html__( $text, $domain = 'default' ) {
       
   177 	return esc_html( translate( $text, $domain ) );
       
   178 }
       
   179 
       
   180 /**
       
   181  * Display translated text.
       
   182  *
       
   183  * @since 1.2.0
       
   184  *
       
   185  * @param string $text   Text to translate.
       
   186  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   187  */
       
   188 function _e( $text, $domain = 'default' ) {
       
   189 	echo translate( $text, $domain );
       
   190 }
       
   191 
       
   192 /**
       
   193  * Display translated text that has been escaped for safe use in an attribute.
       
   194  *
       
   195  * @since 2.8.0
       
   196  *
       
   197  * @param string $text   Text to translate.
       
   198  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   199  */
       
   200 function esc_attr_e( $text, $domain = 'default' ) {
       
   201 	echo esc_attr( translate( $text, $domain ) );
       
   202 }
       
   203 
       
   204 /**
       
   205  * Display translated text that has been escaped for safe use in HTML output.
       
   206  *
       
   207  * @since 2.8.0
       
   208  *
       
   209  * @param string $text   Text to translate.
       
   210  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   211  */
       
   212 function esc_html_e( $text, $domain = 'default' ) {
       
   213 	echo esc_html( translate( $text, $domain ) );
       
   214 }
       
   215 
       
   216 /**
       
   217  * Retrieve translated string with gettext context.
       
   218  *
       
   219  * Quite a few times, there will be collisions with similar translatable text
       
   220  * found in more than two places, but with different translated context.
       
   221  *
       
   222  * By including the context in the pot file, translators can translate the two
       
   223  * strings differently.
       
   224  *
       
   225  * @since 2.8.0
       
   226  *
       
   227  * @param string $text    Text to translate.
       
   228  * @param string $context Context information for the translators.
       
   229  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   230  * @return string Translated context string without pipe.
       
   231  */
       
   232 function _x( $text, $context, $domain = 'default' ) {
       
   233 	return translate_with_gettext_context( $text, $context, $domain );
       
   234 }
       
   235 
       
   236 /**
       
   237  * Display translated string with gettext context.
       
   238  *
       
   239  * @since 3.0.0
       
   240  *
       
   241  * @param string $text    Text to translate.
       
   242  * @param string $context Context information for the translators.
       
   243  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   244  * @return string Translated context string without pipe.
       
   245  */
       
   246 function _ex( $text, $context, $domain = 'default' ) {
       
   247 	echo _x( $text, $context, $domain );
       
   248 }
       
   249 
       
   250 /**
       
   251  * Translate string with gettext context, and escapes it for safe use in an attribute.
       
   252  *
       
   253  * @since 2.8.0
       
   254  *
       
   255  * @param string $text    Text to translate.
       
   256  * @param string $context Context information for the translators.
       
   257  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   258  * @return string Translated text
       
   259  */
       
   260 function esc_attr_x( $text, $context, $domain = 'default' ) {
       
   261 	return esc_attr( translate_with_gettext_context( $text, $context, $domain ) );
       
   262 }
       
   263 
       
   264 /**
       
   265  * Translate string with gettext context, and escapes it for safe use in HTML output.
       
   266  *
       
   267  * @since 2.9.0
       
   268  *
       
   269  * @param string $text    Text to translate.
       
   270  * @param string $context Context information for the translators.
       
   271  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   272  * @return string Translated text.
       
   273  */
       
   274 function esc_html_x( $text, $context, $domain = 'default' ) {
       
   275 	return esc_html( translate_with_gettext_context( $text, $context, $domain ) );
       
   276 }
       
   277 
       
   278 /**
       
   279  * Retrieve the plural or single form based on the supplied amount.
       
   280  *
       
   281  * If the text domain is not set in the $l10n list, then a comparison will be made
       
   282  * and either $plural or $single parameters returned.
       
   283  *
       
   284  * If the text domain does exist, then the parameters $single, $plural, and $number
       
   285  * will first be passed to the text domain's ngettext method. Then it will be passed
       
   286  * to the 'ngettext' filter hook along with the same parameters. The expected
       
   287  * type will be a string.
       
   288  *
       
   289  * @since 2.8.0
       
   290  *
       
   291  * @param string $single The text that will be used if $number is 1.
       
   292  * @param string $plural The text that will be used if $number is not 1.
       
   293  * @param int    $number The number to compare against to use either $single or $plural.
       
   294  * @param string $domain Optional. Text domain. Unique identifier for retrieving translated strings.
       
   295  * @return string Either $single or $plural translated text.
       
   296  */
       
   297 function _n( $single, $plural, $number, $domain = 'default' ) {
       
   298 	$translations = get_translations_for_domain( $domain );
       
   299 	$translation = $translations->translate_plural( $single, $plural, $number );
       
   300 	/**
       
   301 	 * Filter text with its translation when plural option is available.
       
   302 	 *
       
   303 	 * @since 2.2.0
       
   304 	 *
       
   305 	 * @param string $translation Translated text.
       
   306 	 * @param string $single      The text that will be used if $number is 1.
       
   307 	 * @param string $plural      The text that will be used if $number is not 1.
       
   308 	 * @param string $number      The number to compare against to use either $single or $plural.
       
   309 	 * @param string $domain      Text domain. Unique identifier for retrieving translated strings.
       
   310 	 */
       
   311 	return apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain );
       
   312 }
       
   313 
       
   314 /**
       
   315  * Retrieve the plural or single form based on the supplied amount with gettext context.
       
   316  *
       
   317  * This is a hybrid of _n() and _x(). It supports contexts and plurals.
       
   318  *
       
   319  * @since 2.8.0
       
   320  *
       
   321  * @param string $single  The text that will be used if $number is 1.
       
   322  * @param string $plural  The text that will be used if $number is not 1.
       
   323  * @param int    $number  The number to compare against to use either $single or $plural.
       
   324  * @param string $context Context information for the translators.
       
   325  * @param string $domain  Optional. Text domain. Unique identifier for retrieving translated strings.
       
   326  * @return string Either $single or $plural translated text with context.
       
   327  */
       
   328 function _nx($single, $plural, $number, $context, $domain = 'default') {
       
   329 	$translations = get_translations_for_domain( $domain );
       
   330 	$translation = $translations->translate_plural( $single, $plural, $number, $context );
       
   331 	/**
       
   332 	 * Filter text with its translation while plural option and context are available.
       
   333 	 *
       
   334 	 * @since 2.8.0
       
   335 	 *
       
   336 	 * @param string $translation Translated text.
       
   337 	 * @param string $single      The text that will be used if $number is 1.
       
   338 	 * @param string $plural      The text that will be used if $number is not 1.
       
   339 	 * @param string $number      The number to compare against to use either $single or $plural.
       
   340 	 * @param string $context     Context information for the translators.
       
   341 	 * @param string $domain      Text domain. Unique identifier for retrieving translated strings.
       
   342 	 */
       
   343 	return apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain );
       
   344 }
       
   345 
       
   346 /**
       
   347  * Register plural strings in POT file, but don't translate them.
       
   348  *
       
   349  * Used when you want to keep structures with translatable plural
       
   350  * strings and use them later.
       
   351  *
       
   352  * Example:
       
   353  * <code>
       
   354  * $messages = array(
       
   355  *  	'post' => _n_noop('%s post', '%s posts'),
       
   356  *  	'page' => _n_noop('%s pages', '%s pages')
       
   357  * );
       
   358  * ...
       
   359  * $message = $messages[$type];
       
   360  * $usable_text = sprintf( translate_nooped_plural( $message, $count ), $count );
       
   361  * </code>
       
   362  *
       
   363  * @since 2.5.0
       
   364  *
       
   365  * @param string $singular Single form to be i18ned.
       
   366  * @param string $plural   Plural form to be i18ned.
       
   367  * @param string $domain   Optional. Text domain. Unique identifier for retrieving translated strings.
       
   368  * @return array array($singular, $plural)
       
   369  */
       
   370 function _n_noop( $singular, $plural, $domain = null ) {
       
   371 	return array( 0 => $singular, 1 => $plural, 'singular' => $singular, 'plural' => $plural, 'context' => null, 'domain' => $domain );
       
   372 }
       
   373 
       
   374 /**
       
   375  * Register plural strings with context in POT file, but don't translate them.
       
   376  *
       
   377  * @since 2.8.0
       
   378  */
       
   379 function _nx_noop( $singular, $plural, $context, $domain = null ) {
       
   380 	return array( 0 => $singular, 1 => $plural, 2 => $context, 'singular' => $singular, 'plural' => $plural, 'context' => $context, 'domain' => $domain );
       
   381 }
       
   382 
       
   383 /**
       
   384  * Translate the result of _n_noop() or _nx_noop().
       
   385  *
       
   386  * @since 3.1.0
       
   387  *
       
   388  * @param array  $nooped_plural Array with singular, plural and context keys, usually the result of _n_noop() or _nx_noop()
       
   389  * @param int    $count         Number of objects
       
   390  * @param string $domain        Optional. Text domain. Unique identifier for retrieving translated strings. If $nooped_plural contains
       
   391  *                              a text domain passed to _n_noop() or _nx_noop(), it will override this value.
       
   392  * @return string Either $single or $plural translated text.
       
   393  */
       
   394 function translate_nooped_plural( $nooped_plural, $count, $domain = 'default' ) {
       
   395 	if ( $nooped_plural['domain'] )
       
   396 		$domain = $nooped_plural['domain'];
       
   397 
       
   398 	if ( $nooped_plural['context'] )
       
   399 		return _nx( $nooped_plural['singular'], $nooped_plural['plural'], $count, $nooped_plural['context'], $domain );
       
   400 	else
       
   401 		return _n( $nooped_plural['singular'], $nooped_plural['plural'], $count, $domain );
       
   402 }
       
   403 
       
   404 /**
       
   405  * Load a .mo file into the text domain $domain.
       
   406  *
       
   407  * If the text domain already exists, the translations will be merged. If both
       
   408  * sets have the same string, the translation from the original value will be taken.
       
   409  *
       
   410  * On success, the .mo file will be placed in the $l10n global by $domain
       
   411  * and will be a MO object.
       
   412  *
       
   413  * @since 1.5.0
       
   414  *
       
   415  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   416  * @param string $mofile Path to the .mo file.
       
   417  * @return bool True on success, false on failure.
       
   418  */
       
   419 function load_textdomain( $domain, $mofile ) {
       
   420 	global $l10n;
       
   421 
       
   422 	/**
       
   423 	 * Filter text domain and/or MO file path for loading translations.
       
   424 	 *
       
   425 	 * @since 2.9.0
       
   426 	 *
       
   427 	 * @param boolean        Whether to override the text domain. Default false.
       
   428 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   429 	 * @param string $mofile Path to the MO file.
       
   430 	 */
       
   431 	$plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );
       
   432 
       
   433 	if ( true == $plugin_override ) {
       
   434 		return true;
       
   435 	}
       
   436 
       
   437 	/**
       
   438 	 * Fires before the MO translation file is loaded.
       
   439 	 *
       
   440 	 * @since 2.9.0
       
   441 	 *
       
   442 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   443 	 * @param string $mofile Path to the .mo file.
       
   444 	 */
       
   445 	do_action( 'load_textdomain', $domain, $mofile );
       
   446 
       
   447 	/**
       
   448 	 * Filter MO file path for loading translations for a specific text domain.
       
   449 	 *
       
   450 	 * @since 2.9.0
       
   451 	 *
       
   452 	 * @param string $mofile Path to the MO file.
       
   453 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   454 	 */
       
   455 	$mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );
       
   456 
       
   457 	if ( !is_readable( $mofile ) ) return false;
       
   458 
       
   459 	$mo = new MO();
       
   460 	if ( !$mo->import_from_file( $mofile ) ) return false;
       
   461 
       
   462 	if ( isset( $l10n[$domain] ) )
       
   463 		$mo->merge_with( $l10n[$domain] );
       
   464 
       
   465 	$l10n[$domain] = &$mo;
       
   466 
       
   467 	return true;
       
   468 }
       
   469 
       
   470 /**
       
   471  * Unload translations for a text domain.
       
   472  *
       
   473  * @since 3.0.0
       
   474  *
       
   475  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   476  * @return bool Whether textdomain was unloaded.
       
   477  */
       
   478 function unload_textdomain( $domain ) {
       
   479 	global $l10n;
       
   480 
       
   481 	/**
       
   482 	 * Filter text text domain for loading translation.
       
   483 	 *
       
   484 	 * @since 3.0.0
       
   485 	 *
       
   486 	 * @param boolean        Whether to override unloading the text domain. Default false.
       
   487 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   488 	 */
       
   489 	$plugin_override = apply_filters( 'override_unload_textdomain', false, $domain );
       
   490 
       
   491 	if ( $plugin_override )
       
   492 		return true;
       
   493 
       
   494 	/**
       
   495 	 * Fires before the text domain is unloaded.
       
   496 	 *
       
   497 	 * @since 3.0.0
       
   498 	 *
       
   499 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   500 	 */
       
   501 	do_action( 'unload_textdomain', $domain );
       
   502 
       
   503 	if ( isset( $l10n[$domain] ) ) {
       
   504 		unset( $l10n[$domain] );
       
   505 		return true;
       
   506 	}
       
   507 
       
   508 	return false;
       
   509 }
       
   510 
       
   511 /**
       
   512  * Load default translated strings based on locale.
       
   513  *
       
   514  * Loads the .mo file in WP_LANG_DIR constant path from WordPress root.
       
   515  * The translated (.mo) file is named based on the locale.
       
   516  *
       
   517  * @see load_textdomain()
       
   518  *
       
   519  * @since 1.5.0
       
   520  */
       
   521 function load_default_textdomain() {
       
   522 	$locale = get_locale();
       
   523 
       
   524 	load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo" );
       
   525 
       
   526 	if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists(  WP_LANG_DIR . "/admin-$locale.mo" ) ) {
       
   527 		load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" );
       
   528 		return;
       
   529 	}
       
   530 
       
   531 	if ( is_admin() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) )
       
   532 		load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" );
       
   533 
       
   534 	if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) )
       
   535 		load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo" );
       
   536 
       
   537 }
       
   538 
       
   539 /**
       
   540  * Load a plugin's translated strings.
       
   541  *
       
   542  * If the path is not given then it will be the root of the plugin directory.
       
   543  *
       
   544  * The .mo file should be named based on the text domain with a dash, and then the locale exactly.
       
   545  *
       
   546  * @since 1.5.0
       
   547  *
       
   548  * @param string $domain          Unique identifier for retrieving translated strings
       
   549  * @param string $deprecated      Use the $plugin_rel_path parameter instead.
       
   550  * @param string $plugin_rel_path Optional. Relative path to WP_PLUGIN_DIR where the .mo file resides.
       
   551  */
       
   552 function load_plugin_textdomain( $domain, $deprecated = false, $plugin_rel_path = false ) {
       
   553 	$locale = get_locale();
       
   554 	/**
       
   555 	 * Filter a plugin's locale.
       
   556 	 *
       
   557 	 * @since 3.0.0
       
   558 	 *
       
   559 	 * @param string $locale The plugin's current locale.
       
   560 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   561 	 */
       
   562 	$locale = apply_filters( 'plugin_locale', $locale, $domain );
       
   563 
       
   564 	if ( false !== $plugin_rel_path	) {
       
   565 		$path = WP_PLUGIN_DIR . '/' . trim( $plugin_rel_path, '/' );
       
   566 	} else if ( false !== $deprecated ) {
       
   567 		_deprecated_argument( __FUNCTION__, '2.7' );
       
   568 		$path = ABSPATH . trim( $deprecated, '/' );
       
   569 	} else {
       
   570 		$path = WP_PLUGIN_DIR;
       
   571 	}
       
   572 
       
   573 	// Load the textdomain according to the plugin first
       
   574 	$mofile = $domain . '-' . $locale . '.mo';
       
   575 	if ( $loaded = load_textdomain( $domain, $path . '/'. $mofile ) )
       
   576 		return $loaded;
       
   577 
       
   578 	// Otherwise, load from the languages directory
       
   579 	$mofile = WP_LANG_DIR . '/plugins/' . $mofile;
       
   580 	return load_textdomain( $domain, $mofile );
       
   581 }
       
   582 
       
   583 /**
       
   584  * Load the translated strings for a plugin residing in the mu-plugins directory.
       
   585  *
       
   586  * @since 3.0.0
       
   587  *
       
   588  * @param string $domain             Text domain. Unique identifier for retrieving translated strings.
       
   589  * @param string $mu_plugin_rel_path Relative to WPMU_PLUGIN_DIR directory in which the .mo file resides.
       
   590  *                                   Default empty string.
       
   591  * @return bool True when textdomain is successfully loaded, false otherwise.
       
   592  */
       
   593 function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) {
       
   594 	// duplicate_hook
       
   595 	$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
       
   596 	$path = trailingslashit( WPMU_PLUGIN_DIR . '/' . ltrim( $mu_plugin_rel_path, '/' ) );
       
   597 
       
   598 	// Load the textdomain according to the plugin first
       
   599 	$mofile = $domain . '-' . $locale . '.mo';
       
   600 	if ( $loaded = load_textdomain( $domain, $path . $mofile ) )
       
   601 		return $loaded;
       
   602 
       
   603 	// Otherwise, load from the languages directory
       
   604 	$mofile = WP_LANG_DIR . '/plugins/' . $mofile;
       
   605 	return load_textdomain( $domain, $mofile );
       
   606 }
       
   607 
       
   608 /**
       
   609  * Load the theme's translated strings.
       
   610  *
       
   611  * If the current locale exists as a .mo file in the theme's root directory, it
       
   612  * will be included in the translated strings by the $domain.
       
   613  *
       
   614  * The .mo files must be named based on the locale exactly.
       
   615  *
       
   616  * @since 1.5.0
       
   617  *
       
   618  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   619  * @param string $path   Optional. Path to the directory containing the .mo file.
       
   620  *                       Default false.
       
   621  * @return bool True when textdomain is successfully loaded, false otherwise.
       
   622  */
       
   623 function load_theme_textdomain( $domain, $path = false ) {
       
   624 	$locale = get_locale();
       
   625 	/**
       
   626 	 * Filter a theme's locale.
       
   627 	 *
       
   628 	 * @since 3.0.0
       
   629 	 *
       
   630 	 * @param string $locale The theme's current locale.
       
   631 	 * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   632 	 */
       
   633 	$locale = apply_filters( 'theme_locale', $locale, $domain );
       
   634 
       
   635 	if ( ! $path )
       
   636 		$path = get_template_directory();
       
   637 
       
   638 	// Load the textdomain according to the theme
       
   639 	$mofile = "{$path}/{$locale}.mo";
       
   640 	if ( $loaded = load_textdomain( $domain, $mofile ) )
       
   641 		return $loaded;
       
   642 
       
   643 	// Otherwise, load from the languages directory
       
   644 	$mofile = WP_LANG_DIR . "/themes/{$domain}-{$locale}.mo";
       
   645 	return load_textdomain( $domain, $mofile );
       
   646 }
       
   647 
       
   648 /**
       
   649  * Load the child themes translated strings.
       
   650  *
       
   651  * If the current locale exists as a .mo file in the child themes
       
   652  * root directory, it will be included in the translated strings by the $domain.
       
   653  *
       
   654  * The .mo files must be named based on the locale exactly.
       
   655  *
       
   656  * @since 2.9.0
       
   657  *
       
   658  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   659  * @return bool True when the theme textdomain is successfully loaded, false otherwise.
       
   660  */
       
   661 function load_child_theme_textdomain( $domain, $path = false ) {
       
   662 	if ( ! $path )
       
   663 		$path = get_stylesheet_directory();
       
   664 	return load_theme_textdomain( $domain, $path );
       
   665 }
       
   666 
       
   667 /**
       
   668  * Return the Translations instance for a text domain.
       
   669  *
       
   670  * If there isn't one, returns empty Translations instance.
       
   671  *
       
   672  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   673  * @return Translations A Translations instance.
       
   674  */
       
   675 function get_translations_for_domain( $domain ) {
       
   676 	global $l10n;
       
   677 	if ( !isset( $l10n[$domain] ) ) {
       
   678 		$l10n[$domain] = new NOOP_Translations;
       
   679 	}
       
   680 	return $l10n[$domain];
       
   681 }
       
   682 
       
   683 /**
       
   684  * Whether there are translations for the text domain.
       
   685  *
       
   686  * @since 3.0.0
       
   687  * @param string $domain Text domain. Unique identifier for retrieving translated strings.
       
   688  * @return bool Whether there are translations.
       
   689  */
       
   690 function is_textdomain_loaded( $domain ) {
       
   691 	global $l10n;
       
   692 	return isset( $l10n[$domain] );
       
   693 }
       
   694 
       
   695 /**
       
   696  * Translates role name.
       
   697  *
       
   698  * Since the role names are in the database and not in the source there
       
   699  * are dummy gettext calls to get them into the POT file and this function
       
   700  * properly translates them back.
       
   701  *
       
   702  * The before_last_bar() call is needed, because older installs keep the roles
       
   703  * using the old context format: 'Role name|User role' and just skipping the
       
   704  * content after the last bar is easier than fixing them in the DB. New installs
       
   705  * won't suffer from that problem.
       
   706  *
       
   707  * @since 2.8.0
       
   708  *
       
   709  * @param string $name The role name.
       
   710  * @return string Translated role name on success, original name on failure.
       
   711  */
       
   712 function translate_user_role( $name ) {
       
   713 	return translate_with_gettext_context( before_last_bar($name), 'User role' );
       
   714 }
       
   715 
       
   716 /**
       
   717  * Get all available languages based on the presence of *.mo files in a given directory.
       
   718  *
       
   719  * The default directory is WP_LANG_DIR.
       
   720  *
       
   721  * @since 3.0.0
       
   722  *
       
   723  * @param string $dir A directory to search for language files.
       
   724  *                    Default WP_LANG_DIR.
       
   725  * @return array 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.
       
   726  */
       
   727 function get_available_languages( $dir = null ) {
       
   728 	$languages = array();
       
   729 
       
   730 	foreach( (array)glob( ( is_null( $dir) ? WP_LANG_DIR : $dir ) . '/*.mo' ) as $lang_file ) {
       
   731 		$lang_file = basename($lang_file, '.mo');
       
   732 		if ( 0 !== strpos( $lang_file, 'continents-cities' ) && 0 !== strpos( $lang_file, 'ms-' ) &&
       
   733 			0 !== strpos( $lang_file, 'admin-' ))
       
   734 			$languages[] = $lang_file;
       
   735 	}
       
   736 
       
   737 	return $languages;
       
   738 }
       
   739 
       
   740 /**
       
   741  * Get installed translations.
       
   742  *
       
   743  * Looks in the wp-content/languages directory for translations of
       
   744  * plugins or themes.
       
   745  *
       
   746  * @since 3.7.0
       
   747  *
       
   748  * @param string $type What to search for. Accepts 'plugins', 'themes', 'core'.
       
   749  * @return array Array of language data.
       
   750  */
       
   751 function wp_get_installed_translations( $type ) {
       
   752 	if ( $type !== 'themes' && $type !== 'plugins' && $type !== 'core' )
       
   753 		return array();
       
   754 
       
   755 	$dir = 'core' === $type ? '' : "/$type";
       
   756 
       
   757 	if ( ! is_dir( WP_LANG_DIR ) )
       
   758 		return array();
       
   759 
       
   760 	if ( $dir && ! is_dir( WP_LANG_DIR . $dir ) )
       
   761 		return array();
       
   762 
       
   763 	$files = scandir( WP_LANG_DIR . $dir );
       
   764 	if ( ! $files )
       
   765 		return array();
       
   766 
       
   767 	$language_data = array();
       
   768 
       
   769 	foreach ( $files as $file ) {
       
   770 		if ( '.' === $file[0] || is_dir( $file ) )
       
   771 			continue;
       
   772 		if ( substr( $file, -3 ) !== '.po' )
       
   773 			continue;
       
   774 		if ( ! preg_match( '/(?:(.+)-)?([A-Za-z_]{2,6}).po/', $file, $match ) )
       
   775 			continue;
       
   776 
       
   777 		list( , $textdomain, $language ) = $match;
       
   778 		if ( '' === $textdomain )
       
   779 			$textdomain = 'default';
       
   780 		$language_data[ $textdomain ][ $language ] = wp_get_pomo_file_data( WP_LANG_DIR . "$dir/$file" );
       
   781 	}
       
   782 	return $language_data;
       
   783 }
       
   784 
       
   785 /**
       
   786  * Extract headers from a PO file.
       
   787  *
       
   788  * @since 3.7.0
       
   789  *
       
   790  * @param string $po_file Path to PO file.
       
   791  * @return array PO file headers.
       
   792  */
       
   793 function wp_get_pomo_file_data( $po_file ) {
       
   794 	$headers = get_file_data( $po_file, array(
       
   795 		'POT-Creation-Date'  => '"POT-Creation-Date',
       
   796 		'PO-Revision-Date'   => '"PO-Revision-Date',
       
   797 		'Project-Id-Version' => '"Project-Id-Version',
       
   798 		'X-Generator'        => '"X-Generator',
       
   799 	) );
       
   800 	foreach ( $headers as $header => $value ) {
       
   801 		// Remove possible contextual '\n' and closing double quote.
       
   802 		$headers[ $header ] = preg_replace( '~(\\\n)?"$~', '', $value );
       
   803 	}
       
   804 	return $headers;
       
   805 }