ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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  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);
188  $languages[] = $lang_key;
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 
321  public function getInstalledLocalLanguages()
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 ($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  $change_date = date("Y-m-d H:i:s", time());
559  $min_date = date("Y-m-d H:i:s", filemtime($lang_file));
560  $local_changes = $this->getLocalChanges($lang_key, $min_date);
561  }
562 
563  foreach ($content as $key => $val) {
564  $separated = explode($this->separator, trim($val));
565 
566  //get position of the comment_separator
567  $pos = strpos($separated[2], $this->comment_separator);
568 
569  if ($pos !== false) {
570  //cut comment of
571  $separated[2] = substr($separated[2], 0, $pos);
572  }
573 
574  // check if the value has a local change
575  $local_value = $local_changes[$separated[0]][$separated[1]];
576 
577  if (empty($scope)) {
578  if ($local_value != "" and $local_value != $separated[2]) {
579  // keep the locally changed value
580  $lang_array[$separated[0]][$separated[1]] = $local_value;
581  } else {
582  // insert a new value if no local value exists
583  // reset local_change if the values are equal
585  $separated[0],
586  $separated[1],
587  $lang_key,
588  $separated[2]
589  );
590 
591  $lang_array[$separated[0]][$separated[1]] = $separated[2];
592  }
593  } elseif ($scope == 'local') {
594  if ($local_value != "") {
595  // keep a locally changed value that is newer than the local file
596  $lang_array[$separated[0]][$separated[1]] = $local_value;
597  } else {
598  // UPDATE because the global values have already been INSERTed
600  $separated[0],
601  $separated[1],
602  $lang_key,
603  $separated[2],
604  $change_date
605  );
606  $lang_array[$separated[0]][$separated[1]] = $separated[2];
607  }
608  }
609  }
610  }
611 
612  foreach ($lang_array as $module => $lang_arr) {
613  if ($scope == "local") {
614  $q = "SELECT * FROM lng_modules WHERE " .
615  " lang_key = " . $ilDB->quote($this->key, "text") .
616  " AND module = " . $ilDB->quote($module, "text");
617  $set = $ilDB->query($q);
618  $row = $ilDB->fetchAssoc($set);
619  $arr2 = unserialize($row["lang_array"]);
620  if (is_array($arr2)) {
621  $lang_arr = array_merge($arr2, $lang_arr);
622  }
623  }
625  }
626  }
627 
628  chdir($tmpPath);
629  }
630 
634  final public static function replaceLangModule($a_key, $a_module, $a_array)
635  {
636  global $ilDB;
637 
638  $ilDB->manipulate(sprintf(
639  "DELETE FROM lng_modules WHERE lang_key = %s AND module = %s",
640  $ilDB->quote($a_key, "text"),
641  $ilDB->quote($a_module, "text")
642  ));
643  /*$ilDB->manipulate(sprintf("INSERT INTO lng_modules (lang_key, module, lang_array) VALUES ".
644  "(%s,%s,%s)", $ilDB->quote($a_key, "text"),
645  $ilDB->quote($a_module, "text"),
646  $ilDB->quote(serialize($a_array), "clob")));*/
647  $ilDB->insert("lng_modules", array(
648  "lang_key" => array("text", $a_key),
649  "module" => array("text", $a_module),
650  "lang_array" => array("clob", serialize($a_array))
651  ));
652  }
653 
657  final public static function replaceLangEntry(
658  $a_module,
659  $a_identifier,
660  $a_lang_key,
661  $a_value,
662  $a_local_change = null
663  ) {
664  global $ilDB;
665 
666  $ilDB->manipulate(sprintf(
667  "DELETE FROM lng_data WHERE module = %s AND " .
668  "identifier = %s AND lang_key = %s",
669  $ilDB->quote($a_module, "text"),
670  $ilDB->quote($a_identifier, "text"),
671  $ilDB->quote($a_lang_key, "text")
672  ));
673 
674  // insert a new value if no local value exists
675  // reset local_change if the values are equal
676  $ilDB->manipulate(sprintf(
677  "INSERT INTO lng_data " .
678  "(module, identifier, lang_key, value, local_change) " .
679  "VALUES (%s,%s,%s,%s,%s)",
680  $ilDB->quote($a_module, "text"),
681  $ilDB->quote($a_identifier, "text"),
682  $ilDB->quote($a_lang_key, "text"),
683  $ilDB->quote($a_value, "text"),
684  $ilDB->quote($a_local_change, "timestamp")
685  ));
686  }
687 
691  final public static function updateLangEntry(
692  $a_module,
693  $a_identifier,
694  $a_lang_key,
695  $a_value,
696  $a_local_change = null
697  ) {
698  global $ilDB;
699 
700  $ilDB->manipulate(sprintf(
701  "UPDATE lng_data " .
702  "SET value = %s, local_change = %s " .
703  "WHERE module = %s AND identifier = %s AND lang_key = %s ",
704  $ilDB->quote($a_value, "text"),
705  $ilDB->quote($a_local_change, "timestamp"),
706  $ilDB->quote($a_module, "text"),
707  $ilDB->quote($a_identifier, "text"),
708  $ilDB->quote($a_lang_key, "text")
709  ));
710  }
711 
717  public function getLocalLanguages()
718  {
719  $local_langs = array();
720  if (is_dir($this->cust_lang_path)) {
721  $d = dir($this->cust_lang_path);
722  $tmpPath = getcwd();
723  chdir($this->cust_lang_path);
724 
725  // get available .lang.local files
726  while ($entry = $d->read()) {
727  if (is_file($entry) && (preg_match("~(^ilias_.{2}\.lang.local$)~", $entry))) {
728  $lang_key = substr($entry, 6, 2);
729  $local_langs[] = $lang_key;
730  }
731  }
732 
733  chdir($tmpPath);
734  }
735 
736  return $local_langs;
737  }
738 
739  public function getInstallableLanguages()
740  {
741  $setup_langs = $this->getLanguages();
742 
743  $d = dir($this->lang_path);
744  $tmpPath = getcwd();
745  chdir($this->lang_path);
746 
747  // get available lang-files
748  while ($entry = $d->read()) {
749  if (is_file($entry) && (preg_match("~(^ilias_.{2}\.lang$)~", $entry))) {
750  $lang_key = substr($entry, 6, 2);
751  $languages1[] = $lang_key;
752  }
753  }
754 
755  //$languages = array_intersect($languages1,$setup_langs);
756 
757  chdir($tmpPath);
758 
759  return $languages1;
760  }
761 
767  public function setDbHandler($a_db_handler)
768  {
769  if (empty($a_db_handler) or !is_object($a_db_handler)) {
770  return false;
771  }
772 
773  $this->db =&$a_db_handler;
774 
775  return true;
776  }
777 
778  public function loadLanguageModule()
779  {
780  }
781 } // END class.ilLanguage
static replaceLangModule($a_key, $a_module, $a_array)
Replace language module array.
getAvailableLanguages()
get already registered languages (in db)
$result
txt($a_topic)
gets the text for a given topic
static _deleteLangData($a_lang_key, $a_keep_local_change)
Delete languge data.
installLanguages($a_lang_keys, $a_local_keys)
install languages
checkLanguage($a_lang_key, $scope='')
validate the logical structure of a lang-file
getInstalledLocalLanguages()
get already installed local languages (in db)
if($modEnd===false) $module
Definition: module.php:59
cut_header($content)
Remove *.lang header information from &#39;$content&#39;.
getLocalChanges($a_lang_key, $a_min_date="", $a_max_date="")
get locally changed language entries
$r
Definition: example_031.php:79
static replaceLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null)
Replace lang entry.
flushLanguage($a_lang_key, $a_mode='all')
remove language data from database
getLanguages()
get all setup languages in the system
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
__construct($a_lang_key)
Constructor read the single-language file and put this in an array text.
Reload workbook from saved file
setDbHandler($a_db_handler)
set db handler object object db handler
$query
getInstalledLanguages()
get already installed languages (in db)
$txt
Definition: error.php:11
getLocalLanguages()
Searches for the existence of *.lang.local files.
Create styles array
The data for the language used.
insertLanguage($lang_key, $scope='')
insert language data from file in database
global $ilDB
language handling
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
static updateLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null)
Update lang entry.
$key
Definition: croninfo.php:18
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296