ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilTreeExplorerGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once("./Services/UIComponent/Explorer2/classes/class.ilExplorerBaseGUI.php");
5
15{
17 protected $lng;
18
20 protected $httpRequest;
21
22 protected $tree = null;
23 protected $tree_label = "";
24 protected $order_field = "";
25 protected $order_field_numeric = false;
26 protected $type_white_list = array();
27 protected $type_black_list = array();
28 protected $childs = array(); // preloaded childs
29 protected $preloaded = false;
30 protected $preload_childs = false;
31 protected $root_node_data = null;
32 protected $all_childs = array();
33
37 protected $ui;
38
42 public function __construct($a_expl_id, $a_parent_obj, $a_parent_cmd, $a_tree)
43 {
44 global $DIC;
45
46 $this->httpRequest = $DIC->http()->request();
47 $this->ui = $DIC->ui();
48 $this->lng = $DIC->language();
49 parent::__construct($a_expl_id, $a_parent_obj, $a_parent_cmd);
50 $this->tree = $a_tree;
51 }
52
58 public function getTree()
59 {
60 return $this->tree;
61 }
62
68 public function setOrderField($a_val, $a_numeric = false)
69 {
70 $this->order_field = $a_val;
71 $this->order_field_numeric = $a_numeric;
72 }
73
79 public function getOrderField()
80 {
81 return $this->order_field;
82 }
83
89 public function setTypeWhiteList($a_val)
90 {
91 $this->type_white_list = $a_val;
92 }
93
99 public function getTypeWhiteList()
100 {
102 }
103
109 public function setTypeBlackList($a_val)
110 {
111 $this->type_black_list = $a_val;
112 }
113
119 public function getTypeBlackList()
120 {
122 }
123
129 public function setPreloadChilds($a_val)
130 {
131 $this->preload_childs = $a_val;
132 }
133
139 public function getPreloadChilds()
140 {
142 }
143
147 protected function preloadChilds()
148 {
149 $subtree = $this->tree->getSubTree($this->getRootNode());
150 foreach ($subtree as $s) {
151 $wl = $this->getTypeWhiteList();
152 if (is_array($wl) && count($wl) > 0 && !in_array($s["type"], $wl)) {
153 continue;
154 }
155 $bl = $this->getTypeBlackList();
156 if (is_array($bl) && count($bl) > 0 && in_array($s["type"], $bl)) {
157 continue;
158 }
159 $this->childs[$s["parent"]][] = $s;
160 $this->all_childs[$s["child"]] = $s;
161 }
162
163 if ($this->order_field != "") {
164 foreach ($this->childs as $k => $childs) {
165 $this->childs[$k] = ilUtil::sortArray($childs, $this->order_field, "asc", $this->order_field_numeric);
166 }
167 }
168
169 // sort childs and store prev/next reference
170 if ($this->order_field == "") {
171 $this->all_childs =
172 ilUtil::sortArray($this->all_childs, "lft", "asc", true, true);
173 $prev = false;
174 foreach ($this->all_childs as $k => $c) {
175 if ($prev) {
176 $this->all_childs[$prev]["next_node_id"] = $k;
177 }
178 $this->all_childs[$k]["prev_node_id"] = $prev;
179 $this->all_childs[$k]["next_node_id"] = false;
180 $prev = $k;
181 }
182 }
183
184 $this->preloaded = true;
185 }
186
187
188
196 public function getSuccessorNode($a_node_id, $a_type = "")
197 {
198 if ($this->order_field != "") {
199 die("ilTreeExplorerGUI::getSuccessorNode not implemented for order field " . $this->order_field);
200 }
201
202 if ($this->preloaded) {
203 $next_id = $a_node_id;
204 while (($next_id = $this->all_childs[$next_id]["next_node_id"]) && $a_type != "" &&
205 $this->all_childs[$next_id]["type"] != $a_type);
206 if ($next_id) {
207 return $this->all_childs[$next_id];
208 }
209 return false;
210 }
211 return $this->getTree()->fetchSuccessorNode($a_node_id, $a_type);
212 }
213
214
215
222 public function getChildsOfNode($a_parent_node_id)
223 {
224 if ($this->preloaded && $this->getSearchTerm() == "") {
225 if (is_array($this->childs[$a_parent_node_id])) {
226 return $this->childs[$a_parent_node_id];
227 }
228 return array();
229 }
230
231 $wl = $this->getTypeWhiteList();
232 if (is_array($wl) && count($wl) > 0) {
233 $childs = $this->tree->getChildsByTypeFilter($a_parent_node_id, $wl, $this->getOrderField());
234 } else {
235 $childs = $this->tree->getChilds($a_parent_node_id, $this->getOrderField());
236 }
237
238 // apply black list filter
239 $bl = $this->getTypeBlackList();
240 if (is_array($bl) && count($bl) > 0) {
241 $bl_childs = array();
242 foreach ($childs as $k => $c) {
243 if (!in_array($c["type"], $bl) && ($this->matches($c) || $this->requested_node_id != $this->getDomNodeIdForNodeId($a_parent_node_id))) {
244 $bl_childs[$k] = $c;
245 }
246 }
247 return $bl_childs;
248 }
249
250 $final_childs = [];
251 foreach ($childs as $k => $c) {
252 if ($this->matches($c) || $this->requested_node_id != $this->getDomNodeIdForNodeId($a_parent_node_id)) {
253 $final_childs[$k] = $c;
254 }
255 }
256 return $final_childs;
257 }
258
265 protected function matches($node) : bool
266 {
267 if ($this->getSearchTerm() == "" ||
268 is_int(stripos($this->getNodeContent($node), $this->getSearchTerm()))) {
269 return true;
270 }
271 return false;
272 }
273
274
281 public function getNodeId($a_node)
282 {
283 return $a_node["child"];
284 }
285
292 public function getNodeIconAlt($a_node)
293 {
295
296 return $lng->txt("icon") . " " . $lng->txt("obj_" . $a_node["type"]);
297 }
298
304 public function getRootNode()
305 {
306 if (!isset($this->root_node_data)) {
307 $this->root_node_data = $this->getTree()->getNodeData($this->getRootId());
308 }
310 }
311
312 public function setRootId($a_root)
313 {
314 $this->root_id = $a_root;
315 }
316
317 protected function getRootId()
318 {
319 return $this->root_id
320 ? $this->root_id
321 : $this->getTree()->readRootId();
322 }
323
329 public function setPathOpen($a_id)
330 {
331 $path = $this->getTree()->getPathId($a_id);
332 foreach ($path as $id) {
333 $this->setNodeOpen($id);
334 }
335 }
336
342 public function getHTML($new = false)
343 {
344 if ($this->getPreloadChilds()) {
345 $this->preloadChilds();
346 }
347 if (!$new) {
348 return parent::getHTML();
349 }
350 return $this->render();
351 }
352
353 // New implementation
354
358 public function getChildren($node, $environment = null) : array
359 {
360 return $this->getChildsOfNode($node["child"]);
361 }
362
366 protected function createNode(
367 \ILIAS\UI\Component\Tree\Node\Factory $factory,
368 $record
369 ) : \ILIAS\UI\Component\Tree\Node\Node {
370 $nodeIconPath = $this->getNodeIcon($record);
371
372 $icon = null;
373 if (is_string($nodeIconPath) && strlen($nodeIconPath) > 0) {
374 $icon = $this->ui
375 ->factory()
376 ->symbol()
377 ->icon()
378 ->custom($nodeIconPath, $this->getNodeIconAlt($record));
379 }
380
381 return $factory->simple($this->getNodeContent($record), $icon);
382 }
383
390 protected function getNodeStateToggleCmdClasses($record) : array
391 {
392 return [];
393 }
394
398 public function build(
399 \ILIAS\UI\Component\Tree\Node\Factory $factory,
400 $record,
401 $environment = null
402 ) : \ILIAS\UI\Component\Tree\Node\Node {
403 $node = $this->createNode($factory, $record);
404
405 $href = $this->getNodeHref($record);
406 if (is_string($href) && strlen($href) > 0 && '#' !== $href) {
407 $node = $node->withLink(new \ILIAS\Data\URI(ILIAS_HTTP_PATH . '/' . $href));
408 }
409
410 if ($this->isNodeOpen((int) $this->getNodeId($record))) {
411 $node = $node->withExpanded(true);
412 }
413
414 $nodeStateToggleCmdClasses = $this->getNodeStateToggleCmdClasses($record);
415 $cmdClass = end($nodeStateToggleCmdClasses);
416
417 if (is_string($cmdClass) && strlen($cmdClass) > 0) {
418 $node = $node->withAdditionalOnLoadCode(function ($id) use ($record, $nodeStateToggleCmdClasses, $cmdClass) {
419 $serverNodeId = $this->getNodeId($record);
420
421 $this->ctrl->setParameterByClass($cmdClass, 'node_id', $serverNodeId);
422 $url = $this->ctrl->getLinkTargetByClass($nodeStateToggleCmdClasses, 'toggleExplorerNodeState', '', true, false);
423 $this->ctrl->setParameterByClass($cmdClass, 'node_id', null);
424
425 $javascript = "il.UI.tree.registerToggleNodeAsyncAction('$id', '$url', 'prior_state');";
426
427 return $javascript;
428 });
429 }
430
431 return $node;
432 }
433
437 public function getTreeLabel()
438 {
439 return $this->tree_label;
440 }
441
447 public function getTreeComponent()
448 {
449 $f = $this->ui->factory();
450 $tree = $this->getTree();
451
452 $data = array(
453 $tree->getNodeData($tree->readRootId())
454 );
455
456 $label = $this->getTreeLabel();
457 if ($this->getTreeLabel() == "" && $this->getNodeContent($this->getRootNode())) {
458 $label = $this->getNodeContent($this->getRootNode());
459 }
460
461 $tree = $f->tree()->expandable($label, $this)
462 ->withData($data)
463 ->withHighlightOnNodeClick(true);
464
465 return $tree;
466 }
467
471 public function toggleExplorerNodeState() : void
472 {
473 $nodeId = (int) ($this->httpRequest->getQueryParams()['node_id'] ?? 0);
474 $priorState = (int) ($this->httpRequest->getQueryParams()['prior_state'] ?? 0);
475
476 if ($nodeId > 0) {
477 if (0 === $priorState && !in_array($nodeId, $this->open_nodes)) {
478 $this->open_nodes[] = $nodeId;
479 } elseif (1 === $priorState && in_array($nodeId, $this->open_nodes)) {
480 $key = array_search($nodeId, $this->open_nodes);
481 unset($this->open_nodes[$key]);
482 }
483
484 $this->store->set('on_' . $this->id, serialize($this->open_nodes));
485 }
486 exit();
487 }
488
494 protected function render()
495 {
496 $r = $this->ui->renderer();
497
498 return $r->render([
499 $this->getTreeComponent()
500 ]);
501 }
502}
An exception for terminatinating execution or to throw for unit testing.
Explorer base GUI class.
getNodeIcon($a_node)
Get node icon path.
getNodeContent($a_node)
Get content of a node.
getDomNodeIdForNodeId($a_node_id)
Get DOM node id for node id.
getSearchTerm()
Get search term.
setNodeOpen($a_id)
Set node to be opened (additional custom opened node, not standard expand behaviour)
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...
matches($node)
Does a node match a search term (or is search term empty)
__construct($a_expl_id, $a_parent_obj, $a_parent_cmd, $a_tree)
Constructor.
setTypeWhiteList($a_val)
Set type white list.
preloadChilds()
Preload childs.
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.
setTypeBlackList($a_val)
Set type black list.
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.
setPreloadChilds($a_val)
Set preload childs.
getNodeIconAlt($a_node)
Get node icon alt attribute.
build(\ILIAS\UI\Component\Tree\Node\Factory $factory, $record, $environment=null)
getOrderField()
Get order field.
getPreloadChilds()
Get preload childs.
getHTML($new=false)
Get HTML.
getSuccessorNode($a_node_id, $a_type="")
Get successor node (currently only(!) based on lft/rgt tree values)
getChildren($node, $environment=null)
Get a list of records (that list can also be empty).Each record will be relayed to $this->build to re...
setOrderField($a_val, $a_numeric=false)
Set order field.
static sortArray( $array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
$c
Definition: cli.php:37
global $DIC
Definition: goto.php:24
Interface for mapping data-structures to the Tree.
exit
Definition: login.php:29
$factory
Definition: metadata.php:58
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ChatMainBarProvider \MainMenu\Provider.
Class Factory.
$url
$data
Definition: storeScorm.php:23
ui()
Definition: ui.php:5