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