ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilTreeExplorerGUI.php
Go to the documentation of this file.
1<?php
2
20
29{
30 protected ilLanguage $lng;
31 protected \Psr\Http\Message\ServerRequestInterface $httpRequest;
32 protected ?ilTree $tree = null;
33 protected string $tree_label = "";
34 protected string $order_field = "";
35 protected bool $order_field_numeric = false;
36 protected array $type_white_list = array();
37 protected array $type_black_list = array();
38 protected array $childs = array(); // preloaded childs
39 protected bool $preloaded = false;
40 protected bool $preload_childs = false;
41 protected ?array $root_node_data = null;
42 protected array $all_childs = array();
43 protected $root_id = 0;
44 protected \ILIAS\DI\UIServices $ui;
45
46 public function __construct(
47 string $a_expl_id,
48 $a_parent_obj,
49 string $a_parent_cmd,
50 ilTree $a_tree,
51 string $a_node_parameter_name = "node_id"
52 ) {
53 global $DIC;
54
55 $this->httpRequest = $DIC->http()->request();
56 $this->ui = $DIC->ui();
57 $this->lng = $DIC->language();
58 parent::__construct($a_expl_id, $a_parent_obj, $a_parent_cmd, $a_node_parameter_name);
59 $this->tree = $a_tree;
60 }
61
62 public function getTree(): ilTree
63 {
64 return $this->tree;
65 }
66
67 public function setOrderField(
68 string $a_val,
69 bool $a_numeric = false
70 ): void {
71 $this->order_field = $a_val;
72 $this->order_field_numeric = $a_numeric;
73 }
74
75 public function getOrderField(): string
76 {
77 return $this->order_field;
78 }
79
84 public function setTypeWhiteList(array $a_val): void
85 {
86 $this->type_white_list = $a_val;
87 }
88
93 public function getTypeWhiteList(): array
94 {
95 return $this->type_white_list;
96 }
97
102 public function setTypeBlackList(array $a_val): void
103 {
104 $this->type_black_list = $a_val;
105 }
106
111 public function getTypeBlackList(): array
112 {
113 return $this->type_black_list;
114 }
115
116 public function setPreloadChilds(bool $a_val): void
117 {
118 $this->preload_childs = $a_val;
119 }
120
121 public function getPreloadChilds(): bool
122 {
123 return $this->preload_childs;
124 }
125
126 protected function preloadChilds(): void
127 {
128 $subtree = $this->tree->getSubTree($this->getRootNode());
129 foreach ($subtree as $s) {
130 $wl = $this->getTypeWhiteList();
131 if (is_array($wl) && count($wl) > 0 && !in_array($s["type"], $wl)) {
132 continue;
133 }
134 $bl = $this->getTypeBlackList();
135 if (is_array($bl) && count($bl) > 0 && in_array($s["type"], $bl)) {
136 continue;
137 }
138 $this->childs[$s["parent"]][] = $s;
139 $this->all_childs[$s["child"]] = $s;
140 }
141
142 if ($this->order_field !== "") {
143 foreach ($this->childs as $k => $childs) {
144 $this->childs[$k] = ilArrayUtil::sortArray(
145 $childs,
146 $this->order_field,
147 "asc",
148 $this->order_field_numeric
149 );
150 }
151 }
152
153 // sort childs and store prev/next reference
154 if ($this->order_field === "") {
155 $this->all_childs =
156 ilArrayUtil::sortArray($this->all_childs, "lft", "asc", true, true);
157 $prev = false;
158 foreach ($this->all_childs as $k => $c) {
159 if ($prev) {
160 $this->all_childs[$prev]["next_node_id"] = $k;
161 }
162 $this->all_childs[$k]["prev_node_id"] = $prev;
163 $this->all_childs[$k]["next_node_id"] = false;
164 $prev = $k;
165 }
166 }
167
168 $this->preloaded = true;
169 }
170
171
172
179 public function getSuccessorNode(
180 $a_node_id,
181 string $a_type = ""
182 ) {
183 if ($this->order_field !== "") {
184 die("ilTreeExplorerGUI::getSuccessorNode not implemented for order field " . $this->order_field);
185 }
186
187 if ($this->preloaded) {
188 $next_id = $a_node_id;
189 while (($next_id = $this->all_childs[$next_id]["next_node_id"]) && $a_type !== "" &&
190 $this->all_childs[$next_id]["type"] !== $a_type) {
191 // do nothing
192 }
193 if ($next_id) {
194 return $this->all_childs[$next_id];
195 }
196 return false;
197 }
198 return $this->getTree()->fetchSuccessorNode($a_node_id, $a_type);
199 }
200
201
202
208 public function getChildsOfNode($a_parent_node_id): array
209 {
210 if ($this->preloaded && $this->getSearchTerm() === "") {
211 if (isset($this->childs[$a_parent_node_id]) && is_array($this->childs[$a_parent_node_id])) {
212 return $this->childs[$a_parent_node_id];
213 }
214 return array();
215 }
216
217 $wl = $this->getTypeWhiteList();
218 if (count($wl) > 0) {
219 $childs = $this->tree->getChildsByTypeFilter($a_parent_node_id, $wl, $this->getOrderField());
220 } else {
221 $childs = $this->tree->getChilds($a_parent_node_id, $this->getOrderField());
222 }
223
224 // apply black list filter
225 $bl = $this->getTypeBlackList();
226 if (is_array($bl) && count($bl) > 0) {
227 $bl_childs = array();
228 foreach ($childs as $k => $c) {
229 if (!in_array($c["type"], $bl, true) && ($this->matches($c) || !$this->isNodeRequested($a_parent_node_id))) {
230 $bl_childs[$k] = $c;
231 }
232 }
233 return $bl_childs;
234 }
235
236 $final_childs = [];
237 foreach ($childs as $k => $c) {
238 if ($this->isNodeVisible($c)
239 && ($this->matches($c) || !$this->isNodeRequested($a_parent_node_id))) {
240 $final_childs[$k] = $c;
241 }
242 }
243 return $final_childs;
244 }
245
251 protected function matches($node): bool
252 {
253 return (
254 $this->getSearchTerm() === "" ||
255 is_int(ilStr::striPos($this->getNodeContent($node), $this->getSearchTerm()))
256 );
257 }
258
259
266 public function getNodeId($a_node)
267 {
268 return $a_node["child"];
269 }
270
276 public function getNodeIconAlt($a_node): string
277 {
279
280 return $lng->txt("icon") . " " . $lng->txt("obj_" . ($a_node["type"] ?? ''));
281 }
282
288 public function getRootNode()
289 {
290 if (!isset($this->root_node_data)) {
291 $this->root_node_data = $this->getTree()->getNodeData($this->getRootId());
292 }
293 return $this->root_node_data;
294 }
295
299 public function setRootId($a_root): void
300 {
301 $this->root_id = $a_root;
302 }
303
304 protected function getRootId(): int
305 {
306 return $this->root_id
307 ?: $this->getTree()->readRootId();
308 }
309
315 public function setPathOpen($a_id): void
316 {
317 $path = $this->getTree()->getPathId($a_id);
318 foreach ($path as $id) {
319 $this->setNodeOpen($id);
320 }
321 }
322
328 public function getHTML($new = false): string
329 {
330 if ($this->getPreloadChilds()) {
331 $this->preloadChilds();
332 }
333 if (!$new) {
334 return parent::getHTML();
335 }
336 return $this->render();
337 }
338
339 // New implementation
340
341 public function getChildren($record, $environment = null): array
342 {
343 return $this->getChildsOfNode($record["child"]);
344 }
345
349 protected function createNode(
350 \ILIAS\UI\Component\Tree\Node\Factory $factory,
351 $record
352 ): \ILIAS\UI\Component\Tree\Node\Node {
353 $nodeIconPath = $this->getNodeIcon($record);
354
355 $icon = null;
356 if ($nodeIconPath !== '') {
357 $icon = $this->ui
358 ->factory()
359 ->symbol()
360 ->icon()
361 ->custom($nodeIconPath, $this->getNodeIconAlt($record));
362 }
363
364 return $factory->simple($this->getNodeContent($record), $icon);
365 }
366
373 protected function getNodeStateToggleCmdClasses($record): array
374 {
375 return [];
376 }
377
378 public function build(
379 \ILIAS\UI\Component\Tree\Node\Factory $factory,
380 $record,
381 $environment = null
382 ): \ILIAS\UI\Component\Tree\Node\Node {
383 $node = $this->createNode($factory, $record);
384
385 $href = $this->getNodeHref($record);
386 if ($href !== '' && '#' !== $href && $this->isNodeClickable($record)) {
387 $node = $node->withLink(new \ILIAS\Data\URI(ILIAS_HTTP_PATH . '/' . $href));
388 }
389
390 if ($this->isNodeOpen((int) $this->getNodeId($record))) {
391 $node = $node->withExpanded(true);
392 }
393
394 $nodeStateToggleCmdClasses = $this->getNodeStateToggleCmdClasses($record);
395 $cmdClass = end($nodeStateToggleCmdClasses);
396
397 if (is_string($cmdClass) && $cmdClass !== '') {
398 $node = $node->withAdditionalOnLoadCode(function ($id) use ($record, $nodeStateToggleCmdClasses, $cmdClass): string {
399 $serverNodeId = $this->getNodeId($record);
400
401 $this->ctrl->setParameterByClass($cmdClass, $this->node_parameter_name, $serverNodeId);
402 $url = $this->ctrl->getLinkTargetByClass($nodeStateToggleCmdClasses, 'toggleExplorerNodeState', '', true, false);
403 $this->ctrl->setParameterByClass($cmdClass, $this->node_parameter_name, null);
404
405 $javascript = "il.UI.tree.registerToggleNodeAsyncAction('$id', '$url', 'prior_state');";
406
407 return $javascript;
408 });
409 }
410
411 return $node;
412 }
413
414 public function getTreeLabel(): string
415 {
416 return $this->tree_label;
417 }
418
419 public function getTreeComponent(): Tree
420 {
421 $f = $this->ui->factory();
422 $tree = $this->getTree();
423
424 if (!$this->getSkipRootNode()) {
425 $data = array(
426 $tree->getNodeData($tree->readRootId())
427 );
428 } else {
429 $data = $tree->getChilds($tree->readRootId());
430 }
431
432 $label = $this->getTreeLabel();
433 if ($this->getTreeLabel() === "" && $this->getNodeContent($this->getRootNode())) {
434 $label = $this->getNodeContent($this->getRootNode());
435 }
436
437 $tree = $f->tree()->expandable($label, $this)
438 ->withData($data)
439 ->withHighlightOnNodeClick(true);
440
441 return $tree;
442 }
443
447 public function toggleExplorerNodeState(): void
448 {
449 $nodeId = (int) ($this->httpRequest->getQueryParams()[$this->node_parameter_name] ?? 0);
450 $priorState = (int) ($this->httpRequest->getQueryParams()['prior_state'] ?? 0);
451
452 if ($nodeId > 0) {
453 if (0 === $priorState && !in_array($nodeId, $this->open_nodes)) {
454 $this->open_nodes[] = $nodeId;
455 } elseif (1 === $priorState && in_array($nodeId, $this->open_nodes)) {
456 $key = array_search($nodeId, $this->open_nodes);
457 unset($this->open_nodes[$key]);
458 }
459
460 $this->store->set('on_' . $this->id, serialize($this->open_nodes));
461 }
462 exit();
463 }
464
465 protected function render(): string
466 {
467 $r = $this->ui->renderer();
468
469 return $r->render([
470 $this->getTreeComponent()
471 ]);
472 }
473}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
language handling
Explorer class that works on tree objects (Services/Tree)
getNodeStateToggleCmdClasses($record)
Should return an array of ilCtrl-enabled command classes which should be used to build the URL for th...
setOrderField(string $a_val, bool $a_numeric=false)
matches($node)
Does a node match a search term (or is search term empty)
getChildren($record, $environment=null)
Get a list of records (that list can also be empty).
createNode(\ILIAS\UI\Component\Tree\Node\Factory $factory, $record)
Creates at tree node, can be overwritten in derivatives if another node type should be used.
setPathOpen($a_id)
Set node path to be opened.
getTypeWhiteList()
Get type white list.
getNodeId($a_node)
Get id for node.
getSuccessorNode( $a_node_id, string $a_type="")
Get successor node (currently only(!) based on lft/rgt tree values)
getChildsOfNode($a_parent_node_id)
Get childs of node.
toggleExplorerNodeState()
Should be called by an ilCtrl-enabled command class if a tree node toggle action should be processed.
getTypeBlackList()
Get type black list.
__construct(string $a_expl_id, $a_parent_obj, string $a_parent_cmd, ilTree $a_tree, string $a_node_parameter_name="node_id")
getNodeIconAlt($a_node)
Get node icon alt attribute.
setTypeBlackList(array $a_val)
Set type black list.
build(\ILIAS\UI\Component\Tree\Node\Factory $factory, $record, $environment=null)
ILIAS DI UIServices $ui
setTypeWhiteList(array $a_val)
Set type white list.
getHTML($new=false)
Get HTML.
Psr Http Message ServerRequestInterface $httpRequest
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
getNodeData(int $a_node_id, ?int $a_tree_pk=null)
get all information of a node.
getChilds(int $a_node_id, string $a_order="", string $a_direction="ASC")
get child nodes of given node
$c
Definition: deliver.php:25
exit
Interface for mapping data-structures to the Tree.
This describes a Tree Control.
Definition: Tree.php:29
$path
Definition: ltiservices.php:30
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26
$url
Definition: shib_logout.php:68