blob: c7d3597542372c28e3b7aa7c81e45267f51638d2 [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?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
12namespace Symfony\Component\Translation;
13
14use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
15use Symfony\Component\Translation\Exception\InvalidArgumentException;
16use Symfony\Contracts\Translation\LocaleAwareInterface;
17use Symfony\Contracts\Translation\TranslatorInterface;
18
19/**
20 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
21 */
22class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface, WarmableInterface
23{
24 public const MESSAGE_DEFINED = 0;
25 public const MESSAGE_MISSING = 1;
26 public const MESSAGE_EQUALS_FALLBACK = 2;
27
28 /**
29 * @var TranslatorInterface|TranslatorBagInterface
30 */
31 private $translator;
32
33 private $messages = [];
34
35 /**
36 * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
37 */
38 public function __construct(TranslatorInterface $translator)
39 {
40 if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
41 throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
42 }
43
44 $this->translator = $translator;
45 }
46
47 /**
48 * {@inheritdoc}
49 */
50 public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
51 {
52 $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
53 $this->collectMessage($locale, $domain, $id, $trans, $parameters);
54
55 return $trans;
56 }
57
58 /**
59 * {@inheritdoc}
60 */
61 public function setLocale(string $locale)
62 {
63 $this->translator->setLocale($locale);
64 }
65
66 /**
67 * {@inheritdoc}
68 */
69 public function getLocale()
70 {
71 return $this->translator->getLocale();
72 }
73
74 /**
75 * {@inheritdoc}
76 */
77 public function getCatalogue(string $locale = null)
78 {
79 return $this->translator->getCatalogue($locale);
80 }
81
82 /**
83 * {@inheritdoc}
84 */
85 public function getCatalogues(): array
86 {
87 return $this->translator->getCatalogues();
88 }
89
90 /**
91 * {@inheritdoc}
92 *
93 * @return string[]
94 */
95 public function warmUp(string $cacheDir)
96 {
97 if ($this->translator instanceof WarmableInterface) {
98 return (array) $this->translator->warmUp($cacheDir);
99 }
100
101 return [];
102 }
103
104 /**
105 * Gets the fallback locales.
106 *
107 * @return array The fallback locales
108 */
109 public function getFallbackLocales()
110 {
111 if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
112 return $this->translator->getFallbackLocales();
113 }
114
115 return [];
116 }
117
118 /**
119 * Passes through all unknown calls onto the translator object.
120 */
121 public function __call(string $method, array $args)
122 {
123 return $this->translator->{$method}(...$args);
124 }
125
126 /**
127 * @return array
128 */
129 public function getCollectedMessages()
130 {
131 return $this->messages;
132 }
133
134 private function collectMessage(?string $locale, ?string $domain, string $id, string $translation, ?array $parameters = [])
135 {
136 if (null === $domain) {
137 $domain = 'messages';
138 }
139
140 $catalogue = $this->translator->getCatalogue($locale);
141 $locale = $catalogue->getLocale();
142 $fallbackLocale = null;
143 if ($catalogue->defines($id, $domain)) {
144 $state = self::MESSAGE_DEFINED;
145 } elseif ($catalogue->has($id, $domain)) {
146 $state = self::MESSAGE_EQUALS_FALLBACK;
147
148 $fallbackCatalogue = $catalogue->getFallbackCatalogue();
149 while ($fallbackCatalogue) {
150 if ($fallbackCatalogue->defines($id, $domain)) {
151 $fallbackLocale = $fallbackCatalogue->getLocale();
152 break;
153 }
154 $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
155 }
156 } else {
157 $state = self::MESSAGE_MISSING;
158 }
159
160 $this->messages[] = [
161 'locale' => $locale,
162 'fallbackLocale' => $fallbackLocale,
163 'domain' => $domain,
164 'id' => $id,
165 'translation' => $translation,
166 'parameters' => $parameters,
167 'state' => $state,
168 'transChoiceNumber' => isset($parameters['%count%']) && is_numeric($parameters['%count%']) ? $parameters['%count%'] : null,
169 ];
170 }
171}