ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilObjLanguageExtGUI.php
Go to the documentation of this file.
1 <?php
2 
20 declare(strict_types=1);
21 
26 
42 {
43  private const ILIAS_LANGUAGE_MODULE = "components/ILIAS/Language";
44  private string $langmode;
45  protected HTTPServices $http;
46  protected Refinery $refinery;
58  public function __construct($a_data, int $a_id = 0, bool $a_call_by_reference = false)
59  {
60  global $DIC;
61  $ilClientIniFile = $DIC->clientIni();
62  $ilCtrl = $DIC->ctrl();
63  $lng = $DIC->language();
64  $this->http = $DIC->http();
65  $this->refinery = $DIC->refinery();
66 
67  // language maintenance strings are defined in administration
68  $lng->loadLanguageModule("administration");
69  $lng->loadLanguageModule("meta");
70 
71  // view mode ('translate' or empty) determins available table filters
72  $ilCtrl->saveParameter($this, "view_mode");
73 
74  // type and id of get the bound object
75  $this->type = "lng";
76  $obj_id_get = 0;
77  if ($this->http->wrapper()->query()->has("obj_id")) {
78  $obj_id_get = $this->http->wrapper()->query()->retrieve("obj_id", $this->refinery->kindlyTo()->int());
79  } elseif ($this->http->wrapper()->query()->has("language_folder_obj_ids")) {
80  $obj_id_get = $this->http->wrapper()->query()->retrieve("language_folder_obj_ids", $this->refinery->kindlyTo()->int());
81  }
82  if (!$this->id = $obj_id_get) {
84  }
85 
86  // do all generic GUI initialisations
87  parent::__construct($a_data, $this->id, false, true);
88 
89  // initialize the array to store session variables for extended language maintenance
90  if (!is_array($this->getSession())) {
91  ilSession::set("lang_ext_maintenance", array());
92  }
93 
94  // read the lang mode
95  $this->langmode = $ilClientIniFile->readVariable("system", "LANGMODE");
96  }
97 
104  protected function assignObject(): void
105  {
106  $this->object = new ilObjLanguageExt($this->id);
107  }
108 
113  public function getId(): int
114  {
115  return $this->id;
116  }
117 
121  public function executeCommand(): void
122  {
123  global $DIC;
124  $ilHelp = $DIC->help();
125 
127  $this->error->raiseError($this->lng->txt("permission_denied"), $this->error->MESSAGE);
128  exit;
129  }
130 
131  $cmd = $this->ctrl->getCmd("view") . "Object";
132  $this->$cmd();
133 
134  $ilHelp->setScreenIdComponent("lng");
135  }
136 
140  public function cancelObject(): void
141  {
142  $this->viewObject();
143  }
144 
148  protected function getViewTable(): ilLanguageExtTableGUI
149  {
150  // create and configure the table object
151  $table_gui = new ilLanguageExtTableGUI($this, "view", array(
152  "langmode" => $this->langmode,
153  "lang_key" => $this->object->key,
154  ));
155 
156  return $table_gui;
157  }
158 
162  public function viewObject(int $changesSuccessBool = 0): void
163  {
164  global $DIC;
165  $tpl = $DIC["tpl"];
166 
167  // get the view table
168  $table_gui = $this->getViewTable();
169 
170  // get the remarks in database
171  $comments = $this->object->getAllRemarks();
172 
173  $compare_comments = [];
174  $missing_entries = [];
175 
176  // set the language to compare with
177  // get the default values if the compare language is the same
178  $compare = $table_gui->getFilterItemByPostVar("compare")->getValue();
179  if ($compare == $this->object->key) {
180  $compare_object = $this->object->getGlobalLanguageFile();
181  $compare_content = $compare_object->getAllValues();
182  $compare_comments = $compare_object->getAllComments();
183  }
184 
185  // page translation mode:
186  // - the table is filtered by a list of modules and topics
188  // get the selection of modules and topics from request or session
191 
192  $reset_offset_get = false;
193  if ($this->http->wrapper()->query()->has("reset_offset")) {
194  $reset_offset_get = $this->http->wrapper()->query()->retrieve(
195  "reset_offset",
196  $this->refinery->kindlyTo()->bool()
197  );
198  }
199 
200  // first call for translation
201  if ($reset_offset_get) {
202  $table_gui->resetOffset();
203  }
204 
205  if (!isset($compare_content)) {
206  $compare_content = ilObjLanguageExt::_getValues(
207  $compare,
208  $modules,
209  $topics
210  );
211 
212  $compare_comments = ilObjLanguageExt::_getRemarks($compare);
213  }
214 
215  $translations = ilObjLanguageExt::_getValues(
216  $this->object->key,
217  $modules,
218  $topics
219  );
220 
221  // enable adding new entries
222  $db_found = array();
223  foreach ($translations as $name => $translation) {
224  $keys = explode($this->lng->separator, $name);
225  $db_found[] = $keys[1];
226  }
227  $missing_entries = array_diff($topics, $db_found);
228  } else { // normal view mode:
229  // - the table is filtered manually by module, mode and pattern
230  $filter_mode = $table_gui->getFilterItemByPostVar("mode")->getValue();
231  $filter_pattern = $table_gui->getFilterItemByPostVar("pattern")->getValue();
232  $filter_module = $table_gui->getFilterItemByPostVar("module")->getValue();
233  $filter_module = $filter_module === "all" ? "" : $filter_module;
234  $filter_modules = $filter_module ? array($filter_module) : array();
235  $filter_identifier = $table_gui->getFilterItemByPostVar("identifier")->getValue();
236  $filter_topics = $filter_identifier ? array($filter_identifier) : array();
237 
238  if (!isset($compare_content)) {
239  $compare_content = ilObjLanguageExt::_getValues(
240  $compare,
241  $filter_modules,
242  $filter_topics
243  );
244 
245  $compare_comments = ilObjLanguageExt::_getRemarks($compare);
246  }
247 
248  switch ($filter_mode) {
249  case "changed":
250  $translations = $this->object->getChangedValues(
251  $filter_modules,
252  $filter_pattern,
253  $filter_topics
254  );
255  break;
256 
257  case "added": //langmode only
258  $translations = $this->object->getAddedValues(
259  $filter_modules,
260  $filter_pattern,
261  $filter_topics
262  );
263  break;
264 
265  case "unchanged":
266  $translations = $this->object->getUnchangedValues(
267  $filter_modules,
268  $filter_pattern,
269  $filter_topics
270  );
271  break;
272 
273  case "commented":
274  $translations = $this->object->getCommentedValues(
275  $filter_modules,
276  $filter_pattern,
277  $filter_topics
278  );
279  break;
280 
281  case "dbremarks":
282  $translations = $this->object->getAllValues(
283  $filter_modules,
284  $filter_pattern,
285  $filter_topics
286  );
287 
288  $translations = array_intersect_key($translations, $comments);
289  break;
290 
291  case "equal":
292  $translations = $this->object->getAllValues(
293  $filter_modules,
294  $filter_pattern,
295  $filter_topics
296  );
297 
298  $translations = array_intersect_assoc($translations, $compare_content);
299  break;
300 
301  case "different":
302  $translations = $this->object->getAllValues(
303  $filter_modules,
304  $filter_pattern,
305  $filter_topics
306  );
307 
308  $translations = array_diff_assoc($translations, $compare_content);
309  break;
310 
311  case "conflicts":
312  $former_file = $this->object->getDataPath() . "/ilias_" . $this->object->key . ".lang";
313  if (!is_readable($former_file)) {
314  $this->tpl->setOnScreenMessage('failure', sprintf($this->lng->txt("language_former_file_missing"), $former_file)
315  . '<br />' . $this->lng->txt("language_former_file_description"), false);
316  $translations = array();
317  break;
318  }
319  $global_file_obj = $this->object->getGlobalLanguageFile();
320  $former_file_obj = new ilLanguageFile($former_file);
321  $former_file_obj->read();
322  $global_changes = array_diff_assoc(
323  $global_file_obj->getAllValues(),
324  $former_file_obj->getAllValues()
325  );
326  if (!count($global_changes)) {
327  $this->tpl->setOnScreenMessage('info', sprintf($this->lng->txt("language_former_file_equal"), $former_file)
328  . '<br />' . $this->lng->txt("language_former_file_description"), false);
329  $translations = array();
330  break;
331  }
332  $translations = $this->object->getChangedValues(
333  $filter_modules,
334  $filter_pattern,
335  $filter_topics
336  );
337 
338  $translations = array_intersect_key($translations, $global_changes);
339  break;
340 
341  case "all":
342  default:
343  $translations = $this->object->getAllValues(
344  $filter_modules,
345  $filter_pattern,
346  $filter_topics
347  );
348  }
349  }
350 
351  // prepare the the data for the table
352  $data = array();
353  foreach ($translations as $name => $translation) {
354  $keys = explode($this->lng->separator, $name);
355  $row = array();
356 
357  $row["module"] = $keys[0];
358  $row["topic"] = $keys[1];
359  $row["name"] = $name;
360  $row["translation"] = $translation;
361  $row["comment"] = $comments[$name] ?? "";
362  $row["default"] = $compare_content[$name] ?? "";
363  $row["default_comment"] = $compare_comments[$name] ?? "";
364 
365  $data[] = $row;
366  }
367 
368  if ($changesSuccessBool) {
369  $tpl->setVariable("MESSAGE", $this->getSuccessMessage());
370  }
371 
372  // render and show the table
373  $table_gui->setData($data);
374  $tpl->setContent($table_gui->getHTML() . $this->buildMissingEntries($missing_entries));
375  }
376 
380  public function applyFilterObject(): void
381  {
382  $table_gui = $this->getViewTable();
383  $table_gui->writeFilterToSession(); // writes filter to session
384  $table_gui->resetOffset(); // sets record offest to 0 (first page)
385  $this->viewObject();
386  }
387 
391  public function resetFilterObject(): void
392  {
393  $table_gui = $this->getViewTable();
394  $table_gui->resetOffset(); // sets record offest to 0 (first page)
395  $table_gui->resetFilter(); // clears filter
396  $this->viewObject();
397  }
398 
402  public function saveObject(): void
403  {
404  // no changes have been made yet
405  $changesSuccessBool = 0;
406  // prepare the values to be saved
407  $save_array = array();
408  $remarks_array = array();
409  $post = (array) ($this->http->request()->getParsedBody() ?? []);
410  foreach ($post as $key => $value) {
411  $orginal_key = $key;
412  // mantis #25237
413  // @see https://php.net/manual/en/language.variables.external.php
414  $key = str_replace(["_POSTDOT_", "_POSTSPACE_"], [".", " "], $key);
415 
416  // example key of variable: 'common#:#access'
417  // example key of comment: 'common#:#access#:#comment'
418  $keys = explode($this->lng->separator, ilUtil::stripSlashes($key));
419 
420  if (count($keys) === 2) {
421  // avoid line breaks
422  $value = preg_replace("/(\015\012)|(\015)|(\012)/", "<br />", $value);
423  $value = str_replace("<<", "«", $value);
424  $value = ilUtil::stripSlashes($value, true, "<strong><em><u><strike><ol><li><ul><p><div><i><b><code><sup><pre><gap><a><img><bdo><br><span>");
425  $save_array[$key] = $value;
426 
427  // the comment has the key of the language with the suffix
428  $remarks_array[$key] = $post[$orginal_key . $this->lng->separator . "comment"];
429  }
430  }
431 
432  // save the translations
433  ilObjLanguageExt::_saveValues($this->object->key, $save_array, $remarks_array);
434 
435  // set successful changes bool to true;
436  $changesSuccessBool = 1;
437 
438  // view the list
439  $this->viewObject($changesSuccessBool);
440  }
441 
445  public function importObject(): void
446  {
447  $form = $this->initNewImportForm();
448  $this->tpl->setContent($form->getHTML());
449  }
450 
451  protected function initNewImportForm(): ilPropertyFormGUI
452  {
453  $form = new ilPropertyFormGUI();
454  $form->setFormAction($this->ctrl->getFormAction($this));
455  $form->setTitle($this->lng->txt("language_import_file"));
456  $form->addCommandButton("upload", $this->lng->txt("upload"));
457 
458  $fu = new ilFileInputGUI($this->lng->txt("file"), "userfile");
459  $fu->setRequired(true);
460  $form->addItem($fu);
461 
462  $rg = new ilRadioGroupInputGUI($this->lng->txt("language_mode_existing"), "mode_existing");
463  $ro = new ilRadioOption($this->lng->txt("language_mode_existing_keepall"), "keepall");
464  $ro->setInfo($this->lng->txt("language_mode_existing_keepall_info"));
465  $rg->addOption($ro);
466  $ro = new ilRadioOption($this->lng->txt("language_mode_existing_keepnew"), "keepnew");
467  $ro->setInfo($this->lng->txt("language_mode_existing_keepnew_info"));
468  $rg->addOption($ro);
469  $ro = new ilRadioOption($this->lng->txt("language_mode_existing_replace"), "replace");
470  $ro->setInfo($this->lng->txt("language_mode_existing_replace_info"));
471  $rg->addOption($ro);
472  $ro = new ilRadioOption($this->lng->txt("language_mode_existing_delete"), "delete");
473  $ro->setInfo($this->lng->txt("language_mode_existing_delete_info"));
474  $rg->addOption($ro);
475  $rg->setValue($this->getSession()["import"]["mode_existing"] ?? "keepall");
476  $form->addItem($rg);
477 
478  return $form;
479  }
480 
484  public function uploadObject(): void
485  {
486  global $DIC;
487 
488  $form = $this->initNewImportForm();
489  if ($form->checkInput()) {
490  $post_mode_existing = $this->http->request()->getParsedBody()['mode_existing'] ?? "";
491  // save form inputs for next display
492  $tmp["import"]["mode_existing"] = ilUtil::stripSlashes($post_mode_existing);
493  ilSession::set("lang_ext_maintenance", $tmp);
494  try {
495  $upload = $DIC->upload();
496  //mantis #41617
497  if (!$upload->hasBeenProcessed()) {
498  $upload->process();
499  }
500 
501 
502  if (!$upload->hasUploads()) {
503  throw new ilException($DIC->language()->txt("upload_error_file_not_found"));
504  }
505  $UploadResult = $upload->getResults()[$_FILES["userfile"]["tmp_name"]];
506 
507  $ProcessingStatus = $UploadResult->getStatus();
508  if ($ProcessingStatus->getCode() === ProcessingStatus::REJECTED) {
509  throw new ilException($ProcessingStatus->getMessage());
510  }
511 
512  // todo: refactor when importLanguageFile() is able to work with the new Filesystem service
513  $tempfile = ilFileUtils::ilTempnam() . ".sec";
514  $upload->moveOneFileTo($UploadResult, '', Location::TEMPORARY, basename($tempfile), true);
515  $this->object->importLanguageFile($tempfile, $post_mode_existing);
516 
517  $tempfs = $DIC->filesystem()->temp();
518  $tempfs->delete(basename($tempfile));
519  } catch (Exception $e) {
520  $this->tpl->setOnScreenMessage('failure', $e->getMessage(), true);
521  $this->ctrl->redirect($this, 'import');
522  }
523 
524  $this->tpl->setOnScreenMessage(
525  'success',
526  sprintf($this->lng->txt("language_file_imported"), $_FILES["userfile"]["name"]),
527  true
528  );
529  $this->ctrl->redirect($this, "import");
530  }
531 
532  $form->setValuesByPost();
533  $this->tpl->setContent($form->getHTML());
534  }
535 
539  public function exportObject(): void
540  {
541  $form = new ilPropertyFormGUI();
542  $form->setFormAction($this->ctrl->getFormAction($this));
543  $form->setTitle($this->lng->txt("language_export_file"));
544  $form->setPreventDoubleSubmission(false);
545  $form->addCommandButton("download", $this->lng->txt("download"));
546 
547  $rg = new ilRadioGroupInputGUI($this->lng->txt("language_file_scope"), "scope");
548  $ro = new ilRadioOption($this->lng->txt("language_scope_global"), "global");
549  $ro->setInfo($this->lng->txt("language_scope_global_info"));
550  $rg->addOption($ro);
551  $ro = new ilRadioOption($this->lng->txt("language_scope_local"), "local");
552  $ro->setInfo($this->lng->txt("language_scope_local_info"));
553  $rg->addOption($ro);
554  if ($this->langmode) {
555  $ro = new ilRadioOption($this->lng->txt("language_scope_added"), "added");
556  $ro->setInfo($this->lng->txt("language_scope_added_info"));
557  $rg->addOption($ro);
558  }
559  $ro = new ilRadioOption($this->lng->txt("language_scope_unchanged"), "unchanged");
560  $ro->setInfo($this->lng->txt("language_scope_unchanged_info"));
561  $rg->addOption($ro);
562  if ($this->langmode) {
563  $ro = new ilRadioOption($this->lng->txt("language_scope_merged"), "merged");
564  $ro->setInfo($this->lng->txt("language_scope_merged_info"));
565  $rg->addOption($ro);
566  }
567 
568  $rg->setValue($this->getSession()["export"]["scope"] ?? "global");
569  $form->addItem($rg);
570 
571  $this->tpl->setContent($form->getHTML());
572  }
573 
577  public function downloadObject(): void
578  {
579  $post_scope = $this->http->request()->getParsedBody()['scope'] ?? "";
580  // save the selected scope
581  $tmp["export"]["scope"] = ilUtil::stripSlashes($post_scope);
582  ilSession::set("lang_ext_maintenance", $tmp);
583 
584  $filename = "ilias_" . $this->object->key . '_'
585  . str_replace(".", "_", substr(ILIAS_VERSION, 0, strpos(ILIAS_VERSION, " ")))
586  . "-" . gmdate("Y-m-d")
587  . ".lang." . $this->getSession()["export"]["scope"];
588 
589  $global_file_obj = $this->object->getGlobalLanguageFile();
590  $local_file_obj = new ilLanguageFile($filename, $this->object->key, $post_scope);
591 
592  if ($post_scope === "global") {
593  $local_file_obj->setParam("author", $global_file_obj->getParam("author"));
594  $local_file_obj->setParam("version", $global_file_obj->getParam("version"));
595  $local_file_obj->setAllValues($this->object->getAllValues());
596  if ($this->langmode) {
597  $local_file_obj->setAllComments($this->object->getAllRemarks());
598  }
599  } elseif ($post_scope === "local") {
600  $local_file_obj->setParam("based_on", $global_file_obj->getParam("version"));
601  $local_file_obj->setAllValues($this->object->getChangedValues());
602  if ($this->langmode) {
603  $local_file_obj->setAllComments($this->object->getAllRemarks());
604  }
605  } elseif ($post_scope === "added") { // langmode only
606  $local_file_obj->setParam("author", $global_file_obj->getParam("author"));
607  $local_file_obj->setParam("version", $global_file_obj->getParam("version"));
608  $local_file_obj->setAllValues($this->object->getAddedValues());
609  $local_file_obj->setAllComments($this->object->getAllRemarks());
610  } elseif ($post_scope === "unchanged") {
611  $local_file_obj->setParam("author", $global_file_obj->getParam("author"));
612  $local_file_obj->setParam("version", $global_file_obj->getParam("version"));
613  $local_file_obj->setAllValues($this->object->getUnchangedValues());
614  if ($this->langmode) {
615  $local_file_obj->setAllComments($this->object->getAllRemarks());
616  }
617  } elseif ($post_scope === "merged") { // langmode only
618  $local_file_obj->setParam("author", $global_file_obj->getParam("author"));
619  $local_file_obj->setParam("version", $global_file_obj->getParam("version"));
620  $local_file_obj->setAllValues($this->object->getMergedValues());
621  $local_file_obj->setAllComments($this->object->getMergedRemarks());
622  }
623 
624  ilUtil::deliverData($local_file_obj->build(), $filename);
625  }
626 
630  public function maintainObject(): void
631  {
632  $form = new ilPropertyFormGUI();
633  $form->setFormAction($this->ctrl->getFormAction($this));
634  $form->setTitle($this->lng->txt("language_maintenance"));
635  $form->setPreventDoubleSubmission(false);
636  $form->addCommandButton("maintainExecute", $this->lng->txt("language_process_maintenance"));
637 
638  $rg = new ilRadioGroupInputGUI($this->lng->txt("language_maintain_local_changes"), "maintain");
639  $ro = new ilRadioOption($this->lng->txt("language_load_local_changes"), "load");
640  $ro->setInfo(sprintf($this->lng->txt("language_load_local_changes_info"), $this->object->key));
641  $rg->addOption($ro);
642  $ro = new ilRadioOption($this->lng->txt("language_clear_local_changes"), "clear");
643  $ro->setInfo(sprintf($this->lng->txt("language_clear_local_changes_info"), $this->object->key));
644  $rg->addOption($ro);
645  if ($this->langmode) {
646  $ro = new ilRadioOption($this->lng->txt("language_delete_local_additions"), "delete_added");
647  $ro->setInfo(sprintf($this->lng->txt("language_delete_local_additions_info"), $this->object->key));
648  $rg->addOption($ro);
649  $ro = new ilRadioOption($this->lng->txt("language_remove_local_file"), "remove_local_file");
650  $ro->setInfo(sprintf($this->lng->txt("language_remove_local_file_info"), $this->object->key));
651  $rg->addOption($ro);
652  $ro = new ilRadioOption($this->lng->txt("language_merge_local_changes"), "merge");
653  $ro->setInfo(sprintf($this->lng->txt("language_merge_local_changes_info"), $this->object->key));
654  $rg->addOption($ro);
655  }
656  $ro = new ilRadioOption($this->lng->txt("language_save_dist"), "save_dist");
657  $ro->setInfo(sprintf($this->lng->txt("language_save_dist_info"), $this->object->key));
658  $rg->addOption($ro);
659  $rg->setValue($this->getSession()["maintain"] ?? "load");
660  $form->addItem($rg);
661 
662  $this->tpl->setContent($form->getHTML());
663  }
664 
665  public function maintainExecuteObject(): void
666  {
667  $post_maintain = $this->http->request()->getParsedBody()['maintain'] ?? "";
668  if (isset($post_maintain)) {
669  $tmp["maintain"] = ilUtil::stripSlashes($post_maintain);
670  ilSession::set("lang_ext_maintenance", $tmp);
671  }
672 
673  switch ($post_maintain) {
674  // save the global language file for merge after
675  case "save_dist":
676  // save a copy of the distributed language file
677  $orig_file = $this->object->getLangPath() . "/ilias_" . $this->object->key . ".lang";
678  $copy_file = $this->object->getDataPath() . "/ilias_" . $this->object->key . ".lang";
679  if (@copy($orig_file, $copy_file)) {
680  $this->tpl->setOnScreenMessage('success', $this->lng->txt("language_saved_dist"), true);
681  } else {
682  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("language_save_dist_failed"), true);
683  }
684  break;
685 
686  // load the content of the local language file
687  case "load":
688  $lang_file = $this->object->getCustLangPath() . "/ilias_" . $this->object->key . ".lang.local";
689  if (is_file($lang_file) and is_readable($lang_file)) {
690  $this->object->importLanguageFile($lang_file, "replace");
691  $this->object->setLocal(true);
692  $this->tpl->setOnScreenMessage('success', $this->lng->txt("language_loaded_local"), true);
693  } else {
694  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("language_error_read_local"), true);
695  }
696  break;
697 
698  // revert the database to the default language file
699  case "clear":
700  $lang_file = $this->object->getLangPath() . "/ilias_" . $this->object->key . ".lang";
701  if (is_file($lang_file) and is_readable($lang_file)) {
702  $this->object->importLanguageFile($lang_file, "replace");
703  $this->object->setLocal(false);
704  $this->tpl->setOnScreenMessage('success', $this->lng->txt("language_cleared_local"), true);
705  } else {
706  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("language_error_clear_local"), true);
707  }
708  break;
709 
710  // delete local additions in the datavase (langmode only)
711  case "delete_added":
712  ilObjLanguageExt::_deleteValues($this->object->key, $this->object->getAddedValues());
713  break;
714 
715  // merge local changes back to the global language file (langmode only)
716  case "merge":
717  $orig_file = $this->object->getLangPath() . "/ilias_" . $this->object->key . ".lang";
718  $copy_file = $this->object->getCustLangPath() . "/ilias_" . $this->object->key . ".lang";
719 
720  if (is_file($orig_file) and is_writable($orig_file)) {
721  // save a copy of the global language file
722  @copy($orig_file, $copy_file);
723 
724  // modify and write the new global file
725  $global_file_obj = $this->object->getGlobalLanguageFile();
726  $global_file_obj->setAllValues($this->object->getMergedValues());
727  $global_file_obj->setAllComments($this->object->getMergedRemarks());
728  $global_file_obj->write();
729  $this->tpl->setOnScreenMessage('success', $this->lng->txt("language_merged_global"), true);
730  } else {
731  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("language_error_write_global"), true);
732  }
733  break;
734 
735  // remove the local language file (langmode only)
736  case "remove_local_file":
737  $lang_file = $this->object->getCustLangPath() . "/ilias_" . $this->object->key . ".lang.local";
738 
739  if (!is_file($lang_file)) {
740  $this->object->setLocal(false);
741  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("language_error_local_missed"), true);
742  } elseif (@unlink($lang_file)) {
743  $this->object->setLocal(false);
744  $this->tpl->setOnScreenMessage('success', $this->lng->txt("language_local_file_deleted"), true);
745  } else {
746  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("language_error_delete_local"), true);
747  }
748  break;
749  }
750 
751  $this->ctrl->redirect($this, "maintain");
752  }
753 
757  public function settingsObject(): void
758  {
759  $form = $this->initNewSettingsForm();
760  $this->tpl->setContent($form->getHTML());
761  }
762 
766  public function saveSettingsObject(): void
767  {
768  global $DIC;
769  $ilSetting = $DIC->settings();
770 
771  $translate_key = "lang_translate_" . $this->object->key;
772 
773  $post_translation = $this->http->request()->getParsedBody()['translation'] ?? "";
774  // save and get the page translation setting
775  $translate = $ilSetting->get($translate_key, '0');
776  if (!is_null($post_translation) && $post_translation != $translate) {
777  $ilSetting->set($translate_key, $post_translation);
778  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"));
779  }
780  $form = $this->initNewSettingsForm();
781 
782  $this->tpl->setContent($form->getHTML());
783  }
784 
786  {
787  global $DIC;
788  $ilSetting = $DIC->settings();
789  $translate_key = "lang_translate_" . $this->object->key;
790  $translate = (bool) $ilSetting->get($translate_key, '0');
791 
792  $form = new ilPropertyFormGUI();
793  $form->setFormAction($this->ctrl->getFormAction($this));
794  $form->setTitle($this->lng->txt("language_settings"));
795  $form->setPreventDoubleSubmission(false);
796  $form->addCommandButton('saveSettings', $this->lng->txt("language_change_settings"));
797 
798  $ci = new ilCheckboxInputGUI($this->lng->txt("language_translation_enabled"), "translation");
799  $ci->setChecked($translate);
800  $ci->setInfo($this->lng->txt("language_note_translation"));
801  $form->addItem($ci);
802 
803  return $form;
804  }
805 
809  public function statisticsObject(): void
810  {
811  $statisticsTable = (new ilLanguageStatisticsTable(
812  $this->object,
813  $this->ui_factory,
814  $this->lng
815  ))->getTable();
816 
817  $this->tpl->setContent($this->ui_renderer->render($statisticsTable->withRequest($this->request)));
818  }
819 
824  public function getAdminTabs(): void
825  {
826  global $DIC;
827  $ilCtrl = $DIC->ctrl();
828  $cmd = $ilCtrl->getCmd();
829 
831  $this->tabs_gui->setBackTarget(
832  $this->lng->txt("back"),
833  $this->ctrl->getLinkTargetByClass("ilObjLanguageFolderGUI")
834  );
835 
836  $this->ctrl->setParameter($this, "obj_id", $this->id);
837  $this->tabs_gui->addTab(
838  "edit",
839  $this->lng->txt("edit"),
840  $this->ctrl->getLinkTarget($this, "view")
841  );
842 
843  $this->tabs_gui->addTab(
844  "export",
845  $this->lng->txt('export'),
846  $this->ctrl->getLinkTarget($this, "export")
847  );
848 
849  $this->tabs_gui->addTab(
850  "import",
851  $this->lng->txt("import"),
852  $this->ctrl->getLinkTarget($this, "import")
853  );
854 
855  $this->tabs_gui->addTab(
856  "maintain",
857  $this->lng->txt("language_maintain"),
858  $this->ctrl->getLinkTarget($this, "maintain")
859  );
860 
861  $this->tabs_gui->addTab(
862  "settings",
863  $this->lng->txt("settings"),
864  $this->ctrl->getLinkTarget($this, "settings")
865  );
866 
867  $this->tabs_gui->addTab(
868  "statistics",
869  $this->lng->txt("language_statistics"),
870  $this->ctrl->getLinkTarget($this, "statistics")
871  );
872 
873  switch ($cmd) {
874  case "":
875  case "view":
876  case "applyFilter":
877  case "resetFilter":
878  case "save":
879  $this->tabs_gui->activateTab("edit");
880  break;
881  default:
882  $this->tabs_gui->activateTab($cmd);
883  }
884  }
885  }
886 
891  protected function addAdminLocatorItems(bool $do_not_add_object = false): void
892  {
893  global $DIC;
894  $ilLocator = $DIC["ilLocator"];
895 
897  parent::addAdminLocatorItems(true); // #13881
898 
899  $ilLocator->addItem(
900  $this->lng->txt("languages"),
901  $this->ctrl->getLinkTargetByClass("ilobjlanguagefoldergui", "")
902  );
903 
904  $ilLocator->addItem(
905  $this->lng->txt("meta_l_" . $this->object->getTitle()),
906  $this->ctrl->getLinkTarget($this, "view")
907  );
908  }
909  }
910 
915  protected function setTitleAndDescription(): void
916  {
918  $this->tpl->setHeaderPageTitle($this->lng->txt("translation"));
919  $this->tpl->setTitle($this->lng->txt("translation") . " " . $this->lng->txt("meta_l_" . $this->object->key));
920  } else {
921  $this->tpl->setTitle($this->lng->txt("meta_l_" . $this->object->key));
922  }
923  $this->tpl->setTitleIcon(ilUtil::getImagePath("standard/icon_lngf.svg"), $this->lng->txt("obj_" . $this->object->getType()));
924  }
925 
926 
927  //
928  // new entries
929  //
930 
931  protected function buildMissingEntries(array $a_missing = null): string
932  {
933  global $DIC;
934  $ilCtrl = $DIC->ctrl();
935 
936  if (!count($a_missing)) {
937  return '';
938  }
939 
940  $res = array("<h3>" . $this->lng->txt("adm_missing_entries") . "</h3>", "<ul>");
941 
942  foreach ($a_missing as $entry) {
943  $ilCtrl->setParameter($this, "eid", $entry);
944  $res[] = '<li>' . $entry .
945  ' <a href="' . $ilCtrl->getLinkTarget($this, "addNewEntry") .
946  '">' . $this->lng->txt("adm_missing_entry_add_action") . '</a></li>';
947  $ilCtrl->setParameter($this, "eid", "");
948  }
949 
950  $res[] = "</ul>";
951 
952  return implode("\n", $res);
953  }
954 
955  public function addNewEntryObject(ilPropertyFormGUI $a_form = null): void
956  {
957  global $DIC;
958  $tpl = $DIC["tpl"];
959 
960  $id = "";
961  if ($this->http->wrapper()->query()->has("eid")) {
962  $id = trim($this->http->wrapper()->query()->retrieve("eid", $this->refinery->kindlyTo()->string()));
963  }
964  if (!$a_form) {
965  $a_form = $this->initAddNewEntryForm($id);
966  }
967 
968  $tpl->setContent($a_form->getHTML());
969  }
970 
971  protected function initAddNewEntryForm(string $a_id = null): ilPropertyFormGUI
972  {
973  global $DIC;
974  $ilCtrl = $DIC->ctrl();
975 
976  if (!$a_id) {
977  $a_id = $this->http->request()->getParsedBody()['id'] ?? "";
978  }
979 
980  if (!$a_id ||
981  !in_array($a_id, ilObjLanguageAccess::_getSavedTopics())) {
982  $ilCtrl->redirect($this, "view");
983  }
984 
985  $form = new ilPropertyFormGUI();
986  $form->setFormAction($ilCtrl->getFormAction($this, "saveNewEntry"));
987  $form->setTitle($this->lng->txt("adm_missing_entry_add"));
988 
990  $options = array_combine($mods, $mods);
991 
992  $mod = new ilSelectInputGUI(ucfirst($this->lng->txt("module")), "mod");
993  $mod->setOptions(array("" => $this->lng->txt("please_select")) + $options);
994  $mod->setRequired(true);
995  $form->addItem($mod);
996 
997  $id = new ilTextInputGUI(ucfirst($this->lng->txt("identifier")), "id");
998  $id->setValue($a_id);
999  $id->setDisabled(true);
1000  $form->addItem($id);
1001 
1002  foreach ($this->lng->getInstalledLanguages() as $lang_key) {
1003  $trans = new ilTextInputGUI($this->lng->txt("meta_l_" . $lang_key), "trans_" . $lang_key);
1004  if (in_array($lang_key, array("de", "en"))) {
1005  $trans->setRequired(true);
1006  }
1007  $form->addItem($trans);
1008  }
1009 
1010  $form->addCommandButton("saveNewEntry", $this->lng->txt("save"));
1011  $form->addCommandButton("view", $this->lng->txt("cancel"));
1012 
1013  return $form;
1014  }
1015 
1016  public function saveNewEntryObject(): void
1017  {
1018  global $DIC;
1019  $ilDB = $DIC->database();
1020  $ilCtrl = $DIC->ctrl();
1021  $ilUser = $DIC->user();
1022 
1023  $form = $this->initAddNewEntryForm();
1024  if ($form->checkInput()) {
1025  $mod = $form->getInput("mod");
1026  $id = $form->getInput("id");
1027 
1028  $lang = array();
1029  foreach ($this->lng->getInstalledLanguages() as $lang_key) {
1030  $trans = trim($form->getInput("trans_" . $lang_key));
1031  if ($trans) {
1032  // add single entry
1034  $mod,
1035  $id,
1036  $lang_key,
1037  $trans,
1038  gmdate("Y-m-d H:i:s"),
1039  $ilUser->getLogin()
1040  );
1041 
1042  // add to serialized module
1043  $set = $ilDB->query("SELECT lang_array FROM lng_modules" .
1044  " WHERE lang_key = " . $ilDB->quote($lang_key, "text") .
1045  " AND module = " . $ilDB->quote($mod, "text"));
1046  $row = $ilDB->fetchAssoc($set);
1047  $entries = unserialize($row["lang_array"], ["allowed_classes" => false]);
1048  if (is_array($entries)) {
1049  $entries[$id] = $trans;
1050  ilObjLanguage::replaceLangModule($lang_key, $mod, $entries);
1051  }
1052  }
1053  }
1054 
1055  $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
1056  $ilCtrl->redirect($this, "view");
1057  }
1058 
1059  $form->setValuesByPost();
1060  $this->addNewEntryObject($form);
1061  }
1062 
1066  protected function getSuccessMessage(): string
1067  {
1068  global $DIC;
1069  $f = $DIC->ui()->factory();
1070  $renderer = $DIC->ui()->renderer();
1071 
1072  return $renderer->render($f->messageBox()->success($this->lng->txt("language_variables_saved")));
1073  }
1074 
1075  private function getSession(): array
1076  {
1077  return ilSession::get("lang_ext_maintenance") ?? [];
1078  }
1079 } // END class.ilObjLanguageExtGUI
downloadObject()
Download a language file.
static get(string $a_var)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$res
Definition: ltiservices.php:69
$renderer
assignObject()
Assign the extended language object.
getSuccessMessage()
Get success message after variables were saved.
This class represents a selection list property in a property form.
uploadObject()
Process an uploaded language file.
getUserLanguage()
Return language of user.
static _isPageTranslation()
Check if the current request is a page translation.
static _getSavedModules()
Get the stored modules from the user session.
This class represents a file property in a property form.
initAddNewEntryForm(string $a_id=null)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
getViewTable()
Get the table to view language entries.
static _lookupId(string $a_key)
Lookup the object ID for a language key.
cancelObject()
Cancel the current action.
loadLanguageModule(string $a_module)
Load language module.
viewObject()
viewObject container presentation for "administration -> repository, trash, permissions" ...
setVariable(string $variable, $value='')
Sets the given variable to the given value.
Class ilObjLanguageExtGUI.
static deliverData(string $a_data, string $a_filename, string $mime="application/octet-stream")
exportObject()
Show the screen to export a language file.
static _checkMaintenance()
Permission check for language maintenance (import/export)
saveSettingsObject()
Set the language settings.
const ILIAS_VERSION
addAdminLocatorItems(bool $do_not_add_object=false)
Set the locator for admin mode (Overwritten from ilObjectGUI, called by prepareOutput) ...
ilLanguage $lng
importObject()
Show the screen to import a language file.
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.
static http()
Fetches the global http state from ILIAS.
This class represents a property in a property form.
ilGlobalTemplateInterface $tpl
__construct($a_data, int $a_id=0, bool $a_call_by_reference=false)
Constructor.
setContent(string $a_html)
Sets content for standard template.
Class ilObjLanguageExt.
Class ilObjectGUI Basic methods of all Output classes.
getAdminTabs()
Get tabs for admin mode (Overwritten from ilObjectGUI, called by prepareOutput)
global $DIC
Definition: shib_login.php:25
static _deleteValues(string $a_lang_key, array $a_values=array())
Delete a set of translation in the database.
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
$comments
buildMissingEntries(array $a_missing=null)
statisticsObject()
Print out statistics about the language.
settingsObject()
View the language settings.
setTitleAndDescription()
Set the Title and the description (Overwritten from ilObjectGUI, called by prepareOutput) ...
static _getSavedTopics()
Get the stored topics from the user session.
setRequired(bool $a_required)
$filename
Definition: buildRTE.php:78
saveObject()
Save the changed translations.
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 ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
Class ilLanguageFile.
global $ilSetting
Definition: privfeed.php:32
__construct(Container $dic, ilPlugin $plugin)
static _getRemarks(string $a_lang_key, bool $a_all_changed=false)
Get all remarks of a language.
static replaceLangModule(string $a_key, string $a_module, array $a_array)
Replace language module array.
addNewEntryObject(ilPropertyFormGUI $a_form=null)
viewObject(int $changesSuccessBool=0)
Show the edit screen.
maintainObject()
Process the language maintenance.
$post
Definition: ltitoken.php:46
getId()
get the language object id (needed for filter serialization) Return language object id ...
static set(string $a_var, $a_val)
Set a value.
static _saveValues(string $a_lang_key, array $a_values=array(), array $a_remarks=array())
Save a set of translation in the database.