ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Translate.php
Go to the documentation of this file.
1<?php
2
11namespace SimpleSAML\Locale;
12
14{
15
22
23 private $langtext = array();
24
28 private $dictionaries = array();
29
33 private $defaultDictionary = null;
34
40 private $language;
41
42
50 {
51 $this->configuration = $configuration;
52 $this->language = new Language($configuration);
53
54 if ($defaultDictionary !== null && substr($defaultDictionary, -4) === '.php') {
55 // TODO: drop this entire if clause for 2.0
56 // for backwards compatibility - print warning
57 $backtrace = debug_backtrace();
58 $where = $backtrace[0]['file'].':'.$backtrace[0]['line'];
60 'Deprecated use of new SimpleSAML\Locale\Translate(...) at '.$where.
61 '. The last parameter is now a dictionary name, which should not end in ".php".'
62 );
63
64 $this->defaultDictionary = substr($defaultDictionary, 0, -4);
65 } else {
66 $this->defaultDictionary = $defaultDictionary;
67 }
68 }
69
70
76 public function getLanguage()
77 {
78 return $this->language;
79 }
80
81
90 private function getDictionary($name)
91 {
92 assert(is_string($name));
93
94 if (!array_key_exists($name, $this->dictionaries)) {
95 $sepPos = strpos($name, ':');
96 if ($sepPos !== false) {
97 $module = substr($name, 0, $sepPos);
98 $fileName = substr($name, $sepPos + 1);
99 $dictDir = \SimpleSAML\Module::getModuleDir($module).'/dictionaries/';
100 } else {
101 $dictDir = $this->configuration->getPathValue('dictionarydir', 'dictionaries/');
102 $fileName = $name;
103 }
104
105 $this->dictionaries[$name] = $this->readDictionaryFile($dictDir.$fileName);
106 }
107
108 return $this->dictionaries[$name];
109 }
110
111
120 public function getTag($tag)
121 {
122 assert(is_string($tag));
123
124 // first check translations loaded by the includeInlineTranslation and includeLanguageFile methods
125 if (array_key_exists($tag, $this->langtext)) {
126 return $this->langtext[$tag];
127 }
128
129 // check whether we should use the default dictionary or a dictionary specified in the tag
130 if (substr($tag, 0, 1) === '{' && preg_match('/^{((?:\w+:)?\w+?):(.*)}$/D', $tag, $matches)) {
131 $dictionary = $matches[1];
132 $tag = $matches[2];
133 } else {
134 $dictionary = $this->defaultDictionary;
135 if ($dictionary === null) {
136 // we don't have any dictionary to load the tag from
137 return null;
138 }
139 }
140
141 $dictionary = $this->getDictionary($dictionary);
142 if (!array_key_exists($tag, $dictionary)) {
143 return null;
144 }
145
146 return $dictionary[$tag];
147 }
148
149
159 public function getPreferredTranslation($translations)
160 {
161 assert(is_array($translations));
162
163 // look up translation of tag in the selected language
164 $selected_language = $this->language->getLanguage();
165 if (array_key_exists($selected_language, $translations)) {
166 return $translations[$selected_language];
167 }
168
169 // look up translation of tag in the default language
170 $default_language = $this->language->getDefaultLanguage();
171 if (array_key_exists($default_language, $translations)) {
172 return $translations[$default_language];
173 }
174
175 // check for english translation
176 if (array_key_exists('en', $translations)) {
177 return $translations['en'];
178 }
179
180 // pick the first translation available
181 if (count($translations) > 0) {
182 $languages = array_keys($translations);
183 return $translations[$languages[0]];
184 }
185
186 // we don't have anything to return
187 throw new \Exception('Nothing to return from translation.');
188 }
189
190
199 {
200 // normalize attribute name
201 $normName = strtolower($name);
202 $normName = str_replace(":", "_", $normName);
203
204 // check for an extra dictionary
205 $extraDict = $this->configuration->getString('attributes.extradictionary', null);
206 if ($extraDict !== null) {
207 $dict = $this->getDictionary($extraDict);
208 if (array_key_exists($normName, $dict)) {
209 return $this->getPreferredTranslation($dict[$normName]);
210 }
211 }
212
213 // search the default attribute dictionary
214 $dict = $this->getDictionary('attributes');
215 if (array_key_exists('attribute_'.$normName, $dict)) {
216 return $this->getPreferredTranslation($dict['attribute_'.$normName]);
217 }
218
219 // no translations found
220 return $name;
221 }
222
223
231 public static function noop($tag)
232 {
233 return $tag;
234 }
235
236
259 public function t(
260 $tag,
261 $replacements = array(),
262 // TODO: remove this for 2.0. Assume true
263 $fallbackdefault = true,
264 // TODO: remove this for 2.0
265 $oldreplacements = array(),
266 // TODO: remove this for 2.0
267 $striptags = false
268 ) {
269 $backtrace = debug_backtrace();
270 $where = $backtrace[0]['file'].':'.$backtrace[0]['line'];
271 if (!$fallbackdefault) {
273 'Deprecated use of new SimpleSAML\Locale\Translate::t(...) at '.$where.
274 '. This parameter will go away, the fallback will become' .
275 ' identical to the $tag in 2.0.'
276 );
277 }
278 if (!is_array($replacements)) {
279 // TODO: remove this entire if for 2.0
280
281 // old style call to t(...). Print warning to log
283 'Deprecated use of SimpleSAML\Locale\Translate::t(...) at '.$where.
284 '. Please update the code to use the new style of parameters.'
285 );
286
287 // for backwards compatibility
288 if (!$replacements && $this->getTag($tag) === null) {
290 'Code which uses $fallbackdefault === FALSE should be updated to use the getTag() method instead.'
291 );
292 return null;
293 }
294
295 $replacements = $oldreplacements;
296 }
297
298 if (is_array($tag)) {
299 $tagData = $tag;
301 'Deprecated use of new SimpleSAML\Locale\Translate::t(...) at '.$where.
302 '. The $tag-parameter can only be a string in 2.0.'
303 );
304 } else {
305 $tagData = $this->getTag($tag);
306 if ($tagData === null) {
307 // tag not found
308 \SimpleSAML\Logger::info('Template: Looking up ['.$tag.']: not translated at all.');
309 return $this->getStringNotTranslated($tag, $fallbackdefault);
310 }
311 }
312
313 $translated = $this->getPreferredTranslation($tagData);
314
315 foreach ($replacements as $k => $v) {
316 // try to translate if no replacement is given
317 if ($v == null) {
318 $v = $this->t($k);
319 }
320 $translated = str_replace($k, $v, $translated);
321 }
322 return $translated;
323 }
324
325
335 private function getStringNotTranslated($tag, $fallbacktag)
336 {
337 if ($fallbacktag) {
338 return 'not translated ('.$tag.')';
339 } else {
340 return $tag;
341 }
342 }
343
344
355 public function includeInlineTranslation($tag, $translation)
356 {
357 if (is_string($translation)) {
358 $translation = array('en' => $translation);
359 } elseif (!is_array($translation)) {
360 throw new \Exception("Inline translation should be string or array. Is ".gettype($translation)." now!");
361 }
362
363 \SimpleSAML\Logger::debug('Template: Adding inline language translation for tag ['.$tag.']');
364 $this->langtext[$tag] = $translation;
365 }
366
367
377 public function includeLanguageFile($file, $otherConfig = null)
378 {
379 if (!empty($otherConfig)) {
380 $filebase = $otherConfig->getPathValue('dictionarydir', 'dictionaries/');
381 } else {
382 $filebase = $this->configuration->getPathValue('dictionarydir', 'dictionaries/');
383 }
384
385 $lang = $this->readDictionaryFile($filebase.$file);
386 \SimpleSAML\Logger::debug('Template: Merging language array. Loading ['.$file.']');
387 $this->langtext = array_merge($this->langtext, $lang);
388 }
389
390
399 {
400 $definitionFile = $filename.'.definition.json';
401 assert(file_exists($definitionFile));
402
403 $fileContent = file_get_contents($definitionFile);
404 $lang = json_decode($fileContent, true);
405
406 if (empty($lang)) {
407 \SimpleSAML\Logger::error('Invalid dictionary definition file ['.$definitionFile.']');
408 return array();
409 }
410
411 $translationFile = $filename.'.translation.json';
412 if (file_exists($translationFile)) {
413 $fileContent = file_get_contents($translationFile);
414 $moreTrans = json_decode($fileContent, true);
415 if (!empty($moreTrans)) {
416 $lang = array_merge_recursive($lang, $moreTrans);
417 }
418 }
419
420 return $lang;
421 }
422
423
431 private function readDictionaryPHP($filename)
432 {
433 $phpFile = $filename.'.php';
434 assert(file_exists($phpFile));
435
436 $lang = null;
437 include($phpFile);
438 if (isset($lang)) {
439 return $lang;
440 }
441
442 return array();
443 }
444
445
454 {
455 assert(is_string($filename));
456
457 \SimpleSAML\Logger::debug('Template: Reading ['.$filename.']');
458
459 $jsonFile = $filename.'.definition.json';
460 if (file_exists($jsonFile)) {
461 return $this->readDictionaryJSON($filename);
462 }
463
464 $phpFile = $filename.'.php';
465 if (file_exists($phpFile)) {
466 return $this->readDictionaryPHP($filename);
467 }
468
470 $_SERVER['PHP_SELF'].' - Template: Could not find dictionary file at ['.$filename.']'
471 );
472 return array();
473 }
474
475
476 public static function translateSingularGettext($original)
477 {
478 $text = \Gettext\BaseTranslator::$current->gettext($original);
479
480 if (func_num_args() === 1) {
481 return $text;
482 }
483
484 $args = array_slice(func_get_args(), 1);
485
486 return strtr($text, is_array($args[0]) ? $args[0] : $args);
487 }
488
489
490 public static function translatePluralGettext($original, $plural, $value)
491 {
492 $text = \Gettext\BaseTranslator::$current->ngettext($original, $plural, $value);
493
494 if (func_num_args() === 3) {
495 return $text;
496 }
497
498 $args = array_slice(func_get_args(), 3);
499
500 return strtr($text, is_array($args[0]) ? $args[0] : $args);
501 }
502
503
515 public static function translateFromArray($context, $translations)
516 {
517 if (!is_array($translations) || $translations === null) {
518 return null;
519 }
520
521 if (!is_array($context) || !isset($context['currentLanguage'])) {
522 return null;
523 }
524
525 if (isset($translations[$context['currentLanguage']])) {
526 return $translations[$context['currentLanguage']];
527 }
528
529 // we don't have a translation for the current language, load alternative priorities
531 $langcfg = $sspcfg->getConfigItem('language', null);
532 $priorities = array();
533 if ($langcfg instanceof \SimpleSAML_Configuration) {
534 $priorities = $langcfg->getArray('priorities', array());
535 }
536
537 foreach ($priorities[$context['currentLanguage']] as $lang) {
538 if (isset($translations[$lang])) {
539 return $translations[$lang];
540 }
541 }
542
543 // nothing we can use, return null so that we can set a default
544 return null;
545 }
546}
$filename
Definition: buildRTE.php:89
An exception for terminatinating execution or to throw for unit testing.
getAttributeTranslation($name)
Translate the name of an attribute.
Definition: Translate.php:198
__construct(\SimpleSAML_Configuration $configuration, $defaultDictionary=null)
Constructor.
Definition: Translate.php:49
readDictionaryJSON($filename)
Read a dictionary file in JSON format.
Definition: Translate.php:398
readDictionaryFile($filename)
Read a dictionary file.
Definition: Translate.php:453
static noop($tag)
Mark a string for translation without translating it.
Definition: Translate.php:231
getLanguage()
Return the internal language object used by this translator.
Definition: Translate.php:76
includeLanguageFile($file, $otherConfig=null)
Include a language file from the dictionaries directory.
Definition: Translate.php:377
static translateFromArray($context, $translations)
Pick a translation from a given array of translations for the current language.
Definition: Translate.php:515
static translateSingularGettext($original)
Definition: Translate.php:476
t( $tag, $replacements=array(), $fallbackdefault=true, $oldreplacements=array(), $striptags=false)
Translate a tag into the current language, with a fallback to english.
Definition: Translate.php:259
static translatePluralGettext($original, $plural, $value)
Definition: Translate.php:490
getDictionary($name)
This method retrieves a dictionary with the name given.
Definition: Translate.php:90
readDictionaryPHP($filename)
Read a dictionary file in PHP format.
Definition: Translate.php:431
$defaultDictionary
The default dictionary.
Definition: Translate.php:33
getStringNotTranslated($tag, $fallbacktag)
Return the string that should be used when no translation was found.
Definition: Translate.php:335
getTag($tag)
This method retrieves a tag as an array with language => string mappings.
Definition: Translate.php:120
$dictionaries
Associative array of dictionaries.
Definition: Translate.php:28
includeInlineTranslation($tag, $translation)
Include a translation inline instead of putting translations in dictionaries.
Definition: Translate.php:355
getPreferredTranslation($translations)
Retrieve the preferred translation of a given text.
Definition: Translate.php:159
static info($string)
Definition: Logger.php:199
static warning($string)
Definition: Logger.php:177
static error($string)
Definition: Logger.php:166
static debug($string)
Definition: Logger.php:211
static getModuleDir($module)
Retrieve the base directory for a module.
Definition: Module.php:39
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
$languages
Definition: cssgen2.php:34
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
if(function_exists( 'posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
Definition: cron.php:35
if($modEnd===false) $module
Definition: module.php:59
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
$context
Definition: webdav.php:25
$text
Definition: errorreport.php:18