ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilObjLanguage.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once "./Services/Object/classes/class.ilObject.php";
5 
14 class ilObjLanguage extends ilObject
15 {
23  public $separator;
25  public $lang_default;
26  public $lang_user;
27  public $lang_path;
28 
29  public $key;
30  public $status;
31 
32 
40  public function __construct($a_id = 0, $a_call_by_reference = false)
41  {
42  global $DIC;
43  $lng = $DIC->language();
44 
45  $this->type = "lng";
46  parent::__construct($a_id, $a_call_by_reference);
47 
48  $this->type = "lng";
49  $this->key = $this->title;
50  $this->status = $this->desc;
51  $this->lang_default = $lng->lang_default;
52  $this->lang_user = $lng->lang_user;
53  $this->lang_path = $lng->lang_path;
54  $this->cust_lang_path = $lng->cust_lang_path;
55  $this->separator = $lng->separator;
56  $this->comment_separator = $lng->comment_separator;
57  }
58 
59 
64  public static function getInstalledLanguages()
65  {
66  $objects = array();
68  foreach ($languages as $lang) {
69  $langObj = new ilObjLanguage($lang["obj_id"], false);
70  if ($langObj->isInstalled()) {
71  $objects[] = $langObj;
72  } else {
73  unset($langObj);
74  }
75  }
76  return $objects;
77  }
78 
79 
85  public function getKey()
86  {
87  return $this->key;
88  }
89 
95  public function getStatus()
96  {
97  return $this->status;
98  }
99 
103  public function isSystemLanguage()
104  {
105  if ($this->key == $this->lang_default) {
106  return true;
107  } else {
108  return false;
109  }
110  }
111 
115  public function isUserLanguage()
116  {
117  if ($this->key == $this->lang_user) {
118  return true;
119  } else {
120  return false;
121  }
122  }
123 
124 
130  public function isInstalled()
131  {
132  if (substr($this->getStatus(), 0, 9) == "installed") {
133  return true;
134  } else {
135  return false;
136  }
137  }
138 
145  public function isLocal()
146  {
147  if (substr($this->getStatus(), 10) == "local") {
148  return true;
149  } else {
150  return false;
151  }
152  }
153 
160  public function install($scope = '')
161  {
162  if (!empty($scope)) {
163  if ($scope == 'global') {
164  $scope = '';
165  } else {
166  $scopeExtension = '.' . $scope;
167  }
168  }
169 
170  if (($this->isInstalled() == false) ||
171  ($this->isInstalled() == true && $this->isLocal() == false && !empty($scope))) {
172  if ($this->check($scope)) {
173  // lang-file is ok. Flush data in db and...
174  if (empty($scope)) {
175  $this->flush('keep_local');
176  }
177 
178  // ...re-insert data from lang-file
179  $this->insert($scope);
180 
181  // update information in db-table about available/installed languages
182  if (empty($scope)) {
183  $newDesc = 'installed';
184  } elseif ($scope == 'local') {
185  $newDesc = 'installed_local';
186  }
187  $this->setDescription($newDesc);
188  $this->update();
189  return $this->getKey();
190  }
191  }
192  return "";
193  }
194 
195 
201  public function uninstall()
202  {
203  if ((substr($this->status, 0, 9) == "installed") && ($this->key != $this->lang_default) && ($this->key != $this->lang_user)) {
204  $this->flush('all');
205  $this->setTitle($this->key);
206  $this->setDescription("not_installed");
207  $this->update();
208  $this->resetUserLanguage($this->key);
209 
210  return $this->key;
211  }
212  return "";
213  }
214 
215 
220  public function refresh()
221  {
222  if ($this->isInstalled() == true) {
223  if ($this->check()) {
224  $this->flush('keep_local');
225  $this->insert();
226  $this->setTitle($this->getKey());
227  $this->setDescription($this->getStatus());
228  $this->update();
229 
230  if ($this->isLocal() == true) {
231  if ($this->check('local')) {
232  $this->insert('local');
233  $this->setTitle($this->getKey());
234  $this->setDescription($this->getStatus());
235  $this->update();
236  }
237  }
238  return true;
239  }
240  }
241  return false;
242  }
243 
247  public static function refreshAll()
248  {
250  $refreshed = array();
251 
252  foreach ($languages as $lang) {
253  $langObj = new ilObjLanguage($lang["obj_id"], false);
254  if ($langObj->refresh()) {
255  $refreshed[] = $langObj->getKey();
256  }
257  unset($langObj);
258  }
259 
260  self::refreshPlugins($refreshed);
261  }
262 
263 
268  public static function refreshPlugins($a_lang_keys = null)
269  {
270  global $DIC;
271  $ilPluginAdmin = $DIC['ilPluginAdmin'];
272 
273  // refresh languages of activated plugins
274  include_once("./Services/Component/classes/class.ilPluginSlot.php");
275  $slots = ilPluginSlot::getAllSlots();
276  foreach ($slots as $slot) {
277  $act_plugins = $ilPluginAdmin->getActivePluginsForSlot(
278  $slot["component_type"],
279  $slot["component_name"],
280  $slot["slot_id"]
281  );
282  foreach ($act_plugins as $plugin) {
283  include_once("./Services/Component/classes/class.ilPlugin.php");
285  $slot["component_type"],
286  $slot["component_name"],
287  $slot["slot_id"],
288  $plugin
289  );
290  if (is_object($pl)) {
291  $pl->updateLanguages($a_lang_keys);
292  }
293  }
294  }
295  }
296 
297 
303  public static function _deleteLangData($a_lang_key, $a_keep_local_change = false)
304  {
305  global $DIC;
306  $ilDB = $DIC->database();
307 
308  if (!$a_keep_local_change) {
309  $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = " .
310  $ilDB->quote($a_lang_key, "text"));
311  } else {
312  $ilDB->manipulate("DELETE FROM lng_data WHERE lang_key = " .
313  $ilDB->quote($a_lang_key, "text") .
314  " AND local_change IS NULL");
315  }
316  }
317 
322  public function flush($a_mode = 'all')
323  {
324  global $DIC;
325  $ilDB = $DIC->database();
326 
327  ilObjLanguage::_deleteLangData($this->key, ($a_mode == 'keep_local'));
328 
329  if ($a_mode == 'all') {
330  $ilDB->manipulate("DELETE FROM lng_modules WHERE lang_key = " .
331  $ilDB->quote($this->key, "text"));
332  }
333  }
334 
335 
342  public function getLocalChanges($a_min_date = "", $a_max_date = "")
343  {
344  global $DIC;
345  $ilDB = $DIC->database();
346 
347  if ($a_min_date == "") {
348  $a_min_date = "1980-01-01 00:00:00";
349  }
350  if ($a_max_date == "") {
351  $a_max_date = "2200-01-01 00:00:00";
352  }
353 
354  $q = sprintf(
355  "SELECT * FROM lng_data WHERE lang_key = %s " .
356  "AND local_change >= %s AND local_change <= %s",
357  $ilDB->quote($this->key, "text"),
358  $ilDB->quote($a_min_date, "timestamp"),
359  $ilDB->quote($a_max_date, "timestamp")
360  );
361  $result = $ilDB->query($q);
362 
363  $changes = array();
364  while ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
365  $changes[$row["module"]][$row["identifier"]] = $row["value"];
366  }
367  return $changes;
368  }
369 
370 
376  public static function _getLastLocalChange($a_key)
377  {
378  global $DIC;
379  $ilDB = $DIC->database();
380 
381  $q = sprintf(
382  "SELECT MAX(local_change) last_change FROM lng_data " .
383  "WHERE lang_key = %s AND local_change IS NOT NULL",
384  $ilDB->quote($a_key, "text")
385  );
386  $result = $ilDB->query($q);
387 
388  if ($row = $result->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
389  return $row['last_change'];
390  } else {
391  return "";
392  }
393  }
394 
395 
402  public static function _getLocalChangesByModule($a_key, $a_module)
403  {
404  global $DIC;
405  $ilDB = $DIC->database();
406 
407  $changes = array();
408  $result = $ilDB->queryF(
409  "SELECT * FROM lng_data WHERE lang_key = %s AND module = %s AND local_change IS NOT NULL",
410  array('text', 'text'),
411  array($a_key, $a_module)
412  );
413 
414  while ($row = $ilDB->fetchAssoc($result)) {
415  $changes[$row['identifier']] = $row['value'];
416  }
417  return $changes;
418  }
419 
420 
426  public function insert($scope = '')
427  {
428  global $DIC;
429  $ilDB = $DIC->database();
430 
431  if (!empty($scope)) {
432  if ($scope == 'global') {
433  $scope = '';
434  } else {
435  $scopeExtension = '.' . $scope;
436  }
437  }
438 
440  if ($scope == "local") {
441  $path = $this->cust_lang_path;
442  }
443 
444  $lang_file = $path . "/ilias_" . $this->key . ".lang" . $scopeExtension;
445 
446  if (is_file($lang_file)) {
447  // initialize the array for updating lng_modules below
448  $lang_array = array();
449  $lang_array["common"] = array();
450 
451  // remove header first
452  if ($content = $this->cut_header(file($lang_file))) {
453  if (empty($scope)) {
454  // reset change date for a global file
455  // get all local changes for a global file
456  $change_date = null;
457  $local_changes = $this->getLocalChanges();
458  } elseif ($scope == 'local') {
459  // set the change date to import time for a local file
460  // get the modification date of the local file
461  // get the newer local changes for a local file
462  $change_date = date("Y-m-d H:i:s", time());
463  $min_date = date("Y-m-d H:i:s", filemtime($lang_file));
464  $local_changes = $this->getLocalChanges($min_date);
465  }
466 
467  foreach ($content as $key => $val) {
468  // split the line of the language file
469  // [0]: module
470  // [1]: identifier
471  // [2]: value
472  // [3]: comment (optional)
473  $separated = explode($this->separator, trim($val));
474  $pos = strpos($separated[2], $this->comment_separator);
475  if ($pos !== false) {
476  $separated[3] = substr($separated[2], $pos + strlen($this->comment_separator));
477  $separated[2] = substr($separated[2], 0, $pos);
478  }
479 
480  // check if the value has a local change
481  $local_value = $local_changes[$separated[0]][$separated[1]];
482 
483  if (empty($scope)) {
484  // import of a global language file
485 
486  if ($local_value != "" and $local_value != $separated[2]) {
487  // keep an existing and different local calue
488  $lang_array[$separated[0]][$separated[1]] = $local_value;
489  } else {
490  // check for double entries in global file
491  if ($double_checker[$separated[0]][$separated[1]][$this->key]) {
492  $this->ilias->raiseError(
493  "Duplicate Language Entry in $lang_file:\n$val",
494  $this->ilias->error_obj->MESSAGE
495  );
496  }
497  $double_checker[$separated[0]][$separated[1]][$this->key] = true;
498 
499  // insert a new value if no local value exists
500  // reset local change date if the values are equal
502  $separated[0],
503  $separated[1],
504  $this->key,
505  $separated[2],
506  $change_date,
507  $separated[3]
508  );
509 
510  $lang_array[$separated[0]][$separated[1]] = $separated[2];
511  }
512  } elseif ($scope == 'local') {
513  // import of a local language file
514 
515  if ($local_value != "") {
516  // keep a locally changed value that is newer than the file
517  $lang_array[$separated[0]][$separated[1]] = $local_value;
518  } else {
519  // insert a new value if no global value exists
520  // (local files may have additional entries for customizations)
521  // set the change date to the import date
523  $separated[0],
524  $separated[1],
525  $this->key,
526  $separated[2],
527  $change_date,
528  $separated[3]
529  );
530 
531  $lang_array[$separated[0]][$separated[1]] = $separated[2];
532  }
533  }
534  }
535 
536  $ld = "";
537  if (empty($scope)) {
538  $ld = "installed";
539  } elseif ($scope == 'local') {
540  $ld = "installed_local";
541  }
542  if ($ld) {
543  $query = "UPDATE object_data SET " .
544  "description = " . $ilDB->quote($ld, "text") . ", " .
545  "last_update = " . $ilDB->now() . " " .
546  "WHERE title = " . $ilDB->quote($this->key, "text") . " " .
547  "AND type = 'lng'";
548  $ilDB->manipulate($query);
549  }
550  }
551 
552  foreach ($lang_array as $module => $lang_arr) {
553  if ($scope == "local") {
554  $q = "SELECT * FROM lng_modules WHERE " .
555  " lang_key = " . $ilDB->quote($this->key, "text") .
556  " AND module = " . $ilDB->quote($module, "text");
557  $set = $ilDB->query($q);
558  $row = $ilDB->fetchAssoc($set);
559  $arr2 = unserialize($row["lang_array"]);
560  if (is_array($arr2)) {
561  $lang_arr = array_merge($arr2, $lang_arr);
562  }
563  }
564  ilObjLanguage::replaceLangModule($this->key, $module, $lang_arr);
565  }
566  }
567  }
568 
572  final public static function replaceLangModule($a_key, $a_module, $a_array)
573  {
574  global $DIC;
575  $ilDB = $DIC->database();
576 
577  // avoid flushing the whole cache (see mantis #28818)
578  ilCachedLanguage::getInstance($a_key)->deleteInCache();
579 
580  $ilDB->manipulate(sprintf(
581  "DELETE FROM lng_modules WHERE lang_key = %s AND module = %s",
582  $ilDB->quote($a_key, "text"),
583  $ilDB->quote($a_module, "text")
584  ));
585 
586  /*$ilDB->manipulate(sprintf("INSERT INTO lng_modules (lang_key, module, lang_array) VALUES ".
587  "(%s,%s,%s)", $ilDB->quote($a_key, "text"),
588  $ilDB->quote($a_module, "text"),
589  $ilDB->quote(serialize($a_array), "clob")));*/
590  $ilDB->insert("lng_modules", array(
591  "lang_key" => array("text", $a_key),
592  "module" => array("text", $a_module),
593  "lang_array" => array("clob", serialize((array) $a_array))
594  ));
595 
596  // check if the module is correctly saved
597  // see mantis #20046 and #19140
598  $result = $ilDB->queryF(
599  "SELECT lang_array FROM lng_modules WHERE lang_key = %s AND module = %s",
600  array('text','text'),
601  array($a_key, $a_module)
602  );
603  $row = $ilDB->fetchAssoc($result);
604 
605  $unserialied = unserialize($row['lang_array']);
606  if (!is_array($unserialied)) {
608  $ilErr = $DIC['ilErr'];
609  $ilErr->raiseError(
610  "Data for module '" . $a_module . "' of language '" . $a_key . "' is not correctly saved. " .
611  "Please check the collation of your database tables lng_data and lng_modules. It must be utf8_unicode_ci.",
612  $ilErr->MESSAGE
613  );
614  }
615  }
616 
620  final public static function replaceLangEntry(
621  $a_module,
622  $a_identifier,
623  $a_lang_key,
624  $a_value,
625  $a_local_change = null,
626  $a_remarks = null
627  ) {
628  global $DIC;
629  $ilDB = $DIC->database();
630 
631  // avoid a cache flush here (see mantis #28818)
632  // ilGlobalCache::flushAll();
633 
634  if (isset($a_remarks)) {
635  $a_remarks = substr($a_remarks, 0, 250);
636  }
637  if ($a_remarks == '') {
638  unset($a_remarks);
639  }
640 
641  if (isset($a_value)) {
642  $a_value = substr($a_value, 0, 4000);
643  }
644  if ($a_value == '') {
645  unset($a_value);
646  }
647 
648  $ilDB->replace(
649  'lng_data',
650  array(
651  'module' => array('text',$a_module),
652  'identifier' => array('text',$a_identifier),
653  'lang_key' => array('text',$a_lang_key)
654  ),
655  array(
656  'value' => array('text',$a_value),
657  'local_change' => array('timestamp',$a_local_change),
658  'remarks' => array('text', $a_remarks)
659  )
660  );
661  return true;
662 
663  /*
664  $ilDB->manipulate(sprintf("DELETE FROM lng_data WHERE module = %s AND ".
665  "identifier = %s AND lang_key = %s",
666  $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
667  $ilDB->quote($a_lang_key, "text")));
668 
669 
670  $ilDB->manipulate(sprintf("INSERT INTO lng_data " .
671  "(module, identifier, lang_key, value, local_change) " .
672  "VALUES (%s,%s,%s,%s,%s)",
673  $ilDB->quote($a_module, "text"), $ilDB->quote($a_identifier, "text"),
674  $ilDB->quote($a_lang_key, "text"), $ilDB->quote($a_value, "text"),
675  $ilDB->quote($a_local_change, "timestamp")));
676  */
677  }
678 
682  final public static function updateLangEntry(
683  $a_module,
684  $a_identifier,
685  $a_lang_key,
686  $a_value,
687  $a_local_change = null,
688  $a_remarks = null
689  ) {
690  global $DIC;
691  $ilDB = $DIC->database();
692 
693  if (isset($a_remarks)) {
694  $a_remarks = substr($a_remarks, 0, 250);
695  }
696  if ($a_remarks == '') {
697  unset($a_remarks);
698  }
699 
700  if (isset($a_value)) {
701  $a_value = substr($a_value, 0, 4000);
702  }
703  if ($a_value == '') {
704  unset($a_value);
705  }
706 
707  $ilDB->manipulate(sprintf(
708  "UPDATE lng_data " .
709  "SET value = %s, local_change = %s, remarks = %s " .
710  "WHERE module = %s AND identifier = %s AND lang_key = %s ",
711  $ilDB->quote($a_value, "text"),
712  $ilDB->quote($a_local_change, "timestamp"),
713  $ilDB->quote($a_remarks, "text"),
714  $ilDB->quote($a_module, "text"),
715  $ilDB->quote($a_identifier, "text"),
716  $ilDB->quote($a_lang_key, "text")
717  ));
718  }
719 
720 
724  final public static function deleteLangEntry($a_module, $a_identifier, $a_lang_key)
725  {
726  global $DIC;
727  $ilDB = $DIC->database();
728 
729  $ilDB->manipulate(sprintf(
730  "DELETE FROM lng_data " .
731  "WHERE module = %s AND identifier = %s AND lang_key = %s ",
732  $ilDB->quote($a_module, "text"),
733  $ilDB->quote($a_identifier, "text"),
734  $ilDB->quote($a_lang_key, "text")
735  ));
736 
737  return true;
738  }
739 
740 
747  public function resetUserLanguage($lang_key)
748  {
749  global $DIC;
750  $ilDB = $DIC->database();
751 
752  $query = "UPDATE usr_pref SET " .
753  "value = " . $ilDB->quote($this->lang_default, "text") . " " .
754  "WHERE keyword = " . $ilDB->quote('language', "text") . " " .
755  "AND value = " . $ilDB->quote($lang_key, "text");
756  $ilDB->manipulate($query);
757  }
758 
767  public static function cut_header($content)
768  {
769  foreach ($content as $key => $val) {
770  if (trim($val) == "<!-- language file start -->") {
771  return array_slice($content, $key + 1);
772  }
773  }
774 
775  return false;
776  }
777 
784  public function optimizeData()
785  {
786  // Mantis #22313: removed table optimization
787  return true;
788  }
789 
799  public function check($scope = '')
800  {
801  include_once("./Services/Utilities/classes/class.ilStr.php");
802 
803  if (!empty($scope)) {
804  if ($scope == 'global') {
805  $scope = '';
806  } else {
807  $scopeExtension = '.' . $scope;
808  }
809  }
810 
812  if ($scope == "local") {
813  $path = $this->cust_lang_path;
814  }
815 
816  $tmpPath = getcwd();
817 
818  // dir check
819  if (!is_dir($path)) {
820  $this->ilias->raiseError("Directory not found: " . $path, $this->ilias->error_obj->MESSAGE);
821  }
822 
823  chdir($path);
824 
825  // compute lang-file name format
826  $lang_file = "ilias_" . $this->key . ".lang" . $scopeExtension;
827 
828  // file check
829  if (!is_file($lang_file)) {
830  $this->ilias->raiseError("File not found: " . $lang_file, $this->ilias->error_obj->MESSAGE);
831  }
832 
833  // header check
834  $content = $this->cut_header(file($lang_file));
835  if ($content === false) {
836  $this->ilias->raiseError("Wrong Header in " . $lang_file, $this->ilias->error_obj->MESSAGE);
837  }
838 
839  // check (counting) elements of each lang-entry
840  $line = 0;
841  foreach ($content as $key => $val) {
842  $separated = explode($this->separator, trim($val));
843  $num = count($separated);
844  ++$n;
845  if ($num != 3) {
846  $line = $n + 36;
847  $this->ilias->raiseError("Wrong parameter count in " . $lang_file . " in line $line (Value: $val)! Please check your language file!", $this->ilias->error_obj->MESSAGE);
848  }
849  if (!ilStr::isUtf8($separated[2])) {
850  $this->ilias->raiseError("Non UTF8 character found in " . $lang_file . " in line $line (Value: $val)! Please check your language file!", $this->ilias->error_obj->MESSAGE);
851  }
852  }
853 
854  chdir($tmpPath);
855 
856  // no error occured
857  return true;
858  }
859 
863  public static function countUsers($a_lang)
864  {
865  global $DIC;
866  $ilDB = $DIC->database();
867  $lng = $DIC->language();
868 
869  $set = $ilDB->query("SELECT COUNT(*) cnt FROM usr_data ud JOIN usr_pref up" .
870  " ON ud.usr_id = up.usr_id " .
871  " WHERE up.value = " . $ilDB->quote($a_lang, "text") .
872  " AND up.keyword = " . $ilDB->quote("language", "text"));
873  $rec = $ilDB->fetchAssoc($set);
874 
875  // add users with no usr_pref set to default language
876  if ($a_lang == $lng->lang_default) {
877  $set2 = $ilDB->query("SELECT COUNT(*) cnt FROM usr_data ud LEFT JOIN usr_pref up" .
878  " ON (ud.usr_id = up.usr_id AND up.keyword = " . $ilDB->quote("language", "text") . ")" .
879  " WHERE up.value IS NULL ");
880  $rec2 = $ilDB->fetchAssoc($set2);
881  }
882 
883  return (int) $rec["cnt"] + (int) $rec2["cnt"];
884  }
885 } // END class.LanguageObject
optimizeData()
optimizes the db-table langdata
$path
Definition: aliased.php:25
static getPluginObject(string $a_ctype, string $a_cname, string $a_slot_id, string $a_pname)
isUserLanguage()
check if language is system language
$result
global $DIC
Definition: saml.php:7
Class ilObjLanguage.
static getInstalledLanguages()
Get the language objects of the installed languages.
static _getObjectsByType($a_obj_type="", $a_owner="")
Get objects by type.
static countUsers($a_lang)
Count number of users that use a language.
isInstalled()
Check language object status, and return true if language is installed.
insert($scope='')
insert language data from file into database
__construct($a_id=0, $a_call_by_reference=false)
Constructor.
$ilErr
Definition: raiseError.php:18
setTitle($a_title)
set object title
if($modEnd===false) $module
Definition: module.php:59
getStatus()
get language status
$ld
Definition: langwiz.php:244
uninstall()
uninstall current language
check($scope='')
Validate the logical structure of a lang file.
static _getLocalChangesByModule($a_key, $a_module)
Get the local changes of a language module.
static _deleteLangData($a_lang_key, $a_keep_local_change=false)
Delete languge data.
getLocalChanges($a_min_date="", $a_max_date="")
get locally changed language entries
isSystemLanguage()
check if language is system language
static deleteLangEntry($a_module, $a_identifier, $a_lang_key)
Delete lang entry.
refresh()
refresh current language
resetUserLanguage($lang_key)
search ILIAS for users which have selected &#39;$lang_key&#39; as their prefered language and reset them to d...
redirection script todo: (a better solution should control the processing via a xml file) ...
$query
$n
Definition: RandomTest.php:85
install($scope='')
install current language
$row
flush($a_mode='all')
remove language data from database
global $ilDB
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
static refreshAll()
Refresh all installed languages.
isLocal()
Check language object status, and return true if a local language file is installed.
setDescription($a_desc)
set object description
static updateLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null, $a_remarks=null)
Replace lang entry.
$languages
Definition: cssgen2.php:34
update()
update object in db
static _getLastLocalChange($a_key)
get the date of the last local change
static refreshPlugins($a_lang_keys=null)
static replaceLangEntry( $a_module, $a_identifier, $a_lang_key, $a_value, $a_local_change=null, $a_remarks=null)
Replace lang entry.
static getAllSlots()
Get all plugin slots.
static cut_header($content)
remove lang-file haeder information from &#39;$content&#39; This function seeks for a special keyword where t...
static isUtf8($a_str)
Check whether string is utf-8.
getKey()
get language key