MessageCatalogue.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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\Config\Resource\ResourceInterface;
  12. /**
  13. * @author Fabien Potencier <fabien@symfony.com>
  14. */
  15. class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
  16. {
  17. private $messages = array();
  18. private $metadata = array();
  19. private $resources = array();
  20. private $locale;
  21. private $fallbackCatalogue;
  22. private $parent;
  23. /**
  24. * @param string $locale The locale
  25. * @param array $messages An array of messages classified by domain
  26. */
  27. public function __construct($locale, array $messages = array())
  28. {
  29. $this->locale = $locale;
  30. $this->messages = $messages;
  31. }
  32. /**
  33. * {@inheritdoc}
  34. */
  35. public function getLocale()
  36. {
  37. return $this->locale;
  38. }
  39. /**
  40. * {@inheritdoc}
  41. */
  42. public function getDomains()
  43. {
  44. return array_keys($this->messages);
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function all($domain = null)
  50. {
  51. if (null === $domain) {
  52. return $this->messages;
  53. }
  54. return isset($this->messages[$domain]) ? $this->messages[$domain] : array();
  55. }
  56. /**
  57. * {@inheritdoc}
  58. */
  59. public function set($id, $translation, $domain = 'messages')
  60. {
  61. $this->add(array($id => $translation), $domain);
  62. }
  63. /**
  64. * {@inheritdoc}
  65. */
  66. public function has($id, $domain = 'messages')
  67. {
  68. if (isset($this->messages[$domain][$id])) {
  69. return true;
  70. }
  71. if (null !== $this->fallbackCatalogue) {
  72. return $this->fallbackCatalogue->has($id, $domain);
  73. }
  74. return false;
  75. }
  76. /**
  77. * {@inheritdoc}
  78. */
  79. public function defines($id, $domain = 'messages')
  80. {
  81. return isset($this->messages[$domain][$id]);
  82. }
  83. /**
  84. * {@inheritdoc}
  85. */
  86. public function get($id, $domain = 'messages')
  87. {
  88. if (isset($this->messages[$domain][$id])) {
  89. return $this->messages[$domain][$id];
  90. }
  91. if (null !== $this->fallbackCatalogue) {
  92. return $this->fallbackCatalogue->get($id, $domain);
  93. }
  94. return $id;
  95. }
  96. /**
  97. * {@inheritdoc}
  98. */
  99. public function replace($messages, $domain = 'messages')
  100. {
  101. $this->messages[$domain] = array();
  102. $this->add($messages, $domain);
  103. }
  104. /**
  105. * {@inheritdoc}
  106. */
  107. public function add($messages, $domain = 'messages')
  108. {
  109. if (!isset($this->messages[$domain])) {
  110. $this->messages[$domain] = $messages;
  111. } else {
  112. $this->messages[$domain] = array_replace($this->messages[$domain], $messages);
  113. }
  114. }
  115. /**
  116. * {@inheritdoc}
  117. */
  118. public function addCatalogue(MessageCatalogueInterface $catalogue)
  119. {
  120. if ($catalogue->getLocale() !== $this->locale) {
  121. throw new \LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale));
  122. }
  123. foreach ($catalogue->all() as $domain => $messages) {
  124. $this->add($messages, $domain);
  125. }
  126. foreach ($catalogue->getResources() as $resource) {
  127. $this->addResource($resource);
  128. }
  129. if ($catalogue instanceof MetadataAwareInterface) {
  130. $metadata = $catalogue->getMetadata('', '');
  131. $this->addMetadata($metadata);
  132. }
  133. }
  134. /**
  135. * {@inheritdoc}
  136. */
  137. public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
  138. {
  139. // detect circular references
  140. $c = $catalogue;
  141. while ($c = $c->getFallbackCatalogue()) {
  142. if ($c->getLocale() === $this->getLocale()) {
  143. throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
  144. }
  145. }
  146. $c = $this;
  147. do {
  148. if ($c->getLocale() === $catalogue->getLocale()) {
  149. throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
  150. }
  151. foreach ($catalogue->getResources() as $resource) {
  152. $c->addResource($resource);
  153. }
  154. } while ($c = $c->parent);
  155. $catalogue->parent = $this;
  156. $this->fallbackCatalogue = $catalogue;
  157. foreach ($catalogue->getResources() as $resource) {
  158. $this->addResource($resource);
  159. }
  160. }
  161. /**
  162. * {@inheritdoc}
  163. */
  164. public function getFallbackCatalogue()
  165. {
  166. return $this->fallbackCatalogue;
  167. }
  168. /**
  169. * {@inheritdoc}
  170. */
  171. public function getResources()
  172. {
  173. return array_values($this->resources);
  174. }
  175. /**
  176. * {@inheritdoc}
  177. */
  178. public function addResource(ResourceInterface $resource)
  179. {
  180. $this->resources[$resource->__toString()] = $resource;
  181. }
  182. /**
  183. * {@inheritdoc}
  184. */
  185. public function getMetadata($key = '', $domain = 'messages')
  186. {
  187. if ('' == $domain) {
  188. return $this->metadata;
  189. }
  190. if (isset($this->metadata[$domain])) {
  191. if ('' == $key) {
  192. return $this->metadata[$domain];
  193. }
  194. if (isset($this->metadata[$domain][$key])) {
  195. return $this->metadata[$domain][$key];
  196. }
  197. }
  198. }
  199. /**
  200. * {@inheritdoc}
  201. */
  202. public function setMetadata($key, $value, $domain = 'messages')
  203. {
  204. $this->metadata[$domain][$key] = $value;
  205. }
  206. /**
  207. * {@inheritdoc}
  208. */
  209. public function deleteMetadata($key = '', $domain = 'messages')
  210. {
  211. if ('' == $domain) {
  212. $this->metadata = array();
  213. } elseif ('' == $key) {
  214. unset($this->metadata[$domain]);
  215. } else {
  216. unset($this->metadata[$domain][$key]);
  217. }
  218. }
  219. /**
  220. * Adds current values with the new values.
  221. *
  222. * @param array $values Values to add
  223. */
  224. private function addMetadata(array $values)
  225. {
  226. foreach ($values as $domain => $keys) {
  227. foreach ($keys as $key => $value) {
  228. $this->setMetadata($key, $value, $domain);
  229. }
  230. }
  231. }
  232. }