1 <?php
2
3 /*
4 * This file is part of the ICanBoogie package.
5 *
6 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace ICanBoogie\I18n;
13
14 use ICanBoogie\CLDR\Repository;
15 use ICanBoogie\Prototype\MethodNotDefined;
16
17 /**
18 * A locale refers to a set of user preferences that tend to be shared across significant swaths
19 * of the world. Traditionally, the data associated with it provides support for formatting and
20 * parsing of dates, times, numbers, and currencies; for measurement units, for
21 * sort-order (collation), plus translated names for time zones, languages, countries, and
22 * scripts. The data can also include support for text boundaries (character, word, line,
23 * and sentence), text transformations (including transliterations), and other services.
24 *
25 * @property-read string $id Locale id
26 * @property-read string $language Language of the locale.
27 * @property-read string $territory Territory of the locale.
28 * @property-read array $calendar The data of the default calendar for the locale.
29 * @property-read Conventions $conventions The UNICODE conventions for the locale.
30 * @property-read DateFormatter $date_formatter The data formatter for the locale.
31 * @property-read NumberFormatter $number_formatter The number formatter for the locale.
32 * @property-read Translator $translator The translator for the locale.
33 */
34 class Locale extends \ICanBoogie\CLDR\Locale
35 {
36 /**
37 * Instantiated locales.
38 *
39 * @var array[string]Locale
40 */
41 static private $locales = array();
42
43 /**
44 * Returns the locale for the specified id.
45 *
46 * @param string $id The locale id.
47 *
48 * @return Locale.
49 */
50 static public function from($id)
51 {
52 if (isset(self::$locales[$id]))
53 {
54 return self::$locales[$id];
55 }
56
57 return self::$locales[$id] = new static(get_cldr(), $id);
58 }
59
60 /**
61 * Language identifier.
62 *
63 * @var string
64 */
65 protected $id;
66
67 /**
68 * Language of the locale.
69 *
70 * @var string
71 */
72 protected $language;
73
74 /**
75 * Territory code for this locale.
76 *
77 * @var string
78 */
79 protected $territory;
80
81 /**
82 * Initializes the {@link $language} and {@link $territory} properties.
83 *
84 * @param string $id Locale identifier. The underscore character "_" is replace with the
85 * hypen-minus character "-" as advised by the {@link http://www.rfc-editor.org/rfc/bcp/bcp47.txt BCP 47}.
86 */
87 public function __construct(Repository $repository, $id)
88 {
89 $id = strtr($id, '_', '-');
90 $this->id = $id;
91
92 list($this->language, $this->territory) = explode('-', $id) + array(1 => null);
93
94 parent::__construct($repository, $id);
95 }
96
97 public function __get($property)
98 {
99 switch ($property)
100 {
101 case 'id': return $this->id;
102 case 'language': return $this->language;
103 case 'territory': return $this->territory;
104 case 'calendar': return $this->$property = $this->get_calendar();
105 case 'number_formatter': return $this->$property = $this->get_number_formatter();
106 case 'translator': return $this->$property = $this->get_translator();
107 }
108
109 return parent::__get($property);
110 }
111
112 public function __call($method, $arguments)
113 {
114 if (is_callable(array($this, $method)))
115 {
116 return call_user_func_array($this->$method, $arguments);
117 }
118
119 throw new MethodNotDefined(array($method, $this));
120 }
121
122 /**
123 * Returns the locale identifier.
124 *
125 * @return string
126 */
127 public function __toString()
128 {
129 return $this->id;
130 }
131
132 /**
133 * Returns the data of the default calendar for the locale.
134 *
135 * @return array
136 */
137 protected function get_calendar()
138 {
139 return $this->calendars['gregorian'];
140 }
141
142 /**
143 * Returns the number formatter for the locale.
144 *
145 * @return NumberFormatter
146 */
147 protected function get_number_formatter()
148 {
149 return new NumberFormatter($this);
150 }
151
152 /**
153 * Returns the string translator for the locale.
154 *
155 * @return Translator
156 */
157 protected function get_translator()
158 {
159 return Translator::get($this->id);
160 }
161 }