4define(
"IL_LAST_NODE", -2);
 
    5define(
"IL_FIRST_NODE", -1);
 
    7include_once 
'./Services/Tree/exceptions/class.ilInvalidTreeStructureException.php';
 
  160        $this->lang_code = 
"en";
 
  165        if (!isset($a_tree_id) or (func_num_args() == 0)) {
 
  166            $this->log->error(
"No tree_id given!");
 
  168            throw new InvalidArgumentException(
"No tree_id given!");
 
  171        if (func_num_args() > 2) {
 
  172            $this->log->error(
"Wrong parameter count!");
 
  173            throw new InvalidArgumentException(
"Wrong parameter count!");
 
  177        if (empty($a_root_id)) {
 
  178            $a_root_id = ROOT_FOLDER_ID;
 
  181        $this->tree_id = $a_tree_id;
 
  182        $this->root_id = $a_root_id;
 
  183        $this->table_tree = 
'tree';
 
  184        $this->table_obj_data = 
'object_data';
 
  185        $this->table_obj_reference = 
'object_reference';
 
  186        $this->ref_pk = 
'ref_id';
 
  187        $this->obj_pk = 
'obj_id';
 
  188        $this->tree_pk = 
'tree';
 
  190        $this->use_cache = 
true;
 
  193        $this->translation_cache = array();
 
  194        $this->parent_type_cache = array();
 
  212        $db = 
$DIC->database();
 
  214        $query = 
'select tree from tree ' .
 
  220            $trees[] = $row->tree;
 
  232        if (!
$DIC->isDependencyAvailable(
'settings') || 
$DIC->settings()->getModule() != 
'common') {
 
  233            include_once 
'./Services/Administration/classes/class.ilSetting.php';
 
  236            $setting = 
$DIC->settings();
 
  240            if ($setting->get(
'main_tree_impl', 
'ns') == 
'ns') {
 
  241                #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Using nested set.'); 
  242                include_once 
'./Services/Tree/classes/class.ilNestedSetTree.php';
 
  245                #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Using materialized path.'); 
  246                include_once 
'./Services/Tree/classes/class.ilMaterializedPathTree.php';
 
  250            #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Using netsted set for non main tree.'); 
  251            include_once 
'./Services/Tree/classes/class.ilNestedSetTree.php';
 
  270        $this->use_cache = $a_use;
 
  311            $this->lang_code = 
$ilUser->getCurrentLanguage();
 
  312        } 
catch (\InvalidArgumentException 
$e) {
 
  313            $this->lang_code = 
"en";
 
  365        $this->in_tree_cache = array();
 
  385    public function setTableNames($a_table_tree, $a_table_obj_data, $a_table_obj_reference = 
"")
 
  387        if (!isset($a_table_tree) or !isset($a_table_obj_data)) {
 
  389                                "tree table: " . $a_table_tree . 
" object data table: " . $a_table_obj_data;
 
  391            throw new InvalidArgumentException(
$message);
 
  394        $this->table_tree = $a_table_tree;
 
  395        $this->table_obj_data = $a_table_obj_data;
 
  396        $this->table_obj_reference = $a_table_obj_reference;
 
  412        if (!isset($a_column_name)) {
 
  415            throw new InvalidArgumentException(
$message);
 
  418        $this->ref_pk = $a_column_name;
 
  431        if (!isset($a_column_name)) {
 
  434            throw new InvalidArgumentException(
$message);
 
  437        $this->obj_pk = $a_column_name;
 
  450        if (!isset($a_column_name)) {
 
  453            throw new InvalidArgumentException(
$message);
 
  456        $this->tree_pk = $a_column_name;
 
  467        if ($this->table_obj_reference) {
 
  469            return "JOIN " . $this->table_obj_reference . 
" ON " . $this->table_tree . 
".child=" . $this->table_obj_reference . 
"." . $this->ref_pk . 
" " .
 
  470                   "JOIN " . $this->table_obj_data . 
" ON " . $this->table_obj_reference . 
"." . $this->obj_pk . 
"=" . $this->table_obj_data . 
"." . $this->obj_pk . 
" ";
 
  473            return "JOIN " . $this->table_obj_data . 
" ON " . $this->table_tree . 
".child=" . $this->table_obj_data . 
"." . $this->obj_pk . 
" ";
 
  513        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
  514                'WHERE parent = ' . 
$ilDB->quote($a_node, 
'integer') . 
' ' .
 
  515                'AND tree = ' . 
$ilDB->quote($this->tree_id, 
'integer' . 
' ' .
 
  521            $childs[] = $row->child;
 
  535    public function getChilds($a_node_id, $a_order = 
"", $a_direction = 
"ASC")
 
  541        $ilObjDataCache = 
$DIC[
'ilObjDataCache'];
 
  544        if (!isset($a_node_id)) {
 
  547            throw new InvalidArgumentException(
$message);
 
  560        if (!empty($a_order)) {
 
  561            $order_clause = 
"ORDER BY " . $a_order . 
" " . $a_direction;
 
  563            $order_clause = 
"ORDER BY " . $this->table_tree . 
".lft";
 
  568            'SELECT * FROM ' . $this->table_tree . 
' ' .
 
  570                "WHERE parent = %s " .
 
  571                "AND " . $this->table_tree . 
"." . $this->tree_pk . 
" = %s " .
 
  573            $ilDB->quote($a_node_id, 
'integer'),
 
  574            $ilDB->quote($this->tree_id, 
'integer')
 
  579        if (!$count = 
$res->numRows()) {
 
  587            $obj_ids[] = $r[
"obj_id"];
 
  592            is_object(
$ilUser) && $this->lang_code == 
$ilUser->getLanguage() && !$this->oc_preloaded[$a_node_id]) {
 
  594            $ilObjDataCache->preloadObjectCache($obj_ids, $this->lang_code);
 
  596            $this->oc_preloaded[$a_node_id] = 
true;
 
  599        foreach (
$rows as $row) {
 
  604                #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Storing in tree cache '.$row['child'].' = true'); 
  605                $this->in_tree_cache[$row[
'child']] = $row[
'tree'] == 1;
 
  608        $childs[$count - 1][
"last"] = 
true;
 
  623        $childs = $this->
getChilds($a_node, $a_order, $a_direction);
 
  625        foreach ($childs as $child) {
 
  626            if (!in_array($child[
"type"], $a_filter)) {
 
  627                $filtered[] = $child;
 
  630        return $filtered ? $filtered : array();
 
  648        if (!isset($a_node_id) or !isset(
$a_type)) {
 
  649            $message = 
"Missing parameter! node_id:" . $a_node_id . 
" type:" . 
$a_type;
 
  651            throw new InvalidArgumentException(
$message);
 
  654        if (
$a_type == 
'rolf' && $this->table_obj_reference) {
 
  658            $ilDB->setLimit(1, 0);
 
  660                "SELECT * FROM " . $this->table_tree . 
" " .
 
  662                "WHERE parent = %s " .
 
  663                "AND " . $this->table_tree . 
"." . $this->tree_pk . 
" = %s " .
 
  664                "AND " . $this->table_obj_data . 
".type = %s ",
 
  665                $ilDB->quote($a_node_id, 
'integer'),
 
  666                $ilDB->quote($this->tree_id, 
'integer'),
 
  671                "SELECT * FROM " . $this->table_tree . 
" " .
 
  673                "WHERE parent = %s " .
 
  674                "AND " . $this->table_tree . 
"." . $this->tree_pk . 
" = %s " .
 
  675                "AND " . $this->table_obj_data . 
".type = %s " .
 
  676                "ORDER BY " . $this->table_tree . 
".lft",
 
  677                $ilDB->quote($a_node_id, 
'integer'),
 
  678                $ilDB->quote($this->tree_id, 
'integer'),
 
  690        return $childs ? $childs : array();
 
  708        if (!isset($a_node_id) or !$a_types) {
 
  709            $message = 
"Missing parameter! node_id:" . $a_node_id . 
" type:" . $a_types;
 
  711            throw new InvalidArgumentException(
$message);
 
  716            $filter = 
'AND ' . $this->table_obj_data . 
'.type IN(' . implode(
',', 
ilUtil::quoteArray($a_types)) . 
') ';
 
  720        if (!empty($a_order)) {
 
  721            $order_clause = 
"ORDER BY " . $a_order . 
" " . $a_direction;
 
  723            $order_clause = 
"ORDER BY " . $this->table_tree . 
".lft";
 
  726        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
  728            'WHERE parent = ' . 
$ilDB->quote($a_node_id, 
'integer') . 
' ' .
 
  729            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = ' . 
$ilDB->quote($this->tree_id, 
'integer') . 
' ' .
 
  738        return $childs ? $childs : array();
 
  759            if ($a_source_id <= 1 or $a_target_id <= 0) {
 
  761                throw new InvalidArgumentException(
'Invalid parameter given for ilTree::insertNodeFromTrash');
 
  764        if (!isset($a_source_id) or !isset($a_target_id)) {
 
  766            throw new InvalidArgumentException(
'Missing parameter for ilTree::insertNodeFromTrash');
 
  768        if ($this->
isInTree($a_source_id)) {
 
  771            throw new InvalidArgumentException(
'Node already in tree.');
 
  774        $query = 
'DELETE from tree ' .
 
  775                'WHERE tree = ' . 
$ilDB->quote($a_tree_id, 
'integer') . 
' ' .
 
  776                'AND child = ' . 
$ilDB->quote($a_source_id, 
'integer');
 
  800            if ($a_node_id <= 1 or $a_parent_id <= 0) {
 
  802                    'Invalid parameters! $a_node_id: %s $a_parent_id: %s',
 
  807                throw new InvalidArgumentException(
$message);
 
  812        if (!isset($a_node_id) or !isset($a_parent_id)) {
 
  814            throw new InvalidArgumentException(
"Missing parameter! " .
 
  815                "node_id: " . $a_node_id . 
" parent_id: " . $a_parent_id);
 
  818            throw new InvalidArgumentException(
"Node " . $a_node_id . 
" already in tree " .
 
  819                                     $this->table_tree . 
"!");
 
  824        $this->in_tree_cache[$a_node_id] = 
true;
 
  827        if ($a_reset_deletion_date) {
 
  832            $GLOBALS[
'DIC'][
'ilAppEventHandler']->raise(
 
  836                        'tree' => $this->table_tree,
 
  837                        'node_id' => $a_node_id,
 
  838                        'parent_id' => $a_parent_id)
 
  861        foreach ($this->
getSubTree($node) as $subnode) {
 
  862            if ($depth and $subnode[
'depth'] > $depth) {
 
  865            if (!$first and in_array($subnode[
'type'], $a_filter)) {
 
  866                $depth = $subnode[
'depth'];
 
  872            $filtered[] = $subnode;
 
  874        return $filtered ? $filtered : array();
 
  903        if (!is_array($a_node)) {
 
  905            throw new InvalidArgumentException(__METHOD__ . 
': wrong datatype for node data given');
 
  927                $subtree[] = $row[
'child'];
 
  930            if ($this->
__isMainTree() || $this->table_tree == 
"lm_tree") {
 
  931                $this->in_tree_cache[$row[
'child']] = 
true;
 
  934        return $subtree ? $subtree : array();
 
  947        $a_filter = $a_filter ? $a_filter : array();
 
  949        foreach ($this->getSubtree($this->
getNodeData($a_node)) as $node) {
 
  950            if (in_array($node[
"type"], $a_filter)) {
 
  953            $types[
"$node[type]"] = $node[
"type"];
 
  955        return $types ? $types : array();
 
  971        $this->log->debug(
'Delete tree with node ' . $a_node);
 
  973        if (!is_array($a_node)) {
 
  975            throw new InvalidArgumentException(__METHOD__ . 
': Wrong datatype for node data!');
 
  978        $this->log->debug($this->tree_pk);
 
 1015        $pathIds = $this->
getPathId($a_endnode_id, $a_startnode_id);
 
 1023        if (count($pathIds) == 0) {
 
 1027        $inClause = 
'child IN (';
 
 1028        for (
$i = 0; 
$i < count($pathIds); 
$i++) {
 
 1032            $inClause .= 
$ilDB->quote($pathIds[
$i], 
'integer');
 
 1037            'FROM ' . $this->table_tree . 
' ' .
 
 1039            'WHERE ' . $inClause . 
' ' .
 
 1040            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = ' . $this->ilDB->quote($this->tree_id, 
'integer') . 
' ' .
 
 1042        $r = 
$ilDB->query($q);
 
 1044        $pathFull = array();
 
 1050                #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Storing in tree cache '.$row['child']); 
 1051                $this->in_tree_cache[$row[
'child']] = $row[
'tree'] == 1;
 
 1074        $res = 
$ilDB->query(
'SELECT t.depth, t.parent, t.child ' .
 
 1075            'FROM ' . $this->table_tree . 
' t ' .
 
 1076            'WHERE ' . 
$ilDB->in(
"child", $a_node_ids, 
false, 
"integer") .
 
 1077            'AND ' . $this->tree_pk . 
' = ' . 
$ilDB->quote($this->tree_id, 
"integer"));
 
 1078        while ($row = 
$ilDB->fetchAssoc(
$res)) {
 
 1079            $this->depth_cache[$row[
"child"]] = $row[
"depth"];
 
 1080            $this->parent_cache[$row[
"child"]] = $row[
"parent"];
 
 1093    public function getPathId($a_endnode_id, $a_startnode_id = 0)
 
 1095        if (!$a_endnode_id) {
 
 1097            throw new InvalidArgumentException(__METHOD__ . 
': No endnode given!');
 
 1101        if ($this->
isCacheUsed() && isset($this->path_id_cache[$a_endnode_id][$a_startnode_id])) {
 
 1103            return $this->path_id_cache[$a_endnode_id][$a_startnode_id];
 
 1110            $this->path_id_cache[$a_endnode_id][$a_startnode_id] = $pathIds;
 
 1142        if ($titlePath == 
null || count($titlePath) == 0) {
 
 1143            if ($a_startnode_id == 0) {
 
 1151        if ($a_startnode_id != 
null && $a_startnode_id != 0) {
 
 1154            $parent = $a_startnode_id;
 
 1157            $nodePath = array();
 
 1165        require_once(
'include/Unicode/UtfNormal.php');
 
 1166        include_once 
'./Services/Utilities/classes/class.ilStr.php';
 
 1167        $inClause = 
'd.title IN (';
 
 1168        for (
$i = 0; 
$i < count($titlePath); 
$i++) {
 
 1173            $inClause .= 
$ilDB->quote($titlePath[
$i], 
'text');
 
 1178        if ($this->table_obj_reference) {
 
 1179            $joinClause = 
'JOIN ' . $this->table_obj_reference . 
'  r ON t.child = r.' . $this->ref_pk . 
' ' .
 
 1180                'JOIN ' . $this->table_obj_data . 
' d ON r.' . $this->obj_pk . 
' = d.' . 
$this->obj_pk;
 
 1182            $joinClause = 
'JOIN ' . $this->table_obj_data . 
'  d ON t.child = d.' . 
$this->obj_pk;
 
 1189        $q = 
'SELECT t.depth, t.parent, t.child, d.' . $this->obj_pk . 
' obj_id, d.type, d.title ' .
 
 1190            'FROM ' . $this->table_tree . 
'  t ' .
 
 1192            'WHERE ' . $inClause . 
' ' .
 
 1193            'AND t.depth <= ' . (count($titlePath) + count($nodePath)) . 
' ' .
 
 1195            'ORDER BY t.depth, t.child ASC';
 
 1196        $r = 
$ilDB->query($q);
 
 1201            $row[
'ref_id'] = $row[
'child'];
 
 1206        for (
$i = 0; 
$i < count($titlePath); 
$i++) {
 
 1207            $pathElementFound = 
false;
 
 1208            foreach (
$rows as $row) {
 
 1209                if ($row[
'parent'] == $parent &&
 
 1214                    $parent = $row[
'child'];
 
 1215                    $pathElementFound = 
true;
 
 1220            if (!$pathElementFound) {
 
 1253        $pathIds = $this->
getPathId($a_endnode_id, $a_startnode_id);
 
 1256        if (count($pathIds) == 0) {
 
 1263        for (
$i = 0; 
$i < count($pathIds); 
$i++) {
 
 1264            $types[] = 
'integer';
 
 1268        $query = 
'SELECT t.depth,t.parent,t.child,d.obj_id,d.type,d.title ' .
 
 1269            'FROM ' . $this->table_tree . 
' t ' .
 
 1270            'JOIN ' . $this->table_obj_reference . 
' r ON r.ref_id = t.child ' .
 
 1271            'JOIN ' . $this->table_obj_data . 
' d ON d.obj_id = r.obj_id ' .
 
 1272            'WHERE ' . 
$ilDB->in(
't.child', 
$data, 
false, 
'integer') . 
' ' .
 
 1273            'ORDER BY t.depth ';
 
 1277        $titlePath = array();
 
 1278        while ($row = 
$ilDB->fetchAssoc(
$res)) {
 
 1279            $titlePath[] = $row;
 
 1298        $types = array(
'integer');
 
 1299        $query = 
'SELECT lft,rgt FROM ' . $this->table_tree . 
' ' .
 
 1300            'WHERE ' . $this->tree_pk . 
' = %s ';
 
 1303        while ($row = 
$ilDB->fetchObject(
$res)) {
 
 1308        $all = array_merge($lft, $rgt);
 
 1309        $uni = array_unique($all);
 
 1311        if (count($all) != count($uni)) {
 
 1334        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 1335                'WHERE ' . $this->tree_pk . 
' = %s ' .
 
 1337        $r1 = 
$ilDB->queryF(
$query, array(
'integer'), array($this->tree_id));
 
 1339        while ($row = 
$ilDB->fetchAssoc($r1)) {
 
 1341            if (($row[
"child"] == 0) && $a_no_zero_child) {
 
 1342                $message = 
"Tree contains child with ID 0!";
 
 1347            if ($this->table_obj_reference) {
 
 1349                $query = 
'SELECT * FROM ' . $this->table_obj_reference . 
' WHERE ' . $this->ref_pk . 
' = %s ';
 
 1350                $r2 = 
$ilDB->queryF(
$query, array(
'integer'), array($row[
'child']));
 
 1353                if ($r2->numRows() == 0) {
 
 1354                    $message = 
"No Object-to-Reference entry found for ID " . $row[
"child"] . 
"!";
 
 1358                if ($r2->numRows() > 1) {
 
 1359                    $message = 
"More Object-to-Reference entries found for ID " . $row[
"child"] . 
"!";
 
 1365                $obj_ref = 
$ilDB->fetchAssoc($r2);
 
 1367                $query = 
'SELECT * FROM ' . $this->table_obj_data . 
' WHERE ' . $this->obj_pk . 
' = %s';
 
 1368                $r3 = 
$ilDB->queryF(
$query, array(
'integer'), array($obj_ref[$this->obj_pk]));
 
 1369                if ($r3->numRows() == 0) {
 
 1374                if ($r3->numRows() > 1) {
 
 1381                $query = 
'SELECT * FROM ' . $this->table_obj_data . 
' WHERE ' . $this->obj_pk . 
' = %s';
 
 1382                $r2 = 
$ilDB->queryF(
$query, array(
'integer'), array($row[
'child']));
 
 1384                if ($r2->numRows() == 0) {
 
 1385                    $message = 
"No child found for ID " . $row[
"child"] . 
"!";
 
 1389                if ($r2->numRows() > 1) {
 
 1390                    $message = 
"More childs found for ID " . $row[
"child"] . 
"!";
 
 1415        return $row[
'depth'];
 
 1432                $query = 
'SELECT depth FROM ' . $this->table_tree . 
' ' .
 
 1433                    'WHERE child = %s ';
 
 1437                $query = 
'SELECT depth FROM ' . $this->table_tree . 
' ' .
 
 1438                'WHERE child = %s ' .
 
 1439                'AND ' . $this->tree_pk . 
' = %s ';
 
 1440                $res = 
$ilDB->queryF(
$query, array(
'integer',
'integer'), array($a_node_id,$this->tree_id));
 
 1465            throw new InvalidArgumentException(
'Missing or empty parameter $a_node_id: ' . $a_node_id);
 
 1468        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 1469                'WHERE child = ' . 
$ilDB->quote($a_node_id, 
'integer');
 
 1495        if (!isset($a_node_id)) {
 
 1497            throw new InvalidArgumentException(
"No node_id given!");
 
 1500            if ($a_node_id < 1) {
 
 1501                $message = 
'No valid parameter given! $a_node_id: %s' . $a_node_id;
 
 1504                throw new InvalidArgumentException(
$message);
 
 1509        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 1511            'WHERE ' . $this->table_tree . 
'.child = %s ' .
 
 1512            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ';
 
 1515            $a_tree_pk === 
null ? $this->tree_id : $a_tree_pk));
 
 1534        $objDefinition = 
$DIC[
'objDefinition'];
 
 1541        $data[
"desc"] = $a_row[
"description"];  
 
 1546        if (is_object($objDefinition)) {
 
 1547            $translation_type = $objDefinition->getTranslationType(
$data[
"type"]);
 
 1551        if ($translation_type == 
"sys") {
 
 1553            if (
$data[
"type"] == 
"rolf" and 
$data[
"obj_id"] != ROLE_FOLDER_ID) {
 
 1559                $data[
"description"] = 
$lng->txt(
"obj_" . 
$data[
"type"] . 
"_desc");
 
 1563        } elseif ($translation_type == 
"db") {
 
 1567                array_key_exists(
$data[
"obj_id"] . 
'.' . $lang_code, $this->translation_cache)) {
 
 1568                $key = 
$data[
"obj_id"] . 
'.' . $lang_code;
 
 1569                $data[
"title"] = $this->translation_cache[$key][
'title'];
 
 1570                $data[
"description"] = $this->translation_cache[$key][
'description'];
 
 1571                $data[
"desc"] = $this->translation_cache[$key][
'desc'];
 
 1575                $query = 
'SELECT title,description FROM object_translation ' .
 
 1576                    'WHERE obj_id = %s ' .
 
 1577                    'AND lang_code = %s ' .
 
 1578                    'AND NOT lang_default = %s';
 
 1580                $res = 
$ilDB->queryF(
$query, array(
'integer',
'text',
'integer'), array(
 
 1587                    $data[
"title"] = $row->title;
 
 1589                    $data[
"desc"] = $row->description;
 
 1594                if ($this->
isCacheUsed() && count($this->translation_cache) < 1000) {
 
 1595                    $key = 
$data[
"obj_id"] . 
'.' . $lang_code;
 
 1596                    $this->translation_cache[$key] = array();
 
 1597                    $this->translation_cache[$key][
'title'] = 
$data[
"title"] ;
 
 1598                    $this->translation_cache[$key][
'description'] = 
$data[
"description"];
 
 1599                    $this->translation_cache[$key][
'desc'] = 
$data[
"desc"];
 
 1605        if (
$data[
'type'] == 
'crsr' or 
$data[
'type'] == 
'catr' or 
$data[
'type'] == 
'grpr' or 
$data[
'type'] === 
'prgr') {
 
 1606            include_once(
'./Services/ContainerReference/classes/class.ilContainerReference.php');
 
 1622        $ilObjDataCache = 
$DIC[
'ilObjDataCache'];
 
 1624        if ($this->
isCacheUsed() && is_array($a_obj_ids) && is_object($ilObjDataCache)) {
 
 1625            foreach ($a_obj_ids as $id) {
 
 1626                $this->translation_cache[$id . 
'.'][
'title'] = $ilObjDataCache->lookupTitle($id);
 
 1627                $this->translation_cache[$id . 
'.'][
'description'] = $ilObjDataCache->lookupDescription($id);
 
 1629                $this->translation_cache[$id . 
'.'][
'desc'] =
 
 1630                    $this->translation_cache[$id . 
'.'][
'description'];
 
 1649        if (!isset($a_node_id)) {
 
 1651            #$this->ilErr->raiseError(get_class($this)."::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
 
 1654        if ($this->
isCacheUsed() && isset($this->in_tree_cache[$a_node_id])) {
 
 1655            #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Using in tree cache '.$a_node_id); 
 1657            return $this->in_tree_cache[$a_node_id];
 
 1660        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 1661            'WHERE ' . $this->table_tree . 
'.child = %s ' .
 
 1662            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s';
 
 1668        if (
$res->numRows() > 0) {
 
 1670                #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = true'); 
 1671                $this->in_tree_cache[$a_node_id] = 
true;
 
 1676                #$GLOBALS['DIC']['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = false'); 
 1677                $this->in_tree_cache[$a_node_id] = 
false;
 
 1699        if (!isset($a_node_id)) {
 
 1701            throw new InvalidArgumentException(__METHOD__ . 
': No node_id given!');
 
 1704        if ($this->table_obj_reference) {
 
 1706            $innerjoin = 
"JOIN " . $this->table_obj_reference . 
" ON v.child=" . $this->table_obj_reference . 
"." . $this->ref_pk . 
" " .
 
 1707                        "JOIN " . $this->table_obj_data . 
" ON " . $this->table_obj_reference . 
"." . $this->obj_pk . 
"=" . $this->table_obj_data . 
"." . $this->obj_pk . 
" ";
 
 1710            $innerjoin = 
"JOIN " . $this->table_obj_data . 
" ON v.child=" . $this->table_obj_data . 
"." . $this->obj_pk . 
" ";
 
 1713        $query = 
'SELECT * FROM ' . $this->table_tree . 
' s, ' . $this->table_tree . 
' v ' .
 
 1715            'WHERE s.child = %s ' .
 
 1716            'AND s.parent = v.child ' .
 
 1717            'AND s.' . $this->tree_pk . 
' = %s ' .
 
 1718            'AND v.' . $this->tree_pk . 
' = %s';
 
 1719        $res = 
$ilDB->queryF(
$query, array(
'integer',
'integer',
'integer'), array(
 
 1748    public function addTree($a_tree_id, $a_node_id = -1)
 
 1757                'Operation not allowed on main tree! $a_tree_if: %s $a_node_id: %s',
 
 1762            throw new InvalidArgumentException(
$message);
 
 1765        if (!isset($a_tree_id)) {
 
 1768            throw new InvalidArgumentException(
$message);
 
 1771        if ($a_node_id <= 0) {
 
 1772            $a_node_id = $a_tree_id;
 
 1775        $query = 
'INSERT INTO ' . $this->table_tree . 
' (' .
 
 1776            $this->tree_pk . 
', child,parent,lft,rgt,depth) ' .
 
 1778            '(%s,%s,%s,%s,%s,%s)';
 
 1779        $res = 
$ilDB->manipulateF(
$query, array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer'), array(
 
 1807            throw new InvalidArgumentException(
'Type not given or wrong datatype');
 
 1810        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 1812            'WHERE ' . $this->table_obj_data . 
'.type = ' . $this->ilDB->quote(
$a_type, 
'text') .
 
 1813            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = ' . $this->ilDB->quote($this->tree_id, 
'integer');
 
 1817        while ($row = 
$ilDB->fetchAssoc(
$res)) {
 
 1841            throw new InvalidArgumentException(
'Operation not allowed on main tree');
 
 1845            throw new InvalidArgumentException(
'Missing parameter tree id');
 
 1848        $query = 
'DELETE FROM ' . $this->table_tree .
 
 1849            ' WHERE ' . $this->tree_pk . 
' = %s ';
 
 1850        $ilDB->manipulateF(
$query, array(
'integer'), array($a_tree_id));
 
 1862    public function moveToTrash($a_node_id, $a_set_deleted = 
false, $a_deleted_by = 0)
 
 1867        $user = 
$DIC->user();
 
 1868        if(!$a_deleted_by) {
 
 1869            $a_deleted_by = $user->getId();
 
 1874            throw new InvalidArgumentException(
'No valid parameter given! $a_node_id: ' . $a_node_id);
 
 1881        $subnodes = array();
 
 1883            $subnodes[] = $row[
'child'];
 
 1886        if (!count($subnodes)) {
 
 1891        if ($a_set_deleted) {
 
 1907        return $this->
isSaved($a_node_id);
 
 1922        if ($this->
isCacheUsed() && isset($this->is_saved_cache[$a_node_id])) {
 
 1924            return $this->is_saved_cache[$a_node_id];
 
 1927        $query = 
'SELECT ' . $this->tree_pk . 
' FROM ' . $this->table_tree . 
' ' .
 
 1928            'WHERE child = %s ';
 
 1932        if ($row[$this->tree_pk] < 0) {
 
 1934                $this->is_saved_cache[$a_node_id] = 
true;
 
 1939                $this->is_saved_cache[$a_node_id] = 
false;
 
 1957        if (!is_array($a_node_ids) || !$this->
isCacheUsed()) {
 
 1961        $query = 
'SELECT ' . $this->tree_pk . 
', child FROM ' . $this->table_tree . 
' ' .
 
 1962            'WHERE ' . 
$ilDB->in(
"child", $a_node_ids, 
false, 
"integer");
 
 1965        while ($row = 
$ilDB->fetchAssoc(
$res)) {
 
 1966            if ($row[$this->tree_pk] < 0) {
 
 1968                    $this->is_saved_cache[$row[
"child"]] = 
true;
 
 1972                    $this->is_saved_cache[$row[
"child"]] = 
false;
 
 1992        if (!isset($a_parent_id)) {
 
 1995            throw new InvalidArgumentException(
$message);
 
 1998        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2000            'WHERE ' . $this->table_tree . 
'.' . $this->tree_pk . 
' < %s ' .
 
 2001            'AND ' . $this->table_tree . 
'.parent = %s';
 
 2006        while ($row = 
$ilDB->fetchAssoc(
$res)) {
 
 2010        return $saved ? $saved : array();
 
 2025        $query = 
'SELECT ' . $this->table_obj_data . 
'.obj_id FROM ' . $this->table_tree . 
' ' .
 
 2027            'WHERE ' . $this->table_tree . 
'.' . $this->tree_pk . 
' < ' . 
$ilDB->quote(0, 
'integer') . 
' ' .
 
 2028            'AND ' . 
$ilDB->in($this->table_obj_data . 
'.obj_id', $a_obj_ids, 
'', 
'integer');
 
 2030        while ($row = 
$ilDB->fetchAssoc(
$res)) {
 
 2031            $saved[] = $row[
'obj_id'];
 
 2034        return $saved ? $saved : array();
 
 2050        if (!isset($a_node_id)) {
 
 2053            throw new InvalidArgumentException(
$message);
 
 2057            $query = 
'SELECT parent FROM ' . $this->table_tree . 
' ' .
 
 2058                'WHERE child = %s ';
 
 2065            $query = 
'SELECT parent FROM ' . $this->table_tree . 
' ' .
 
 2066            'WHERE child = %s ' .
 
 2067            'AND ' . $this->tree_pk . 
' = %s ';
 
 2074        return $row->parent;
 
 2090        if (!isset($a_node_id)) {
 
 2093            throw new InvalidArgumentException(
$message);
 
 2096        $query = 
'SELECT lft FROM ' . $this->table_tree . 
' ' .
 
 2097            'WHERE child = %s ' .
 
 2098            'AND ' . $this->tree_pk . 
' = %s ';
 
 2119        if (!isset($a_node)) {
 
 2122            throw new InvalidArgumentException(
$message);
 
 2126            $query = 
'SELECT count(*) cnt FROM ' . $this->table_tree . 
' ' .
 
 2128                'WHERE lft <= %s ' .
 
 2130                'AND parent = %s ' .
 
 2131                'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ';
 
 2133            $res = 
$ilDB->queryF(
$query, array(
'integer',
'text',
'integer',
'integer'), array(
 
 2139            $query = 
'SELECT count(*) cnt FROM ' . $this->table_tree . 
' ' .
 
 2141                'WHERE lft <= %s ' .
 
 2142                'AND parent = %s ' .
 
 2143                'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ';
 
 2145            $res = 
$ilDB->queryF(
$query, array(
'integer',
'integer',
'integer'), array(
 
 2166        $query = 
'SELECT child FROM ' . $this->table_tree . 
' ' .
 
 2167            'WHERE parent = %s ' .
 
 2168            'AND ' . $this->tree_pk . 
' = %s ';
 
 2173        $this->root_id = $row->child;
 
 2188        $this->root_id = $a_root_id;
 
 2208        $this->tree_id = $a_tree_id;
 
 2225        if (!isset($a_node_id)) {
 
 2228            throw new InvalidArgumentException(
$message);
 
 2232        $query = 
'SELECT lft FROM ' . $this->table_tree . 
' ' .
 
 2233            'WHERE ' . $this->table_tree . 
'.child = %s ' .
 
 2234            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ';
 
 2241            $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2244                'AND ' . $this->table_obj_data . 
'.type = %s ' .
 
 2245                'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ' .
 
 2248            $res = 
$ilDB->queryF(
$query, array(
'integer',
'text',
'integer'), array(
 
 2253            $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2256                'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ' .
 
 2264        if (
$res->numRows() < 1) {
 
 2286        if (!isset($a_node_id)) {
 
 2289            throw new InvalidArgumentException(
$message);
 
 2293        $query = 
'SELECT lft FROM ' . $this->table_tree . 
' ' .
 
 2294            'WHERE ' . $this->table_tree . 
'.child = %s ' .
 
 2295            'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ';
 
 2303            $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2306                'AND ' . $this->table_obj_data . 
'.type = %s ' .
 
 2307                'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ' .
 
 2308                'ORDER BY lft DESC';
 
 2310            $res = 
$ilDB->queryF(
$query, array(
'integer',
'text',
'integer'), array(
 
 2315            $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2318                'AND ' . $this->table_tree . 
'.' . $this->tree_pk . 
' = %s ' .
 
 2319                'ORDER BY lft DESC';
 
 2326        if (
$res->numRows() < 1) {
 
 2354            $ilAtomQuery = 
$ilDB->buildAtomQuery();
 
 2355            $ilAtomQuery->addTableLock($this->table_tree);
 
 2357            $ilAtomQuery->addQueryCallable($renumber_callable);
 
 2358            $ilAtomQuery->run();
 
 2360            $renumber_callable(
$ilDB);
 
 2382            $query = 
'UPDATE ' . $this->table_tree . 
' SET lft = %s WHERE child = %s';
 
 2385                array(
'integer',
'integer'),
 
 2391            $query = 
'UPDATE ' . $this->table_tree . 
' SET lft = %s WHERE child = %s AND tree = %s';
 
 2394                array(
'integer',
'integer',
'integer'),
 
 2402        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2403            'WHERE parent = ' . 
$ilDB->quote($node_id, 
'integer') . 
' ' .
 
 2409            $childs[] = $row->child;
 
 2412        foreach ($childs as $child) {
 
 2418        if (count($childs) > 0) {
 
 2419            $i += $this->gap * 2;
 
 2424            $query = 
'UPDATE ' . $this->table_tree . 
' SET rgt = %s WHERE child = %s';
 
 2427                array(
'integer',
'integer'),
 
 2433            $query = 
'UPDATE ' . $this->table_tree . 
' SET rgt = %s WHERE child = %s AND tree = %s';
 
 2434            $res = 
$ilDB->manipulateF(
$query, array(
'integer',
'integer', 
'integer'), array(
 
 2456        $cache_key = $a_ref_id . 
'.' . 
$a_type . 
'.' . ((int) $a_exclude_source_check);
 
 2460            array_key_exists($cache_key, $this->parent_type_cache)) {
 
 2461            return $this->parent_type_cache[$cache_key];
 
 2465        $do_cache = ($this->
__isMainTree() && count($this->parent_type_cache) < 1000);
 
 2470                $this->parent_type_cache[$cache_key] = 
false;
 
 2475        $path = array_reverse($this->
getPathFull($a_ref_id));
 
 2478        if ($a_exclude_source_check) {
 
 2482        foreach ($path as $node) {
 
 2484            if ($node[
"type"] == 
$a_type) {
 
 2486                    $this->parent_type_cache[$cache_key] = $node[
"child"];
 
 2488                return $node[
"child"];
 
 2493            $this->parent_type_cache[$cache_key] = 
false;
 
 2508    public static function _removeEntry($a_tree, $a_child, $a_db_table = 
"tree")
 
 2514        if ($a_db_table === 
'tree') {
 
 2515            if ($a_tree == 1 and $a_child == ROOT_FOLDER_ID) {
 
 2517                    'Tried to delete root node! $a_tree: %s $a_child: %s',
 
 2522                throw new InvalidArgumentException(
$message);
 
 2526        $query = 
'DELETE FROM ' . $a_db_table . 
' ' .
 
 2527            'WHERE tree = %s ' .
 
 2542        return $this->table_tree === 
'tree';
 
 2564        $this->log->debug(
$query);
 
 2567        $counter = (int) $lft_childs = array();
 
 2568        while ($row = 
$ilDB->fetchObject(
$res)) {
 
 2569            $lft_childs[$row->child] = $row->parent;
 
 2574        if ($counter != count($lft_childs)) {
 
 2575            $message = 
'Duplicate entries for "child" in maintree! $a_node_id: ' . $a_node[
'child'];
 
 2582        $parent_childs = array();
 
 2605        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2606            'WHERE child = %s ' .
 
 2613        while ($row = 
$ilDB->fetchObject(
$res)) {
 
 2614            $parent_childs[$a_node_id] = $row->parent;
 
 2619            $message = 
'Multiple entries in maintree! $a_node_id: ' . $a_node_id;
 
 2626        $query = 
'SELECT * FROM ' . $this->table_tree . 
' ' .
 
 2627            'WHERE parent = %s ';
 
 2630        while ($row = 
$ilDB->fetchObject(
$res)) {
 
 2648        ksort($parent_childs);
 
 2650        $this->log->debug(
'left childs ' . print_r($lft_childs, 
true));
 
 2651        $this->log->debug(
'parent childs ' . print_r($parent_childs, 
true));
 
 2653        if (count($lft_childs) != count($parent_childs)) {
 
 2654            $message = 
'(COUNT) Tree is corrupted! Left/Right subtree does not comply with parent relation';
 
 2660        foreach ($lft_childs as $key => $value) {
 
 2661            if ($parent_childs[$key] != $value) {
 
 2662                $message = 
'(COMPARE) Tree is corrupted! Left/Right subtree does not comply with parent relation';
 
 2666            if ($key == ROOT_FOLDER_ID) {
 
 2667                $message = 
'(ROOT_FOLDER) Tree is corrupted! Tried to delete root folder';
 
 2684    public function moveTree($a_source_id, $a_target_id, $a_location = self::POS_LAST_NODE)
 
 2686        $old_parent_id = $this->
getParentId($a_source_id);
 
 2689            $GLOBALS[
'DIC'][
'ilAppEventHandler']->raise(
 
 2693                        'tree' => $this->table_tree,
 
 2694                        'source_id' => $a_source_id,
 
 2695                        'target_id' => $a_target_id,
 
 2696                        'old_parent_id' => $old_parent_id
 
 2726    public function getSubTreeQuery($a_node_id, $a_fields = array(), $a_types = 
'', $a_force_join_reference = 
false)
 
 2731            $a_force_join_reference,
 
 2744            $a_force_join_reference,
 
 2765        if (!
sizeof($node)) {
 
 2774        if (count($a_fields)) {
 
 2775            $fields = implode(
',', $a_fields);
 
 2778        $query = 
"SELECT " . $fields .
 
 2784        while ($row = 
$ilDB->fetchAssoc($set)) {
 
 2796        $ilAppEventHandler = 
$DIC[
'ilAppEventHandler'];
 
 2798        $query = 
'DELETE FROM tree where ' .
 
 2799                'child = ' . 
$ilDB->quote($a_node_id, 
'integer') . 
' ' .
 
 2800                'AND tree = ' . 
$ilDB->quote($a_tree_id, 
'integer');
 
 2803        $ilAppEventHandler->raise(
 
 2806            array(
'tree' => $this->table_tree,
 
 2807                          'node_id' => $a_node_id,
 
 2808                          'tree_id' => $a_tree_id
 
 2824        $query = 
'SELECT DISTINCT(o.type) ' . 
$ilDB->quoteIdentifier(
'type') . 
' FROM tree t JOIN object_reference r ON child = r.ref_id ' .
 
 2825                'JOIN object_data o on r.obj_id = o.obj_id ' .
 
 2826                'WHERE tree < ' . 
$ilDB->quote(0, 
'integer') . 
' ' .
 
 2827                'AND child = -tree ' .
 
 2831        $types_deleted = array();
 
 2833            $types_deleted[] = $row->type;
 
 2835        return $types_deleted;
 
 2843        if ($this->table_tree == 
'tree') {
 
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
An exception for terminatinating execution or to throw for unit testing.
static toNFC($string)
Convert a UTF-8 string to normal form C, canonical composition.
static _lookupTitle($a_obj_id)
Overwitten from base class.
Thrown if invalid tree strucutes are found.
static getLogger($a_component_id)
Get component logger.
Base class for materialize path based trees Based on implementation of Werner Randelshofer.
Base class for nested set path based trees.
static setDeletedDates($a_ref_ids, $a_user_id)
Set deleted date.
static _resetDeletedDate($a_ref_id)
only called in ilObjectGUI::insertSavedNodes
static strToLower($a_string)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
isCacheUsed()
Check if cache is active.
fetchPredecessorNode($a_node_id, $a_type="")
get node data of predecessor node
lookupTrashedObjectTypes()
Lookup object types in trash @global type $ilDB.
getRelation($a_node_a, $a_node_b)
Get relation of two nodes.
getSubTree($a_node, $a_with_data=true, $a_type="")
get all nodes in the subtree under specified node
getFilteredChilds($a_filter, $a_node, $a_order="", $a_direction="ASC")
get child nodes of given node (exclude filtered obj_types) @access public
isGrandChild($a_startnode_id, $a_querynode_id)
checks if a node is in the path of an other node @access public
getSubTreeTypes($a_node, $a_filter=0)
get types of nodes in the subtree under specified node
getRelationOfNodes($a_node_a_arr, $a_node_b_arr)
get relation of two nodes by node data
setObjectTablePK($a_column_name)
set column containing primary key in object table @access public
getTreePk()
Get tree primary key.
getParentId($a_node_id)
get parent id of given node @access public
getRbacSubtreeInfo($a_endnode_id)
This method is used for change existing objects and returns all necessary information for this action...
getParentCache()
Get parent cache.
setReferenceTablePK($a_column_name)
set column containing primary key in reference table @access public
checkTreeChilds($a_no_zero_child=true)
check, if all childs of tree nodes exist in object table
getDepth($a_node_id)
return depth of a node in tree @access private
getSavedNodeData($a_parent_id)
get data saved/deleted nodes
getChildSequenceNumber($a_node, $type="")
get sequence number of node in sibling sequence @access public
isRepositoryTree()
check if current tree instance operates on repository tree table
insertNodeFromTrash($a_source_id, $a_target_id, $a_tree_id, $a_pos=IL_LAST_NODE, $a_reset_deleted_date=false)
Insert node from trash deletes trash entry.
useCache($a_use=true)
Use Cache (usually activated)
deleteTree($a_node)
delete node and the whole subtree under this node @access public
getLeftValue($a_node_id)
get left value of given node @access public
__checkDelete($a_node)
Check for deleteTree() compares a subtree of a given node by checking lft, rgt against parent relatio...
fetchSuccessorNode($a_node_id, $a_type="")
get node data of successor node
getDepthCache()
Get depth cache.
getTreeId()
get tree id @access public
getChildIds($a_node)
Get node child ids @global type $ilDB.
getNodeDataByType($a_type)
get nodes by type
getTreeTable()
Get tree table name.
static _removeEntry($a_tree, $a_child, $a_db_table="tree")
STATIC METHOD Removes a single entry from a tree.
getSubTreeQuery($a_node_id, $a_fields=array(), $a_types='', $a_force_join_reference=false)
Get tree subtree query.
__renumber($node_id=1, $i=1)
This method is private.
setTreeTablePK($a_column_name)
set column containing primary key in tree table @access public
isDeleted($a_node_id)
This is a wrapper for isSaved() with a more useful name.
getNodeTreeData($a_node_id)
return all columns of tabel tree
setTableNames($a_table_tree, $a_table_obj_data, $a_table_obj_reference="")
set table names The primary key of the table containing your object_data must be 'obj_id' You may use...
getTableReference()
Get reference table if available.
const TREE_TYPE_NESTED_SET
fetchTranslationFromObjectDataCache($a_obj_ids)
Get translation data from object cache (trigger in object cache on preload)
readRootId()
read root id from database
removeTree($a_tree_id)
remove an existing tree
static lookupTreesForNode(int $node_id)
fetchNodeData($a_row)
get data of parent node from tree and object_data @access private
checkTree()
check consistence of tree all left & right values are checked if they are exists only once @access pu...
getSubTreeFilteredByObjIds($a_node_id, array $a_obj_ids, array $a_fields=array())
get all node ids in the subtree under specified node id, filter by object ids
renumber($node_id=1, $i=1)
Wrapper for renumber.
getNodePath($a_endnode_id, $a_startnode_id=0)
Returns the node path for the specified object reference.
getChildsByType($a_node_id, $a_type)
get child nodes of given node by object type @access public
getNodeData($a_node_id, $a_tree_pk=null)
get all information of a node.
setTreeId($a_tree_id)
set tree id @access public
getSavedNodeObjIds(array $a_obj_ids)
get object id of saved/deleted nodes
getChildsByTypeFilter($a_node_id, $a_types, $a_order="", $a_direction="ASC")
get child nodes of given node by object type @access public
deleteNode($a_tree_id, $a_node_id)
getMaximumDepth()
Return the current maximum depth in the tree @access public.
moveTree($a_source_id, $a_target_id, $a_location=self::POS_LAST_NODE)
Move Tree Implementation.
preloadDepthParent($a_node_ids)
Preload depth/parent.
isSaved($a_node_id)
Use method isDeleted check if node is saved.
initLangCode()
Store user language.
buildJoin()
build join depending on table settings @access private
getTreeImplementation()
Get tree implementation.
getNodePathForTitlePath($titlePath, $a_startnode_id=null)
Converts a path consisting of object titles into a path consisting of tree nodes.
initTreeImplementation()
Init tree implementation.
getTrashSubTreeQuery($a_node_id, $a_fields=[], $a_types='', $a_force_join_reference=false)
preloadDeleted($a_node_ids)
Preload deleted information.
__construct($a_tree_id, $a_root_id=0)
Constructor @access public.
getFilteredSubTree($a_node_id, $a_filter=array())
get filtered subtree
getObjectDataTable()
Get object data table.
getRootId()
get the root id of tree @access public
const TREE_TYPE_MATERIALIZED_PATH
insertNode($a_node_id, $a_parent_id, $a_pos=IL_LAST_NODE, $a_reset_deletion_date=false)
insert new node with node_id under parent node with parent_id @access public
checkForParentType($a_ref_id, $a_type, $a_exclude_source_check=false)
Check for parent type e.g check if a folder (ref_id 3) is in a parent course obj => checkForParentTyp...
__isMainTree()
Check if operations are done on main tree.
moveToTrash($a_node_id, $a_set_deleted=false, $a_deleted_by=0)
Move node to trash bin.
__getSubTreeByParentRelation($a_node_id, &$parent_childs)
@global type $ilDB
isInTree($a_node_id)
get all information of a node.
getGap()
Get default gap *.
__validateSubtrees(&$lft_childs, $parent_childs)
getPathId($a_endnode_id, $a_startnode_id=0)
get path from a given startnode to a given endnode if startnode is not given the rootnode is startnod...
addTree($a_tree_id, $a_node_id=-1)
create a new tree to do: ???
getPathFull($a_endnode_id, $a_startnode_id=0)
get path from a given startnode to a given endnode if startnode is not given the rootnode is startnod...
getParentNodeData($a_node_id)
get data of parent node from tree and object_data @access public
getChilds($a_node_id, $a_order="", $a_direction="ASC")
get child nodes of given node @access public
validateParentRelations()
Validate parent relations of tree.
getSubTreeIds($a_ref_id)
Get all ids of subnodes.
static quoteArray($a_array)
Quotes all members of an array for usage in DB query statement.
static shortenText( $a_str, $a_len, $a_dots=false, $a_next_blank=false, $a_keep_extension=false)
shorten a string to given length.
foreach($_POST as $key=> $value) $res