ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.SkillTreeNodeManager.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\Skill\Node;
22
23use ilArrayUtil;
25
32{
33 protected int $skill_tree_id = 0;
34 protected \ilSkillTree $tree;
35 protected \ilObjUser $user;
36
37 public function __construct(int $skill_tree_id, Tree\SkillTreeFactory $tree_factory)
38 {
39 global $DIC;
40
41 $this->user = $DIC->user();
42
43 $this->skill_tree_id = $skill_tree_id;
44 $this->tree = $tree_factory->getTreeById($skill_tree_id);
45 }
46
47 public function putIntoTree(\ilSkillTreeNode $node, int $parent_node_id, int $a_target_node_id = 0): void
48 {
50 $node->setOrderNr($tree->getMaxOrderNr($parent_node_id) + 10);
51 $node->update();
52
53 // determine parent
54 $parent_id = ($parent_node_id <= 0)
55 ? $tree->readRootId()
56 : $parent_node_id;
57
58 // make a check, whether the type of object is allowed under
59 // the parent
60 $allowed = array(
61 "skrt" => array("skll", "scat", "sktr", "sktp", "sctp"),
62 "scat" => array("skll", "scat", "sktr"),
63 "sctp" => array("sktp", "sctp"));
64 $par_type = \ilSkillTreeNode::_lookupType($parent_id);
65 if (!is_array($allowed[$par_type]) ||
66 !in_array($node->getType(), $allowed[$par_type])) {
67 return;
68 }
69
70 // determine target
71 if ($a_target_node_id != 0) {
72 $target = $a_target_node_id;
73 } else {
74 // determine last child that serves as predecessor
75 $childs = $tree->getChilds($parent_id);
76
77 if (count($childs) == 0) {
79 } else {
80 $target = $childs[count($childs) - 1]["obj_id"];
81 }
82 }
83
84 if ($tree->isInTree($parent_id) && !$tree->isInTree($node->getId())) {
85 $tree->insertNode($node->getId(), $parent_id, $target);
86 }
87 }
88
89 public function getWrittenPath(int $node_id, int $tref_id = 0): string
90 {
91 $path = $this->tree->getSkillTreePath($node_id, $tref_id);
92
93 $path_items = [];
94 foreach ($path as $p) {
95 if ($p["type"] != "skrt") {
96 $path_items[] = $p["title"];
97 }
98 }
99 return implode(" > ", $path_items);
100 }
101
102 public function getRootId(): int
103 {
104 return $this->tree->readRootId();
105 }
106
107
111 public function clipboardCut(array $a_ids): void
112 {
113 $this->clearClipboard();
114 $tree = $this->tree;
115
116 $cut_ids = [];
117 if (!is_array($a_ids)) {
118 return;
119 } else {
120 // get all "top" ids, i.e. remove ids, that have a selected parent
121 foreach ($a_ids as $id) {
123 $take = true;
124 foreach ($path as $path_id) {
125 if ($path_id != $id && in_array($path_id, $a_ids)) {
126 $take = false;
127 }
128 }
129 if ($take) {
130 $cut_ids[] = $id;
131 }
132 }
133 }
134
135 $this->clipboardCopy($cut_ids);
136
137 // remove the objects from the tree
138 // note: we are getting skills/categories which are *not* in the tree
139 // we do not delete any pages/chapters here
140 foreach ($cut_ids as $id) {
141 $curnode = $tree->getNodeData($id);
142 if ($tree->isInTree($id)) {
143 $tree->deleteTree($curnode);
144 }
145 }
146 // @todo check if needed
148 }
149
153 public function clipboardCopy(array $a_ids): void
154 {
155 $ilUser = $this->user;
156
157 $this->clearClipboard();
158 $tree = $this->tree;
159
160 // put them into the clipboard
161 $time = date("Y-m-d H:i:s", time());
162 $order = 0;
163 foreach ($a_ids as $id) {
164 $curnode = "";
165 if ($tree->isInTree($id)) {
166 $curnode = $tree->getNodeData($id);
167 $subnodes = $tree->getSubTree($curnode);
168 foreach ($subnodes as $subnode) {
169 if ($subnode["child"] != $id) {
170 $ilUser->addObjectToClipboard(
171 $subnode["child"],
172 $subnode["type"],
173 $subnode["title"],
174 $subnode["parent"],
175 $time,
176 $subnode["lft"]
177 );
178 }
179 }
180 }
181 $order = ($curnode["lft"] > 0)
182 ? $curnode["lft"]
183 : (int) ($order + 1);
184 $ilUser->addObjectToClipboard(
185 $id,
188 0,
189 $time,
190 $order
191 );
192 }
194 }
195
196
200 public function insertItemsFromClip(string $a_type, int $a_obj_id): array
201 {
202 $ilUser = $this->user;
203
204 $parent_id = $a_obj_id;
205 $target = \ilTree::POS_LAST_NODE;
206
207 // cut and paste
208 $skills = $ilUser->getClipboardObjects($a_type); // this will get all skills _regardless_ of level
209 $copied_nodes = [];
210 foreach ($skills as $skill) {
211 // if skill was already copied as part of tree - do not copy it again
212 if (!in_array($skill["id"], array_keys($copied_nodes))) {
213 $cid = $this->pasteTree(
214 (int) $skill["id"],
215 $parent_id,
216 $target,
217 $skill["insert_time"],
218 $copied_nodes,
219 (\ilEditClipboard::getAction() == "copy"),
220 true
221 );
222 // $target = $cid;
223 }
224 }
225
226 $this->clearClipboard();
227
228 $this->saveChildsOrder(
229 $a_obj_id,
230 [],
231 in_array($a_type, array("sktp", "sctp"))
232 );
233
234 return $copied_nodes;
235 }
236
240 public static function clearClipboard(): void
241 {
242 global $DIC;
243
244 $ilUser = $DIC->user();
245
246 $ilUser->clipboardDeleteObjectsOfType("skll");
247 $ilUser->clipboardDeleteObjectsOfType("scat");
248 $ilUser->clipboardDeleteObjectsOfType("sktr");
249 $ilUser->clipboardDeleteObjectsOfType("sktp");
250 $ilUser->clipboardDeleteObjectsOfType("sctp");
252 }
253
254
258 protected function pasteTree(
259 int $a_item_id,
260 int $a_parent_id,
261 int $a_target,
262 string $a_insert_time,
263 array &$a_copied_nodes,
264 bool $a_as_copy = false,
265 bool $a_add_suffix = false
266 ): int {
267 global $DIC;
268
269 $ilUser = $this->user;
270 $ilLog = $DIC["ilLog"];
271 $lng = $DIC->language();
272
273 $item_type = \ilSkillTreeNode::_lookupType($a_item_id);
274
275 $item = null;
276 if ($item_type == "scat") {
277 $item = new \ilSkillCategory($a_item_id);
278 } elseif ($item_type == "skll") {
279 $item = new \ilBasicSkill($a_item_id);
280 } elseif ($item_type == "sktr") {
281 $item = new \ilSkillTemplateReference($a_item_id);
282 } elseif ($item_type == "sktp") {
283 $item = new \ilBasicSkillTemplate($a_item_id);
284 } elseif ($item_type == "sctp") {
285 $item = new \ilSkillTemplateCategory($a_item_id);
286 }
287
288 $ilLog->write("Getting from clipboard type " . $item_type . ", " .
289 "Item ID: " . $a_item_id);
290
291 if ($a_as_copy) {
292 $target_item = $item->copy();
293 if ($a_add_suffix) {
294 $target_item->setTitle($target_item->getTitle() . " " . $lng->txt("copy_of_suffix"));
295 $target_item->update();
296 }
297 $a_copied_nodes[$item->getId()] = $target_item->getId();
298 } else {
299 $target_item = $item;
300 }
301
302 $ilLog->write("Putting into skill tree type " . $target_item->getType() .
303 "Item ID: " . $target_item->getId() . ", Parent: " . $a_parent_id . ", " .
304 "Target: " . $a_target);
305
306 $this->putIntoTree($target_item, $a_parent_id, $a_target);
307
308 $childs = $ilUser->getClipboardChilds($item->getId(), $a_insert_time);
309
310 foreach ($childs as $child) {
311 $this->pasteTree(
312 (int) $child["id"],
313 $target_item->getId(),
315 $a_insert_time,
316 $a_copied_nodes,
317 $a_as_copy
318 );
319 }
320
321 return $target_item->getId();
322 }
323
324 public function saveChildsOrder(int $a_par_id, array $a_childs_order, bool $a_templates = false): void
325 {
326 $skill_tree = $this->tree;
327
328 if ($a_par_id != $skill_tree->readRootId()) {
329 $childs = $skill_tree->getChilds($a_par_id);
330 } else {
331 if ($a_templates) {
332 $childs = $skill_tree->getChildsByTypeFilter(
333 $a_par_id,
334 array("skrt", "sktp", "sctp")
335 );
336 } else {
337 $childs = $skill_tree->getChildsByTypeFilter(
338 $a_par_id,
339 array("skrt", "skll", "scat", "sktr")
340 );
341 }
342 }
343
344 foreach ($childs as $k => $c) {
345 if (isset($a_childs_order[$c["child"]])) {
346 $childs[$k]["order_nr"] = (int) $a_childs_order[$c["child"]];
347 }
348 }
349
350 $childs = ilArrayUtil::sortArray($childs, "order_nr", "asc", true);
351
352 $cnt = 10;
353 foreach ($childs as $c) {
354 \ilSkillTreeNode::_writeOrderNr((int) $c["child"], $cnt);
355 $cnt += 10;
356 }
357 }
358
362 public function getTopTemplates(): array
363 {
364 return $this->tree->getChildsByTypeFilter(
365 $this->tree->readRootId(),
366 array("sktp", "sctp")
367 );
368 }
369}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
putIntoTree(\ilSkillTreeNode $node, int $parent_node_id, int $a_target_node_id=0)
insertItemsFromClip(string $a_type, int $a_obj_id)
Insert basic skills from clipboard.
getTopTemplates()
Get top skill templates and template categories.
clipboardCopy(array $a_ids)
Copy a set of skills/skill categories into the clipboard.
static clearClipboard()
Remove all skill items from clipboard.
pasteTree(int $a_item_id, int $a_parent_id, int $a_target, string $a_insert_time, array &$a_copied_nodes, bool $a_as_copy=false, bool $a_add_suffix=false)
Paste item (tree) from clipboard to skill tree.
saveChildsOrder(int $a_par_id, array $a_childs_order, bool $a_templates=false)
clipboardCut(array $a_ids)
Cut and copy a set of skills/skill categories into the clipboard.
__construct(int $skill_tree_id, Tree\SkillTreeFactory $tree_factory)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static sortArray(array $array, string $a_array_sortby_key, string $a_array_sortorder="asc", bool $a_numeric=false, bool $a_keep_keys=false)
static setAction(string $a_action)
A node in the skill tree.
static _lookupTitle(int $a_obj_id, int $a_tref_id=0)
static _writeOrderNr(int $a_obj_id, int $a_nr)
static _lookupType(int $a_obj_id)
getMaxOrderNr(int $a_par_id, bool $a_templates=false)
isInTree(?int $a_node_id)
get all information of a node.
insertNode(int $a_node_id, int $a_parent_id, int $a_pos=self::POS_LAST_NODE, bool $a_reset_deletion_date=false)
insert new node with node_id under parent node with parent_id
getNodeData(int $a_node_id, ?int $a_tree_pk=null)
get all information of a node.
const POS_LAST_NODE
getChilds(int $a_node_id, string $a_order="", string $a_direction="ASC")
get child nodes of given node
getSubTree(array $a_node, bool $a_with_data=true, array $a_type=[])
get all nodes in the subtree under specified node
deleteTree(array $a_node)
delete node and the whole subtree under this node
const POS_FIRST_NODE
getPathId(int $a_endnode_id, int $a_startnode_id=0)
get path from a given startnode to a given endnode if startnode is not given the rootnode is startnod...
$c
Definition: deliver.php:25
$path
Definition: ltiservices.php:30
global $lng
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26