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