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