ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjLanguage.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 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 require_once "./classes/class.ilObject.php";
25 
34 class ilObjLanguage extends ilObject
35 {
48 
49  var $key;
50  var $status;
51 
52 
60  function ilObjLanguage($a_id = 0, $a_call_by_reference = false)
61  {
62  global $lng;
63 
64  $this->type = "lng";
65  $this->ilObject($a_id,$a_call_by_reference);
66 
67  $this->type = "lng";
68  $this->key = $this->title;
69  $this->status = $this->desc;
70  $this->lang_default = $lng->lang_default;
71  $this->lang_user = $lng->lang_user;
72  $this->lang_path = $lng->lang_path;
73  $this->cust_lang_path = $lng->cust_lang_path;
74  $this->separator = $lng->separator;
75  $this->comment_separator = $lng->comment_separator;
76  }
77 
83  function getKey()
84  {
85  return $this->key;
86  }
87 
93  function getStatus()
94  {
95  return $this->status;
96  }
97 
101  function isSystemLanguage()
102  {
103  if ($this->key == $this->lang_default)
104  return true;
105  else
106  return false;
107  }
108 
112  function isUserLanguage()
113  {
114  if ($this->key == $this->lang_user)
115  {
116  return true;
117  }
118  else
119  {
120  return false;
121  }
122  }
123 
124 
130  function isInstalled()
131  {
132  if (substr($this->getStatus(), 0, 9) == "installed")
133  {
134  return true;
135  }
136  else
137  {
138  return false;
139  }
140  }
141 
148  function isLocal()
149  {
150  if (substr($this->getStatus(), 10) == "local")
151  {
152  return true;
153  }
154  else
155  {
156  return false;
157  }
158  }
159 
166  function install($scope = '')
167  {
168  if (!empty($scope))
169  {
170  if ($scope == 'global')
171  {
172  $scope = '';
173  }
174  else
175  {
176  $scopeExtension = '.' . $scope;
177  }
178  }
179 
180  if (($this->isInstalled() == false) ||
181  ($this->isInstalled() == true && $this->isLocal() == false && !empty($scope)))
182  {
183  if ($this->check($scope))
184  {
185  // lang-file is ok. Flush data in db and...
186  if (empty($scope))
187  {
188  $this->flush('keep_local');
189  }
190 
191  // ...re-insert data from lang-file
192  $this->insert($scope);
193 
194  // update information in db-table about available/installed languages
195  if (empty($scope))
196  {
197  $newDesc = 'installed';
198  }
199  else if ($scope == 'local')
200  {
201  $newDesc = 'installed_local';
202  }
203  $this->setDescription($newDesc);
204  $this->update();
205  $this->optimizeData();
206  return $this->getKey();
207  }
208  }
209  return "";
210  }
211 
212 
218  function uninstall()
219  {
220  if ((substr($this->status, 0, 9) == "installed") && ($this->key != $this->lang_default) && ($this->key != $this->lang_user))
221  {
222  $this->flush('all');
223  $this->setTitle($this->key);
224  $this->setDescription("not_installed");
225  $this->update();
226  $this->resetUserLanguage($this->key);
227 
228  return $this->key;
229  }
230  return "";
231  }
232 
233 
238  function flush($a_mode = 'all')
239  {
240  global $ilDB;
241 
242  $query = "DELETE FROM lng_data WHERE lang_key=".
243  $ilDB->quote($this->key);
244 
245  if ($a_mode == 'keep_local')
246  {
247  $query .= " AND local_change='0000-00-00 00:00:00'";
248  }
249  $ilDB->query($query);
250 
251  if ($a_mode == 'all')
252  {
253  $query = "DELETE FROM lng_modules WHERE lang_key=".
254  $ilDB->quote($this->key);
255  $ilDB->query($query);
256  }
257  }
258 
259 
266  function getLocalChanges($a_min_date = "", $a_max_date = "")
267  {
268  global $ilDB;
269 
270  $query = "SELECT * FROM lng_data WHERE"
271  ." lang_key =".$ilDB->quote($this->key);
272  if ($a_min_date <> "")
273  {
274  $query .= " and local_change >= ".$ilDB->quote($a_min_date);
275  }
276  if ($a_max_date <> "")
277  {
278  $query .= " and local_change <= ".$ilDB->quote($a_max_date);
279  }
280  $result = $ilDB->query($query);
281 
282  $changes = array();
283  while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
284  {
285  $changes[$row["module"]][$row["identifier"]] = $row["value"];
286  }
287  return $changes;
288  }
289 
290 
296  function insert($scope = '')
297  {
298  global $ilDB;
299 
300  if (!empty($scope))
301  {
302  if ($scope == 'global')
303  {
304  $scope = '';
305  }
306  else
307  {
308  $scopeExtension = '.' . $scope;
309  }
310  }
311 
312  $path = $this->lang_path;
313  if ($scope == "local")
314  {
315  $path = $this->cust_lang_path;
316  }
317 
318  $tmpPath = getcwd();
319  chdir($path);
320 
321  $lang_file = "ilias_" . $this->key . ".lang" . $scopeExtension;
322 
323  if ($lang_file)
324  {
325  // initialize the array for updating lng_modules below
326  $lang_array = array();
327  $lang_array["common"] = array();
328 
329  // remove header first
330  if ($content = $this->cut_header(file($lang_file)))
331  {
332  // get the local changes from the database
333  if (empty($scope))
334  {
335  $local_changes = $this->getLocalChanges();
336  }
337  else if ($scope == 'local')
338  {
339  $change_date = date("Y-m-d H:i:s",time());
340  $min_date = date("Y-m-d H:i:s", filemtime($lang_file));
341  $local_changes = $this->getLocalChanges($min_date);
342  }
343 
344  foreach ($content as $key => $val)
345  {
346  $separated = explode($this->separator,trim($val));
347 
348  //get position of the comment_separator
349  $pos = strpos($separated[2], $this->comment_separator);
350 
351  if ($pos !== false)
352  {
353  //cut comment of
354  $separated[2] = substr($separated[2] , 0 , $pos);
355  }
356 
357  // check if the value has a local change
358  $local_value = $local_changes[$separated[0]][$separated[1]];
359 
360  if (empty($scope))
361  {
362  if ($local_value != "" and $local_value != $separated[2])
363  {
364  // keep the locally changed value
365  $lang_array[$separated[0]][$separated[1]] = $local_value;
366  }
367  else
368  {
369  if ($double_checker[$separated[0]][$separated[1]][$this->key])
370  {
371  $this->ilias->raiseError("Duplicate Language Entry: ".
372  $separated[0]."-".$separated[1]."-".$this->key,
373  $this->ilias->error_obj->MESSAGE);
374  }
375 
376  $double_checker[$separated[0]][$separated[1]][$this->key] = true;
377 
378  // insert a new value if no local value exists
379  // reset local_change if the values are equal
380  $query = "REPLACE INTO lng_data " .
381  "(module, identifier, lang_key, value, local_change) " .
382  "VALUES " .
383  "(".$ilDB->quote($separated[0]).",".
384  $ilDB->quote($separated[1]).",".
385  $ilDB->quote($this->key).",".
386  $ilDB->quote($separated[2]).",".
387  $ilDB->quote("0000-00-00 00:00:00").")";
388  $ilDB->query($query);
389  $lang_array[$separated[0]][$separated[1]] = $separated[2];
390  }
391  }
392  else if ($scope == 'local')
393  {
394  if ($local_value != "")
395  {
396  // keep a locally changed value that is newer than the local file
397  $lang_array[$separated[0]][$separated[1]] = $local_value;
398  }
399  else
400  {
401  // UPDATE because the global values have already been INSERTed
402  $query = "UPDATE lng_data SET ".
403  "value = ".$ilDB->quote($separated[2]).", " .
404  "local_change = ".$ilDB->quote($change_date)." " .
405  "WHERE module = ".$ilDB->quote($separated[0])." " .
406  "AND identifier = ".$ilDB->quote($separated[1])." " .
407  "AND lang_key = ".$ilDB->quote($this->key);
408  $ilDB->query($query);
409  $lang_array[$separated[0]][$separated[1]] = $separated[2];
410  }
411  }
412  }
413 
414  if (empty($scope))
415  {
416  $query = "UPDATE object_data SET " .
417  "description = 'installed', " .
418  "last_update = now() " .
419  "WHERE title = ".$ilDB->quote($this->key)." " .
420  "AND type = 'lng'";
421  $ilDB->query($query);
422  }
423  else if ($scope == 'local')
424  {
425  $query = "UPDATE object_data SET " .
426  "description = 'installed_local', " .
427  "last_update = now() " .
428  "WHERE title = ".$ilDB->quote($this->key)." " .
429  "AND type = 'lng'";
430  $ilDB->query($query);
431  }
432  }
433 
434  foreach($lang_array as $module => $lang_arr)
435  {
436  if ($scope == "local")
437  {
438  $q = "SELECT * FROM lng_modules WHERE ".
439  " lang_key = ".$ilDB->quote($this->key).
440  " AND module = ".$ilDB->quote($module);
441  $set = $ilDB->query($q);
442  $row = $set->fetchRow(DB_FETCHMODE_ASSOC);
443  $arr2 = unserialize($row["lang_array"]);
444  if (is_array($arr2))
445  {
446  $lang_arr = array_merge($arr2, $lang_arr);
447  }
448  }
449  $query = "REPLACE INTO lng_modules (lang_key, module, lang_array) VALUES ".
450  "(".$ilDB->quote($this->key).", " .
451  " ".$ilDB->quote($module).", " .
452  " ".$ilDB->quote(serialize($lang_arr)).") ";
453  $ilDB->query($query);
454  }
455  }
456 
457  chdir($tmpPath);
458  }
459 
463  static final function replaceLangModule($a_key, $a_module, $a_array)
464  {
465  global $ilDB;
466 
467  $query = "REPLACE INTO lng_modules (lang_key, module, lang_array) VALUES ".
468  "(".$ilDB->quote($a_key).", " .
469  " ".$ilDB->quote($a_module).", " .
470  " ".$ilDB->quote(serialize($a_array)).") ";
471  $ilDB->query($query);
472  }
473 
480  function resetUserLanguage($lang_key)
481  {
482  global $ilDB;
483 
484  $query = "UPDATE usr_pref SET " .
485  "value = ".$ilDB->quote($this->lang_default)." " .
486  "WHERE keyword = 'language' " .
487  "AND value = ".$ilDB->quote($lang_key);
488  $this->ilias->db->query($query);
489  }
490 
499  function cut_header($content)
500  {
501  foreach ($content as $key => $val)
502  {
503  if (trim($val) == "<!-- language file start -->")
504  {
505  return array_slice($content,$key +1);
506  }
507  }
508 
509  return false;
510  }
511 
517  function optimizeData()
518  {
519  // optimize
520  $query = "OPTIMIZE TABLE lng_data";
521  $this->ilias->db->query($query);
522 
523  return true;
524  }
525 
535  function check($scope = '')
536  {
537  if (!empty($scope))
538  {
539  if ($scope == 'global')
540  {
541  $scope = '';
542  }
543  else
544  {
545  $scopeExtension = '.' . $scope;
546  }
547  }
548 
549  $path = $this->lang_path;
550  if ($scope == "local")
551  {
552  $path = $this->cust_lang_path;
553  }
554 
555  $tmpPath = getcwd();
556 
557  // dir check
558  if (!is_dir($path))
559  {
560  $this->ilias->raiseError("Directory not found: ".$path, $this->ilias->error_obj->MESSAGE);
561  }
562 
563  chdir($path);
564 
565  // compute lang-file name format
566  $lang_file = "ilias_" . $this->key . ".lang" . $scopeExtension;
567 
568  // file check
569  if (!is_file($lang_file))
570  {
571  $this->ilias->raiseError("File not found: ".$lang_file,$this->ilias->error_obj->MESSAGE);
572  }
573 
574  // header check
575  if (!$content = $this->cut_header(file($lang_file)))
576  {
577  $this->ilias->raiseError("Wrong Header in ".$lang_file,$this->ilias->error_obj->MESSAGE);
578  }
579 
580  // check (counting) elements of each lang-entry
581  $line = 0;
582  foreach ($content as $key => $val)
583  {
584  $separated = explode($this->separator, trim($val));
585  $num = count($separated);
586  ++$n;
587  if ($num != 3)
588  {
589  $line = $n + 36;
590  $this->ilias->raiseError("Wrong parameter count in ".$lang_file." in line $line (Value: $val)! Please check your language file!",$this->ilias->error_obj->MESSAGE);
591  }
592  }
593 
594  chdir($tmpPath);
595 
596  // no error occured
597  return true;
598  }
599 } // END class.LanguageObject
600 ?>