ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilObjLanguageExt.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 require_once "./Services/Language/classes/class.ilObjLanguage.php";
22 
32 {
37  public function getGlobalLanguageFile(): object
38  {
39  require_once "./Services/Language/classes/class.ilLanguageFile.php";
40  return ilLanguageFile::_getGlobalLanguageFile($this->key);
41  }
42 
48  public function setLocal(bool $a_local = true): void
49  {
50  if ($this->isInstalled()) {
51  if ($a_local) {
52  $this->setDescription("installed_local");
53  } else {
54  $this->setDescription("installed");
55  }
56  $this->update();
57  }
58  }
59 
60 
66  public function getLongDescription(): string
67  {
68  return $this->lng->txt($this->desc);
69  }
70 
71 
75  public function getDataPath(): string
76  {
77  if (!is_dir(CLIENT_DATA_DIR . "/lang_data")) {
78  ilFileUtils::makeDir(CLIENT_DATA_DIR . "/lang_data");
79  }
80  return CLIENT_DATA_DIR . "/lang_data";
81  }
82 
88  public function getLangPath(): string
89  {
90  return $this->lang_path;
91  }
92 
98  public function getCustLangPath(): string
99  {
100  return $this->cust_lang_path;
101  }
102 
108  public function getAllRemarks(): array
109  {
110  return self::_getRemarks($this->key);
111  }
112 
121  public function getAllValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
122  {
123  return self::_getValues($this->key, $a_modules, $a_topics, $a_pattern);
124  }
125 
126 
136  public function getChangedValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
137  {
138  return self::_getValues($this->key, $a_modules, $a_topics, $a_pattern, "changed");
139  }
140 
141 
148  public function getUnchangedValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
149  {
150  return self::_getValues($this->key, $a_modules, $a_topics, $a_pattern, "unchanged");
151  }
152 
161  public function getAddedValues(array $a_modules = array(), string $a_pattern = '', array $a_topics = array()): array
162  {
163  $global_file_obj = $this->getGlobalLanguageFile();
164  $global_values = $global_file_obj->getAllValues();
165  $local_values = self::_getValues($this->key, $a_modules, $a_topics, $a_pattern);
166 
167  return array_diff_key($local_values, $global_values);
168  }
169 
170 
182  public function getCommentedValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
183  {
184  $global_file_obj = $this->getGlobalLanguageFile();
185  $global_comments = $global_file_obj->getAllComments();
186  $local_values = self::_getValues($this->key, $a_modules, $a_topics, $a_pattern);
187 
188  return array_intersect_key($local_values, $global_comments);
189  }
190 
191 
203  public function getMergedValues(): array
204  {
205  $global_file_obj = $this->getGlobalLanguageFile();
206  $global_values = $global_file_obj->getAllValues();
207  $local_values = self::_getValues($this->key);
208 
209  return array_merge($global_values, $local_values);
210  }
211 
223  public function getMergedRemarks(): array
224  {
225  $global_file_obj = $this->getGlobalLanguageFile();
226  $global_comments = $global_file_obj->getAllComments();
227 
228  // get remarks including empty remarks for local changes
229  $local_remarks = self::_getRemarks($this->key, true);
230 
231  return array_merge($global_comments, $local_remarks);
232  }
233 
240  public function importLanguageFile(string $a_file, string $a_mode_existing = "keepnew"): void
241  {
242  global $DIC;
243  $ilDB = $DIC->database();
245  $ilErr = $DIC["ilErr"];
246 
247  // read the new language file
248  require_once "./Services/Language/classes/class.ilLanguageFile.php";
249  $import_file_obj = new ilLanguageFile($a_file);
250  if (!$import_file_obj->read()) {
251  $ilErr->raiseError($import_file_obj->getErrorMessage(), $ilErr->MESSAGE);
252  }
253 
254  switch ($a_mode_existing) {
255  // keep all existing entries
256  case "keepall":
257  $to_keep = $this->getAllValues();
258  break;
259 
260  // keep existing online changes
261  case "keepnew":
262  $to_keep = $this->getChangedValues();
263  break;
264 
265  // replace all existing definitions
266  case "replace":
267  $to_keep = array();
268  break;
269 
270  // delete all existing entries
271  case "delete":
272  ilObjLanguage::_deleteLangData($this->key, false);
273  $ilDB->manipulate("DELETE FROM lng_modules WHERE lang_key = " .
274  $ilDB->quote($this->key, "text"));
275  $to_keep = array();
276  break;
277 
278  default:
279  return;
280  }
281 
282  // process the values of the import file
283  $to_save = array();
284  foreach ($import_file_obj->getAllValues() as $key => $value) {
285  if (!isset($to_keep[$key])) {
286  $to_save[$key] = $value;
287  }
288  }
289  self::_saveValues($this->key, $to_save, $import_file_obj->getAllComments());
290  }
291 
298  public static function _getModules(string $a_lang_key): array
299  {
300  global $DIC;
301  $ilDB = $DIC->database();
302 
303  $q = "SELECT DISTINCT module FROM lng_data WHERE " .
304  " lang_key = " . $ilDB->quote($a_lang_key, "text") . " order by module";
305  $set = $ilDB->query($q);
306 
307  $modules = array();
308  while ($rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
309  $modules[] = $rec["module"];
310  }
311  return $modules;
312  }
313 
314 
322  public static function _getRemarks(string $a_lang_key, bool $a_all_changed = false): array
323  {
324  global $DIC;
325  $ilDB = $DIC->database();
326  $lng = $DIC->language();
327 
328  $q = "SELECT module, identifier, remarks"
329  . " FROM lng_data"
330  . " WHERE lang_key = " . $ilDB->quote($a_lang_key, "text");
331 
332  if ($a_all_changed) {
333  $q .= " AND (remarks IS NOT NULL OR local_change IS NOT NULL)";
334  } else {
335  $q .= " AND remarks IS NOT NULL";
336  }
337 
338  $result = $ilDB->query($q);
339 
340  $remarks = array();
341  while ($row = $ilDB->fetchAssoc($result)) {
342  $remarks[$row["module"] . $lng->separator . $row["identifier"]] = $row["remarks"];
343  }
344  return $remarks;
345  }
346 
347 
358  public static function _getValues(
359  string $a_lang_key,
360  array $a_modules = array(),
361  array $a_topics = array(),
362  string $a_pattern = '',
363  string $a_state = ''
364  ): array {
365  global $DIC;
366  $ilDB = $DIC->database();
367  $lng = $DIC->language();
368 
369  $q = "SELECT * FROM lng_data WHERE" .
370  " lang_key = " . $ilDB->quote($a_lang_key, "text") . " ";
371 
372  if (is_array($a_modules) && count($a_modules) > 0) {
373  $q .= " AND " . $ilDB->in("module", $a_modules, false, "text");
374  }
375  if (is_array($a_topics) && count($a_topics) > 0) {
376  $q .= " AND " . $ilDB->in("identifier", $a_topics, false, "text");
377  }
378  if ($a_pattern) {
379  $q .= " AND " . $ilDB->like("value", "text", "%" . $a_pattern . "%");
380  }
381  if ($a_state === "changed") {
382  $q .= " AND NOT local_change IS NULL ";
383  }
384  if ($a_state === "unchanged") {
385  $q .= " AND local_change IS NULL ";
386  }
387  $q .= " ORDER BY module, identifier";
388 
389  $set = $ilDB->query($q);
390 
391  $values = array();
392  while ($rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
393  $values[$rec["module"] . $lng->separator . $rec["identifier"]] = $rec["value"];
394  }
395  return $values;
396  }
397 
405  public static function _saveValues(string $a_lang_key, array $a_values = array(), array $a_remarks = array()): void
406  {
407  global $DIC;
408  $ilDB = $DIC->database();
409  $lng = $DIC->language();
410 
411  if (!is_array($a_values)) {
412  return;
413  }
414  $save_array = [];
415  $save_date = (new DateTimeImmutable('now', new DateTimeZone('UTC')))
416  ->format('Y-m-d H:i:s');
417 
418  // read and get the global values
419  require_once "./Services/Language/classes/class.ilLanguageFile.php";
420  $global_file_obj = ilLanguageFile::_getGlobalLanguageFile($a_lang_key);
421  $file_values = $global_file_obj->getAllValues();
422  $file_comments = $global_file_obj->getAllComments();
423  $db_values = self::_getValues($a_lang_key);
424  $db_comments = self::_getRemarks($a_lang_key);
425  $global_values = array_merge($db_values, $file_values);
426  $global_comments = array_merge($db_comments, $file_comments);
427 
428  // save the single translations in lng_data
429  foreach ($a_values as $key => $value) {
430  $keys = explode($lng->separator, $key);
431 
432  if (count($keys) !== 2) {
433  continue;
434  }
435 
436  list($module, $topic) = $keys;
437  $save_array[$module][$topic] = $value;
438 
439  $are_comments_set = array_key_exists($key, $global_comments) && array_key_exists($key, $a_remarks);
440  $are_changes_made = (isset($global_values[$key]) ? $global_values[$key] != $value : true) || (isset($db_values[$key]) ? $db_values[$key] != $value : true);
441  if ($are_changes_made || ($are_comments_set ? $global_comments[$key] != $a_remarks[$key] : $are_comments_set)) {
442  $local_change = (isset($db_values[$key]) ? $db_values[$key] == $value : true) || (isset($global_values[$key]) ? $global_values[$key] != $value : true) ? $save_date : null;
444  $module,
445  $topic,
446  $a_lang_key,
447  $value,
448  $local_change,
449  $a_remarks[$key] ?? null
450  );
451  }
452  }
453 
454  // save the serialized module entries in lng_modules
455  foreach ($save_array as $module => $entries) {
456  $set = $ilDB->query(sprintf(
457  "SELECT * FROM lng_modules " .
458  "WHERE lang_key = %s AND module = %s",
459  $ilDB->quote($a_lang_key, "text"),
460  $ilDB->quote($module, "text")
461  ));
462  $row = $ilDB->fetchAssoc($set);
463  if (!$row) {
464  $DIC->logger()->root()->warning("Language module '{$module}' not found for language {$a_lang_key}.");
465  continue;
466  }
467 
468  $arr = unserialize($row["lang_array"], ["allowed_classes" => false]);
469  if (is_array($arr)) {
470  $entries = array_merge($arr, $entries);
471  }
472  ilObjLanguage::replaceLangModule($a_lang_key, $module, $entries);
473  }
474 
475  require_once("class.ilCachedLanguage.php");
476  ilCachedLanguage::getInstance($a_lang_key)->flush();
477  }
478 
485  public static function _deleteValues(string $a_lang_key, array $a_values = array()): void
486  {
487  global $DIC;
488  $ilDB = $DIC->database();
489  $lng = $DIC->language();
490 
491  if (!is_array($a_values)) {
492  return;
493  }
494  $delete_array = array();
495 
496  // save the single translations in lng_data
497  foreach ($a_values as $key => $value) {
498  $keys = explode($lng->separator, $key);
499  if (count($keys) === 2) {
500  $module = $keys[0];
501  $topic = $keys[1];
502  $delete_array[$module][$topic] = $value;
503 
504  ilObjLanguage::deleteLangEntry($module, $topic, $a_lang_key);
505  }
506  }
507 
508  // save the serialized module entries in lng_modules
509  foreach ($delete_array as $module => $entries) {
510  $set = $ilDB->query(sprintf(
511  "SELECT * FROM lng_modules " .
512  "WHERE lang_key = %s AND module = %s",
513  $ilDB->quote($a_lang_key, "text"),
514  $ilDB->quote($module, "text")
515  ));
516  $row = $ilDB->fetchAssoc($set);
517 
518  $arr = unserialize($row["lang_array"], ["allowed_classes" => false]);
519  if (is_array($arr)) {
520  $entries = array_diff_key($arr, $entries);
521  }
522  ilObjLanguage::replaceLangModule($a_lang_key, $module, $entries);
523  }
524  }
525 } // END class.ilObjLanguageExt
getMergedRemarks()
Get the local remarks merged into the remarks of the global language file.
static _deleteLangData(string $a_lang_key, bool $a_keep_local_change=false)
Delete languge data $a_lang_key lang key.
getMergedValues()
Get the local values merged into the values of the global language file.
getAllRemarks()
Get all remarks from the database.
getCustLangPath()
Get the customized language files path.
getChangedValues(array $a_modules=array(), string $a_pattern="", array $a_topics=array())
Get only the changed values from the database which differ from the original language file...
Class ilObjLanguage.
getAllValues(array $a_modules=array(), string $a_pattern="", array $a_topics=array())
Get all values from the database.
getDataPath()
Return the path for language data written by ILIAS.
isInstalled()
Check language object status, and return true if language is installed.
$ilErr
Definition: raiseError.php:17
global $DIC
Definition: feed.php:28
const CLIENT_DATA_DIR
Definition: constants.php:46
static _getValues(string $a_lang_key, array $a_modules=array(), array $a_topics=array(), string $a_pattern='', string $a_state='')
Get the translations of specified topics.
getGlobalLanguageFile()
Read and get the global language file as an object.
Class ilObjLanguageExt.
ilLanguage $lng
getAddedValues(array $a_modules=array(), string $a_pattern='', array $a_topics=array())
Get only the entries which don&#39;t exist in the global language file.
static _getModules(string $a_lang_key)
Get all modules of a language.
static _deleteValues(string $a_lang_key, array $a_values=array())
Delete a set of translation in the database.
setLocal(bool $a_local=true)
Set the local status of the language.
static replaceLangEntry(string $a_module, string $a_identifier, string $a_lang_key, string $a_value, string $a_local_change=null, string $a_remarks=null)
Replace lang entry.
getLongDescription()
Get the full language description.
getUnchangedValues(array $a_modules=array(), string $a_pattern="", array $a_topics=array())
Get only the unchanged values from the database which are equal to the original language file...
Class ilLanguageFile.
static _getRemarks(string $a_lang_key, bool $a_all_changed=false)
Get all remarks of a language.
static _getGlobalLanguageFile(string $a_lang_key)
Read and get a global language file as a singleton object $a_lang_key language key.
$q
Definition: shib_logout.php:21
getLangPath()
Get the language files path.
setDescription(string $description)
getCommentedValues(array $a_modules=array(), string $a_pattern="", array $a_topics=array())
Get all values from the database for wich the global language file has a comment. ...
static _saveValues(string $a_lang_key, array $a_values=array(), array $a_remarks=array())
Save a set of translation in the database.
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static deleteLangEntry(string $a_module, string $a_identifier, string $a_lang_key)
Delete lang entry.