ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
TreeSelectNodeRetrieval.php
Go to the documentation of this file.
1<?php
2
18declare(strict_types=1);
19
21
24
28readonly class TreeSelectNodeRetrieval implements Field\Node\NodeRetrieval
29{
31 protected const string NODE_SORT_BY = 'title';
32
34 protected array $node_object_type_list;
35
40 public function __construct(
41 protected \ILIAS\Language\Language $language,
42 protected \ILIAS\Data\Factory $data_factory,
43 protected \ILIAS\UI\URLBuilderToken $async_node_id_parameter,
44 protected \ILIAS\UI\URLBuilder $async_node_url_builder,
45 protected \ilAccess $access,
46 protected \ilTree $tree,
47 protected array $branch_object_type_list,
48 protected array $leaf_object_type_list,
49 protected int $max_branch_node_depth,
50 protected int $root_node_id,
51 ) {
52 $this->node_object_type_list = array_merge($this->branch_object_type_list, $this->leaf_object_type_list);
53 }
54
55 public function getNodes(
56 Field\Node\Factory $node_factory,
57 Icon\Factory $icon_factory,
58 array $sync_node_id_whitelist = [],
59 ?string $parent_id = null,
60 ): \Generator {
61 yield from $this->createNodes(
62 $node_factory,
63 $icon_factory,
64 $sync_node_id_whitelist,
65 (int) ($parent_id ?? $this->root_node_id),
66 );
67 }
68
69 public function getNodesAsLeaf(
70 Field\Node\Factory $node_factory,
71 Icon\Factory $icon_factory,
72 array $node_ids
73 ): \Generator {
74 foreach ($node_ids as $node_id) {
75 try {
76 $tree_node_data = $this->tree->getNodeData((int) $node_id);
77 [$object_path, $object_ref_id, $object_type, $object_title] = $this->extractObjectDataOrAbort($tree_node_data);
78 yield $node_factory->leaf(
79 $object_path,
80 $object_title,
81 $this->getObjectIcon($icon_factory, $object_ref_id, $object_type),
82 );
83 } catch (\LogicException) {
84 yield $node_factory->leaf([$node_id], $this->language->txt('unknown'));
85 }
86 }
87 }
88
90 protected function createNodes(
91 Field\Node\Factory $node_factory,
92 Icon\Factory $icon_factory,
93 array $max_depth_node_id_whitelist,
94 int $parent_object_id,
95 int $depth = 0,
96 ): array {
97 $children = $this->tree->getChildsByTypeFilter(
98 $parent_object_id,
99 $this->node_object_type_list,
100 self::NODE_SORT_BY,
101 );
102
103 $nodes = [];
104 foreach ($children as $child) {
105 [$object_path, $object_ref_id, $object_type, $object_title] = $this->extractObjectDataOrAbort($child);
106
107 $is_object_visible = $this->isObjectVisible($object_ref_id, $object_type);
108 $is_object_container = $this->isObjectContainer($object_type);
109
110 // append visible children of an invisible branch node to the current node.
111 if (!$is_object_visible && $is_object_container) {
112 $nodes = [...$nodes, ...$this->createNodes(
113 $node_factory,
114 $icon_factory,
115 $max_depth_node_id_whitelist,
116 $object_ref_id,
117 $depth + 1
118 )];
119 continue;
120 }
121
122 $object_icon = $this->getObjectIcon($icon_factory, $object_ref_id, $object_type);
123
124 if ($is_object_visible && $is_object_container) {
125 if ($depth < $this->max_branch_node_depth || in_array($object_ref_id, $max_depth_node_id_whitelist, true)) {
126 $nodes[] = $node_factory->branch(
127 $object_path,
128 $object_title,
129 $object_icon,
130 ...$this->createNodes(
131 $node_factory,
132 $icon_factory,
133 $max_depth_node_id_whitelist,
134 $object_ref_id,
135 $depth + 1
136 ),
137 );
138 } else {
139 $nodes[] = $node_factory->async(
140 $this->getAsyncRenderUrl($object_ref_id),
141 $object_path,
142 $object_title,
143 $object_icon,
144 );
145 }
146 continue;
147 }
148 if ($is_object_visible && !$is_object_container) {
149 $nodes[] = $node_factory->leaf($object_path, $object_title, $object_icon);
150 }
151 }
152 return $nodes;
153 }
154
156 protected function extractObjectDataOrAbort(array $tree_node_data): array
157 {
158 $object_path = array_map('intval', explode('.', (string) ($tree_node_data['path'] ?? '')));
159 $object_ref_id = $tree_node_data['ref_id'] ?? $tree_node_data['child'] ?? null;
160 $object_type = $tree_node_data['type'] ?? null;
161 $object_title = $tree_node_data['title'] ?? null;
162 if (empty($object_path) || null === $object_ref_id || null === $object_type || null === $object_title) {
163 throw new \LogicException("Object data is invalid");
164 }
165 return [$object_path, $object_ref_id, $object_type, $object_title];
166 }
167
168 protected function getAsyncRenderUrl(int $object_ref_id): \ILIAS\Data\URI
169 {
170 $async_node_url_builder = $this->async_node_url_builder->withParameter(
171 $this->async_node_id_parameter,
172 (string) $object_ref_id
173 );
174 return $this->data_factory->uri((string) $async_node_url_builder->buildURI());
175 }
176
177 protected function getObjectIcon(Icon\Factory $icon_factory, int $object_ref_id, string $object_type): Icon\Icon
178 {
179 // ensures plugin object types are properly handled as well.
180 $icon_path = \ilObject::_getIcon(\ilObject::_lookupObjectId($object_ref_id), Icon\Icon::SMALL);
181
182 if ($this->tree->getRootId() >= $object_ref_id) {
183 $alt_text = $this->language->txt('repository');
184 } else {
185 $alt_text = $this->language->txt($object_type);
186 }
187 return $icon_factory->custom($icon_path, $alt_text, Icon\Icon::SMALL);
188 }
189
190 protected function isObjectVisible(int $object_ref_id, string $object_type = ''): bool
191 {
192 return $this->access->checkAccess('visible', '', $object_ref_id, $object_type);
193 }
194
195 protected function isObjectContainer(string $object_type): bool
196 {
197 return in_array($object_type, $this->branch_object_type_list, true);
198 }
199}
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
withParameter(string $key, $value)
Get URI with modified parameters.
Definition: URI.php:387
Definition: UI.php:24
Class ilAccessHandler Checks access for ILIAS objects.
static _lookupObjectId(int $ref_id)
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
This is what a factory for input fields looks like.
Definition: Factory.php:31
This describes how an icon could be modified during construction of UI.
Definition: Icon.php:29
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: Checkbox.php:21
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.