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