ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilObjFileGUI.php
Go to the documentation of this file.
1<?php
2
23use Psr\Http\Message\ServerRequestInterface;
43
55{
59
60 public const UPLOAD_MAX_FILES = 100;
61 public const PARAM_FILES = 'files';
62 public const PARAM_TITLE = 'title';
63 public const PARAM_DESCRIPTION = 'description';
64 public const PARAM_COPYRIGHT_ID = "copyright_id";
65
66 public const PARAM_UPLOAD_ORIGIN = 'origin';
67 public const UPLOAD_ORIGIN_STANDARD = 'standard';
68 public const UPLOAD_ORIGIN_DROPZONE = 'dropzone';
69
70 public const CMD_EDIT = Capabilities::EDIT_SETTINGS->value;
71 public const CMD_VERSIONS = Capabilities::MANAGE_VERSIONS->value;
72 public const CMD_UPLOAD_FILES = "uploadFiles";
73
74 public const CMD_SEND_FILE = Capabilities::DOWNLOAD->value;
76
80 public ?ilObject $object = null;
82 protected UIServices $ui;
85 protected Services $storage;
86 protected ?ilLogger $log = null;
88 protected \ILIAS\Refinery\Factory $refinery;
92 protected \ILIAS\UI\Component\Input\Factory $inputs;
94 protected ServerRequestInterface $request;
97 protected LOMServices $lom_services;
98
102 public function __construct(int $a_id = 0, int $a_id_type = self::REPOSITORY_NODE_ID, int $a_parent_node_id = 0)
103 {
104 global $DIC;
105 $this->refinery = $DIC->refinery();
106 $this->file_service_settings = $DIC->fileServiceSettings();
107 $this->user = $DIC->user();
108 $this->lng = $DIC->language();
110 $this->ui = $DIC->ui();
111 $this->storage = $DIC->resourceStorage();
112 $this->upload_handler = new ilObjFileUploadHandlerGUI();
113 $this->stakeholder = new ilObjFileStakeholder();
114 $this->general_settings = new General();
115 parent::__construct($a_id, $a_id_type, $a_parent_node_id);
116 $this->obj_service = $DIC->object();
117 $this->lng->loadLanguageModule(ilObjFile::OBJECT_TYPE);
118 $this->icon_repo = new IconDatabaseRepository();
119 $this->inputs = $DIC->ui()->factory()->input();
120 $this->renderer = $DIC->ui()->renderer();
121 $this->request = $DIC->http()->request();
122 $this->data_factory = new Factory();
123 $this->action_repo = new ActionDBRepository($DIC->database());
124 $this->lom_services = $DIC->learningObjectMetadata();
125
126 $capability_builder = new CapabilityBuilder(
128 $this->access,
129 $this->ctrl,
130 $this->action_repo,
131 $DIC->http(),
132 $DIC['static_url.uri_builder']
133 );
134
135 $capability_context = new Context(
136 $this->object_id,
137 $this->ref_id,
138 ($a_id_type === self::WORKSPACE_NODE_ID) ? Context::CONTEXT_WORKSPACE : Context::CONTEXT_REPO
139 );
140
141 $this->capabilities = $capability_builder->get($capability_context);
142 }
143
144 protected function updateLearningProgress(): void
145 {
146 if ($this->object->getLPMode() === ilLPObjSettings::LP_MODE_CONTENT_VISITED) {
148 $this->object->getId(),
149 $this->user->getId(),
150 null,
151 false,
152 true
153 );
154 }
155 }
156
157 public function getType(): string
158 {
160 }
161
162 public function getParentId(): int
163 {
164 return $this->parent_id;
165 }
166
167 #[\Override]
168 public function executeCommand(): void
169 {
170 global $DIC;
171 $ilNavigationHistory = $DIC['ilNavigationHistory'];
172 $ilUser = $DIC['ilUser'];
173 $ilTabs = $DIC['ilTabs'];
174 $ilErr = $DIC['ilErr'];
175
176 $next_class = $this->ctrl->getNextClass($this);
177 $cmd = $this->ctrl->getCmd();
178
179 if (
180 !$this->getCreationMode()
181 && (
182 $this->id_type === self::REPOSITORY_NODE_ID
183 && $this->capabilities->get(Capabilities::DOWNLOAD)->isUnlocked()
184 )) {
185 // add entry to navigation history
186 $ilNavigationHistory->addItem(
187 $this->node_id,
188 (string) $this->capabilities->get(Capabilities::INFO_PAGE)->getUri(),
190 );
191 }
192
193 $this->prepareOutput();
194
195 $info = (new ilObjFileInfoRepository())->getByObjectId($this->obj_id);
196
197 $suffix = $info->getSuffix();
198 $path_file_icon = $this->icon_repo->getIconFilePathBySuffix($suffix);
199 $this->tpl->setTitleIcon($path_file_icon);
200
201 switch ($next_class) {
202 case strtolower(ilInfoScreenGUI::class):
203 $this->infoScreenForward(); // forwards command
204 break;
205
206 case 'ilobjectmetadatagui':
207 if (!$this->capabilities->get(Capabilities::EDIT_SETTINGS)->isUnlocked()) {
208 $ilErr->raiseError($this->lng->txt('permission_denied'), $ilErr->WARNING);
209 }
210
211 $ilTabs->activateTab("id_meta");
212
213 $md_gui = new ilObjectMetaDataGUI($this->object, null, null, $this->call_by_reference);
214
215 // todo: make this work
216 // $md_gui->addMDObserver($this->object,'MDUpdateListener','Technical');
217
218 $this->ctrl->forwardCommand($md_gui);
219 break;
220
221 // repository permissions
222 case 'ilpermissiongui':
223 $ilTabs->activateTab("id_permissions");
224 $perm_gui = new ilPermissionGUI($this);
225 $this->ctrl->forwardCommand($perm_gui);
226 break;
227
228 case "ilexportgui":
229 $ilTabs->activateTab("export");
230 $exp_gui = new ilExportGUI($this);
231 $exp_gui->addFormat();
232 $this->ctrl->forwardCommand($exp_gui);
233 break;
234
235 case 'ilobjectcopygui':
236 $cp = new ilObjectCopyGUI($this);
237 $cp->setType(ilObjFile::OBJECT_TYPE);
238 $this->ctrl->forwardCommand($cp);
239 break;
240
241 // personal workspace permissions
242 case "ilworkspaceaccessgui":
243 $ilTabs->activateTab("id_permissions");
244 $wspacc = new ilWorkspaceAccessGUI($this->node_id, $this->getAccessHandler());
245 $this->ctrl->forwardCommand($wspacc);
246 break;
247
248 case "ilcommonactiondispatchergui":
250 $this->ctrl->forwardCommand($gui);
251 break;
252
253 case "illearningprogressgui":
254 $ilTabs->activateTab('learning_progress');
255 $user_id = $this->request_wrapper->has('user_id')
256 ? $this->request_wrapper->retrieve('user_id', $this->refinery->kindlyTo()->int())
257 : $ilUser->getId();
258 $new_gui = new ilLearningProgressGUI(
260 $this->object->getRefId(),
262 );
263 $this->ctrl->forwardCommand($new_gui);
264 $this->tabs_gui->setTabActive('learning_progress');
265 break;
266 case strtolower(ilFileVersionsGUI::class):
267 $this->tabs_gui->activateTab("id_versions");
268
269 if (!$this->capabilities->get(Capabilities::MANAGE_VERSIONS)->isUnlocked()) {
270 $this->error->raiseError($this->lng->txt("permission_denied"), $this->error->MESSAGE);
271 }
273 $obj = $this->object;
274 $this->ctrl->forwardCommand(new ilFileVersionsGUI($obj));
275 break;
276 case strtolower(ilObjFileUploadHandlerGUI::class):
277 $this->ctrl->forwardCommand(new ilObjFileUploadHandlerGUI());
278 break;
279 case strtolower(ilWOPIEmbeddedApplicationGUI::class):
280 $capability = match($cmd) {
281 ilWOPIEmbeddedApplicationGUI::CMD_VIEW => $this->capabilities->get(Capabilities::VIEW_EXTERNAL),
282 ilWOPIEmbeddedApplicationGUI::CMD_EDIT => $this->capabilities->get(Capabilities::EDIT_EXTERNAL),
283 ilWOPIEmbeddedApplicationGUI::CMD_RETURN => $this->capabilities->get(Capabilities::INFO_PAGE),
284 default => null
285 };
286
287 if ($capability === null || !$capability->isUnlocked()) {
288 $this->error->raiseError($this->lng->txt("permission_denied"), $this->error->MESSAGE);
289 return;
290 }
291 $action = match ($capability->getCapability()) {
292 Capabilities::VIEW_EXTERNAL => $this->action_repo->getViewActionForSuffix($suffix),
293 Capabilities::EDIT_EXTERNAL => $this->action_repo->getEditActionForSuffix($suffix),
294 default => null
295 };
296
297 $this->tabs_gui->activateTab('content');
298 $this->updateLearningProgress();
299
300 if ($this->id_type === Context::CONTEXT_WORKSPACE) {
302 $this->node_id,
303 $this->object->getId()
304 );
305 } else {
306 $goto_link = ilLink::_getLink($this->object->getRefId());
307 }
308
309 $embeded_application = new EmbeddedApplication(
310 $this->storage->manage()->find($this->object->getResourceId()),
311 $action,
312 $this->stakeholder,
313 new URI($goto_link),
314 $capability->getCapability() === Capabilities::VIEW_EXTERNAL,
315 $this->lng->getLangKey()
316 );
317
318 $this->ctrl->forwardCommand(
320 $embeded_application
321 )
322 );
323 break;
324
325 case strtolower(ilFileCommonSettingsGUI::class):
326 $this->initSettingsTab();
327 $this->tabs_gui->activateSubTab("service_settings");
328 $this->ctrl->forwardCommand(
330 $this->object,
331 $this->ctrl,
332 $this->tpl,
333 $this->lng,
334 $this->object_service
335 )
336 );
337 break;
338
339 default:
340 // in personal workspace use object2gui
341 if ($this->id_type === self::WORKSPACE_NODE_ID) {
342 $this->addHeaderAction();
343 $ilTabs->clearTargets();
344
345 if (empty($cmd) || $cmd === 'render') {
346 $cmd = Capabilities::INFO_PAGE->value;
347 $this->$cmd();
348 } else {
349 parent::executeCommand();
350 }
351 break; // otherwise subtabs are duplicated
352 }
353
354 if (empty($cmd) || $cmd === 'render') {
355 $cmd = Capabilities::INFO_PAGE->value;
356 }
357
358 $this->$cmd();
359 break;
360 }
361
362 $this->addHeaderAction();
363 }
364
365
366 protected function addUIFormToAccordion(
367 ilAccordionGUI $accordion,
368 Standard $form,
369 int $form_type
370 ): void {
371 // abort if form-type is unknown
372 if (!in_array($form_type, [self::CFORM_NEW, self::CFORM_CLONE, self::CFORM_IMPORT], true)) {
373 return;
374 }
375
376 $inputs = $form->getInputs();
377 // use label of first input as title, because UI Component forms don't support form-titles yet
378 $title = ($inputs === []) ?
379 '' : $inputs[array_key_first($inputs)]->getLabel();
380
381 $tpl = new ilTemplate("tpl.creation_acc_head.html", true, true, "components/ILIAS/ILIASObject");
382 $tpl->setVariable("TITLE", $this->lng->txt("option") . " " . $form_type . ": " . $title);
383
384 $accordion->addItem($tpl->get(), $this->ui->renderer()->render($form));
385 }
386
387 protected function addLegacyFormToAccordion(
388 ilAccordionGUI $accordion,
389 ilPropertyFormGUI $form,
390 int $form_type
391 ): void {
392 // abort if form-type is unknown
393 if (!in_array($form_type, [self::CFORM_NEW, self::CFORM_CLONE, self::CFORM_IMPORT], true)) {
394 return;
395 }
396 $title = $form->getTitle();
397 $form->setTitle(''); // see https://mantis.ilias.de/view.php?id=37786
398
399 $tpl = new ilTemplate("tpl.creation_acc_head.html", true, true, "components/ILIAS/ILIASObject");
400 $tpl->setVariable("TITLE", $this->lng->txt("option") . " " . $form_type . ": " . $title);
401
402 $accordion->addItem($tpl->get(), $form->getHTML());
403 }
404
408 #[\Override]
409 protected function initCreateForm(string $new_type): Standard
410 {
411 return $this->initUploadForm();
412 }
413
414 #[\Override]
415 protected function getCreationFormTitle(): string
416 {
417 return $this->lng->txt('upload_files');
418 }
419
420 public function initUploadForm(): Standard
421 {
422 $this->getLanguage()->loadLanguageModule('file');
423 $inputs = [];
424
425 $this->ctrl->setParameterByClass(self::class, 'new_type', $this->getType());
426 $this->ctrl->setParameterByClass(
427 self::class,
428 self::PARAM_UPLOAD_ORIGIN,
429 self::UPLOAD_ORIGIN_STANDARD
430 );
431
432
433 $inputs[self::PARAM_FILES] = $this->ui->factory()->input()->field()->file(
434 $this->upload_handler,
435 $this->lng->txt('upload_files'),
436 null,
437 $this->ui->factory()->input()->field()->group([
438 self::PARAM_TITLE => $this->ui->factory()->input()->field()->text(
439 $this->lng->txt('title')
440 )->withAdditionalTransformation(
441 $this->getEmptyStringToNullTransformation()
442 ),
443 self::PARAM_DESCRIPTION => $this->ui->factory()->input()->field()->textarea(
444 $this->lng->txt('description')
445 )->withAdditionalTransformation(
446 $this->getEmptyStringToNullTransformation()
447 ),
448 ])
449 )->withMaxFiles(
450 self::UPLOAD_MAX_FILES
451 )->withRequired(true);
452
453 if ($this->lom_services->copyrightHelper()->isCopyrightSelectionActive()) {
454 $inputs[self::PARAM_COPYRIGHT_ID] = $this->getCopyrightSelectionInput('set_license_for_all_files');
455 }
456
457 return $this->ui->factory()->input()->container()->form()->standard(
458 $this->ctrl->getFormActionByClass(self::class, self::CMD_UPLOAD_FILES),
459 $inputs
460 )->withSubmitLabel($this->lng->txt('upload_files'));
461 }
462
466 protected function uploadFiles(): void
467 {
468 $origin = ($this->request_wrapper->has(self::PARAM_UPLOAD_ORIGIN)) ?
469 $this->request_wrapper->retrieve(
470 self::PARAM_UPLOAD_ORIGIN,
471 $this->refinery->kindlyTo()->string()
472 ) : self::UPLOAD_ORIGIN_STANDARD;
473
474 if (self::UPLOAD_ORIGIN_DROPZONE === $origin) {
475 $dropzone = new ilObjFileUploadDropzone($this->parent_id);
476 $dropzone = $dropzone->getDropzone()->withRequest($this->request);
477 $data = $dropzone->getData();
478 } else {
479 $form = $this->initUploadForm()->withRequest($this->request);
480 $data = $form->getData();
481 }
482 $files = $data[self::PARAM_FILES] ?? $data[0] ?? null;
483
484 if (empty($files)) {
485 $form = $this->initUploadForm()->withRequest($this->request);
486 $this->tpl->setContent($this->getCreationFormsHTML($form));
487 return;
488 }
489
490 $processor = new ilObjFileProcessor(
491 $this->stakeholder,
492 $this,
493 $this->storage,
494 $this->file_service_settings
495 );
496
497 $errors = false;
498 foreach ($files as $file_data) {
499 $rid = $this->storage->manage()->find($file_data[0]);
500 if (null !== $rid) {
501 try {
502 $processor->process(
503 $rid,
504 $file_data[1][self::PARAM_TITLE] ?? null,
505 $file_data[1][self::PARAM_DESCRIPTION] ?? null,
506 $data[self::PARAM_COPYRIGHT_ID] ?? null
507 );
508 } catch (Throwable $t) {
509 $errors = true;
510 if (null !== $this->log) {
511 $this->log->error($t->getMessage() . ": " . $t->getTraceAsString());
512 }
513 }
514 }
515 }
516
517 if ($errors) {
518 $this->ui->mainTemplate()->setOnScreenMessage(
519 'failure',
520 $this->lng->txt('could_not_create_file_objs'),
521 true
522 );
523 }
524
525 if ($processor->getInvalidFileNames() !== []) {
526 $this->ui->mainTemplate()->setOnScreenMessage(
527 'info',
528 sprintf(
529 $this->lng->txt('file_upload_info_file_with_critical_extension'),
530 implode(', ', $processor->getInvalidFileNames())
531 ),
532 true
533 );
534 }
535
536 $link = match ($this->id_type) {
537 self::WORKSPACE_NODE_ID => $this->ctrl->getLinkTargetByClass(ilObjWorkspaceRootFolderGUI::class),
538 default => ilLink::_getLink($this->requested_ref_id),
539 };
540
541 $this->ctrl->redirectToURL($link);
542 }
543
544 #[\Override]
545 public function putObjectInTree(ilObject $obj, ?int $parent_node_id = null): void
546 {
547 // this is needed to support multi fileuploads in personal and shared resources
548 $backup_node_id = $this->node_id;
549 parent::putObjectInTree($obj, $parent_node_id);
550 $this->node_id = $backup_node_id;
551 }
552
556 #[\Override]
557 public function update(): void
558 {
559 $data = [];
560 $form = $this->initPropertiesForm();
561 $form = $form->withRequest($this->request);
562 $inputs = $form->getData();
563
567 $title_and_description = $inputs['file_info']['title_and_description'];
568
569 $title = $title_and_description->getTitle();
570 // bugfix mantis 26045:
571 $filename = $this->object->getFileName();
572 if (trim((string) $title) === '') {
573 $title = $filename;
574 }
575 $title = $this->object->appendSuffixToTitle($title, $filename);
576
577 $this->object->handleChangedObjectTitle($title);
578
579 $description = $title_and_description->getLongDescription();
580 $this->object->setDescription($description);
581
582 $updated_title_and_description = new TitleAndDescription($title, $description);
583 $this->object->getObjectProperties()->storePropertyTitleAndDescription($updated_title_and_description);
584
585 $this->object->setImportantInfo($inputs['file_info']['important_info']);
586 $this->object->setRating($inputs['obj_features']['rating'] ?? false);
587 $this->object->setOnclickMode((int) $inputs['file_info']['on_click_action']);
588 $this->object->update();
589
590 $this->object->getObjectProperties()->storePropertyIsOnline($inputs['availability']['online_status']);
591
592 if (($inputs['presentation']['tile_image'] ?? null) !== null) {
593 $this->object->getObjectProperties()->storePropertyTileImage($inputs['presentation']['tile_image']);
594 }
595
596 // BEGIN ChangeEvent: Record update event.
597 if (!empty($data["name"])) {
598 global $DIC;
599 $ilUser = $DIC['ilUser'];
600 ilChangeEvent::_recordWriteEvent($this->object->getId(), $ilUser->getId(), 'update');
601 }
602 // END ChangeEvent: Record update event.
603
604 // Update ecs export settings
605 // $ecs = new ilECSFileSettings($this->object);
606 // $ecs->handleSettingsUpdate(); TODO: reintroduce usage of ECS file settings once they have been made compatible with the new ui components
607
608 $this->tpl->setOnScreenMessage('success', $this->lng->txt("msg_obj_modified"), true);
609 $this->ctrl->redirectByClass(self::class, self::CMD_EDIT);
610 }
611
612 #[\Override]
613 public function edit(): void
614 {
615 global $DIC;
616 $ilErr = $DIC['ilErr'];
617
618 if (!$this->capabilities->get(Capabilities::EDIT_SETTINGS)->isUnlocked()) {
619 $ilErr->raiseError($this->lng->txt("msg_no_perm_write"));
620 }
621
622 $this->initSettingsTab();
623
624 $form = $this->initPropertiesForm();
625
626 // $ecs = new ilECSFileSettings($this->object);
627 // $ecs->addSettingsToForm($form, ilObjFile::OBJECT_TYPE); TODO: reintroduce usage of ECS file settings once they have been made compatible with the new ui components
628
629 $this->tpl->setContent($this->renderer->render($form));
630 }
631
632 protected function initPropertiesForm(): Standard
633 {
634 $title_and_description = $this->object->getObjectProperties()->getPropertyTitleAndDescription()->toForm(
635 $this->lng,
636 $this->ui->factory()->input()->field(),
637 $this->refinery
638 );
639
640 $important_info = $this->inputs->field()->markdown(
642 $this->lng->txt('important_info'),
643 $this->lng->txt('important_info_byline')
644 )->withValue(
645 $this->object->getImportantInfo() ?? ""
646 );
647
648 $on_click_action = $this->inputs->field()->radio(
649 $this->lng->txt('on_click_action')
650 )->withOption(
652 $this->lng->txt('file_action_download'),
653 $this->lng->txt('file_action_download_info'),
654 )->withOption(
656 $this->lng->txt('file_action_show'),
657 $this->lng->txt('file_action_show_info'),
658 )->withValue(
659 (string) $this->object->getOnClickMode()
660 );
661
662 $input_groups = array_filter([
663 "title_and_description" => $title_and_description,
664 "important_info" => $important_info,
665 "on_click_action" => $on_click_action
666 ], static fn(FormInput $input): bool => null !== $input);
667
668 $file_info_section = $this->inputs->field()->section(
669 $input_groups,
670 $this->lng->txt('file_info')
671 );
672
673 $online_status = $this->object->getObjectProperties()->getPropertyIsOnline()->toForm(
674 $this->lng,
675 $this->ui->factory()->input()->field(),
676 $this->refinery
677 );
678 $availability_section = $this->inputs->field()->section(
679 ["online_status" => $online_status],
680 $this->lng->txt('rep_activation_availability')
681 );
682
683 $presentation_section = null;
684 if ($this->id_type === self::REPOSITORY_NODE_ID) {
685 $tile_image = $this->object->getObjectProperties()->getPropertyTileImage()->toForm(
686 $this->lng,
687 $this->ui->factory()->input()->field(),
688 $this->refinery
689 );
690 $presentation_section = $this->inputs->field()->section(
691 ["tile_image" => $tile_image],
692 $this->lng->txt('settings_presentation_header')
693 );
694 }
695
696 $additional_features_section = null;
697 if ($this->id_type === self::REPOSITORY_NODE_ID) {
698 $this->lng->loadLanguageModule('rating');
699
700 $enable_rating = $this->inputs->field()->checkbox(
701 $this->lng->txt('rating_activate_rating'),
702 $this->lng->txt('rating_activate_rating_info')
703 )->withValue(
704 $this->object->hasRating()
705 );
706 $additional_features_section = $this->inputs->field()->section(
707 ["rating" => $enable_rating],
708 $this->lng->txt('obj_features')
709 );
710 }
711
712 $inputs = array_filter([
713 "file_info" => $file_info_section,
714 "availability" => $availability_section,
715 "presentation" => $presentation_section,
716 "obj_features" => $additional_features_section
717 ], static fn(?Section $input): bool => null !== $input);
718
719 return $this->inputs->container()->form()->standard(
720 $this->ctrl->getLinkTargetByClass(self::class, 'update'),
721 $inputs
722 );
723 }
724
725 public function sendFile(): bool
726 {
727 $hist_entry_id = $this->request_wrapper->has('hist_id')
728 ? $this->request_wrapper->retrieve('hist_id', $this->refinery->kindlyTo()->int())
729 : null;
730 try {
731 if (ANONYMOUS_USER_ID === $this->user->getId() && $this->request_wrapper->has('transaction')) {
732 $this->object->sendFile($hist_entry_id);
733 }
734
735 if ($this->capabilities->get(Capabilities::DOWNLOAD)->isUnlocked()) {
736 // Record read event and catchup with write events
738 $this->object->getType(),
739 $this->object->getRefId(),
740 $this->object->getId(),
741 $this->user->getId()
742 );
743 $this->updateLearningProgress();
744
745 $this->object->sendFile($hist_entry_id);
746 } else {
747 $this->error->raiseError($this->lng->txt("permission_denied"), $this->error->MESSAGE);
748 }
749 } catch (FileNotFoundException $e) {
750 $this->error->raiseError($e->getMessage(), $this->error->MESSAGE);
751 }
752
753 return true;
754 }
755
759 public function showSummary(): void
760 {
761 $this->ctrl->redirectToURL(
762 (string) $this->capabilities->get(Capabilities::INFO_PAGE)->getUri()
763 );
764 }
765 public function showSummaryForced(): void
766 {
767 $this->ctrl->redirectToURL(
768 (string) $this->capabilities->get(Capabilities::FORCED_INFO_PAGE)->getUri()
769 );
770 }
771
772 public function versions(): void
773 {
774 $this->ctrl->redirectToURL(
775 (string) $this->capabilities->get(Capabilities::MANAGE_VERSIONS)->getUri()
776 );
777 }
778
779 public function unzipCurrentRevision(): void
780 {
781 $this->ctrl->redirectToURL(
782 (string) $this->capabilities->get(Capabilities::UNZIP)->getUri()
783 );
784 }
785
786 protected function editExternal(): void
787 {
788 $this->ctrl->redirectToURL(
789 (string) $this->capabilities->get(Capabilities::EDIT_EXTERNAL)->getUri()
790 );
791 }
792 protected function viewExternal(): void
793 {
794 $this->ctrl->redirectToURL(
795 (string) $this->capabilities->get(Capabilities::VIEW_EXTERNAL)->getUri()
796 );
797 }
798
802 public function infoScreenForward(): void
803 {
804 $this->tabs_gui->activateTab("id_info");
805
806 if (!$this->capabilities->get(Capabilities::INFO_PAGE)->isUnlocked()) {
807 $GLOBALS['DIC']['ilErr']->raiseError(
808 $this->lng->txt("msg_no_perm_read"),
809 2
810 ); // TODO remove magic number and old ilErr call
811 }
812
813 // add set completed button, if LP mode is active
814 if ($this->object->getLPMode() === ilLPObjSettings::LP_MODE_MANUAL) {
815 if (ilLPStatus::_hasUserCompleted($this->object->getId(), $this->user->getId())) {
816 $label = $this->lng->txt('file_btn_lp_toggle_state_completed');
817 } else {
818 $label = $this->lng->txt('file_btn_lp_toggle_state_not_completed');
819 }
820 $this->toolbar->addComponent(
821 $this->ui->factory()->button()->standard(
822 $label,
823 $this->ctrl->getLinkTarget($this, 'toggleLearningProgress')
824 )
825 );
826 }
827
828 // Add WOPI editor Button
829 if ($this->capabilities->get(Capabilities::EDIT_EXTERNAL)->isUnlocked()) {
830 $external_editor = $this->ui->factory()
831 ->button()
832 ->standard(
833 $this->lng->txt('open_external_editor'),
834 $this->ctrl->getLinkTargetByClass(
835 \ilWOPIEmbeddedApplicationGUI::class,
837 )
838 );
839 $this->toolbar->addComponent($external_editor);
840 }
841
842 $info = $this->buildInfoScreen(false);
843 $this->ctrl->forwardCommand($info);
844 }
845
846 protected function toggleLearningProgress(): void
847 {
849 $this->user->getId(),
850 $this->obj_id,
851 $this->ref_id,
852 'file'
853 );
854
855 $lp_marks = new ilLPMarks($this->obj_id, $this->user->getId());
856 $lp_marks->setCompleted(!ilLPStatus::_hasUserCompleted($this->object->getId(), $this->user->getId()));
857 $lp_marks->update();
858
859 ilLPStatusWrapper::_updateStatus($this->obj_id, $this->user->getId());
860
861 $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
862 $this->ctrl->redirect($this, Capabilities::INFO_PAGE->value);
863 }
864
865 public function buildInfoScreen(bool $kiosk_mode): ilInfoScreenGUI
866 {
867 $info = new ilInfoScreenGUI($this);
868
869 if (!$kiosk_mode) { // in kiosk mode we don't want to show the following sections
870 $info->enablePrivateNotes();
871
872 if ($this->capabilities->get(Capabilities::DOWNLOAD)->isUnlocked()) {
873 $info->enableNews();
874 }
875
876 // no news editing for files, just notifications
877 $info->enableNewsEditing(false);
878 if ($this->capabilities->get(Capabilities::MANAGE_VERSIONS)->isUnlocked()) {
879 $news_set = new ilSetting("news");
880 $enable_internal_rss = $news_set->get("enable_rss_for_internal");
881
882 if ($enable_internal_rss) {
883 $info->setBlockProperty("news", "settings", true);
884 $info->setBlockProperty("news", "public_notifications_option", true);
885 }
886 }
887
888 $obj_id = $this->object->getId();
889 $record_gui = new ilAdvancedMDRecordGUI(
891 'file',
892 $obj_id,
893 '',
894 0,
895 $this->call_by_reference
896 );
897 $record_gui->setInfoObject($info);
898 $record_gui->parse();
899 }
900 // show rating is not possible in kiosk mode
901
902 // Important Information
903 $important_info = $this->object->getImportantInfo();
904 if (!empty($important_info)) {
905 $group = new Group(new Factory(), $this->lng);
906 $markdown_to_html = $group->markdown()->toHTML();
907
908 $info->addSection($this->lng->txt("important_info"));
909 $info->addProperty("", $markdown_to_html->transform($important_info));
910 }
911
912 // Download Launcher
913 if ($this->capabilities->get(Capabilities::DOWNLOAD)->isUnlocked()) {
914 // get permanent download link for repository
915 if ($this->id_type === self::REPOSITORY_NODE_ID) {
916 $download_target = ilObjFileAccess::_getPermanentDownloadLink($this->node_id);
917 } else {
918 $download_target = rtrim(ILIAS_HTTP_PATH, '/') . '/' . $this->ctrl->getLinkTarget(
919 $this,
920 self::CMD_SEND_FILE
921 );
922 }
923 $url = $this->data_factory->uri($download_target);
924 $link = $this->data_factory->link($this->lng->txt('file_download'), $url);
925 $download_launcher = $this->ui->factory()->launcher()->inline($link);
926 // create own section for download launcher if there is no important info section
927 if (empty($important_info)) {
928 $info->addSection("");
929 }
930 // add download launcher
931 $info->addProperty("", $this->renderer->render($download_launcher));
932 }
933
934 // standard meta data
935 $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
936
937 // in kiosk mode we don't want to show the following sections
938 // links to resource
939 if (!$kiosk_mode && ($this->access->checkAccess("write", "", $this->ref_id) ||
940 $this->access->checkAccess("edit_permissions", "", $this->ref_id))) {
941 $rs = ilObject::_getAllReferences($this->obj_id);
942 $refs = [];
943 foreach ($rs as $r) {
944 if ($this->tree->isInTree($r)) {
945 $refs[] = $r;
946 }
947 }
948 if (count($refs) > 1) {
949 $links = $sep = "";
950 foreach ($refs as $r) {
951 $cont_loc = new ilLocatorGUI();
952 $cont_loc->addContextItems($r, true);
953 $links .= $sep . $cont_loc->getHTML();
954 $sep = "<br />";
955 }
956
957 $info->addProperty(
958 $this->lng->txt("res_links"),
959 '<div class="small">' . $links . '</div>'
960 );
961 }
962 }
963
964 // File Info
965 $info->addSection($this->lng->txt("file_info"));
966 if ($kiosk_mode) {
967 $file_info_for_users = $this->getFileInfoForUsers();
968 foreach ($file_info_for_users as $file_info_entry_key => $file_info_entry_value) {
969 if ($file_info_entry_value !== null) {
970 $info->addProperty($file_info_entry_key, $file_info_entry_value);
971 }
972 }
973 } else {
974 $file_info = $this->getAllFileInfoForCurrentUser();
975 foreach ($file_info as $file_info_block) {
976 foreach ($file_info_block as $file_info_entry_key => $file_info_entry_value) {
977 if ($file_info_entry_value !== null) {
978 $info->addProperty($file_info_entry_key, $file_info_entry_value);
979 }
980 }
981 }
982 }
983
984 $info->hideFurtherSections(false);
985
986 return $info;
987 }
988
989 // get tabs
990 #[\Override]
991 protected function setTabs(): void
992 {
993 global $DIC;
994 $ilHelp = $DIC['ilHelp'];
995 $ilHelp->setScreenIdComponent(ilObjFile::OBJECT_TYPE);
996
997 $this->ctrl->setParameter($this, "ref_id", $this->node_id);
998
999 if (($c = $this->capabilities->get(Capabilities::VIEW_EXTERNAL)) && $c->isUnlocked()) {
1000 $this->tabs_gui->addTab(
1001 "content",
1002 $this->lng->txt("content"),
1003 $c->getURI()
1004 );
1005 }
1006
1007 if (($c = $this->capabilities->get(Capabilities::MANAGE_VERSIONS)) && $c->isUnlocked()) {
1008 $this->tabs_gui->addTab(
1009 "id_versions",
1010 $this->lng->txt(self::CMD_VERSIONS),
1011 $this->ctrl->getLinkTargetByClass(ilFileVersionsGUI::class, ilFileVersionsGUI::CMD_DEFAULT)
1012 );
1013 }
1014
1015 if (($c = $this->capabilities->get(Capabilities::INFO_PAGE)) && $c->isUnlocked()) {
1016 $this->tabs_gui->addTab(
1017 "id_info",
1018 $this->lng->txt("info_short"),
1019 $this->ctrl->getLinkTargetByClass(["ilobjfilegui", "ilinfoscreengui"], "showSummary")
1020 );
1021 }
1022
1023 if (($c = $this->capabilities->get(Capabilities::EDIT_SETTINGS)) && $c->isUnlocked()) {
1024 $this->tabs_gui->addTab(
1025 "settings",
1026 $this->lng->txt("settings"),
1027 $this->ctrl->getLinkTarget($this, self::CMD_EDIT)
1028 );
1029 }
1030
1031 if (ilLearningProgressAccess::checkAccess($this->object->getRefId())) {
1032 $this->tabs_gui->addTab(
1033 'learning_progress',
1034 $this->lng->txt('learning_progress'),
1035 $this->ctrl->getLinkTargetByClass([self::class, 'illearningprogressgui'], '')
1036 );
1037 }
1038
1039 // meta data
1040 if (($c = $this->capabilities->get(Capabilities::EDIT_SETTINGS)) && $c->isUnlocked()) {
1041 $mdgui = new ilObjectMetaDataGUI($this->object, null, null, $this->call_by_reference);
1042 $mdtab = $mdgui->getTab();
1043 if ($mdtab) {
1044 $this->tabs_gui->addTab(
1045 "id_meta",
1046 $this->lng->txt("meta_data"),
1047 $mdtab
1048 );
1049 }
1050 }
1051
1052 // export
1053 if (($c = $this->capabilities->get(Capabilities::EDIT_SETTINGS)) && $c->isUnlocked()) {
1054 $this->tabs_gui->addTab(
1055 "export",
1056 $this->lng->txt("export"),
1057 $this->ctrl->getLinkTargetByClass("ilexportgui", "")
1058 );
1059 }
1060
1061 // will add permission tab if needed
1062 parent::setTabs();
1063 }
1064
1065 protected function initSettingsTab(): void
1066 {
1067 $this->tabs_gui->activateTab("settings");
1068 // add subtab for common settings
1069 $this->tabs_gui->addSubTab(
1070 'file_settings',
1071 $this->lng->txt('settings'),
1072 $this->ctrl->getLinkTargetByClass(self::class, self::CMD_EDIT)
1073 );
1074 if (in_array('file', ilAdvancedMDRecord::_getActivatedObjTypes(), true)) {
1075 $this->tabs_gui->addSubTab(
1076 'service_settings',
1077 $this->lng->txt('service_settings'),
1078 $this->ctrl->getLinkTargetByClass(ilFileCommonSettingsGUI::class, ilFileCommonSettingsGUI::CMD_EDIT)
1079 );
1080 }
1081
1082 $this->tabs_gui->activateSubTab("file_settings");
1083 }
1084
1085 public static function _goto($a_target, $a_additional = null): void
1086 {
1087 global $DIC;
1088 $main_tpl = $DIC->ui()->mainTemplate();
1089 $ilErr = $DIC['ilErr'];
1090 $lng = $DIC['lng'];
1091 $ilAccess = $DIC['ilAccess'];
1092
1093 if ($a_additional && str_ends_with((string) $a_additional, "wsp")) {
1095 }
1096
1097 // added support for direct download goto links
1098 if ($a_additional && str_ends_with((string) $a_additional, "download")) {
1099 ilObjectGUI::_gotoRepositoryNode($a_target, "sendfile");
1100 }
1101
1102 // static method, no workspace support yet
1103
1104 if ($ilAccess->checkAccess("visible", "", $a_target)
1105 || $ilAccess->checkAccess("read", "", $a_target)) {
1106 ilObjectGUI::_gotoRepositoryNode($a_target, Capabilities::INFO_PAGE->value);
1107 } elseif ($ilAccess->checkAccess("read", "", ROOT_FOLDER_ID)) {
1108 $main_tpl->setOnScreenMessage(
1109 'failure',
1110 sprintf(
1111 $lng->txt("msg_no_perm_read_item"),
1113 ),
1114 true
1115 );
1117 }
1118
1119 $ilErr->raiseError($lng->txt("msg_no_perm_read"), $ilErr->FATAL);
1120 }
1121
1125 protected function addLocatorItems(): void
1126 {
1127 global $DIC;
1128 $ilLocator = $DIC['ilLocator'];
1129
1130 if (is_object($this->object)) {
1131 $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, ""), "", $this->node_id);
1132 }
1133 }
1134
1135 #[\Override]
1136 protected function initHeaderAction(?string $a_sub_type = null, ?int $a_sub_id = null): ?\ilObjectListGUI
1137 {
1138 $lg = parent::initHeaderAction($a_sub_type, $a_sub_id);
1139 if ($lg instanceof ilObjectListGUI && $this->object->hasRating()) {
1140 $lg->enableRating(
1141 true,
1142 null,
1143 false,
1144 [ilCommonActionDispatcherGUI::class, ilRatingGUI::class]
1145 );
1146 }
1147
1148 return $lg;
1149 }
1150
1151 protected function getCtrl(): \ilCtrl
1152 {
1153 return $this->ctrl;
1154 }
1155
1159 protected function getFileObj(): ilObjFile
1160 {
1161 if (!$this->object instanceof ilObjFile) {
1162 throw new ilFileException("Error: object is not of type ilObjFile or doesn't exist");
1163 }
1164
1165 return $this->object;
1166 }
1167
1169 {
1170 return $this->stakeholder;
1171 }
1172
1173 protected function getGeneralSettings(): General
1174 {
1175 return $this->general_settings;
1176 }
1177
1178 protected function getLanguage(): \ilLanguage
1179 {
1180 return $this->lng;
1181 }
1182
1183 protected function getNodeID(): int
1184 {
1185 return $this->node_id;
1186 }
1187
1188 protected function getRefinery(): \ILIAS\Refinery\Factory
1189 {
1190 return $this->refinery;
1191 }
1192
1193 protected function getUIFactory(): ILIAS\UI\Factory
1194 {
1195 return $this->ui->factory();
1196 }
1197
1198 protected function getUser(): ilObjUser
1199 {
1200 return $this->user;
1201 }
1202}
renderer()
$filename
Definition: buildRTE.php:78
Provides fluid interface to RBAC services.
Definition: UIServices.php:25
Builds data types.
Definition: Factory.php:36
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
Indicates that a file is missing or not found.
error(string $a_errmsg)
return true
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getActivatedObjTypes()
get activated obj types
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, $a_ext_rc=null, $a_ext_time=null)
static _recordWriteEvent(int $obj_id, int $usr_id, string $action, ?int $parent_obj_id=null)
Records a write event.
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
Class ilCtrl provides processing control methods.
Export User Interface Class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilInfoScreenGUI.
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
static _hasUserCompleted(int $a_obj_id, int $a_user_id)
Lookup user object completion.
language handling
static checkAccess(int $a_ref_id, bool $a_allow_only_read=true)
check access to learning progress
Class ilObjUserTrackingGUI.
static _tracProgress(int $a_user_id, int $a_obj_id, int $a_ref_id, string $a_obj_type='')
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static _getPermanentDownloadLink(int $ref_id)
Gets the permanent download link for the file.
GUI class for file objects.
LOMServices $lom_services
ServerRequestInterface $request
uploadFiles()
MUST be protected, since this is Called from ilObject2GUI when used in Personal Workspace.
ActionDBRepository $action_repo
const UPLOAD_ORIGIN_DROPZONE
initHeaderAction(?string $a_sub_type=null, ?int $a_sub_id=null)
Add header action menu.
addUIFormToAccordion(ilAccordionGUI $accordion, Standard $form, int $form_type)
getType()
Functions that must be overwritten.
putObjectInTree(ilObject $obj, ?int $parent_node_id=null)
Add object to tree at given position.
initCreateForm(string $new_type)
ILIAS UI Component Input Factory $inputs
const UPLOAD_ORIGIN_STANDARD
CapabilityCollection $capabilities
static _goto($a_target, $a_additional=null)
IconDatabaseRepository $icon_repo
ILIAS Refinery Factory $refinery
buildInfoScreen(bool $kiosk_mode)
infoScreenForward()
show information screen
General $general_settings
__construct(int $a_id=0, int $a_id_type=self::REPOSITORY_NODE_ID, int $a_parent_node_id=0)
Constructor.
ilObjectService $obj_service
ilFileServicesSettings $file_service_settings
ResourceStakeholder $stakeholder
addLegacyFormToAccordion(ilAccordionGUI $accordion, ilPropertyFormGUI $form, int $form_type)
addLocatorItems()
Functions to be overwritten.
UploadHandler $upload_handler
setTabs()
create tabs (repository/workspace switch)
Class ilObjFileProcessorInterface.
Class ilObjFileStakeholder.
Class ilObjFile.
const CLICK_MODE_DOWNLOAD
const CLICK_MODE_INFOPAGE
const OBJECT_TYPE
User class.
New implementation of ilObjectGUI.
executeCommand()
execute command
ilGlobalTemplateInterface $tpl
prepareOutput(bool $show_sub_objects=true)
GUI class for the workflow of copying objects.
static _gotoSharedWorkspaceNode(int $wsp_id)
static _gotoRepositoryRoot(bool $raise_error=false)
Goto repository root.
addHeaderAction()
Add header action menu.
static _gotoRepositoryNode(int $ref_id, string $cmd="")
Class ilObjectMetaDataGUI.
Class ilObject Basic functions for all objects.
static _getAllReferences(int $id)
get all reference ids for object ID
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
This class represents a property form user interface.
ILIAS Setting Class.
special template class to simplify handling of ITX/PEAR
static getGotoLink(int $a_node_id, int $a_obj_id, string $a_additional="")
const ANONYMOUS_USER_ID
Definition: constants.php:27
const ROOT_FOLDER_ID
Definition: constants.php:32
$c
Definition: deliver.php:25
$info
Definition: entry_point.php:21
setVariable(string $variable, $value='')
Sets the given variable to the given value.
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
This describes inputs that can be used in forms.
Definition: FormInput.php:33
This describes a standard form.
Definition: Standard.php:30
This describes section inputs.
Definition: Section.php:29
An entity that renders components to a string output.
Definition: Renderer.php:31
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $lng
Definition: privfeed.php:31
$ilErr
Definition: raiseError.php:33
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:68
trait ilObjFileCopyrightInput
getLanguage()
trait ilObjFileInfoProvider
trait ilObjFileTransformation
$GLOBALS["DIC"]
Definition: wac.php:54