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