diff options
Diffstat (limited to 'vendor/commerceguys/intl/src/LocaleResolverTrait.php')
-rw-r--r-- | vendor/commerceguys/intl/src/LocaleResolverTrait.php | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/vendor/commerceguys/intl/src/LocaleResolverTrait.php b/vendor/commerceguys/intl/src/LocaleResolverTrait.php new file mode 100644 index 000000000..797e5abaf --- /dev/null +++ b/vendor/commerceguys/intl/src/LocaleResolverTrait.php @@ -0,0 +1,244 @@ +<?php + +namespace CommerceGuys\Intl; + +use CommerceGuys\Intl\Exception\UnknownLocaleException; + +trait LocaleResolverTrait +{ + /** + * The path where per-locale definitions are stored. + * + * @var string + */ + protected $definitionPath; + + /** + * The default locale. + * + * @var string + */ + protected $defaultLocale = 'en'; + + /** + * The fallback locale. + * + * @var string + */ + protected $fallbackLocale = null; + + /** + * Common locale aliases. + * + * @var array + */ + protected $localeAliases = [ + 'az-AZ' => 'az-Latn-AZ', + 'bs-BA' => 'bs-Latn-BA', + 'ha-GH' => 'ha-Latn-GH', + 'ha-NE' => 'ha-Latn-NE', + 'ha-NG' => 'ha-Latn-NG', + 'in' => 'id', + 'in-ID' => 'id-ID', + 'iw' => 'he', + 'iw-IL' => 'he-IL', + 'kk-KZ' => 'kk-Cyrl-KZ', + 'ks-IN' => 'ks-Arab-IN', + 'ky-KG' => 'ky-Cyrl-KG', + 'mn-MN' => 'mn-Cyrl-MN', + 'mo' => 'ro-MD', + 'ms-BN' => 'ms-Latn-BN', + 'ms-MY' => 'ms-Latn-MY', + 'ms-SG' => 'ms-Latn-SG', + 'no' => 'nb', + 'no-NO' => 'nb-NO', + 'no-NO-NY' => 'nn-NO', + 'pa-IN' => 'pa-Guru-IN', + 'pa-PK' => 'pa-Arab-PK', + 'sh' => 'sr-Latn', + 'sh-BA' => 'sr-Latn-BA', + 'sh-CS' => 'sr-Latn-RS', + 'sh-YU' => 'sr-Latn-RS', + 'shi-MA' => 'shi-Tfng-MA', + 'sr-BA' => 'sr-Cyrl-BA', + 'sr-ME' => 'sr-Latn-ME', + 'sr-RS' => 'sr-Cyrl-RS', + 'sr-XK' => 'sr-Cyrl-XK', + 'tl' => 'fil', + 'tl-PH' => 'fil-PH', + 'tzm-MA' => 'tzm-Latn-MA', + 'ug-CN' => 'ug-Arab-CN', + 'uz-AF' => 'uz-Arab-AF', + 'uz-UZ' => 'uz-Latn-UZ', + 'vai-LR' => 'vai-Vaii-LR', + 'zh-CN' => 'zh-Hans-CN', + 'zh-HK' => 'zh-Hant-HK', + 'zh-MO' => 'zh-Hant-MO', + 'zh-SG' => 'zh-Hans-SG', + 'zh-TW' => 'zh-Hant-TW', + ]; + + /** + * Determines which locale should be used for loading definitions. + * + * If the "bs-Cyrl-BA" locale is requested, with an "en" fallback, + * the system will try to find the definitions for: + * 1) bs-Cyrl-BA + * 2) bs-Cyrl + * 3) bs + * 4) en + * The first locale for which a definition file is found, wins. + * Otherwise, an exception is thrown. + * + * @param string $locale The desired locale (i.e. fr-FR). + * @param string $fallbackLocale A fallback locale (i.e "en"). + * + * @return string + * + * @throws UnknownLocaleException + */ + protected function resolveLocale($locale = null, $fallbackLocale = null) + { + $locale = $locale ?: $this->getDefaultLocale(); + $locale = $this->canonicalizeLocale($locale); + $locale = $this->resolveLocaleAlias($locale); + // List all possible variants (i.e. en-US gives "en-US" and "en"). + $localeVariants = $this->getLocaleVariants($locale); + // A fallback locale was provided, add it to the end of the chain. + $fallbackLocale = $fallbackLocale ?: $this->getFallbackLocale(); + if (isset($fallbackLocale)) { + $localeVariants[] = $fallbackLocale; + } + + // Try to resolve a locale by finding a matching definition file. + $resolvedLocale = null; + foreach ($localeVariants as $localeVariant) { + $path = $this->definitionPath . $localeVariant . '.json'; + if (file_exists($path)) { + $resolvedLocale = $localeVariant; + break; + } + } + // No locale could be resolved, stop here. + if (!$resolvedLocale) { + throw new UnknownLocaleException($locale); + } + + return $resolvedLocale; + } + + /** + * Resolves known locale aliases. + * + * For example, "zh-CN" is resolved to "zh-Hans-CN". + * + * @param string $locale The locale. + * + * @return string The locale. + */ + protected function resolveLocaleAlias($locale = null) + { + if ($locale && isset($this->localeAliases[$locale])) { + $locale = $this->localeAliases[$locale]; + } + + return $locale; + } + + /** + * Canonicalize the given locale. + * + * @param string $locale The locale. + * + * @return string The canonicalized locale. + */ + protected function canonicalizeLocale($locale = null) + { + if (is_null($locale)) { + return $locale; + } + + $locale = str_replace('-', '_', strtolower($locale)); + $localeParts = explode('_', $locale); + foreach ($localeParts as $index => $part) { + if ($index === 0) { + // The language code should stay lowercase. + continue; + } + + if (strlen($part) == 4) { + // Script code. + $localeParts[$index] = ucfirst($part); + } else { + // Country or variant code. + $localeParts[$index] = strtoupper($part); + } + } + + return implode('-', $localeParts); + } + + /** + * Gets the default locale. + * + * @return string The default locale. + */ + public function getDefaultLocale() + { + return $this->defaultLocale; + } + + /** + * Sets the default locale. + * + * @return void + */ + public function setDefaultLocale($locale) + { + $this->defaultLocale = $locale; + } + + /** + * Gets the fallback locale. + * + * @return string The fallback locale. + */ + public function getFallbackLocale() + { + return $this->fallbackLocale; + } + + /** + * Sets the fallback locale. + * + * @return void + */ + public function setFallbackLocale($locale) + { + $this->fallbackLocale = $locale; + } + + /** + * Gets all variants of a locale. + * + * For example, "bs-Cyrl-BA" has the following variants: + * 1) bs-Cyrl-BA + * 2) bs-Cyrl + * 3) bs + * + * @param string $locale The locale (i.e. fr-FR). + * + * @return array An array of all variants of a locale. + */ + protected function getLocaleVariants($locale) + { + $localeVariants = []; + $localeParts = explode('-', $locale); + while (!empty($localeParts)) { + $localeVariants[] = implode('-', $localeParts); + array_pop($localeParts); + } + + return $localeVariants; + } +} |