ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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  {
157 
158  $this->ilias = $ilias;
159 
160  if (!isset($log)) {
161  if (is_object($ilias)) {
162  require_once "./Services/Logging/classes/class.ilLog.php";
163  $this->log = new ilLog(ILIAS_LOG_DIR, ILIAS_LOG_FILE, $ilias->getClientId(), ILIAS_LOG_ENABLED);
164  }
165  } else {
166  $this->log =&$log;
167  }
168 
169  $this->lang_key = $a_lang_key;
170 
171  $this->text = array();
172  $this->loaded_modules = array();
173 
174  $this->usage_log_enabled = self::isUsageLogEnabled();
175 
176  //$this->lang_path = ILIAS_ABSOLUTE_PATH.substr($this->ilias->ini->readVariable("language","path"),1);
177 
178  // if no directory was found fall back to default lang dir
179  //if (!is_dir($this->lang_path))
180  //{
181  $this->lang_path = ILIAS_ABSOLUTE_PATH . "/lang";
182  //}
183  $this->cust_lang_path = ILIAS_ABSOLUTE_PATH . "/Customizing/global/lang";
184 
185  $this->lang_default = $ilIliasIniFile->readVariable("language", "default");
186  if (is_object($ilSetting) && $ilSetting->get("language") != "") {
187  $this->lang_default = $ilSetting->get("language");
188  }
189  $this->lang_user = $ilUser->prefs["language"];
190 
191  $langs = $this->getInstalledLanguages();
192 
193  if (!in_array($this->lang_key, $langs)) {
194  $this->lang_key = $this->lang_default;
195  }
196 
197  require_once('./Services/Language/classes/class.ilCachedLanguage.php');
198  $this->global_cache = ilCachedLanguage::getInstance($this->lang_key);
199  if ($this->global_cache->isActive()) {
200  $this->cached_modules = $this->global_cache->getTranslations();
201  }
202 
203  $this->loadLanguageModule("common");
204 
205  return true;
206  }
207 
208  public function getLangKey()
209  {
210  return $this->lang_key;
211  }
212 
213  public function getDefaultLanguage()
214  {
215  return $this->lang_default ? $this->lang_default : 'en';
216  }
217 
227  public function txtlng($a_module, $a_topic, $a_language)
228  {
229  if (strcmp($a_language, $this->lang_key) == 0) {
230  return $this->txt($a_topic);
231  } else {
232  return ilLanguage::_lookupEntry($a_language, $a_module, $a_topic);
233  }
234  }
235 
244  public function txt($a_topic, $a_default_lang_fallback_mod = "")
245  {
246  if (empty($a_topic)) {
247  return "";
248  }
249 
250  // remember the used topics
251  self::$used_topics[$a_topic] = $a_topic;
252 
253  $translation = "";
254  if (isset($this->text[$a_topic])) {
255  $translation = $this->text[$a_topic];
256  }
257 
258  if ($translation == "" && $a_default_lang_fallback_mod != "") {
259  // #13467 - try current language first (could be missing module)
260  if ($this->lang_key != $this->lang_default) {
261  $translation = ilLanguage::_lookupEntry(
262  $this->lang_key,
263  $a_default_lang_fallback_mod,
264  $a_topic
265  );
266  }
267  // try default language last
268  if ($translation == "" || $translation == "-" . $a_topic . "-") {
269  $translation = ilLanguage::_lookupEntry(
270  $this->lang_default,
271  $a_default_lang_fallback_mod,
272  $a_topic
273  );
274  }
275  }
276 
277 
278  if ($translation == "") {
279  if (ILIAS_LOG_ENABLED && is_object($this->log)) {
280  $this->log->writeLanguageLog($a_topic, $this->lang_key);
281  }
282  return "-" . $a_topic . "-";
283  } else {
284  if ($this->usage_log_enabled) {
285  self::logUsage($this->map_modules_txt[$a_topic], $a_topic);
286  }
287  return $translation;
288  }
289  }
290 
296  public function exists($a_topic)
297  {
298  return isset($this->text[$a_topic]);
299  }
300 
301  public function loadLanguageModule($a_module)
302  {
303  global $ilDB;
304 
305  if (in_array($a_module, $this->loaded_modules)) {
306  return;
307  }
308 
309  $this->loaded_modules[] = $a_module;
310 
311  // remember the used modules globally
312  self::$used_modules[$a_module] = $a_module;
313 
315 
316  if (empty($this->lang_key)) {
318  }
319 
320  if (is_array($this->cached_modules[$a_module])) {
321  $this->text = array_merge($this->text, $this->cached_modules[$a_module]);
322 
323  if ($this->usage_log_enabled) {
324  foreach (array_keys($this->cached_modules[$a_module]) as $key) {
325  $this->map_modules_txt[$key] = $a_module;
326  }
327  }
328 
329  return;
330  }
331 
332  /*
333  $query = "SELECT identifier,value FROM lng_data " .
334  "WHERE lang_key = '" . $lang_key."' " .
335  "AND module = '$a_module'";
336  $r = $this->ilias->db->query($query);
337 
338  while ($row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
339  {
340  $this->text[$row->identifier] = $row->value;
341  }
342  */
343 
344  $q = "SELECT * FROM lng_modules " .
345  "WHERE lang_key = " . $ilDB->quote($lang_key, "text") . " AND module = " .
346  $ilDB->quote($a_module, "text");
347  $r = $ilDB->query($q);
349 
350  $new_text = unserialize($row["lang_array"]);
351  if (is_array($new_text)) {
352  $this->text = array_merge($this->text, $new_text);
353 
354  if ($this->usage_log_enabled) {
355  foreach (array_keys($new_text) as $key) {
356  $this->map_modules_txt[$key] = $a_module;
357  }
358  }
359  }
360  }
361 
362 
363  public function getInstalledLanguages()
364  {
365  return self::_getInstalledLanguages();
366  }
367 
368  public static function _getInstalledLanguages()
369  {
370  include_once("./Services/Object/classes/class.ilObject.php");
371  $langlist = ilObject::_getObjectsByType("lng");
372 
373  foreach ($langlist as $lang) {
374  if (substr($lang["desc"], 0, 9) == "installed") {
375  $languages[] = $lang["title"];
376  }
377  }
378 
379  return $languages ? $languages : array();
380  }
381 
382  public static function _lookupEntry($a_lang_key, $a_mod, $a_id)
383  {
384  global $ilDB;
385 
386  $set = $ilDB->query($q = sprintf(
387  "SELECT * FROM lng_data WHERE module = %s " .
388  "AND lang_key = %s AND identifier = %s",
389  $ilDB->quote((string) $a_mod, "text"),
390  $ilDB->quote((string) $a_lang_key, "text"),
391  $ilDB->quote((string) $a_id, "text")
392  ));
393  $rec = $ilDB->fetchAssoc($set);
394 
395  if ($rec["value"] != "") {
396  // remember the used topics
397  self::$used_topics[$a_id] = $a_id;
398  self::$used_modules[$a_mod] = $a_mod;
399 
400  if (self::isUsageLogEnabled()) {
401  self::logUsage($a_mod, $a_id);
402  }
403 
404  return $rec["value"];
405  }
406 
407  return "-" . $a_id . "-";
408  }
409 
416  public static function lookupId($a_lang_key)
417  {
418  global $ilDB;
419 
420  $query = 'SELECT obj_id FROM object_data ' . ' ' .
421  'WHERE title = ' . $ilDB->quote($a_lang_key, 'text') . ' ' .
422  'AND type = ' . $ilDB->quote('lng', 'text');
423 
424  $res = $ilDB->query($query);
425  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
426  return $row->obj_id;
427  }
428  return 0;
429  }
430 
431 
432  public function getUsedTopics()
433  {
434  asort(self::$used_topics);
435  return self::$used_topics;
436  }
437 
438  public function getUsedModules()
439  {
440  asort(self::$used_modules);
441  return self::$used_modules;
442  }
443 
444  public function getUserLanguage()
445  {
446  return $this->lang_user;
447  }
448 
453  public static function getFallbackInstance()
454  {
455  return new self('en');
456  }
457 
462  public static function getGlobalInstance()
463  {
468  global $ilUser, $ilSetting, $lng;
469 
470  if (!ilSession::get('lang') && !$_GET['lang']) {
471  if (
472  $ilUser instanceof ilObjUser &&
473  (!$ilUser->getId() || $ilUser->isAnonymous())
474  ) {
475  require_once 'Services/Language/classes/class.ilLanguageDetection.php';
476  $language_detection = new ilLanguageDetection();
477  $language = $language_detection->detect();
478 
479  $ilUser->setPref('language', $language);
480  $_GET['lang'] = $language;
481  }
482  }
483 
484  if (isset($_POST['change_lang_to']) && $_POST['change_lang_to'] != "") {
485  $_GET['lang'] = ilUtil::stripSlashes($_POST['change_lang_to']);
486  }
487 
488  // prefer personal setting when coming from login screen
489  // Added check for ilUser->getId > 0 because it is 0 when the language is changed and the terms of service should be displayed
490  if (
491  $ilUser instanceof ilObjUser &&
492  ($ilUser->getId() && !$ilUser->isAnonymous())
493  ) {
494  ilSession::set('lang', $ilUser->getPref('language'));
495  }
496 
497  ilSession::set('lang', (isset($_GET['lang']) && $_GET['lang']) ? $_GET['lang'] : ilSession::get('lang'));
498 
499  // check whether lang selection is valid
500  $langs = self::_getInstalledLanguages();
501  if (!in_array(ilSession::get('lang'), $langs)) {
502  if ($ilSetting instanceof ilSetting && $ilSetting->get('language') != '') {
503  ilSession::set('lang', $ilSetting->get('language'));
504  } else {
505  ilSession::set('lang', $langs[0]);
506  }
507  }
508  $_GET['lang'] = ilSession::get('lang');
509 
510  return new self(ilSession::get('lang'));
511  }
512 
513  /*
514  * Transfer text to Javascript
515  *
516  * @param string|array $a_lang_key languag key or array of language keys
517  * @param ilTemplate $a_tpl template
518  */
519  public function toJS($a_lang_key, ilTemplate $a_tpl = null)
520  {
521  global $tpl;
522 
523  if (!is_object($a_tpl)) {
524  $a_tpl = $tpl;
525  }
526 
527  if (!is_array($a_lang_key)) {
528  $a_lang_key = array($a_lang_key);
529  }
530 
531  $map = array();
532  foreach ($a_lang_key as $lk) {
533  $map[$lk] = $this->txt($lk);
534  }
535  $this->toJSMap($map, $a_tpl);
536  }
537 
544  public function toJSMap($a_map, ilTemplate $a_tpl = null)
545  {
546  global $tpl;
547 
548  if (!is_object($a_tpl)) {
549  $a_tpl = $tpl;
550  }
551 
552  if (!is_array($a_map)) {
553  return;
554  }
555 
556  foreach ($a_map as $k => $v) {
557  if ($v != "") {
558  include_once("./Services/JSON/classes/class.ilJsonUtil.php");
559  $a_tpl->addOnloadCode("il.Language.setLangVar('" . $k . "', " . ilJsonUtil::encode($v) . ");");
560  }
561  }
562  }
563 
570  protected static function logUsage($a_module, $a_identifier)
571  {
572  if ($a_module != "" && $a_identifier != "") {
573  self::$lng_log[$a_identifier] = $a_module;
574  }
575  }
576 
585  protected static function isUsageLogEnabled()
586  {
588  global $ilClientIniFile, $ilDB;
589 
590  if (!(($ilDB instanceof ilDBMySQL) || ($ilDB instanceof ilDBPdoMySQLMyISAM)) || !$ilClientIniFile instanceof ilIniFile) {
591  return false;
592  }
593 
594  if (DEVMODE) {
595  return true;
596  }
597 
598  if (!$ilClientIniFile->variableExists('system', 'LANGUAGE_LOG')) {
599  return $ilClientIniFile->readVariable('system', 'LANGUAGE_LOG') == 1;
600  }
601  return false;
602  }
603 
607  public function __destruct()
608  {
609  global $ilDB;
610 
611  //case $ilDB not existing should not happen but if something went wrong it shouldn't leads to any failures
612  if (!$this->usage_log_enabled || !(($ilDB instanceof ilDBMySQL) || ($ilDB instanceof ilDBPdoMySQLMyISAM))) {
613  return;
614  }
615 
616  foreach ((array) self::$lng_log as $identifier => $module) {
617  $wave[] = '(' . $ilDB->quote($module, 'text') . ', ' . $ilDB->quote($identifier, 'text') . ')';
618  unset(self::$lng_log[$identifier]);
619 
620  if (count($wave) == 150 || (count(self::$lng_log) == 0 && count($wave) > 0)) {
621  $query = 'REPLACE INTO lng_log (module, identifier) VALUES ' . implode(', ', $wave);
622  $ilDB->manipulate($query);
623 
624  $wave = array();
625  }
626  }
627  }
628 } // END class.Language
toJSMap($a_map, ilTemplate $a_tpl=null)
Transfer text to Javascript.
$_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.
logging
Definition: class.ilLog.php:18
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
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
redirection script todo: (a better solution should control the processing via a xml file) ...
__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.
MySQL Database Wrapper.
Create styles array
The data for the language used.
global $ilSetting
Definition: privfeed.php:17
global $lng
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.
$ilIliasIniFile
language handling
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.