ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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 var $text = array();
52
59 var $lang_default = "en";
60
68 var $lang_path;
69
75 var $lang_key;
76
82 var $separator = "#:#";
83
89 var $comment_separator = "###";
90
100 function ilLanguage($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 {
112 foreach ($txt as $row)
113 {
114 if ($row[0] != "#")
115 {
116 $a = explode($this->separator,trim($row));
117 $this->text[trim($a[0])] = trim($a[1]);
118 }
119 }
120 }
121
122 // set lang file...
123 $txt = file($this->lang_path."/setup_".$this->lang_key.".lang");
124
125 // ...and load langdata
126 if (is_array($txt))
127 {
128 foreach ($txt as $row)
129 {
130 if ($row[0] != "#")
131 {
132 $a = explode($this->separator,trim($row));
133 $this->text[trim($a[0])] = trim($a[1]);
134 }
135 }
136
137 return true;
138 }
139
140 return false;
141 }
142
151 function txt($a_topic)
152 {
153 global $log;
154
155 if (empty($a_topic))
156 {
157 return "";
158 }
159
160 $translation = $this->text[$a_topic];
161
162 //get position of the comment_separator
163 $pos = strpos($translation, $this->comment_separator);
164
165 if ($pos !== false)
166 {
167 // remove comment
168 $translation = substr($translation,0,$pos);
169 }
170
171 if ($translation == "")
172 {
173 $log->writeLanguageLog($a_topic,$this->lang_key);
174 return "-".$a_topic."-";
175 }
176 else
177 {
178 return $translation;
179 }
180 }
181
189 function getLanguages()
190 {
191 $d = dir($this->lang_path);
192 $tmpPath = getcwd();
193 chdir ($this->lang_path);
194
195 // get available setup-files
196 while ($entry = $d->read())
197 {
198 if (is_file($entry) && (ereg ("(^setup_.{2}\.lang$)", $entry)))
199 {
200 $lang_key = substr($entry,6,2);
201 $languages[] = $lang_key;
202 }
203 }
204
205 chdir($tmpPath);
206
207 return $languages;
208 }
209
216 function installLanguages($a_lang_keys, $a_local_keys)
217 {
218 global $ilDB;
219
220 if (empty($a_lang_keys))
221 {
222 $a_lang_keys = array();
223 }
224
225 if (empty($a_local_keys))
226 {
227 $a_local_keys = array();
228 }
229
230 $err_lang = array();
231
232 $db_langs = $this->getAvailableLanguages();
233
234 foreach ($a_lang_keys as $lang_key)
235 {
236 if ($this->checkLanguage($lang_key))
237 {
238 $this->flushLanguage($lang_key, 'keep_local');
239 $this->insertLanguage($lang_key);
240
241 if (in_array($lang_key, $a_local_keys))
242 {
243 if ($this->checkLanguage($lang_key, "local"))
244 {
245 $this->insertLanguage($lang_key, "local");
246 }
247 else
248 {
249 $err_lang[] = $lang_key;
250 }
251 }
252
253 // register language first time install
254 if (!array_key_exists($lang_key,$db_langs))
255 {
256 if (in_array($lang_key, $a_local_keys))
257 {
258 $itype = 'installed_local';
259 }
260 else
261 {
262 $itype = 'installed';
263 }
264 $lid = $ilDB->nextId("object_data");
265 $query = "INSERT INTO object_data ".
266 "(obj_id,type,title,description,owner,create_date,last_update) ".
267 "VALUES ".
268 "(".
269 $ilDB->quote($lid, "integer").",".
270 $ilDB->quote("lng", "text").",".
271 $ilDB->quote($lang_key, "text").",".
272 $ilDB->quote($itype, "text").",".
273 $ilDB->quote('-1',"integer").",".
274 $ilDB->now().",".
275 $ilDB->now().
276 ")";
277 $this->db->manipulate($query);
278 }
279 }
280 else
281 {
282 $err_lang[] = $lang_key;
283 }
284 }
285
286 foreach ($db_langs as $key => $val)
287 {
288 if (!in_array($key,$err_lang))
289 {
290 if (in_array($key,$a_lang_keys))
291 {
292 if (in_array($key, $a_local_keys))
293 {
294 $ld = 'installed_local';
295 }
296 else
297 {
298 $ld = 'installed';
299 }
300 $query = "UPDATE object_data SET " .
301 "description = ".$ilDB->quote($ld, "text").", " .
302 "last_update = ".$ilDB->now()." " .
303 "WHERE obj_id = ".$ilDB->quote($val["obj_id"], "integer")." " .
304 "AND type = ".$ilDB->quote("lng", "text");
305 $ilDB->manipulate($query);
306 }
307 else
308 {
309 $this->flushLanguage($key, "all");
310
311 if (substr($val["status"], 0, 9) == "installed")
312 {
313 $query = "UPDATE object_data SET " .
314 "description = ".$ilDB->quote("not_installed", "text").", " .
315 "last_update = ".$ilDB->now()." " .
316 "WHERE obj_id = ".$ilDB->quote($val["obj_id"], "integer")." " .
317 "AND type = ".$ilDB->quote("lng", "text");
318 $ilDB->manipulate($query);
319 }
320 }
321 }
322 }
323
324 return ($err_lang) ? $err_lang : true;
325 }
326
327
328
335 {
336 global $ilDB;
337
338 $arr = array();
339
340 $query = "SELECT * FROM object_data ".
341 "WHERE type = ".$ilDB->quote("lng", "text")." ".
342 "AND ".$ilDB->like("description", "text", 'installed%');
343 $r = $ilDB->query($query);
344
345 while ($row = $ilDB->fetchObject($r))
346 {
347 $arr[] = $row->title;
348 }
349
350 return $arr;
351 }
352
359 {
360 global $ilDB;
361
362 $arr = array();
363
364 $query = "SELECT * FROM object_data ".
365 "WHERE type = ".$ilDB->quote("lng", "text")." ".
366 "AND description = ".$ilDB->quote('installed_local', "text");
367 $r = $ilDB->query($query);
368
369 while ($row = $ilDB->fetchObject($r))
370 {
371 $arr[] = $row->title;
372 }
373
374 return $arr;
375 }
376
382 {
383 global $ilDB;
384
385 $arr = array();
386
387 $query = "SELECT * FROM object_data ".
388 "WHERE type = ".$ilDB->quote("lng", "text");
389 $r = $ilDB->query($query);
390
391 while ($row = $ilDB->fetchObject($r))
392 {
393 $arr[$row->title]["obj_id"] = $row->obj_id;
394 $arr[$row->title]["status"] = $row->description;
395 }
396
397 return $arr;
398 }
399
411 function checkLanguage($a_lang_key, $scope = '')
412 {
413 if (!empty($scope))
414 {
415 if ($scope == 'global')
416 {
417 $scope = '';
418 }
419 else
420 {
421 $scopeExtension = '.' . $scope;
422 }
423 }
424
426 if ($scope == "local")
427 {
428 $path = $this->cust_lang_path;
429 }
430
431 $tmpPath = getcwd();
432 chdir($path);
433
434 // compute lang-file name format
435 $lang_file = "ilias_" . $a_lang_key . ".lang" . $scopeExtension;
436
437 // file check
438 if (!is_file($lang_file))
439 {
440 chdir($tmpPath);
441 return false;
442 }
443
444 // header check
445 if (!$content = $this->cut_header(file($lang_file)))
446 {
447 chdir($tmpPath);
448 return false;
449 }
450
451 // check (counting) elements of each lang-entry
452 foreach ($content as $key => $val)
453 {
454 $separated = explode($this->separator, trim($val));
455 $num = count($separated);
456
457 if ($num != 3)
458 {
459 chdir($tmpPath);
460 return false;
461 }
462 }
463
464 chdir($tmpPath);
465
466 // no error occured
467 return true;
468 }
469
480 function cut_header($content)
481 {
482 foreach ($content as $key => $val)
483 {
484 if (trim($val) == "<!-- language file start -->")
485 {
486 return array_slice($content,$key +1);
487 }
488 }
489
490 return false;
491 }
492
493
499 function flushLanguage($a_lang_key, $a_mode = 'all')
500 {
501 $ilDB = $this->db;
502
503 ilLanguage::_deleteLangData($a_lang_key, ($a_mode == 'keep_local'));
504
505 if ($a_mode == 'all')
506 {
507 $ilDB->manipulate("DELETE FROM lng_modules WHERE lang_key = ".
508 $ilDB->quote($a_lang_key, "text"));
509 }
510 }
511
517 static function _deleteLangData($a_lang_key, $a_keep_local_change)
518 {
519 global $ilDB;
520
521 if (!$a_keep_local_change)
522 {
523 $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = ".
524 $ilDB->quote($a_lang_key, "text"));
525 }
526 else
527 {
528 $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = ".
529 $ilDB->quote($a_lang_key, "text").
530 " AND local_change IS NULL");
531 }
532 }
533
541 function getLocalChanges($a_lang_key, $a_min_date = "", $a_max_date = "")
542 {
543 $ilDB = $this->db;
544
545 if ($a_min_date == "")
546 {
547 $a_min_date = "1980-01-01 00:00:00";
548 }
549 if ($a_max_date == "")
550 {
551 $a_max_date = "2200-01-01 00:00:00";
552 }
553
554 $q = sprintf("SELECT * FROM lng_data WHERE lang_key = %s ".
555 "AND local_change >= %s AND local_change <= %s",
556 $ilDB->quote($a_lang_key, "text"), $ilDB->quote($a_min_date, "timestamp"),
557 $ilDB->quote($a_max_date, "timestamp"));
558 $result = $ilDB->query($q);
559
560 $changes = array();
561 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
562 {
563 $changes[$row["module"]][$row["identifier"]] = $row["value"];
564 }
565 return $changes;
566 }
567
568
569 //TODO: remove redundant checks here!
577 function insertLanguage($lang_key, $scope = '')
578 {
579 $ilDB =& $this->db;
580
581 $lang_array = array();
582
583 if (!empty($scope))
584 {
585 if ($scope == 'global')
586 {
587 $scope = '';
588 }
589 else
590 {
591 $scopeExtension = '.' . $scope;
592 }
593 }
594
596 if ($scope == "local")
597 {
598 $path = $this->cust_lang_path;
599 }
600
601 $tmpPath = getcwd();
602 chdir($path);
603
604 $lang_file = "ilias_" . $lang_key . ".lang" . $scopeExtension;
605
606 if ($lang_file)
607 {
608 // initialize the array for updating lng_modules below
609 $lang_array = array();
610 $lang_array["common"] = array();
611
612 // remove header first
613 if ($content = $this->cut_header(file($lang_file)))
614 {
615 // get the local changes from the database
616 if (empty($scope))
617 {
618 $local_changes = $this->getLocalChanges($lang_key);
619 }
620 else if ($scope == 'local')
621 {
622 $change_date = date("Y-m-d H:i:s",time());
623 $min_date = date("Y-m-d H:i:s", filemtime($lang_file));
624 $local_changes = $this->getLocalChanges($lang_key, $min_date);
625 }
626
627 foreach ($content as $key => $val)
628 {
629 $separated = explode($this->separator,trim($val));
630
631 //get position of the comment_separator
632 $pos = strpos($separated[2], $this->comment_separator);
633
634 if ($pos !== false)
635 {
636 //cut comment of
637 $separated[2] = substr($separated[2] , 0 , $pos);
638 }
639
640 // check if the value has a local change
641 $local_value = $local_changes[$separated[0]][$separated[1]];
642
643 if (empty($scope))
644 {
645 if ($local_value != "" and $local_value != $separated[2])
646 {
647 // keep the locally changed value
648 $lang_array[$separated[0]][$separated[1]] = $local_value;
649 }
650 else
651 {
652 // insert a new value if no local value exists
653 // reset local_change if the values are equal
654 ilLanguage::replaceLangEntry($separated[0], $separated[1],
655 $lang_key, $separated[2]);
656
657 $lang_array[$separated[0]][$separated[1]] = $separated[2];
658 }
659 }
660 else if ($scope == 'local')
661 {
662 if ($local_value != "")
663 {
664 // keep a locally changed value that is newer than the local file
665 $lang_array[$separated[0]][$separated[1]] = $local_value;
666 }
667 else
668 {
669 // UPDATE because the global values have already been INSERTed
670 ilLanguage::updateLangEntry($separated[0], $separated[1],
671 $lang_key, $separated[2], $change_date);
672 $lang_array[$separated[0]][$separated[1]] = $separated[2];
673 }
674 }
675 }
676 }
677
678 foreach($lang_array as $module => $lang_arr)
679 {
680 if ($scope == "local")
681 {
682 $q = "SELECT * FROM lng_modules WHERE ".
683 " lang_key = ".$ilDB->quote($this->key, "text").
684 " AND module = ".$ilDB->quote($module, "text");
685 $set = $ilDB->query($q);
686 $row = $ilDB->fetchAssoc($set);
687 $arr2 = unserialize($row["lang_array"]);
688 if (is_array($arr2))
689 {
690 $lang_arr = array_merge($arr2, $lang_arr);
691 }
692 }
693 ilLanguage::replaceLangModule($lang_key, $module, $lang_arr);
694 }
695 }
696
697 chdir($tmpPath);
698 }
699
703 static final function replaceLangModule($a_key, $a_module, $a_array)
704 {
705 global $ilDB;
706
707 $ilDB->manipulate(sprintf("DELETE FROM lng_modules WHERE lang_key = %s AND module = %s",
708 $ilDB->quote($a_key, "text"), $ilDB->quote($a_module, "text")));
709 /*$ilDB->manipulate(sprintf("INSERT INTO lng_modules (lang_key, module, lang_array) VALUES ".
710 "(%s,%s,%s)", $ilDB->quote($a_key, "text"),
711 $ilDB->quote($a_module, "text"),
712 $ilDB->quote(serialize($a_array), "clob")));*/
713 $ilDB->insert("lng_modules", array(
714 "lang_key" => array("text", $a_key),
715 "module" => array("text", $a_module),
716 "lang_array" => array("clob", serialize($a_array))
717 ));
718 }
719
723 static final function replaceLangEntry($a_module, $a_identifier,
724 $a_lang_key, $a_value, $a_local_change = null)
725 {
726 global $ilDB;
727
728 $ilDB->manipulate(sprintf("DELETE FROM lng_data WHERE module = %s AND ".
729 "identifier = %s AND lang_key = %s",
730 $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
731 $ilDB->quote($a_lang_key, "text")));
732
733 // insert a new value if no local value exists
734 // reset local_change if the values are equal
735 $ilDB->manipulate(sprintf("INSERT INTO lng_data " .
736 "(module, identifier, lang_key, value, local_change) " .
737 "VALUES (%s,%s,%s,%s,%s)",
738 $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
739 $ilDB->quote($a_lang_key, "text"), $ilDB->quote($a_value, "text"),
740 $ilDB->quote($a_local_change, "timestamp")));
741 }
742
746 static final function updateLangEntry($a_module, $a_identifier,
747 $a_lang_key, $a_value, $a_local_change = null)
748 {
749 global $ilDB;
750
751 $ilDB->manipulate(sprintf("UPDATE lng_data " .
752 "SET value = %s, local_change = %s ".
753 "WHERE module = %s AND identifier = %s AND lang_key = %s ",
754 $ilDB->quote($a_value, "text"), $ilDB->quote($a_local_change, "timestamp"),
755 $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
756 $ilDB->quote($a_lang_key, "text")));
757 }
758
765 {
766 $local_langs = array();
767 if (is_dir($this->cust_lang_path))
768 {
769 $d = dir($this->cust_lang_path);
770 $tmpPath = getcwd();
771 chdir ($this->cust_lang_path);
772
773 // get available .lang.local files
774 while ($entry = $d->read())
775 {
776 if (is_file($entry) && (ereg ("(^ilias_.{2}\.lang.local$)", $entry)))
777 {
778 $lang_key = substr($entry,6,2);
779 $local_langs[] = $lang_key;
780 }
781 }
782
783 chdir($tmpPath);
784 }
785
786 return $local_langs;
787 }
788
790 {
791 $setup_langs = $this->getLanguages();
792
793 $d = dir($this->lang_path);
794 $tmpPath = getcwd();
795 chdir ($this->lang_path);
796
797 // get available lang-files
798 while ($entry = $d->read())
799 {
800 if (is_file($entry) && (ereg ("(^ilias_.{2}\.lang$)", $entry)))
801 {
802 $lang_key = substr($entry,6,2);
803 $languages1[] = $lang_key;
804 }
805 }
806
807 //$languages = array_intersect($languages1,$setup_langs);
808
809 chdir($tmpPath);
810
811 return $languages1;
812 }
813
819 function setDbHandler($a_db_handler)
820 {
821 if (empty($a_db_handler) or !is_object($a_db_handler))
822 {
823 return false;
824 }
825
826 $this->db =& $a_db_handler;
827
828 return true;
829 }
830
832 {
833 }
834} // END class.ilLanguage
835?>
$result
const DB_FETCHMODE_ASSOC
Definition: class.ilDB.php:10
language handling
ilLanguage($a_lang_key)
Constructor read the single-language file and put this in an array text.
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 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
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.
static replaceLangEntry($a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null)
Replace lang entry.
$txt
Definition: error.php:12
$r
Definition: example_031.php:79
$path
Definition: index.php:22
global $ilDB
const ILIAS_ABSOLUTE_PATH