ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
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 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
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
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
$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
$lang
Definition: xapiexit.php:25