ILIAS  trunk Revision v13.0_alpha-52-g21c366bbdd4
class.ilAdvancedMDSettingsGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22use ILIAS\UI\Factory as UIFactory;
23use ILIAS\Refinery\Factory as RefineryFactory;
25use Psr\Http\Message\RequestInterface;
27
34{
35 public const CONTEXT_ADMINISTRATION = 1;
36 public const CONTEXT_OBJECT = 2;
37
38 protected const TAB_RECORD_SETTINGS = 'editRecord';
39 protected const TAB_TRANSLATION = 'translations';
40
45 private $context = null;
47 protected ?ilPropertyFormGUI $form = null;
48
49 protected ilLanguage $lng;
51 protected ilCtrl $ctrl;
52 protected RequestInterface $request;
54 protected RefineryFactory $refinery;
55 protected ilDBInterface $db;
56
58 protected UIFactory $ui_factory;
61 protected ilLogger $logger;
62 protected ilObjUser $user;
63 protected ilAccess $access;
64
66 protected ?ilAdvancedMDRecord $record = null;
67
68 private string $active_language = '';
69 protected int $ref_id;
70 protected ?int $obj_id;
71 protected ?string $obj_type = null;
75 protected $sub_type = null;
76
81 public function __construct(int $a_context, int $a_ref_id, ?string $a_obj_type = null, $a_sub_type = null)
82 {
83 global $DIC;
84
85 $this->ctrl = $DIC->ctrl();
86 $this->lng = $DIC->language();
87 $this->lng->loadLanguageModule('meta');
88 $this->tpl = $DIC->ui()->mainTemplate();
89 $this->tabs_gui = $DIC->tabs();
90
91 $this->refinery = $DIC->refinery();
92 $this->toolbar = $DIC->toolbar();
93 $this->ui_factory = $DIC->ui()->factory();
94 $this->ui_renderer = $DIC->ui()->renderer();
95 $this->request = $DIC->http()->request();
96 $this->http = $DIC->http();
97 $this->db = $DIC->database();
98 $this->user = $DIC->user();
99 $this->access = $DIC->access();
100
102 $this->logger = $DIC->logger()->amet();
103
104 $this->context = $a_context;
106 $this->context,
107 $a_ref_id,
108 $a_obj_type,
109 $a_sub_type
110 );
111
113 $this->permissions = ilAdvancedMDPermissionHelper::getInstance($DIC->user()->getId(), $this->ref_id);
114 }
115
116 protected function getRecordIdFromQuery(): ?int
117 {
118 if ($this->http->wrapper()->query()->has('record_id')) {
119 return $this->http->wrapper()->query()->retrieve(
120 'record_id',
121 $this->refinery->kindlyTo()->int()
122 );
123 }
124 return null;
125 }
126
127 protected function getRecordIdsFromPost(): SplFixedArray
128 {
129 if ($this->http->wrapper()->post()->has('record_id')) {
130 return SplFixedArray::fromArray(
131 $this->http->wrapper()->post()->retrieve(
132 'record_id',
133 $this->refinery->kindlyTo()->listOf(
134 $this->refinery->kindlyTo()->int()
135 )
136 )
137 );
138 }
139 return new SplFixedArray(0);
140 }
141
142 protected function getFieldIdFromQuery(): ?int
143 {
144 if ($this->http->wrapper()->query()->has('field_id')) {
145 return $this->http->wrapper()->query()->retrieve(
146 'field_id',
147 $this->refinery->kindlyTo()->int()
148 );
149 }
150 return null;
151 }
152
153 protected function getFieldIdsFromPost(): SplFixedArray
154 {
155 if ($this->http->wrapper()->post()->has('field_id')) {
156 return SplFixedArray::fromArray(
157 $this->http->wrapper()->post()->retrieve(
158 'field_id',
159 $this->refinery->kindlyTo()->listOf(
160 $this->refinery->kindlyTo()->int()
161 )
162 )
163 );
164 }
165 return new SplFixedArray(0);
166 }
167
168 protected function getFileIdsFromPost(): SplFixedArray
169 {
170 if ($this->http->wrapper()->post()->has('file_id')) {
171 return SplFixedArray::fromArray(
172 $this->http->wrapper()->post()->retrieve(
173 'file_id',
174 $this->refinery->kindlyTo()->dictOf(
175 $this->refinery->kindlyTo()->string()
176 )
177 )
178 );
179 }
180 return new SplFixedArray(0);
181 }
182
183 protected function getFieldTypeFromQuery(): ?int
184 {
185 if ($this->http->wrapper()->query()->has('ftype')) {
186 return $this->http->wrapper()->query()->retrieve(
187 'ftype',
188 $this->refinery->kindlyTo()->int()
189 );
190 }
191 return null;
192 }
193
194 protected function getFieldTypeFromPost(): ?int
195 {
196 if ($this->http->wrapper()->post()->has('ftype')) {
197 return $this->http->wrapper()->post()->retrieve(
198 'ftype',
199 $this->refinery->kindlyTo()->int()
200 );
201 }
202 return null;
203 }
204
205 protected function getOidFromQuery(): ?string
206 {
207 $name = 'advmd_oid';
208 if ($this->http->wrapper()->query()->has($name)) {
209 return $this->http->wrapper()->query()->retrieve(
210 $name,
211 $this->refinery->kindlyTo()->string()
212 );
213 }
214
215 return null;
216 }
217
218 protected function getOidFromTable(): ?string
219 {
220 $name = 'advmd_oid_table';
221 if ($this->http->wrapper()->query()->has($name)) {
222 $oids = $this->http->wrapper()->query()->retrieve(
223 $name,
224 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string())
225 );
226 return (string) ($oids[0] ?? '');
227 }
228
229 return null;
230 }
231
235 protected function getPositionsFromPost(): array
236 {
237 if ($this->http->wrapper()->post()->has('position')) {
238 return $this->http->wrapper()->post()->retrieve(
239 'position',
240 $this->refinery->kindlyTo()->dictOf(
241 $this->refinery->byTrying([
242 $this->refinery->kindlyTo()->float(),
243 $this->refinery->always(0)
244 ])
245 )
246 );
247 }
248 return [];
249 }
250
255 {
256 return $this->permissions;
257 }
258
262 protected function initContextParameters(
263 int $context,
264 int $ref_id,
265 ?string $obj_type,
267 ): void {
269 $this->ref_id = $ref_id;
270 $this->obj_id = null;
271 $this->obj_type = null;
272 $this->sub_type = null;
273 } else {
274 $this->ref_id = $ref_id;
275 $this->obj_id = ilObject::_lookupObjId($ref_id);
276 $this->obj_type = $obj_type;
277 $this->sub_type = $sub_type;
278 }
279 }
280
281 public function executeCommand(): void
282 {
283 $next_class = $this->ctrl->getNextClass($this);
284 $cmd = $this->ctrl->getCmd();
285 switch ($next_class) {
286 case strtolower(ilAdvancedMDRecordTranslationGUI::class):
287 $record = $this->initRecordObject();
288 $this->setRecordSubTabs(1, true);
289 $int_gui = new \ilAdvancedMDRecordTranslationGUI($record);
290 $this->ctrl->forwardCommand($int_gui);
291 break;
292
293 case "ilpropertyformgui":
294 $this->initRecordObject();
295 $this->initForm(
296 $this->record->getRecordId() > 0 ? 'edit' : 'create'
297 );
298 $GLOBALS['DIC']->ctrl()->forwardCommand($this->form);
299 break;
300
301 default:
302 if (!$cmd) {
303 $cmd = 'showRecords';
304 }
305 $this->$cmd();
306 }
307 }
308
309 public function showRecords(): void
310 {
311 $this->setSubTabs($this->context);
312
313 $perm = $this->getPermissions()->hasPermissions(
315 $this->ref_id,
316 array(
319 )
320 );
321
323 $button = $this->ui_factory->button()->standard(
324 $this->lng->txt('add'),
325 $this->ctrl->getLinkTargetByClass(strtolower(self::class), "createRecord")
326 );
327 $this->toolbar->addComponent($button);
328
330 $this->toolbar->addSeparator();
331 }
332 }
333
335 $button = $this->ui_factory->button()->standard(
336 $this->lng->txt('import'),
337 $this->ctrl->getLinkTargetByClass(strtolower(self::class), "importRecords")
338 );
339 $this->toolbar->addComponent($button);
340 }
341
342 $obj_type_context = ($this->obj_id > 0)
343 ? ilObject::_lookupType($this->obj_id)
344 : "";
345 $table_gui = new ilAdvancedMDRecordTableGUI(
346 $this,
347 "showRecords",
348 $this->getPermissions(),
349 $obj_type_context
350 );
351 $table_gui->setTitle($this->lng->txt("md_record_list_table"));
352 $table_gui->setData($this->getParsedRecordObjects());
353
354 // permissions?
355 //$table_gui->addCommandButton('createRecord',$this->lng->txt('add'));
356 $table_gui->addMultiCommand("exportRecords", $this->lng->txt('export'));
357 $table_gui->setSelectAllCheckbox("record_id");
358
359 if ($this->access->checkAccess('write', '', $this->ref_id)) {
360 $table_gui->addMultiCommand("confirmDeleteRecords", $this->lng->txt("delete"));
361 $table_gui->addCommandButton("updateRecords", $this->lng->txt("save"));
362 }
363
364 $this->tpl->setContent($table_gui->getHTML());
365 }
366
367 protected function showPresentation(): void
368 {
369 $this->setSubTabs($this->context);
370 $form = $this->initFormSubstitutions();
371 if ($form instanceof ilPropertyFormGUI) {
372 $this->tabs_gui->setSubTabActive('md_adv_presentation');
373 $this->tpl->setContent($this->form->getHTML());
374 return;
375 }
376 $this->showRecords();
377 }
378
383 public function updateSubstitutions(): void
384 {
385 if (!$this->access->checkAccess('write', '', $this->ref_id)) {
386 $this->ctrl->redirect($this, "showPresentation");
387 }
388
389 $form = $this->initFormSubstitutions();
390 if (!$form instanceof ilPropertyFormGUI) {
391 $this->ctrl->redirect($this, 'showPresentation');
392 return;
393 }
394 if (!$form->checkInput()) {
395 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'), true);
396 $this->ctrl->redirect($this, "showPresentation");
397 }
398
399 if (!$visible_records = ilAdvancedMDRecord::_getAllRecordsByObjectType()) {
400 return;
401 }
402
403 foreach ($visible_records as $obj_type => $record) {
405 $sub->enableDescription((bool) $form->getInput('enabled_desc_' . $obj_type));
406 $sub->enableFieldNames((bool) $form->getInput('enabled_field_names_' . $obj_type));
407
409 $definitions = $sub->sortDefinitions($definitions);
410
411 // gather existing data
412 $counter = 1;
413 $old_sub = array();
414 foreach ($definitions as $def) {
415 $field_id = $def->getFieldId();
416 $old_sub[$field_id] = array(
417 "active" => $sub->isSubstituted($field_id),
418 "pos" => $counter++,
419 "bold" => $sub->isBold($field_id),
420 "newline" => $sub->hasNewline($field_id)
421 );
422 }
423
424 $sub->resetSubstitutions();
425
426 $new_sub = [];
427 foreach ($definitions as $def) {
428 $field_id = $def->getFieldId();
429 $old = $old_sub[$field_id];
430
431 $active = (bool) $form->getInput('show_' . $obj_type . '_' . $field_id);
432
433 if ($active) {
434 $new_sub[$field_id] = $old;
435 $new_sub[$field_id]['pos'] = (int) $form->getInput('position_' . $obj_type . '_' . $field_id);
436 $new_sub[$field_id]['bold'] = (bool) $form->getInput('bold_' . $obj_type . '_' . $field_id);
437 $new_sub[$field_id]['newline'] = (bool) $form->getInput('newline_' . $obj_type . '_' . $field_id);
438 }
439 }
440
441 if (sizeof($new_sub)) {
442 $new_sub = ilArrayUtil::sortArray($new_sub, "pos", "asc", true, true);
443 foreach ($new_sub as $field_id => $field) {
444 $sub->appendSubstitution($field_id, (bool) $field["bold"], (bool) $field["newline"]);
445 }
446 }
447 $sub->update();
448 }
449
450 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
451 $this->ctrl->redirect($this, "showPresentation");
452 }
453
458 public function exportRecords(): void
459 {
460 $record_ids = $this->getRecordIdsFromPost();
461 if (!count($record_ids)) {
462 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
463 $this->showRecords();
464 return;
465 }
466
467 // all records have to be exportable
468 $fail = array();
469 foreach ($record_ids as $record_id) {
470 if (!$this->getPermissions()->hasPermission(
472 (int) $record_id,
474 )) {
475 $record = ilAdvancedMDRecord::_getInstanceByRecordId($record_id);
476 $fail[] = $record->getTitle();
477 }
478 }
479 if ($fail) {
480 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_perm_copy') . " " . implode(", ", $fail), true);
481 $this->ctrl->redirect($this, "showRecords");
482 }
483
484 $xml_writer = new ilAdvancedMDRecordXMLWriter((array) $record_ids);
485 $xml_writer->write();
486
487 $export_files = new ilAdvancedMDRecordExportFiles(
488 $this->user->getId(),
489 $this->context === self::CONTEXT_ADMINISTRATION ? null : new ObjectId($this->obj_id)
490 );
491 $export_files->create($xml_writer->xmlDumpMem(false));
492
493 $this->tpl->setOnScreenMessage('success', $this->lng->txt('md_adv_records_exported'));
494 $this->showFiles();
495 }
496
500 protected function showFiles(): void
501 {
502 $this->setSubTabs($this->context);
503 $this->tabs_gui->setSubTabActive('md_adv_file_list');
504
506 $this->user->getId(),
507 $this->context === self::CONTEXT_ADMINISTRATION ? null : new ObjectId($this->obj_id)
508 );
509 $file_data = $files->readFilesInfo();
510
511 $table_gui = new ilAdvancedMDRecordExportFilesTableGUI($this, "showFiles");
512 $table_gui->setTitle($this->lng->txt("md_record_export_table"));
513 $table_gui->parseFiles($file_data);
514 $table_gui->addMultiCommand("downloadFile", $this->lng->txt('download'));
515
516 if ($GLOBALS['DIC']->access()->checkAccess('write', '', $this->ref_id)) {
517 $table_gui->addMultiCommand("confirmDeleteFiles", $this->lng->txt("delete"));
518 }
519 $table_gui->setSelectAllCheckbox("file_id");
520
521 $this->tpl->setContent($table_gui->getHTML());
522 }
523
529 public function downloadFile(): void
530 {
531 $file_ids = $this->getFileIdsFromPost();
532 if (count($file_ids) !== 1) {
533 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('md_adv_select_one_file'));
534 $this->showFiles();
535 return;
536 }
538 $this->user->getId(),
539 $this->context === self::CONTEXT_ADMINISTRATION ? null : new ObjectId($this->obj_id)
540 );
541 $files->download($file_ids[0], 'ilias_meta_data_record.xml');
542 }
543
548 public function confirmDeleteFiles(): void
549 {
550 $file_ids = $this->getFileIdsFromPost();
551 if (count($file_ids) !== 1) {
552 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
553 $this->showFiles();
554 return;
555 }
556
557 $c_gui = new ilConfirmationGUI();
558 $c_gui->setFormAction($this->ctrl->getFormAction($this, "deleteFiles"));
559 $c_gui->setHeaderText($this->lng->txt("md_adv_delete_files_sure"));
560 $c_gui->setCancel($this->lng->txt("cancel"), "showFiles");
561 $c_gui->setConfirm($this->lng->txt("confirm"), "deleteFiles");
562
564 $this->user->getId(),
565 $this->context === self::CONTEXT_ADMINISTRATION ? null : new ObjectId($this->obj_id)
566 );
567 $file_data = $files->readFilesInfo();
568
569 // add items to delete
570 foreach ($file_ids as $file_id) {
571 $info = $file_data[$file_id];
572 $c_gui->addItem(
573 "file_id[]",
574 (string) $file_id,
575 is_array($info['name'] ?? false) ? implode(',', $info['name']) : 'No Records'
576 );
577 }
578 $this->tpl->setContent($c_gui->getHTML());
579 }
580
586 public function deleteFiles(): void
587 {
588 $file_ids = $this->getFileIdsFromPost();
589 if (count($file_ids) === 0) {
590 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
591 $this->showFiles();
592 return;
593 }
594
595 if (!$GLOBALS['DIC']->access()->checkAccess('write', '', $this->ref_id)) {
596 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true);
597 $GLOBALS['DIC']->ctrl()->redirect($this, 'showFiles');
598 }
599
601 $this->user->getId(),
602 $this->context === self::CONTEXT_ADMINISTRATION ? null : new ObjectId($this->obj_id)
603 );
604 foreach ($file_ids as $file_id) {
605 $files->deleteByFileId(
606 $this->user->getId(),
607 $file_id
608 );
609 }
610 $this->tpl->setOnScreenMessage('success', $this->lng->txt('md_adv_deleted_files'));
611 $this->showFiles();
612 }
613
618 public function confirmDeleteRecords(): void
619 {
620 $this->initRecordObject();
621 $this->setRecordSubTabs();
622
623 $record_ids = $this->getRecordIdsFromPost();
624 if (!count($record_ids)) {
625 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
626 $this->showRecords();
627 return;
628 }
629
630 $c_gui = new ilConfirmationGUI();
631
632 // set confirm/cancel commands
633 $c_gui->setFormAction($this->ctrl->getFormAction($this, "deleteRecords"));
634 $c_gui->setHeaderText($this->lng->txt("md_adv_delete_record_sure"));
635 $c_gui->setCancel($this->lng->txt("cancel"), "showRecords");
636 $c_gui->setConfirm($this->lng->txt("confirm"), "deleteRecords");
637
638 // add items to delete
639 foreach ($record_ids as $record_id) {
640 $record = ilAdvancedMDRecord::_getInstanceByRecordId($record_id);
641 $c_gui->addItem("record_id[]", (string) $record_id, $record->getTitle() ?: 'No Title');
642 }
643 $this->tpl->setContent($c_gui->getHTML());
644 }
645
650 public function deleteRecords(): void
651 {
652 $record_ids = $this->getRecordIdsFromPost();
653 if (!count($record_ids)) {
654 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
655 $this->showRecords();
656 return;
657 }
658
659 // all records have to be deletable
660 $fail = array();
661 foreach ($record_ids as $record_id) {
662 // must not delete global records in local context
663 if ($this->context == self::CONTEXT_OBJECT) {
664 $record = ilAdvancedMDRecord::_getInstanceByRecordId($record_id);
665 if (!$record->getParentObject()) {
666 $fail[] = $record->getTitle();
667 }
668 }
669
670 if (!$this->getPermissions()->hasPermission(
672 (int) $record_id,
674 )) {
675 $record = ilAdvancedMDRecord::_getInstanceByRecordId($record_id);
676 $fail[] = $record->getTitle();
677 }
678 }
679 if ($fail) {
680 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_perm_delete') . " " . implode(", ", $fail), true);
681 $this->ctrl->redirect($this, "showRecords");
682 }
683
684 foreach ($record_ids as $record_id) {
685 $record = ilAdvancedMDRecord::_getInstanceByRecordId($record_id);
686 $record->delete();
687 }
688 $this->tpl->setOnScreenMessage('success', $this->lng->txt('md_adv_deleted_records'), true);
689 $this->ctrl->redirect($this, "showRecords");
690 }
691
697 public function updateRecords(): void
698 {
699 // sort positions and renumber
700 $positions = $this->getPositionsFromPost();
701 $records = $this->getParsedRecordObjects();
702
703 $all_positions = $positions;
704 foreach ($records as $record) {
705 if (!array_key_exists($record['id'], $all_positions)) {
706 $all_positions[$record['id']] = $record['position'];
707 }
708 }
709 asort($all_positions, SORT_NUMERIC);
710
711 $sorted_positions = [];
712 $i = 1;
713 foreach ($all_positions as $record_id => $pos) {
714 $sorted_positions[(int) $record_id] = $i++;
715 }
716 $selected_global = [];
717
718 $post_active = (array) ($this->http->request()->getParsedBody()['active'] ?? []);
719 if ($this->obj_id > 0) {
721 }
722 foreach ($records as $item) {
723 // BT 35518: this is kind of a hacky solution to skip items not in the table due to pagination
724 $is_on_page = array_key_exists($item['id'], $positions);
725
726 $perm = $this->getPermissions()->hasPermissions(
728 (int) $item['id'],
729 [
731 [
734 ]
735 ]
736 );
737
738 $record_obj = ilAdvancedMDRecord::_getInstanceByRecordId($item['id']);
739
740 if (
742 $is_on_page
743 ) {
744 $obj_types = array();
745 $post_object_types = (array) ($this->http->request()->getParsedBody()['obj_types'] ?? []);
746 if (is_array($post_object_types[$record_obj->getRecordId()] ?? false)) {
747 foreach ($post_object_types[$record_obj->getRecordId()] as $type => $status) {
748 if ($status) {
749 $type = explode(":", $type);
750 $obj_types[] = array(
751 "obj_type" => ilUtil::stripSlashes($type[0]),
752 "sub_type" => ilUtil::stripSlashes($type[1]),
753 "optional" => ((int) $status == 2)
754 );
755 }
756 }
757 }
758
759 // global records in global administration and local records in local administration
760 if (!$item['readonly']) {
761 // table adv_md_record_objs
762 $record_obj->setAssignedObjectTypes($obj_types);
763 } else { // global records in local administration
764 foreach ($obj_types as $t) {
765 // table adv_md_obj_rec_select
766 ilAdvancedMDRecord::saveObjRecSelection($this->obj_id, $t["sub_type"], [$record_obj->getRecordId()], false);
767 }
768 }
769 }
770
771 if ($this->context == self::CONTEXT_ADMINISTRATION) {
772 if (
774 $is_on_page
775 ) {
776 $record_obj->setActive(isset($post_active[$record_obj->getRecordId()]));
777 }
778
779 $record_obj->setGlobalPosition((int) $sorted_positions[$record_obj->getRecordId()]);
780 $record_obj->update();
781 } elseif (
783 $is_on_page
784 ) {
785 // global, optional record
786 if ($item['readonly'] &&
787 $item['optional'] &&
788 ($post_active[$item['id']] ?? false)) {
789 $selected_global[] = $item['id'];
790 } elseif ($item['local']) {
791 $record_obj = ilAdvancedMDRecord::_getInstanceByRecordId($item['id']);
792 $record_obj->setActive((bool) ($post_active[$item['id']] ?? false));
793 $record_obj->update();
794 }
795 }
796
797 // save local sorting
798 if ($this->context == self::CONTEXT_OBJECT) {
799 $local_position = new \ilAdvancedMDRecordObjectOrdering(
800 $item['id'],
801 $this->obj_id,
802 $this->db
803 );
804 $local_position->setPosition((int) $sorted_positions[$item['id']]);
805 $local_position->save();
806 }
807 }
808
809 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
810 $this->ctrl->redirect($this, "showRecords");
811 }
812
813 public function confirmDeleteFields(): void
814 {
815 $field_ids = $this->getFieldIdsFromPost();
816 if (!count($field_ids)) {
817 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
818 $this->editFields();
819 return;
820 }
821
822 $this->initRecordObject();
823 $this->setRecordSubTabs(2);
824
825 $c_gui = new ilConfirmationGUI();
826
827 // set confirm/cancel commands
828 $c_gui->setFormAction($this->ctrl->getFormAction($this, "deleteFields"));
829 $c_gui->setHeaderText($this->lng->txt("md_adv_delete_fields_sure"));
830 $c_gui->setCancel($this->lng->txt("cancel"), "editFields");
831 $c_gui->setConfirm($this->lng->txt("confirm"), "deleteFields");
832
833 // add items to delete
834 foreach ($field_ids as $field_id) {
836 $c_gui->addItem("field_id[]", (string) $field_id, $field->getTitle() ?: 'No Title');
837 }
838 $this->tpl->setContent($c_gui->getHTML());
839 }
840
841 public function deleteFields(): void
842 {
843 $this->ctrl->saveParameter($this, 'record_id');
844
845 $field_ids = $this->getFieldIdsFromPost();
846 if (!count($field_ids)) {
847 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
848 $this->editFields();
849 return;
850 }
851
852 // all fields have to be deletable
853 $fail = array();
854 foreach ($field_ids as $field_id) {
855 if (!$this->getPermissions()->hasPermission(
857 (int) $field_id,
859 )) {
861 $fail[] = $field->getTitle();
862 }
863 }
864 if ($fail) {
865 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_perm_delete') . " " . implode(", ", $fail), true);
866 $this->ctrl->redirect($this, "editFields");
867 }
868
869 foreach ($field_ids as $field_id) {
871 $field->delete();
872 }
873 $this->tpl->setOnScreenMessage('success', $this->lng->txt('md_adv_deleted_fields'), true);
874 $this->ctrl->redirect($this, "editFields");
875 }
876
877 public function editRecord(?ilPropertyFormGUI $form = null): void
878 {
879 $record_id = $this->getRecordIdFromQuery();
880 if (!$record_id) {
881 $this->ctrl->redirect($this, 'showRecords');
882 }
883 $this->initRecordObject();
884 $this->setRecordSubTabs(1, true);
885 $this->tabs_gui->activateTab(self::TAB_RECORD_SETTINGS);
886
887 if (!$form instanceof ilPropertyFormGUI) {
888 $this->initLanguage($record_id);
889 $this->showLanguageSwitch($record_id, 'editRecord');
890 $this->initForm('edit');
891 }
892 $this->tpl->setContent($this->form->getHTML());
893 }
894
895 protected function editFields(): void
896 {
897 $record_id = $this->getRecordIdFromQuery();
898 if (!$record_id) {
899 $this->ctrl->redirect($this, 'showRecords');
900 }
901 $this->ctrl->saveParameter($this, 'record_id');
902 $this->initRecordObject();
903 $this->setRecordSubTabs();
904 $this->initLanguage($record_id);
905 $this->showLanguageSwitch($record_id, 'editFields');
906
907 $perm = $this->getPermissions()->hasPermissions(
909 (int) $this->record->getRecordId(),
910 array(
912 ,
914 )
915 );
916
917 $filter_warn = [];
919 // type selection
920 $field_buttons = [];
921 foreach (ilAdvancedMDFieldDefinition::getValidTypes() as $type) {
922 $field = ilAdvancedMDFieldDefinition::getInstance(null, $type);
923
924 $this->ctrl->setParameter($this, 'ftype', $type);
925 $create_link = $this->ctrl->getLinkTarget($this, 'createField');
926 $this->ctrl->clearParameterByClass(strtolower(self::class), 'ftype');
927
928 $field_buttons[] = $this->ui_factory->button()->shy(
929 $this->lng->txt($field->getTypeTitle()),
930 $create_link
931 );
932
933 if (!$field->isFilterSupported()) {
934 $filter_warn[] = $this->lng->txt($field->getTypeTitle());
935 }
936 }
937
938 if (count($this->toolbar->getItems())) {
939 $this->toolbar->addSeparator();
940 }
941
942 $dropdown = $this->ui_factory->dropdown()
943 ->standard($field_buttons)
944 ->withLabel($this->lng->txt('meta_advmd_add_field'));
945 $this->toolbar->addComponent($dropdown);
946 }
947
948 // #17092
949 if (sizeof($filter_warn)) {
950 $this->tpl->setOnScreenMessage('info', sprintf($this->lng->txt("md_adv_field_filter_warning"), implode(", ", $filter_warn)));
951 }
952
953 // show field table
955 $this->record->getRecordId(),
956 false,
957 $this->active_language
958 );
959
960 $table_gui = new ilAdvancedMDFieldTableGUI(
961 $this,
962 'editFields',
963 $this->getPermissions(),
965 $this->record->getDefaultLanguage()
966 );
967 $table_gui->setTitle($this->lng->txt("md_adv_field_table"));
968 $table_gui->parseDefinitions($fields);
969 if (sizeof($fields)) {
970 $table_gui->addCommandButton("updateFields", $this->lng->txt("save"));
971 }
972 $table_gui->addCommandButton("showRecords", $this->lng->txt('cancel'));
973 $table_gui->addMultiCommand("confirmDeleteFields", $this->lng->txt("delete"));
974 $table_gui->setSelectAllCheckbox("field_id");
975
976 $this->tpl->setContent($table_gui->getHTML());
977 }
978
983 public function updateFields(): void
984 {
985 $this->ctrl->saveParameter($this, 'record_id');
986 $positions = $this->getPositionsFromPost();
987 asort($positions, SORT_NUMERIC);
988 $record_id = $this->getRecordIdFromQuery();
989 if (!$record_id) {
990 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
991 $this->editFields();
992 return;
993 }
994
996
997 if ($this->getPermissions()->hasPermission(
999 $record_id,
1001 )) {
1002 $positions_flipped = array_flip(array_keys($positions));
1003 foreach ($fields as $field) {
1004 $field->setPosition((int) $positions_flipped[$field->getFieldId()]);
1005 $field->update();
1006 }
1007 }
1008
1009 foreach ($fields as $field) {
1010 if ($this->getPermissions()->hasPermission(
1012 (int) $field->getFieldId(),
1015 )) {
1016 $post_searchable = (array) ($this->http->request()->getParsedBody()['searchable'] ?? []);
1017 $field->setSearchable((bool) ($post_searchable[$field->getFieldId()] ?? false));
1018 $field->update();
1019 }
1020 }
1021
1022 $language = $this->request->getQueryParams()['mdlang'] ?? false;
1023 if ($language) {
1024 $this->ctrl->setParameter($this, 'mdlang', $this->request->getQueryParams()['mdlang']);
1025 }
1026 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
1027 $this->ctrl->redirect($this, "editFields");
1028 }
1029
1035 public function updateRecord(): void
1036 {
1037 $record_id = $this->getRecordIdFromQuery();
1038 if (!$record_id) {
1039 $this->ctrl->redirect($this, 'showRecords');
1040 }
1041 $this->initRecordObject();
1042 $this->initLanguage($record_id);
1043 $this->showLanguageSwitch($record_id, 'editRecord');
1044
1045 $form = $this->initForm('edit');
1046 if (!$this->form->checkInput()) {
1047 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
1048 $this->form->setValuesByPost();
1049 $this->editRecord($this->form);
1050 return;
1051 }
1052
1053 $this->loadRecordFormData($form);
1054 $this->record->update();
1055
1056 $translations = ilAdvancedMDRecordTranslations::getInstanceByRecordId($this->record->getRecordId());
1057 $translations->updateTranslations(
1058 $this->active_language,
1059 $this->form->getInput('title'),
1060 $this->form->getInput('desc')
1061 );
1062
1063 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
1064 $this->ctrl->redirect($this, 'editRecord');
1065 }
1066
1072 public function createRecord(?ilPropertyFormGUI $form = null): void
1073 {
1074 $this->initRecordObject();
1075 $this->setRecordSubTabs();
1076 if (!$form instanceof ilPropertyFormGUI) {
1077 $this->initForm('create');
1078 }
1079 $this->tpl->setContent($this->form->getHTML());
1080 }
1081
1082 protected function importRecords(): void
1083 {
1084 $this->initRecordObject();
1085 $this->setRecordSubTabs();
1086
1087 // Import Table
1088 $this->initImportForm();
1089 $this->tpl->setContent($this->import_form->getHTML());
1090 }
1091
1095 protected function setRecordSubTabs(int $level = 1, bool $show_settings = false): void
1096 {
1097 $this->tabs_gui->clearTargets();
1098 $this->tabs_gui->clearSubTabs();
1099
1100 if ($level == 1) {
1101 $this->tabs_gui->setBackTarget(
1102 $this->lng->txt('md_adv_record_list'),
1103 $this->ctrl->getLinkTarget($this, 'showRecords')
1104 );
1105
1106 if ($show_settings) {
1107 $this->tabs_gui->addTab(
1108 self::TAB_RECORD_SETTINGS,
1109 $this->lng->txt('settings'),
1110 $this->ctrl->getLinkTarget($this, self::TAB_RECORD_SETTINGS)
1111 );
1112 $this->ctrl->setParameterByClass(
1113 strtolower(\ilAdvancedMDRecordTranslationGUI::class),
1114 'record_id',
1115 $this->record->getRecordId()
1116 );
1117 $this->lng->loadLanguageModule('obj');
1118 $this->tabs_gui->addTab(
1119 self::TAB_TRANSLATION,
1120 $this->lng->txt('obj_multilinguality'),
1121 $this->ctrl->getLinkTargetByClass(
1122 strtolower(\ilAdvancedMDRecordTranslationGUI::class),
1123 ''
1124 )
1125 );
1126 }
1127 }
1128 if ($level == 2) {
1129 $this->tabs_gui->setBack2Target(
1130 $this->lng->txt('md_adv_record_list'),
1131 $this->ctrl->getLinkTarget($this, 'showRecords')
1132 );
1133 $this->tabs_gui->setBackTarget(
1134 $this->lng->txt('md_adv_field_list'),
1135 $this->ctrl->getLinkTarget($this, 'editFields')
1136 );
1137 }
1138 }
1139
1140 protected function initImportForm(): void
1141 {
1142 if (is_object($this->import_form)) {
1143 return;
1144 }
1145
1146 $this->import_form = new ilPropertyFormGUI();
1147 $this->import_form->setMultipart(true);
1148 $this->import_form->setFormAction($this->ctrl->getFormAction($this));
1149
1150 // add file property
1151 $file = new ilFileInputGUI($this->lng->txt('file'), 'file');
1152 $file->setSuffixes(array('xml'));
1153 $file->setRequired(true);
1154 $this->import_form->addItem($file);
1155
1156 $this->import_form->setTitle($this->lng->txt('md_adv_import_record'));
1157 $this->import_form->addCommandButton('importRecord', $this->lng->txt('import'));
1158 $this->import_form->addCommandButton('showRecords', $this->lng->txt('cancel'));
1159 }
1160
1161 public function importRecord(): void
1162 {
1163 $this->initImportForm();
1164 if (!$this->import_form->checkInput()) {
1165 $this->import_form->setValuesByPost();
1166 $this->importRecords();
1167 return;
1168 }
1169
1170 $import_files = new ilAdvancedMDRecordImportFiles();
1171 if (!$create_time = $import_files->moveUploadedFile($_FILES['file']['tmp_name'])) {
1172 $this->createRecord();
1173 return;
1174 }
1175
1176 try {
1177 $parser = new ilAdvancedMDRecordParser($import_files->getImportFileByCreationDate($create_time));
1178
1179 // local import?
1180 if ($this->context === self::CONTEXT_OBJECT) {
1181 $parser->setContext($this->obj_id, $this->obj_type, $this->sub_type);
1182 }
1183
1184 // Validate
1186 $parser->startParsing();
1187
1188 // Insert
1190 $parser->startParsing();
1191 $this->tpl->setOnScreenMessage('success', $this->lng->txt('md_adv_added_new_record'), true);
1192 $this->ctrl->redirect($this, "showRecords");
1193 } catch (ilSaxParserException $exc) {
1194 $this->tpl->setOnScreenMessage('failure', $exc->getMessage(), true);
1195 $this->ctrl->redirect($this, "importRecords");
1196 }
1197
1198 // Finally delete import file
1199 $import_files->deleteFileByCreationDate($create_time);
1200 }
1201
1207 public function saveRecord(): void
1208 {
1209 $this->initRecordObject();
1210 $form = $this->initForm('create');
1211 if (!$this->form->checkInput()) {
1212 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
1213 $this->createRecord($this->form);
1214 return;
1215 }
1216
1217 $record = $this->loadRecordFormData($form);
1218 if ($this->obj_type) {
1219 $sub_types = (!is_array($this->sub_type))
1220 ? [$this->sub_type]
1221 : $this->sub_type;
1222 $assigned_object_types = array_map(function ($sub_type) {
1223 return [
1224 "obj_type" => $this->obj_type,
1225 "sub_type" => $sub_type,
1226 "optional" => false
1227 ];
1228 }, $sub_types);
1229 $this->record->setAssignedObjectTypes($assigned_object_types);
1230 }
1231
1232 $record->setDefaultLanguage($this->lng->getDefaultLanguage());
1233 $record->save();
1234
1235 $translations = ilAdvancedMDRecordTranslations::getInstanceByRecordId($record->getRecordId());
1236 $translations->addTranslationEntry($record->getDefaultLanguage(), true);
1237 $translations->updateTranslations(
1238 $record->getDefaultLanguage(),
1239 $this->form->getInput('title'),
1240 $this->form->getInput('desc')
1241 );
1242 $this->tpl->setOnScreenMessage('success', $this->lng->txt('md_adv_added_new_record'), true);
1243 $this->ctrl->redirect($this, 'showRecords');
1244 }
1245
1250 public function editField(?ilPropertyFormGUI $a_form = null): void
1251 {
1252 $record_id = $this->getRecordIdFromQuery();
1253 $field_id = $this->getFieldIdFromQuery();
1254 if (!$record_id || !$field_id) {
1255 $this->editFields();
1256 return;
1257 }
1258 $this->ctrl->saveParameter($this, 'field_id');
1259 $this->ctrl->saveParameter($this, 'record_id');
1260 $this->initRecordObject();
1261 $this->setRecordSubTabs(2);
1262
1263 $field_definition = ilAdvancedMDFieldDefinition::getInstance($field_id);
1264
1265 if (!$a_form instanceof ilPropertyFormGUI) {
1266 $this->initLanguage($this->record->getRecordId());
1267 $this->showLanguageSwitch($this->record->getRecordId(), 'editField');
1268 $a_form = $this->initFieldForm($field_definition);
1269 }
1270 $table = '';
1271 if ($field_definition->hasComplexOptions()) {
1272 $table_obj = $field_definition->getComplexOptionsOverview();
1273 if ($table_obj !== null) {
1274 $table = $this->ui_renderer->render($table_obj);
1275 }
1276 }
1277 $this->tpl->setContent($a_form->getHTML() . $table);
1278 }
1279
1284 public function updateField(): void
1285 {
1286 $record_id = $this->getRecordIdFromQuery();
1287 $field_id = $this->getFieldIdFromQuery();
1288 $this->ctrl->saveParameter($this, 'record_id');
1289 $this->ctrl->saveParameter($this, 'field_id');
1290
1291 if (!$record_id || !$field_id) {
1292 $this->editFields();
1293 return;
1294 }
1295
1296 $this->initRecordObject();
1297 $this->initLanguage($record_id);
1298 $this->showLanguageSwitch($record_id, 'editField');
1299
1300 $confirm = false;
1301 $field_definition = ilAdvancedMDFieldDefinition::getInstance($field_id);
1302 $form = $this->initFieldForm($field_definition);
1303 if ($form->checkInput()) {
1304 $field_definition->importDefinitionFormPostValues($form, $this->getPermissions(), $this->active_language);
1305 if (!$field_definition->importDefinitionFormPostValuesNeedsConfirmation()) {
1306 $field_definition->update();
1307 $translations = ilAdvancedMDFieldTranslations::getInstanceByRecordId($this->record->getRecordId());
1308 $translations->updateFromForm($field_id, $this->active_language, $form);
1309
1310 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
1311 $this->ctrl->redirect($this, 'editField');
1312 } else {
1313 $confirm = true;
1314 }
1315 }
1316
1317 $form->setValuesByPost();
1318
1319 // fields needs confirmation of updated settings
1320 if ($confirm) {
1321 $this->tpl->setOnScreenMessage('info', $this->lng->txt("md_adv_confirm_definition"));
1322 $field_definition->prepareDefinitionFormConfirmation($form);
1323 }
1324
1325 $this->editField($form);
1326 }
1327
1332 public function createField(?ilPropertyFormGUI $a_form = null): void
1333 {
1334 $record_id = $this->getRecordIdFromQuery();
1335 $field_type = $this->getFieldTypeFromPost();
1336 if (!$field_type) {
1337 $field_type = $this->getFieldTypeFromQuery();
1338 }
1339
1340 $this->initRecordObject();
1341 $this->ctrl->setParameter($this, 'ftype', $field_type);
1342 $this->setRecordSubTabs(2);
1343 if (!$record_id || !$field_type) {
1344 $this->editFields();
1345 return;
1346 }
1347
1348 if (!$a_form) {
1349 $field_definition = ilAdvancedMDFieldDefinition::getInstance(null, $field_type);
1350 $field_definition->setRecordId($record_id);
1351 $a_form = $this->initFieldForm($field_definition);
1352 }
1353 $this->tpl->setContent($a_form->getHTML());
1354 }
1355
1356 public function saveField(): void
1357 {
1358 $record_id = $this->getRecordIdFromQuery();
1359 $ftype = $this->getFieldTypeFromQuery();
1360
1361 if (!$record_id || !$ftype) {
1362 $this->editFields();
1363 return;
1364 }
1365
1366 $this->initRecordObject();
1367 $this->initLanguage($record_id);
1368 $this->ctrl->saveParameter($this, 'ftype');
1369
1370 $field_definition = ilAdvancedMDFieldDefinition::getInstance(
1371 null,
1372 $ftype
1373 );
1374 $field_definition->setRecordId($record_id);
1375 $form = $this->initFieldForm($field_definition);
1376
1377 if ($form->checkInput()) {
1378 $field_definition->importDefinitionFormPostValues($form, $this->getPermissions(), $this->active_language);
1379 $field_definition->save();
1380
1381 $translations = ilAdvancedMDFieldTranslations::getInstanceByRecordId($record_id);
1382 $translations->read();
1383 $translations->updateFromForm($field_definition->getFieldId(), $this->active_language, $form);
1384
1385 $this->tpl->setOnScreenMessage('success', $this->lng->txt('settings_saved'), true);
1386 $this->ctrl->redirect($this, "editFields");
1387 }
1388
1389 $form->setValuesByPost();
1390 $this->createField($form);
1391 }
1392
1394 {
1395 $is_creation_mode = $a_definition->getFieldId() ? false : true;
1396
1397 $form = new ilPropertyFormGUI();
1398 $form->setFormAction($this->ctrl->getFormAction($this));
1399
1400 $translations = ilAdvancedMDFieldTranslations::getInstanceByRecordId($this->record->getRecordId());
1401 if ($is_creation_mode) {
1402 $form->setDescription($a_definition->getDescription());
1403 } else {
1404 $form->setDescription($translations->getFormTranslationInfo(
1405 $a_definition->getFieldId(),
1406 $this->active_language
1407 ));
1408 }
1409 $type = new ilNonEditableValueGUI($this->lng->txt("type"));
1410 $type->setValue($this->lng->txt($a_definition->getTypeTitle()));
1411 $form->addItem($type);
1412 $a_definition->addToFieldDefinitionForm($form, $this->getPermissions(), $this->active_language);
1413
1414 if ($is_creation_mode) {
1415 $form->setTitle($this->lng->txt('md_adv_create_field'));
1416 $form->addCommandButton('saveField', $this->lng->txt('create'));
1417 } else {
1418 $form->setTitle($this->lng->txt('md_adv_edit_field'));
1419 $form->addCommandButton('updateField', $this->lng->txt('save'));
1420 }
1421
1422 $form->addCommandButton('editFields', $this->lng->txt('cancel'));
1423
1424 return $form;
1425 }
1426
1427 protected function initForm($a_mode): ilPropertyFormGUI
1428 {
1429 if ($this->form instanceof ilPropertyFormGUI) {
1430 return $this->form;
1431 }
1432 $perm = $this->getPermissions()->hasPermissions(
1434 $this->record->getRecordId(),
1435 array(
1438 )
1439 ,
1442 )
1443 ,
1446 )
1447 ,
1449 )
1450 );
1451
1452 $this->form = new ilPropertyFormGUI();
1453
1454 $translations = ilAdvancedMDRecordTranslations::getInstanceByRecordId($this->record->getRecordId());
1455 $this->form->setDescription($translations->getFormTranslationInfo($this->active_language));
1456 $this->form->setFormAction($this->ctrl->getFormAction($this));
1457
1458 // title
1459 $title = new ilTextInputGUI($this->lng->txt('title'), 'title');
1460 $title->setValue($this->record->getTitle());
1461 $title->setSize(20);
1462 $title->setMaxLength(70);
1463 $title->setRequired(true);
1464
1466 $title->setDisabled(true);
1467 }
1468 $this->form->addItem($title);
1469 $translations->modifyTranslationInfoForTitle($this->form, $title, $this->active_language);
1470
1471 // desc
1472 $desc = new ilTextAreaInputGUI($this->lng->txt('description'), 'desc');
1473 $desc->setValue($this->record->getDescription());
1474 $desc->setRows(3);
1475
1477 $desc->setDisabled(true);
1478 }
1479 $this->form->addItem($desc);
1480 $translations->modifyTranslationInfoForDescription($this->form, $desc, $this->active_language);
1481
1482 // active
1483 $check = new ilCheckboxInputGUI($this->lng->txt('md_adv_active'), 'active');
1484 $check->setChecked($this->record->isActive());
1485 $check->setValue("1");
1486 $this->form->addItem($check);
1487
1489 $check->setDisabled(true);
1490 }
1491
1492 if (!$this->obj_type) {
1493 // scope
1494 $scope = new ilCheckboxInputGUI($this->lng->txt('md_adv_scope'), 'scope');
1495 $scope->setInfo($this->lng->txt('md_adv_scope_info'));
1496 $scope->setChecked($this->record->enabledScope());
1497 $scope->setValue("1");
1498 $this->form->addItem($scope);
1499 $subitems = new ilRepositorySelector2InputGUI(
1500 $this->lng->txt('md_adv_scope_objects'),
1501 "scope_containers",
1502 true,
1503 $this->form
1504 );
1505 $subitems->setValue($this->record->getScopeRefIds());
1506 $exp = $subitems->getExplorerGUI();
1507
1508 $definition = $GLOBALS['DIC']['objDefinition'];
1509 $white_list = [];
1510 foreach ($definition->getAllRepositoryTypes() as $type) {
1511 if ($definition->isContainer($type)) {
1512 $white_list[] = $type;
1513 }
1514 }
1515
1516 $exp->setTypeWhiteList($white_list);
1517 $exp->setSkipRootNode(false);
1518 $exp->setRootId(ROOT_FOLDER_ID);
1519 $scope->addSubItem($subitems);
1520 }
1521
1522 if (!$this->obj_type) {
1523 $section = new ilFormSectionHeaderGUI();
1524 $section->setTitle($this->lng->txt('md_obj_types'));
1525 $this->form->addItem($section);
1526
1527 // see ilAdvancedMDRecordTableGUI::fillRow()
1528 $options = array(
1529 0 => $this->lng->txt("meta_obj_type_inactive"),
1530 1 => $this->lng->txt("meta_obj_type_mandatory"),
1531 2 => $this->lng->txt("meta_obj_type_optional")
1532 );
1533
1534 foreach (ilAdvancedMDRecord::_getAssignableObjectTypes(true) as $type) {
1535 $t = $type["obj_type"] . ":" . $type["sub_type"];
1536 $this->lng->loadLanguageModule($type["obj_type"]);
1537
1538 /*
1539 * BT 35914: workaround for hiding portfolio pages in portfolios,
1540 * since they only get data from portfolio templates
1541 */
1542 $hidden = false;
1543 if ($type["obj_type"] == "prtf" && $type["sub_type"] == "pfpg") {
1544 $hidden = true;
1545 }
1546 // EmployeeTalks get their md from templates
1547 if ($type["obj_type"] == "tals" && $type["sub_type"] == "etal") {
1548 $hidden = true;
1549 }
1550
1551
1552 $type_options = $options;
1553 switch ($type["obj_type"]) {
1554 case "orgu":
1555 // currently only optional records for org unit (types)
1556 unset($type_options[1]);
1557 break;
1558 case "talt":
1559 // currently only optional records for talk templates (types)
1560 unset($type_options[1]);
1561 break;
1562 case "rcrs":
1563 // optional makes no sense for ecs-courses
1564 unset($type_options[2]);
1565 break;
1566 }
1567
1568 $value = 0;
1569 if ($a_mode == "edit") {
1570 foreach ($this->record->getAssignedObjectTypes() as $item) {
1571 if ($item["obj_type"] == $type["obj_type"] &&
1572 $item["sub_type"] == $type["sub_type"]) {
1573 $value = $item["optional"]
1574 ? 2
1575 : 1;
1576 }
1577 }
1578 }
1579
1580 $sel_name = 'obj_types__' . $t;
1581
1582 if ($hidden) {
1583 $hidden = new ilHiddenInputGUI($sel_name);
1584 $hidden->setValue((string) $value);
1585 $this->form->addItem($hidden);
1586 continue;
1587 }
1588
1589 $check = new ilSelectInputGUI($type['text'], $sel_name);
1590 //$check = new ilSelectInputGUI($type["text"], 'obj_types[' . $t . ']');
1591 $check->setOptions($type_options);
1592 $check->setValue($value);
1593 $this->form->addItem($check);
1594
1596 $check->setDisabled(true);
1597 }
1598 }
1599 }
1600
1601 switch ($a_mode) {
1602 case 'create':
1603 $this->form->setTitle($this->lng->txt('md_adv_create_record'));
1604 $this->form->addCommandButton('saveRecord', $this->lng->txt('add'));
1605 $this->form->addCommandButton('showRecords', $this->lng->txt('cancel'));
1606 break;
1607
1608 case 'edit':
1609 $this->form->setTitle($this->lng->txt('md_adv_edit_record'));
1610 $this->form->addCommandButton('updateRecord', $this->lng->txt('save'));
1611 $this->form->addCommandButton('showRecords', $this->lng->txt('cancel'));
1612 }
1613 return $this->form;
1614 }
1615
1621 {
1622 if (!$visible_records = ilAdvancedMDRecord::_getAllRecordsByObjectType()) {
1623 return null;
1624 }
1625
1626 $this->form = new ilPropertyFormGUI();
1627 $this->form->setFormAction($this->ctrl->getFormAction($this));
1628 #$this->form->setTableWidth('100%');
1629
1630 // substitution
1631 foreach ($visible_records as $obj_type => $records) {
1632 $read_only = !$this->access->checkAccess('write', '', $this->ref_id);
1633 ;
1634
1636
1637 // Show section
1638 $section = new ilFormSectionHeaderGUI();
1639 $section->setTitle($this->lng->txt('objs_' . $obj_type));
1640 $this->form->addItem($section);
1641
1642 $check = new ilCheckboxInputGUI($this->lng->txt('description'), 'enabled_desc_' . $obj_type);
1643 $check->setValue("1");
1644 $check->setOptionTitle($this->lng->txt('md_adv_desc_show'));
1645 $check->setChecked($sub->isDescriptionEnabled());
1646 $this->form->addItem($check);
1647
1648 if ($read_only) {
1649 $check->setDisabled(true);
1650 }
1651
1652 $check = new ilCheckboxInputGUI($this->lng->txt('md_adv_field_names'), 'enabled_field_names_' . $obj_type);
1653 $check->setValue("1");
1654 $check->setOptionTitle($this->lng->txt('md_adv_fields_show'));
1655 $check->setChecked($sub->enabledFieldNames());
1656 $this->form->addItem($check);
1657
1658 if ($read_only) {
1659 $check->setDisabled(true);
1660 }
1661
1663 $definitions = $sub->sortDefinitions($definitions);
1664
1665 $counter = 1;
1666 foreach ($definitions as $def) {
1667 $definition_id = $def->getFieldId();
1668
1669 $title = ilAdvancedMDRecord::_lookupTitle((int) $def->getRecordId());
1670 $title = $def->getTitle() . ' (' . $title . ')';
1671
1672 $check = new ilCheckboxInputGUI($title, 'show_' . $obj_type . '_' . $definition_id);
1673 $check->setValue("1");
1674 $check->setOptionTitle($this->lng->txt('md_adv_show'));
1675 $check->setChecked($sub->isSubstituted($definition_id));
1676
1677 if ($read_only) {
1678 $check->setDisabled(true);
1679 }
1680
1681 $pos = new ilNumberInputGUI(
1682 $this->lng->txt('position'),
1683 'position_' . $obj_type . '_' . $definition_id
1684 );
1685 $pos->setSize(3);
1686 $pos->setMaxLength(4);
1687 $pos->allowDecimals(true);
1688 $pos->setValue(sprintf('%.1f', $counter++));
1689 $check->addSubItem($pos);
1690
1691 if ($read_only) {
1692 $pos->setDisabled(true);
1693 }
1694
1695 $bold = new ilCheckboxInputGUI(
1696 $this->lng->txt('bold'),
1697 'bold_' . $obj_type . '_' . $definition_id
1698 );
1699 $bold->setValue("1");
1700 $bold->setChecked($sub->isBold($definition_id));
1701 $check->addSubItem($bold);
1702
1703 if ($read_only) {
1704 $bold->setDisabled(true);
1705 }
1706
1707 $bold = new ilCheckboxInputGUI(
1708 $this->lng->txt('newline'),
1709 'newline_' . $obj_type . '_' . $definition_id
1710 );
1711 $bold->setValue("1");
1712 $bold->setChecked($sub->hasNewline($definition_id));
1713 $check->addSubItem($bold);
1714
1715 if ($read_only) {
1716 $bold->setDisabled(true);
1717 }
1718
1719 $this->form->addItem($check);
1720 }
1721 }
1722 $this->form->setTitle($this->lng->txt('md_adv_substitution_table'));
1723
1724 if ($this->access->checkAccess('write', '', $this->ref_id)) {
1725 $this->form->addCommandButton('updateSubstitutions', $this->lng->txt('save'));
1726 }
1727 return $this->form;
1728 }
1729
1731 {
1732 $translations = ilAdvancedMDRecordTranslations::getInstanceByRecordId($this->record->getRecordId());
1733
1734 $perm = $this->getPermissions()->hasPermissions(
1736 $this->record->getRecordId(),
1737 array(
1740 )
1741 ,
1744 )
1745 ,
1748 )
1749 ,
1751 )
1752 );
1753
1755 $this->record->setActive((bool) $form->getInput('active'));
1756 }
1758 if (
1759 $translations->getDefaultTranslation() == null ||
1760 $translations->getDefaultTranslation()->getLangKey() == $this->active_language
1761 ) {
1762 $this->record->setTitle((string) $form->getInput('title'));
1763 }
1764 }
1766 if (
1767 $translations->getDefaultTranslation() == null ||
1768 $translations->getDefaultTranslation()->getLangKey() == $this->active_language) {
1769 $this->record->setDescription($form->getInput('desc'));
1770 }
1771 }
1772
1773 if (!$this->obj_type) {
1775 $obj_types = [];
1776 foreach (ilAdvancedMDRecord::_getAssignableObjectTypes(true) as $type) {
1777 $t = $type["obj_type"] . ":" . $type["sub_type"];
1778 $value = $form->getInput('obj_types__' . $t);
1779 if (!$value) {
1780 continue;
1781 }
1782 $obj_types[] = [
1783 'obj_type' => $type['obj_type'],
1784 'sub_type' => $type['sub_type'],
1785 'optional' => ($value > 1)
1786 ];
1787 }
1788 $this->record->setAssignedObjectTypes($obj_types);
1789 }
1790 }
1791
1792 $scopes = $form->getInput('scope');
1793 $scopes_selection = $form->getInput('scope_containers');
1794 if ($scopes && is_array($scopes_selection)) {
1795 $this->record->enableScope(true);
1796 $this->record->setScopes(
1797 array_map(
1798 function (string $scope_ref_id) {
1799 $scope = new ilAdvancedMDRecordScope();
1800 $scope->setRefId((int) $scope_ref_id);
1801 return $scope;
1802 },
1803 $scopes_selection
1804 )
1805 );
1806 } else {
1807 $this->record->enableScope(false);
1808 $this->record->setScopes([]);
1809 }
1810 return $this->record;
1811 }
1812
1817 {
1818 if (!$this->record instanceof ilAdvancedMDRecord) {
1819 $record_id = $this->getRecordIdFromQuery();
1820 $this->record = ilAdvancedMDRecord::_getInstanceByRecordId((int) $record_id);
1821 $this->ctrl->saveParameter($this, 'record_id');
1822
1823 // bind to parent object (aka local adv md)
1824 if (!$record_id && $this->obj_id) {
1825 $this->record->setParentObject($this->obj_id);
1826 }
1827 }
1828 return $this->record;
1829 }
1830
1835 protected function setSubTabs(int $context): void
1836 {
1837 if ($context == self::CONTEXT_OBJECT) {
1838 return;
1839 }
1840
1841 $this->tabs_gui->clearSubTabs();
1842
1843 $this->tabs_gui->addSubTabTarget(
1844 "md_adv_record_list",
1845 $this->ctrl->getLinkTarget($this, "showRecords"),
1846 '',
1847 '',
1848 '',
1849 true
1850 );
1851
1853 $this->tabs_gui->addSubTabTarget(
1854 "md_adv_presentation",
1855 $this->ctrl->getLinkTarget($this, "showPresentation")
1856 );
1857 }
1858
1859 $this->tabs_gui->addSubTabTarget(
1860 "md_adv_file_list",
1861 $this->ctrl->getLinkTarget($this, "showFiles"),
1862 "showFiles"
1863 );
1864 }
1865
1870 protected function getParsedRecordObjects(): array
1871 {
1872 $res = [];
1873
1874 $sub_type = (!is_array($this->sub_type))
1875 ? [$this->sub_type]
1876 : $this->sub_type;
1877
1878 if ($this->context === self::CONTEXT_OBJECT) {
1879 // get all records selected for subtype
1880 foreach ($sub_type as $st) {
1881 $selected[$st] = ilAdvancedMDRecord::getObjRecSelection($this->obj_id, $st);
1882 }
1883 }
1884
1886 $orderings = new ilAdvancedMDRecordObjectOrderings();
1887 $records = $orderings->sortRecords($records, $this->obj_id);
1888
1889 $position = 0;
1890
1891 // get all records usuable in current context
1892 foreach ($records as $record) {
1893 $parent_id = $record->getParentObject();
1894
1895 if ($this->context == self::CONTEXT_ADMINISTRATION) {
1896 if ($parent_id) {
1897 continue;
1898 }
1899 } else {
1900 // does not match current object
1901 if ($parent_id && $parent_id != $this->obj_id) {
1902 continue;
1903 }
1904
1905 // inactive records only in administration
1906 if (!$parent_id && !$record->isActive()) {
1907 continue;
1908 }
1909 // scope needs to match in object context
1910 if (
1912 $this->ref_id,
1913 $record->getScopes()
1914 )
1915 ) {
1916 continue;
1917 }
1918 }
1919
1920 $tmp_arr = [];
1921 $tmp_arr['readonly'] = null;
1922 $tmp_arr['local'] = null;
1923 $tmp_arr['optional'] = null;
1924 $tmp_arr['id'] = $record->getRecordId();
1925 $tmp_arr['active'] = $record->isActive();
1926 $tmp_arr['title'] = $record->getTitle();
1927 $tmp_arr['description'] = $record->getDescription();
1928 $tmp_arr['fields'] = [];
1929 /*
1930 * This is a workaround to fix sorting by scope, see #21963
1931 */
1932 $tmp_arr['first_scope'] = ilObject::_lookupTitle(
1933 ilObject::_lookupObjId($record->getScopeRefIds()[0] ?? 0)
1934 );
1935 $tmp_arr['obj_types'] = $record->getAssignedObjectTypes();
1936 foreach ($record->getAssignedObjectTypes() as $idx => $item) {
1937 $tmp_arr['obj_types'][$idx]['context'] = null;
1938 }
1939 $position += 10;
1940 $tmp_arr['position'] = $position;
1941
1942 $tmp_arr['perm'] = $this->permissions->hasPermissions(
1944 $record->getRecordId(),
1945 array(
1947 ,
1949 ,
1951 ,
1954 )
1955 )
1956 );
1957
1958 if ($this->obj_type) {
1959 $tmp_arr["readonly"] = !(bool) $parent_id;
1960 $tmp_arr["local"] = $parent_id;
1961
1962 // local records are never optional (or unassigned)
1963 $assigned = (bool) $parent_id;
1964 $optional = false;
1965 foreach ($tmp_arr['obj_types'] as $idx => $item) {
1966 if ($item["obj_type"] == $this->obj_type &&
1967 in_array($item["sub_type"], $sub_type)) {
1968 $assigned = true;
1969 $optional = $item["optional"];
1970 $tmp_arr['obj_types'][$idx]['context'] = true;
1971 } else {
1972 unset($tmp_arr['obj_types'][$idx]);
1973 }
1974 }
1975 $tmp_arr['optional'] = $optional;
1976 if ($optional) {
1977 // in object context "active" means selected record
1978 // $tmp_arr['active'] = (is_array($selected[$item["sub_type"]]) && in_array($record->getRecordId(), $selected[$item["sub_type"]]));
1979 $tmp_arr['local_selected'] = [];
1980 foreach ($selected as $key => $records) {
1981 if (in_array($record->getRecordId(), $records)) {
1982 $tmp_arr['local_selected'][$this->obj_type][] = $key;
1983 }
1984 }
1985 }
1986 }
1987
1988 if ($assigned ?? true) {
1989 $res[] = $tmp_arr;
1990 }
1991 }
1992 return $res;
1993 }
1994
1995
1996 //
1997 // complex options
1998 //
1999
2000 public function editComplexOption(?ilPropertyFormGUI $a_form = null): void
2001 {
2002 $field_id = $this->getFieldIdFromQuery();
2003 if (!$field_id) {
2004 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_select_one'));
2005 $this->ctrl->redirect($this, 'showRecords');
2006 }
2007
2008 $field_definition = ilAdvancedMDFieldDefinition::getInstance($field_id);
2009 if (!$field_definition->hasComplexOptions()) {
2010 $this->ctrl->redirect($this, "editField");
2011 }
2012
2013 if (!$a_form) {
2014 $oid = $this->getOidFromTable();
2015 $a_form = $this->initComplexOptionForm($field_definition, $oid);
2016 }
2017
2018 $this->tpl->setContent($a_form->getHTML());
2019 }
2020
2022 {
2023 $this->ctrl->saveParameter($this, "record_id");
2024 $this->ctrl->saveParameter($this, "field_id");
2025
2026 if ($oid !== null) {
2027 $this->ctrl->setParameter($this, "advmd_oid", $oid);
2028 }
2029
2030 $form = new ilPropertyFormGUI();
2031 $form->setTitle($this->lng->txt("md_adv_edit_complex_option"));
2032 $form->setFormAction($this->ctrl->getFormAction($this, "updateComplexOption"));
2033
2034 $a_def->initOptionForm($form, $oid);
2035
2036 $form->addCommandButton("updateComplexOption", $this->lng->txt("save"));
2037 $form->addCommandButton("editField", $this->lng->txt("cancel"));
2038
2039 return $form;
2040 }
2041
2042 public function updateComplexOption(): void
2043 {
2044 $field_id = $this->getFieldIdFromQuery();
2045 $field_definition = ilAdvancedMDFieldDefinition::getInstance($field_id);
2046 $oid = $this->getOidFromQuery();
2047
2048 if ($field_definition->hasComplexOptions()) {
2049 $form = $this->initComplexOptionForm($field_definition, $oid);
2050 if ($form->checkInput() &&
2051 $field_definition->updateComplexOption($form, $oid)) {
2052 $field_definition->update();
2053 $this->tpl->setOnScreenMessage('success', $this->lng->txt("settings_saved"), true);
2054 }
2055 }
2056
2057 $this->ctrl->redirect($this, "editField");
2058 }
2059
2060 protected function initLanguage(int $record_id): void
2061 {
2063 // read active language
2064 $default = '';
2065 foreach ($translations->getTranslations() as $translation) {
2066 if ($translation->getLangKey() == $translations->getDefaultLanguage()) {
2067 $default = $translation->getLangKey();
2068 }
2069 }
2070 $active = $this->request->getQueryParams()['mdlang'] ?? $default;
2071 $this->active_language = $active;
2072 }
2073
2074 protected function showLanguageSwitch(int $record_id, string $target): void
2075 {
2077
2078 if (count($translations->getTranslations()) <= 1) {
2079 return;
2080 }
2081 $actions = [];
2082 foreach ($translations->getTranslations() as $translation) {
2083 $this->ctrl->setParameter($this, 'mdlang', $translation->getLangKey());
2084 $actions[$translation->getLangKey()] = $this->ctrl->getLinkTarget(
2085 $this,
2086 $target
2087 );
2088 }
2089 $this->ctrl->setParameter($this, 'mdlang', $this->active_language);
2090 $view_control = $this->ui_factory->viewControl()->mode(
2091 $actions,
2092 $this->lng->txt('meta_aria_language_selection')
2093 )->withActive($this->active_language);
2094 $this->toolbar->addComponent($view_control);
2095 }
2096}
$check
Definition: buildRTE.php:81
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
Checks access for ILIAS objects.
static getInstancesByRecordId( $a_record_id, $a_only_searchable=false, string $language='')
Get definitions by record id.
static getInstancesByObjType($a_obj_type, $a_active_only=true)
addToFieldDefinitionForm(ilPropertyFormGUI $a_form, ilAdvancedMDPermissionHelper $a_permissions, string $language='')
Add input elements to definition form.
static getInstance(?int $a_field_id, ?int $a_type=null, string $language='')
Advanced metadata permission helper.
SAX based XML parser for record import files.
Scope restrictions for advanced md records.
static _lookupTitle(int $a_record_id)
static deleteObjRecSelection(int $a_obj_id)
Delete repository object record selection.
static _getAllRecordsByObjectType()
Get records by obj_type Note: this returns only records with no sub types!
static _getInstanceByRecordId(int $a_record_id)
static _getAssignableObjectTypes(bool $a_include_text=false)
Get assignable object type @access public.
static getObjRecSelection(int $a_obj_id, string $a_sub_type="")
Get repository object record selection.
static _getRecords()
Get records @access public.
static saveObjRecSelection(int $a_obj_id, string $a_sub_type="", ?array $a_records=null, bool $a_delete_before=true)
Save repository object record selection.
static isFilteredByScope($a_ref_id, array $scopes)
Check if a given ref id is not filtered by scope restriction.
loadRecordFormData(ilPropertyFormGUI $form)
updateSubstitutions()
Update substitution @access public.
initComplexOptionForm(ilAdvancedMDFieldDefinition $a_def, string $oid)
createField(?ilPropertyFormGUI $a_form=null)
Show field type selection @access public.
editField(?ilPropertyFormGUI $a_form=null)
Edit field @access public.
updateRecord()
Update record @access public.
updateRecords()
Save records (assigned object typed) @access public.
initContextParameters(int $context, int $ref_id, ?string $obj_type, $sub_type)
editComplexOption(?ilPropertyFormGUI $a_form=null)
setSubTabs(int $context)
Set sub tabs @access protected.
__construct(int $a_context, int $a_ref_id, ?string $a_obj_type=null, $a_sub_type=null)
Constructor @access public.
saveRecord()
Save record @access public.
confirmDeleteFiles()
confirm delete files @access public
initFieldForm(ilAdvancedMDFieldDefinition $a_definition)
initFormSubstitutions()
init form table 'substitutions' @access protected
deleteRecords()
Permanently delete records @access public.
exportRecords()
Export records @access public.
updateFields()
Update fields @access public.
ilAdvancedMDPermissionHelper $permissions
confirmDeleteRecords()
Confirm delete @access public.
showLanguageSwitch(int $record_id, string $target)
createRecord(?ilPropertyFormGUI $form=null)
Show @access public.
downloadFile()
Download XML file @access public.
editRecord(?ilPropertyFormGUI $form=null)
updateField()
Update field @access public.
setRecordSubTabs(int $level=1, bool $show_settings=false)
Set subtabs for record editing/creation.
deleteFiles()
Delete files @access public.
static _getInstanceByObjectType(string $a_type)
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
This class represents a checkbox property in a property form.
static getInstance(int $a_user_id, int $a_ref_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilCtrl provides processing control methods.
This class represents a file property in a property form.
This class represents a section header in a property form.
This class represents a hidden form property in a property form.
language handling
Component logger with individual log levels by component id.
This class represents a non editable value in a property form.
This class represents a number property in a property form.
User class.
static _lookupType(int $id, bool $reference=false)
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
This class represents a property form user interface.
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a text area property in a property form.
This class represents a text property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
const ROOT_FOLDER_ID
Definition: constants.php:32
$info
Definition: entry_point.php:21
Interface GlobalHttpState.
An entity that renders components to a string output.
Definition: Renderer.php:31
Interface ilDBInterface.
if(strtoupper($request->getMethod()) !=='POST') if(( $body[ 'grant_type'] ?? '') !=='client_credentials') if(($body['client_assertion_type'] ?? '') !=='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'||!is_string($body['client_assertion'] ?? null)) $scopes
Definition: ltitoken.php:60
static http()
Fetches the global http state from ILIAS.
form(?array $class_path, string $cmd, string $submit_caption="")
foreach(array_slice( $argv, 1) as $argument) if(!is_dir($target)) $parser
foreach($_POST as $key=> $value) $res
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$GLOBALS["DIC"]
Definition: wac.php:66