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