ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
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 if (!$this->fav_manager->ifIsFavourite($this->user->getId(), $this->getCommandId())) {
1812 // Pass type and object ID to ilAccess to improve performance
1813 if ($this->checkCommandAccess('read', '', $this->ref_id, $this->type, $this->obj_id)) {
1814 $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'addToDesk');
1815 $this->insertCommand($cmd_link, $this->lng->txt('rep_add_to_favourites'));
1816 }
1817 } else {
1818 $cmd_link = $this->ctrl->getLinkTarget($this->container_obj, 'removeFromDesk');
1819 $this->insertCommand($cmd_link, $this->lng->txt('rep_remove_from_favourites'));
1820 }
1821
1822 $this->ctrl->clearParameters($this->container_obj);
1823 }
1824 }
1825
1826 public function insertInfoScreenCommand(): void
1827 {
1828 if ($this->std_cmd_only) {
1829 return;
1830 }
1831 $this->insertCommand(
1832 $this->getCommandLink('infoScreen'),
1833 $this->lng->txt('info_short'),
1834 $this->getCommandFrame('infoScreen'),
1835 ilUtil::getImagePath('standard/icon_info.svg')
1836 );
1837 }
1838
1842 public function insertCommonSocialCommands(bool $header_actions = false): void
1843 {
1844 if ($this->std_cmd_only || $this->user->isAnonymous()) {
1845 return;
1846 }
1847
1848 $this->lng->loadLanguageModule('notes');
1849 $this->lng->loadLanguageModule('tagging');
1850 $cmd_frame = $this->getCommandFrame('infoScreen');
1851
1852 // reference objects have translated ids, revert to originals
1853 $note_ref_id = $this->ref_id;
1854 if ($this->reference_ref_id) {
1855 $note_ref_id = $this->reference_ref_id;
1856 }
1857
1858 $js_updater = $header_actions
1859 ? 'il.Object.redrawActionHeader();'
1860 : 'il.Object.redrawListItem(' . $note_ref_id . ')';
1861
1862 $comments_enabled = $this->isCommentsActivated($this->type, $this->ref_id, $this->obj_id, $header_actions);
1863 if ($comments_enabled) {
1864 $this->insertCommand(
1865 '#',
1866 $this->lng->txt('notes_comments'),
1867 $cmd_frame,
1868 '',
1869 '',
1870 ilNoteGUI::getListCommentsJSCall($this->ajax_hash, $js_updater)
1871 );
1872 }
1873
1874 if ($this->notes_enabled) {
1875 $this->insertCommand(
1876 '#',
1877 $this->lng->txt('notes'),
1878 $cmd_frame,
1879 '',
1880 '',
1881 ilNoteGUI::getListNotesJSCall($this->ajax_hash, $js_updater)
1882 );
1883 }
1884
1885 if ($this->tags_enabled) {
1886 $this->insertCommand(
1887 '#',
1888 $this->lng->txt('tagging_set_tag'),
1889 $cmd_frame,
1890 '',
1891 '',
1892 ilTaggingGUI::getListTagsJSCall($this->ajax_hash, $js_updater)
1893 );
1894 }
1895 }
1896
1903 public function insertTimingsCommand(): void
1904 {
1905 if (
1906 $this->std_cmd_only || is_null($this->container_obj) ||
1907 !method_exists($this->container_obj, 'getObject') ||
1908 !is_object($this->container_obj->getObject())
1909 ) {
1910 return;
1911 }
1912
1913 $parent_ref_id = $this->container_obj->getObject()->getRefId();
1914 $parent_type = $this->container_obj->getObject()->getType();
1915
1916 // #18737
1917 if ($this->reference_ref_id) {
1918 $this->ctrl->setParameterByClass('ilconditionhandlergui', 'ref_id', $this->reference_ref_id);
1919 }
1920
1921 if (
1922 $this->checkCommandAccess('write', '', $parent_ref_id, $parent_type) ||
1923 $this->checkCommandAccess('write', '', $this->ref_id, $this->type)
1924 ) {
1925 $this->ctrl->setParameterByClass(
1926 get_class($this->container_obj),
1927 'tl_id',
1928 $this->ref_id
1929 );
1930 $time_limit_link = $this->ctrl->getLinkTargetByClass(
1931 get_class($this->container_obj),
1932 'editAvailabilityPeriod'
1933 );
1934 $this->insertCommand($time_limit_link, $this->lng->txt('edit_availability_period'));
1935 $this->ctrl->clearParameterByClass(
1936 get_class($this->container_obj),
1937 'tl_id',
1938 );
1939
1940 $this->ctrl->setParameterByClass(
1941 'ilconditionhandlergui',
1942 'cadh',
1943 $this->ajax_hash
1944 );
1945 $this->ctrl->setParameterByClass(
1946 'ilconditionhandlergui',
1947 'parent_id',
1948 $parent_ref_id
1949 );
1950
1951 $availbility_link = $this->ctrl->getLinkTargetByClass(
1952 [$this->gui_class_name, 'ilcommonactiondispatchergui', 'ilobjectactivationgui', 'ilconditionhandlergui'],
1953 'listConditions'
1954 );
1955
1956 $this->insertCommand($availbility_link, $this->lng->txt('preconditions'));
1957 }
1958
1959 if ($this->reference_ref_id) {
1960 $this->ctrl->setParameterByClass('ilconditionhandlergui', 'ref_id', $this->ref_id);
1961 }
1962 }
1963
1967 private function populateCommands(
1968 bool $for_header
1969 ): void {
1970 $commands = $this->getCommands();
1971 if (!$this->getCommandsStatus() || $this->commandsNeedToBeHidden($for_header)) {
1972 foreach ($commands as $command) {
1973 if ($command['default'] === true) {
1974 $this->default_command = $command['granted'] === true ? $this->createDefaultCommand($command) : [];
1975 }
1976 return;
1977 }
1978 return;
1979 }
1980
1981 $this->ctrl->setParameterByClass($this->gui_class_name, 'ref_id', $this->ref_id);
1982
1983 $this->current_actions = [];
1984 $this->default_command = [];
1985 $this->prevent_duplicate_commands = [];
1986
1987 // we only allow the following commands inside the header actions
1988 $valid_header_commands = ['mount_webfolder'];
1989
1990 foreach ($commands as $command) {
1991 if ($for_header && !in_array($command['cmd'], $valid_header_commands)
1992 || $command['granted'] === false) {
1993 continue;
1994 }
1995
1996 if ($command['default'] !== true) {
1997 if (!$this->std_cmd_only) {
1998 // workaround for repository frameset
1999 $command['link'] =
2000 $this->appendRepositoryFrameParameter($command['link']);
2001
2002 $cmd_link = $command['link'];
2003 $txt = ($command['lang_var'] == '')
2004 ? $command['txt']
2005 : $this->lng->txt($command['lang_var']);
2006 $this->insertCommand(
2007 $cmd_link,
2008 $txt,
2009 $command['frame'],
2010 $command['img'],
2011 $command['cmd']
2012 );
2013 }
2014 } else {
2015 $this->default_command = $this->createDefaultCommand($command);
2016 }
2017 }
2018
2019 // custom commands
2020 if (is_array($this->cust_commands)) {
2021 foreach ($this->cust_commands as $command) {
2022 if ($command instanceof Button) {
2023 $this->current_actions[] = $command;
2024 continue;
2025 }
2026
2027 $this->insertCommand(
2028 $command['link'],
2029 $this->lng->txt($command['lang_var']),
2030 $command['frame'],
2031 '',
2032 $command['cmd'] ?? '',
2033 $command['onclick']
2034 );
2035 }
2036 }
2037 $this->insertLPSettingsCommand();
2038
2039 // info screen command
2040 if ($this->getInfoScreenStatus()) {
2041 $this->insertInfoScreenCommand();
2042 }
2043
2044 $this->insertLPCommand();
2045
2046 if (!$this->isMode(self::IL_LIST_AS_TRIGGER)) {
2047 // edit timings
2048 if ($this->timings_enabled) {
2049 $this->insertTimingsCommand();
2050 }
2051
2052 // delete
2053 if ($this->delete_enabled) {
2054 $this->insertDeleteCommand();
2055 }
2056
2057 // link
2058 if ($this->link_enabled) {
2059 $this->insertLinkCommand();
2060 }
2061
2062 // cut
2063 if ($this->cut_enabled) {
2064 $this->insertCutCommand();
2065 }
2066
2067 // copy
2068 if ($this->copy_enabled) {
2069 $this->insertCopyCommand();
2070 }
2071
2072 // cut/copy from workspace to repository
2073 if ($this->repository_transfer_enabled) {
2074 $this->insertCutCommand(true);
2075 $this->insertCopyCommand(true);
2076 }
2077
2078 // subscribe
2079 if ($this->subscribe_enabled) {
2080 $this->insertSubscribeCommand();
2081 }
2082
2083 // multi download
2084 if ($this->multi_download_enabled && $for_header) {
2085 $this->insertMultiDownloadCommand();
2086 }
2087
2088 // BEGIN PATCH Lucene search
2089 if ($this->cut_enabled or $this->link_enabled) {
2090 $this->insertPasteCommand();
2091 }
2092 // END PATCH Lucene Search
2093 }
2094
2095 // common social commands (comment, notes, tags)
2096 if (!$this->isMode(self::IL_LIST_AS_TRIGGER)) {
2097 $this->insertCommonSocialCommands($for_header);
2098 }
2099 }
2100
2104 // there is one case, where no action menu should be displayed:
2105 // public area, category, no info tab
2106 // todo: make this faster and remove type specific implementation if possible
2107 private function commandsNeedToBeHidden(
2108 bool $for_header
2109 ): bool {
2110 if (!$for_header
2111 && $this->user->getId() === ANONYMOUS_USER_ID && $this->checkInfoPageOnAsynchronousRendering()
2112 && $this->object_properties->getPropertyInfoTabVisibility()) {
2113 return true;
2114 }
2115 return false;
2116 }
2117
2118 public function enableComments(bool $value, bool $enable_comments_settings = true): void
2119 {
2120 if ($this->settings->get('disable_comments')) {
2121 $value = false;
2122 }
2123
2124 $this->comments_enabled = $value;
2125 $this->comments_settings_enabled = $enable_comments_settings;
2126 }
2127
2128 public function enableNotes(bool $value): void
2129 {
2130 if ($this->settings->get('disable_notes')) {
2131 $value = false;
2132 }
2133
2134 $this->notes_enabled = $value;
2135 }
2136
2137 public function enableTags(bool $value): void
2138 {
2139 $tags_set = new ilSetting('tags');
2140 if (!$tags_set->get('enable')) {
2141 $value = false;
2142 }
2143 $this->tags_enabled = $value;
2144 }
2145
2146 public function enableRating(
2147 bool $value,
2148 ?string $text = null,
2149 bool $categories = false,
2150 ?array $ctrl_path = null,
2151 bool $force_rate_parent = false
2152 ): void {
2153 $this->rating_enabled = $value;
2154
2155 if ($this->rating_enabled) {
2156 $this->rating_categories_enabled = $categories;
2157 $this->rating_text = $text;
2158 $this->rating_ctrl_path = $ctrl_path;
2159 $this->force_rate_parent = $force_rate_parent;
2160 }
2161 }
2162
2168 public function enableMultiDownload(bool $value): void
2169 {
2170 $folder_set = new ilSetting('fold');
2171 if (!$folder_set->get('enable_multi_download')) {
2172 $value = false;
2173 }
2174 $this->multi_download_enabled = $value;
2175 }
2176
2177 public function insertMultiDownloadCommand(): void
2178 {
2179 if ($this->std_cmd_only) {
2180 return;
2181 }
2182
2183 if (!$this->obj_definition->isContainer(ilObject::_lookupType($this->obj_id))) {
2184 return;
2185 }
2186
2187 if ($this->getContainerObject() instanceof ilContainerGUI) {
2188 $this->ctrl->setParameter($this->getContainerObject(), 'type', '');
2189 $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', '');
2190 $this->ctrl->setParameter($this->getContainerObject(), 'active_node', '');
2191 // bugfix mantis 24559
2192 // undoing an erroneous change inside mantis 23516 by
2193 // adding 'Download Multiple Objects'-functionality for non-admins
2194 // as they don't have the possibility to use the multi-download-capability of the manage-tab
2195 $user_id = $this->user->getId();
2196 $hasAdminAccess = $this->access->checkAccessOfUser($user_id, 'crs_admin', $this->ctrl->getCmd(), $this->requested_ref_id);
2197 // to still prevent duplicate download functions for admins
2198 // the following if-else statement keeps the redirection for admins
2199 // while letting other course members access the original multi-download functionality
2200 if ($hasAdminAccess) {
2201 $cmd = ($this->requested_cmd == 'enableAdministrationPanel')
2202 ? 'render'
2203 : 'enableAdministrationPanel';
2204 } else {
2205 $cmd = ($this->requested_cmd == 'enableMultiDownload')
2206 ? 'render'
2207 : 'enableMultiDownload';
2208 }
2209 $cmd_link = $this->ctrl->getLinkTarget($this->getContainerObject(), $cmd);
2210 $this->insertCommand($cmd_link, $this->lng->txt('download_multiple_objects'));
2211 }
2212 }
2213
2214 public function enableDownloadCheckbox(int $ref_id): void
2215 {
2216 // TODO: delegate to list object class!
2217 if (!$this->getContainerObject()->isActiveAdministrationPanel() || $this->clipboard->hasEntries()) {
2218 if (
2219 in_array($this->type, ['file', 'fold']) &&
2220 $this->access->checkAccess('read', '', $ref_id, $this->type)
2221 ) {
2222 $this->download_checkbox_state = self::DOWNLOAD_CHECKBOX_ENABLED;
2223 } else {
2224 $this->download_checkbox_state = self::DOWNLOAD_CHECKBOX_DISABLED;
2225 }
2226 } else {
2227 $this->download_checkbox_state = self::DOWNLOAD_CHECKBOX_NONE;
2228 }
2229 }
2230
2232 {
2233 return $this->download_checkbox_state;
2234 }
2235
2239 public static function prepareJsLinks(
2240 string $redraw_url,
2241 string $notes_url,
2242 string $tags_url,
2243 ?ilGlobalTemplateInterface $tpl = null
2244 ): void {
2245 global $DIC;
2246
2247 if (is_null($tpl)) {
2248 $tpl = $DIC['tpl'];
2249 }
2250
2251 //if ($notes_url) {
2252 $DIC->notes()->gui()->initJavascript($notes_url);
2253 //}
2254
2255 if ($tags_url) {
2256 ilTaggingGUI::initJavascript($tags_url, $tpl);
2257 }
2258
2259 if ($redraw_url) {
2260 $tpl->addOnLoadCode('il.Object.setRedrawAHUrl("' . $redraw_url . '");');
2261 }
2262 }
2263
2264 public function setHeaderSubObject(?string $type, ?int $id): void
2265 {
2266 $this->sub_obj_type = $type;
2267 $this->sub_obj_id = (int) $id;
2268 }
2269
2270 public function addHeaderIcon(
2271 string $id,
2272 string $img,
2273 ?string $tooltip = null,
2274 ?string $onclick = null,
2275 ?string $status_text = null,
2276 ?string $href = null
2277 ): void {
2278 $this->header_icons[$id] = [
2279 'img' => $img,
2280 'tooltip' => $tooltip,
2281 'onclick' => $onclick,
2282 'status_text' => $status_text,
2283 'href' => $href
2284 ];
2285 }
2286
2287 public function addHeaderIconHTML(string $id, string $html): void
2288 {
2289 $this->header_icons[$id] = $html;
2290 }
2291
2292 public function addHeaderGlyph(string $id, ILIAS\UI\Component\Symbol\Glyph\Glyph $glyph, $onclick = null): void
2293 {
2294 $this->header_icons[$id] = ['glyph' => $glyph, 'onclick' => $onclick];
2295 }
2296
2297 public function setAjaxHash(string $hash): void
2298 {
2299 $this->ajax_hash = $hash;
2300 }
2301
2302 public function getHeaderAction(?ilGlobalTemplateInterface $main_tpl = null): string
2303 {
2304 if ($main_tpl == null) {
2305 $main_tpl = $this->main_tpl;
2306 }
2307
2308 $htpl = new ilTemplate('tpl.header_action.html', true, true, 'components/ILIAS/ILIASObject');
2309
2310 $redraw_js = 'il.Object.redrawActionHeader();';
2311
2312 // tags
2313 if ($this->tags_enabled) {
2315 $this->obj_id,
2316 ilObject::_lookupType($this->obj_id),
2317 0,
2318 '',
2319 $this->user->getId()
2320 );
2321 if (count($tags) > 0) {
2322 $this->lng->loadLanguageModule('tagging');
2323
2324 $f = $this->ui->factory();
2325 $this->addHeaderGlyph(
2326 'tags',
2327 $f->symbol()->glyph()->tag('#')
2328 ->withCounter($f->counter()->status(count($tags))),
2329 ilTaggingGUI::getListTagsJSCall($this->ajax_hash, $redraw_js)
2330 );
2331 }
2332 }
2333
2334 // notes and comments
2335 $comments_enabled = $this->isCommentsActivated($this->type, $this->ref_id, $this->obj_id, true, false);
2336 if ($this->notes_enabled || $comments_enabled) {
2337 $type = ($this->sub_obj_type == '') ? $this->type : $this->sub_obj_type;
2338 $context = $this->notes_service->data()->context($this->obj_id, $this->sub_obj_id, $type);
2339 $cnt[$this->obj_id][Note::PUBLIC] = $this->notes_service->domain()->getNrOfCommentsForContext($context);
2340 $cnt[$this->obj_id][Note::PRIVATE] = $this->notes_service->domain()->getNrOfNotesForContext($context);
2341 if (
2342 $this->notes_enabled &&
2343 isset($cnt[$this->obj_id][Note::PRIVATE]) &&
2344 $cnt[$this->obj_id][Note::PRIVATE] > 0
2345 ) {
2346 $f = $this->ui->factory();
2347 $this->addHeaderGlyph(
2348 'notes',
2349 $f->symbol()->glyph()->note('#')
2350 ->withCounter($f->counter()->status((int) $cnt[$this->obj_id][Note::PRIVATE])),
2351 ilNoteGUI::getListNotesJSCall($this->ajax_hash, $redraw_js)
2352 );
2353 }
2354
2355 if (
2356 $comments_enabled &&
2357 isset($cnt[$this->obj_id][Note::PUBLIC]) &&
2358 $cnt[$this->obj_id][Note::PUBLIC] > 0
2359 ) {
2360 $this->lng->loadLanguageModule('notes');
2361 $f = $this->ui->factory();
2362 $this->addHeaderGlyph(
2363 'comments',
2364 $f->symbol()->glyph()->comment('#')
2365 ->withCounter($f->counter()->status((int) $cnt[$this->obj_id][Note::PUBLIC])),
2366 ilNoteGUI::getListCommentsJSCall($this->ajax_hash, $redraw_js)
2367 );
2368 }
2369 }
2370
2371 // rating
2372 if ($this->rating_enabled) {
2373 $rating_gui = new ilRatingGUI();
2374 $rating_gui->enableCategories($this->rating_categories_enabled);
2375 // never rate sub objects from header action!
2376 $rating_gui->setObject($this->obj_id, $this->type);
2377 if ($this->rating_text) {
2378 $rating_gui->setYourRatingText($this->rating_text);
2379 }
2380
2381 $ajax_hash = $this->force_rate_parent
2383 : $this->ajax_hash;
2384 $this->ctrl->setParameterByClass('ilRatingGUI', 'cadh', $ajax_hash);
2385 $this->ctrl->setParameterByClass('ilRatingGUI', 'rnsb', true);
2386 if ($this->rating_ctrl_path) {
2387 $rating_gui->setCtrlPath($this->rating_ctrl_path);
2388 $ajax_url = $this->ctrl->getFormActionByClass($this->rating_ctrl_path, 'saveRating', '', true);
2389 } else {
2390 $ajax_url = $this->ctrl->getFormActionByClass('ilRatingGUI', 'saveRating', '', true);
2391 }
2392 $main_tpl->addOnLoadCode('il.Object.setRatingUrl("' . $ajax_url . '");');
2393 $this->addHeaderIconHTML(
2394 'rating',
2395 $rating_gui->getHTML(
2396 true,
2397 $this->checkCommandAccess('read', '', $this->ref_id, $this->type),
2398 'il.Object.saveRating(%rating%);'
2399 )
2400 );
2401 }
2402
2403 if ($this->header_icons) {
2404 $chunks = [];
2405 foreach ($this->header_icons as $id => $attr) {
2406 $id = 'headp_' . $id;
2407
2408 if (is_array($attr)) {
2409 if (isset($attr['glyph']) && $attr['glyph']) {
2410 if ($attr['onclick']) {
2411 $htpl->setCurrentBlock('prop_glyph_oc');
2412 $htpl->setVariable('GLYPH_ONCLICK', $attr['onclick']);
2413 $htpl->parseCurrentBlock();
2414 }
2415 $renderer = $this->ui->renderer();
2416 $html = $renderer->render($attr['glyph']);
2417 $htpl->setCurrentBlock('prop_glyph');
2418 $htpl->setVariable('GLYPH', $html);
2419 $htpl->parseCurrentBlock();
2420 } else {
2421 if ($attr['onclick']) {
2422 $htpl->setCurrentBlock('onclick');
2423 $htpl->setVariable('PROP_ONCLICK', $attr['onclick']);
2424 $htpl->parseCurrentBlock();
2425 }
2426
2427 if ($attr['status_text']) {
2428 $htpl->setCurrentBlock('status');
2429 $htpl->setVariable('PROP_TXT', $attr['status_text']);
2430 $htpl->parseCurrentBlock();
2431 }
2432
2433
2434 $htpl->setCurrentBlock('prop');
2435 if ($attr['href'] || $attr['onclick']) {
2436 $htpl->setVariable('TAG', 'a');
2437 } else {
2438 $htpl->setVariable('TAG', 'span');
2439 }
2440 $htpl->setVariable('PROP_ID', $id);
2441 $htpl->setVariable('IMG_SRC', $attr['img']);
2442 if ($attr['href'] != '') {
2443 $htpl->setVariable('PROP_HREF', ' href="' . $attr['href'] . '" ');
2444 }
2445
2446 if ($attr['tooltip']) {
2447 $htpl->setVariable('IMG_ADDITIONAL', "alt=\"{$attr['tooltip']}\" title=\"{$attr['tooltip']}\"");
2448 }
2449 $htpl->parseCurrentBlock();
2450 }
2451 } else {
2452 $chunks[] = $attr;
2453 }
2454 }
2455
2456 if (sizeof($chunks)) {
2457 $htpl->setVariable(
2458 'PROP_CHUNKS',
2459 implode('&nbsp;&nbsp;&nbsp;', $chunks) . '&nbsp;&nbsp;&nbsp;'
2460 );
2461 }
2462 }
2463
2464 $this->setTitle(ilObject::_lookupTitle($this->obj_id));
2465 $dropdown_label = '<span class="hidden-xs">' .
2466 $this->lng->txt('actions') .
2467 '</span>';
2468 $dropdown = $this->getCommandsDropdown($dropdown_label, true);
2469 $htpl->setVariable(
2470 'ACTION_DROP_DOWN',
2471 $this->ui->renderer()->render($dropdown)
2472 );
2473
2474 if ($this->cust_modals !== []) {
2475 $htpl->setVariable('TRIGGERED_MODALS', $this->ui->renderer()->render($this->cust_modals));
2476 }
2477
2478 return $htpl->get();
2479 }
2480
2481
2486 public function appendRepositoryFrameParameter(string $link): string
2487 {
2488 // we should get rid of this nonsense with 4.4 (alex)
2489 $base_class = $this->request_wrapper->retrieve('baseClass', $this->refinery->kindlyTo()->string());
2490 if (
2491 (strtolower($base_class) != 'ilrepositorygui') &&
2492 is_int(strpos($link, 'baseClass=ilRepositoryGUI'))
2493 ) {
2494 if ($this->type != 'frm') {
2495 $link = ilUtil::appendUrlParameterString($link, 'rep_frame=1');
2496 }
2497 }
2498
2499 return $link;
2500 }
2501
2502 protected function modifyTitleLink(string $default_link): string
2503 {
2504 if ($this->default_command_params) {
2505 $params = [];
2506 foreach ($this->default_command_params as $name => $value) {
2507 $params[] = $name . '=' . $value;
2508 }
2509 $params = implode('&', $params);
2510
2511
2512 // #12370
2513 if (!stristr($default_link, '?')) {
2514 $default_link = ($default_link . '?' . $params);
2515 } else {
2516 $default_link = ($default_link . '&' . $params);
2517 }
2518 }
2519 return $default_link;
2520 }
2521
2525 public function modifySAHSlaunch(string $link, string $target): array
2526 {
2527 if (strstr($link, ilSAHSPresentationGUI::class) === false) {
2528 return [$link, $target];
2529 }
2530
2531 $sahs_obj = new ilObjSAHSLearningModule($this->ref_id);
2532 $om = $sahs_obj->getOpenMode();
2533 $width = $sahs_obj->getWidth();
2534 $height = $sahs_obj->getHeight();
2535 if (($om == 5 || $om == 1) && $width > 0 && $height > 0) {
2536 $om++;
2537 }
2538 if ($om !== 0 && !$this->http->agent()->isMobile()) {
2539 $this->default_command['frame'] = '';
2540 $link =
2541 'javascript:void(0); onclick=startSAHS(\'' .
2542 $link .
2543 '\',\'' .
2544 $target .
2545 '\',' .
2546 $om .
2547 ',' .
2548 $width .
2549 ',' .
2550 $height .
2551 ');'
2552 ;
2553 } else {
2554 $target = "ilContObj" . $this->ref_id;
2555 }
2556 return [$link, $target];
2557 }
2558
2559 public function insertPath(): void
2560 {
2561 if ($this->getPathStatus() != false) {
2562 if (!$this->path_gui instanceof \ilPathGUI) {
2563 $path_gui = new \ilPathGUI();
2564 } else {
2565 $path_gui = $this->path_gui;
2566 }
2567
2568 $path_gui->enableTextOnly(!$this->path_linked);
2569 $path_gui->setUseImages(false);
2570
2571 $start_node = ROOT_FOLDER_ID;
2572 if ($this->path_start_node) {
2573 $start_node = $this->path_start_node;
2574 }
2575
2576 $this->tpl->setCurrentBlock('path_item');
2577 $this->tpl->setVariable('PATH_ITEM', $path_gui->getPath($start_node, $this->ref_id));
2578 $this->tpl->parseCurrentBlock();
2579
2580 $this->tpl->setCurrentBlock('path');
2581 $this->tpl->setVariable('TXT_LOCATION', $this->lng->txt('locator'));
2582 $this->tpl->parseCurrentBlock();
2583 }
2584 }
2585
2586 public function insertProgressInfo(): void
2587 {
2588 }
2589
2590 public function insertIconsAndCheckboxes(): void
2591 {
2592 $cnt = 0;
2593 if ($this->getCheckboxStatus()) {
2594 $this->tpl->setCurrentBlock('check');
2595 $this->tpl->setVariable('VAL_ID', $this->getCommandId());
2596 $this->tpl->setVariable('CHECK_TITLE', $this->lng->txt('select') . ' ' . $this->getTitle());
2597 $this->tpl->parseCurrentBlock();
2598 $cnt += 1;
2599 } elseif ($this->getDownloadCheckboxState() != self::DOWNLOAD_CHECKBOX_NONE) {
2600 $this->tpl->setCurrentBlock('check_download');
2601 $this->tpl->setVariable('CHECK_DOWNLOAD_TITLE', $this->lng->txt('download') . ' ' . $this->getTitle());
2602 if ($this->getDownloadCheckboxState() == self::DOWNLOAD_CHECKBOX_ENABLED) {
2603 $this->tpl->setVariable('VAL_ID', $this->getCommandId());
2604 } else {
2605 $this->tpl->setVariable('VAL_VISIBILITY', 'visibility: hidden;" disabled="disabled');
2606 }
2607 $this->tpl->parseCurrentBlock();
2608 $cnt += 1;
2609 } elseif ($this->getExpandStatus()) {
2610 $this->tpl->setCurrentBlock('expand');
2611
2612 if ($this->isExpanded()) {
2613 $this->ctrl->setParameter($this->container_obj, 'expand', -1 * $this->obj_id);
2614 // 'view' added, see #19922
2615 $this->tpl->setVariable('EXP_HREF', $this->ctrl->getLinkTarget($this->container_obj, 'view', $this->getUniqueItemId(true)));
2616 $this->ctrl->clearParameters($this->container_obj);
2617 $this->tpl->setVariable('EXP_IMG', ilUtil::getImagePath('nav/tree_exp.svg'));
2618 $this->tpl->setVariable('EXP_ALT', $this->lng->txt('collapse'));
2619 } else {
2620 $this->ctrl->setParameter($this->container_obj, 'expand', $this->obj_id);
2621 // 'view' added, see #19922
2622 $this->tpl->setVariable('EXP_HREF', $this->ctrl->getLinkTarget($this->container_obj, 'view', $this->getUniqueItemId(true)));
2623 $this->ctrl->clearParameters($this->container_obj);
2624 $this->tpl->setVariable('EXP_IMG', ilUtil::getImagePath('nav/tree_col.svg'));
2625 $this->tpl->setVariable('EXP_ALT', $this->lng->txt('expand'));
2626 }
2627
2628 $this->tpl->parseCurrentBlock();
2629 $cnt += 1;
2630 }
2631
2632 if ($this->getIconStatus()) {
2633 if ($cnt == 1) {
2634 $this->tpl->touchBlock('i_1');
2635 }
2636
2637 $this->tpl->setCurrentBlock('icon');
2638 $this->tpl->setVariable('ALT_ICON', $this->buildTranslatedType());
2639
2640 $this->tpl->setVariable(
2641 'SRC_ICON',
2642 $this->getTypeIcon()
2643 );
2644 $this->tpl->parseCurrentBlock();
2645 $cnt += 1;
2646 }
2647
2648 $this->tpl->touchBlock('d_' . $cnt);
2649 }
2650
2654 public function getTypeIcon(): string
2655 {
2656 return ilObject::getIconForReference(
2657 $this->ref_id,
2658 $this->obj_id,
2659 'small',
2660 $this->getIconImageType()
2661 );
2662 }
2663
2664 public function insertSubItems(): void
2665 {
2666 foreach ($this->sub_item_html as $sub_html) {
2667 $this->tpl->setCurrentBlock('subitem');
2668 $this->tpl->setVariable('SUBITEM', $sub_html);
2669 $this->tpl->parseCurrentBlock();
2670 }
2671 }
2672
2673 public function insertPositionField(): void
2674 {
2675 if ($this->position_enabled) {
2676 $this->tpl->setCurrentBlock('position');
2677 $this->tpl->setVariable('POS_ID', $this->position_field_index);
2678 $this->tpl->setVariable('POS_VAL', $this->position_value);
2679 $this->tpl->parseCurrentBlock();
2680 }
2681 }
2682
2687 public function adminCommandsIncluded(): bool
2688 {
2689 return $this->adm_commands_included;
2690 }
2691
2695 public function getListItemHTML(
2696 int $ref_id,
2697 int $obj_id,
2698 string $title,
2699 string $description
2700 ): string {
2701 // this variable stores whether any admin commands
2702 // are included in the output
2703 $this->adm_commands_included = false;
2704
2705 // only for performance exploration
2706 $type = ilObject::_lookupType($obj_id);
2707
2708 $this->initItem($ref_id, $obj_id, $type, $title, $description);
2709
2710 if ($this->rating_enabled) {
2711 if (ilRating::hasRatingInListGUI($this->obj_id, $this->type)) {
2712 $may_rate = $this->checkCommandAccess('read', '', $this->ref_id, $this->type);
2713 $rating = new ilRatingGUI();
2714 $rating->setObject($this->obj_id, $this->type);
2715 $this->addCustomProperty(
2716 '',
2717 $rating->getListGUIProperty($this->ref_id, $may_rate, $this->ajax_hash, $this->parent_ref_id),
2718 false,
2719 true
2720 );
2721 }
2722 }
2723
2724 // visible check
2725 if (!$this->checkCommandAccess('visible', '', $ref_id, '', $obj_id)) {
2726 $this->resetCustomData();
2727 return '';
2728 }
2729
2730 // BEGIN WEBDAV
2731 if ($type == 'file' and ilObjFileAccess::_isFileHidden($title)) {
2732 $this->resetCustomData();
2733 return '';
2734 }
2735 // END WEBDAV
2736
2737 $this->tpl = new ilTemplate(
2738 static::$tpl_file_name,
2739 true,
2740 true,
2741 static::$tpl_component,
2742 'DEFAULT',
2743 false,
2744 true
2745 );
2746
2747 if ($this->getCommandsStatus()) {
2748 if (!$this->getSeparateCommands()) {
2749 $dropdown = $this->getCommandsDropdown($title);
2750 $this->tpl->setVariable(
2751 'COMMAND_SELECTION_LIST',
2752 $this->ui->renderer()->render($dropdown)
2753 );
2754 }
2755 }
2756
2757 if ($this->getProgressInfoStatus()) {
2758 $this->insertProgressInfo();
2759 }
2760
2761 // insert title and describtion
2762 $this->insertTitle();
2763 if (!$this->isMode(self::IL_LIST_AS_TRIGGER)) {
2764 if ($this->getDescriptionStatus()) {
2765 $this->insertDescription();
2766 }
2767 }
2768
2769 if ($this->getSearchFragmentStatus()) {
2770 $this->insertSearchFragment();
2771 }
2772
2773 // properties
2774 if ($this->getPropertiesStatus()) {
2775 $this->insertProperties();
2776 }
2777
2778 // notice properties
2779 if ($this->getNoticePropertiesStatus()) {
2780 $this->insertNoticeProperties();
2781 }
2782
2783 // preconditions
2784 if ($this->getPreconditionsStatus()) {
2785 $this->insertPreconditions();
2786 }
2787
2788 // path
2789 $this->insertPath();
2790
2791 if ($this->getItemDetailLinkStatus()) {
2792 $this->insertItemDetailLinks();
2793 }
2794
2795 // icons and checkboxes
2796 $this->insertIconsAndCheckboxes();
2797
2798 // input field for position
2799 $this->insertPositionField();
2800
2801 // subitems
2802 $this->insertSubItems();
2803
2804 $this->resetCustomData();
2805
2806 $this->tpl->setVariable('DIV_CLASS', 'ilContainerListItemOuter');
2807 $this->tpl->setVariable(
2808 'DIV_ID',
2809 'data-list-item-id="' . $this->getUniqueItemId(true) . '" id = "' . $this->getUniqueItemId(true) . '"'
2810 );
2811 $this->tpl->setVariable('ADDITIONAL', $this->getAdditionalInformation());
2812
2813 if (is_object($this->getContainerObject())) {
2814 // #11554 - make sure that internal ids are reset
2815 $this->ctrl->setParameter($this->getContainerObject(), 'item_ref_id', '');
2816 }
2817
2818 // if file upload is enabled the content is wrapped by a UI dropzone.
2819 $content = $this->tpl->get();
2820 $file_upload_dropzone = new ilObjFileUploadDropzone($this->ref_id, $content);
2821 if ($this->context === self::CONTEXT_REPOSITORY
2822 && ($this->requested_cmd === "view" || $this->requested_cmd === "" || $this->requested_cmd === "render")
2823 && $file_upload_dropzone->isUploadAllowed($this->type)
2824 && !(new ModeSessionRepository())->isAdminMode()
2825 ) {
2826 return $file_upload_dropzone->getDropzoneHtml();
2827 }
2828
2829 return $content;
2830 }
2831
2835 protected function resetCustomData(): void
2836 {
2837 // #15747
2838 $this->cust_prop = [];
2839 $this->cust_commands = [];
2840 $this->cust_modals = [];
2841 $this->sub_item_html = [];
2842 $this->position_enabled = false;
2843 }
2844
2848 public function setParentRefId(int $ref_id): void
2849 {
2850 $this->parent_ref_id = $ref_id;
2851 }
2852
2859 public function getUniqueItemId(bool $as_div = false): string
2860 {
2861 // use correct id for references
2862 $id_ref = $this->ref_id;
2863 if ($this->reference_ref_id > 0) {
2864 $id_ref = $this->reference_ref_id;
2865 }
2866
2867 // add unique identifier for preconditions (objects can appear twice in same container)
2868 if ($this->condition_depth) {
2869 $id_ref .= '_pc' . $this->condition_depth;
2870 }
2871
2872 // unique
2873 $id_ref .= '_pref_' . $this->parent_ref_id;
2874
2875 if (!$as_div) {
2876 return $id_ref;
2877 } else {
2878 // action menu [yellow] toggle
2879 return 'lg_div_' . $id_ref;
2880 }
2881 }
2882
2886 public function getCommandsHTML(string $title = ''): string
2887 {
2888 return $this->ui->renderer()->render($this->getCommandsDropdown($title, false));
2889 }
2890
2891 private function getCommandsDropdown(string $title, bool $for_header = false): StandardDropdown
2892 {
2893 $this->populateCommands($for_header);
2894 return $this->ui->factory()
2895 ->dropdown()
2896 ->standard($this->current_actions)
2897 ->withAriaLabel(sprintf(
2898 $this->lng->txt('actions_for'),
2899 htmlspecialchars(addslashes($title))
2900 ));
2901 }
2902
2906 public function isSideBlock(): bool
2907 {
2908 return false;
2909 }
2910
2911 public function setBoldTitle(bool $bold_title): void
2912 {
2913 $this->bold_title = $bold_title;
2914 }
2915
2916 public function isTitleBold(): bool
2917 {
2918 return $this->bold_title;
2919 }
2920
2921 public static function preloadCommonProperties(array $obj_ids, int $context): void
2922 {
2923 global $DIC;
2924 $lng = $DIC->language();
2925 $ilSetting = $DIC->settings();
2926 $ilUser = $DIC->user();
2927 $notes_manager = $DIC->notes()->internal()->domain()->notes();
2928
2929 if ($context == self::CONTEXT_REPOSITORY) {
2930 $active_notes = !$ilSetting->get('disable_notes');
2931 $active_comments = !$ilSetting->get('disable_comments');
2932
2933 if ($active_comments) {
2934 // needed for action
2935 self::$comments_activation = $DIC->notes()
2936 ->internal()
2937 ->domain()
2938 ->notes()->commentsActiveMultiple($obj_ids);
2939 }
2940
2941 // properties are optional
2942 if ($ilSetting->get('comments_tagging_in_lists')) {
2943 if ($active_notes || $active_comments) {
2944 // @todo: should be refactored, see comment in notes db repo
2945 self::$cnt_notes = $notes_manager->countNotesAndCommentsMultipleObjects(
2946 $obj_ids,
2947 true
2948 );
2949
2950 $lng->loadLanguageModule('notes');
2951 }
2952
2953 $tags_set = new ilSetting('tags');
2954 if ($tags_set->get('enable')) {
2955 $all_users = (bool) $tags_set->get('enable_all_users');
2956
2957 if (!$ilSetting->get('comments_tagging_in_lists_tags')) {
2958 self::$cnt_tags = ilTagging::_countTags($obj_ids, $all_users);
2959 } else {
2960 $tag_user_id = null;
2961 if (!$all_users) {
2962 $tag_user_id = $ilUser->getId();
2963 }
2964 self::$tags = ilTagging::_getListTagsForObjects($obj_ids, $tag_user_id);
2965 }
2966
2967 $lng->loadLanguageModule('tagging');
2968 }
2969 }
2970
2971 $lng->loadLanguageModule('rating');
2972 }
2973
2974 self::$preload_done = true;
2975 }
2976
2980 protected function isCommentsActivated(
2981 string $type,
2982 int $ref_id,
2983 int $obj_id,
2984 bool $header_actions,
2985 bool $check_write_access = true
2986 ): bool {
2987 if ($this->comments_enabled) {
2988 if (!$this->comments_settings_enabled) {
2989 return true;
2990 }
2991 if ($check_write_access && $this->checkCommandAccess('write', '', $ref_id, $type)) {
2992 return true;
2993 }
2994 // fallback to single object check if no preloaded data
2995 // only the repository does preloadCommonProperties() yet
2996 if (!$header_actions && self::$preload_done) {
2997 if (isset(self::$comments_activation[$obj_id]) &&
2998 self::$comments_activation[$obj_id]) {
2999 return true;
3000 }
3001 } elseif ($this->notes_service->domain()->commentsActive($obj_id)) {
3002 return true;
3003 }
3004 }
3005 return false;
3006 }
3007
3011 public function enableTimings(bool $status): void
3012 {
3013 $this->timings_enabled = $status;
3014 }
3015
3019 public function getAsListItem(
3020 int $ref_id,
3021 int $obj_id,
3022 string $type,
3023 string $title,
3024 string $description
3025 ): ?Item {
3026 $ui = $this->ui;
3027
3028 // even b tag produced bugs, see #32304
3029 $description = $this->refinery->encode()->htmlSpecialCharsAsEntities()->transform(
3030 $description
3031 );
3032
3033 $this->initItem(
3034 $ref_id,
3035 $obj_id,
3036 $type,
3037 $title,
3038 $description
3039 );
3040
3041 $this->enableCommands(true);
3042
3043 // actions
3044 $this->populateCommands(false);
3045
3046 $dropdown = $this->getCommandsDropdown($title);
3047 $def_command = $this->getDefaultCommand();
3048
3049 if ($def_command['link'] ?? false) {
3050 list($def_command['link'], $def_command['frame']) =
3051 $this->modifySAHSlaunch($def_command['link'], $def_command['frame']);
3052 $new_viewport = !in_array($def_command['frame'], ['', '_top', '_self', '_parent'], true);
3053 $link = $this->ui->factory()
3054 ->link()
3055 ->standard($this->getTitle(), $def_command['link'])
3056 ->withOpenInNewViewport($new_viewport);
3057 $list_item = $ui->factory()->item()->standard($link);
3058 } else {
3059 $list_item = $ui->factory()->item()->standard($this->getTitle());
3060 }
3061
3062 if ($description != '') {
3063 $list_item = $list_item->withDescription($description);
3064 }
3065 $list_item = $list_item->withActions($dropdown)->withLeadIcon(
3066 $this->ui->factory()->symbol()->icon()->custom(
3067 $this->getTypeIcon(),
3068 $this->buildTranslatedType(),
3069 'medium'
3070 )
3071 );
3072
3073
3074 $l = [];
3075 $this->enableComments(true);
3076 $this->enableNotes(true);
3077 $this->enableTags(true);
3078 $this->enableRating(true);
3079
3080 foreach ($this->determineProperties() as $p) {
3081 //if ($p['property'] !== $this->lng->txt('learning_progress')) {
3082 $l[(string) $p['property']] = (string) $p['value'];
3083 //}
3084 }
3085 if (count($l) > 0) {
3086 $list_item = $list_item->withProperties($l);
3087 }
3088
3089 return $list_item;
3090 }
3091
3095 public function getAsCard(
3096 int $ref_id,
3097 int $obj_id,
3098 string $type,
3099 string $title,
3100 string $description
3101 ): ?RepositoryObject {
3102 $ui = $this->ui;
3103
3104 $title = $this->refinery->encode()->htmlSpecialCharsAsEntities()->transform($title);
3105 // even b tag produced bugs, see #32304
3106 $description = $this->refinery->encode()->htmlSpecialCharsAsEntities()->transform(
3107 $description
3108 );
3109
3110 $this->initItem(
3111 $ref_id,
3112 $obj_id,
3113 $type,
3114 $title,
3115 $description
3116 );
3117
3118 $user = $this->user;
3119 $access = $this->access;
3120
3121 $this->enableCommands(true);
3122
3123 $sections = [];
3124 if ($description !== '') {
3125 $sections[] = $ui->factory()->legacy()->content('<div class="il-multi-line-cap-3">' . $description . '</div>');
3126 }
3127
3128 $this->populateCommands(false);
3129
3130 $def_command = $this->getDefaultCommand();
3131
3132 $dropdown = $this->getCommandsDropdown($title);
3133
3134 // workaround for #26205
3135 // we should get rid of _top links completely and gifure our how
3136 // to manage scorm links better
3137 $def_cmd_frame = ($def_command['frame'] ?? '');
3138 if ($def_cmd_frame === '_top') {
3139 $def_cmd_frame = '';
3140 }
3141 $def_cmd_link = ($def_command['link'] ?? '');
3142
3143 // workaround for scorm
3144 list($modified_link, $def_cmd_frame) =
3145 $this->modifySAHSlaunch($def_cmd_link, $def_cmd_frame);
3146
3147 $image = $this->getTileImage();
3148
3149 if ($def_cmd_link != '') { // #24256
3150 if ($def_cmd_frame !== '' && ($modified_link === $def_cmd_link)) {
3151 $signal = (new SignalGenerator())->create();
3152 $this->main_tpl->addOnLoadCode(
3153 "$(document).on('{$signal->getId()}', function(event, signalData) {"
3154 . ' window.open("' . str_replace(
3155 '&amp;',
3156 '&',
3157 $def_cmd_link
3158 ) . '", "' . $def_cmd_frame . '");'
3159 . '});'
3160 );
3161
3162 $image = $image->withAction($signal);
3163
3164 $button =
3165 $ui->factory()->button()->shy($title, '')->appendOnClick($signal);
3166 $title = $ui->renderer()->render($button);
3167 } else {
3168 $image = $image->withAction($modified_link);
3169 }
3170 }
3171
3172 if ($type == 'sess') {
3173 if ($title != '') {
3174 $title = ': ' . $title;
3175 }
3176 $app_info = ilSessionAppointment::_lookupAppointment($obj_id);
3177 $title = ilSessionAppointment::_appointmentToString(
3178 $app_info['start'],
3179 $app_info['end'],
3180 (bool) $app_info['fullday']
3181 ) . $title;
3182 }
3183
3184 $icon = $this->ui->factory()->symbol()->icon()->custom(
3185 $this->getTypeIcon(),
3186 $this->buildTranslatedType(),
3187 'medium'
3188 );
3189
3190 // card title action
3191 $card_title_action = '';
3192 if ($def_cmd_link != '' && ($def_cmd_frame == '' || $modified_link != $def_cmd_link)) { // #24256
3193 $card_title_action = $modified_link;
3194 } elseif ($def_cmd_link == '' &&
3195 $this->getInfoScreenStatus() &&
3196 $access->checkAccessOfUser(
3197 $user->getId(),
3198 'visible',
3199 '',
3200 $ref_id
3201 )) {
3202 $card_title_action = ilLink::_getLink($ref_id);
3203 if ($image->getAction() == '') {
3204 $image = $image->withAction($card_title_action);
3205 }
3206 }
3207
3208 $card = $ui->factory()->card()->repositoryObject(
3209 $title . '<span data-list-item-id="' . $this->getUniqueItemId(true) . '"></span>',
3210 $image
3211 )->withObjectIcon(
3212 $icon
3213 )->withActions(
3214 $dropdown
3215 );
3216
3217 if ($card_title_action != '') {
3218 $card = $card->withTitleAction($card_title_action);
3219 }
3220
3221 $l = [];
3222 foreach ($this->determineProperties() as $p) {
3223 if (isset($p['alert']) && $p['alert'] == true
3224 && isset($p['property']) && $p['property'] !== $this->lng->txt('learning_progress')) {
3225 $l[(string) $p['property']] = (string) $p['value'];
3226 }
3227 }
3228 if (count($l) > 0) {
3229 $prop_list = $ui->factory()->listing()->descriptive($l);
3230 $sections[] = $prop_list;
3231 }
3232 if (count($sections) > 0) {
3233 $card = $card->withSections($sections);
3234 }
3235
3236 $lp = ilLPStatus::getListGUIStatus($obj_id, false);
3237 if (is_array($lp) && array_key_exists('status', $lp)) {
3238 $percentage = (int) ilLPStatus::_lookupPercentage($obj_id, $this->user->getId());
3239 if ($lp['status'] == ilLPStatus::LP_STATUS_COMPLETED_NUM) {
3240 $percentage = 100;
3241 }
3242
3243 $card = $card->withProgress(
3244 $ui->factory()
3245 ->chart()
3246 ->progressMeter()
3247 ->mini(100, $percentage)
3248 );
3249 }
3250
3251 return $card;
3252 }
3253
3254 public function checkInfoPageOnAsynchronousRendering(): bool
3255 {
3256 return false;
3257 }
3258
3259 private function getTileImage(): Image
3260 {
3261 return $this->object_properties->getPropertyTileImage()
3262 ->getTileImage()->getImage($this->ui->factory()->image());
3263 }
3264
3268 public function insertLPCommand(): void
3269 {
3270 if ($this->std_cmd_only || !$this->lp_cmd_enabled) {
3271 return;
3272 }
3273 $relevant = ilLPStatus::hasListGUIStatus($this->obj_id);
3274 if ($relevant) {
3275 $cmd_link = $this->getCommandLink('learningProgress');
3276 $this->insertCommand(
3277 $cmd_link,
3278 $this->lng->txt('learning_progress')
3279 );
3280 }
3281 }
3282
3286 private function insertLPSettingsCommand(): void
3287 {
3288 if (!$this->lp_settings_cmd_enabled
3289 || !ilObjUserTracking::_enabledLearningProgress()
3290 || ilObjectLP::getTypeClass($this->type) === ''
3291 || ! $this->checkCommandAccess('edit_learning_progress', '', $this->ref_id, $this->type)
3292 ) {
3293 return;
3294 }
3295
3296 $cmd_link = '';
3297 $this->ctrl->setParameterByClass(ilLearningProgressGUI::class, 'ref_id', $this->ref_id);
3298 switch ($this->type) {
3299 case 'sahs':
3300 switch (ilObjSAHSLearningModule::_lookupSubType($this->obj_id)) {
3301 case 'scorm2004':
3302 $scorm_class = ilObjSCORM2004LearningModuleGUI::class;
3303 break;
3304 case 'scorm':
3305 $scorm_class = ilObjSCORMLearningModuleGUI::class;
3306 break;
3307 default:
3308 $scorm_class = '';
3309 break;
3310 }
3311
3312 $cmd_link = $this->ctrl->getLinkTargetByClass([
3313 ilSAHSEditGUI::class,
3314 $scorm_class,
3315 ilLearningProgressGUI::class,
3316 ilLPListOfSettingsGUI::class
3317 ]);
3318 break;
3319
3320 case 'lm':
3321 $cmd_link = $this->ctrl->getLinkTargetByClass([
3322 ilLMEditorGUI::class,
3323 ilObjLearningModuleGUI::class,
3324 ilLearningProgressGUI::class,
3325 ilLPListOfSettingsGUI::class
3326 ]);
3327 break;
3328
3329 case 'lso':
3330 $cmd_link = $this->ctrl->getLinkTargetByClass([
3331 ilObjLearningSequenceGUI::class,
3332 ilLearningProgressGUI::class,
3333 ilLPListOfSettingsGUI::class
3334 ]);
3335 break;
3336
3337 case 'copa':
3338 case 'iass':
3339 case 'tst':
3340 case 'htlm':
3341 case 'exc':
3342 case 'svy':
3343 case 'mcst':
3344 case 'file':
3345 case 'crs':
3346 $gui_class = 'ilObj' . $this->obj_definition->getClassName($this->type) . 'GUI';
3347 $cmd_link = $this->ctrl->getLinkTargetByClass([
3348 ilRepositoryGUI::class,
3349 $gui_class,
3350 ilLearningProgressGUI::class,
3351 ilLPListOfSettingsGUI::class
3352 ]);
3353 break;
3354
3355 case 'prgr':
3356 case 'prg':
3357 case 'lso':
3358 break;
3359 default:
3360 break;
3361 }
3362
3363 $this->ctrl->setParameterByClass('ilrepositorygui', 'ref_id', $this->requested_ref_id);
3364 if ($cmd_link !== '') {
3365 $this->insertCommand(
3366 $cmd_link,
3367 $this->lng->txt('listaction_learning_progress_settings')
3368 );
3369 }
3370 }
3371
3372 private function buildTranslatedType(): string
3373 {
3374 if ($this->obj_definition->isPlugin($this->getIconImageType())) {
3375 return ilObjectPlugin::lookupTxtById($this->getIconImageType(), 'obj_' . $this->getIconImageType());
3376 }
3377
3378 return $this->lng->txt('obj_' . $this->getIconImageType());
3379 }
3380}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$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.)
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
$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
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:57
$context
Definition: webdav.php:31
$text
Definition: xapiexit.php:21