PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Translation / Translator.php
matomo / app / core / Translation Last commit date
Loader 6 years ago Transifex 6 years ago Translator.php 6 years ago
Translator.php
272 lines
1 <?php
2 /**
3 * Piwik - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 */
8
9 namespace Piwik\Translation;
10
11 use Piwik\Config;
12 use Piwik\Piwik;
13 use Piwik\Plugin;
14 use Piwik\Translation\Loader\LoaderInterface;
15
16 /**
17 * Translates messages.
18 *
19 * @api
20 */
21 class Translator
22 {
23 /**
24 * Contains the translated messages, indexed by the language name.
25 *
26 * @var array
27 */
28 private $translations = array();
29
30 /**
31 * @var string
32 */
33 private $currentLanguage;
34
35 /**
36 * @var string
37 */
38 private $fallback = 'en';
39
40 /**
41 * Directories containing the translations to load.
42 *
43 * @var string[]
44 */
45 private $directories = array();
46
47 /**
48 * @var LoaderInterface
49 */
50 private $loader;
51
52 public function __construct(LoaderInterface $loader, array $directories = null)
53 {
54 $this->loader = $loader;
55 $this->currentLanguage = $this->getDefaultLanguage();
56
57 if ($directories === null) {
58 // TODO should be moved out of this class
59 $directories = array(PIWIK_INCLUDE_PATH . '/lang');
60 }
61 $this->directories = $directories;
62 }
63
64 /**
65 * Returns an internationalized string using a translation ID. If a translation
66 * cannot be found for the ID, the ID is returned.
67 *
68 * @param string $translationId Translation ID, eg, `General_Date`.
69 * @param array|string|int $args `sprintf` arguments to be applied to the internationalized
70 * string.
71 * @param string|null $language Optionally force the language.
72 * @return string The translated string or `$translationId`.
73 * @api
74 */
75 public function translate($translationId, $args = array(), $language = null)
76 {
77 $args = is_array($args) ? $args : array($args);
78
79 if (strpos($translationId, "_") !== false) {
80 list($plugin, $key) = explode("_", $translationId, 2);
81 $language = is_string($language) ? $language : $this->currentLanguage;
82
83 $translationId = $this->getTranslation($translationId, $language, $plugin, $key);
84 }
85
86 if (count($args) == 0) {
87 return str_replace('%%', '%', $translationId);
88 }
89 return vsprintf($translationId, $args);
90 }
91
92 /**
93 * @return string
94 */
95 public function getCurrentLanguage()
96 {
97 return $this->currentLanguage;
98 }
99
100 /**
101 * @param string $language
102 */
103 public function setCurrentLanguage($language)
104 {
105 if (!$language) {
106 $language = $this->getDefaultLanguage();
107 }
108
109 $this->currentLanguage = $language;
110 }
111
112 /**
113 * @return string The default configured language.
114 */
115 public function getDefaultLanguage()
116 {
117 $generalSection = Config::getInstance()->General;
118
119 // the config may not be available (for example, during environment setup), so we default to 'en'
120 // if the config cannot be found.
121 return @$generalSection['default_language'] ?: 'en';
122 }
123
124 /**
125 * Generate javascript translations array
126 */
127 public function getJavascriptTranslations()
128 {
129 $clientSideTranslations = array();
130 foreach ($this->getClientSideTranslationKeys() as $id) {
131 list($plugin, $key) = explode('_', $id, 2);
132 $clientSideTranslations[$id] = $this->getTranslation($id, $this->currentLanguage, $plugin, $key);
133 }
134
135 $js = 'var translations = ' . json_encode($clientSideTranslations) . ';';
136 $js .= "\n" . 'if (typeof(piwik_translations) == \'undefined\') { var piwik_translations = new Object; }' .
137 'for(var i in translations) { piwik_translations[i] = translations[i];} ';
138 return $js;
139 }
140
141 /**
142 * Returns the list of client side translations by key. These translations will be outputted
143 * to the translation JavaScript.
144 */
145 private function getClientSideTranslationKeys()
146 {
147 $result = array();
148
149 /**
150 * Triggered before generating the JavaScript code that allows i18n strings to be used
151 * in the browser.
152 *
153 * Plugins should subscribe to this event to specify which translations
154 * should be available to JavaScript.
155 *
156 * Event handlers should add whole translation keys, ie, keys that include the plugin name.
157 *
158 * **Example**
159 *
160 * public function getClientSideTranslationKeys(&$result)
161 * {
162 * $result[] = "MyPlugin_MyTranslation";
163 * }
164 *
165 * @param array &$result The whole list of client side translation keys.
166 */
167 Piwik::postEvent('Translate.getClientSideTranslationKeys', array(&$result));
168
169 $result = array_unique($result);
170
171 return $result;
172 }
173
174 /**
175 * Add a directory containing translations.
176 *
177 * @param string $directory
178 */
179 public function addDirectory($directory)
180 {
181 if (isset($this->directories[$directory])) {
182 return;
183 }
184 // index by name to avoid duplicates
185 $this->directories[$directory] = $directory;
186
187 // clear currently loaded translations to force reloading them
188 $this->translations = array();
189 }
190
191 /**
192 * Should be used by tests only, and this method should eventually be removed.
193 */
194 public function reset()
195 {
196 $this->currentLanguage = $this->getDefaultLanguage();
197 $this->directories = array(PIWIK_INCLUDE_PATH . '/lang');
198 $this->translations = array();
199 }
200
201 /**
202 * @param string $translation
203 * @return null|string
204 */
205 public function findTranslationKeyForTranslation($translation)
206 {
207 foreach ($this->getAllTranslations() as $key => $translations) {
208 $possibleKey = array_search($translation, $translations);
209 if (!empty($possibleKey)) {
210 return $key . '_' . $possibleKey;
211 }
212 }
213
214 return null;
215 }
216
217 /**
218 * Returns all the translation messages loaded.
219 *
220 * @return array
221 */
222 public function getAllTranslations()
223 {
224 $this->loadTranslations($this->currentLanguage);
225
226 if (!isset($this->translations[$this->currentLanguage])) {
227 return array();
228 }
229
230 return $this->translations[$this->currentLanguage];
231 }
232
233 private function getTranslation($id, $lang, $plugin, $key)
234 {
235 $this->loadTranslations($lang);
236
237 if (isset($this->translations[$lang][$plugin])
238 && isset($this->translations[$lang][$plugin][$key])
239 ) {
240 return $this->translations[$lang][$plugin][$key];
241 }
242
243 /**
244 * Fallback for keys moved to new Intl plugin to avoid untranslated string in non core plugins
245 * @todo remove this in Piwik 3.0
246 */
247 if ($plugin != 'Intl') {
248 if (isset($this->translations[$lang]['Intl'])
249 && isset($this->translations[$lang]['Intl'][$key])
250 ) {
251 return $this->translations[$lang]['Intl'][$key];
252 }
253 }
254
255 // fallback
256 if ($lang !== $this->fallback) {
257 return $this->getTranslation($id, $this->fallback, $plugin, $key);
258 }
259
260 return $id;
261 }
262
263 private function loadTranslations($language)
264 {
265 if (empty($language) || isset($this->translations[$language])) {
266 return;
267 }
268
269 $this->translations[$language] = $this->loader->load($language, $this->directories);
270 }
271 }
272