ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilObjLanguage.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once "./Services/Object/classes/class.ilObject.php";
5
15{
23 public $separator;
26 public $lang_user;
27 public $lang_path;
28
29 public $key;
30 public $status;
31
32
40 public function __construct($a_id = 0, $a_call_by_reference = false)
41 {
42 global $DIC;
43 $lng = $DIC->language();
44
45 $this->type = "lng";
46 parent::__construct($a_id, $a_call_by_reference);
47
48 $this->type = "lng";
49 $this->key = $this->title;
50 $this->status = $this->desc;
51 $this->lang_default = $lng->lang_default;
52 $this->lang_user = $lng->lang_user;
53 $this->lang_path = $lng->lang_path;
54 $this->cust_lang_path = $lng->cust_lang_path;
55 $this->separator = $lng->separator;
56 $this->comment_separator = $lng->comment_separator;
57 }
58
59
64 public static function getInstalledLanguages()
65 {
66 $objects = array();
68 foreach ($languages as $lang) {
69 $langObj = new ilObjLanguage($lang["obj_id"], false);
70 if ($langObj->isInstalled()) {
71 $objects[] = $langObj;
72 } else {
73 unset($langObj);
74 }
75 }
76 return $objects;
77 }
78
79
85 public function getKey()
86 {
87 return $this->key;
88 }
89
95 public function getStatus()
96 {
97 return $this->status;
98 }
99
103 public function isSystemLanguage()
104 {
105 if ($this->key == $this->lang_default) {
106 return true;
107 } else {
108 return false;
109 }
110 }
111
115 public function isUserLanguage()
116 {
117 if ($this->key == $this->lang_user) {
118 return true;
119 } else {
120 return false;
121 }
122 }
123
124
130 public function isInstalled()
131 {
132 if (substr($this->getStatus(), 0, 9) == "installed") {
133 return true;
134 } else {
135 return false;
136 }
137 }
138
145 public function isLocal()
146 {
147 if (substr($this->getStatus(), 10) == "local") {
148 return true;
149 } else {
150 return false;
151 }
152 }
153
160 public function install($scope = '')
161 {
162 if (!empty($scope)) {
163 if ($scope == 'global') {
164 $scope = '';
165 } else {
166 $scopeExtension = '.' . $scope;
167 }
168 }
169
170 if (($this->isInstalled() == false) ||
171 ($this->isInstalled() == true && $this->isLocal() == false && !empty($scope))) {
172 if ($this->check($scope)) {
173 // lang-file is ok. Flush data in db and...
174 if (empty($scope)) {
175 $this->flush('keep_local');
176 }
177
178 // ...re-insert data from lang-file
179 $this->insert($scope);
180
181 // update information in db-table about available/installed languages
182 if (empty($scope)) {
183 $newDesc = 'installed';
184 } elseif ($scope == 'local') {
185 $newDesc = 'installed_local';
186 }
187 $this->setDescription($newDesc);
188 $this->update();
189 return $this->getKey();
190 }
191 }
192 return "";
193 }
194
195
201 public function uninstall()
202 {
203 if ((substr($this->status, 0, 9) == "installed") && ($this->key != $this->lang_default) && ($this->key != $this->lang_user)) {
204 $this->flush('all');
205 $this->setTitle($this->key);
206 $this->setDescription("not_installed");
207 $this->update();
208 $this->resetUserLanguage($this->key);
209
210 return $this->key;
211 }
212 return "";
213 }
214
215
220 public function refresh()
221 {
222 if ($this->isInstalled() == true) {
223 if ($this->check()) {
224 $this->flush('keep_local');
225 $this->insert();
226 $this->setTitle($this->getKey());
227 $this->setDescription($this->getStatus());
228 $this->update();
229
230 if ($this->isLocal() == true) {
231 if ($this->check('local')) {
232 $this->insert('local');
233 $this->setTitle($this->getKey());
234 $this->setDescription($this->getStatus());
235 $this->update();
236 }
237 }
238 return true;
239 }
240 }
241 return false;
242 }
243
247 public static function refreshAll()
248 {
250 $refreshed = array();
251
252 foreach ($languages as $lang) {
253 $langObj = new ilObjLanguage($lang["obj_id"], false);
254 if ($langObj->refresh()) {
255 $refreshed[] = $langObj->getKey();
256 }
257 unset($langObj);
258 }
259
260 self::refreshPlugins($refreshed);
261 }
262
263
268 public static function refreshPlugins($a_lang_keys = null)
269 {
270 global $DIC;
271 $ilPluginAdmin = $DIC['ilPluginAdmin'];
272
273 // refresh languages of activated plugins
274 include_once("./Services/Component/classes/class.ilPluginSlot.php");
275 $slots = ilPluginSlot::getAllSlots();
276 foreach ($slots as $slot) {
277 $act_plugins = $ilPluginAdmin->getActivePluginsForSlot(
278 $slot["component_type"],
279 $slot["component_name"],
280 $slot["slot_id"]
281 );
282 foreach ($act_plugins as $plugin) {
283 include_once("./Services/Component/classes/class.ilPlugin.php");
285 $slot["component_type"],
286 $slot["component_name"],
287 $slot["slot_id"],
288 $plugin
289 );
290 if (is_object($pl)) {
291 $pl->updateLanguages($a_lang_keys);
292 }
293 }
294 }
295 }
296
297
303 public static function _deleteLangData($a_lang_key, $a_keep_local_change = false)
304 {
305 global $DIC;
306 $ilDB = $DIC->database();
307
308 if (!$a_keep_local_change) {
309 $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = " .
310 $ilDB->quote($a_lang_key, "text"));
311 } else {
312 $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = " .
313 $ilDB->quote($a_lang_key, "text") .
314 " AND local_change IS NULL");
315 }
316 }
317
322 public function flush($a_mode = 'all')
323 {
324 global $DIC;
325 $ilDB = $DIC->database();
326
327 ilObjLanguage::_deleteLangData($this->key, ($a_mode == 'keep_local'));
328
329 if ($a_mode == 'all') {
330 $ilDB->manipulate("DELETE FROM lng_modules WHERE lang_key = " .
331 $ilDB->quote($this->key, "text"));
332 }
333 }
334
335
342 public function getLocalChanges($a_min_date = "", $a_max_date = "")
343 {
344 global $DIC;
345 $ilDB = $DIC->database();
346
347 if ($a_min_date == "") {
348 $a_min_date = "1980-01-01 00:00:00";
349 }
350 if ($a_max_date == "") {
351 $a_max_date = "2200-01-01 00:00:00";
352 }
353
354 $q = sprintf(
355 "SELECT * FROM lng_data WHERE lang_key = %s " .
356 "AND local_change >= %s AND local_change <= %s",
357 $ilDB->quote($this->key, "text"),
358 $ilDB->quote($a_min_date, "timestamp"),
359 $ilDB->quote($a_max_date, "timestamp")
360 );
361 $result = $ilDB->query($q);
362
363 $changes = array();
364 while ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
365 $changes[$row["module"]][$row["identifier"]] = $row["value"];
366 }
367 return $changes;
368 }
369
370
376 public static function _getLastLocalChange($a_key)
377 {
378 global $DIC;
379 $ilDB = $DIC->database();
380
381 $q = sprintf(
382 "SELECT MAX(local_change) last_change FROM lng_data " .
383 "WHERE lang_key = %s AND local_change IS NOT NULL",
384 $ilDB->quote($a_key, "text")
385 );
386 $result = $ilDB->query($q);
387
389 return $row['last_change'];
390 } else {
391 return "";
392 }
393 }
394
395
402 public static function _getLocalChangesByModule($a_key, $a_module)
403 {
404 global $DIC;
405 $ilDB = $DIC->database();
406
407 $changes = array();
408 $result = $ilDB->queryF(
409 "SELECT * FROM lng_data WHERE lang_key = %s AND module = %s AND local_change IS NOT NULL",
410 array('text', 'text'),
411 array($a_key, $a_module)
412 );
413
414 while ($row = $ilDB->fetchAssoc($result)) {
415 $changes[$row['identifier']] = $row['value'];
416 }
417 return $changes;
418 }
419
420
426 public function insert($scope = '')
427 {
428 global $DIC;
429 $ilDB = $DIC->database();
430
431 if (!empty($scope)) {
432 if ($scope == 'global') {
433 $scope = '';
434 } else {
435 $scopeExtension = '.' . $scope;
436 }
437 }
438
440 if ($scope == "local") {
441 $path = $this->cust_lang_path;
442 }
443
444 $lang_file = $path . "/ilias_" . $this->key . ".lang" . $scopeExtension;
445
446 if (is_file($lang_file)) {
447 // initialize the array for updating lng_modules below
448 $lang_array = array();
449 $lang_array["common"] = array();
450
451 // remove header first
452 if ($content = $this->cut_header(file($lang_file))) {
453 if (empty($scope)) {
454 // reset change date for a global file
455 // get all local changes for a global file
456 $change_date = null;
457 $local_changes = $this->getLocalChanges();
458 } elseif ($scope == 'local') {
459 // set the change date to import time for a local file
460 // get the modification date of the local file
461 // get the newer local changes for a local file
462 $change_date = date("Y-m-d H:i:s", time());
463 $min_date = date("Y-m-d H:i:s", filemtime($lang_file));
464 $local_changes = $this->getLocalChanges($min_date);
465 }
466
467 foreach ($content as $key => $val) {
468 // split the line of the language file
469 // [0]: module
470 // [1]: identifier
471 // [2]: value
472 // [3]: comment (optional)
473 $separated = explode($this->separator, trim($val));
474 $pos = strpos($separated[2], $this->comment_separator);
475 if ($pos !== false) {
476 $separated[3] = substr($separated[2], $pos + strlen($this->comment_separator));
477 $separated[2] = substr($separated[2], 0, $pos);
478 }
479
480 // check if the value has a local change
481 $local_value = $local_changes[$separated[0]][$separated[1]];
482
483 if (empty($scope)) {
484 // import of a global language file
485
486 if ($local_value != "" and $local_value != $separated[2]) {
487 // keep an existing and different local calue
488 $lang_array[$separated[0]][$separated[1]] = $local_value;
489 } else {
490 // check for double entries in global file
491 if ($double_checker[$separated[0]][$separated[1]][$this->key]) {
492 $this->ilias->raiseError(
493 "Duplicate Language Entry in $lang_file:\n$val",
494 $this->ilias->error_obj->MESSAGE
495 );
496 }
497 $double_checker[$separated[0]][$separated[1]][$this->key] = true;
498
499 // insert a new value if no local value exists
500 // reset local change date if the values are equal
502 $separated[0],
503 $separated[1],
504 $this->key,
505 $separated[2],
506 $change_date,
507 $separated[3]
508 );
509
510 $lang_array[$separated[0]][$separated[1]] = $separated[2];
511 }
512 } elseif ($scope == 'local') {
513 // import of a local language file
514
515 if ($local_value != "") {
516 // keep a locally changed value that is newer than the file
517 $lang_array[$separated[0]][$separated[1]] = $local_value;
518 } else {
519 // insert a new value if no global value exists
520 // (local files may have additional entries for customizations)
521 // set the change date to the import date
523 $separated[0],
524 $separated[1],
525 $this->key,
526 $separated[2],
527 $change_date,
528 $separated[3]
529 );
530
531 $lang_array[$separated[0]][$separated[1]] = $separated[2];
532 }
533 }
534 }
535
536 $ld = "";
537 if (empty($scope)) {
538 $ld = "installed";
539 } elseif ($scope == 'local') {
540 $ld = "installed_local";
541 }
542 if ($ld) {
543 $query = "UPDATE object_data SET " .
544 "description = " . $ilDB->quote($ld, "text") . ", " .
545 "last_update = " . $ilDB->now() . " " .
546 "WHERE title = " . $ilDB->quote($this->key, "text") . " " .
547 "AND type = 'lng'";
548 $ilDB->manipulate($query);
549 }
550 }
551
552 foreach ($lang_array as $module => $lang_arr) {
553 if ($scope == "local") {
554 $q = "SELECT * FROM lng_modules WHERE " .
555 " lang_key = " . $ilDB->quote($this->key, "text") .
556 " AND module = " . $ilDB->quote($module, "text");
557 $set = $ilDB->query($q);
558 $row = $ilDB->fetchAssoc($set);
559 $arr2 = unserialize($row["lang_array"]);
560 if (is_array($arr2)) {
561 $lang_arr = array_merge($arr2, $lang_arr);
562 }
563 }
564 ilObjLanguage::replaceLangModule($this->key, $module, $lang_arr);
565 }
566 }
567 }
568
572 final public static function replaceLangModule($a_key, $a_module, $a_array)
573 {
574 global $DIC;
575 $ilDB = $DIC->database();
576
577 // avoid flushing the whole cache (see mantis #28818)
578 ilCachedLanguage::getInstance($a_key)->deleteInCache();
579
580 $ilDB->manipulate(sprintf(
581 "DELETE FROM lng_modules WHERE lang_key = %s AND module = %s",
582 $ilDB->quote($a_key, "text"),
583 $ilDB->quote($a_module, "text")
584 ));
585
586 /*$ilDB->manipulate(sprintf("INSERT INTO lng_modules (lang_key, module, lang_array) VALUES ".
587 "(%s,%s,%s)", $ilDB->quote($a_key, "text"),
588 $ilDB->quote($a_module, "text"),
589 $ilDB->quote(serialize($a_array), "clob")));*/
590 $ilDB->insert("lng_modules", array(
591 "lang_key" => array("text", $a_key),
592 "module" => array("text", $a_module),
593 "lang_array" => array("clob", serialize((array) $a_array))
594 ));
595
596 // check if the module is correctly saved
597 // see mantis #20046 and #19140
598 $result = $ilDB->queryF(
599 "SELECT lang_array FROM lng_modules WHERE lang_key = %s AND module = %s",
600 array('text','text'),
601 array($a_key, $a_module)
602 );
603 $row = $ilDB->fetchAssoc($result);
604
605 $unserialied = unserialize($row['lang_array']);
606 if (!is_array($unserialied)) {
608 $ilErr = $DIC['ilErr'];
609 $ilErr->raiseError(
610 "Data for module '" . $a_module . "' of language '" . $a_key . "' is not correctly saved. " .
611 "Please check the collation of your database tables lng_data and lng_modules. It must be utf8_unicode_ci.",
612 $ilErr->MESSAGE
613 );
614 }
615 }
616
620 final public static function replaceLangEntry(
621 $a_module,
622 $a_identifier,
623 $a_lang_key,
624 $a_value,
625 $a_local_change = null,
626 $a_remarks = null
627 ) {
628 global $DIC;
629 $ilDB = $DIC->database();
630
631 // avoid a cache flush here (see mantis #28818)
632 // ilGlobalCache::flushAll();
633
634 if (isset($a_remarks)) {
635 $a_remarks = substr($a_remarks, 0, 250);
636 }
637 if ($a_remarks == '') {
638 unset($a_remarks);
639 }
640
641 if (isset($a_value)) {
642 $a_value = substr($a_value, 0, 4000);
643 }
644 if ($a_value == '') {
645 unset($a_value);
646 }
647
648 $ilDB->replace(
649 'lng_data',
650 array(
651 'module' => array('text',$a_module),
652 'identifier' => array('text',$a_identifier),
653 'lang_key' => array('text',$a_lang_key)
654 ),
655 array(
656 'value' => array('text',$a_value),
657 'local_change' => array('timestamp',$a_local_change),
658 'remarks' => array('text', $a_remarks)
659 )
660 );
661 return true;
662
663 /*
664 $ilDB->manipulate(sprintf("DELETE FROM lng_data WHERE module = %s AND ".
665 "identifier = %s AND lang_key = %s",
666 $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
667 $ilDB->quote($a_lang_key, "text")));
668
669
670 $ilDB->manipulate(sprintf("INSERT INTO lng_data " .
671 "(module, identifier, lang_key, value, local_change) " .
672 "VALUES (%s,%s,%s,%s,%s)",
673 $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
674 $ilDB->quote($a_lang_key, "text"), $ilDB->quote($a_value, "text"),
675 $ilDB->quote($a_local_change, "timestamp")));
676 */
677 }
678
682 final public static function updateLangEntry(
683 $a_module,
684 $a_identifier,
685 $a_lang_key,
686 $a_value,
687 $a_local_change = null,
688 $a_remarks = null
689 ) {
690 global $DIC;
691 $ilDB = $DIC->database();
692
693 if (isset($a_remarks)) {
694 $a_remarks = substr($a_remarks, 0, 250);
695 }
696 if ($a_remarks == '') {
697 unset($a_remarks);
698 }
699
700 if (isset($a_value)) {
701 $a_value = substr($a_value, 0, 4000);
702 }
703 if ($a_value == '') {
704 unset($a_value);
705 }
706
707 $ilDB->manipulate(sprintf(
708 "UPDATE lng_data " .
709 "SET value = %s, local_change = %s, remarks = %s " .
710 "WHERE module = %s AND identifier = %s AND lang_key = %s ",
711 $ilDB->quote($a_value, "text"),
712 $ilDB->quote($a_local_change, "timestamp"),
713 $ilDB->quote($a_remarks, "text"),
714 $ilDB->quote($a_module, "text"),
715 $ilDB->quote($a_identifier, "text"),
716 $ilDB->quote($a_lang_key, "text")
717 ));
718 }
719
720
724 final public static function deleteLangEntry($a_module, $a_identifier, $a_lang_key)
725 {
726 global $DIC;
727 $ilDB = $DIC->database();
728
729 $ilDB->manipulate(sprintf(
730 "DELETE FROM lng_data " .
731 "WHERE module = %s AND identifier = %s AND lang_key = %s ",
732 $ilDB->quote($a_module, "text"),
733 $ilDB->quote($a_identifier, "text"),
734 $ilDB->quote($a_lang_key, "text")
735 ));
736
737 return true;
738 }
739
740
747 public function resetUserLanguage($lang_key)
748 {
749 global $DIC;
750 $ilDB = $DIC->database();
751
752 $query = "UPDATE usr_pref SET " .
753 "value = " . $ilDB->quote($this->lang_default, "text") . " " .
754 "WHERE keyword = " . $ilDB->quote('language', "text") . " " .
755 "AND value = " . $ilDB->quote($lang_key, "text");
756 $ilDB->manipulate($query);
757 }
758
767 public static function cut_header($content)
768 {
769 foreach ($content as $key => $val) {
770 if (trim($val) == "<!-- language file start -->") {
771 return array_slice($content, $key + 1);
772 }
773 }
774
775 return false;
776 }
777
784 public function optimizeData()
785 {
786 // Mantis #22313: removed table optimization
787 return true;
788 }
789
799 public function check($scope = '')
800 {
801 include_once("./Services/Utilities/classes/class.ilStr.php");
802
803 if (!empty($scope)) {
804 if ($scope == 'global') {
805 $scope = '';
806 } else {
807 $scopeExtension = '.' . $scope;
808 }
809 }
810
812 if ($scope == "local") {
813 $path = $this->cust_lang_path;
814 }
815
816 $tmpPath = getcwd();
817
818 // dir check
819 if (!is_dir($path)) {
820 $this->ilias->raiseError("Directory not found: " . $path, $this->ilias->error_obj->MESSAGE);
821 }
822
823 chdir($path);
824
825 // compute lang-file name format
826 $lang_file = "ilias_" . $this->key . ".lang" . $scopeExtension;
827
828 // file check
829 if (!is_file($lang_file)) {
830 $this->ilias->raiseError("File not found: " . $lang_file, $this->ilias->error_obj->MESSAGE);
831 }
832
833 // header check
834 $content = $this->cut_header(file($lang_file));
835 if ($content === false) {
836 $this->ilias->raiseError("Wrong Header in " . $lang_file, $this->ilias->error_obj->MESSAGE);
837 }
838
839 // check (counting) elements of each lang-entry
840 $line = 0;
841 foreach ($content as $key => $val) {
842 $separated = explode($this->separator, trim($val));
843 $num = count($separated);
844 ++$n;
845 if ($num != 3) {
846 $line = $n + 36;
847 $this->ilias->raiseError("Wrong parameter count in " . $lang_file . " in line $line (Value: $val)! Please check your language file!", $this->ilias->error_obj->MESSAGE);
848 }
849 if (!ilStr::isUtf8($separated[2])) {
850 $this->ilias->raiseError("Non UTF8 character found in " . $lang_file . " in line $line (Value: $val)! Please check your language file!", $this->ilias->error_obj->MESSAGE);
851 }
852 }
853
854 chdir($tmpPath);
855
856 // no error occured
857 return true;
858 }
859
863 public static function countUsers($a_lang)
864 {
865 global $DIC;
866 $ilDB = $DIC->database();
867 $lng = $DIC->language();
868
869 $set = $ilDB->query("SELECT COUNT(*) cnt FROM usr_data ud JOIN usr_pref up" .
870 " ON ud.usr_id = up.usr_id " .
871 " WHERE up.value = " . $ilDB->quote($a_lang, "text") .
872 " AND up.keyword = " . $ilDB->quote("language", "text"));
873 $rec = $ilDB->fetchAssoc($set);
874
875 // add users with no usr_pref set to default language
876 if ($a_lang == $lng->lang_default) {
877 $set2 = $ilDB->query("SELECT COUNT(*) cnt FROM usr_data ud LEFT JOIN usr_pref up" .
878 " ON (ud.usr_id = up.usr_id AND up.keyword = " . $ilDB->quote("language", "text") . ")" .
879 " WHERE up.value IS NULL ");
880 $rec2 = $ilDB->fetchAssoc($set2);
881 }
882
883 return (int) $rec["cnt"] + (int) $rec2["cnt"];
884 }
885} // END class.LanguageObject
$result
$n
Definition: RandomTest.php:85
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
Class ilObjLanguage.
static refreshPlugins($a_lang_keys=null)
static _deleteLangData($a_lang_key, $a_keep_local_change=false)
Delete languge data.
static _getLocalChangesByModule($a_key, $a_module)
Get the local changes of a language module.
static updateLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null, $a_remarks=null)
Replace lang entry.
static deleteLangEntry($a_module, $a_identifier, $a_lang_key)
Delete lang entry.
static refreshAll()
Refresh all installed languages.
isInstalled()
Check language object status, and return true if language is installed.
uninstall()
uninstall current language
getKey()
get language key
getStatus()
get language status
isLocal()
Check language object status, and return true if a local language file is installed.
static getInstalledLanguages()
Get the language objects of the installed languages.
static countUsers($a_lang)
Count number of users that use a language.
resetUserLanguage($lang_key)
search ILIAS for users which have selected '$lang_key' as their prefered language and reset them to d...
install($scope='')
install current language
isSystemLanguage()
check if language is system language
isUserLanguage()
check if language is system language
flush($a_mode='all')
remove language data from database
insert($scope='')
insert language data from file into database
static cut_header($content)
remove lang-file haeder information from '$content' This function seeks for a special keyword where t...
static replaceLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null, $a_remarks=null)
Replace lang entry.
__construct($a_id=0, $a_call_by_reference=false)
Constructor.
refresh()
refresh current language
getLocalChanges($a_min_date="", $a_max_date="")
get locally changed language entries
optimizeData()
optimizes the db-table langdata
check($scope='')
Validate the logical structure of a lang file.
static _getLastLocalChange($a_key)
get the date of the last local change
Class ilObject Basic functions for all objects.
update()
update object in db
static _getObjectsByType($a_obj_type="", $a_owner="")
Get objects by type.
setTitle($a_title)
set object title
setDescription($a_desc)
set object description
static getAllSlots()
Get all plugin slots.
static getPluginObject(string $a_ctype, string $a_cname, string $a_slot_id, string $a_pname)
static isUtf8($a_str)
Check whether string is utf-8.
$languages
Definition: cssgen2.php:34
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
$ld
Definition: langwiz.php:244
$row
if($modEnd===false) $module
Definition: module.php:59
redirection script todo: (a better solution should control the processing via a xml file)
$query
$ilErr
Definition: raiseError.php:18
global $DIC
Definition: saml.php:7
global $ilDB