ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilLanguage.php
Go to the documentation of this file.
1<?php
2/*
3 +-----------------------------------------------------------------------------+
4 | ILIAS open source |
5 +-----------------------------------------------------------------------------+
6 | Copyright (c) 1998-2009 ILIAS open source, University of Cologne |
7 | |
8 | This program is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU General Public License |
10 | as published by the Free Software Foundation; either version 2 |
11 | of the License, or (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 +-----------------------------------------------------------------------------+
22*/
23
24
44class ilLanguage
45{
51 public $text = array();
52
59 public $lang_default = "en";
60
68 public $lang_path;
69
75 public $lang_key;
76
82 public $separator = "#:#";
83
89 public $comment_separator = "###";
90
100 public function __construct($a_lang_key)
101 {
102 $this->lang_key = ($a_lang_key) ? $a_lang_key : $this->lang_default;
103 $this->lang_path = ILIAS_ABSOLUTE_PATH . "/lang";
104 $this->cust_lang_path = ILIAS_ABSOLUTE_PATH . "/Customizing/global/lang";
105
106 // set lang file...
107 $txt = file($this->lang_path . "/setup_lang_sel_multi.lang");
108
109 // ...and load langdata
110 if (is_array($txt)) {
111 foreach ($txt as $row) {
112 if ($row[0] != "#") {
113 $a = explode($this->separator, trim($row));
114 $this->text[trim($a[0])] = trim($a[1]);
115 }
116 }
117 }
118
119 // set lang file...
120 $txt = file($this->lang_path . "/setup_" . $this->lang_key . ".lang");
121
122 // ...and load langdata
123 if (is_array($txt)) {
124 foreach ($txt as $row) {
125 if ($row[0] != "#") {
126 $a = explode($this->separator, trim($row));
127 $this->text[trim($a[0])] = trim($a[1]);
128 }
129 }
130
131 return true;
132 }
133
134 return false;
135 }
136
145 public function txt($a_topic)
146 {
147 global $log;
148
149 if (empty($a_topic)) {
150 return "";
151 }
152
153 $translation = $this->text[$a_topic];
154
155 //get position of the comment_separator
156 $pos = strpos($translation, $this->comment_separator);
157
158 if ($pos !== false) {
159 // remove comment
160 $translation = substr($translation, 0, $pos);
161 }
162
163 if ($translation == "") {
164 $log->writeLanguageLog($a_topic, $this->lang_key);
165 return "-" . $a_topic . "-";
166 } else {
167 return $translation;
168 }
169 }
170
178 public function getLanguages()
179 {
180 $d = dir($this->lang_path);
181 $tmpPath = getcwd();
182 chdir($this->lang_path);
183
184 // get available setup-files
185 while ($entry = $d->read()) {
186 if (is_file($entry) && (preg_match('/(^setup_.{2}\.lang$)/', $entry))) {
187 $lang_key = substr($entry, 6, 2);
189 }
190 }
191
192 chdir($tmpPath);
193
194 return $languages;
195 }
196
203 public function installLanguages($a_lang_keys, $a_local_keys)
204 {
205 global $ilDB;
206
207 if (empty($a_lang_keys)) {
208 $a_lang_keys = array();
209 }
210
211 if (empty($a_local_keys)) {
212 $a_local_keys = array();
213 }
214
215 $err_lang = array();
216
217 $db_langs = $this->getAvailableLanguages();
218
219 foreach ($a_lang_keys as $lang_key) {
220 if ($this->checkLanguage($lang_key)) {
221 $this->flushLanguage($lang_key, 'keep_local');
222 $this->insertLanguage($lang_key);
223
224 if (in_array($lang_key, $a_local_keys)) {
225 if ($this->checkLanguage($lang_key, "local")) {
226 $this->insertLanguage($lang_key, "local");
227 } else {
228 $err_lang[] = $lang_key;
229 }
230 }
231
232 // register language first time install
233 if (!array_key_exists($lang_key, $db_langs)) {
234 if (in_array($lang_key, $a_local_keys)) {
235 $itype = 'installed_local';
236 } else {
237 $itype = 'installed';
238 }
239 $lid = $ilDB->nextId("object_data");
240 $query = "INSERT INTO object_data " .
241 "(obj_id,type,title,description,owner,create_date,last_update) " .
242 "VALUES " .
243 "(" .
244 $ilDB->quote($lid, "integer") . "," .
245 $ilDB->quote("lng", "text") . "," .
246 $ilDB->quote($lang_key, "text") . "," .
247 $ilDB->quote($itype, "text") . "," .
248 $ilDB->quote('-1', "integer") . "," .
249 $ilDB->now() . "," .
250 $ilDB->now() .
251 ")";
252 $this->db->manipulate($query);
253 }
254 } else {
255 $err_lang[] = $lang_key;
256 }
257 }
258
259 foreach ($db_langs as $key => $val) {
260 if (!in_array($key, $err_lang)) {
261 if (in_array($key, $a_lang_keys)) {
262 if (in_array($key, $a_local_keys)) {
263 $ld = 'installed_local';
264 } else {
265 $ld = 'installed';
266 }
267 $query = "UPDATE object_data SET " .
268 "description = " . $ilDB->quote($ld, "text") . ", " .
269 "last_update = " . $ilDB->now() . " " .
270 "WHERE obj_id = " . $ilDB->quote($val["obj_id"], "integer") . " " .
271 "AND type = " . $ilDB->quote("lng", "text");
272 $ilDB->manipulate($query);
273 } else {
274 $this->flushLanguage($key, "all");
275
276 if (substr($val["status"], 0, 9) == "installed") {
277 $query = "UPDATE object_data SET " .
278 "description = " . $ilDB->quote("not_installed", "text") . ", " .
279 "last_update = " . $ilDB->now() . " " .
280 "WHERE obj_id = " . $ilDB->quote($val["obj_id"], "integer") . " " .
281 "AND type = " . $ilDB->quote("lng", "text");
282 $ilDB->manipulate($query);
283 }
284 }
285 }
286 }
287
288 return ($err_lang) ? $err_lang : true;
289 }
290
291
292
298 public function getInstalledLanguages()
299 {
300 global $ilDB;
301
302 $arr = array();
303
304 $query = "SELECT * FROM object_data " .
305 "WHERE type = " . $ilDB->quote("lng", "text") . " " .
306 "AND " . $ilDB->like("description", "text", 'installed%');
307 $r = $ilDB->query($query);
308
309 while ($row = $ilDB->fetchObject($r)) {
310 $arr[] = $row->title;
311 }
312
313 return $arr;
314 }
315
322 {
323 global $ilDB;
324
325 $arr = array();
326
327 $query = "SELECT * FROM object_data " .
328 "WHERE type = " . $ilDB->quote("lng", "text") . " " .
329 "AND description = " . $ilDB->quote('installed_local', "text");
330 $r = $ilDB->query($query);
331
332 while ($row = $ilDB->fetchObject($r)) {
333 $arr[] = $row->title;
334 }
335
336 return $arr;
337 }
338
343 public function getAvailableLanguages()
344 {
345 global $ilDB;
346
347 $arr = array();
348
349 $query = "SELECT * FROM object_data " .
350 "WHERE type = " . $ilDB->quote("lng", "text");
351 $r = $ilDB->query($query);
352
353 while ($row = $ilDB->fetchObject($r)) {
354 $arr[$row->title]["obj_id"] = $row->obj_id;
355 $arr[$row->title]["status"] = $row->description;
356 }
357
358 return $arr;
359 }
360
372 public function checkLanguage($a_lang_key, $scope = '')
373 {
374 if (!empty($scope)) {
375 if ($scope == 'global') {
376 $scope = '';
377 } else {
378 $scopeExtension = '.' . $scope;
379 }
380 }
381
383 if ($scope == "local") {
384 $path = $this->cust_lang_path;
385 }
386
387 $tmpPath = getcwd();
388 chdir($path);
389
390 // compute lang-file name format
391 $lang_file = "ilias_" . $a_lang_key . ".lang" . $scopeExtension;
392
393 // file check
394 if (!is_file($lang_file)) {
395 chdir($tmpPath);
396 return false;
397 }
398
399 // header check
400 if (!$content = $this->cut_header(file($lang_file))) {
401 chdir($tmpPath);
402 return false;
403 }
404
405 // check (counting) elements of each lang-entry
406 foreach ($content as $key => $val) {
407 $separated = explode($this->separator, trim($val));
408 $num = count($separated);
409
410 if ($num != 3) {
411 chdir($tmpPath);
412 return false;
413 }
414 }
415
416 chdir($tmpPath);
417
418 // no error occured
419 return true;
420 }
421
432 public function cut_header($content)
433 {
434 foreach ($content as $key => $val) {
435 if (trim($val) == "<!-- language file start -->") {
436 return array_slice($content, $key + 1);
437 }
438 }
439
440 return false;
441 }
442
443
449 public function flushLanguage($a_lang_key, $a_mode = 'all')
450 {
451 $ilDB = $this->db;
452
453 ilLanguage::_deleteLangData($a_lang_key, ($a_mode == 'keep_local'));
454
455 if ($a_mode == 'all') {
456 $ilDB->manipulate("DELETE FROM lng_modules WHERE lang_key = " .
457 $ilDB->quote($a_lang_key, "text"));
458 }
459 }
460
466 public static function _deleteLangData($a_lang_key, $a_keep_local_change)
467 {
468 global $ilDB;
469
470 if (!$a_keep_local_change) {
471 $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = " .
472 $ilDB->quote($a_lang_key, "text"));
473 } else {
474 $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = " .
475 $ilDB->quote($a_lang_key, "text") .
476 " AND local_change IS NULL");
477 }
478 }
479
487 public function getLocalChanges($a_lang_key, $a_min_date = "", $a_max_date = "")
488 {
489 $ilDB = $this->db;
490
491 if ($a_min_date == "") {
492 $a_min_date = "1980-01-01 00:00:00";
493 }
494 if ($a_max_date == "") {
495 $a_max_date = "2200-01-01 00:00:00";
496 }
497
498 $q = sprintf(
499 "SELECT * FROM lng_data WHERE lang_key = %s " .
500 "AND local_change >= %s AND local_change <= %s",
501 $ilDB->quote($a_lang_key, "text"),
502 $ilDB->quote($a_min_date, "timestamp"),
503 $ilDB->quote($a_max_date, "timestamp")
504 );
505 $result = $ilDB->query($q);
506
507 $changes = array();
508 while ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
509 $changes[$row["module"]][$row["identifier"]] = $row["value"];
510 }
511 return $changes;
512 }
513
514
515 //TODO: remove redundant checks here!
523 public function insertLanguage($lang_key, $scope = '')
524 {
525 $ilDB = &$this->db;
526
527 $lang_array = array();
528
529 if (!empty($scope)) {
530 if ($scope == 'global') {
531 $scope = '';
532 } else {
533 $scopeExtension = '.' . $scope;
534 }
535 }
536
538 if ($scope == "local") {
539 $path = $this->cust_lang_path;
540 }
541
542 $tmpPath = getcwd();
543 chdir($path);
544
545 $lang_file = "ilias_" . $lang_key . ".lang" . $scopeExtension;
546
547 if (is_file($lang_file)) {
548 // initialize the array for updating lng_modules below
549 $lang_array = array();
550 $lang_array["common"] = array();
551
552 // remove header first
553 if ($content = $this->cut_header(file($lang_file))) {
554 // get the local changes from the database
555 if (empty($scope)) {
556 $local_changes = $this->getLocalChanges($lang_key);
557 } elseif ($scope == 'local') {
558 // set the change date to import time for a local file
559 // get the modification date of the local file
560 // get the newer local changes for a local file
561 $change_date = date("Y-m-d H:i:s", time());
562 $min_date = date("Y-m-d H:i:s", filemtime($lang_file));
563 $local_changes = $this->getLocalChanges($lang_key, $min_date);
564 }
565
566 foreach ($content as $key => $val) {
567 // split the line of the language file
568 // [0]: module
569 // [1]: identifier
570 // [2]: value
571 // [3]: comment (optional)
572 $separated = explode($this->separator, trim($val));
573
574 //get position of the comment_separator
575 $pos = strpos($separated[2], $this->comment_separator);
576
577 if ($pos !== false) {
578 //cut comment of
579 $separated[2] = substr($separated[2], 0, $pos);
580 }
581
582 // check if the value has a local change
583 $local_value = $local_changes[$separated[0]][$separated[1]];
584
585 if (empty($scope)) {
586 if ($local_value != "" and $local_value != $separated[2]) {
587 // keep the locally changed value
588 $lang_array[$separated[0]][$separated[1]] = $local_value;
589 } else {
590 // insert a new value if no local value exists
591 // reset local_change if the values are equal
593 $separated[0],
594 $separated[1],
595 $lang_key,
596 $separated[2]
597 );
598
599 $lang_array[$separated[0]][$separated[1]] = $separated[2];
600 }
601 } elseif ($scope == 'local') {
602 if ($local_value != "") {
603 // keep a locally changed value that is newer than the local file
604 $lang_array[$separated[0]][$separated[1]] = $local_value;
605 } else {
606 // UPDATE because the global values have already been INSERTed
608 $separated[0],
609 $separated[1],
610 $lang_key,
611 $separated[2],
612 $change_date
613 );
614 $lang_array[$separated[0]][$separated[1]] = $separated[2];
615 }
616 }
617 }
618 }
619
620 foreach ($lang_array as $module => $lang_arr) {
621 if ($scope == "local") {
622 $q = "SELECT * FROM lng_modules WHERE " .
623 " lang_key = " . $ilDB->quote($lang_key, "text") .
624 " AND module = " . $ilDB->quote($module, "text");
625 $set = $ilDB->query($q);
626 $row = $ilDB->fetchAssoc($set);
627 $arr2 = unserialize($row["lang_array"]);
628 if (is_array($arr2)) {
629 $lang_arr = array_merge($arr2, $lang_arr);
630 }
631 }
633 }
634 }
635
636 chdir($tmpPath);
637 }
638
642 final public static function replaceLangModule($a_key, $a_module, $a_array)
643 {
644 global $ilDB;
645
646 $ilDB->manipulate(sprintf(
647 "DELETE FROM lng_modules WHERE lang_key = %s AND module = %s",
648 $ilDB->quote($a_key, "text"),
649 $ilDB->quote($a_module, "text")
650 ));
651 /*$ilDB->manipulate(sprintf("INSERT INTO lng_modules (lang_key, module, lang_array) VALUES ".
652 "(%s,%s,%s)", $ilDB->quote($a_key, "text"),
653 $ilDB->quote($a_module, "text"),
654 $ilDB->quote(serialize($a_array), "clob")));*/
655 $ilDB->insert("lng_modules", array(
656 "lang_key" => array("text", $a_key),
657 "module" => array("text", $a_module),
658 "lang_array" => array("clob", serialize($a_array))
659 ));
660 }
661
665 final public static function replaceLangEntry(
666 $a_module,
667 $a_identifier,
668 $a_lang_key,
669 $a_value,
670 $a_local_change = null
671 ) {
672 global $ilDB;
673
674 $ilDB->manipulate(sprintf(
675 "DELETE FROM lng_data WHERE module = %s AND " .
676 "identifier = %s AND lang_key = %s",
677 $ilDB->quote($a_module, "text"),
678 $ilDB->quote($a_identifier, "text"),
679 $ilDB->quote($a_lang_key, "text")
680 ));
681
682 // insert a new value if no local value exists
683 // reset local_change if the values are equal
684 $ilDB->manipulate(sprintf(
685 "INSERT INTO lng_data " .
686 "(module, identifier, lang_key, value, local_change) " .
687 "VALUES (%s,%s,%s,%s,%s)",
688 $ilDB->quote($a_module, "text"),
689 $ilDB->quote($a_identifier, "text"),
690 $ilDB->quote($a_lang_key, "text"),
691 $ilDB->quote($a_value, "text"),
692 $ilDB->quote($a_local_change, "timestamp")
693 ));
694 }
695
699 final public static function updateLangEntry(
700 $a_module,
701 $a_identifier,
702 $a_lang_key,
703 $a_value,
704 $a_local_change = null
705 ) {
706 global $ilDB;
707
708 $ilDB->manipulate(sprintf(
709 "UPDATE lng_data " .
710 "SET value = %s, local_change = %s " .
711 "WHERE module = %s AND identifier = %s AND lang_key = %s ",
712 $ilDB->quote($a_value, "text"),
713 $ilDB->quote($a_local_change, "timestamp"),
714 $ilDB->quote($a_module, "text"),
715 $ilDB->quote($a_identifier, "text"),
716 $ilDB->quote($a_lang_key, "text")
717 ));
718 }
719
725 public function getLocalLanguages()
726 {
727 $local_langs = array();
728 if (is_dir($this->cust_lang_path)) {
729 $d = dir($this->cust_lang_path);
730 $tmpPath = getcwd();
731 chdir($this->cust_lang_path);
732
733 // get available .lang.local files
734 while ($entry = $d->read()) {
735 if (is_file($entry) && (preg_match("~(^ilias_.{2}\.lang.local$)~", $entry))) {
736 $lang_key = substr($entry, 6, 2);
737 $local_langs[] = $lang_key;
738 }
739 }
740
741 chdir($tmpPath);
742 }
743
744 return $local_langs;
745 }
746
747 public function getInstallableLanguages()
748 {
749 $setup_langs = $this->getLanguages();
750
751 $d = dir($this->lang_path);
752 $tmpPath = getcwd();
753 chdir($this->lang_path);
754
755 // get available lang-files
756 while ($entry = $d->read()) {
757 if (is_file($entry) && (preg_match("~(^ilias_.{2}\.lang$)~", $entry))) {
758 $lang_key = substr($entry, 6, 2);
759 $languages1[] = $lang_key;
760 }
761 }
762
763 //$languages = array_intersect($languages1,$setup_langs);
764
765 chdir($tmpPath);
766
767 return $languages1;
768 }
769
775 public function setDbHandler($a_db_handler)
776 {
777 if (empty($a_db_handler) or !is_object($a_db_handler)) {
778 return false;
779 }
780
781 $this->db = &$a_db_handler;
782
783 return true;
784 }
785
786 public function loadLanguageModule()
787 {
788 }
789} // END class.ilLanguage
$result
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
language handling
getInstalledLocalLanguages()
get already installed local languages (in db)
static updateLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null)
Update lang entry.
getAvailableLanguages()
get already registered languages (in db)
getLocalChanges($a_lang_key, $a_min_date="", $a_max_date="")
get locally changed language entries
static _deleteLangData($a_lang_key, $a_keep_local_change)
Delete languge data.
txt($a_topic)
gets the text for a given topic
static replaceLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null)
Replace lang entry.
static replaceLangModule($a_key, $a_module, $a_array)
Replace language module array.
flushLanguage($a_lang_key, $a_mode='all')
remove language data from database
getInstalledLanguages()
get already installed languages (in db)
insertLanguage($lang_key, $scope='')
insert language data from file in database
getLanguages()
get all setup languages in the system
checkLanguage($a_lang_key, $scope='')
validate the logical structure of a lang-file
__construct($a_lang_key)
Constructor read the single-language file and put this in an array text.
cut_header($content)
Remove *.lang header information from '$content'.
setDbHandler($a_db_handler)
set db handler object @string object db handler
installLanguages($a_lang_keys, $a_local_keys)
install languages
getLocalLanguages()
Searches for the existence of *.lang.local files.
$key
Definition: croninfo.php:18
$languages
Definition: cssgen2.php:34
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
$txt
Definition: error.php:11
$r
Definition: example_031.php:79
$ld
Definition: langwiz.php:244
$row
if($modEnd===false) $module
Definition: module.php:59
$query
$log
Definition: sabredav.php:21
global $ilDB