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