ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilVirtualSkillTree.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
14{
18 protected $lng;
19
20 protected static $order_node_data = null;
21 protected $include_drafts = false;
22 protected $drafts = array();
23 protected $include_outdated = false;
24 protected $outdated = array();
25
29 public function __construct()
30 {
31 global $DIC;
32
33 $this->lng = $DIC->language();
34 $this->tree = new ilSkillTree();
35 }
36
42 public function getRootNode()
43 {
44 $root_id = $this->tree->readRootId();
45 $root_node = $this->tree->getNodeData($root_id);
46 unset($root_node["child"]);
47 $root_node["id"] = $root_id . ":0";
48 $root_node["cskill_id"] = $root_id . ":0";
49
50 return $root_node;
51 }
52
58 public function setIncludeDrafts($a_val)
59 {
60 $this->include_drafts = $a_val;
61 }
62
68 public function getIncludeDrafts()
69 {
71 }
72
78 public function setIncludeOutdated($a_val)
79 {
80 $this->include_outdated = $a_val;
81 }
82
88 public function getIncludeOutdated()
89 {
91 }
92
99 public function getNode($a_id)
100 {
101 $id_parts = explode(":", $a_id);
102 $skl_tree_id = $id_parts[0];
103 $skl_template_tree_id = $id_parts[1];
104
105 if ($skl_template_tree_id == 0 || (ilSkillTemplateReference::_lookupTemplateId($skl_tree_id)
106 == $skl_template_tree_id)) {
107 $node_data = $this->tree->getNodeData($skl_tree_id);
108 $node_data["parent"] = $node_data["parent"] . ":0";
109 } else {
110 $node_data = $this->tree->getNodeData($skl_template_tree_id);
111 $node_data["parent"] = $skl_tree_id . ":" . $node_data["parent"];
112 }
113
114 unset($node_data["child"]);
115 unset($node_data["skl_tree_id"]);
116 unset($node_data["lft"]);
117 unset($node_data["rgt"]);
118 unset($node_data["depth"]);
119
120 $node_data["id"] = $a_id;
121 $cid = $this->getCSkillIdForVTreeId($a_id);
122 $cid_parts = explode(":", $cid);
123 $node_data["skill_id"] = $cid_parts[0];
124 $node_data["tref_id"] = $cid_parts[1];
125 $node_data["cskill_id"] = $cid;
126
127
128 return $node_data;
129 }
130
131
138 public function getChildsOfNode($a_parent_id)
139 {
140 $a_parent_id_parts = explode(":", $a_parent_id);
141 $a_parent_skl_tree_id = $a_parent_id_parts[0];
142 $a_parent_skl_template_tree_id = $a_parent_id_parts[1];
143
144 if ($a_parent_skl_template_tree_id == 0) {
145 $childs = $this->tree->getChildsByTypeFilter($a_parent_skl_tree_id, array("scat", "skll", "sktr"), "order_nr");
146 } else {
147 $childs = $this->tree->getChildsByTypeFilter($a_parent_skl_template_tree_id, array("sktp", "sctp"), "order_nr");
148 }
149
150 $drafts = array();
151 $outdated = array();
152 foreach ($childs as $k => $c) {
153 if ($a_parent_skl_template_tree_id > 0) {
154 // we are in template tree only
155 $child_id = $a_parent_skl_tree_id . ":" . $c["child"];
156 } elseif (!in_array($c["type"], array("sktr", "sctr"))) {
157 // we are in main tree only
158 $child_id = $c["child"] . ":0";
159 } else {
160 // get template id for references
161 $child_id = $c["child"] . ":" . ilSkillTemplateReference::_lookupTemplateId($c["child"]);
162 }
163 unset($childs[$k]["child"]);
164 unset($childs[$k]["skl_tree_id"]);
165 unset($childs[$k]["lft"]);
166 unset($childs[$k]["rgt"]);
167 unset($childs[$k]["depth"]);
168 $childs[$k]["id"] = $child_id;
169 //echo "-".$child_id."-";
170 $cid = $this->getCSkillIdForVTreeId($child_id);
171 //echo "-".$cid."-";
172 $cid_parts = explode(":", $cid);
173 $childs[$k]["skill_id"] = $cid_parts[0];
174 $childs[$k]["tref_id"] = $cid_parts[1];
175 $childs[$k]["cskill_id"] = $cid;
176 $childs[$k]["parent"] = $a_parent_id;
177
178 $this->parent[$c["id"]] = $a_parent_id;
179
180 // @todo: prepare this for tref id?
182 in_array($a_parent_id, $this->drafts)) {
183 $this->drafts[] = $child_id;
184 $drafts[] = $k;
185 }
187 in_array($a_parent_id, $this->outdated)) {
188 $this->outdated[] = $child_id;
189 $outdated[] = $k;
190 }
191 }
192 if (!$this->getIncludeDrafts()) {
193 foreach ($drafts as $d) {
194 unset($childs[$d]);
195 }
196 }
197 if (!$this->getIncludeOutdated()) {
198 foreach ($outdated as $d) {
199 unset($childs[$d]);
200 }
201 }
202
203 return $childs;
204 }
205
212 public function getChildsOfNodeForCSkillId($a_cskill_id)
213 {
214 $id_parts = explode(":", $a_cskill_id);
215 if ($id_parts[1] == 0) {
216 $id = $id_parts[0] . ":0";
217 } else {
218 $id = $id_parts[1] . ":" . $id_parts[0];
219 }
220 return $this->getChildsOfNode($id);
221 }
222
229 public function getCSkillIdForVTreeId($a_vtree_id)
230 {
231 $id_parts = explode(":", $a_vtree_id);
232 if ($id_parts[1] == 0) {
233 // skill in main tree
234 $skill_id = $id_parts[0];
235 $tref_id = 0;
236 } else {
237 // skill in template
238 $tref_id = $id_parts[0];
239 $skill_id = $id_parts[1];
240 }
241 return $skill_id . ":" . $tref_id;
242 }
243
250 public function getVTreeIdForCSkillId($a_cskill_id)
251 {
252 $id_parts = explode(":", $a_cskill_id);
253 if ($id_parts[1] == 0) {
254 $id = $id_parts[0] . ":0";
255 } else {
256 $id = $id_parts[1] . ":" . $id_parts[0];
257 }
258 return $id;
259 }
260
261
262
269 public function getNodeTitle($a_node)
270 {
272
273 $a_parent_id_parts = explode(":", $a_node["id"]);
274 $a_parent_skl_tree_id = $a_parent_id_parts[0];
275 $a_parent_skl_template_tree_id = $a_parent_id_parts[1];
276
277 // title
278 $title = $a_node["title"];
279
280 // root?
281 if ($a_node["type"] == "skrt") {
282 $lng->txt("skmg_skills");
283 } else {
284 if ($a_node["type"] == "sktr") {
285 // $title.= " (".ilSkillTreeNode::_lookupTitle($a_parent_skl_template_tree_id).")";
286 }
287 }
288
289 return $title;
290 }
291
299 public function getSubTreeForCSkillId($a_cskill_id, $a_only_basic = false)
300 {
301 $id_parts = explode(":", $a_cskill_id);
302 if ($id_parts[1] == 0) {
303 $id = $id_parts[0] . ":0";
304 } else {
305 $id = $id_parts[1] . ":" . $id_parts[0];
306 }
307
308 $result = array();
309
310 $node = $this->getNode($id);
311 if (!$a_only_basic || in_array($node["type"], array("skll", "sktp")) ||
312 ($node["type"] == "sktr" && ilSkillTreeNode::_lookupType($node["skill_id"]) == "sktp")) {
313 $result[] = $node;
314 }
315 $this->__getSubTreeRec($id, $result, $a_only_basic);
316
317 return $result;
318 }
319
327 private function __getSubTreeRec($id, &$result, $a_only_basic)
328 {
329 $childs = $this->getChildsOfNode($id);
330 foreach ($childs as $c) {
331 if (!$a_only_basic || in_array($c["type"], array("skll", "sktp")) ||
332 ($c["type"] == "sktr" && ilSkillTreeNode::_lookupType($c["skill_id"]) == "sktp")) {
333 $result[] = $c;
334 }
335 $this->__getSubTreeRec($c["id"], $result, $a_only_basic);
336 }
337 }
338
345 public function isDraft($a_node_id)
346 {
347 return in_array($a_node_id, $this->drafts);
348 }
349
356 public function isOutdated($a_node_id)
357 {
358 return in_array($a_node_id, $this->outdated);
359 }
360
369 public function getOrderedNodeset($c_skill_ids, $a_skill_id_key = "", $a_tref_id_key = "")
370 {
371 global $DIC;
372
373 $db = $DIC->database();
374
375 if (self::$order_node_data == null) {
376 $node_data = array();
377 $set = $db->query("SELECT t.child, t.parent, t.lft, n.order_nr FROM skl_tree t JOIN skl_tree_node n ON (t.child = n.obj_id)");
378 while ($rec = $db->fetchAssoc($set)) {
379 $node_data[$rec["child"]] = array(
380 "parent" => $rec["parent"],
381 "lft" => $rec["lft"],
382 "order_nr" => $rec["order_nr"],
383 );
384 }
385 self::$order_node_data = $node_data;
386 } else {
387 $node_data = self::$order_node_data;
388 }
389
390 uasort($c_skill_ids, function ($a, $b) use ($node_data, $a_skill_id_key, $a_tref_id_key) {
391
392 // normalize to cskill strings
393 if (is_array($a)) {
394 $cskilla = $a[$a_skill_id_key] . ":" . $a[$a_tref_id_key];
395 $cskillb = $b[$a_skill_id_key] . ":" . $b[$a_tref_id_key];
396 } else {
397 $cskilla = $a;
398 $cskillb = $b;
399 }
400
401 // get vtree ids
402 $vida = explode(":", $this->getVTreeIdForCSkillId($cskilla));
403 $vidb = explode(":", $this->getVTreeIdForCSkillId($cskillb));
404
405 $ua = $this->getFirstUncommonAncestors($vida[0], $vidb[0], $node_data);
406 if (is_array($ua)) {
407 return ($node_data[$ua[0]]["order_nr"] - $node_data[$ua[1]]["order_nr"]);
408 }
409 // if we did not find a first uncommon ancestor, we are in the same node in the
410 // main tree, here, if we have tref ids, we let the template tree decide
411 if ($vida[1] > 0 && $vidb[1] > 0) {
412 $ua = $this->getFirstUncommonAncestors($vida[1], $vidb[1], $node_data);
413 if (is_array($ua)) {
414 return ($node_data[$ua[0]]["order_nr"] - $node_data[$ua[1]]["order_nr"]);
415 }
416 }
417
418 return 0;
419 });
420
421 return $c_skill_ids;
422 }
423
424 // get path in node data
425 protected function getPath($a, $node_data)
426 {
427 $path[] = $a;
428 while ($node_data[$a]["parent"] != 0) {
429 $a = $node_data[$a]["parent"];
430 $path[] = $a;
431 }
432 return array_reverse($path);
433 }
434
435 // get first uncommon ancestors of $a and $b in $node_data
436 protected function getFirstUncommonAncestors($a, $b, $node_data)
437 {
438 $path_a = $this->getPath($a, $node_data);
439 $path_b = $this->getPath($b, $node_data);
440 foreach ($path_a as $k => $v) {
441 if ($v != $path_b[$k]) {
442 return array($v, $path_b[$k]);
443 }
444 }
445 return false;
446 }
447}
$result
An exception for terminatinating execution or to throw for unit testing.
static _lookupTemplateId($a_obj_id)
Lookup template ID.
static _lookupStatus($a_obj_id)
Lookup Status.
static _lookupType($a_obj_id)
Lookup Type.
getSubTreeForCSkillId($a_cskill_id, $a_only_basic=false)
Get sub tree.
isDraft($a_node_id)
Is draft.
__getSubTreeRec($id, &$result, $a_only_basic)
Get subtree, internal.
isOutdated($a_node_id)
Is outdated.
getIncludeDrafts()
Get include drafts.
getChildsOfNode($a_parent_id)
Get childs of node.
getVTreeIdForCSkillId($a_cskill_id)
Get tree id for common skill id.
getNodeTitle($a_node)
Get node content.
setIncludeDrafts($a_val)
Set include drafts.
getOrderedNodeset($c_skill_ids, $a_skill_id_key="", $a_tref_id_key="")
Get ordererd nodeset for common skill ids.
setIncludeOutdated($a_val)
Set include outdated.
getFirstUncommonAncestors($a, $b, $node_data)
getIncludeOutdated()
Get include outdated.
getCSkillIdForVTreeId($a_vtree_id)
Get common skill id for tree id.
getChildsOfNodeForCSkillId($a_cskill_id)
Get childs of node for cskill id.
$c
Definition: cli.php:37
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
global $DIC
Definition: goto.php:24
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples