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