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