PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Symfony/Component/Translation/Translator.php

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