ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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
257 return $final_childs;
258 }
259
266 protected function matches($node) : bool
267 {
268 if ($this->getSearchTerm() == "" ||
269 is_int(stripos($this->getNodeContent($node), $this->getSearchTerm()))) {
270 return true;
271 }
272 return false;
273 }
274
275
282 public function getNodeId($a_node)
283 {
284 return $a_node["child"];
285 }
286
293 public function getNodeIconAlt($a_node)
294 {
296
297 return $lng->txt("icon") . " " . $lng->txt("obj_" . $a_node["type"]);
298 }
299
305 public function getRootNode()
306 {
307 if (!isset($this->root_node_data)) {
308 $this->root_node_data = $this->getTree()->getNodeData($this->getRootId());
309 }
311 }
312
313 public function setRootId($a_root)
314 {
315 $this->root_id = $a_root;
316 }
317
318 protected function getRootId()
319 {
320 return $this->root_id
321 ? $this->root_id
322 : $this->getTree()->readRootId();
323 }
324
330 public function setPathOpen($a_id)
331 {
332 $path = $this->getTree()->getPathId($a_id);
333 foreach ($path as $id) {
334 $this->setNodeOpen($id);
335 }
336 }
337
343 public function getHTML($new = false)
344 {
345 if ($this->getPreloadChilds()) {
346 $this->preloadChilds();
347 }
348 if (!$new) {
349 return parent::getHTML();
350 }
351 return $this->render();
352 }
353
354 // New implementation
355
359 public function getChildren($node, $environment = null) : array
360 {
361 return $this->getChildsOfNode($node["child"]);
362 }
363
367 protected function createNode(
368 \ILIAS\UI\Component\Tree\Node\Factory $factory,
369 $record
370 ) : \ILIAS\UI\Component\Tree\Node\Node {
371 $nodeIconPath = $this->getNodeIcon($record);
372
373 $icon = null;
374 if (is_string($nodeIconPath) && strlen($nodeIconPath) > 0) {
375 $icon = $this->ui
376 ->factory()
377 ->symbol()
378 ->icon()
379 ->custom($nodeIconPath, $this->getNodeIconAlt($record));
380 }
381
382 return $factory->simple($this->getNodeContent($record), $icon);
383 }
384
391 protected function getNodeStateToggleCmdClasses($record) : array
392 {
393 return [];
394 }
395
399 public function build(
400 \ILIAS\UI\Component\Tree\Node\Factory $factory,
401 $record,
402 $environment = null
403 ) : \ILIAS\UI\Component\Tree\Node\Node {
404 $node = $this->createNode($factory, $record);
405
406 $href = $this->getNodeHref($record);
407 if (is_string($href) && strlen($href) > 0 && '#' !== $href) {
408 $node = $node->withLink(new \ILIAS\Data\URI(ILIAS_HTTP_PATH . '/' . $href));
409 }
410
411 if ($this->isNodeOpen((int) $this->getNodeId($record))) {
412 $node = $node->withExpanded(true);
413 }
414
415 $nodeStateToggleCmdClasses = $this->getNodeStateToggleCmdClasses($record);
416 $cmdClass = end($nodeStateToggleCmdClasses);
417
418 if (is_string($cmdClass) && strlen($cmdClass) > 0) {
419 $node = $node->withAdditionalOnLoadCode(function ($id) use ($record, $nodeStateToggleCmdClasses, $cmdClass) {
420 $serverNodeId = $this->getNodeId($record);
421
422 $this->ctrl->setParameterByClass($cmdClass, 'node_id', $serverNodeId);
423 $url = $this->ctrl->getLinkTargetByClass($nodeStateToggleCmdClasses, 'toggleExplorerNodeState', '', true, false);
424 $this->ctrl->setParameterByClass($cmdClass, 'node_id', null);
425
426 $javascript = "$('#$id').on('click', function(event) {
427 let node = $(this);
428
429 if (node.hasClass('expandable')) {
430 il.UI.tree.toggleNodeState(event, '$url', 'prior_state', node.hasClass('expanded'));
431 event.preventDefault();
432 event.stopPropagation();
433 }
434 });";
435
436 return $javascript;
437 });
438 }
439
440 return $node;
441 }
442
446 public function getTreeLabel()
447 {
448 return $this->tree_label;
449 }
450
456 public function getTreeComponent()
457 {
458 $f = $this->ui->factory();
459 $tree = $this->getTree();
460
461 $data = array(
462 $tree->getNodeData($tree->readRootId())
463 );
464
465 $label = $this->getTreeLabel();
466 if ($this->getTreeLabel() == "" && $this->getNodeContent($this->getRootNode())) {
467 $label = $this->getNodeContent($this->getRootNode());
468 }
469
470 $tree = $f->tree()->expandable($label, $this)
471 ->withData($data)
472 ->withHighlightOnNodeClick(true);
473
474 return $tree;
475 }
476
480 public function toggleExplorerNodeState() : void
481 {
482 $nodeId = (int) ($this->httpRequest->getQueryParams()['node_id'] ?? 0);
483 $priorState = (int) ($this->httpRequest->getQueryParams()['prior_state'] ?? 0);
484
485 if ($nodeId > 0) {
486 if (0 === $priorState && !in_array($nodeId, $this->open_nodes)) {
487 $this->open_nodes[] = $nodeId;
488 } elseif (1 === $priorState && in_array($nodeId, $this->open_nodes)) {
489 $key = array_search($nodeId, $this->open_nodes);
490 unset($this->open_nodes[$key]);
491 }
492
493 $this->store->set('on_' . $this->id, serialize($this->open_nodes));
494 }
495 exit();
496 }
497
503 protected function render()
504 {
505 $r = $this->ui->renderer();
506
507 return $r->render([
508 $this->getTreeComponent()
509 ]);
510 }
511}
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
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
$a_type
Definition: workflow.php:92
$DIC
Definition: xapitoken.php:46