ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilObjLanguageExt.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
30{
35 public function getGlobalLanguageFile(): object
36 {
38 }
39
45 public function setLocal(bool $a_local = true): void
46 {
47 if ($this->isInstalled()) {
48 if ($a_local) {
49 $this->setDescription("installed_local");
50 } else {
51 $this->setDescription("installed");
52 }
53 $this->update();
54 }
55 }
56
57
63 public function getLongDescription(): string
64 {
65 return $this->lng->txt($this->desc);
66 }
67
68
72 public function getDataPath(): string
73 {
74 if (!is_dir(CLIENT_DATA_DIR . "/lang_data")) {
76 }
77 return CLIENT_DATA_DIR . "/lang_data";
78 }
79
85 public function getLangPath(): string
86 {
87 return $this->lang_path;
88 }
89
95 public function getCustLangPath(): string
96 {
98 }
99
105 public function getAllRemarks(): array
106 {
107 return self::_getRemarks($this->key);
108 }
109
118 public function getAllValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
119 {
120 return self::_getValues($this->key, $a_modules, $a_topics, $a_pattern);
121 }
122
123
133 public function getChangedValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
134 {
135 return self::_getValues($this->key, $a_modules, $a_topics, $a_pattern, "changed");
136 }
137
138
145 public function getUnchangedValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
146 {
147 return self::_getValues($this->key, $a_modules, $a_topics, $a_pattern, "unchanged");
148 }
149
158 public function getAddedValues(array $a_modules = array(), string $a_pattern = '', array $a_topics = array()): array
159 {
160 $global_file_obj = $this->getGlobalLanguageFile();
161 $global_values = $global_file_obj->getAllValues();
162 $local_values = self::_getValues($this->key, $a_modules, $a_topics, $a_pattern);
163
164 return array_diff_key($local_values, $global_values);
165 }
166
167
179 public function getCommentedValues(array $a_modules = array(), string $a_pattern = "", array $a_topics = array()): array
180 {
181 $global_file_obj = $this->getGlobalLanguageFile();
182 $global_comments = $global_file_obj->getAllComments();
183 $local_values = self::_getValues($this->key, $a_modules, $a_topics, $a_pattern);
184
185 return array_intersect_key($local_values, $global_comments);
186 }
187
188
200 public function getMergedValues(): array
201 {
202 $global_file_obj = $this->getGlobalLanguageFile();
203 $global_values = $global_file_obj->getAllValues();
204 $local_values = self::_getValues($this->key);
205
206 return array_merge($global_values, $local_values);
207 }
208
220 public function getMergedRemarks(): array
221 {
222 $global_file_obj = $this->getGlobalLanguageFile();
223 $global_comments = $global_file_obj->getAllComments();
224
225 // get remarks including empty remarks for local changes
226 $local_remarks = self::_getRemarks($this->key, true);
227
228 return array_merge($global_comments, $local_remarks);
229 }
230
237 public function importLanguageFile(string $a_file, string $a_mode_existing = "keepnew"): void
238 {
239 global $DIC;
240 $ilDB = $DIC->database();
242 $ilErr = $DIC["ilErr"];
243
244 // read the new language file
245 $import_file_obj = new ilLanguageFile($a_file);
246 if (!$import_file_obj->read()) {
247 $ilErr->raiseError($import_file_obj->getErrorMessage(), $ilErr->MESSAGE);
248 }
249
250 switch ($a_mode_existing) {
251 // keep all existing entries
252 case "keepall":
253 $to_keep = $this->getAllValues();
254 break;
255
256 // keep existing online changes
257 case "keepnew":
258 $to_keep = $this->getChangedValues();
259 break;
260
261 // replace all existing definitions
262 case "replace":
263 $to_keep = array();
264 break;
265
266 // delete all existing entries
267 case "delete":
268 ilObjLanguage::_deleteLangData($this->key, false);
269 $ilDB->manipulate("DELETE FROM lng_modules WHERE lang_key = " .
270 $ilDB->quote($this->key, "text"));
271 $to_keep = array();
272 break;
273
274 default:
275 return;
276 }
277
278 // process the values of the import file
279 $to_save = array();
280 foreach ($import_file_obj->getAllValues() as $key => $value) {
281 if (!isset($to_keep[$key])) {
282 $to_save[$key] = $value;
283 }
284 }
285 self::_saveValues($this->key, $to_save, $import_file_obj->getAllComments());
286 }
287
294 public static function _getModules(string $a_lang_key): array
295 {
296 global $DIC;
297 $ilDB = $DIC->database();
298
299 $q = "SELECT DISTINCT module FROM lng_data WHERE " .
300 " lang_key = " . $ilDB->quote($a_lang_key, "text") . " order by module";
301 $set = $ilDB->query($q);
302
303 $modules = array();
304 while ($rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
305 $modules[] = $rec["module"];
306 }
307 return $modules;
308 }
309
310
318 public static function _getRemarks(string $a_lang_key, bool $a_all_changed = false): array
319 {
320 global $DIC;
321 $ilDB = $DIC->database();
322 $lng = $DIC->language();
323
324 $q = "SELECT module, identifier, remarks"
325 . " FROM lng_data"
326 . " WHERE lang_key = " . $ilDB->quote($a_lang_key, "text");
327
328 if ($a_all_changed) {
329 $q .= " AND (remarks IS NOT NULL OR local_change IS NOT NULL)";
330 } else {
331 $q .= " AND remarks IS NOT NULL";
332 }
333
334 $result = $ilDB->query($q);
335
336 $remarks = array();
337 while ($row = $ilDB->fetchAssoc($result)) {
338 $remarks[$row["module"] . $lng->separator . $row["identifier"]] = $row["remarks"];
339 }
340 return $remarks;
341 }
342
343
354 public static function _getValues(
355 string $a_lang_key,
356 array $a_modules = array(),
357 array $a_topics = array(),
358 string $a_pattern = '',
359 string $a_state = ''
360 ): array {
361 global $DIC;
362 $ilDB = $DIC->database();
363 $lng = $DIC->language();
364
365 $q = "SELECT * FROM lng_data WHERE" .
366 " lang_key = " . $ilDB->quote($a_lang_key, "text") . " ";
367
368 if (is_array($a_modules) && count($a_modules) > 0) {
369 $q .= " AND " . $ilDB->in("module", $a_modules, false, "text");
370 }
371 if (is_array($a_topics) && count($a_topics) > 0) {
372 $q .= " AND " . $ilDB->in("identifier", $a_topics, false, "text");
373 }
374 if ($a_pattern) {
375 $q .= " AND " . $ilDB->like("value", "text", "%" . $a_pattern . "%");
376 }
377 if ($a_state === "changed") {
378 $q .= " AND NOT local_change IS NULL ";
379 }
380 if ($a_state === "unchanged") {
381 $q .= " AND local_change IS NULL ";
382 }
383 $q .= " ORDER BY module, identifier";
384
385 $set = $ilDB->query($q);
386
387 $values = array();
388 while ($rec = $set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
389 $values[$rec["module"] . $lng->separator . $rec["identifier"]] = $rec["value"];
390 }
391 return $values;
392 }
393
401 public static function _saveValues(string $a_lang_key, array $a_values = array(), array $a_remarks = array()): void
402 {
403 global $DIC;
404 $ilDB = $DIC->database();
405 $lng = $DIC->language();
406
407 if (!is_array($a_values)) {
408 return;
409 }
410 $save_array = [];
411 $save_date = (new DateTimeImmutable('now', new DateTimeZone('UTC')))
412 ->format('Y-m-d H:i:s');
413
414 // read and get the global values
415 $global_file_obj = ilLanguageFile::_getGlobalLanguageFile($a_lang_key);
416 $file_values = $global_file_obj->getAllValues();
417 $file_comments = $global_file_obj->getAllComments();
418 $db_values = self::_getValues($a_lang_key);
419 $db_comments = self::_getRemarks($a_lang_key);
420 $global_values = array_merge($db_values, $file_values);
421 $global_comments = array_merge($db_comments, $file_comments);
422
423 // save the single translations in lng_data
424 foreach ($a_values as $key => $value) {
425 $keys = explode($lng->separator, $key);
426
427 if (count($keys) !== 2) {
428 continue;
429 }
430
431 list($module, $topic) = $keys;
432 $save_array[$module][$topic] = $value;
433
434 $are_comments_set = array_key_exists($key, $global_comments) && array_key_exists($key, $a_remarks);
435 $are_changes_made = (isset($global_values[$key]) ? $global_values[$key] != $value : true) || (isset($db_values[$key]) ? $db_values[$key] != $value : true);
436 if ($are_changes_made || ($are_comments_set ? $global_comments[$key] != $a_remarks[$key] : $are_comments_set)) {
437 $local_change = (isset($db_values[$key]) ? $db_values[$key] == $value : true) || (isset($global_values[$key]) ? $global_values[$key] != $value : true) ? $save_date : null;
439 $module,
440 $topic,
441 $a_lang_key,
442 $value,
443 $local_change,
444 $a_remarks[$key] ?? null
445 );
446 }
447 }
448
449 // save the serialized module entries in lng_modules
450 foreach ($save_array as $module => $entries) {
451 $set = $ilDB->query(sprintf(
452 "SELECT * FROM lng_modules " .
453 "WHERE lang_key = %s AND module = %s",
454 $ilDB->quote($a_lang_key, "text"),
455 $ilDB->quote($module, "text")
456 ));
457 $row = $ilDB->fetchAssoc($set);
458 if (!$row) {
459 $DIC->logger()->root()->warning("Language module '{$module}' not found for language {$a_lang_key}.");
460 continue;
461 }
462
463 $entries = self::_mergeLanguageEntriesFromRow($row, $entries);
464
465 ilObjLanguage::replaceLangModule($a_lang_key, $module, $entries);
466 }
467
468 ilCachedLanguage::getInstance($a_lang_key)->flush();
469 }
470
478 private static function _mergeLanguageEntriesFromRow(?array $databaseRow, array $entries): array
479 {
480 if ($databaseRow === null || !isset($databaseRow["lang_array"])) {
481 return $entries;
482 }
483
484 $languageEntries = unserialize($databaseRow["lang_array"], ["allowed_classes" => false]);
485 if (!is_array($languageEntries)) {
486 return $entries;
487 }
488
489 return array_merge($languageEntries, $entries);
490 }
491
492
499 public static function _deleteValues(string $a_lang_key, array $a_values = array()): void
500 {
501 global $DIC;
502 $ilDB = $DIC->database();
503 $lng = $DIC->language();
504
505 if (!is_array($a_values)) {
506 return;
507 }
508 $delete_array = array();
509
510 // save the single translations in lng_data
511 foreach ($a_values as $key => $value) {
512 $keys = explode($lng->separator, $key);
513 if (count($keys) === 2) {
514 $module = $keys[0];
515 $topic = $keys[1];
516 $delete_array[$module][$topic] = $value;
517
518 ilObjLanguage::deleteLangEntry($module, $topic, $a_lang_key);
519 }
520 }
521
522 // save the serialized module entries in lng_modules
523 foreach ($delete_array as $module => $entries) {
524 $set = $ilDB->query(sprintf(
525 "SELECT * FROM lng_modules " .
526 "WHERE lang_key = %s AND module = %s",
527 $ilDB->quote($a_lang_key, "text"),
528 $ilDB->quote($module, "text")
529 ));
530 $row = $ilDB->fetchAssoc($set);
531
532 $arr = unserialize($row["lang_array"], ["allowed_classes" => false]);
533 if (is_array($arr)) {
534 $entries = array_diff_key($arr, $entries);
535 }
536 ilObjLanguage::replaceLangModule($a_lang_key, $module, $entries);
537 }
538 }
539} // END class.ilObjLanguageExt
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
Class ilLanguageFile.
static _getGlobalLanguageFile(string $a_lang_key)
Read and get a global language file as a singleton object $a_lang_key language key.
Class ilObjLanguageExt.
getGlobalLanguageFile()
Read and get the global language file as an object.
setLocal(bool $a_local=true)
Set the local status of the language.
static _deleteValues(string $a_lang_key, array $a_values=array())
Delete a set of translation in the database.
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.
static _getModules(string $a_lang_key)
Get all modules of a language.
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.
getAllValues(array $a_modules=array(), string $a_pattern="", array $a_topics=array())
Get all values from the database.
getLongDescription()
Get the full language description.
getMergedValues()
Get the local values merged into the values of the global language file.
getCustLangPath()
Get the customized language files path.
getDataPath()
Return the path for language data written by ILIAS.
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.
static _mergeLanguageEntriesFromRow(?array $databaseRow, array $entries)
Merge language entries from a database row with existing entries.
getAddedValues(array $a_modules=array(), string $a_pattern='', array $a_topics=array())
Get only the entries which don't exist in the global language file.
static _getRemarks(string $a_lang_key, bool $a_all_changed=false)
Get all remarks of a language.
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.
getLangPath()
Get the language files path.
getMergedRemarks()
Get the local remarks merged into the remarks of the global language file.
getAllRemarks()
Get all remarks from the database.
Class ilObjLanguage.
static _deleteLangData(string $a_lang_key, bool $a_keep_local_change=false)
Delete languge data $a_lang_key lang key.
static deleteLangEntry(string $a_module, string $a_identifier, string $a_lang_key)
Delete lang entry.
isInstalled()
Check language object status, and return true if language is installed.
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.
static replaceLangModule(string $a_key, string $a_module, array $a_array)
Replace language module array.
ilLanguage $lng
setDescription(string $description)
const CLIENT_DATA_DIR
Definition: constants.php:46
global $lng
Definition: privfeed.php:31
$ilErr
Definition: raiseError.php:33
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23