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