1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
<?php
namespace CommerceGuys\Intl;
use CommerceGuys\Intl\Exception\UnknownLocaleException;
trait LocaleResolverTrait
{
/**
* The path where per-locale definitions are stored.
*/
protected $definitionPath;
/**
* 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)
{
if (is_null($locale)) {
// Use the default locale if none was provided.
// @todo Provide a way to override this.
$locale = 'en';
}
// Normalize the locale. Allows en_US to work the same as en-US, etc.
$locale = str_replace('_', '-', $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.
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;
}
/**
* Returns 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 = array();
$localeParts = explode('-', $locale);
while (!empty($localeParts)) {
$localeVariants[] = implode('-', $localeParts);
array_pop($localeParts);
}
return $localeVariants;
}
}
|