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