1 | <?php |
||||
2 | |||||
3 | namespace Elgg\I18n; |
||||
4 | |||||
5 | use Elgg\Config; |
||||
6 | use Elgg\Includer; |
||||
7 | |||||
8 | /** |
||||
9 | * Translator |
||||
10 | * |
||||
11 | * Use elgg()->translator |
||||
12 | * |
||||
13 | * @since 1.10.0 |
||||
14 | */ |
||||
15 | class Translator { |
||||
16 | |||||
17 | /** |
||||
18 | * @var Config |
||||
19 | */ |
||||
20 | private $config; |
||||
21 | |||||
22 | /** |
||||
23 | * @var LocaleService |
||||
24 | */ |
||||
25 | private $localeService; |
||||
26 | |||||
27 | /** |
||||
28 | * @var array |
||||
29 | */ |
||||
30 | private $translations = []; |
||||
31 | |||||
32 | /** |
||||
33 | * @var string |
||||
34 | */ |
||||
35 | private $defaultPath = null; |
||||
36 | |||||
37 | /** |
||||
38 | * @var string |
||||
39 | */ |
||||
40 | private $current_language = null; |
||||
41 | |||||
42 | /** |
||||
43 | * Paths to scan for autoloading languages. |
||||
44 | * |
||||
45 | * Languages are automatically loaded for the site or |
||||
46 | * user's default language. Plugins can extend or override strings. |
||||
47 | * language_paths is an array of paths to scan for PHP files matching |
||||
48 | * the default language. The order of paths is determined by the plugin load order, |
||||
49 | * with later entries overriding earlier. Language files within these paths are |
||||
50 | * named as the two-letter ISO 639-1 country codes for the language they represent. |
||||
51 | * |
||||
52 | * @link http://en.wikipedia.org/wiki/ISO_639-1 |
||||
53 | * |
||||
54 | * @var array (paths are keys) |
||||
55 | */ |
||||
56 | private $language_paths = []; |
||||
57 | |||||
58 | /** |
||||
59 | * @var bool |
||||
60 | */ |
||||
61 | private $was_reloaded = false; |
||||
62 | |||||
63 | /** |
||||
64 | * Constructor |
||||
65 | * |
||||
66 | * @param Config $config Elgg config |
||||
67 | * @param LocaleService $localService locale service |
||||
68 | * |
||||
69 | * @access private |
||||
70 | * @internal |
||||
71 | */ |
||||
72 | 4898 | public function __construct(Config $config, LocaleService $localService) { |
|||
73 | 4898 | $this->config = $config; |
|||
74 | 4898 | $this->localeService = $localService; |
|||
75 | |||||
76 | 4898 | $this->defaultPath = dirname(dirname(dirname(dirname(__DIR__)))) . "/languages/"; |
|||
77 | |||||
78 | 4898 | $this->registerLanguagePath($this->defaultPath); |
|||
79 | 4898 | } |
|||
80 | |||||
81 | /** |
||||
82 | * Get a map of all loaded translations |
||||
83 | * |
||||
84 | * @return array |
||||
85 | */ |
||||
86 | 765 | public function getLoadedTranslations() { |
|||
87 | 765 | return $this->translations; |
|||
88 | } |
||||
89 | |||||
90 | /** |
||||
91 | * Given a message key, returns an appropriately translated full-text string |
||||
92 | * |
||||
93 | * @param string $message_key The short message code |
||||
94 | * @param array $args An array of arguments to pass through vsprintf(). |
||||
95 | * @param string $language Optionally, the standard language code |
||||
96 | * (defaults to site/user default, then English) |
||||
97 | * |
||||
98 | * @return string Either the translated string, the English string, |
||||
99 | * or the original language string. |
||||
100 | */ |
||||
101 | 1029 | public function translate($message_key, array $args = [], $language = "") { |
|||
102 | 1029 | if (!is_string($message_key) || strlen($message_key) < 1) { |
|||
103 | 1 | _elgg_services()->logger->warning( |
|||
104 | 1 | '$message_key needs to be a string in ' . __METHOD__ . '(), ' . gettype($message_key) . ' provided' |
|||
105 | ); |
||||
106 | 1 | return ''; |
|||
107 | } |
||||
108 | |||||
109 | 1029 | if (!$language) { |
|||
110 | // no language provided, get current language |
||||
111 | // based on detection, user setting or site |
||||
112 | 1013 | $language = $this->getCurrentLanguage(); |
|||
113 | } |
||||
114 | |||||
115 | 1029 | $this->ensureTranslationsLoaded($language); |
|||
116 | |||||
117 | // build language array for different trys |
||||
118 | // avoid dupes without overhead of array_unique |
||||
119 | $langs = [ |
||||
120 | 1029 | $language => true, |
|||
121 | ]; |
||||
122 | |||||
123 | // load site language |
||||
124 | 1029 | $site_language = $this->config->language; |
|||
125 | 1029 | if (!empty($site_language)) { |
|||
126 | 1029 | $this->ensureTranslationsLoaded($site_language); |
|||
127 | |||||
128 | 1029 | $langs[$site_language] = true; |
|||
129 | } |
||||
130 | |||||
131 | // ultimate language fallback |
||||
132 | 1029 | $langs['en'] = true; |
|||
133 | |||||
134 | // try to translate |
||||
135 | 1029 | $logger = _elgg_services()->logger; |
|||
136 | 1029 | $string = $message_key; |
|||
137 | 1029 | foreach (array_keys($langs) as $try_lang) { |
|||
138 | 1029 | if (isset($this->translations[$try_lang][$message_key])) { |
|||
139 | 865 | $string = $this->translations[$try_lang][$message_key]; |
|||
140 | |||||
141 | // only pass through if we have arguments to allow backward compatibility |
||||
142 | // with manual sprintf() calls. |
||||
143 | 865 | if (!empty($args)) { |
|||
144 | 93 | $string = vsprintf($string, $args); |
|||
145 | } |
||||
146 | |||||
147 | 865 | break; |
|||
148 | } else { |
||||
149 | 376 | $message = sprintf( |
|||
150 | 376 | 'Missing %s translation for "%s" language key', |
|||
151 | 376 | ($try_lang === 'en') ? 'English' : $try_lang, |
|||
152 | 376 | $message_key |
|||
153 | ); |
||||
154 | |||||
155 | 376 | if ($try_lang === 'en') { |
|||
156 | 258 | $logger->notice($message); |
|||
157 | } else { |
||||
158 | 376 | $logger->info($message); |
|||
159 | } |
||||
160 | } |
||||
161 | } |
||||
162 | |||||
163 | 1029 | return $string; |
|||
164 | } |
||||
165 | |||||
166 | /** |
||||
167 | * Add a translation. |
||||
168 | * |
||||
169 | * Translations are arrays in the Zend Translation array format, eg: |
||||
170 | * |
||||
171 | * $english = array('message1' => 'message1', 'message2' => 'message2'); |
||||
172 | * $german = array('message1' => 'Nachricht1','message2' => 'Nachricht2'); |
||||
173 | * |
||||
174 | * @param string $country_code Standard country code (eg 'en', 'nl', 'es') |
||||
175 | * @param array $language_array Formatted array of strings |
||||
176 | * @param bool $ensure_translations_loaded Ensures translations are loaded before adding the language array (default: true) |
||||
177 | * |
||||
178 | * @return bool Depending on success |
||||
179 | */ |
||||
180 | 5360 | public function addTranslation($country_code, $language_array, $ensure_translations_loaded = true) { |
|||
181 | 5360 | $country_code = strtolower($country_code); |
|||
182 | 5360 | $country_code = trim($country_code); |
|||
183 | |||||
184 | 5360 | if (!is_array($language_array) || empty($language_array) || $country_code === "") { |
|||
185 | 1 | return false; |
|||
186 | } |
||||
187 | |||||
188 | 5360 | if (!isset($this->translations[$country_code])) { |
|||
189 | 4899 | $this->translations[$country_code] = []; |
|||
190 | |||||
191 | 4899 | if ($ensure_translations_loaded) { |
|||
192 | // make sure all existing paths are included first before adding language arrays |
||||
193 | 4875 | $this->loadTranslations($country_code); |
|||
194 | } |
||||
195 | } |
||||
196 | |||||
197 | // Note that we are using union operator instead of array_merge() due to performance implications |
||||
198 | 5360 | $this->translations[$country_code] = $language_array + $this->translations[$country_code]; |
|||
199 | |||||
200 | 5360 | return true; |
|||
201 | } |
||||
202 | |||||
203 | /** |
||||
204 | * Get the current system/user language or "en". |
||||
205 | * |
||||
206 | * @return string The language code for the site/user or "en" if not set |
||||
207 | */ |
||||
208 | 5808 | public function getCurrentLanguage() { |
|||
209 | 5808 | if (!isset($this->current_language)) { |
|||
210 | 4940 | $this->current_language = $this->detectLanguage(); |
|||
211 | } |
||||
212 | |||||
213 | 5808 | if (!$this->current_language) { |
|||
214 | $this->current_language = 'en'; |
||||
215 | } |
||||
216 | |||||
217 | 5808 | return $this->current_language; |
|||
218 | } |
||||
219 | |||||
220 | /** |
||||
221 | * Sets current system language |
||||
222 | * |
||||
223 | * @param string $language Language code |
||||
224 | * |
||||
225 | * @return void |
||||
226 | */ |
||||
227 | 1292 | public function setCurrentLanguage($language = null) { |
|||
228 | 1292 | $this->current_language = $language; |
|||
229 | 1292 | } |
|||
230 | |||||
231 | /** |
||||
232 | * Detect the current system/user language or false. |
||||
233 | * |
||||
234 | * @return false|string The language code (eg "en") or false if not set |
||||
235 | * @access private |
||||
236 | * @internal |
||||
237 | */ |
||||
238 | 4940 | public function detectLanguage() { |
|||
239 | // detect from URL |
||||
240 | 4940 | $url_lang = _elgg_services()->request->getParam('hl'); |
|||
241 | 4940 | if (!empty($url_lang)) { |
|||
242 | 2 | return $url_lang; |
|||
243 | } |
||||
244 | |||||
245 | // check logged in user |
||||
246 | 4940 | $user = _elgg_services()->session->getLoggedInUser(); |
|||
247 | 4940 | if (!empty($user) && !empty($user->language)) { |
|||
248 | 1 | return $user->language; |
|||
249 | } |
||||
250 | |||||
251 | // get site setting |
||||
252 | 4940 | $site_language = $this->config->language; |
|||
253 | 4940 | if (!empty($site_language)) { |
|||
254 | 4940 | return $site_language; |
|||
255 | } |
||||
256 | |||||
257 | return false; |
||||
258 | } |
||||
259 | |||||
260 | /** |
||||
261 | * Ensures all needed translations are loaded |
||||
262 | * |
||||
263 | * This loads only English and the language of the logged in user. |
||||
264 | * |
||||
265 | * @return void |
||||
266 | * |
||||
267 | * @access private |
||||
268 | * @internal |
||||
269 | */ |
||||
270 | 5358 | public function bootTranslations() { |
|||
271 | 5358 | $languages = array_unique(['en', $this->getCurrentLanguage()]); |
|||
272 | |||||
273 | 5358 | foreach ($languages as $language) { |
|||
274 | 5358 | $this->loadTranslations($language); |
|||
275 | } |
||||
276 | 5358 | } |
|||
277 | |||||
278 | /** |
||||
279 | * Load both core and plugin translations |
||||
280 | * |
||||
281 | * The $language argument can be used to load translations |
||||
282 | * on-demand in case we need to translate something to a language not |
||||
283 | * loaded by default for the current request. |
||||
284 | * |
||||
285 | * @param string $language Language code |
||||
286 | * |
||||
287 | * @return void |
||||
288 | * |
||||
289 | * @access private |
||||
290 | * @internal |
||||
291 | */ |
||||
292 | 5360 | public function loadTranslations($language) { |
|||
293 | 5360 | if (!is_string($language)) { |
|||
294 | 6 | return; |
|||
295 | } |
||||
296 | |||||
297 | 5360 | $data = elgg_load_system_cache("{$language}.lang"); |
|||
298 | 5360 | if ($data) { |
|||
299 | 154 | $this->addTranslation($language, $data, false); |
|||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
300 | 154 | return; |
|||
301 | } |
||||
302 | |||||
303 | 5333 | foreach ($this->getLanguagePaths() as $path) { |
|||
304 | 5333 | $this->registerTranslations($path, false, $language); |
|||
305 | } |
||||
306 | |||||
307 | 5333 | $translations = elgg_extract($language, $this->translations, []); |
|||
308 | 5333 | elgg_save_system_cache("{$language}.lang", $translations); |
|||
0 ignored issues
–
show
It seems like
$translations can also be of type array ; however, parameter $data of elgg_save_system_cache() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
309 | 5333 | } |
|||
310 | |||||
311 | /** |
||||
312 | * When given a full path, finds translation files and loads them |
||||
313 | * |
||||
314 | * @param string $path Full path |
||||
315 | * @param bool $load_all If true all languages are loaded, if |
||||
316 | * false only the current language + en are loaded |
||||
317 | * @param string $language Language code |
||||
318 | * |
||||
319 | * @return bool success |
||||
320 | * |
||||
321 | * @access private |
||||
322 | * @internal |
||||
323 | */ |
||||
324 | 5339 | public function registerTranslations($path, $load_all = false, $language = null) { |
|||
325 | 5339 | $path = \Elgg\Project\Paths::sanitize($path); |
|||
326 | |||||
327 | // don't need to register translations as the folder is missing |
||||
328 | 5339 | if (!is_dir($path)) { |
|||
329 | _elgg_services()->logger->info("No translations could be loaded from: $path"); |
||||
330 | return true; |
||||
331 | } |
||||
332 | |||||
333 | // Make a note of this path just in case we need to register this language later |
||||
334 | 5339 | $this->registerLanguagePath($path); |
|||
335 | |||||
336 | 5339 | _elgg_services()->logger->info("Translations loaded from: $path"); |
|||
337 | |||||
338 | 5339 | if ($language) { |
|||
339 | 5333 | $load_language_files = ["$language.php"]; |
|||
340 | 5333 | $load_all = false; |
|||
341 | } else { |
||||
342 | // Get the current language based on site defaults and user preference |
||||
343 | 21 | $current_language = $this->getCurrentLanguage(); |
|||
344 | |||||
345 | $load_language_files = [ |
||||
346 | 21 | 'en.php', |
|||
347 | 21 | "$current_language.php" |
|||
348 | ]; |
||||
349 | |||||
350 | 21 | $load_language_files = array_unique($load_language_files); |
|||
351 | } |
||||
352 | |||||
353 | 5339 | $return = true; |
|||
354 | 5339 | if ($handle = opendir($path)) { |
|||
355 | 5339 | while (false !== ($language_file = readdir($handle))) { |
|||
356 | // ignore bad files |
||||
357 | 5339 | if (substr($language_file, 0, 1) == '.' || substr($language_file, -4) !== '.php') { |
|||
358 | 5339 | continue; |
|||
359 | } |
||||
360 | |||||
361 | 5339 | if (in_array($language_file, $load_language_files) || $load_all) { |
|||
362 | 5339 | $return = $return && $this->includeLanguageFile($path . $language_file); |
|||
363 | } |
||||
364 | } |
||||
365 | 5339 | closedir($handle); |
|||
366 | } else { |
||||
367 | _elgg_services()->logger->error("Could not open language path: $path"); |
||||
368 | $return = false; |
||||
369 | } |
||||
370 | |||||
371 | 5339 | return $return; |
|||
372 | } |
||||
373 | |||||
374 | /** |
||||
375 | * Load cached or include a language file by its path |
||||
376 | * |
||||
377 | * @param string $path Path to file |
||||
378 | * @return bool |
||||
379 | * @access private |
||||
380 | * @internal |
||||
381 | */ |
||||
382 | 34 | protected function includeLanguageFile($path) { |
|||
383 | 34 | $result = Includer::includeFile($path); |
|||
384 | |||||
385 | 34 | if (is_array($result)) { |
|||
386 | 34 | $this->addTranslation(basename($path, '.php'), $result); |
|||
387 | 34 | return true; |
|||
388 | } |
||||
389 | |||||
390 | return false; |
||||
391 | } |
||||
392 | |||||
393 | /** |
||||
394 | * Reload all translations from all registered paths. |
||||
395 | * |
||||
396 | * This is only called by functions which need to know all possible translations. |
||||
397 | * |
||||
398 | * @todo Better on demand loading based on language_paths array |
||||
399 | * |
||||
400 | * @return void |
||||
401 | * @access private |
||||
402 | * @internal |
||||
403 | */ |
||||
404 | 764 | public function reloadAllTranslations() { |
|||
405 | 764 | if ($this->was_reloaded) { |
|||
406 | 352 | return; |
|||
407 | } |
||||
408 | |||||
409 | 764 | $languages = $this->getAvailableLanguages(); |
|||
410 | |||||
411 | 764 | foreach ($languages as $language) { |
|||
412 | 764 | $this->ensureTranslationsLoaded($language); |
|||
413 | } |
||||
414 | |||||
415 | 764 | _elgg_services()->events->triggerAfter('reload', 'translations'); |
|||
416 | |||||
417 | 764 | $this->was_reloaded = true; |
|||
418 | 764 | } |
|||
419 | |||||
420 | /** |
||||
421 | * Return an array of installed translations as an associative |
||||
422 | * array "two letter code" => "native language name". |
||||
423 | * |
||||
424 | * @param boolean $calculate_completeness Set to true if you want a completeness postfix added to the language text |
||||
425 | * |
||||
426 | * @return array |
||||
427 | */ |
||||
428 | 382 | public function getInstalledTranslations($calculate_completeness = false) { |
|||
429 | 382 | if ($calculate_completeness) { |
|||
430 | // Ensure that all possible translations are loaded |
||||
431 | $this->reloadAllTranslations(); |
||||
432 | } |
||||
433 | |||||
434 | 382 | $result = []; |
|||
435 | |||||
436 | 382 | $languages = $this->getAvailableLanguages(); |
|||
437 | 382 | foreach ($languages as $language) { |
|||
438 | 382 | if ($this->languageKeyExists($language, $language)) { |
|||
439 | 382 | $value = $this->translate($language, [], $language); |
|||
440 | } else { |
||||
441 | 346 | $value = $this->translate($language); |
|||
442 | } |
||||
443 | |||||
444 | 382 | if (($language !== 'en') && $calculate_completeness) { |
|||
445 | $completeness = $this->getLanguageCompleteness($language); |
||||
446 | $value .= " (" . $completeness . "% " . $this->translate('complete') . ")"; |
||||
447 | } |
||||
448 | |||||
449 | 382 | $result[$language] = $value; |
|||
450 | } |
||||
451 | |||||
452 | 382 | natcasesort($result); |
|||
453 | |||||
454 | 382 | return $result; |
|||
455 | } |
||||
456 | |||||
457 | /** |
||||
458 | * Return the level of completeness for a given language code (compared to english) |
||||
459 | * |
||||
460 | * @param string $language Language |
||||
461 | * |
||||
462 | * @return float |
||||
463 | */ |
||||
464 | 382 | public function getLanguageCompleteness($language) { |
|||
465 | |||||
466 | 382 | if ($language == 'en') { |
|||
467 | 30 | return (float) 100; |
|||
468 | } |
||||
469 | |||||
470 | // Ensure that all possible translations are loaded |
||||
471 | 352 | $this->reloadAllTranslations(); |
|||
472 | |||||
473 | 352 | $en = count($this->translations['en']); |
|||
474 | |||||
475 | 352 | $missing = $this->getMissingLanguageKeys($language); |
|||
476 | 352 | if ($missing) { |
|||
477 | 352 | $missing = count($missing); |
|||
478 | } else { |
||||
479 | $missing = 0; |
||||
480 | } |
||||
481 | |||||
482 | 352 | $lang = $en - $missing; |
|||
483 | |||||
484 | 352 | return round(($lang / $en) * 100, 2); |
|||
485 | } |
||||
486 | |||||
487 | /** |
||||
488 | * Return the translation keys missing from a given language, |
||||
489 | * or those that are identical to the english version. |
||||
490 | * |
||||
491 | * @param string $language The language |
||||
492 | * |
||||
493 | * @return mixed |
||||
494 | * @access private |
||||
495 | * @internal |
||||
496 | */ |
||||
497 | 352 | public function getMissingLanguageKeys($language) { |
|||
498 | |||||
499 | // Ensure that all possible translations are loaded |
||||
500 | 352 | $this->reloadAllTranslations(); |
|||
501 | |||||
502 | 352 | $missing = []; |
|||
503 | |||||
504 | 352 | foreach ($this->translations['en'] as $k => $v) { |
|||
505 | 352 | if ((!isset($this->translations[$language][$k])) |
|||
506 | 352 | || ($this->translations[$language][$k] == $this->translations['en'][$k])) { |
|||
507 | 352 | $missing[] = $k; |
|||
508 | } |
||||
509 | } |
||||
510 | |||||
511 | 352 | if (count($missing)) { |
|||
512 | 352 | return $missing; |
|||
513 | } |
||||
514 | |||||
515 | return false; |
||||
516 | } |
||||
517 | |||||
518 | /** |
||||
519 | * Check if a given language key exists |
||||
520 | * |
||||
521 | * @param string $key The translation key |
||||
522 | * @param string $language The specific language to check |
||||
523 | * |
||||
524 | * @return bool |
||||
525 | * @since 1.11 |
||||
526 | */ |
||||
527 | 547 | public function languageKeyExists($key, $language = 'en') { |
|||
528 | 547 | if (empty($key)) { |
|||
529 | return false; |
||||
530 | } |
||||
531 | |||||
532 | 547 | $this->ensureTranslationsLoaded($language); |
|||
533 | |||||
534 | 547 | if (!array_key_exists($language, $this->translations)) { |
|||
535 | 6 | return false; |
|||
536 | } |
||||
537 | |||||
538 | 541 | return array_key_exists($key, $this->translations[$language]); |
|||
539 | } |
||||
540 | |||||
541 | /** |
||||
542 | * Returns an array of all available language keys. Triggers a hook to allow plugins to add/remove languages |
||||
543 | * |
||||
544 | * @return array |
||||
545 | * @since 3.0 |
||||
546 | */ |
||||
547 | 764 | public function getAvailableLanguages() { |
|||
548 | 764 | $languages = []; |
|||
549 | |||||
550 | 764 | $allowed_languages = $this->localeService->getLanguageCodes(); |
|||
551 | |||||
552 | 764 | foreach ($this->getLanguagePaths() as $path) { |
|||
553 | try { |
||||
554 | 764 | $iterator = new \DirectoryIterator($path); |
|||
555 | } catch (\Exception $e) { |
||||
556 | continue; |
||||
557 | } |
||||
558 | |||||
559 | 764 | foreach ($iterator as $file) { |
|||
560 | 764 | if ($file->isDir()) { |
|||
561 | 764 | continue; |
|||
562 | } |
||||
563 | |||||
564 | 764 | if ($file->getExtension() !== 'php') { |
|||
565 | continue; |
||||
566 | } |
||||
567 | |||||
568 | 764 | $language = $file->getBasename('.php'); |
|||
569 | 764 | if (empty($language) || !in_array($language, $allowed_languages)) { |
|||
570 | continue; |
||||
571 | } |
||||
572 | |||||
573 | 764 | $languages[$language] = true; |
|||
574 | } |
||||
575 | } |
||||
576 | |||||
577 | 764 | $languages = array_keys($languages); |
|||
578 | |||||
579 | 764 | return _elgg_services()->hooks->trigger('languages', 'translations', [], $languages); |
|||
580 | } |
||||
581 | |||||
582 | /** |
||||
583 | * Registers a path for potential translation files |
||||
584 | * |
||||
585 | * @param string $path path to a folder that contains translation files |
||||
586 | * |
||||
587 | * @return void |
||||
588 | * @access private |
||||
589 | * @internal |
||||
590 | */ |
||||
591 | 5378 | public function registerLanguagePath($path) { |
|||
592 | 5378 | $this->language_paths[$path] = true; |
|||
593 | 5378 | } |
|||
594 | |||||
595 | /** |
||||
596 | * Returns a unique array with locations of translation files |
||||
597 | * |
||||
598 | * @return array |
||||
599 | * @access private |
||||
600 | * @internal |
||||
601 | */ |
||||
602 | 5333 | protected function getLanguagePaths() { |
|||
603 | 5333 | return array_keys($this->language_paths); |
|||
604 | } |
||||
605 | |||||
606 | /** |
||||
607 | * Make sure translations are loaded |
||||
608 | * |
||||
609 | * @param string $language Language |
||||
610 | * @return void |
||||
611 | * @access private |
||||
612 | * @internal |
||||
613 | */ |
||||
614 | 1441 | private function ensureTranslationsLoaded($language) { |
|||
615 | 1441 | if (isset($this->translations[$language])) { |
|||
616 | 1441 | return; |
|||
617 | } |
||||
618 | |||||
619 | // The language being requested is not the same as the language of the |
||||
620 | // logged in user, so we will have to load it separately. (Most likely |
||||
621 | // we're sending a notification and the recipient is using a different |
||||
622 | // language than the logged in user.) |
||||
623 | 773 | $this->loadTranslations($language); |
|||
624 | 773 | } |
|||
625 | |||||
626 | /** |
||||
627 | * Returns an array of language codes. |
||||
628 | * |
||||
629 | * @return array |
||||
630 | * @deprecated 3.0 please use elgg()->locale->getLanguageCodes() |
||||
631 | */ |
||||
632 | public static function getAllLanguageCodes() { |
||||
633 | elgg_deprecated_notice(__METHOD__ . ' has been deprecated use elgg()->locale->getLanguageCodes()', '3.0'); |
||||
634 | return elgg()->locale->getLanguageCodes(); |
||||
635 | } |
||||
636 | |||||
637 | /** |
||||
638 | * Normalize a language code (e.g. from Transifex) |
||||
639 | * |
||||
640 | * @param string $code Language code |
||||
641 | * |
||||
642 | * @return string |
||||
643 | * @access private |
||||
644 | * @internal |
||||
645 | */ |
||||
646 | public static function normalizeLanguageCode($code) { |
||||
647 | $code = strtolower($code); |
||||
648 | $code = preg_replace('~[^a-z0-9]~', '_', $code); |
||||
649 | return $code; |
||||
650 | } |
||||
651 | } |
||||
652 |