ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 $fallbackdefault = true, // TODO: remove this for 2.0. Assume true
263 $oldreplacements = array(), // TODO: remove this for 2.0
264 $striptags = false // TODO: remove this for 2.0
265 ) {
266 $backtrace = debug_backtrace();
267 $where = $backtrace[0]['file'].':'.$backtrace[0]['line'];
268 if (!$fallbackdefault) {
270 'Deprecated use of new SimpleSAML\Locale\Translate::t(...) at '.$where.
271 '. This parameter will go away, the fallback will become' .
272 ' identical to the $tag in 2.0.'
273 );
274 }
275 if (!is_array($replacements)) {
276 // TODO: remove this entire if for 2.0
277
278 // old style call to t(...). Print warning to log
280 'Deprecated use of SimpleSAML\Locale\Translate::t(...) at '.$where.
281 '. Please update the code to use the new style of parameters.'
282 );
283
284 // for backwards compatibility
285 if (!$replacements && $this->getTag($tag) === null) {
287 'Code which uses $fallbackdefault === FALSE should be updated to use the getTag() method instead.'
288 );
289 return null;
290 }
291
292 $replacements = $oldreplacements;
293 }
294
295 if (is_array($tag)) {
296 $tagData = $tag;
298 'Deprecated use of new SimpleSAML\Locale\Translate::t(...) at '.$where.
299 '. The $tag-parameter can only be a string in 2.0.'
300 );
301 } else {
302 $tagData = $this->getTag($tag);
303 if ($tagData === null) {
304 // tag not found
305 \SimpleSAML\Logger::info('Template: Looking up ['.$tag.']: not translated at all.');
306 return $this->getStringNotTranslated($tag, $fallbackdefault);
307 }
308 }
309
310 $translated = $this->getPreferredTranslation($tagData);
311
312 foreach ($replacements as $k => $v) {
313 // try to translate if no replacement is given
314 if ($v == null) {
315 $v = $this->t($k);
316 }
317 $translated = str_replace($k, $v, $translated);
318 }
319 return $translated;
320 }
321
322
332 private function getStringNotTranslated($tag, $fallbacktag)
333 {
334 if ($fallbacktag) {
335 return 'not translated ('.$tag.')';
336 } else {
337 return $tag;
338 }
339 }
340
341
352 public function includeInlineTranslation($tag, $translation)
353 {
354 if (is_string($translation)) {
355 $translation = array('en' => $translation);
356 } elseif (!is_array($translation)) {
357 throw new \Exception("Inline translation should be string or array. Is ".gettype($translation)." now!");
358 }
359
360 \SimpleSAML\Logger::debug('Template: Adding inline language translation for tag ['.$tag.']');
361 $this->langtext[$tag] = $translation;
362 }
363
364
374 public function includeLanguageFile($file, $otherConfig = null)
375 {
376 if (!empty($otherConfig)) {
377 $filebase = $otherConfig->getPathValue('dictionarydir', 'dictionaries/');
378 } else {
379 $filebase = $this->configuration->getPathValue('dictionarydir', 'dictionaries/');
380 }
381
382 $lang = $this->readDictionaryFile($filebase.$file);
383 \SimpleSAML\Logger::debug('Template: Merging language array. Loading ['.$file.']');
384 $this->langtext = array_merge($this->langtext, $lang);
385 }
386
387
396 {
397 $definitionFile = $filename.'.definition.json';
398 assert('file_exists($definitionFile)');
399
400 $fileContent = file_get_contents($definitionFile);
401 $lang = json_decode($fileContent, true);
402
403 if (empty($lang)) {
404 \SimpleSAML\Logger::error('Invalid dictionary definition file ['.$definitionFile.']');
405 return array();
406 }
407
408 $translationFile = $filename.'.translation.json';
409 if (file_exists($translationFile)) {
410 $fileContent = file_get_contents($translationFile);
411 $moreTrans = json_decode($fileContent, true);
412 if (!empty($moreTrans)) {
413 $lang = array_merge_recursive($lang, $moreTrans);
414 }
415 }
416
417 return $lang;
418 }
419
420
428 private function readDictionaryPHP($filename)
429 {
430 $phpFile = $filename.'.php';
431 assert('file_exists($phpFile)');
432
433 $lang = null;
434 include($phpFile);
435 if (isset($lang)) {
436 return $lang;
437 }
438
439 return array();
440 }
441
442
451 {
452 assert('is_string($filename)');
453
454 \SimpleSAML\Logger::debug('Template: Reading ['.$filename.']');
455
456 $jsonFile = $filename.'.definition.json';
457 if (file_exists($jsonFile)) {
458 return $this->readDictionaryJSON($filename);
459 }
460
461 $phpFile = $filename.'.php';
462 if (file_exists($phpFile)) {
463 return $this->readDictionaryPHP($filename);
464 }
465
467 $_SERVER['PHP_SELF'].' - Template: Could not find dictionary file at ['.$filename.']'
468 );
469 return array();
470 }
471
472
473 public static function translateSingularGettext($original)
474 {
475 $text = \Gettext\BaseTranslator::$current->gettext($original);
476
477 if (func_num_args() === 1) {
478 return $text;
479 }
480
481 $args = array_slice(func_get_args(), 1);
482
483 return strtr($text, is_array($args[0]) ? $args[0] : $args);
484 }
485
486
487 public static function translatePluralGettext($original, $plural, $value)
488 {
489 $text = \Gettext\BaseTranslator::$current->ngettext($original, $plural, $value);
490
491 if (func_num_args() === 3) {
492 return $text;
493 }
494
495 $args = array_slice(func_get_args(), 3);
496
497 return strtr($text, is_array($args[0]) ? $args[0] : $args);
498 }
499}
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:395
readDictionaryFile($filename)
Read a dictionary file.
Definition: Translate.php:450
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:374
static translateSingularGettext($original)
Definition: Translate.php:473
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:487
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:428
$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:332
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:352
getPreferredTranslation($translations)
Retrieve the preferred translation of a given text.
Definition: Translate.php:159
static info($string)
Definition: Logger.php:201
static warning($string)
Definition: Logger.php:179
static error($string)
Definition: Logger.php:168
static debug($string)
Definition: Logger.php:213
static getModuleDir($module)
Retrieve the base directory for a module.
Definition: Module.php:122
$lang
Definition: consent.php:3
if(function_exists( 'posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
Definition: cron.php:35
if($format !==null) $name
Definition: metadata.php:146
if($modEnd===false) $module
Definition: module.php:59
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
$text
Definition: errorreport.php:18