ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilLanguage.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 
27 {
34  public $ilias;
35 
42  public $text;
43 
51  public $lang_default;
52 
61  public $lang_user;
62 
71  public $lang_path;
72 
79  public $lang_key;
80 
87  public $lang_name;
88 
95  public $separator = "#:#";
96 
103  public $comment_separator = "###";
104 
112 
117  protected static $used_topics = array();
118 
123  protected static $used_modules = array();
127  protected $cached_modules = array();
128 
132  protected $map_modules_txt = array();
133 
137  protected $usage_log_enabled = false;
138 
142  protected static $lng_log = array();
143 
154  public function __construct($a_lang_key)
155  {
156  global $DIC;
157  $ilIliasIniFile = $DIC->iliasIni();
158 
159  $this->log = $DIC->logger()->root();
160 
161  $this->lang_key = $a_lang_key;
162 
163  $this->text = array();
164  $this->loaded_modules = array();
165 
166  $this->usage_log_enabled = self::isUsageLogEnabled();
167 
168  $this->lang_path = ILIAS_ABSOLUTE_PATH . "/lang";
169  $this->cust_lang_path = ILIAS_ABSOLUTE_PATH . "/Customizing/global/lang";
170 
171  $this->lang_default = $ilIliasIniFile->readVariable("language", "default");
172 
173  if ($DIC->offsetExists('ilSetting')) {
174  $ilSetting = $DIC->settings();
175  if ($ilSetting->get("language") != "") {
176  $this->lang_default = $ilSetting->get("language");
177  }
178  }
179  if ($DIC->offsetExists('ilUser')) {
180  $ilUser = $DIC->user();
181  $this->lang_user = $ilUser->prefs["language"];
182  }
183 
184  $langs = $this->getInstalledLanguages();
185 
186  if (!in_array($this->lang_key, $langs)) {
187  $this->lang_key = $this->lang_default;
188  }
189 
190  require_once('./Services/Language/classes/class.ilCachedLanguage.php');
191  $this->global_cache = ilCachedLanguage::getInstance($this->lang_key);
192  if ($this->global_cache->isActive()) {
193  $this->cached_modules = $this->global_cache->getTranslations();
194  }
195 
196  $this->loadLanguageModule("common");
197 
198  return true;
199  }
200 
201  public function getLangKey()
202  {
203  return $this->lang_key;
204  }
205 
206  public function getDefaultLanguage()
207  {
208  return $this->lang_default ? $this->lang_default : 'en';
209  }
210 
220  public function txtlng($a_module, $a_topic, $a_language)
221  {
222  if (strcmp($a_language, $this->lang_key) == 0) {
223  return $this->txt($a_topic);
224  } else {
225  return ilLanguage::_lookupEntry($a_language, $a_module, $a_topic);
226  }
227  }
228 
237  public function txt($a_topic, $a_default_lang_fallback_mod = "")
238  {
239  if (empty($a_topic)) {
240  return "";
241  }
242 
243  // remember the used topics
244  self::$used_topics[$a_topic] = $a_topic;
245 
246  $translation = "";
247  if (isset($this->text[$a_topic])) {
248  $translation = $this->text[$a_topic];
249  }
250 
251  if ($translation == "" && $a_default_lang_fallback_mod != "") {
252  // #13467 - try current language first (could be missing module)
253  if ($this->lang_key != $this->lang_default) {
254  $translation = ilLanguage::_lookupEntry(
255  $this->lang_key,
256  $a_default_lang_fallback_mod,
257  $a_topic
258  );
259  }
260  // try default language last
261  if ($translation == "" || $translation == "-" . $a_topic . "-") {
262  $translation = ilLanguage::_lookupEntry(
263  $this->lang_default,
264  $a_default_lang_fallback_mod,
265  $a_topic
266  );
267  }
268  }
269 
270 
271  if ($translation == "") {
272  if (ILIAS_LOG_ENABLED && is_object($this->log)) {
273  $this->log->debug("Language (" . $a_lang_key . "): topic -" . $a_topic . "- not present");
274  }
275  return "-" . $a_topic . "-";
276  } else {
277  if ($this->usage_log_enabled) {
278  self::logUsage($this->map_modules_txt[$a_topic], $a_topic);
279  }
280  return $translation;
281  }
282  }
283 
289  public function exists($a_topic)
290  {
291  return isset($this->text[$a_topic]);
292  }
293 
294  public function loadLanguageModule($a_module)
295  {
296  global $DIC;
297  $ilDB = $DIC->database();
298 
299  if (in_array($a_module, $this->loaded_modules)) {
300  return;
301  }
302 
303  $this->loaded_modules[] = $a_module;
304 
305  // remember the used modules globally
306  self::$used_modules[$a_module] = $a_module;
307 
309 
310  if (empty($this->lang_key)) {
312  }
313 
314  if (is_array($this->cached_modules[$a_module])) {
315  $this->text = array_merge($this->text, $this->cached_modules[$a_module]);
316 
317  if ($this->usage_log_enabled) {
318  foreach (array_keys($this->cached_modules[$a_module]) as $key) {
319  $this->map_modules_txt[$key] = $a_module;
320  }
321  }
322 
323  return;
324  }
325 
326  $q = "SELECT * FROM lng_modules " .
327  "WHERE lang_key = " . $ilDB->quote($lang_key, "text") . " AND module = " .
328  $ilDB->quote($a_module, "text");
329  $r = $ilDB->query($q);
331 
332  $new_text = unserialize($row["lang_array"]);
333  if (is_array($new_text)) {
334  $this->text = array_merge($this->text, $new_text);
335 
336  if ($this->usage_log_enabled) {
337  foreach (array_keys($new_text) as $key) {
338  $this->map_modules_txt[$key] = $a_module;
339  }
340  }
341  }
342  }
343 
344 
345  public function getInstalledLanguages()
346  {
347  return self::_getInstalledLanguages();
348  }
349 
350  public static function _getInstalledLanguages()
351  {
352  include_once("./Services/Object/classes/class.ilObject.php");
353  $langlist = ilObject::_getObjectsByType("lng");
354 
355  foreach ($langlist as $lang) {
356  if (substr($lang["desc"], 0, 9) == "installed") {
357  $languages[] = $lang["title"];
358  }
359  }
360 
361  return $languages ? $languages : array();
362  }
363 
364  public static function _lookupEntry($a_lang_key, $a_mod, $a_id)
365  {
366  global $DIC;
367  $ilDB = $DIC->database();
368 
369  $set = $ilDB->query($q = sprintf(
370  "SELECT * FROM lng_data WHERE module = %s " .
371  "AND lang_key = %s AND identifier = %s",
372  $ilDB->quote((string) $a_mod, "text"),
373  $ilDB->quote((string) $a_lang_key, "text"),
374  $ilDB->quote((string) $a_id, "text")
375  ));
376  $rec = $ilDB->fetchAssoc($set);
377 
378  if ($rec["value"] != "") {
379  // remember the used topics
380  self::$used_topics[$a_id] = $a_id;
381  self::$used_modules[$a_mod] = $a_mod;
382 
383  if (self::isUsageLogEnabled()) {
384  self::logUsage($a_mod, $a_id);
385  }
386 
387  return $rec["value"];
388  }
389 
390  return "-" . $a_id . "-";
391  }
392 
399  public static function lookupId($a_lang_key)
400  {
401  global $DIC;
402  $ilDB = $DIC->database();
403 
404  $query = 'SELECT obj_id FROM object_data ' . ' ' .
405  'WHERE title = ' . $ilDB->quote($a_lang_key, 'text') . ' ' .
406  'AND type = ' . $ilDB->quote('lng', 'text');
407 
408  $res = $ilDB->query($query);
409  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
410  return $row->obj_id;
411  }
412  return 0;
413  }
414 
415 
416  public function getUsedTopics()
417  {
418  asort(self::$used_topics);
419  return self::$used_topics;
420  }
421 
422  public function getUsedModules()
423  {
424  asort(self::$used_modules);
425  return self::$used_modules;
426  }
427 
428  public function getUserLanguage()
429  {
430  return $this->lang_user;
431  }
432 
437  public static function getFallbackInstance()
438  {
439  return new self('en');
440  }
441 
446  public static function getGlobalInstance()
447  {
448  global $DIC;
449  $ilSetting = $DIC->settings();
450  if ($DIC->offsetExists('ilUser')) {
451  $ilUser = $DIC->user();
452  }
453 
454  if (!ilSession::get('lang') && !$_GET['lang']) {
455  if (
456  $ilUser instanceof ilObjUser &&
457  (!$ilUser->getId() || $ilUser->isAnonymous())
458  ) {
459  require_once 'Services/Language/classes/class.ilLanguageDetection.php';
460  $language_detection = new ilLanguageDetection();
461  $language = $language_detection->detect();
462 
463  $ilUser->setPref('language', $language);
464  $_GET['lang'] = $language;
465  }
466  }
467 
468  if (isset($_POST['change_lang_to']) && $_POST['change_lang_to'] != "") {
469  $_GET['lang'] = ilUtil::stripSlashes($_POST['change_lang_to']);
470  }
471 
472  // prefer personal setting when coming from login screen
473  // Added check for ilUser->getId > 0 because it is 0 when the language is changed and the terms of service should be displayed
474  if (
475  $ilUser instanceof ilObjUser &&
476  ($ilUser->getId() && !$ilUser->isAnonymous())
477  ) {
478  ilSession::set('lang', $ilUser->getPref('language'));
479  }
480 
481  ilSession::set('lang', (isset($_GET['lang']) && $_GET['lang']) ? $_GET['lang'] : ilSession::get('lang'));
482 
483  // check whether lang selection is valid
484  $langs = self::_getInstalledLanguages();
485  if (!in_array(ilSession::get('lang'), $langs)) {
486  if ($ilSetting instanceof ilSetting && $ilSetting->get('language') != '') {
487  ilSession::set('lang', $ilSetting->get('language'));
488  } else {
489  ilSession::set('lang', $langs[0]);
490  }
491  }
492  $_GET['lang'] = ilSession::get('lang');
493 
494  return new self(ilSession::get('lang'));
495  }
496 
497  /*
498  * Transfer text to Javascript
499  *
500  * @param string|array $a_lang_key languag key or array of language keys
501  * @param ilTemplate $a_tpl template
502  */
503  public function toJS($a_lang_key, ilTemplate $a_tpl = null)
504  {
505  global $DIC;
506  $tpl = $DIC['tpl'];
507 
508  if (!is_object($a_tpl)) {
509  $a_tpl = $tpl;
510  }
511 
512  if (!is_array($a_lang_key)) {
513  $a_lang_key = array($a_lang_key);
514  }
515 
516  $map = array();
517  foreach ($a_lang_key as $lk) {
518  $map[$lk] = $this->txt($lk);
519  }
520  $this->toJSMap($map, $a_tpl);
521  }
522 
529  public function toJSMap($a_map, ilTemplate $a_tpl = null)
530  {
531  global $DIC;
532  $tpl = $DIC['tpl'];
533 
534  if (!is_object($a_tpl)) {
535  $a_tpl = $tpl;
536  }
537 
538  if (!is_array($a_map)) {
539  return;
540  }
541 
542  foreach ($a_map as $k => $v) {
543  if ($v != "") {
544  include_once("./Services/JSON/classes/class.ilJsonUtil.php");
545  $a_tpl->addOnloadCode("il.Language.setLangVar('" . $k . "', " . ilJsonUtil::encode($v) . ");");
546  }
547  }
548  }
549 
556  protected static function logUsage($a_module, $a_identifier)
557  {
558  if ($a_module != "" && $a_identifier != "") {
559  self::$lng_log[$a_identifier] = $a_module;
560  }
561  }
562 
571  protected static function isUsageLogEnabled()
572  {
573  global $DIC;
574  $ilClientIniFile = $DIC->clientIni();
575  $ilDB = $DIC->database();
576 
577  if (!(($ilDB instanceof ilDBMySQL) || ($ilDB instanceof ilDBPdoMySQLMyISAM)) || !$ilClientIniFile instanceof ilIniFile) {
578  return false;
579  }
580 
581  if (DEVMODE) {
582  return true;
583  }
584 
585  if (!$ilClientIniFile->variableExists('system', 'LANGUAGE_LOG')) {
586  return $ilClientIniFile->readVariable('system', 'LANGUAGE_LOG') == 1;
587  }
588  return false;
589  }
590 
594  public function __destruct()
595  {
596  global $DIC;
597 
598  //case $ilDB not existing should not happen but if something went wrong it shouldn't leads to any failures
599  if (!$this->usage_log_enabled || !$DIC->isDependencyAvailable("database")) {
600  return;
601  }
602 
603  $ilDB = $DIC->database();
604 
605  foreach ((array) self::$lng_log as $identifier => $module) {
606  $wave[] = '(' . $ilDB->quote($module, 'text') . ', ' . $ilDB->quote($identifier, 'text') . ')';
607  unset(self::$lng_log[$identifier]);
608 
609  if (count($wave) == 150 || (count(self::$lng_log) == 0 && count($wave) > 0)) {
610  $query = 'REPLACE INTO lng_log (module, identifier) VALUES ' . implode(', ', $wave);
611  $ilDB->manipulate($query);
612 
613  $wave = array();
614  }
615  }
616  }
617 } // END class.Language
toJSMap($a_map, ilTemplate $a_tpl=null)
Transfer text to Javascript.
global $DIC
Definition: saml.php:7
$_GET["client_id"]
$tpl
Definition: ilias.php:10
toJS($a_lang_key, ilTemplate $a_tpl=null)
static get($a_var)
Get a value.
Class ilDBPdoMySQLMyISAM.
static set($a_var, $a_val)
Set a value.
static _getObjectsByType($a_obj_type="", $a_owner="")
Get objects by type.
static _lookupEntry($a_lang_key, $a_mod, $a_id)
Class ilLanguageDetection.
static logUsage($a_module, $a_identifier)
saves tupel of language module and identifier
txtlng($a_module, $a_topic, $a_language)
gets the text for a given topic in a given language if the topic is not in the list, the topic itself with "-" will be returned
static getGlobalInstance()
Builds the global language object.
if($modEnd===false) $module
Definition: module.php:59
static $used_modules
exists($a_topic)
Check if language entry exists.
$r
Definition: example_031.php:79
static encode($mixed, $suppress_native=false)
foreach($_POST as $key=> $value) $res
special template class to simplify handling of ITX/PEAR
$ilUser
Definition: imgupload.php:18
__construct($a_lang_key)
Constructor read the single-language file and put this in an array text.
$query
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static getFallbackInstance()
Builds a global default language instance.
$row
global $ilSetting
Definition: privfeed.php:17
loadLanguageModule($a_module)
global $ilDB
__destruct()
destructor saves all language usages to db if log is enabled and ilDB exists
static lookupId($a_lang_key)
Lookup obj_id of language ilDB $ilDB.
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
$ilIliasIniFile
language handling
$languages
Definition: cssgen2.php:34
txt($a_topic, $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
$key
Definition: croninfo.php:18
$_POST["username"]
static _getInstalledLanguages()
INIFile Parser.
static isUsageLogEnabled()
checks if language usage log is enabled you need MySQL to use this function this function is automati...