]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/translation/Symfony/Component/Translation/Translator.php
twig implementation
[github/wallabag/wallabag.git] / vendor / symfony / translation / Symfony / Component / Translation / Translator.php
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.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 Symfony\Component\Translation;
13
14 use Symfony\Component\Translation\Loader\LoaderInterface;
15 use Symfony\Component\Translation\Exception\NotFoundResourceException;
16
17 /**
18 * Translator.
19 *
20 * @author Fabien Potencier <fabien@symfony.com>
21 *
22 * @api
23 */
24 class Translator implements TranslatorInterface
25 {
26 /**
27 * @var MessageCatalogueInterface[]
28 */
29 protected $catalogues = array();
30
31 /**
32 * @var string
33 */
34 protected $locale;
35
36 /**
37 * @var array
38 */
39 private $fallbackLocales = array();
40
41 /**
42 * @var LoaderInterface[]
43 */
44 private $loaders = array();
45
46 /**
47 * @var array
48 */
49 private $resources = array();
50
51 /**
52 * @var MessageSelector
53 */
54 private $selector;
55
56 /**
57 * Constructor.
58 *
59 * @param string $locale The locale
60 * @param MessageSelector|null $selector The message selector for pluralization
61 *
62 * @api
63 */
64 public function __construct($locale, MessageSelector $selector = null)
65 {
66 $this->locale = $locale;
67 $this->selector = $selector ?: new MessageSelector();
68 }
69
70 /**
71 * Adds a Loader.
72 *
73 * @param string $format The name of the loader (@see addResource())
74 * @param LoaderInterface $loader A LoaderInterface instance
75 *
76 * @api
77 */
78 public function addLoader($format, LoaderInterface $loader)
79 {
80 $this->loaders[$format] = $loader;
81 }
82
83 /**
84 * Adds a Resource.
85 *
86 * @param string $format The name of the loader (@see addLoader())
87 * @param mixed $resource The resource name
88 * @param string $locale The locale
89 * @param string $domain The domain
90 *
91 * @api
92 */
93 public function addResource($format, $resource, $locale, $domain = null)
94 {
95 if (null === $domain) {
96 $domain = 'messages';
97 }
98
99 $this->resources[$locale][] = array($format, $resource, $domain);
100
101 if (in_array($locale, $this->fallbackLocales)) {
102 $this->catalogues = array();
103 } else {
104 unset($this->catalogues[$locale]);
105 }
106 }
107
108 /**
109 * {@inheritdoc}
110 *
111 * @api
112 */
113 public function setLocale($locale)
114 {
115 $this->locale = $locale;
116 }
117
118 /**
119 * {@inheritdoc}
120 *
121 * @api
122 */
123 public function getLocale()
124 {
125 return $this->locale;
126 }
127
128 /**
129 * Sets the fallback locale(s).
130 *
131 * @param string|array $locales The fallback locale(s)
132 *
133 * @deprecated since 2.3, to be removed in 3.0. Use setFallbackLocales() instead.
134 *
135 * @api
136 */
137 public function setFallbackLocale($locales)
138 {
139 $this->setFallbackLocales(is_array($locales) ? $locales : array($locales));
140 }
141
142 /**
143 * Sets the fallback locales.
144 *
145 * @param array $locales The fallback locales
146 *
147 * @api
148 */
149 public function setFallbackLocales(array $locales)
150 {
151 // needed as the fallback locales are linked to the already loaded catalogues
152 $this->catalogues = array();
153
154 $this->fallbackLocales = $locales;
155 }
156
157 /**
158 * Gets the fallback locales.
159 *
160 * @return array $locales The fallback locales
161 *
162 * @api
163 */
164 public function getFallbackLocales()
165 {
166 return $this->fallbackLocales;
167 }
168
169 /**
170 * {@inheritdoc}
171 *
172 * @api
173 */
174 public function trans($id, array $parameters = array(), $domain = null, $locale = null)
175 {
176 if (null === $locale) {
177 $locale = $this->getLocale();
178 }
179
180 if (null === $domain) {
181 $domain = 'messages';
182 }
183
184 if (!isset($this->catalogues[$locale])) {
185 $this->loadCatalogue($locale);
186 }
187
188 return strtr($this->catalogues[$locale]->get((string) $id, $domain), $parameters);
189 }
190
191 /**
192 * {@inheritdoc}
193 *
194 * @api
195 */
196 public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
197 {
198 if (null === $locale) {
199 $locale = $this->getLocale();
200 }
201
202 if (null === $domain) {
203 $domain = 'messages';
204 }
205
206 if (!isset($this->catalogues[$locale])) {
207 $this->loadCatalogue($locale);
208 }
209
210 $id = (string) $id;
211
212 $catalogue = $this->catalogues[$locale];
213 while (!$catalogue->defines($id, $domain)) {
214 if ($cat = $catalogue->getFallbackCatalogue()) {
215 $catalogue = $cat;
216 $locale = $catalogue->getLocale();
217 } else {
218 break;
219 }
220 }
221
222 return strtr($this->selector->choose($catalogue->get($id, $domain), (int) $number, $locale), $parameters);
223 }
224
225 protected function loadCatalogue($locale)
226 {
227 try {
228 $this->doLoadCatalogue($locale);
229 } catch (NotFoundResourceException $e) {
230 if (!$this->computeFallbackLocales($locale)) {
231 throw $e;
232 }
233 }
234 $this->loadFallbackCatalogues($locale);
235 }
236
237 private function doLoadCatalogue($locale)
238 {
239 $this->catalogues[$locale] = new MessageCatalogue($locale);
240
241 if (isset($this->resources[$locale])) {
242 foreach ($this->resources[$locale] as $resource) {
243 if (!isset($this->loaders[$resource[0]])) {
244 throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0]));
245 }
246 $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
247 }
248 }
249 }
250
251 private function loadFallbackCatalogues($locale)
252 {
253 $current = $this->catalogues[$locale];
254
255 foreach ($this->computeFallbackLocales($locale) as $fallback) {
256 if (!isset($this->catalogues[$fallback])) {
257 $this->doLoadCatalogue($fallback);
258 }
259
260 $current->addFallbackCatalogue($this->catalogues[$fallback]);
261 $current = $this->catalogues[$fallback];
262 }
263 }
264
265 protected function computeFallbackLocales($locale)
266 {
267 $locales = array();
268 foreach ($this->fallbackLocales as $fallback) {
269 if ($fallback === $locale) {
270 continue;
271 }
272
273 $locales[] = $fallback;
274 }
275
276 if (strrchr($locale, '_') !== false) {
277 array_unshift($locales, substr($locale, 0, -strlen(strrchr($locale, '_'))));
278 }
279
280 return array_unique($locales);
281 }
282 }