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