ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilObjectListGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
33 
46 {
47  public const IL_LIST_AS_TRIGGER = 'trigger';
48  public const IL_LIST_FULL = 'full';
49 
50  public const DETAILS_MINIMAL = 10;
51  public const DETAILS_SEARCH = 20 ;
52  public const DETAILS_ALL = 30;
53 
54  public const CONTEXT_REPOSITORY = 1;
55  public const CONTEXT_WORKSPACE = 2;
56  public const CONTEXT_WORKSPACE_SHARING = 4;
57  public const CONTEXT_PERSONAL_DESKTOP = 5;
58  public const CONTEXT_SEARCH = 6;
59 
60  public const DOWNLOAD_CHECKBOX_NONE = 0;
61  public const DOWNLOAD_CHECKBOX_ENABLED = 1;
62  public const DOWNLOAD_CHECKBOX_DISABLED = 2;
63 
64  protected static array $cnt_notes = [];
65  protected static array $cnt_tags = [];
66  protected static array $tags = [];
67  protected static array $comments_activation = [];
68  protected static bool $preload_done = false;
69  protected static int $js_unique_id = 0;
70  protected static string $tpl_file_name = 'tpl.container_list_item.html';
71  protected static string $tpl_component = 'Services/Container';
72  private \ILIAS\Notes\Service $notes_service;
73  protected bool $force_rate_parent = false;
74 
75  protected array $access_cache;
77  protected ilObjUser $user;
81  protected ilTree $tree;
82  protected ilSetting $settings;
83  protected HTTPServices $http;
84  protected UIServices $ui;
88  protected ilLanguage $lng;
89  protected string $mode;
90  protected bool $path_enabled;
91  protected int $context;
94 
95  protected bool $static_link_enabled = false;
96  protected bool $delete_enabled = false;
97  protected bool $cut_enabled = false;
98  protected bool $subscribe_enabled = false;
99  protected bool $link_enabled = false;
100  protected bool $copy_enabled = true;
101  protected bool $progress_enabled = false;
102  protected bool $notice_properties_enabled = true;
103  protected bool $info_screen_enabled = false;
104  protected string $type;
105  protected string $gui_class_name = '';
106  protected array $commands = [];
107 
110  protected int $requested_ref_id;
111  protected string $requested_cmd;
112  protected string $requested_base_class;
114 
115 
116  protected bool $description_enabled = true;
117  protected bool $preconditions_enabled = true;
118  protected bool $properties_enabled = true;
119  protected bool $commands_enabled = true;
120  protected array $cust_prop = [];
122  protected array $cust_commands = [];
124  protected array $cust_modals = [];
125  protected int $condition_depth = 0;
126  protected bool $std_cmd_only = false;
127  protected array $sub_item_html = [];
128  protected bool $multi_download_enabled = false;
129  protected int $download_checkbox_state = self::DOWNLOAD_CHECKBOX_NONE;
130  protected int $obj_id;
131  protected int $ref_id;
132  protected int $sub_obj_id;
133  protected ?string $sub_obj_type;
135  protected bool $substitutions_enabled = false;
136  protected bool $icons_enabled = false;
137  protected bool $checkboxes_enabled = false;
138  protected bool $position_enabled = false;
139  protected bool $item_detail_links_enabled = false;
140  protected array $item_detail_links = [];
141  protected string $item_detail_links_intro = '';
142  protected bool $search_fragments_enabled = false;
143  protected string $search_fragment = '';
144  protected bool $path_linked = false;
145  protected bool $enabled_relevance = false;
146  protected int $relevance = 0;
147  protected bool $expand_enabled = false;
148  protected bool $is_expanded = true;
149  protected bool $bold_title = false;
150  protected int $details_level = self::DETAILS_ALL;
151  protected int $reference_ref_id = 0;
152  protected ?int $reference_obj_id = null;
153  protected bool $separate_commands = false;
154  protected bool $search_fragment_enabled = false;
155  protected ?string $additional_information = '';
156  protected bool $repository_transfer_enabled = false;
157  protected bool $shared = false;
158  protected bool $restrict_to_goto = false;
159  protected bool $comments_enabled = false;
160  protected bool $comments_settings_enabled = false;
161  protected bool $notes_enabled = false;
162  protected bool $tags_enabled = false;
163  protected bool $rating_enabled = false;
164  protected bool $rating_categories_enabled = false;
165  protected ?string $rating_text = null;
166  protected ?array $rating_ctrl_path = null;
167  protected bool $timings_enabled = true;
168  protected bool $force_visible_only = false;
169  protected array $prevent_duplicate_commands = [];
170  protected int $parent_ref_id;
171  protected string $title_link = '';
172  protected bool $title_link_disabled = false;
173  protected bool $lp_cmd_enabled = false;
175  protected ?ilPathGUI $path_gui = null;
176  protected array $default_command_params = [];
177  protected array $header_icons = [];
178  protected ?object $container_obj = null;
179  protected ilTemplate $tpl;
180  protected string $position_value;
181  protected int $path_start_node;
182  protected array $default_command = [];
183  protected bool $adm_commands_included;
184  protected bool $prevent_access_caching;
185  protected array $condition_target;
186  protected array $notice_prop = [];
187  protected string $ajax_hash;
189  protected string $position_field_index = '';
190  protected string $title = '';
191  protected string $description = '';
193 
194  public function __construct(int $context = self::CONTEXT_REPOSITORY)
195  {
197  global $DIC;
198 
199  $this->access = $DIC['ilAccess'];
200  $this->user = $DIC['ilUser'];
201  $this->object_dic = ilObjectDIC::dic();
202  $this->obj_definition = $DIC['objDefinition'];
203  $this->tree = $DIC['tree'];
204  $this->settings = $DIC['ilSetting'];
205  $this->http = $DIC->http();
206  $this->ui = $DIC->ui();
207  $this->main_tpl = $DIC['tpl'];
208  $this->rbacsystem = $DIC['rbacsystem'];
209  $this->ctrl = $DIC['ilCtrl'];
210  $this->lng = $DIC['lng'];
211  $this->mode = self::IL_LIST_FULL;
212  $this->path_enabled = false;
213  $this->context = $context;
214  $this->request_wrapper = $DIC->http()->wrapper()->query();
215  $this->refinery = $DIC['refinery'];
216 
217  $this->enableComments(false);
218  $this->enableNotes(false);
219  $this->enableTags(false);
220 
221  // unique js-ids
222  $this->setParentRefId((int) ($_REQUEST['ref_id'] ?? 0));
223 
224  $this->init();
225 
226  $this->ldap_mapping = ilLDAPRoleGroupMapping::_getInstance();
227  $this->fav_manager = new ilFavouritesManager();
228 
229  $this->lng->loadLanguageModule('obj');
230  $this->lng->loadLanguageModule('rep');
231  $params = $DIC->http()->request()->getQueryParams();
232  $this->requested_ref_id = (int) ($params['ref_id'] ?? null);
233  $this->requested_cmd = (string) ($params['cmd'] ?? null);
234  $this->requested_base_class = (string) ($params['baseClass'] ?? null);
235  $this->clipboard = $DIC
236  ->repository()
237  ->internal()
238  ->domain()
239  ->clipboard();
240  $this->notes_service = $DIC->notes();
241  }
242 
243  public function setContainerObject(object $container_obj): void
244  {
245  $this->container_obj = $container_obj;
246  }
247 
248  public function getContainerObject(): ?object
249  {
250  return $this->container_obj;
251  }
252 
253 
259  public function init(): void
260  {
261  // Create static links for default command (linked title) or not
262  $this->static_link_enabled = true;
263  $this->delete_enabled = true;
264  $this->cut_enabled = true;
265  $this->subscribe_enabled = true;
266  $this->link_enabled = false;
267  $this->copy_enabled = false;
268  $this->progress_enabled = false;
269  $this->notice_properties_enabled = true;
270  $this->info_screen_enabled = false;
271  $this->type = ''; // 'cat', 'course', ...
272  $this->gui_class_name = ''; // 'ilobjcategorygui', 'ilobjcoursegui', ...
273 
274  // general commands array, e.g.
275  $this->commands = ilObjectAccess::_getCommands();
276  }
277 
278  public function enableProperties(bool $status): void
279  {
280  $this->properties_enabled = $status;
281  }
282 
283  public function getPropertiesStatus(): bool
284  {
286  }
287 
288  public function enablePreconditions(bool $status): void
289  {
290  $this->preconditions_enabled = $status;
291  }
292 
293  public function getPreconditionsStatus(): bool
294  {
296  }
297 
298  public function enableNoticeProperties(bool $status): void
299  {
300  $this->notice_properties_enabled = $status;
301  }
302 
303  public function getNoticePropertiesStatus(): bool
304  {
306  }
307 
308  public function enableDescription(bool $status): void
309  {
310  $this->description_enabled = $status;
311  }
312 
313  public function getDescriptionStatus(): bool
314  {
316  }
317 
318  public function enableSearchFragments(bool $status): void
319  {
320  $this->search_fragment_enabled = $status;
321  }
322 
323  public function getSearchFragmentStatus(): bool
324  {
326  }
327 
328  public function enableLinkedPath(bool $status): void
329  {
330  $this->path_linked = $status;
331  }
332 
333  public function enableRelevance(bool $status): void
334  {
335  $this->enabled_relevance = $status;
336  }
337 
338  public function enabledRelevance(): bool
339  {
341  }
342 
343  public function setRelevance(int $rel): void
344  {
345  $this->relevance = $rel;
346  }
347 
348  public function getRelevance(): int
349  {
350  return $this->relevance;
351  }
352 
353  public function enableIcon(bool $status): void
354  {
355  $this->icons_enabled = $status;
356  }
357 
358  public function getIconStatus(): bool
359  {
360  return $this->icons_enabled;
361  }
362 
363  public function enableCheckbox(bool $status): void
364  {
365  $this->checkboxes_enabled = $status;
366  }
367 
368  public function getCheckboxStatus(): bool
369  {
371  }
372 
373  public function enableExpand(bool $status): void
374  {
375  $this->expand_enabled = $status;
376  }
377 
378  public function getExpandStatus(): bool
379  {
380  return $this->expand_enabled;
381  }
382 
383  public function setExpanded(bool $status): void
384  {
385  $this->is_expanded = $status;
386  }
387 
388  public function isExpanded(): bool
389  {
390  return $this->is_expanded;
391  }
396  public function setPositionInputField(string $field_index, string $position_value): void
397  {
398  $this->position_enabled = true;
399  $this->position_field_index = $field_index;
400  $this->position_value = $position_value;
401  }
402 
403  public function enableDelete(bool $status): void
404  {
405  $this->delete_enabled = $status;
406  }
407 
408  public function getDeleteStatus(): bool
409  {
410  return $this->delete_enabled;
411  }
412 
413  public function enableCut(bool $status): void
414  {
415  $this->cut_enabled = $status;
416  }
417 
418  public function getCutStatus(): bool
419  {
420  return $this->cut_enabled;
421  }
422 
423  public function enableCopy(bool $status): void
424  {
425  $this->copy_enabled = $status;
426  }
427 
428  public function getCopyStatus(): bool
429  {
430  return $this->copy_enabled;
431  }
432 
433  public function enableSubscribe(bool $status): void
434  {
435  $this->subscribe_enabled = $status;
436  }
437 
438  public function getSubscribeStatus(): bool
439  {
441  }
442 
443  public function enableLink(bool $status): void
444  {
445  $this->link_enabled = $status;
446  }
447 
448  public function getLinkStatus(): bool
449  {
450  return $this->link_enabled;
451  }
452 
453  public function enablePath(bool $path, int $start_node = 0, \ilPathGUI $path_gui = null): void
454  {
455  $this->path_enabled = $path;
456  $this->path_start_node = $start_node;
457  $this->path_gui = $path_gui;
458  }
459 
460  public function getPathStatus(): bool
461  {
462  return $this->path_enabled;
463  }
464 
465  public function enableCommands(bool $status, bool $std_only = false): void
466  {
467  $this->commands_enabled = $status;
468  $this->std_cmd_only = $std_only;
469  }
470 
471  public function getCommandsStatus(): bool
472  {
474  }
475 
476  public function enableInfoScreen(bool $info_screen): void
477  {
478  $this->info_screen_enabled = $info_screen;
479  }
480 
481  public function getInfoScreenStatus(): bool
482  {
484  }
485 
486  protected function enableLearningProgress(bool $enabled): void
487  {
488  $this->lp_cmd_enabled = $enabled;
489  }
490 
496  public function addSubItemHTML(string $html): void
497  {
498  $this->sub_item_html[] = $html;
499  }
500 
501  public function enableProgressInfo(bool $status): void
502  {
503  $this->progress_enabled = $status;
504  }
505 
506  public function getProgressInfoStatus(): bool
507  {
509  }
510 
511  public function enableSubstitutions(bool $status): void
512  {
513  $this->substitutions_enabled = $status;
514  }
515 
516  public function getSubstitutionStatus(): bool
517  {
519  }
520 
525  public function enableItemDetailLinks(bool $status): void
526  {
527  $this->item_detail_links_enabled = $status;
528  }
529 
533  public function getItemDetailLinkStatus(): bool
534  {
536  }
537 
543  public function setItemDetailLinks(array $detail_links, string $intro_txt = ''): void
544  {
545  $this->item_detail_links = $detail_links;
546  $this->item_detail_links_intro = $intro_txt;
547  }
548 
549  public function insertItemDetailLinks(): void
550  {
551  if (!count($this->item_detail_links)) {
552  return;
553  }
554  if (strlen($this->item_detail_links_intro)) {
555  $this->tpl->setCurrentBlock('item_detail_intro');
556  $this->tpl->setVariable('ITEM_DETAIL_INTRO_TXT', $this->item_detail_links_intro);
557  $this->tpl->parseCurrentBlock();
558  }
559 
560  foreach ($this->item_detail_links as $info) {
561  $this->tpl->setCurrentBlock('item_detail_link');
562  $this->tpl->setVariable('ITEM_DETAIL_LINK_TARGET', $info['target']);
563  $this->tpl->setVariable('ITEM_DETAIL_LINK_DESC', $info['desc']);
564  $this->tpl->setVariable('ITEM_DETAIL_LINK_HREF', $info['link']);
565  $this->tpl->setVariable('ITEM_DETAIL_LINK_NAME', $info['name']);
566  $this->tpl->parseCurrentBlock();
567  }
568  $this->tpl->setCurrentBlock('item_detail_links');
569  $this->tpl->parseCurrentBlock();
570  }
571  public function setTitle(string $title): void
572  {
573  $this->title = strip_tags(
574  $title,
576  );
577  }
578 
582  public function getTitle(): string
583  {
584  return $this->title;
585  }
586 
587  public function setDescription(string $description): void
588  {
589  $this->description = strip_tags(
590  $description,
592  );
593  }
594 
598  public function getDescription(): string
599  {
600  return $this->description;
601  }
602 
606  public function setSearchFragment(string $text): void
607  {
608  $this->search_fragment = $text;
609  }
610 
611  public function getSearchFragment(): string
612  {
613  return $this->search_fragment;
614  }
615 
616  public function setSeparateCommands(bool $val): void
617  {
618  $this->separate_commands = $val;
619  }
620 
621  public function getSeparateCommands(): bool
622  {
624  }
625 
631  public function getCommandId(): int
632  {
633  return $this->ref_id;
634  }
635 
636  public function setAdditionalInformation(?string $val): void
637  {
638  $this->additional_information = $val;
639  }
640 
641  public function getAdditionalInformation(): ?string
642  {
644  }
645 
651  public function setDetailsLevel(int $level): void
652  {
653  $this->details_level = $level;
654  }
655 
656  public function getDetailsLevel(): int
657  {
658  return $this->details_level;
659  }
660 
664  public function enableRepositoryTransfer(bool $value): void
665  {
666  $this->repository_transfer_enabled = $value;
667  }
668 
672  public function restrictToGoto(bool $value): void
673  {
674  $this->restrict_to_goto = $value;
675  }
676 
677  public function getDefaultCommand(): array
678  {
679  return $this->default_command;
680  }
681 
682  public function checkCommandAccess(
683  string $permission,
684  string $cmd,
685  int $ref_id,
686  string $type,
687  ?int $obj_id = null
688  ): bool {
689  // e.g: sub items should not be readable since their parent session is readonly.
690  if ($permission != 'visible' and $this->isVisibleOnlyForced()) {
691  return false;
692  }
693 
694  $cache_prefix = null;
695  if ($this->context == self::CONTEXT_WORKSPACE || $this->context == self::CONTEXT_WORKSPACE_SHARING) {
696  $cache_prefix = 'wsp';
697  if (!isset($this->ws_access)) {
698  $this->ws_access = new ilWorkspaceAccessHandler();
699  }
700  }
701 
702  if (isset($this->access_cache[$permission]['-' . $cmd][$cache_prefix . $ref_id])) {
703  return $this->access_cache[$permission]['-' . $cmd][$cache_prefix . $ref_id];
704  }
705 
706  if ($this->context == self::CONTEXT_REPOSITORY || $this->context == self::CONTEXT_SEARCH) {
707  $access = $this->access->checkAccess($permission, $cmd, $ref_id, $type, (int) $obj_id);
708  if ($this->access->getPreventCachingLastResult()) {
709  $this->prevent_access_caching = true;
710  }
711  } else {
712  $access = $this->ws_access->checkAccess($permission, $cmd, $ref_id, $type);
713  }
714 
715  $this->access_cache[$permission]['-' . $cmd][$cache_prefix . $ref_id] = $access;
716  return $access;
717  }
718 
722  public function initItem(
723  int $ref_id,
724  int $obj_id,
725  string $type,
726  string $title = '',
727  string $description = ''
728  ): void {
729  $this->access_cache = [];
730  $this->ref_id = $ref_id;
731  $this->obj_id = $obj_id;
732  $this->object_properties = $this->object_dic['object_properties_agregator']->getFor($obj_id);
733  $this->setTitle($title);
734  $this->setDescription($description);
735 
736  $this->current_selection_list = new ilAdvancedSelectionListGUI();
737  $this->current_selection_list->setAriaListTitle(
738  sprintf(
739  $this->lng->txt('actions_for'),
740  htmlspecialchars(addslashes($this->getTitle()))
741  )
742  );
743 
744  // checks, whether any admin commands are included in the output
745  $this->adm_commands_included = false;
746  $this->prevent_access_caching = false;
747 
748  // prepare ajax calls
749  if ($this->context == self::CONTEXT_REPOSITORY) {
751  } else {
753  }
754  $this->setAjaxHash(ilCommonActionDispatcherGUI::buildAjaxHash($node_type, $ref_id, $type, $obj_id));
755  }
756 
757  public function setConditionTarget(int $ref_id, int $obj_id, string $target_type): void
758  {
759  $this->condition_target = [
760  'ref_id' => $ref_id,
761  'obj_id' => $obj_id,
762  'target_type' => $target_type
763  ];
764  }
765 
766  public function resetConditionTarget(): void
767  {
768  $this->condition_target = [];
769  }
770 
771  public function disableTitleLink(bool $status): void
772  {
773  $this->title_link_disabled = $status;
774  }
775 
776  public function setDefaultCommandParameters(array $params): void
777  {
778  $this->default_command_params = $params;
779  }
780 
786  public function createDefaultCommand(array $command): array
787  {
788  if ($this->static_link_enabled && !$this->default_command_params) {
789  if ($link = ilLink::_getStaticLink($this->ref_id, $this->type, false)) {
790  $command['link'] = $link;
791  $command['frame'] = '_top';
792  }
793  }
794  if ($this->default_command_params) {
795  $params = [];
796  foreach ($this->default_command_params as $name => $value) {
797  $params[] = $name . '=' . $value;
798  }
799  $params = implode('&', $params);
800 
801  if (!stristr($command['link'], '?')) {
802  $command['link'] .= '?' . $params;
803  } else {
804  $command['link'] .= '&' . $params;
805  }
806  }
807  return $command;
808  }
809 
818  public function getCommandLink(string $cmd): string
819  {
820  if ($this->context == self::CONTEXT_REPOSITORY || $this->context == self::CONTEXT_SEARCH) {
821  // BEGIN WebDAV Get mount webfolder link.
822  if ($cmd == 'mount_webfolder' && ilDAVActivationChecker::_isActive()) {
823  $uri_builder = new ilWebDAVUriBuilder($this->http->request());
824  return $uri_builder->getUriToMountInstructionModalByRef($this->ref_id);
825  }
826  // END WebDAV Get mount webfolder link.
827 
828  $this->ctrl->setParameterByClass('ilrepositorygui', 'ref_id', $this->getCommandId());
829  $cmd_link = $this->ctrl->getLinkTargetByClass('ilrepositorygui', $cmd);
830  $this->ctrl->setParameterByClass('ilrepositorygui', 'ref_id', $this->requested_ref_id);
831  return $cmd_link;
832  }
833 
834  $this->ctrl->setParameterByClass($this->gui_class_name, 'ref_id', '');
835  $this->ctrl->setParameterByClass($this->gui_class_name, 'wsp_id', $this->ref_id);
836  return $this->ctrl->getLinkTargetByClass($this->gui_class_name, $cmd);
837  }
838 
847  public function getCommandFrame(string $cmd): string
848  {
849  return '';
850  }
851 
860  public function getCommandImage(string $cmd): string
861  {
862  return '';
863  }
864 
876  public function getProperties(): array
877  {
878  $props = [];
879 
880  // #8280: WebDav is only supported in repository
881  if ($this->context == self::CONTEXT_REPOSITORY) {
882  // add centralized offline status
883  if (ilObject::lookupOfflineStatus($this->obj_id)) {
884  $props[] =
885  [
886  'alert' => true,
887  'property' => $this->lng->txt('status'),
888  'value' => $this->lng->txt('offline')
889  ];
890  }
891 
892  // BEGIN WebDAV Display locking information
894  // Show lock info
895  $webdav_dic = new ilWebDAVDIC();
896  $webdav_dic->initWithoutDIC();
897  $webdav_lock_backend = $webdav_dic->locksbackend();
898  if ($this->user->getId() !== ANONYMOUS_USER_ID) {
899  if ($lock = $webdav_lock_backend->getLocksOnObjectId($this->obj_id)) {
900  $lock_user = new ilObjUser($lock->getIliasOwner());
901 
902  $props[] = [
903  'alert' => false,
904  'property' => $this->lng->txt('in_use_by'),
905  'value' => $lock_user->getLogin(),
906  'link' =>
907  './ilias.php?user=' .
908  $lock_user->getId() .
909  '&cmd=showUserProfile&cmdClass=ildashboardgui&baseClass=ilDashboardGUI'
910  ];
911  }
912  }
913  }
914  // END WebDAV Display warning for invisible files and files with special characters
915  }
916 
917  return $props;
918  }
919 
920  public function addCustomProperty(
921  string $property = '',
922  string $value = '',
923  bool $alert = false,
924  bool $newline = false
925  ): void {
926  $this->cust_prop[] = [
927  'property' => $property,
928  'value' => $value,
929  'alert' => $alert,
930  'newline' => $newline
931  ];
932  }
933 
934  public function getCustomProperties(array $prop): array
935  {
936  if (is_array($this->cust_prop)) {
937  foreach ($this->cust_prop as $property) {
938  $prop[] = $property;
939  }
940  }
941  return $prop;
942  }
943 
944  public function getAlertProperties(): array
945  {
946  $alert = [];
947  foreach ($this->getProperties() as $prop) {
948  if (isset($prop['alert']) && $prop['alert'] == true) {
949  $alert[] = $prop;
950  }
951  }
952  return $alert;
953  }
954 
955  public function getNoticeProperties(): array
956  {
957  $this->notice_prop = [];
958  if ($infos = $this->ldap_mapping->getInfoStrings($this->obj_id, true)) {
959  foreach ($infos as $info) {
960  $this->notice_prop[] = ['value' => $info];
961  }
962  }
963  return $this->notice_prop;
964  }
965 
966  public function addCustomCommand(string $link, string $lang_var, string $frame = '', string $onclick = ''): void
967  {
968  $this->cust_commands[] = [
969  'link' => $link,
970  'lang_var' => $lang_var,
971  'frame' => $frame,
972  'onclick' => $onclick
973  ];
974  }
975 
976  public function addCustomCommandButton(
977  Button $button,
978  ?Modal $triggeredModal = null
979  ): void {
980  $this->cust_commands[] = $button;
981  if ($triggeredModal !== null) {
982  $this->cust_modals[] = $triggeredModal;
983  }
984  }
985 
986  public function forceVisibleOnly(bool $stat): void
987  {
988  $this->force_visible_only = $stat;
989  }
990 
991  public function isVisibleOnlyForced(): bool
992  {
994  }
995 
1019  public function getCommands(): array
1020  {
1021  $ref_commands = [];
1022  foreach ($this->commands as $command) {
1023  $permission = $command['permission'];
1024  $cmd = $command['cmd'];
1025  $lang_var = $command['lang_var'] ?? '';
1026  $txt = '';
1027  $info_object = null;
1028  $cmd_link = '';
1029  $cmd_frame = '';
1030  $cmd_image = '';
1031  $access_granted = false;
1032 
1033  if (isset($command['txt'])) {
1034  $txt = $command['txt'];
1035  }
1036 
1037  // Suppress commands that don't make sense for anonymous users
1038  if (
1039  $this->user->getId() == ANONYMOUS_USER_ID &&
1040  (isset($command['enable_anonymous']) && $command['enable_anonymous'] == 'false')
1041  ) {
1042  continue;
1043  }
1044 
1045  // all access checking should be made within $this->access and
1046  // the checkAccess of the ilObj...Access classes
1047  // $access = $this->access->checkAccess($permission, $cmd, $this->ref_id, $this->type);
1048  $access = $this->checkCommandAccess($permission, $cmd, $this->ref_id, $this->type);
1049 
1050  if ($access) {
1051  $access_granted = true;
1052  $cmd_link = $this->getCommandLink($command['cmd']);
1053  $cmd_frame = $this->getCommandFrame($command['cmd']);
1054  $cmd_image = $this->getCommandImage($command['cmd']);
1055  } else {
1056  $info_object = $this->access->getInfo();
1057  }
1058 
1059  if (!isset($command['default'])) {
1060  $command['default'] = '';
1061  }
1062  $ref_commands[] = [
1063  'permission' => $permission,
1064  'cmd' => $cmd,
1065  'link' => $cmd_link,
1066  'frame' => $cmd_frame,
1067  'lang_var' => $lang_var,
1068  'txt' => $txt,
1069  'granted' => $access_granted,
1070  'access_info' => $info_object,
1071  'img' => $cmd_image,
1072  'default' => $command['default']
1073  ];
1074  }
1075 
1076  return $ref_commands;
1077  }
1078 
1086  public function getIconImageType(): string
1087  {
1088  return $this->type;
1089  }
1090 
1091  public function insertTitle(): void
1092  {
1093  if ($this->restrict_to_goto) {
1094  $this->default_command = [
1095  'frame' => '',
1096  'link' => $this->buildGotoLink()
1097  ];
1098  }
1099  // begin-patch lok
1100  if ($this->default_command === []
1101  || !$this->getCommandsStatus() && !$this->restrict_to_goto
1102  || $this->title_link_disabled
1103  ) {
1104  // end-patch lok
1105  $this->tpl->setCurrentBlock('item_title');
1106  $this->tpl->setVariable('TXT_TITLE', $this->getTitle());
1107  } else {
1108  $this->default_command['link'] = $this->modifyTitleLink($this->default_command['link']);
1109 
1110  list($this->default_command['link'], $this->default_command['frame']) =
1111  $this->modifySAHSlaunch($this->default_command['link'], $this->default_command['frame']);
1112 
1113  if ($this->default_command['frame'] != '') {
1114  $this->tpl->setCurrentBlock('title_linked_frame');
1115  $this->tpl->setVariable('TARGET_TITLE_LINKED', $this->default_command['frame']);
1116  $this->tpl->parseCurrentBlock();
1117  }
1118 
1119  // workaround for repository frameset
1120  $this->default_command['link'] = $this->appendRepositoryFrameParameter($this->default_command['link']);
1121 
1122  // the default command is linked with the title
1123  $this->tpl->setCurrentBlock('item_title_linked');
1124  $this->tpl->setVariable('TXT_TITLE_LINKED', $this->getTitle());
1125  $this->tpl->setVariable('HREF_TITLE_LINKED', $this->default_command['link']);
1126 
1127  // New Preview Implementation, File-Objects only
1128  if ($this->type === 'file') {
1129  $preview = new ilObjFilePreviewRendererGUI($this->obj_id);
1130  if ($preview->has()) {
1131  $this->tpl->setVariable('PREVIEW_GLYPH', $preview->getRenderedTriggerComponents());
1132  $this->tpl->parseCurrentBlock();
1133  }
1134  }
1135  }
1136  $this->tpl->parseCurrentBlock();
1137 
1138  if ($this->bold_title == true) {
1139  $this->tpl->touchBlock('bold_title_start');
1140  $this->tpl->touchBlock('bold_title_end');
1141  }
1142  }
1143 
1144  protected function buildGotoLink(): ?string
1145  {
1146  switch ($this->context) {
1147  case self::CONTEXT_WORKSPACE_SHARING:
1148  return ilWorkspaceAccessHandler::getGotoLink($this->ref_id, $this->obj_id);
1149 
1150  default:
1151  // not implemented yet
1152  break;
1153  }
1154  return null;
1155  }
1156 
1157  public function insertSubstitutions(): void
1158  {
1159  $fields_shown = false;
1160  foreach ($this->substitutions->getParsedSubstitutions($this->ref_id, $this->obj_id) as $data) {
1161  if ($data['bold']) {
1162  $data['name'] = '<strong>' . $data['name'] . '</strong>';
1163  $data['value'] = '<strong>' . $data['value'] . '</strong>';
1164  }
1165  $this->tpl->touchBlock('std_prop');
1166  $this->tpl->setCurrentBlock('item_property');
1167  if ($data['show_field']) {
1168  $this->tpl->setVariable('TXT_PROP', $data['name']);
1169  }
1170  $this->tpl->setVariable('VAL_PROP', $data['value']);
1171  $this->tpl->parseCurrentBlock();
1172 
1173  if ($data['newline']) {
1174  $this->tpl->touchBlock('newline_prop');
1175  }
1176  $fields_shown = false;
1177  }
1178  }
1179 
1180  public function insertDescription(): void
1181  {
1182  if ($this->getSubstitutionStatus()) {
1183  $this->insertSubstitutions();
1184  if (!$this->substitutions->isDescriptionEnabled()) {
1185  return;
1186  }
1187  }
1188 
1189  // see bug #16519
1190  $d = $this->getDescription();
1191  // even b tag produced bugs, see #32304
1192  $d = strip_tags($d);
1193  $this->tpl->setCurrentBlock('item_description');
1194  $this->tpl->setVariable('TXT_DESC', $d);
1195  $this->tpl->parseCurrentBlock();
1196  }
1197 
1201  public function insertSearchFragment(): void
1202  {
1203  if (strlen($this->getSearchFragment())) {
1204  $this->tpl->setCurrentBlock('search_fragment');
1205  $this->tpl->setVariable('TXT_SEARCH_FRAGMENT', $this->getSearchFragment() . ' ...');
1206  $this->tpl->parseCurrentBlock();
1207  }
1208  }
1209 
1210  public function insertRelevance(): void
1211  {
1212  if (!$this->enabledRelevance() or !$this->getRelevance()) {
1213  return;
1214  }
1215 
1216  $pbar = ilProgressBar::getInstance();
1217  $pbar->setCurrent($this->getRelevance());
1218 
1219  $this->tpl->setCurrentBlock('relevance');
1220  $this->tpl->setVariable('REL_PBAR', $pbar->render());
1221  $this->tpl->parseCurrentBlock();
1222  }
1223 
1229  public function setMode(string $mode): void
1230  {
1231  $this->mode = $mode;
1232  }
1233 
1239  public function getMode(): string
1240  {
1241  return $this->mode;
1242  }
1243 
1247  public function setConditionDepth(int $depth): void
1248  {
1249  $this->condition_depth = $depth;
1250  }
1251 
1258  public function isMode(string $mode): bool
1259  {
1260  return $mode === $this->mode;
1261  }
1262 
1263  public function determineProperties(): array
1264  {
1265  $props = $this->getCustomProperties(
1266  $this->getProperties()
1267  );
1268 
1269  if ($this->context != self::CONTEXT_WORKSPACE && $this->context != self::CONTEXT_WORKSPACE_SHARING) {
1270  // add learning progress custom property
1271  $lp = ilLPStatus::getListGUIStatus($this->obj_id);
1272  if ($lp) {
1273  $props[] = [
1274  'alert' => false,
1275  'property' => $this->lng->txt('learning_progress'),
1276  'value' => $lp,
1277  'newline' => true
1278  ];
1279  }
1280 
1281  // add no item access note in public section
1282  // for items that are visible but not readable
1283  if ($this->user->getId() === ANONYMOUS_USER_ID) {
1284  if (!$this->access->checkAccess('read', '', $this->ref_id, $this->type, $this->obj_id)) {
1285  $props[] = [
1286  'alert' => true,
1287  'value' => $this->lng->txt('no_access_item_public'),
1288  'newline' => true
1289  ];
1290  }
1291  }
1292  }
1293 
1294  // reference objects have translated ids, revert to originals
1295  $note_ref_id = $this->ref_id;
1296  $note_obj_id = $this->obj_id;
1297  if ($this->reference_ref_id) {
1298  $note_ref_id = $this->reference_ref_id;
1299  $note_obj_id = $this->reference_obj_id;
1300  }
1301  $redraw_js = 'il.Object.redrawListItem(' . $note_ref_id . ');';
1302 
1303  // add common properties (comments, notes, tags)
1304  if (
1305  (
1306  (
1307  isset(self::$cnt_notes[$note_obj_id][Note::PRIVATE]) &&
1308  self::$cnt_notes[$note_obj_id][Note::PRIVATE] > 0
1309  ) || (
1310  isset(self::$cnt_notes[$note_obj_id][Note::PUBLIC]) &&
1311  self::$cnt_notes[$note_obj_id][Note::PUBLIC] > 0
1312  ) || (
1313  isset(self::$cnt_tags[$note_obj_id]) && self::$cnt_tags[$note_obj_id] > 0
1314  ) || (
1315  isset(self::$tags[$note_obj_id]) && is_array(self::$tags[$note_obj_id])
1316  )
1317  ) && ($this->user->getId() !== ANONYMOUS_USER_ID)
1318  ) {
1319  $nl = true;
1320  $cnt_comments = self::$cnt_notes[$note_obj_id][Note::PUBLIC] ?? 0;
1321  if ($this->isCommentsActivated($this->type, $this->ref_id, $this->obj_id, false, false)
1322  && $cnt_comments > 0) {
1323  $props[] = [
1324  'alert' => false,
1325  'property' => $this->lng->txt('notes_comments'),
1326  'value' =>
1327  '<a href="#" onclick="return ' .
1328  ilNoteGUI::getListCommentsJSCall($this->ajax_hash, $redraw_js) . '">' .
1329  self::$cnt_notes[$note_obj_id][Note::PUBLIC] . '</a>',
1330  'newline' => $nl
1331  ];
1332  $nl = false;
1333  }
1334 
1335  $cnt_notes = self::$cnt_notes[$note_obj_id][Note::PRIVATE] ?? 0;
1336  if ($this->notes_enabled && $cnt_notes > 0) {
1337  $props[] = [
1338  'alert' => false,
1339  'property' => $this->lng->txt('notes'),
1340  'value' =>
1341  '<a href="#" onclick="return ' .
1342  ilNoteGUI::getListNotesJSCall($this->ajax_hash, $redraw_js) . '">' .
1343  self::$cnt_notes[$note_obj_id][Note::PRIVATE] . '</a>',
1344  'newline' => $nl
1345  ];
1346  $nl = false;
1347  }
1348  $cnt_tags = self::$cnt_tags[$note_obj_id] ?? 0;
1349  if ($this->tags_enabled && ($cnt_tags > 0 || isset(self::$tags[$note_obj_id]))) {
1350  $tags_set = new ilSetting('tags');
1351  if ($tags_set->get('enable')) {
1352  $tags_url = ilTaggingGUI::getListTagsJSCall($this->ajax_hash, $redraw_js);
1353 
1354  // list object tags
1355  if (isset(self::$tags[$note_obj_id])) {
1356  $tags_tmp = [];
1357  foreach (self::$tags[$note_obj_id] as $tag => $is_tag_owner) {
1358  if ($is_tag_owner) {
1359  $tags_tmp[] = '<a class="ilTag ilTagRelHigh" href="#" onclick="return ' .
1360  $tags_url . '">' . $tag . '</a>';
1361  } else {
1362  $tags_tmp[] = '<span class="ilTag ilTagRelMiddle">' . $tag . '</span>';
1363  }
1364  }
1365  $tags_value = implode(' ', $tags_tmp);
1366  $nl = true;
1367  $prop_text = '';
1368  } // tags counter
1369  else {
1370  $tags_value = '<a href="#" onclick="return ' . $tags_url . '>' .
1371  self::$cnt_tags[$note_obj_id] . '</a>';
1372  $prop_text = $this->lng->txt('tagging_tags');
1373  }
1374  $props[] = [
1375  'alert' => false,
1376  'property' => $prop_text,
1377  'value' => $tags_value,
1378  'newline' => $nl
1379  ];
1380  }
1381  }
1382  }
1383 
1384  if (!isset($props)) {
1385  return [];
1386  }
1387 
1388  return $props;
1389  }
1390 
1391  public function insertProperties(): void
1392  {
1393  $props = $this->determineProperties();
1394  $cnt = 1;
1395  if (is_array($props) && count($props) > 0) {
1396  foreach ($props as $prop) {
1397  if ($cnt > 1) {
1398  $this->tpl->touchBlock('separator_prop');
1399  }
1400 
1401  if (isset($prop['alert']) && $prop['alert'] == true) {
1402  $this->tpl->touchBlock('alert_prop');
1403  } else {
1404  $this->tpl->touchBlock('std_prop');
1405  }
1406 
1407  if (isset($prop['newline']) && $prop['newline'] == true && $cnt > 1) {
1408  $this->tpl->touchBlock('newline_prop');
1409  }
1410 
1411  //BEGIN WebDAV: Support hidden property names.
1412  if (
1413  isset($prop['property']) &&
1414  (($prop['propertyNameVisible'] ?? null) !== false) &&
1415  $prop['property'] != ''
1416  ) {
1417  //END WebDAV: Support hidden property names.
1418  $this->tpl->setCurrentBlock('prop_name');
1419  $this->tpl->setVariable('TXT_PROP', $prop['property']);
1420  $this->tpl->parseCurrentBlock();
1421  }
1422 
1423  $this->tpl->setCurrentBlock('item_property');
1424  //BEGIN WebDAV: Support links in property values.
1425  if (isset($prop['link']) && $prop['link']) {
1426  $this->tpl->setVariable('LINK_PROP', $prop['link']);
1427  $this->tpl->setVariable('LINK_VAL_PROP', $prop['value']);
1428  } else {
1429  $this->tpl->setVariable('VAL_PROP', $prop['value']);
1430  }
1431  //END WebDAV: Support links in property values.
1432  $this->tpl->parseCurrentBlock();
1433 
1434  $cnt++;
1435  }
1436  $this->tpl->setCurrentBlock('item_properties');
1437  $this->tpl->parseCurrentBlock();
1438  }
1439  }
1440 
1441  public function insertNoticeProperties(): void
1442  {
1443  $this->getNoticeProperties();
1444  foreach ($this->notice_prop as $property) {
1445  $this->tpl->setCurrentBlock('notice_item');
1446  $this->tpl->setVariable('NOTICE_ITEM_VALUE', $property['value']);
1447  $this->tpl->parseCurrentBlock();
1448  }
1449  $this->tpl->setCurrentBlock('notice_property');
1450  $this->tpl->parseCurrentBlock();
1451  }
1452 
1453  protected function parseConditions(int $toggle_id, array $conditions, bool $obligatory = true): bool
1454  {
1455  $num_required = ilConditionHandler::calculateEffectiveRequiredTriggers($this->ref_id, $this->obj_id);
1456  $num_optional_required =
1457  $num_required -
1458  count($conditions) +
1459  count(ilConditionHandler::getEffectiveOptionalConditionsOfTarget($this->ref_id, $this->obj_id))
1460  ;
1461 
1462  // Check if all conditions are fulfilled
1463  $visible_conditions = [];
1464  $passed_optional = 0;
1465  foreach ($conditions as $condition) {
1466  if ($obligatory && !$condition['obligatory']) {
1467  continue;
1468  }
1469  if (!$obligatory && $condition['obligatory']) {
1470  continue;
1471  }
1472 
1473  if ($this->tree->isDeleted($condition['trigger_ref_id'])) {
1474  continue;
1475  }
1476 
1477  $ok = ilConditionHandler::_checkCondition($condition) && !ilMemberViewSettings::getInstance()->isActive();
1478 
1479  if (!$ok) {
1480  $visible_conditions[] = $condition['id'];
1481  }
1482 
1483  if (!$obligatory && $ok) {
1484  ++$passed_optional;
1485  // optional passed
1486  if ($passed_optional >= $num_optional_required) {
1487  return true;
1488  }
1489  }
1490  }
1491 
1492  $missing_cond_exist = false;
1493  foreach ($conditions as $condition) {
1494  if (!in_array($condition['id'], $visible_conditions)) {
1495  continue;
1496  }
1497 
1498  $operator = ilConditionHandlerGUI::translateOperator($condition['trigger_obj_id'], $condition['operator']);
1499  $cond_txt = $operator . ' ' . $condition['value'];
1500 
1501  // display trigger item
1502  $class = $this->obj_definition->getClassName($condition['trigger_type']);
1503  $location = $this->obj_definition->getLocation($condition['trigger_type']);
1504  if ($class == '' && $location == '') {
1505  continue;
1506  }
1507  $missing_cond_exist = true;
1508 
1509  $full_class = 'ilObj' . $class . 'ListGUI';
1510  $item_list_gui = new $full_class($this->context);
1511  $item_list_gui->setMode(self::IL_LIST_AS_TRIGGER);
1512  $item_list_gui->enablePath(false);
1513  $item_list_gui->enableIcon(true);
1514  $item_list_gui->setConditionDepth($this->condition_depth + 1);
1515  $item_list_gui->setParentRefId($this->ref_id);
1516  $item_list_gui->addCustomProperty($this->lng->txt('precondition_required_itemlist'), $cond_txt, false, true);
1517  $item_list_gui->enableCommands($this->commands_enabled, $this->std_cmd_only);
1518  $item_list_gui->enableProperties($this->properties_enabled);
1519 
1520  $trigger_html = $item_list_gui->getListItemHTML(
1521  $condition['trigger_ref_id'],
1522  $condition['trigger_obj_id'],
1523  ilObject::_lookupTitle($condition['trigger_obj_id']),
1524  ''
1525  );
1526  $this->tpl->setCurrentBlock('precondition');
1527  if ($trigger_html == '') {
1528  $trigger_html = $this->lng->txt('precondition_not_accessible');
1529  }
1530  $this->tpl->setVariable('TXT_CONDITION', trim($cond_txt));
1531  $this->tpl->setVariable('TRIGGER_ITEM', $trigger_html);
1532  $this->tpl->parseCurrentBlock();
1533  }
1534 
1535  if ($missing_cond_exist && $obligatory) {
1536  $this->tpl->setCurrentBlock('preconditions');
1537  $this->tpl->setVariable('CONDITION_TOGGLE_ID', '_obl_' . $toggle_id);
1538  $this->tpl->setVariable('TXT_PRECONDITIONS', $this->lng->txt('preconditions_obligatory_hint'));
1539  $this->tpl->parseCurrentBlock();
1540  } elseif ($missing_cond_exist && !$obligatory) {
1541  $this->tpl->setCurrentBlock('preconditions');
1542  $this->tpl->setVariable('CONDITION_TOGGLE_ID', '_opt_' . $toggle_id);
1543  $this->tpl->setVariable(
1544  'TXT_PRECONDITIONS',
1545  sprintf(
1546  $this->lng->txt('preconditions_optional_hint'),
1547  $num_optional_required - $passed_optional
1548  )
1549  );
1550  $this->tpl->parseCurrentBlock();
1551  }
1552 
1553  return !$missing_cond_exist;
1554  }
1555 
1559  public function insertPreconditions(): void
1560  {
1561  // do not show multi level conditions (messes up layout)
1562  if ($this->condition_depth > 0) {
1563  return;
1564  }
1565 
1566  if ($this->context == self::CONTEXT_WORKSPACE) {
1567  return;
1568  }
1569 
1570  if (isset($this->condition_target) && is_array($this->condition_target)
1571  && count($this->condition_target) > 0) {
1572  $conditions = ilConditionHandler::_getEffectiveConditionsOfTarget(
1573  (int) $this->condition_target['ref_id'],
1574  (int) $this->condition_target['obj_id'],
1575  $this->condition_target['target_type'] ?? ''
1576  );
1577  } else {
1578  $conditions = ilConditionHandler::_getEffectiveConditionsOfTarget($this->ref_id, $this->obj_id);
1579  }
1580 
1581  if (sizeof($conditions)) {
1582  for ($i = 0; $i < count($conditions); $i++) {
1583  $conditions[$i]['title'] = ilObject::_lookupTitle($conditions[$i]['trigger_obj_id']);
1584  }
1585  $conditions = ilArrayUtil::sortArray($conditions, 'title', 'DESC');
1586 
1587  ++self::$js_unique_id;
1588  // Show obligatory and optional preconditions seperated
1589  $all_done_obl = $this->parseConditions(self::$js_unique_id, $conditions);
1590  $all_done_opt = $this->parseConditions(self::$js_unique_id, $conditions, false);
1591 
1592  if (!$all_done_obl || !$all_done_opt) {
1593  $this->tpl->setCurrentBlock('preconditions_toggle');
1594  $this->tpl->setVariable('PRECONDITION_TOGGLE_INTRO', $this->lng->txt('precondition_toggle'));
1595  $this->tpl->setVariable('PRECONDITION_TOGGLE_TRIGGER', $this->lng->txt('show'));
1596  $this->tpl->setVariable('PRECONDITION_TOGGLE_ID', self::$js_unique_id);
1597  $this->tpl->setVariable('TXT_PRECONDITION_SHOW', $this->lng->txt('show'));
1598  $this->tpl->setVariable('TXT_PRECONDITION_HIDE', $this->lng->txt('hide'));
1599  $this->tpl->parseCurrentBlock();
1600  }
1601  }
1602  }
1603 
1607  public function insertCommand(
1608  string $href,
1609  string $text,
1610  string $frame = '',
1611  string $img = '',
1612  string $cmd = '',
1613  string $onclick = ''
1614  ): void {
1615  // #11099
1616  $checksum = md5($href . $text);
1617  if ($href == '#' || !in_array($checksum, $this->prevent_duplicate_commands)) {
1618  if ($href != '#') {
1619  $this->prevent_duplicate_commands[] = $checksum;
1620  }
1621 
1622  $prevent_background_click = false;
1623  if ($cmd == 'mount_webfolder') {
1624  $onclick = "triggerWebDAVModal('$href')";
1625  $href = '#';
1627  }
1628 
1629  $this->current_selection_list->addItem(
1630  $text,
1631  '',
1632  $href,
1633  $img,
1634  $text,
1635  $frame,
1636  '',
1637  $prevent_background_click,
1638  $onclick
1639  );
1640  }
1641  }
1642 
1643  public function insertDeleteCommand(): void
1644  {
1645  if ($this->std_cmd_only) {
1646  return;
1647  }
1648 
1649  if (is_object($this->getContainerObject()) and
1651  if ($this->checkCommandAccess('delete', '', $this->ref_id, $this->type)) {
1652  $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', $this->getCommandId());
1653  $cmd_link = $this->ctrl->getLinkTarget($this->getContainerObject(), 'delete');
1654  $this->insertCommand($cmd_link, $this->lng->txt('delete'));
1655  $this->adm_commands_included = true;
1656  }
1657  return;
1658  }
1659 
1660  if ($this->checkCommandAccess('delete', '', $this->ref_id, $this->type)) {
1661  $this->ctrl->setParameter(
1662  $this->container_obj,
1663  'ref_id',
1664  $this->container_obj->getObject()->getRefId()
1665  );
1666  $this->ctrl->setParameter($this->container_obj, 'item_ref_id', $this->getCommandId());
1667  $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'delete');
1668  $this->insertCommand($cmd_link, $this->lng->txt('delete'));
1669  $this->adm_commands_included = true;
1670  }
1671  }
1672 
1673  public function insertLinkCommand(): void
1674  {
1675  $objDefinition = $this->obj_definition;
1676 
1677  if ($this->std_cmd_only) {
1678  return;
1679  }
1680 
1681  // #17307
1682  if (
1683  !$this->checkCommandAccess('delete', '', $this->ref_id, $this->type) ||
1684  !$objDefinition->allowLink($this->type)
1685  ) {
1686  return;
1687  }
1688 
1689  // BEGIN PATCH Lucene search
1690  if ($this->getContainerObject() instanceof ilAdministrationCommandHandling) {
1691  $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', $this->getCommandId());
1692  $cmd_link = $this->ctrl->getLinkTarget($this->getContainerObject(), 'link');
1693  $this->insertCommand($cmd_link, $this->lng->txt('link'));
1694  $this->adm_commands_included = true;
1695  return;
1696  }
1697  // END PATCH Lucene Search
1698 
1699  // if the permission is changed here, it has
1700  // also to be changed in ilContainerGUI, admin command check
1701  $this->ctrl->setParameter(
1702  $this->container_obj,
1703  'ref_id',
1704  $this->container_obj->getObject()->getRefId()
1705  );
1706  $this->ctrl->setParameter($this->container_obj, 'item_ref_id', $this->getCommandId());
1707  $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'link');
1708  $this->insertCommand($cmd_link, $this->lng->txt('link'));
1709  $this->adm_commands_included = true;
1710  }
1711 
1712  public function insertCutCommand(bool $to_repository = false): void
1713  {
1714  if ($this->std_cmd_only) {
1715  return;
1716  }
1717  // BEGIN PATCH Lucene search
1718  if (
1720  ) {
1721  if ($this->checkCommandAccess('delete', '', $this->ref_id, $this->type)) {
1722  $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', $this->getCommandId());
1723  $cmd_link = $this->ctrl->getLinkTarget($this->getContainerObject(), 'cut');
1724  $this->insertCommand($cmd_link, $this->lng->txt('move'));
1725  $this->adm_commands_included = true;
1726  }
1727  return;
1728  }
1729  // END PATCH Lucene Search
1730 
1731  // if the permission is changed here, it has
1732  // also to be changed in ilContainerContentGUI, determineAdminCommands
1733  if ($this->checkCommandAccess('delete', '', $this->ref_id, $this->type) && $this->container_obj->getObject()) {
1734  $this->ctrl->setParameter(
1735  $this->container_obj,
1736  'ref_id',
1737  $this->container_obj->getObject()->getRefId()
1738  );
1739  $this->ctrl->setParameter($this->container_obj, 'item_ref_id', $this->getCommandId());
1740 
1741  if (!$to_repository) {
1742  $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'cut');
1743  $this->insertCommand($cmd_link, $this->lng->txt('move'));
1744  } else {
1745  $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'cut_for_repository');
1746  $this->insertCommand($cmd_link, $this->lng->txt('wsp_move_to_repository'));
1747  }
1748 
1749  $this->adm_commands_included = true;
1750  }
1751  }
1752 
1753  public function insertCopyCommand(bool $to_repository = false): void
1754  {
1755  if ($this->std_cmd_only) {
1756  return;
1757  }
1758 
1759  if ($this->checkCommandAccess('copy', 'copy', $this->ref_id, $this->type) &&
1760  $this->obj_definition->allowCopy($this->type)) {
1761  if ($this->context != self::CONTEXT_WORKSPACE && $this->context != self::CONTEXT_WORKSPACE_SHARING) {
1762  $this->ctrl->setParameterByClass('ilobjectcopygui', 'source_id', $this->getCommandId());
1763  $cmd_copy = $this->ctrl->getLinkTargetByClass('ilobjectcopygui', 'initTargetSelection');
1764  $this->insertCommand($cmd_copy, $this->lng->txt('copy'));
1765  } else {
1766  $this->ctrl->setParameter(
1767  $this->container_obj,
1768  'ref_id',
1769  $this->container_obj->getObject()->getRefId()
1770  );
1771  $this->ctrl->setParameter($this->container_obj, 'item_ref_id', $this->getCommandId());
1772 
1773  if (!$to_repository) {
1774  $cmd_copy = $this->ctrl->getLinkTarget($this->container_obj, 'copy');
1775  $this->insertCommand($cmd_copy, $this->lng->txt('copy'));
1776  } else {
1777  $cmd_copy = $this->ctrl->getLinkTarget($this->container_obj, 'copy_to_repository');
1778  $this->insertCommand($cmd_copy, $this->lng->txt('wsp_copy_to_repository'));
1779  }
1780  }
1781 
1782  $this->adm_commands_included = true;
1783  }
1784  }
1785 
1786  public function insertPasteCommand(): void
1787  {
1788  if ($this->std_cmd_only) {
1789  return;
1790  }
1791 
1792  if (!$this->obj_definition->isContainer(ilObject::_lookupType($this->obj_id))) {
1793  return;
1794  }
1795 
1796  if (
1798  $this->clipboard->hasEntries()
1799  ) {
1800  $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', $this->getCommandId());
1801  $cmd_link = $this->ctrl->getLinkTarget($this->getContainerObject(), 'paste');
1802  $this->insertCommand($cmd_link, $this->lng->txt('paste'));
1803  $this->adm_commands_included = true;
1804  }
1805  }
1806 
1807  public function insertSubscribeCommand(): void
1808  {
1809  if ($this->std_cmd_only
1810  || $this->user->getId() === ANONYMOUS_USER_ID
1811  || !$this->getContainerObject() instanceof ilDesktopItemHandling
1812  || $this->settings->get('rep_favourites', '0') !== '1') {
1813  return;
1814  }
1815 
1817 
1818  // #17467 - add ref_id to link (in repository only!)
1819  if (
1820  is_object($this->container_obj) &&
1821  !($this->container_obj instanceof ilAdministrationCommandHandling) &&
1822  method_exists($this->container_obj, 'getObject') &&
1823  is_object($this->container_obj->getObject())
1824  ) {
1825  $this->ctrl->setParameter(
1826  $this->container_obj,
1827  'ref_id',
1828  $this->container_obj->getObject()->getRefId()
1829  );
1830  }
1831  if ($this->getContainerObject() instanceof ilDesktopItemHandling) {
1832  $this->ctrl->setParameter($this->container_obj, 'type', $type);
1833  $this->ctrl->setParameter($this->container_obj, 'item_ref_id', $this->getCommandId());
1834 
1835  if (!$this->fav_manager->ifIsFavourite($this->user->getId(), $this->getCommandId())) {
1836  // Pass type and object ID to ilAccess to improve performance
1837  if ($this->checkCommandAccess('read', '', $this->ref_id, $this->type, $this->obj_id)) {
1838  $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'addToDesk');
1839  $this->insertCommand($cmd_link, $this->lng->txt('rep_add_to_favourites'));
1840  }
1841  } else {
1842  $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'removeFromDesk');
1843  $this->insertCommand($cmd_link, $this->lng->txt('rep_remove_from_favourites'));
1844  }
1845 
1846  $this->ctrl->clearParameters($this->container_obj);
1847  }
1848  }
1849 
1850  public function insertInfoScreenCommand(): void
1851  {
1852  if ($this->std_cmd_only) {
1853  return;
1854  }
1855  $this->insertCommand(
1856  $this->getCommandLink('infoScreen'),
1857  $this->lng->txt('info_short'),
1858  $this->getCommandFrame('infoScreen'),
1859  ilUtil::getImagePath('standard/icon_info.svg')
1860  );
1861  }
1862 
1866  public function insertCommonSocialCommands(bool $header_actions = false): void
1867  {
1868  if ($this->std_cmd_only || $this->user->isAnonymous()) {
1869  return;
1870  }
1871 
1872  $this->lng->loadLanguageModule('notes');
1873  $this->lng->loadLanguageModule('tagging');
1874  $cmd_frame = $this->getCommandFrame('infoScreen');
1875 
1876  // reference objects have translated ids, revert to originals
1877  $note_ref_id = $this->ref_id;
1878  if ($this->reference_ref_id) {
1879  $note_ref_id = $this->reference_ref_id;
1880  }
1881 
1882  $js_updater = $header_actions
1883  ? 'il.Object.redrawActionHeader();'
1884  : 'il.Object.redrawListItem(' . $note_ref_id . ')';
1885 
1886  $comments_enabled = $this->isCommentsActivated($this->type, $this->ref_id, $this->obj_id, $header_actions);
1887  if ($comments_enabled) {
1888  $this->insertCommand(
1889  '#',
1890  $this->lng->txt('notes_comments'),
1891  $cmd_frame,
1892  '',
1893  '',
1894  ilNoteGUI::getListCommentsJSCall($this->ajax_hash, $js_updater)
1895  );
1896  }
1897 
1898  if ($this->notes_enabled) {
1899  $this->insertCommand(
1900  '#',
1901  $this->lng->txt('notes'),
1902  $cmd_frame,
1903  '',
1904  '',
1905  ilNoteGUI::getListNotesJSCall($this->ajax_hash, $js_updater)
1906  );
1907  }
1908 
1909  if ($this->tags_enabled) {
1910  $this->insertCommand(
1911  '#',
1912  $this->lng->txt('tagging_set_tag'),
1913  $cmd_frame,
1914  '',
1915  '',
1916  ilTaggingGUI::getListTagsJSCall($this->ajax_hash, $js_updater)
1917  );
1918  }
1919  }
1920 
1927  public function insertTimingsCommand(): void
1928  {
1929  if (
1930  $this->std_cmd_only || is_null($this->container_obj) ||
1931  !method_exists($this->container_obj, 'getObject') ||
1932  !is_object($this->container_obj->getObject())
1933  ) {
1934  return;
1935  }
1936 
1937  $parent_ref_id = $this->container_obj->getObject()->getRefId();
1938  $parent_type = $this->container_obj->getObject()->getType();
1939 
1940  // #18737
1941  if ($this->reference_ref_id) {
1942  $this->ctrl->setParameterByClass('ilconditionhandlergui', 'ref_id', $this->reference_ref_id);
1943  }
1944 
1945  if (
1946  $this->checkCommandAccess('write', '', $parent_ref_id, $parent_type) ||
1947  $this->checkCommandAccess('write', '', $this->ref_id, $this->type)
1948  ) {
1949  $this->ctrl->setParameterByClass(
1950  get_class($this->container_obj),
1951  'tl_id',
1952  $this->ref_id
1953  );
1954  $time_limit_link = $this->ctrl->getLinkTargetByClass(
1955  get_class($this->container_obj),
1956  'editAvailabilityPeriod'
1957  );
1958  $this->insertCommand($time_limit_link, $this->lng->txt('edit_availability_period'));
1959  $this->ctrl->clearParameterByClass(
1960  get_class($this->container_obj),
1961  'tl_id',
1962  );
1963 
1964  $this->ctrl->setParameterByClass(
1965  'ilconditionhandlergui',
1966  'cadh',
1967  $this->ajax_hash
1968  );
1969  $this->ctrl->setParameterByClass(
1970  'ilconditionhandlergui',
1971  'parent_id',
1972  $parent_ref_id
1973  );
1974 
1975  $availbility_link = $this->ctrl->getLinkTargetByClass(
1976  [$this->gui_class_name, 'ilcommonactiondispatchergui', 'ilobjectactivationgui', 'ilconditionhandlergui'],
1977  'listConditions'
1978  );
1979 
1980  $this->insertCommand($availbility_link, $this->lng->txt('preconditions'));
1981  }
1982 
1983  if ($this->reference_ref_id) {
1984  $this->ctrl->setParameterByClass('ilconditionhandlergui', 'ref_id', $this->ref_id);
1985  }
1986  }
1987 
1991  public function insertCommands(
1992  bool $use_async = false,
1993  bool $get_async_commands = false,
1994  string $async_url = '',
1995  bool $header_actions = false
1996  ): string {
1997  $commands = $this->getCommands();
1998  if ($use_async && !$get_async_commands) {
1999  foreach ($commands as $command) {
2000  if ($command['default'] === true) {
2001  $this->default_command = $command['granted'] === true ? $this->createDefaultCommand($command) : [];
2002  break;
2003  }
2004  }
2005  }
2006 
2007  if (!$this->getCommandsStatus() || $this->commandsNeedToBeHidden(
2008  $use_async,
2009  $get_async_commands,
2010  $header_actions
2011  )) {
2012  return '';
2013  }
2014 
2015  $this->current_selection_list->setAsynch($use_async && !$get_async_commands);
2016  $this->current_selection_list->setAsynchUrl($async_url);
2017  if ($header_actions) {
2018  $this->current_selection_list->setListTitle(
2019  '<span class="hidden-xs">' .
2020  $this->lng->txt('actions') .
2021  '</span>'
2022  );
2023  } else {
2024  $this->current_selection_list->setListTitle('');
2025  }
2026  $this->current_selection_list->setId('act_' . $this->getUniqueItemId());
2027  $this->current_selection_list->setSelectionHeaderClass('');
2028  $this->current_selection_list->setItemLinkClass('');
2029  $this->current_selection_list->setLinksMode('il_ContainerItemCommand2');
2030  $this->current_selection_list->setHeaderIcon(ilAdvancedSelectionListGUI::DOWN_ARROW_DARK);
2031  $this->current_selection_list->setUseImages(false);
2032  $this->current_selection_list->setAdditionalToggleElement(
2033  $this->getUniqueItemId(true),
2034  'ilContainerListItemOuterHighlight'
2035  );
2036 
2037  if ($use_async && !$get_async_commands) {
2038  return $this->current_selection_list->getHTML();
2039  }
2040 
2041  $this->ctrl->setParameterByClass($this->gui_class_name, 'ref_id', $this->ref_id);
2042 
2043  $this->default_command = [];
2044  $this->prevent_duplicate_commands = [];
2045 
2046  // we only allow the following commands inside the header actions
2047  $valid_header_commands = ['mount_webfolder'];
2048 
2049 
2050  foreach ($commands as $command) {
2051  if ($header_actions && !in_array($command['cmd'], $valid_header_commands)
2052  || $command['granted'] === false) {
2053  continue;
2054  }
2055 
2056  if ($command['default'] === true) {
2057  $this->default_command = $this->createDefaultCommand($command);
2058  continue;
2059  }
2060 
2061  // workaround for repository frameset
2062  $command['link'] =
2063  $this->appendRepositoryFrameParameter($command['link']);
2064 
2065  $cmd_link = $command['link'];
2066  $txt = ($command['lang_var'] == '')
2067  ? $command['txt']
2068  : $this->lng->txt($command['lang_var']);
2069  $this->insertCommand(
2070  $cmd_link,
2071  $txt,
2072  $command['frame'],
2073  $command['img'],
2074  $command['cmd']
2075  );
2076  }
2077 
2078  // custom commands
2079  if (is_array($this->cust_commands)) {
2080  foreach ($this->cust_commands as $command) {
2081  if ($command instanceof Button) {
2082  $this->current_selection_list->addComponent($command);
2083  continue;
2084  }
2085 
2086  $this->insertCommand(
2087  $command['link'],
2088  $this->lng->txt($command['lang_var']),
2089  $command['frame'],
2090  '',
2091  $command['cmd'] ?? '',
2092  $command['onclick']
2093  );
2094  }
2095  }
2096  $this->insertLPSettingsCommand();
2097 
2098  // info screen command
2099  if ($this->getInfoScreenStatus()) {
2100  $this->insertInfoScreenCommand();
2101  }
2102 
2103  $this->insertLPCommand();
2104 
2105  if (!$this->isMode(self::IL_LIST_AS_TRIGGER)) {
2106  // delete
2107  if ($this->delete_enabled) {
2108  $this->insertDeleteCommand();
2109  }
2110 
2111  // link
2112  if ($this->link_enabled) {
2113  $this->insertLinkCommand();
2114  }
2115 
2116  // cut
2117  if ($this->cut_enabled) {
2118  $this->insertCutCommand();
2119  }
2120 
2121  // copy
2122  if ($this->copy_enabled) {
2123  $this->insertCopyCommand();
2124  }
2125 
2126  // cut/copy from workspace to repository
2127  if ($this->repository_transfer_enabled) {
2128  $this->insertCutCommand(true);
2129  $this->insertCopyCommand(true);
2130  }
2131 
2132  if ($this->timings_enabled) {
2133  $this->insertTimingsCommand();
2134  }
2135 
2136  // subscribe
2137  if ($this->subscribe_enabled) {
2138  $this->insertSubscribeCommand();
2139  }
2140 
2141  // multi download
2142  if ($this->multi_download_enabled && $header_actions) {
2143  $this->insertMultiDownloadCommand();
2144  }
2145 
2146  // BEGIN PATCH Lucene search
2147  if ($this->cut_enabled or $this->link_enabled) {
2148  $this->insertPasteCommand();
2149  }
2150  // END PATCH Lucene Search
2151  }
2152 
2153  // common social commands (comment, notes, tags)
2154  if (!$this->isMode(self::IL_LIST_AS_TRIGGER)) {
2155  $this->insertCommonSocialCommands($header_actions);
2156  }
2157 
2158  if (!$header_actions) {
2159  $this->ctrl->clearParametersByClass($this->gui_class_name);
2160  }
2161 
2162  if ($use_async && $get_async_commands) {
2163  return $this->current_selection_list->getHTML(true);
2164  }
2165 
2166  return $this->current_selection_list->getHTML();
2167  }
2168 
2172  // there is one case, where no action menu should be displayed:
2173  // public area, category, no info tab
2174  // todo: make this faster and remove type specific implementation if possible
2175  private function commandsNeedToBeHidden(
2176  bool $use_async,
2177  bool $get_async_commands,
2178  bool $header_actions
2179  ): bool {
2180  return $use_async && !$get_async_commands && !$header_actions
2181  && $this->user->getId() === ANONYMOUS_USER_ID && $this->checkInfoPageOnAsynchronousRendering()
2182  && $this->object_properties->getPropertyInfoTabVisibility();
2183  }
2184 
2185  public function enableComments(bool $value, bool $enable_comments_settings = true): void
2186  {
2187  if ($this->settings->get('disable_comments')) {
2188  $value = false;
2189  }
2190 
2191  $this->comments_enabled = $value;
2192  $this->comments_settings_enabled = $enable_comments_settings;
2193  }
2194 
2195  public function enableNotes(bool $value): void
2196  {
2197  if ($this->settings->get('disable_notes')) {
2198  $value = false;
2199  }
2200 
2201  $this->notes_enabled = $value;
2202  }
2203 
2204  public function enableTags(bool $value): void
2205  {
2206  $tags_set = new ilSetting('tags');
2207  if (!$tags_set->get('enable')) {
2208  $value = false;
2209  }
2210  $this->tags_enabled = $value;
2211  }
2212 
2213  public function enableRating(
2214  bool $value,
2215  string $text = null,
2216  bool $categories = false,
2217  array $ctrl_path = null,
2218  bool $force_rate_parent = false
2219  ): void {
2220  $this->rating_enabled = $value;
2221 
2222  if ($this->rating_enabled) {
2223  $this->rating_categories_enabled = $categories;
2224  $this->rating_text = $text;
2225  $this->rating_ctrl_path = $ctrl_path;
2226  $this->force_rate_parent = $force_rate_parent;
2227  }
2228  }
2229 
2235  public function enableMultiDownload(bool $value): void
2236  {
2237  $folder_set = new ilSetting('fold');
2238  if (!$folder_set->get('enable_multi_download')) {
2239  $value = false;
2240  }
2241  $this->multi_download_enabled = $value;
2242  }
2243 
2244  public function insertMultiDownloadCommand(): void
2245  {
2246  if ($this->std_cmd_only) {
2247  return;
2248  }
2249 
2250  if (!$this->obj_definition->isContainer(ilObject::_lookupType($this->obj_id))) {
2251  return;
2252  }
2253 
2254  if ($this->getContainerObject() instanceof ilContainerGUI) {
2255  $this->ctrl->setParameter($this->getContainerObject(), 'type', '');
2256  $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', '');
2257  $this->ctrl->setParameter($this->getContainerObject(), 'active_node', '');
2258  // bugfix mantis 24559
2259  // undoing an erroneous change inside mantis 23516 by
2260  // adding 'Download Multiple Objects'-functionality for non-admins
2261  // as they don't have the possibility to use the multi-download-capability of the manage-tab
2262  $user_id = $this->user->getId();
2263  $hasAdminAccess = $this->access->checkAccessOfUser($user_id, 'crs_admin', $this->ctrl->getCmd(), $this->requested_ref_id);
2264  // to still prevent duplicate download functions for admins
2265  // the following if-else statement keeps the redirection for admins
2266  // while letting other course members access the original multi-download functionality
2267  if ($hasAdminAccess) {
2268  $cmd = ($this->requested_cmd == 'enableAdministrationPanel')
2269  ? 'render'
2270  : 'enableAdministrationPanel';
2271  } else {
2272  $cmd = ($this->requested_cmd == 'enableMultiDownload')
2273  ? 'render'
2274  : 'enableMultiDownload';
2275  }
2276  $cmd_link = $this->ctrl->getLinkTarget($this->getContainerObject(), $cmd);
2277  $this->insertCommand($cmd_link, $this->lng->txt('download_multiple_objects'));
2278  }
2279  }
2280 
2281  public function enableDownloadCheckbox(int $ref_id): void
2282  {
2283  // TODO: delegate to list object class!
2284  if (!$this->getContainerObject()->isActiveAdministrationPanel() || $this->clipboard->hasEntries()) {
2285  if (
2286  in_array($this->type, ['file', 'fold']) &&
2287  $this->access->checkAccess('read', '', $ref_id, $this->type)
2288  ) {
2289  $this->download_checkbox_state = self::DOWNLOAD_CHECKBOX_ENABLED;
2290  } else {
2291  $this->download_checkbox_state = self::DOWNLOAD_CHECKBOX_DISABLED;
2292  }
2293  } else {
2294  $this->download_checkbox_state = self::DOWNLOAD_CHECKBOX_NONE;
2295  }
2296  }
2297 
2298  public function getDownloadCheckboxState(): int
2299  {
2301  }
2302 
2306  public static function prepareJsLinks(
2307  string $redraw_url,
2308  string $notes_url,
2309  string $tags_url,
2310  ilGlobalTemplateInterface $tpl = null
2311  ): void {
2312  global $DIC;
2313 
2314  if (is_null($tpl)) {
2315  $tpl = $DIC['tpl'];
2316  }
2317 
2318  //if ($notes_url) {
2319  $DIC->notes()->gui()->initJavascript($notes_url);
2320  //}
2321 
2322  if ($tags_url) {
2323  ilTaggingGUI::initJavascript($tags_url, $tpl);
2324  }
2325 
2326  if ($redraw_url) {
2327  $tpl->addOnLoadCode('il.Object.setRedrawAHUrl("' . $redraw_url . '");');
2328  }
2329  }
2330 
2331  public function setHeaderSubObject(?string $type, ?int $id): void
2332  {
2333  $this->sub_obj_type = $type;
2334  $this->sub_obj_id = (int) $id;
2335  }
2336 
2337  public function addHeaderIcon(
2338  string $id,
2339  string $img,
2340  string $tooltip = null,
2341  string $onclick = null,
2342  string $status_text = null,
2343  string $href = null
2344  ): void {
2345  $this->header_icons[$id] = [
2346  'img' => $img,
2347  'tooltip' => $tooltip,
2348  'onclick' => $onclick,
2349  'status_text' => $status_text,
2350  'href' => $href
2351  ];
2352  }
2353 
2354  public function addHeaderIconHTML(string $id, string $html): void
2355  {
2356  $this->header_icons[$id] = $html;
2357  }
2358 
2359  public function addHeaderGlyph(string $id, ILIAS\UI\Component\Symbol\Glyph\Glyph $glyph, $onclick = null): void
2360  {
2361  $this->header_icons[$id] = ['glyph' => $glyph, 'onclick' => $onclick];
2362  }
2363 
2364  public function setAjaxHash(string $hash): void
2365  {
2366  $this->ajax_hash = $hash;
2367  }
2368 
2369  public function getHeaderAction(ilGlobalTemplateInterface $main_tpl = null): string
2370  {
2371  if ($main_tpl == null) {
2372  $main_tpl = $this->main_tpl;
2373  }
2374 
2375  $htpl = new ilTemplate('tpl.header_action.html', true, true, 'Services/Repository');
2376 
2377  $redraw_js = 'il.Object.redrawActionHeader();';
2378 
2379  // tags
2380  if ($this->tags_enabled) {
2382  $this->obj_id,
2383  ilObject::_lookupType($this->obj_id),
2384  0,
2385  '',
2386  $this->user->getId()
2387  );
2388  if (count($tags) > 0) {
2389  $this->lng->loadLanguageModule('tagging');
2390 
2391  $f = $this->ui->factory();
2392  $this->addHeaderGlyph(
2393  'tags',
2394  $f->symbol()->glyph()->tag('#')
2395  ->withCounter($f->counter()->status(count($tags))),
2396  ilTaggingGUI::getListTagsJSCall($this->ajax_hash, $redraw_js)
2397  );
2398  }
2399  }
2400 
2401  // notes and comments
2402  $comments_enabled = $this->isCommentsActivated($this->type, $this->ref_id, $this->obj_id, true, false);
2403  if ($this->notes_enabled || $comments_enabled) {
2404  $type = ($this->sub_obj_type == '') ? $this->type : $this->sub_obj_type;
2405  $context = $this->notes_service->data()->context($this->obj_id, $this->sub_obj_id, $type);
2406  $cnt[$this->obj_id][Note::PUBLIC] = $this->notes_service->domain()->getNrOfCommentsForContext($context);
2407  $cnt[$this->obj_id][Note::PRIVATE] = $this->notes_service->domain()->getNrOfNotesForContext($context);
2408  if (
2409  $this->notes_enabled &&
2410  isset($cnt[$this->obj_id][Note::PRIVATE]) &&
2411  $cnt[$this->obj_id][Note::PRIVATE] > 0
2412  ) {
2413  $f = $this->ui->factory();
2414  $this->addHeaderGlyph(
2415  'notes',
2416  $f->symbol()->glyph()->note('#')
2417  ->withCounter($f->counter()->status((int) $cnt[$this->obj_id][Note::PRIVATE])),
2418  ilNoteGUI::getListNotesJSCall($this->ajax_hash, $redraw_js)
2419  );
2420  }
2421 
2422  if (
2423  $comments_enabled &&
2424  isset($cnt[$this->obj_id][Note::PUBLIC]) &&
2425  $cnt[$this->obj_id][Note::PUBLIC] > 0
2426  ) {
2427  $this->lng->loadLanguageModule('notes');
2428  $f = $this->ui->factory();
2429  $this->addHeaderGlyph(
2430  'comments',
2431  $f->symbol()->glyph()->comment('#')
2432  ->withCounter($f->counter()->status((int) $cnt[$this->obj_id][Note::PUBLIC])),
2433  ilNoteGUI::getListCommentsJSCall($this->ajax_hash, $redraw_js)
2434  );
2435  }
2436  }
2437 
2438  // rating
2439  if ($this->rating_enabled) {
2440  $rating_gui = new ilRatingGUI();
2441  $rating_gui->enableCategories($this->rating_categories_enabled);
2442  // never rate sub objects from header action!
2443  $rating_gui->setObject($this->obj_id, $this->type);
2444  if ($this->rating_text) {
2445  $rating_gui->setYourRatingText($this->rating_text);
2446  }
2447 
2448  $ajax_hash = $this->force_rate_parent
2450  : $this->ajax_hash;
2451  $this->ctrl->setParameterByClass('ilRatingGUI', 'cadh', $ajax_hash);
2452  $this->ctrl->setParameterByClass('ilRatingGUI', 'rnsb', true);
2453  if ($this->rating_ctrl_path) {
2454  $rating_gui->setCtrlPath($this->rating_ctrl_path);
2455  $ajax_url = $this->ctrl->getLinkTargetByClass($this->rating_ctrl_path, 'saveRating', '', true);
2456  } else {
2457  $ajax_url = $this->ctrl->getLinkTargetByClass('ilRatingGUI', 'saveRating', '', true);
2458  }
2459  $main_tpl->addOnLoadCode('il.Object.setRatingUrl("' . $ajax_url . '");');
2460  $this->addHeaderIconHTML(
2461  'rating',
2462  $rating_gui->getHTML(
2463  true,
2464  $this->checkCommandAccess('read', '', $this->ref_id, $this->type),
2465  'il.Object.saveRating(%rating%);'
2466  )
2467  );
2468  }
2469 
2470  if ($this->header_icons) {
2471  $chunks = [];
2472  foreach ($this->header_icons as $id => $attr) {
2473  $id = 'headp_' . $id;
2474 
2475  if (is_array($attr)) {
2476  if (isset($attr['glyph']) && $attr['glyph']) {
2477  if ($attr['onclick']) {
2478  $htpl->setCurrentBlock('prop_glyph_oc');
2479  $htpl->setVariable('GLYPH_ONCLICK', $attr['onclick']);
2480  $htpl->parseCurrentBlock();
2481  }
2482  $renderer = $this->ui->renderer();
2483  $html = $renderer->render($attr['glyph']);
2484  $htpl->setCurrentBlock('prop_glyph');
2485  $htpl->setVariable('GLYPH', $html);
2486  $htpl->parseCurrentBlock();
2487  } else {
2488  if ($attr['onclick']) {
2489  $htpl->setCurrentBlock('onclick');
2490  $htpl->setVariable('PROP_ONCLICK', $attr['onclick']);
2491  $htpl->parseCurrentBlock();
2492  }
2493 
2494  if ($attr['status_text']) {
2495  $htpl->setCurrentBlock('status');
2496  $htpl->setVariable('PROP_TXT', $attr['status_text']);
2497  $htpl->parseCurrentBlock();
2498  }
2499 
2500 
2501  $htpl->setCurrentBlock('prop');
2502  if ($attr['href'] || $attr['onclick']) {
2503  $htpl->setVariable('TAG', 'a');
2504  } else {
2505  $htpl->setVariable('TAG', 'span');
2506  }
2507  $htpl->setVariable('PROP_ID', $id);
2508  $htpl->setVariable('IMG', ilUtil::img($attr['img'], $attr['tooltip']));
2509  if ($attr['href'] != '') {
2510  $htpl->setVariable('PROP_HREF', ' href="' . $attr['href'] . '" ');
2511  }
2512  $htpl->parseCurrentBlock();
2513 
2514  if ($attr['tooltip']) {
2515  ilTooltipGUI::addTooltip($id, $attr['tooltip']);
2516  }
2517  }
2518  } else {
2519  $chunks[] = $attr;
2520  }
2521  }
2522 
2523  if (sizeof($chunks)) {
2524  $htpl->setVariable(
2525  'PROP_CHUNKS',
2526  implode('&nbsp;&nbsp;&nbsp;', $chunks) . '&nbsp;&nbsp;&nbsp;'
2527  );
2528  }
2529  }
2530 
2531  $this->setTitle(ilObject::_lookupTitle($this->obj_id));
2532  $htpl->setVariable(
2533  'ACTION_DROP_DOWN',
2534  $this->insertCommands(false, false, '', true)
2535  );
2536 
2537  if ($this->cust_modals !== []) {
2538  $htpl->setVariable('TRIGGERED_MODALS', $this->ui->renderer()->render($this->cust_modals));
2539  }
2540 
2541  return $htpl->get();
2542  }
2543 
2544 
2549  public function appendRepositoryFrameParameter(string $link): string
2550  {
2551  // we should get rid of this nonsense with 4.4 (alex)
2552  $base_class = $this->request_wrapper->retrieve('baseClass', $this->refinery->kindlyTo()->string());
2553  if (
2554  (strtolower($base_class) != 'ilrepositorygui') &&
2555  is_int(strpos($link, 'baseClass=ilRepositoryGUI'))
2556  ) {
2557  if ($this->type != 'frm') {
2558  $link = ilUtil::appendUrlParameterString($link, 'rep_frame=1');
2559  }
2560  }
2561 
2562  return $link;
2563  }
2564 
2565  protected function modifyTitleLink(string $default_link): string
2566  {
2567  if ($this->default_command_params) {
2568  $params = [];
2569  foreach ($this->default_command_params as $name => $value) {
2570  $params[] = $name . '=' . $value;
2571  }
2572  $params = implode('&', $params);
2573 
2574 
2575  // #12370
2576  if (!stristr($default_link, '?')) {
2577  $default_link = ($default_link . '?' . $params);
2578  } else {
2579  $default_link = ($default_link . '&' . $params);
2580  }
2581  }
2582  return $default_link;
2583  }
2584 
2588  public function modifySAHSlaunch(string $link, string $target): array
2589  {
2590  if (strstr($link, ilSAHSPresentationGUI::class) === false) {
2591  return [$link, $target];
2592  }
2593 
2594  $sahs_obj = new ilObjSAHSLearningModule($this->ref_id);
2595  $om = $sahs_obj->getOpenMode();
2596  $width = $sahs_obj->getWidth();
2597  $height = $sahs_obj->getHeight();
2598  if (($om == 5 || $om == 1) && $width > 0 && $height > 0) {
2599  $om++;
2600  }
2601  if ($om !== 0 && !$this->http->agent()->isMobile()) {
2602  $this->default_command['frame'] = '';
2603  $link =
2604  'javascript:void(0); onclick=startSAHS(\'' .
2605  $link .
2606  '\',\'' .
2607  $target .
2608  '\',' .
2609  $om .
2610  ',' .
2611  $width .
2612  ',' .
2613  $height .
2614  ');'
2615  ;
2616  } else {
2617  $target = "ilContObj" . $this->ref_id;
2618  }
2619  return [$link, $target];
2620  }
2621 
2622  public function insertPath(): void
2623  {
2624  if ($this->getPathStatus() != false) {
2625  if (!$this->path_gui instanceof \ilPathGUI) {
2626  $path_gui = new \ilPathGUI();
2627  } else {
2628  $path_gui = $this->path_gui;
2629  }
2630 
2631  $path_gui->enableTextOnly(!$this->path_linked);
2632  $path_gui->setUseImages(false);
2633 
2634  $start_node = ROOT_FOLDER_ID;
2635  if ($this->path_start_node) {
2636  $start_node = $this->path_start_node;
2637  }
2638 
2639  $this->tpl->setCurrentBlock('path_item');
2640  $this->tpl->setVariable('PATH_ITEM', $path_gui->getPath($start_node, $this->ref_id));
2641  $this->tpl->parseCurrentBlock();
2642 
2643  $this->tpl->setCurrentBlock('path');
2644  $this->tpl->setVariable('TXT_LOCATION', $this->lng->txt('locator'));
2645  $this->tpl->parseCurrentBlock();
2646  }
2647  }
2648 
2649  public function insertProgressInfo(): void
2650  {
2651  }
2652 
2653  public function insertIconsAndCheckboxes(): void
2654  {
2655  $cnt = 0;
2656  if ($this->getCheckboxStatus()) {
2657  $this->tpl->setCurrentBlock('check');
2658  $this->tpl->setVariable('VAL_ID', $this->getCommandId());
2659  $this->tpl->setVariable('CHECK_TITLE', $this->lng->txt('select') . ' ' . $this->getTitle());
2660  $this->tpl->parseCurrentBlock();
2661  $cnt += 1;
2662  } elseif ($this->getDownloadCheckboxState() != self::DOWNLOAD_CHECKBOX_NONE) {
2663  $this->tpl->setCurrentBlock('check_download');
2664  $this->tpl->setVariable('CHECK_DOWNLOAD_TITLE', $this->lng->txt('download') . ' ' . $this->getTitle());
2665  if ($this->getDownloadCheckboxState() == self::DOWNLOAD_CHECKBOX_ENABLED) {
2666  $this->tpl->setVariable('VAL_ID', $this->getCommandId());
2667  } else {
2668  $this->tpl->setVariable('VAL_VISIBILITY', 'visibility: hidden;" disabled="disabled');
2669  }
2670  $this->tpl->parseCurrentBlock();
2671  $cnt += 1;
2672  } elseif ($this->getExpandStatus()) {
2673  $this->tpl->setCurrentBlock('expand');
2674 
2675  if ($this->isExpanded()) {
2676  $this->ctrl->setParameter($this->container_obj, 'expand', -1 * $this->obj_id);
2677  // 'view' added, see #19922
2678  $this->tpl->setVariable('EXP_HREF', $this->ctrl->getLinkTarget($this->container_obj, 'view', $this->getUniqueItemId(true)));
2679  $this->ctrl->clearParameters($this->container_obj);
2680  $this->tpl->setVariable('EXP_IMG', ilUtil::getImagePath('nav/tree_exp.svg'));
2681  $this->tpl->setVariable('EXP_ALT', $this->lng->txt('collapse'));
2682  } else {
2683  $this->ctrl->setParameter($this->container_obj, 'expand', $this->obj_id);
2684  // 'view' added, see #19922
2685  $this->tpl->setVariable('EXP_HREF', $this->ctrl->getLinkTarget($this->container_obj, 'view', $this->getUniqueItemId(true)));
2686  $this->ctrl->clearParameters($this->container_obj);
2687  $this->tpl->setVariable('EXP_IMG', ilUtil::getImagePath('nav/tree_col.svg'));
2688  $this->tpl->setVariable('EXP_ALT', $this->lng->txt('expand'));
2689  }
2690 
2691  $this->tpl->parseCurrentBlock();
2692  $cnt += 1;
2693  }
2694 
2695  if ($this->getIconStatus()) {
2696  if ($cnt == 1) {
2697  $this->tpl->touchBlock('i_1');
2698  }
2699 
2700  $this->tpl->setCurrentBlock('icon');
2701  $this->tpl->setVariable('ALT_ICON', $this->buildTranslatedType());
2702 
2703  $this->tpl->setVariable(
2704  'SRC_ICON',
2705  $this->getTypeIcon()
2706  );
2707  $this->tpl->parseCurrentBlock();
2708  $cnt += 1;
2709  }
2710 
2711  $this->tpl->touchBlock('d_' . $cnt);
2712  }
2713 
2717  public function getTypeIcon(): string
2718  {
2719  return ilObject::getIconForReference(
2720  $this->ref_id,
2721  $this->obj_id,
2722  'small',
2723  $this->getIconImageType()
2724  );
2725  }
2726 
2727  public function insertSubItems(): void
2728  {
2729  foreach ($this->sub_item_html as $sub_html) {
2730  $this->tpl->setCurrentBlock('subitem');
2731  $this->tpl->setVariable('SUBITEM', $sub_html);
2732  $this->tpl->parseCurrentBlock();
2733  }
2734  }
2735 
2736  public function insertPositionField(): void
2737  {
2738  if ($this->position_enabled) {
2739  $this->tpl->setCurrentBlock('position');
2740  $this->tpl->setVariable('POS_ID', $this->position_field_index);
2741  $this->tpl->setVariable('POS_VAL', $this->position_value);
2742  $this->tpl->parseCurrentBlock();
2743  }
2744  }
2745 
2750  public function adminCommandsIncluded(): bool
2751  {
2752  return $this->adm_commands_included;
2753  }
2754 
2755  public function storeAccessCache(): void
2756  {
2757  if ($this->acache->getLastAccessStatus() == 'miss' && !$this->prevent_access_caching) {
2758  $this->acache->storeEntry(
2759  $this->user->getId() . ':' . $this->ref_id,
2760  serialize($this->access_cache),
2761  $this->ref_id
2762  );
2763  }
2764  }
2765 
2769  public function getListItemHTML(
2770  int $ref_id,
2771  int $obj_id,
2772  string $title,
2773  string $description,
2774  bool $use_async = false,
2775  bool $get_async_commands = false,
2776  string $async_url = ''
2777  ): string {
2778  // this variable stores whether any admin commands
2779  // are included in the output
2780  $this->adm_commands_included = false;
2781 
2782  // only for performance exploration
2783  $type = ilObject::_lookupType($obj_id);
2784 
2785  $this->initItem($ref_id, $obj_id, $type, $title, $description);
2786 
2787  if ($use_async && $get_async_commands) {
2788  return $this->insertCommands(true, true);
2789  }
2790 
2791  if ($this->rating_enabled) {
2792  if (ilRating::hasRatingInListGUI($this->obj_id, $this->type)) {
2793  $may_rate = $this->checkCommandAccess('read', '', $this->ref_id, $this->type);
2794  $rating = new ilRatingGUI();
2795  $rating->setObject($this->obj_id, $this->type);
2796  $this->addCustomProperty(
2797  '',
2798  $rating->getListGUIProperty($this->ref_id, $may_rate, $this->ajax_hash, $this->parent_ref_id),
2799  false,
2800  true
2801  );
2802  }
2803  }
2804 
2805  // read from cache
2806  $this->acache = new ilListItemAccessCache();
2807  $cres = $this->acache->getEntry($this->user->getId() . ':' . $ref_id);
2808  if ($this->acache->getLastAccessStatus() == 'hit') {
2809  $this->access_cache = unserialize($cres);
2810  } else {
2811  // write to cache
2812  $this->storeAccessCache();
2813  }
2814 
2815  // visible check
2816  if (!$this->checkCommandAccess('visible', '', $ref_id, '', $obj_id)) {
2817  $this->resetCustomData();
2818  return '';
2819  }
2820 
2821  // BEGIN WEBDAV
2822  if ($type == 'file' and ilObjFileAccess::_isFileHidden($title)) {
2823  $this->resetCustomData();
2824  return '';
2825  }
2826  // END WEBDAV
2827 
2828  $this->tpl = new ilTemplate(
2829  static::$tpl_file_name,
2830  true,
2831  true,
2832  static::$tpl_component,
2833  'DEFAULT',
2834  false,
2835  true
2836  );
2837 
2838  if ($this->getCommandsStatus()) {
2839  if (!$this->getSeparateCommands()) {
2840  $this->tpl->setVariable(
2841  'COMMAND_SELECTION_LIST',
2842  $this->insertCommands($use_async, $get_async_commands, $async_url)
2843  );
2844  }
2845  }
2846 
2847  if ($this->getProgressInfoStatus()) {
2848  $this->insertProgressInfo();
2849  }
2850 
2851  // insert title and describtion
2852  $this->insertTitle();
2853  if (!$this->isMode(self::IL_LIST_AS_TRIGGER)) {
2854  if ($this->getDescriptionStatus()) {
2855  $this->insertDescription();
2856  }
2857  }
2858 
2859  if ($this->getSearchFragmentStatus()) {
2860  $this->insertSearchFragment();
2861  }
2862  if ($this->enabledRelevance()) {
2863  $this->insertRelevance();
2864  }
2865 
2866  // properties
2867  if ($this->getPropertiesStatus()) {
2868  $this->insertProperties();
2869  }
2870 
2871  // notice properties
2872  if ($this->getNoticePropertiesStatus()) {
2873  $this->insertNoticeProperties();
2874  }
2875 
2876  // preconditions
2877  if ($this->getPreconditionsStatus()) {
2878  $this->insertPreconditions();
2879  }
2880 
2881  // path
2882  $this->insertPath();
2883 
2884  if ($this->getItemDetailLinkStatus()) {
2885  $this->insertItemDetailLinks();
2886  }
2887 
2888  // icons and checkboxes
2889  $this->insertIconsAndCheckboxes();
2890 
2891  // input field for position
2892  $this->insertPositionField();
2893 
2894  // subitems
2895  $this->insertSubItems();
2896 
2897  $this->resetCustomData();
2898 
2899  $this->tpl->setVariable('DIV_CLASS', 'ilContainerListItemOuter');
2900  $this->tpl->setVariable(
2901  'DIV_ID',
2902  'data-list-item-id="' . $this->getUniqueItemId(true) . '" id = "' . $this->getUniqueItemId(true) . '"'
2903  );
2904  $this->tpl->setVariable('ADDITIONAL', $this->getAdditionalInformation());
2905 
2906  if (is_object($this->getContainerObject())) {
2907  // #11554 - make sure that internal ids are reset
2908  $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', '');
2909  }
2910 
2911  // if file upload is enabled the content is wrapped by a UI dropzone.
2912  $content = $this->tpl->get();
2913  $file_upload_dropzone = new ilObjFileUploadDropzone($this->ref_id, $content);
2914  if ($this->context === self::CONTEXT_REPOSITORY
2915  && ($this->requested_cmd === "view" || $this->requested_cmd === "" || $this->requested_cmd === "render")
2916  && $file_upload_dropzone->isUploadAllowed($this->type)
2917  && !(new ModeSessionRepository())->isAdminMode()
2918  ) {
2919  return $file_upload_dropzone->getDropzoneHtml();
2920  }
2921 
2922  return $content;
2923  }
2924 
2928  protected function resetCustomData(): void
2929  {
2930  // #15747
2931  $this->cust_prop = [];
2932  $this->cust_commands = [];
2933  $this->cust_modals = [];
2934  $this->sub_item_html = [];
2935  $this->position_enabled = false;
2936  }
2937 
2941  public function setParentRefId(int $ref_id): void
2942  {
2943  $this->parent_ref_id = $ref_id;
2944  }
2945 
2952  public function getUniqueItemId(bool $as_div = false): string
2953  {
2954  // use correct id for references
2955  $id_ref = $this->ref_id;
2956  if ($this->reference_ref_id > 0) {
2957  $id_ref = $this->reference_ref_id;
2958  }
2959 
2960  // add unique identifier for preconditions (objects can appear twice in same container)
2961  if ($this->condition_depth) {
2962  $id_ref .= '_pc' . $this->condition_depth;
2963  }
2964 
2965  // unique
2966  $id_ref .= '_pref_' . $this->parent_ref_id;
2967 
2968  if (!$as_div) {
2969  return $id_ref;
2970  } else {
2971  // action menu [yellow] toggle
2972  return 'lg_div_' . $id_ref;
2973  }
2974  }
2975 
2979  public function getCommandsHTML(): string
2980  {
2981  return $this->insertCommands();
2982  }
2983 
2987  public function isSideBlock(): bool
2988  {
2989  return false;
2990  }
2991 
2992  public function setBoldTitle(bool $bold_title): void
2993  {
2994  $this->bold_title = $bold_title;
2995  }
2996 
2997  public function isTitleBold(): bool
2998  {
2999  return $this->bold_title;
3000  }
3001 
3002  public static function preloadCommonProperties(array $obj_ids, int $context): void
3003  {
3004  global $DIC;
3005  $lng = $DIC->language();
3006  $ilSetting = $DIC->settings();
3007  $ilUser = $DIC->user();
3008  $notes_manager = $DIC->notes()->internal()->domain()->notes();
3009 
3010  if ($context == self::CONTEXT_REPOSITORY) {
3011  $active_notes = !$ilSetting->get('disable_notes');
3012  $active_comments = !$ilSetting->get('disable_comments');
3013 
3014  if ($active_comments) {
3015  // needed for action
3016  self::$comments_activation = $DIC->notes()
3017  ->internal()
3018  ->domain()
3019  ->notes()->commentsActiveMultiple($obj_ids);
3020  }
3021 
3022  // properties are optional
3023  if ($ilSetting->get('comments_tagging_in_lists')) {
3024  if ($active_notes || $active_comments) {
3025  // @todo: should be refactored, see comment in notes db repo
3026  self::$cnt_notes = $notes_manager->countNotesAndCommentsMultipleObjects(
3027  $obj_ids,
3028  true
3029  );
3030 
3031  $lng->loadLanguageModule('notes');
3032  }
3033 
3034  $tags_set = new ilSetting('tags');
3035  if ($tags_set->get('enable')) {
3036  $all_users = (bool) $tags_set->get('enable_all_users');
3037 
3038  if (!$ilSetting->get('comments_tagging_in_lists_tags')) {
3039  self::$cnt_tags = ilTagging::_countTags($obj_ids, $all_users);
3040  } else {
3041  $tag_user_id = null;
3042  if (!$all_users) {
3043  $tag_user_id = $ilUser->getId();
3044  }
3045  self::$tags = ilTagging::_getListTagsForObjects($obj_ids, $tag_user_id);
3046  }
3047 
3048  $lng->loadLanguageModule('tagging');
3049  }
3050  }
3051 
3052  $lng->loadLanguageModule('rating');
3053  }
3054 
3055  self::$preload_done = true;
3056  }
3057 
3061  protected function isCommentsActivated(
3062  string $type,
3063  int $ref_id,
3064  int $obj_id,
3065  bool $header_actions,
3066  bool $check_write_access = true
3067  ): bool {
3068  if ($this->comments_enabled) {
3069  if (!$this->comments_settings_enabled) {
3070  return true;
3071  }
3072  if ($check_write_access && $this->checkCommandAccess('write', '', $ref_id, $type)) {
3073  return true;
3074  }
3075  // fallback to single object check if no preloaded data
3076  // only the repository does preloadCommonProperties() yet
3077  if (!$header_actions && self::$preload_done) {
3078  if (isset(self::$comments_activation[$obj_id]) &&
3079  self::$comments_activation[$obj_id]) {
3080  return true;
3081  }
3082  } elseif ($this->notes_service->domain()->commentsActive($obj_id)) {
3083  return true;
3084  }
3085  }
3086  return false;
3087  }
3088 
3092  public function enableTimings(bool $status): void
3093  {
3094  $this->timings_enabled = $status;
3095  }
3096 
3100  public function getAsListItem(
3101  int $ref_id,
3102  int $obj_id,
3103  string $type,
3104  string $title,
3105  string $description
3106  ): ?Item {
3107  $ui = $this->ui;
3108 
3109  // even b tag produced bugs, see #32304
3110  $description = strip_tags($description);
3111 
3112  $this->initItem(
3113  $ref_id,
3114  $obj_id,
3115  $type,
3116  $title,
3117  $description
3118  );
3119 
3120  $this->enableCommands(true);
3121 
3122  // actions
3123  $this->insertCommands();
3124  $actions = [];
3125  foreach ($this->current_selection_list->getItems() as $action_item) {
3126  $action = $ui->factory()
3127  ->button()
3128  ->shy($action_item['title'], $action_item['link']);
3129 
3130  if ($action_item['onclick'] !== null && $action_item['onclick'] !== '') {
3131  $action = $action->withAdditionalOnLoadCode(function ($id) use ($action_item): string {
3132  return "$('#$id').click(function(){" . $action_item['onclick'] . ';});';
3133  });
3134  }
3135 
3136  $actions[] = $action;
3137  }
3138 
3139  $dropdown = $ui->factory()
3140  ->dropdown()
3141  ->standard($actions)
3142  ->withAriaLabel(sprintf(
3143  $this->lng->txt('actions_for'),
3144  htmlspecialchars(addslashes($title))
3145  ));
3146 
3147  $def_command = $this->getDefaultCommand();
3148 
3149  if ($def_command['link'] ?? false) {
3150  list($def_command['link'], $def_command['frame']) =
3151  $this->modifySAHSlaunch($def_command['link'], $def_command['frame']);
3152  $new_viewport = !in_array($def_command['frame'], ['', '_top', '_self', '_parent'], true);
3153  $link = $this->ui->factory()
3154  ->link()
3155  ->standard($this->getTitle(), $def_command['link'])
3156  ->withOpenInNewViewport($new_viewport);
3157  $list_item = $ui->factory()->item()->standard($link);
3158  } else {
3159  $list_item = $ui->factory()->item()->standard($this->getTitle());
3160  }
3161 
3162  if ($description != '') {
3163  $list_item = $list_item->withDescription($description);
3164  }
3165  $list_item = $list_item->withActions($dropdown)->withLeadIcon(
3166  $this->ui->factory()->symbol()->icon()->custom(
3167  $this->getTypeIcon(),
3168  $this->buildTranslatedType(),
3169  'medium'
3170  )
3171  );
3172 
3173 
3174  $l = [];
3175  $this->enableComments(true);
3176  $this->enableNotes(true);
3177  $this->enableTags(true);
3178  $this->enableRating(true);
3179 
3180  foreach ($this->determineProperties() as $p) {
3181  //if ($p['property'] !== $this->lng->txt('learning_progress')) {
3182  $l[(string) $p['property']] = (string) $p['value'];
3183  //}
3184  }
3185  if (count($l) > 0) {
3186  $list_item = $list_item->withProperties($l);
3187  }
3188 
3189  return $list_item;
3190  }
3191 
3195  public function getAsCard(
3196  int $ref_id,
3197  int $obj_id,
3198  string $type,
3199  string $title,
3200  string $description
3201  ): ?RepositoryObject {
3202  $ui = $this->ui;
3203 
3204  $title = htmlspecialchars($title);
3205  // even b tag produced bugs, see #32304
3206  $description = strip_tags($description);
3207 
3208  $this->initItem(
3209  $ref_id,
3210  $obj_id,
3211  $type,
3212  $title,
3213  $description
3214  );
3215 
3216  $user = $this->user;
3217  $access = $this->access;
3218 
3219  $this->enableCommands(true);
3220 
3221  $sections = [];
3222 
3223  // description, @todo: move to new ks element
3224  if ($description != '') {
3225  $sections[] = $ui->factory()->legacy('<div class="il-multi-line-cap-3">' . $description . '</div>');
3226  }
3227 
3228  $this->insertCommands();
3229  $actions = [];
3230 
3231  foreach ($this->current_selection_list->getItems() as $item) {
3232  if (!isset($item['onclick']) || $item['onclick'] == '') {
3233  $actions[] =
3234  $ui->factory()->button()->shy($item['title'], $item['link']);
3235  } else {
3236  $actions[] =
3237  $ui->factory()->button()->shy($item['title'], '')->withAdditionalOnLoadCode(function ($id) use ($item): string {
3238  return
3239  "$('#$id').click(function(e) { " . $item['onclick'] . '});';
3240  });
3241  }
3242  }
3243 
3244  $def_command = $this->getDefaultCommand();
3245 
3246  $dropdown = $ui->factory()->dropdown()->standard($actions)
3247  ->withAriaLabel(sprintf(
3248  $this->lng->txt('actions_for'),
3249  $title
3250  ));
3251 
3252  // workaround for #26205
3253  // we should get rid of _top links completely and gifure our how
3254  // to manage scorm links better
3255  $def_cmd_frame = ($def_command['frame'] ?? '');
3256  if ($def_cmd_frame === '_top') {
3257  $def_cmd_frame = '';
3258  }
3259  $def_cmd_link = ($def_command['link'] ?? '');
3260 
3261  // workaround for scorm
3262  list($modified_link, $def_cmd_frame) =
3263  $this->modifySAHSlaunch($def_cmd_link, $def_cmd_frame);
3264 
3265  $image = $this->getTileImage();
3266 
3267  if ($def_cmd_link != '') { // #24256
3268  if ($def_cmd_frame !== '' && ($modified_link === $def_cmd_link)) {
3269  $signal = (new SignalGenerator())->create();
3270  $this->main_tpl->addOnLoadCode(
3271  "$(document).on('{$signal->getId()}', function(event, signalData) {"
3272  . ' window.open("' . str_replace(
3273  '&amp;',
3274  '&',
3275  $def_cmd_link
3276  ) . '", "' . $def_cmd_frame . '");'
3277  . '});'
3278  );
3279 
3280  $image = $image->withAction($signal);
3281 
3282  $button =
3283  $ui->factory()->button()->shy($title, '')->appendOnClick($signal);
3284  $title = $ui->renderer()->render($button);
3285  } else {
3286  $image = $image->withAction($modified_link);
3287  }
3288  }
3289 
3290  if ($type == 'sess') {
3291  if ($title != '') {
3292  $title = ': ' . $title;
3293  }
3294  $app_info = ilSessionAppointment::_lookupAppointment($obj_id);
3295  $title = ilSessionAppointment::_appointmentToString(
3296  $app_info['start'],
3297  $app_info['end'],
3298  (bool) $app_info['fullday']
3299  ) . $title;
3300  }
3301 
3302  $icon = $this->ui->factory()->symbol()->icon()->custom(
3303  $this->getTypeIcon(),
3304  $this->buildTranslatedType(),
3305  'medium'
3306  );
3307 
3308  // card title action
3309  $card_title_action = '';
3310  if ($def_cmd_link != '' && ($def_cmd_frame == '' || $modified_link != $def_cmd_link)) { // #24256
3311  $card_title_action = $modified_link;
3312  } elseif ($def_cmd_link == '' &&
3313  $this->getInfoScreenStatus() &&
3314  $access->checkAccessOfUser(
3315  $user->getId(),
3316  'visible',
3317  '',
3318  $ref_id
3319  )) {
3320  $card_title_action = ilLink::_getLink($ref_id);
3321  if ($image->getAction() == '') {
3322  $image = $image->withAction($card_title_action);
3323  }
3324  }
3325 
3326  $card = $ui->factory()->card()->repositoryObject(
3327  $title . '<span data-list-item-id="' . $this->getUniqueItemId(true) . '"></span>',
3328  $image
3329  )->withObjectIcon(
3330  $icon
3331  )->withActions(
3332  $dropdown
3333  );
3334 
3335  if ($card_title_action != '') {
3336  $card = $card->withTitleAction($card_title_action);
3337  }
3338 
3339  $l = [];
3340  foreach ($this->determineProperties() as $p) {
3341  if (isset($p['alert']) && $p['alert'] == true
3342  && isset($p['property']) && $p['property'] !== $this->lng->txt('learning_progress')) {
3343  $l[(string) $p['property']] = (string) $p['value'];
3344  }
3345  }
3346  if (count($l) > 0) {
3347  $prop_list = $ui->factory()->listing()->descriptive($l);
3348  $sections[] = $prop_list;
3349  }
3350  if (count($sections) > 0) {
3351  $card = $card->withSections($sections);
3352  }
3353 
3354  $lp = ilLPStatus::getListGUIStatus($obj_id, false);
3355  if (is_array($lp) && array_key_exists('status', $lp)) {
3356  $percentage = (int) ilLPStatus::_lookupPercentage($obj_id, $this->user->getId());
3357  if ($lp['status'] == ilLPStatus::LP_STATUS_COMPLETED_NUM) {
3358  $percentage = 100;
3359  }
3360 
3361  $card = $card->withProgress(
3362  $ui->factory()
3363  ->chart()
3364  ->progressMeter()
3365  ->mini(100, $percentage)
3366  );
3367  }
3368 
3369  return $card;
3370  }
3371 
3372  public function checkInfoPageOnAsynchronousRendering(): bool
3373  {
3374  return false;
3375  }
3376 
3377  private function getTileImage(): Image
3378  {
3379  return $this->object_properties->getPropertyTileImage()
3380  ->getTileImage()->getImage($this->ui->factory()->image());
3381  }
3382 
3386  public function insertLPCommand(): void
3387  {
3388  if ($this->std_cmd_only || !$this->lp_cmd_enabled) {
3389  return;
3390  }
3391  $relevant = ilLPStatus::hasListGUIStatus($this->obj_id);
3392  if ($relevant) {
3393  $cmd_link = $this->getCommandLink('learningProgress');
3394  $this->insertCommand(
3395  $cmd_link,
3396  $this->lng->txt('learning_progress')
3397  );
3398  }
3399  }
3400 
3404  private function insertLPSettingsCommand(): void
3405  {
3406  if (!ilObjUserTracking::_enabledLearningProgress()
3407  || ilObjectLP::getTypeClass($this->type) === ''
3408  || ! $this->checkCommandAccess('edit_learning_progress', '', $this->ref_id, $this->type)
3409  ) {
3410  return;
3411  }
3412 
3413  $cmd_link = '';
3414  $this->ctrl->setParameterByClass(ilLearningProgressGUI::class, 'ref_id', $this->ref_id);
3415  switch ($this->type) {
3416  case 'sahs':
3417  switch (ilObjSAHSLearningModule::_lookupSubType($this->obj_id)) {
3418  case 'scorm2004':
3419  $scorm_class = ilObjSCORM2004LearningModuleGUI::class;
3420  break;
3421  case 'scorm':
3422  $scorm_class = ilObjSCORMLearningModuleGUI::class;
3423  break;
3424  default:
3425  $scorm_class = '';
3426  break;
3427  }
3428 
3429  $cmd_link = $this->ctrl->getLinkTargetByClass([
3430  ilSAHSEditGUI::class,
3431  $scorm_class,
3432  ilLearningProgressGUI::class,
3433  ilLPListOfSettingsGUI::class
3434  ]);
3435  break;
3436 
3437  case 'lm':
3438  $cmd_link = $this->ctrl->getLinkTargetByClass([
3439  ilLMEditorGUI::class,
3440  ilObjLearningModuleGUI::class,
3441  ilLearningProgressGUI::class,
3442  ilLPListOfSettingsGUI::class
3443  ]);
3444  break;
3445 
3446  case 'lso':
3447  $cmd_link = $this->ctrl->getLinkTargetByClass([
3448  ilObjLearningSequenceGUI::class,
3449  ilLearningProgressGUI::class,
3450  ilLPListOfSettingsGUI::class
3451  ]);
3452  break;
3453 
3454  case 'copa':
3455  case 'iass':
3456  case 'tst':
3457  case 'htlm':
3458  case 'exc':
3459  case 'svy':
3460  case 'file':
3461  case 'crs':
3462  $gui_class = 'ilObj' . $this->obj_definition->getClassName($this->type) . 'GUI';
3463  $cmd_link = $this->ctrl->getLinkTargetByClass([
3464  ilRepositoryGUI::class,
3465  $gui_class,
3466  ilLearningProgressGUI::class,
3467  ilLPListOfSettingsGUI::class
3468  ]);
3469  break;
3470 
3471  case 'prgr':
3472  case 'prg':
3473  case 'lso':
3474  break;
3475  default:
3476  break;
3477  }
3478 
3479  $this->ctrl->setParameterByClass('ilrepositorygui', 'ref_id', $this->requested_ref_id);
3480  if ($cmd_link !== '') {
3481  $this->insertCommand(
3482  $cmd_link,
3483  $this->lng->txt('listaction_learning_progress_settings')
3484  );
3485  }
3486  }
3487 
3488  private function buildTranslatedType(): string
3489  {
3490  if ($this->obj_definition->isPlugin($this->getIconImageType())) {
3491  return ilObjectPlugin::lookupTxtById($this->getIconImageType(), 'obj_' . $this->getIconImageType());
3492  }
3493 
3494  return $this->lng->txt('obj_' . $this->getIconImageType());
3495  }
3496 }
getCommands()
get all current commands for a specific ref id (in the permission context of the current user) ...
This describes commonalities between the different modals.
Definition: Modal.php:34
Creates a path for a start and endnode.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setHeaderSubObject(?string $type, ?int $id)
parseConditions(int $toggle_id, array $conditions, bool $obligatory=true)
insertSearchFragment()
Insert highlighted search fragment.
setConditionTarget(int $ref_id, int $obj_id, string $target_type)
getDescription()
getDescription overwritten in class.ilObjLinkResourceList.php
static appendUrlParameterString(string $a_url, string $a_par, bool $xml_style=false)
bool $enabled
Whether the system instance is enabled to accept connection requests.
Definition: System.php:123
init()
initialisation
static string $tpl_component
ilListItemAccessCache $acache
modifySAHSlaunch(string $link, string $target)
workaround: SAHS in new javavasript-created window or iframe
const ANONYMOUS_USER_ID
Definition: constants.php:27
ilObjectProperties $object_properties
setParentRefId(int $ref_id)
Set current parent ref id to enable unique js-ids (sessions, etc.)
setMode(string $mode)
set output mode
enableCommands(bool $status, bool $std_only=false)
setAdditionalInformation(?string $val)
setContainerObject(object $container_obj)
setSearchFragment(string $text)
getUniqueItemId(bool $as_div=false)
Get unique item identifier (for js-actions)
initItem(int $ref_id, int $obj_id, string $type, string $title='', string $description='')
initialize new item (is called by getItemHTML())
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: buildRTE.php:22
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:33
static getListTagsJSCall(string $a_hash, string $a_update_code=null)
addHeaderIcon(string $id, string $img, string $tooltip=null, string $onclick=null, string $status_text=null, string $href=null)
insertPreconditions()
insert all missing preconditions
Class ChatMainBarProvider .
setDescription(string $description)
static prepareJsLinks(string $redraw_url, string $notes_url, string $tags_url, ilGlobalTemplateInterface $tpl=null)
Insert js/ajax links into template.
checkAccess(string $a_permission, string $a_cmd, int $a_ref_id, string $a_type="", ?int $a_obj_id=null, ?int $a_tree_id=null)
check access for an object (provide $a_type and $a_obj_id if available for better performance) ...
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
checkCommandAccess(string $permission, string $cmd, int $ref_id, string $type, ?int $obj_id=null)
getCommandFrame(string $cmd)
Get command target frame.
static getGotoLink(int $a_node_id, int $a_obj_id, string $a_additional="")
appendRepositoryFrameParameter(string $link)
workaround: all links into the repository (from outside) must tell repository to set up the frameset ...
enableExpand(bool $status)
enableDelete(bool $status)
insertCopyCommand(bool $to_repository=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getItemDetailLinkStatus()
get item detail link status
setPositionInputField(string $field_index, string $position_value)
insertCommands(bool $use_async=false, bool $get_async_commands=false, string $async_url='', bool $header_actions=false)
insert all commands into html code
enableMultiDownload(bool $value)
Toggles whether multiple objects can be downloaded at once or not.
setDetailsLevel(int $level)
Details level Currently used in Search which shows only limited properties of forums Currently used f...
ilAccessHandler $access
ILIAS Notes Service $notes_service
ilFavouritesManager $fav_manager
enableSubscribe(bool $status)
ilWorkspaceAccessHandler $ws_access
ilAdvancedSelectionListGUI $current_selection_list
addCustomCommandButton(Button $button, ?Modal $triggeredModal=null)
enableLinkedPath(bool $status)
ilGlobalTemplateInterface $main_tpl
static img(string $a_src, ?string $a_alt=null, $a_width="", $a_height="", $a_border=0, $a_id="", $a_class="")
Build img tag.
Manages favourites, currently the interface for other components, needs discussion.
$path
Definition: ltiservices.php:32
enableInfoScreen(bool $info_screen)
static _lookupObjId(int $ref_id)
static lookupOfflineStatus(int $obj_id)
Lookup offline status using objectDataCache.
static string $tpl_file_name
enableRating(bool $value, string $text=null, bool $categories=false, array $ctrl_path=null, bool $force_rate_parent=false)
global $DIC
Definition: feed.php:28
enablePreconditions(bool $status)
enableSearchFragments(bool $status)
enableProperties(bool $status)
static _getInstance()
Get singleton instance of this class.
parses the objects.xml it handles the xml-description of all ilias objects
enableNoticeProperties(bool $status)
Provides fluid interface to RBAC services.
Definition: UIServices.php:23
const ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION
getHeaderAction(ilGlobalTemplateInterface $main_tpl=null)
static http()
Fetches the global http state from ILIAS.
static _getCommands()
get commands
__construct(VocabulariesInterface $vocabularies)
getMode()
get output mode
getProperties()
Get item properties.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
createDefaultCommand(array $command)
Get default command link Overwritten for e.g categories,courses => they return a goto link If search ...
enablePath(bool $path, int $start_node=0, \ilPathGUI $path_gui=null)
static _checkCondition(array $condition, int $a_usr_id=0)
checks wether a single condition is fulfilled every trigger object type must implement a static metho...
enableComments(bool $value, bool $enable_comments_settings=true)
static _lookupTitle(int $obj_id)
getCommandId()
get command id Normally the ref id.
restrictToGoto(bool $value)
Restrict all actions/links to goto.
static calculateEffectiveRequiredTriggers(int $a_target_ref_id, int $a_target_obj_id, string $a_target_obj_type='')
setDefaultCommandParameters(array $params)
getCommandImage(string $cmd)
Get command icon image.
enableProgressInfo(bool $status)
ilCtrlInterface $ctrl
Manages items in repository clipboard.
isMode(string $mode)
check current output mode
setConditionDepth(int $depth)
set depth for precondition output (stops at level 5)
getIconImageType()
Returns the icon image type.
disableTitleLink(bool $status)
$txt
Definition: error.php:14
static addTooltip(string $a_el_id, string $a_text, string $a_container="", string $a_my="bottom center", string $a_at="top center", bool $a_use_htmlspecialchars=true)
addOnLoadCode(string $a_code, int $a_batch=2)
Add on load code.
addSubItemHTML(string $html)
Add HTML for sub item (used for sessions)
isCommentsActivated(string $type, int $ref_id, int $obj_id, bool $header_actions, bool $check_write_access=true)
Check comments status against comments settings and context.
addCustomCommand(string $link, string $lang_var, string $frame='', string $onclick='')
static getListGUIStatus(int $a_obj_id, bool $a_image_only=true)
enableLearningProgress(bool $enabled)
getCustomProperties(array $prop)
insertLPCommand()
insert learning progress command
static getTagsForUserAndObject(int $a_obj_id, string $a_obj_type, int $a_sub_obj_id, string $a_sub_obj_type, int $a_user_id)
ILIAS Refinery Factory $refinery
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
insertCutCommand(bool $to_repository=false)
static initJavascript(string $a_ajax_url, ilGlobalTemplateInterface $a_main_tpl=null)
getTitle()
getTitle overwritten in class.ilObjLinkResourceList.php
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static buildAjaxHash(int $node_type, ?int $node_id, string $obj_type, int $obj_id, string $sub_type=null, int $sub_id=null, int $news_id=0)
Build ajax hash.
addHeaderGlyph(string $id, ILIAS\UI\Component\Symbol\Glyph\Glyph $glyph, $onclick=null)
commandsNeedToBeHidden(bool $use_async, bool $get_async_commands, bool $header_actions)
Fix bug #12417: We hide the action menu when we are in the public area.
static getListNotesJSCall(string $a_hash, string $a_update_code=null)
Get list notes js call.
ilAdvancedMDSubstitution $substitutions
enableRelevance(bool $status)
enableSubstitutions(bool $status)
insertTimingsCommand()
ks, 23 OCT 2023: This function is badly named and it already was before the changes made today...
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
link(string $caption, string $href, bool $new_viewport=false)
enableCheckbox(bool $status)
static translateOperator(int $a_obj_id, string $a_operator)
Class ilContainerGUI This is a base GUI class for all container objects in ILIAS: root folder...
setItemDetailLinks(array $detail_links, string $intro_txt='')
set items detail links
getCommandLink(string $cmd)
Get command link url.
ILIAS HTTP Wrapper RequestWrapper $request_wrapper
static getEffectiveOptionalConditionsOfTarget(int $a_target_ref_id, int $a_target_obj_id, string $a_obj_type='')
ClipboardManager $clipboard
ilObjectDefinition $obj_definition
insertCommand(string $href, string $text, string $frame='', string $img='', string $cmd='', string $onclick='')
insert command button
enableItemDetailLinks(bool $status)
enable item detail links E.g Direct links to chapters or pages
getUriToMountInstructionModalByRef(int $a_ref_id)
disabled()
Example showing how to plug a disabled checkbox into a form.
Definition: disabled.php:10
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...
static getListCommentsJSCall(string $a_hash, string $a_update_code=null)
Get list comments js call.
insertCommonSocialCommands(bool $header_actions=false)
Insert common social commands (comments, notes, tagging)
static _lookupType(int $id, bool $reference=false)
enableDescription(bool $status)
static array $comments_activation
addHeaderIconHTML(string $id, string $html)
enableDownloadCheckbox(int $ref_id)
enableRepositoryTransfer(bool $value)
Enable copy/move to repository (from personal workspace)
ilLDAPRoleGroupMapping $ldap_mapping
catch(InvalidArgumentException $e) if(!ilDAVActivationChecker::_isActive()) $webdav_dic
Definition: webdav.php:57
Class ilObjSCORMLearningModule.
modifyTitleLink(string $default_link)
addCustomProperty(string $property='', string $value='', bool $alert=false, bool $newline=false)
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)