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