ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.SkillTreeNodeManager.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\Skill\Node;
22 
23 use 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  {
49  $tree = $this->tree;
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) {
78  $target = \ilTree::POS_FIRST_NODE;
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) {
122  $path = $tree->getPathId($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 }
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:25
static _lookupType(int $a_obj_id)
$path
Definition: ltiservices.php:29
clipboardCut(array $a_ids)
Cut and copy a set of skills/skill categories into the clipboard.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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:22
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:23
global $lng
Definition: privfeed.php:31
A node in the skill tree.
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)