/**
  * Constructor
  */
 function __construct($a_parent_obj, $a_parent_cmd, $a_sn_id, $a_se = null)
 {
     global $ilCtrl, $lng, $ilAccess, $lng;
     $this->sn_id = $a_sn_id;
     if ($a_se != null) {
         $this->se = $a_se;
         $this->levels = $this->se->getLevels();
     }
     // build title
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $stree = new ilSkillTree();
     $path = $stree->getPathFull($this->sn_id);
     $title = $sep = "";
     foreach ($path as $p) {
         if ($p["type"] != "skrt") {
             $title .= $sep . $p["title"];
             $sep = " > ";
         }
     }
     parent::__construct($a_parent_obj, $a_parent_cmd);
     $this->setData($this->getLevels());
     $this->setTitle($title);
     $this->setLimit(9999);
     $this->addColumn($this->lng->txt("skmg_your_self_evaluation"));
     $this->addColumn($this->lng->txt("skmg_skill_level"));
     $this->setEnableHeader(true);
     //		$this->setFormAction($ilCtrl->getFormAction($a_parent_obj));
     $this->setRowTemplate("tpl.self_eval_row.html", "Services/Skill");
     $this->disable("footer");
     $this->setEnableTitle(true);
     //		$this->addMultiCommand("", $lng->txt(""));
     //		$this->addCommandButton("", $lng->txt(""));
 }
 /**
  * Constructor
  */
 function __construct($a_parent_obj, $a_parent_cmd, $a_cskill_id, $a_usage)
 {
     global $ilCtrl, $lng, $ilAccess, $lng;
     $id_parts = explode(":", $a_cskill_id);
     $this->skill_id = $id_parts[0];
     $this->tref_id = $id_parts[1];
     $data = array();
     foreach ($a_usage as $k => $v) {
         $data[] = array("type" => $k, "usages" => $v);
     }
     parent::__construct($a_parent_obj, $a_parent_cmd);
     $this->setData($data);
     $this->setTitle(ilSkillTreeNode::_lookupTitle($this->skill_id, $this->tref_id));
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $tree = new ilSkillTree();
     $path = $tree->getSkillTreePathAsString($this->skill_id, $this->tref_id);
     $this->setDescription($path);
     $this->addColumn($this->lng->txt("skmg_type"), "", "50%");
     $this->addColumn($this->lng->txt("skmg_number"), "", "50%");
     $this->setFormAction($ilCtrl->getFormAction($a_parent_obj));
     $this->setRowTemplate("tpl.skill_usage_row.html", "Services/Skill");
     $this->setEnableNumInfo(false);
     //		$this->addMultiCommand("", $lng->txt(""));
     //		$this->addCommandButton("", $lng->txt(""));
 }
 /**
  * Constructor
  */
 function __construct($a_parent_obj, $a_parent_cmd, $a_top_skill_id, $a_tref_id, $a_basic_skill_id)
 {
     global $ilCtrl, $lng, $ilAccess, $lng, $ilUser;
     $this->top_skill_id = $a_top_skill_id;
     $this->tref_id = (int) $a_tref_id;
     $this->basic_skill_id = $a_basic_skill_id;
     $this->cur_level_id = ilPersonalSkill::getSelfEvaluation($ilUser->getId(), $this->top_skill_id, $this->tref_id, $this->basic_skill_id);
     // build title
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $stree = new ilSkillTree();
     $path = $stree->getPathFull($this->basic_skill_id);
     $title = $sep = "";
     foreach ($path as $p) {
         if ($p["type"] != "skrt") {
             $title .= $sep . $p["title"];
             $sep = " > ";
         }
     }
     parent::__construct($a_parent_obj, $a_parent_cmd);
     $this->setData($this->getLevels());
     $this->setTitle($title);
     $this->setLimit(9999);
     $this->addColumn("", "", "", true);
     $this->addColumn($this->lng->txt("skmg_skill_level"));
     $this->addColumn($this->lng->txt("description"));
     $this->setEnableHeader(true);
     $this->setRowTemplate("tpl.simple_self_eval.html", "Services/Skill");
     $this->disable("footer");
     $this->setEnableTitle(true);
     $this->addCommandButton("saveSelfEvaluation", $lng->txt("save"));
     $this->setFormAction($ilCtrl->getFormAction($a_parent_obj));
 }
 /**
  * Get personal selected user skills
  *
  * @param int $a_user_id user id
  * @return array 
  */
 static function getSelectedUserSkills($a_user_id)
 {
     global $ilDB;
     include_once "Services/Skill/classes/class.ilSkillTreeNode.php";
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $stree = new ilSkillTree();
     $set = $ilDB->query("SELECT * FROM skl_personal_skill " . " WHERE user_id = " . $ilDB->quote($a_user_id, "integer"));
     $pskills = array();
     while ($rec = $ilDB->fetchAssoc($set)) {
         if ($stree->isInTree($rec["skill_node_id"])) {
             $pskills[$rec["skill_node_id"]] = array("skill_node_id" => $rec["skill_node_id"], "title" => ilSkillTreeNode::_lookupTitle($rec["skill_node_id"]));
         }
     }
     return $pskills;
 }
 /**
  * Constructor
  */
 function __construct($a_parent_obj, $a_parent_cmd, $a_top_skill_id, $a_tref_id, $a_basic_skill_id)
 {
     global $ilUser;
     include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
     include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php";
     $this->ws_tree = new ilWorkspaceTree($ilUser->getId());
     $this->ws_access = new ilWorkspaceAccessHandler();
     $this->top_skill_id = $a_top_skill_id;
     $this->tref_id = (int) $a_tref_id;
     $this->basic_skill_id = $a_basic_skill_id;
     // workspace tree
     include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
     $this->ws_tree = new ilWorkspaceTree($ilUser->getId());
     // build title
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $stree = new ilSkillTree();
     $path = $stree->getPathFull($this->basic_skill_id);
     $title = $sep = "";
     foreach ($path as $p) {
         if ($p["type"] != "skrt") {
             $title .= $sep . $p["title"];
             $sep = " > ";
         }
     }
     parent::__construct($a_parent_obj, $a_parent_cmd);
     $this->setData($this->getLevels());
     $this->setTitle($title);
     $this->setLimit(9999);
     $this->addColumn($this->lng->txt("skmg_skill_level"));
     $this->addColumn($this->lng->txt("description"), "", "60%");
     $this->addColumn($this->lng->txt("skmg_materials"));
     $this->addColumn($this->lng->txt("actions"));
     $this->setEnableHeader(true);
     //		$this->setFormAction($ilCtrl->getFormAction($a_parent_obj));
     $this->setRowTemplate("tpl.skill_materials_row.html", "Services/Skill");
     $this->disable("footer");
     $this->setEnableTitle(true);
     //		$this->addMultiCommand("", $lng->txt(""));
     //		$this->addCommandButton("", $lng->txt(""));
 }
 public function loadAdditionalSkillData()
 {
     require_once 'Services/Skill/classes/class.ilBasicSkill.php';
     require_once 'Services/Skill/classes/class.ilSkillTree.php';
     $this->setSkillTitle(ilBasicSkill::_lookupTitle($this->getSkillBaseId(), $this->getSkillTrefId()));
     $tree = new ilSkillTree();
     $path = $tree->getSkillTreePath($this->getSkillBaseId(), $this->getSkillTrefId());
     $nodes = array();
     foreach ($path as $node) {
         if ($node['child'] > 1 && $node['skill_id'] != $this->getSkillBaseId()) {
             $nodes[] = $node['title'];
         }
     }
     $this->setSkillPath(implode(' > ', $nodes));
 }
 /**
  * Get gap analysis html
  *
  * @param
  * @return
  */
 function getGapAnalysisHTML($a_user_id = 0, $a_skills = null)
 {
     global $ilUser, $lng;
     //		$this->setTabs("list_skills");
     if ($a_user_id == 0) {
         $user_id = $ilUser->getId();
     } else {
         $user_id = $a_user_id;
     }
     $skills = array();
     if ($this->getProfileId() > 0) {
         $profile = new ilSkillProfile($this->getProfileId());
         $this->profile_levels = $profile->getSkillLevels();
         foreach ($this->profile_levels as $l) {
             $skills[] = array("base_skill_id" => $l["base_skill_id"], "tref_id" => $l["tref_id"], "level_id" => $l["level_id"]);
         }
     } else {
         if (is_array($a_skills)) {
             $skills = $a_skills;
         }
     }
     // get actual levels for gap analysis
     $this->actual_levels = array();
     include_once "./Services/Skill/classes/class.ilBasicSkill.php";
     foreach ($skills as $sk) {
         $bs = new ilBasicSkill($sk["base_skill_id"]);
         if ($this->gap_mode == "max_per_type") {
             $max = $bs->getMaxLevelPerType($sk["tref_id"], $this->gap_mode_type, $user_id);
             $this->actual_levels[$sk["base_skill_id"]][$sk["tref_id"]] = $max;
         } else {
             if ($this->gap_mode == "max_per_object") {
                 $max = $bs->getMaxLevelPerObject($sk["tref_id"], $this->gap_mode_obj_id, $user_id);
                 $this->actual_levels[$sk["base_skill_id"]][$sk["tref_id"]] = $max;
             }
         }
     }
     $incl_self_eval = false;
     if (count($this->getGapAnalysisSelfEvalLevels() > 0)) {
         $incl_self_eval = true;
         $self_vals = $this->getGapAnalysisSelfEvalLevels();
     }
     // output spider stuff
     if (count($skills) >= 3) {
         $max_cnt = 0;
         $leg_labels = array();
         //var_dump($this->profile_levels);
         //foreach ($this->profile_levels as $k => $l)
         // write target, actual and self counter to skill array
         foreach ($skills as $k => $l) {
             //$bs = new ilBasicSkill($l["base_skill_id"]);
             $bs = new ilBasicSkill($l["base_skill_id"]);
             $leg_labels[] = $bs->getTitle();
             $levels = $bs->getLevelData();
             $cnt = 0;
             foreach ($levels as $lv) {
                 $cnt++;
                 if ($l["level_id"] == $lv["id"]) {
                     $skills[$k]["target_cnt"] = $cnt;
                 }
                 if ($this->actual_levels[$l["base_skill_id"]][$l["tref_id"]] == $lv["id"]) {
                     $skills[$k]["actual_cnt"] = $cnt;
                 }
                 if ($incl_self_eval) {
                     if ($self_vals[$l["base_skill_id"]][$l["tref_id"]] == $lv["id"]) {
                         $skills[$k]["self_cnt"] = $cnt;
                     }
                 }
                 $max_cnt = max($max_cnt, $cnt);
             }
         }
         //			$leg_labels = array("AAAAA", "BBBBB", "CCCCC");
         //var_dump($this->profile_levels);
         //var_dump($this->actual_levels);
         include_once "./Services/Chart/classes/class.ilChart.php";
         $chart = new ilChart("gap_chart", 600, 300);
         $chart->setYAxisMax($max_cnt);
         $chart->setLegLabels($leg_labels);
         // target level
         $cd = new ilChartData("spider");
         $cd->setLabel($lng->txt("skmg_target_level"));
         $cd->setFill("true", "#A0A0A0");
         // other users
         $cd2 = new ilChartData("spider");
         if ($this->gap_cat_title != "") {
             $cd2->setLabel($this->gap_cat_title);
         } else {
             if ($this->gap_mode == "max_per_type") {
                 $cd2->setLabel($lng->txt("objs_" . $this->gap_mode_type));
             } else {
                 if ($this->gap_mode == "max_per_object") {
                     $cd2->setLabel(ilObject::_lookupTitle($this->gap_mode_obj_id));
                 }
             }
         }
         $cd2->setFill("true", "#8080FF");
         // self evaluation
         if ($incl_self_eval) {
             $cd3 = new ilChartData("spider");
             $cd3->setLabel($lng->txt("skmg_self_evaluation"));
             $cd3->setFill("true", "#FF8080");
         }
         // fill in data
         $cnt = 0;
         foreach ($skills as $pl) {
             $cd->addPoint($cnt, (int) $pl["target_cnt"]);
             $cd2->addPoint($cnt, (int) $pl["actual_cnt"]);
             if ($incl_self_eval) {
                 $cd3->addPoint($cnt, (int) $pl["self_cnt"]);
             }
             $cnt++;
         }
         // add data to chart
         if ($this->getProfileId() > 0) {
             $chart->addData($cd);
         }
         $chart->addData($cd2);
         if ($incl_self_eval && count($this->getGapAnalysisSelfEvalLevels()) > 0) {
             $chart->addData($cd3);
         }
         $lg = new ilChartLegend();
         $chart->setLegend($lg);
         $chart_html = $chart->getHTML();
     }
     $stree = new ilSkillTree();
     $html = "";
     foreach ($skills as $s) {
         $path = $stree->getSkillTreePath($s["base_skill_id"]);
         // check draft
         foreach ($path as $p) {
             if ($p["draft"]) {
                 continue 2;
             }
         }
         $html .= $this->getSkillHTML($s["base_skill_id"], $user_id, false, $s["tref_id"]);
     }
     // list skills
     //		include_once("./Services/Skill/classes/class.ilPersonalSkillTableGUI.php");
     //		$sktab = new ilPersonalSkillTableGUI($this, "listSkills");
     return $chart_html . $html;
 }
 /**
  * LIst skills for adding
  *
  * @param
  * @return
  */
 function listSkillsForAdd()
 {
     global $ilUser, $tpl, $ilCtrl, $lng, $ilTabs;
     ilUtil::sendInfo($lng->txt("skmg_select_skill"));
     $ilTabs->setBackTarget($lng->txt("back"), $ilCtrl->getLinkTarget($this, ""));
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $skill_tree = new ilSkillTree();
     require_once "./Services/Skill/classes/class.ilPersonalSkillExplorer.php";
     $exp = new ilPersonalSkillExplorer($ilCtrl->getLinkTarget($this, "listSkillsForAdd"));
     $exp->setTargetGet("obj_id");
     $exp->setExpandTarget($ilCtrl->getLinkTarget($this, "listSkillsForAdd"));
     if ($_GET["skpexpand"] == "") {
         $expanded = $skill_tree->readRootId();
     } else {
         $expanded = $_GET["skpexpand"];
     }
     if ($_GET["obj_id"] > 0) {
         $path = $this->skill_tree->getPathId($_GET["obj_id"]);
         $exp->setForceOpenPath($path);
         $exp->highlightNode($_GET["obj_id"]);
     } else {
         $exp->highlightNode($this->skill_tree->readRootId());
     }
     $exp->setExpand($expanded);
     // build html-output
     $exp->setOutput(0);
     $output = $exp->getOutput();
     // asynchronous output
     if ($ilCtrl->isAsynch()) {
         echo $output;
         exit;
     }
     $tpl->setContent($output);
 }
 /**
  * Determine steps
  *
  * @param
  * @return
  */
 static function determineSteps($a_sn_id)
 {
     $steps = array();
     if ($a_sn_id > 0) {
         include_once "./Services/Skill/classes/class.ilSkillTree.php";
         include_once "./Services/Skill/classes/class.ilSkillSelfEvalSkillTableGUI.php";
         $stree = new ilSkillTree();
         if ($stree->isInTree($a_sn_id)) {
             $cnode = $stree->getNodeData($a_sn_id);
             $childs = $stree->getSubTree($cnode);
             foreach ($childs as $child) {
                 if ($child["type"] == "skll") {
                     $steps[] = $child["child"];
                 }
             }
         }
     }
     return $steps;
 }
 /**
  * Set Locator Items
  */
 function setLocator()
 {
     global $ilLocator, $tpl, $ilCtrl;
     $ilLocator->addRepositoryItems($_GET["ref_id"]);
     $this->getParentGUI()->addLocatorItems();
     if ($_GET["obj_id"] > 0) {
         include_once "./Services/Skill/classes/class.ilSkillTree.php";
         $tree = new ilSkillTree();
         $path = $tree->getPathFull($_GET["obj_id"]);
         for ($i = 1; $i < count($path); $i++) {
             switch ($path[$i]["type"]) {
                 case "scat":
                     $ilCtrl->setParameterByClass("ilskillcategorygui", "obj_id", $path[$i]["child"]);
                     $ilLocator->addItem($path[$i]["title"], $ilCtrl->getLinkTargetByClass("ilskillmanagementgui", "ilskillcategorygui"), "", 0, $path[$i]["type"], ilUtil::getImagePath("icon_skmg_s.png"));
                     break;
                 case "skll":
                     $ilCtrl->setParameterByClass("ilbasicskillgui", "obj_id", $path[$i]["child"]);
                     $ilLocator->addItem($path[$i]["title"], $ilCtrl->getLinkTargetByClass("ilskillmanagementgui", "ilbasicskillgui"), "", 0, $path[$i]["type"], ilUtil::getImagePath("icon_skmg_s.png"));
                     break;
             }
         }
     }
     $ilCtrl->setParameter($this, "obj_id", $_GET["obj_id"]);
     $tpl->setLocator();
 }
 /**
  * Save childs order
  *
  * @param
  * @return
  */
 static function saveChildsOrder($a_par_id, $a_childs_order, $a_templates = false)
 {
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $skill_tree = new ilSkillTree();
     if ($a_par_id != $skill_tree->readRootId()) {
         $childs = $skill_tree->getChilds($a_par_id);
     } else {
         if ($a_templates) {
             $childs = $skill_tree->getChildsByTypeFilter($a_par_id, array("skrt", "sktp", "sctp"));
         } else {
             $childs = $skill_tree->getChildsByTypeFilter($a_par_id, array("skrt", "skll", "scat", "sktr"));
         }
     }
     foreach ($childs as $k => $c) {
         if (isset($a_childs_order[$c["child"]])) {
             $childs[$k]["order_nr"] = (int) $a_childs_order[$c["child"]];
         }
     }
     $childs = ilUtil::sortArray($childs, "order_nr", "asc", true);
     $cnt = 10;
     foreach ($childs as $c) {
         ilSkillTreeNode::_writeOrderNr($c["child"], $cnt);
         $cnt += 10;
     }
 }
 /**
  * Find skills
  *
  * @param
  * @return
  */
 public static function findSkills($a_term)
 {
     global $ilDB;
     $res = array();
     $candidates = array();
     $skill_tree = new ilSkillTree();
     $sql = "SELECT * " . " FROM skl_tree_node" . " WHERE " . $ilDB->like("title", "text", "%" . $a_term . "%");
     $sql .= " ORDER BY title";
     $set = $ilDB->query($sql);
     include_once "./Services/Skill/classes/class.ilSkillTemplateReference.php";
     while ($row = $ilDB->fetchAssoc($set)) {
         if (in_array($row["type"], array("sctp", "sktp"))) {
             // need to get "top template" first! (if it is already the top level, do not use it!)
             $path = $skill_tree->getSkillTreePath($row["obj_id"]);
             if ($path[1]["child"] != $row["obj_id"]) {
                 $trefs = ilSkillTemplateReference::_lookupTrefIdsForTopTemplateId($path[1]["child"]);
                 foreach ($trefs as $tref) {
                     $candidates[] = array("tref_id" => $tref, "skill_id" => $row["obj_id"], "title" => $row["title"]);
                 }
             }
         } else {
             if ($row["type"] == "sktr") {
                 // works
                 $candidates[] = array("tref_id" => $row["obj_id"], "skill_id" => ilSkillTemplateReference::_lookupTemplateId($row["obj_id"]), "title" => $row["title"]);
             } else {
                 // works
                 $candidates[] = array("tref_id" => 0, "skill_id" => $row["obj_id"], "title" => $row["title"]);
             }
         }
     }
     foreach ($candidates as $c) {
         // if we get a path array, and the array has items try to use the data
         $path = $skill_tree->getSkillTreePath($c["skill_id"], $c["tref_id"]);
         $use = false;
         if (is_array($path) && count($path) > 0) {
             $use = true;
         }
         // if any inactive/outdated -> do not use the data
         if (is_array($path)) {
             foreach ($path as $p) {
                 if ($p["status"] > 0) {
                     $use = false;
                 }
             }
         }
         if ($use) {
             if (!in_array($c["title"], $res)) {
                 $res[] = $c["title"];
             }
         }
     }
     return $res;
 }
 /**
  * Set header for level
  */
 function setLevelHead()
 {
     global $ilTabs, $ilCtrl, $tpl, $lng, $ilHelp;
     // tabs
     $ilTabs->clearTargets();
     $ilHelp->setScreenIdComponent("skmg_lev");
     $ilTabs->setBackTarget($lng->txt("back"), $ilCtrl->getLinkTarget($this, "edit"));
     if ($_GET["level_id"] > 0) {
         $ilTabs->addTab("level_settings", $lng->txt("settings"), $ilCtrl->getLinkTarget($this, "editLevel"));
         /*			$ilTabs->addTab("level_trigger",
         				$lng->txt("skmg_trigger"),
         				$ilCtrl->getLinkTarget($this, "editLevelTrigger"));*/
         $ilTabs->addTab("level_resources", $lng->txt("skmg_resources"), $ilCtrl->getLinkTarget($this, "showLevelResources"));
         /*
         			$ilTabs->addTab("level_certificate",
         				$lng->txt("certificate"),
         				$ilCtrl->getLinkTargetByClass("ilcertificategui", "certificateEditor"));*/
     }
     // title
     if ($_GET["level_id"] > 0) {
         $tpl->setTitle($lng->txt("skmg_skill_level") . ": " . ilBasicSkill::lookupLevelTitle((int) $_GET["level_id"]));
     } else {
         $tpl->setTitle($lng->txt("skmg_skill_level"));
     }
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $tree = new ilSkillTree();
     $path = $tree->getPathFull($this->node_object->getId());
     $desc = "";
     foreach ($path as $p) {
         if (in_array($p["type"], array("scat", "skll"))) {
             $desc .= $sep . $p["title"];
             $sep = " > ";
         }
     }
     $tpl->setDescription($desc);
 }
 /**
  * Get all tref ids for a template id
  *
  * @param int $a_tid template node id (node id in template tree)
  * @return array of ids
  */
 static function _lookupTrefIdsForTemplateId($a_tid)
 {
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $tree = new ilSkillTree();
     $top_template_id = $tree->getTopParentNodeId($a_tid);
     return self::_lookupTrefIdsForTopTemplateId($top_template_id);
 }
 /**
  * Assign Level
  */
 function assignLevel()
 {
     global $lng, $ilTabs, $ilCtrl, $tpl;
     $tpl->setTitle($lng->txt("skmg_profile") . ": " . $this->profile->getTitle());
     $tpl->setDescription("");
     //$this->setTabs("levels");
     ilUtil::sendInfo($lng->txt("skmg_select_skill_level_assign"));
     $ilTabs->clearTargets();
     $ilTabs->setBackTarget($lng->txt("back"), $ilCtrl->getLinkTarget($this, "showLevels"));
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $skill_tree = new ilSkillTree();
     require_once "./Services/Skill/classes/class.ilSkillProfileAssignmentExplorer.php";
     $exp = new ilSkillProfileAssignmentExplorer($ilCtrl->getLinkTarget($this, "assignLevel"));
     $exp->setTargetGet("level_id");
     $exp->setExpandTarget($ilCtrl->getLinkTarget($this, "assignLevel"));
     if ($_GET["skaexpand"] == "") {
         $expanded = $skill_tree->readRootId();
     } else {
         $expanded = $_GET["skaexpand"];
     }
     /*		if ($_GET["level_id"] > 0)
     		{
     			$path = $this->skill_tree->getPathId($_GET["obj_id"]);
     			$exp->setForceOpenPath($path);
     			$exp->highlightNode($_GET["obj_id"]);
     		}
     		else
     		{
     			$exp->highlightNode($this->skill_tree->readRootId());
     		}*/
     $exp->setExpand($expanded);
     // build html-output
     $exp->setOutput(0);
     $output = $exp->getOutput();
     // asynchronous output
     if ($ilCtrl->isAsynch()) {
         echo $output;
         exit;
     }
     $tpl->setContent($output);
 }
 /**
  * Execute Drag Drop Action
  *
  * @param	string	$source_id		Source element ID
  * @param	string	$target_id		Target element ID
  * @param	string	$first_child	Insert as first child of target
  * @param	string	$movecopy		Position ("move" | "copy")
  */
 function executeDragDrop($source_id, $target_id, $first_child, $as_subitem = false, $movecopy = "move")
 {
     include_once "./Services/Skill/classes/class.ilSkillTree.php";
     $tree = new ilSkillTree();
     include_once "./Services/Skill/classes/class.ilSkillTreeNodeFactory.php";
     $source_obj = ilSkillTreeNodeFactory::getInstance($source_id);
     if (!$first_child) {
         $target_obj = ilSkillTreeNodeFactory::getInstance($target_id);
         $target_parent = $tree->getParentId($target_id);
     }
     // handle skills
     if ($source_obj->getType() == "skll") {
         if ($tree->isInTree($source_obj->getId())) {
             $node_data = $tree->getNodeData($source_obj->getId());
             // cut on move
             if ($movecopy == "move") {
                 $parent_id = $tree->getParentId($source_obj->getId());
                 $tree->deleteTree($node_data);
             }
             // paste page
             if (!$tree->isInTree($source_obj->getId())) {
                 if ($first_child) {
                     $target_pos = IL_FIRST_NODE;
                     $parent = $target_id;
                 } else {
                     if ($as_subitem) {
                         $parent = $target_id;
                         $target_pos = IL_FIRST_NODE;
                         $childs = $tree->getChildsByType($parent, array("skll", "scat"));
                         if (count($childs) != 0) {
                             $target_pos = $childs[count($childs) - 1]["obj_id"];
                         }
                     } else {
                         $target_pos = $target_id;
                         $parent = $target_parent;
                     }
                 }
                 // insert skill into tree
                 $tree->insertNode($source_obj->getId(), $parent, $target_pos);
             }
         }
     }
     // handle skil categories
     if ($source_obj->getType() == "scat") {
         $source_node = $tree->getNodeData($source_id);
         $subnodes = $tree->getSubtree($source_node);
         // check, if target is within subtree
         foreach ($subnodes as $subnode) {
             if ($subnode["obj_id"] == $target_id) {
                 return;
             }
         }
         $target_pos = $target_id;
         if ($first_child) {
             $target_pos = IL_FIRST_NODE;
             $target_parent = $target_id;
         } else {
             if ($as_subitem) {
                 $target_parent = $target_id;
                 $target_pos = IL_FIRST_NODE;
                 $childs = $tree->getChilds($target_parent);
                 if (count($childs) != 0) {
                     $target_pos = $childs[count($childs) - 1]["obj_id"];
                 }
             }
         }
         // delete source tree
         if ($movecopy == "move") {
             $tree->deleteTree($source_node);
         }
         if (!$tree->isInTree($source_id)) {
             $tree->insertNode($source_id, $target_parent, $target_pos);
             // insert moved tree
             if ($movecopy == "move") {
                 foreach ($subnodes as $node) {
                     if ($node["obj_id"] != $source_id) {
                         $tree->insertNode($node["obj_id"], $node["parent"]);
                     }
                 }
             }
         }
     }
 }