4 define(
"IL_LAST_NODE", -2);
5 define(
"IL_FIRST_NODE", -1);
130 function ilTree($a_tree_id, $a_root_id = 0)
147 $this->lang_code =
"en";
149 if (!isset($a_tree_id) or (func_num_args() == 0) )
151 $this->ilErr->raiseError(get_class($this).
"::Constructor(): No tree_id given!",$this->ilErr->WARNING);
154 if (func_num_args() > 2)
156 $this->ilErr->raiseError(get_class($this).
"::Constructor(): Wrong parameter count!",$this->ilErr->WARNING);
163 if (empty($a_root_id))
165 $a_root_id = ROOT_FOLDER_ID;
168 $this->tree_id = $a_tree_id;
169 $this->root_id = $a_root_id;
170 $this->table_tree =
'tree';
171 $this->table_obj_data =
'object_data';
172 $this->table_obj_reference =
'object_reference';
173 $this->ref_pk =
'ref_id';
174 $this->obj_pk =
'obj_id';
175 $this->tree_pk =
'tree';
177 $this->use_cache =
true;
180 $this->translation_cache = array();
181 $this->parent_type_cache = array();
192 $this->use_cache = $a_use;
213 if (!is_object($ilUser))
215 $this->lang_code =
"en";
219 $this->lang_code = $ilUser->getCurrentLanguage();
238 function setTableNames($a_table_tree,$a_table_obj_data,$a_table_obj_reference =
"")
240 if (!isset($a_table_tree) or !isset($a_table_obj_data))
242 $this->ilErr->raiseError(get_class($this).
"::setTableNames(): Missing parameter! ".
243 "tree table: ".$a_table_tree.
" object data table: ".$a_table_obj_data,$this->ilErr->WARNING);
246 $this->table_tree = $a_table_tree;
247 $this->table_obj_data = $a_table_obj_data;
248 $this->table_obj_reference = $a_table_obj_reference;
261 if (!isset($a_column_name))
263 $this->ilErr->raiseError(get_class($this).
"::setReferenceTablePK(): No column name given!",$this->ilErr->WARNING);
266 $this->ref_pk = $a_column_name;
278 if (!isset($a_column_name))
280 $this->ilErr->raiseError(get_class($this).
"::setObjectTablePK(): No column name given!",$this->ilErr->WARNING);
283 $this->obj_pk = $a_column_name;
295 if (!isset($a_column_name))
297 $this->ilErr->raiseError(get_class($this).
"::setTreeTablePK(): No column name given!",$this->ilErr->WARNING);
300 $this->tree_pk = $a_column_name;
311 if ($this->table_obj_reference)
314 return "JOIN ".$this->table_obj_reference.
" ON ".$this->table_tree.
".child=".$this->table_obj_reference.
".".$this->ref_pk.
" ".
315 "JOIN ".$this->table_obj_data.
" ON ".$this->table_obj_reference.
".".$this->obj_pk.
"=".$this->table_obj_data.
".".$this->obj_pk.
" ";
320 return "JOIN ".$this->table_obj_data.
" ON ".$this->table_tree.
".child=".$this->table_obj_data.
".".$this->obj_pk.
" ";
332 function getChilds($a_node_id, $a_order =
"", $a_direction =
"ASC")
336 if (!isset($a_node_id))
338 $message = get_class($this).
"::getChilds(): No node_id given!";
339 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
352 if (!empty($a_order))
354 $order_clause =
"ORDER BY ".$a_order.
" ".$a_direction;
358 $order_clause =
"ORDER BY ".$this->table_tree.
".lft";
362 $query = sprintf(
'SELECT * FROM '.$this->table_tree.
' '.
364 "WHERE parent = %s " .
365 "AND ".$this->table_tree.
".".$this->tree_pk.
" = %s ".
367 $ilDB->quote($a_node_id,
'integer'),
368 $ilDB->quote($this->tree_id,
'integer'));
372 if(!$count = $res->numRows())
379 while($r = $ilDB->fetchAssoc($res))
382 $obj_ids[] = $r[
"obj_id"];
387 is_object($ilUser) && $this->lang_code == $ilUser->getLanguage() && !$this->oc_preloaded[$a_node_id])
390 $ilObjDataCache->preloadObjectCache($obj_ids, $this->lang_code);
392 $this->oc_preloaded[$a_node_id] =
true;
395 foreach ($rows as
$row)
402 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$row['child'].' = true');
403 $this->in_tree_cache[$row[
'child']] = $row[
'tree'] == 1;
406 $childs[$count - 1][
"last"] =
true;
421 $childs = $this->
getChilds($a_node,$a_order,$a_direction);
423 foreach($childs as $child)
425 if(!in_array($child[
"type"],$a_filter))
427 $filtered[] = $child;
430 return $filtered ? $filtered : array();
445 if (!isset($a_node_id) or !isset($a_type))
447 $message = get_class($this).
"::getChildsByType(): Missing parameter! node_id:".$a_node_id.
" type:".$a_type;
448 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
451 if ($a_type==
'rolf' && $this->table_obj_reference) {
455 $ilDB->setLimit(1,0);
456 $query = sprintf(
"SELECT * FROM ".$this->table_tree.
" ".
458 "WHERE parent = %s ".
459 "AND ".$this->table_tree.
".".$this->tree_pk.
" = %s ".
460 "AND ".$this->table_obj_data.
".type = %s ",
461 $ilDB->quote($a_node_id,
'integer'),
462 $ilDB->quote($this->tree_id,
'integer'),
463 $ilDB->quote($a_type,
'text'));
465 $query = sprintf(
"SELECT * FROM ".$this->table_tree.
" ".
467 "WHERE parent = %s ".
468 "AND ".$this->table_tree.
".".$this->tree_pk.
" = %s ".
469 "AND ".$this->table_obj_data.
".type = %s ".
470 "ORDER BY ".$this->table_tree.
".lft",
471 $ilDB->quote($a_node_id,
'integer'),
472 $ilDB->quote($this->tree_id,
'integer'),
473 $ilDB->quote($a_type,
'text'));
479 while(
$row = $ilDB->fetchAssoc(
$res))
484 return $childs ? $childs : array();
499 if (!isset($a_node_id) or !$a_types)
501 $message = get_class($this).
"::getChildsByType(): Missing parameter! node_id:".$a_node_id.
" type:".$a_types;
502 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
508 $filter =
'AND '.$this->table_obj_data.
'.type IN('.implode(
',',
ilUtil::quoteArray($a_types)).
') ';
511 $query =
'SELECT * FROM '.$this->table_tree.
' '.
513 'WHERE parent = '.$ilDB->quote($a_node_id,
'integer').
' '.
514 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = '.$ilDB->quote($this->tree_id,
'integer').
' '.
516 'ORDER BY '.$this->table_tree.
'.lft';
519 while(
$row = $ilDB->fetchAssoc(
$res))
524 return $childs ? $childs : array();
542 if($a_node_id <= 1 or $a_parent_id <= 0)
544 $message = sprintf(
'%s::insertNode(): Invalid parameters! $a_node_id: %s $a_parent_id: %s',
548 $this->log->write($message,$this->log->FATAL);
549 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
554 if (!isset($a_node_id) or !isset($a_parent_id))
556 $this->ilErr->raiseError(get_class($this).
"::insertNode(): Missing parameter! ".
557 "node_id: ".$a_node_id.
" parent_id: ".$a_parent_id,$this->ilErr->WARNING);
561 $this->ilErr->raiseError(get_class($this).
"::insertNode(): Node ".$a_node_id.
" already in tree ".
562 $this->table_tree.
"!",$this->ilErr->WARNING);
572 #ilDB::_lockTables(array('tree' => 'WRITE'));
579 $query = sprintf(
'SELECT * FROM '.$this->table_tree.
' '.
581 'AND '.$this->tree_pk.
' = %s ',
582 $ilDB->quote($a_parent_id,
'integer'),
583 $ilDB->quote($this->tree_id,
'integer'));
586 $r = $ilDB->fetchObject($res);
588 if ($r->parent == NULL)
592 $ilDB->unlockTables();
594 $this->ilErr->raiseError(get_class($this).
"::insertNode(): Parent with ID ".$a_parent_id.
" not found in ".
595 $this->table_tree.
"!",$this->ilErr->WARNING);
603 $query = sprintf(
'UPDATE '.$this->table_tree.
' SET '.
604 'lft = CASE WHEN lft > %s THEN lft + 2 ELSE lft END, '.
605 'rgt = CASE WHEN rgt > %s THEN rgt + 2 ELSE rgt END '.
606 'WHERE '.$this->tree_pk.
' = %s ',
607 $ilDB->quote($left,
'integer'),
608 $ilDB->quote($left,
'integer'),
609 $ilDB->quote($this->tree_id,
'integer'));
610 $res = $ilDB->manipulate(
$query);
619 #ilDB::_lockTables(array('tree' => 'WRITE'));
627 $query = sprintf(
'SELECT rgt,lft,parent FROM '.$this->table_tree.
' '.
629 'AND '.$this->tree_pk.
' = %s',
630 $ilDB->quote($a_parent_id,
'integer'),
631 $ilDB->quote($this->tree_id,
'integer'));
632 $res = $ilDB->query(
$query);
633 $r = $ilDB->fetchAssoc($res);
635 if ($r[
'parent'] == null)
639 $ilDB->unlockTables();
641 $this->ilErr->raiseError(get_class($this).
"::insertNode(): Parent with ID ".
642 $a_parent_id.
" not found in ".$this->table_tree.
"!",$this->ilErr->WARNING);
644 $parentRgt = $r[
'rgt'];
645 $parentLft = $r[
'lft'];
648 $availableSpace = $parentRgt - $parentLft;
649 if ($availableSpace < 2)
660 $query = sprintf(
'SELECT MAX(rgt) max_rgt FROM '.$this->table_tree.
' '.
661 'WHERE parent = %s '.
662 'AND '.$this->tree_pk.
' = %s',
663 $ilDB->quote($a_parent_id,
'integer'),
664 $ilDB->quote($this->tree_id,
'integer'));
665 $res = $ilDB->query(
$query);
666 $r = $ilDB->fetchAssoc($res);
668 if (isset($r[
'max_rgt']))
672 $availableSpace = $parentRgt - $r[
'max_rgt'];
673 $lft = $r[
'max_rgt'] + 1;
680 $lft = $parentLft + 1;
687 if ($availableSpace < 2)
690 $query = sprintf(
'UPDATE '.$this->table_tree.
' SET '.
691 'lft = CASE WHEN lft > %s THEN lft + %s ELSE lft END, '.
692 'rgt = CASE WHEN rgt >= %s THEN rgt + %s ELSE rgt END '.
693 'WHERE '.$this->tree_pk.
' = %s ',
694 $ilDB->quote($parentRgt,
'integer'),
695 $ilDB->quote((2 + $this->gap * 2),
'integer'),
696 $ilDB->quote($parentRgt,
'integer'),
697 $ilDB->quote((2 + $this->gap * 2),
'integer'),
698 $ilDB->quote($this->tree_id,
'integer'));
699 $res = $ilDB->manipulate(
$query);
711 #ilDB::_lockTables(array('tree' => 'WRITE'));
719 $query = sprintf(
'SELECT * FROM '.$this->table_tree.
' '.
721 'AND '.$this->tree_pk.
' = %s ',
722 $ilDB->quote($a_parent_id,
'integer'),
723 $ilDB->quote($this->tree_id,
'integer'));
724 $res = $ilDB->query(
$query);
725 $r = $ilDB->fetchObject($res);
727 if ($r->parent == null)
731 $ilDB->unlockTables();
733 $this->ilErr->raiseError(get_class($this).
"::insertNode(): Parent with ID ".
734 $a_parent_id.
" not found in ".$this->table_tree.
"!",$this->ilErr->WARNING);
742 $query = sprintf(
'UPDATE '.$this->table_tree.
' SET '.
743 'lft = CASE WHEN lft > %s THEN lft + 2 ELSE lft END, '.
744 'rgt = CASE WHEN rgt >= %s THEN rgt + 2 ELSE rgt END '.
745 'WHERE '.$this->tree_pk.
' = %s',
746 $ilDB->quote($right,
'integer'),
747 $ilDB->quote($right,
'integer'),
748 $ilDB->quote($this->tree_id,
'integer'));
749 $res = $ilDB->manipulate(
$query);
759 #ilDB::_lockTables(array('tree' => 'WRITE'));
767 $query = sprintf(
'SELECT * FROM '.$this->table_tree.
' '.
769 'AND '.$this->tree_pk.
' = %s ',
770 $ilDB->quote($a_pos,
'integer'),
771 $ilDB->quote($this->tree_id,
'integer'));
772 $res = $ilDB->query(
$query);
773 $r = $ilDB->fetchObject($res);
776 if ($r->parent != $a_parent_id)
780 $ilDB->unlockTables();
782 $this->ilErr->raiseError(get_class($this).
"::insertNode(): Parents mismatch! ".
783 "new node parent: ".$a_parent_id.
" sibling parent: ".$r->parent,$this->ilErr->WARNING);
791 $query = sprintf(
'UPDATE '.$this->table_tree.
' SET '.
792 'lft = CASE WHEN lft > %s THEN lft + 2 ELSE lft END, '.
793 'rgt = CASE WHEN rgt > %s THEN rgt + 2 ELSE rgt END '.
794 'WHERE '.$this->tree_pk.
' = %s',
795 $ilDB->quote($right,
'integer'),
796 $ilDB->quote($right,
'integer'),
797 $ilDB->quote($this->tree_id,
'integer'));
798 $res = $ilDB->manipulate(
$query);
804 $depth = $this->
getDepth($a_parent_id) + 1;
808 $query = sprintf(
'INSERT INTO '.$this->table_tree.
' ('.$this->tree_pk.
',child,parent,lft,rgt,depth) '.
809 'VALUES (%s,%s,%s,%s,%s,%s)',
810 $ilDB->quote($this->tree_id,
'integer'),
811 $ilDB->quote($a_node_id,
'integer'),
812 $ilDB->quote($a_parent_id,
'integer'),
813 $ilDB->quote($lft,
'integer'),
814 $ilDB->quote($rgt,
'integer'),
815 $ilDB->quote($depth,
'integer'));
821 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = true');
822 $this->in_tree_cache[$a_node_id] =
true;
823 $ilDB->unlockTables();
827 if ($a_reset_deletion_date)
853 if($depth and $subnode[
'depth'] > $depth)
857 if(!$first and in_array($subnode[
'type'],$a_filter))
859 $depth = $subnode[
'depth'];
865 $filtered[] = $subnode;
867 return $filtered ? $filtered : array();
879 $query =
'SELECT s.child FROM '.$this->table_tree.
' s, '.$this->table_tree.
' t '.
880 'WHERE t.child = %s '.
881 'AND s.lft > t.lft '.
882 'AND s.rgt < t.rgt '.
883 'AND s.'.$this->tree_pk.
' = %s';
885 $res = $ilDB->queryF(
887 array(
'integer',
'integer'),
888 array($a_ref_id,$this->tree_id)
892 $childs[] =
$row->child;
894 return $childs ? $childs : array();
906 function getSubTree($a_node,$a_with_data =
true, $a_type =
"")
910 if (!is_array($a_node))
912 $this->ilErr->raiseError(get_class($this).
"::getSubTree(): Wrong datatype for node_data! ",$this->ilErr->WARNING);
915 if($a_node[
'lft'] < 1 or $a_node[
'rgt'] < 2)
917 $message = sprintf(
'%s::getSubTree(): Invalid node given! $a_node["lft"]: %s $a_node["rgt"]: %s',
922 $this->log->write($message,$this->log->FATAL);
932 echo $e->getTraceAsString();
937 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
941 $fields = array(
'integer',
'integer',
'integer');
942 $data = array($a_node[
'lft'],$a_node[
'rgt'],$this->tree_id);
945 if (is_array($a_type))
947 $type_str =
"AND ".$ilDB->in($this->table_obj_data.
".type", $a_type,
false,
"text");
949 else if(strlen($a_type))
953 $type_str =
"AND ".$this->table_obj_data.
".type = ".
954 $ilDB->quote($a_type,
"text");
957 $query =
"SELECT * FROM ".$this->table_tree.
" ".
959 "WHERE ".$this->table_tree.
".lft BETWEEN %s AND %s ".
960 "AND ".$this->table_tree.
".".$this->tree_pk.
" = %s ".
962 "ORDER BY ".$this->table_tree.
".lft";
964 while(
$row = $ilDB->fetchAssoc(
$res))
972 $subtree[] =
$row[
'child'];
976 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = true');
977 $this->in_tree_cache[
$row[
'child']] =
true;
981 return $subtree ? $subtree : array();
994 $a_filter = $a_filter ? $a_filter : array();
996 foreach($this->getSubtree($this->
getNodeData($a_node)) as $node)
998 if(in_array($node[
"type"],$a_filter))
1002 $types[
"$node[type]"] = $node[
"type"];
1004 return $types ? $types : array();
1016 if (!is_array($a_node))
1018 $this->ilErr->raiseError(get_class($this).
"::deleteTree(): Wrong datatype for node_data! ",$this->ilErr->WARNING);
1020 if($this->
__isMainTree() and $a_node[$this->tree_pk] === 1)
1022 if($a_node[
'lft'] <= 1 or $a_node[
'rgt'] <= 2)
1024 $message = sprintf(
'%s::deleteTree(): Invalid parameters given: $a_node["lft"]: %s, $a_node["rgt"] %s',
1029 $this->log->write($message,$this->log->FATAL);
1030 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1034 $message = sprintf(
'%s::deleteTree(): Check delete failed: $a_node["lft"]: %s, $a_node["rgt"] %s',
1038 $this->log->write($message,$this->log->FATAL);
1039 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1043 $diff = $a_node[
"rgt"] - $a_node[
"lft"] + 1;
1050 #ilDB::_lockTables(array('tree' => 'WRITE'));
1057 $query = sprintf(
'SELECT * FROM '.$this->table_tree.
' '.
1058 'WHERE child = %s '.
1059 'AND '.$this->tree_pk.
' = %s ',
1060 $ilDB->quote($a_node[
'child'],
'integer'),
1061 $ilDB->quote($a_node[$this->tree_pk],
'integer'));
1063 while(
$row = $ilDB->fetchObject($res))
1065 $a_node[
'lft'] =
$row->lft;
1066 $a_node[
'rgt'] =
$row->rgt;
1067 $diff = $a_node[
"rgt"] - $a_node[
"lft"] + 1;
1071 $query = sprintf(
'DELETE FROM '.$this->table_tree.
' '.
1072 'WHERE lft BETWEEN %s AND %s '.
1073 'AND rgt BETWEEN %s AND %s '.
1074 'AND '.$this->tree_pk.
' = %s',
1075 $ilDB->quote($a_node[
'lft'],
'integer'),
1076 $ilDB->quote($a_node[
'rgt'],
'integer'),
1077 $ilDB->quote($a_node[
'lft'],
'integer'),
1078 $ilDB->quote($a_node[
'rgt'],
'integer'),
1079 $ilDB->quote($a_node[$this->tree_pk],
'integer'));
1080 $res = $ilDB->manipulate(
$query);
1085 if ($a_node[$this->tree_pk] >= 0 && $a_node[
'rgt'] - $a_node[
'lft'] >= $this->gap * 2)
1089 $query = sprintf(
'UPDATE '.$this->table_tree.
' SET '.
1090 'lft = CASE WHEN lft > %s THEN lft - %s ELSE lft END, '.
1091 'rgt = CASE WHEN rgt > %s THEN rgt - %s ELSE rgt END '.
1092 'WHERE '.$this->tree_pk.
' = %s ',
1093 $ilDB->quote($a_node[
'lft'],
'integer'),
1094 $ilDB->quote($diff,
'integer'),
1095 $ilDB->quote($a_node[
'lft'],
'integer'),
1096 $ilDB->quote($diff,
'integer'),
1097 $ilDB->quote($a_node[$this->tree_pk],
'integer'));
1099 $res = $ilDB->manipulate(
$query);
1108 #$GLOBALS['ilLog']->write(__METHOD__.': Resetting in tree cache ');
1109 $ilDB->unlockTables();
1110 $this->in_tree_cache = array();
1127 $pathIds =& $this->
getPathId($a_endnode_id, $a_startnode_id);
1133 if (count($pathIds) == 0)
1138 $inClause =
'child IN (';
1139 for ($i=0; $i < count($pathIds); $i++)
1141 if ($i > 0) $inClause .=
',';
1142 $inClause .= $ilDB->quote($pathIds[$i],
'integer');
1147 'FROM '.$this->table_tree.
' '.
1149 'WHERE '.$inClause.
' '.
1150 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = '.$this->
ilDB->
quote($this->tree_id,
'integer').
' '.
1152 $r = $ilDB->query($q);
1154 $pathFull = array();
1162 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$row['child']);
1163 $this->in_tree_cache[
$row[
'child']] = $row[
'tree'] == 1;
1186 if (!isset($a_endnode_id))
1188 $this->ilErr->raiseError(get_class($this).
"::getPathId(): No endnode_id given! ",$this->ilErr->WARNING);
1191 $fields = array(
'integer',
'integer',
'integer');
1192 $data = array($a_endnode_id,$this->tree_id,$this->tree_id);
1194 $query =
"SELECT T2.child ".
1195 "FROM ".$this->table_tree.
" T1, ".$this->table_tree.
" T2 ".
1196 "WHERE T1.child = %s ".
1197 "AND T1.lft BETWEEN T2.lft AND T2.rgt ".
1198 "AND T1.".$this->tree_pk.
" = %s ".
1199 "AND T2.".$this->tree_pk.
" = %s ".
1200 "ORDER BY T2.depth";
1203 $takeId = $a_startnode_id == 0;
1204 while(
$row = $ilDB->fetchAssoc(
$res))
1206 if ($takeId ||
$row[
'child'] == $a_startnode_id)
1209 $pathIds[] =
$row[
'child'];
1212 return $pathIds ? $pathIds : array();
1230 $takeId = $a_startnode_id == 0;
1232 if (!isset($a_endnode_id))
1234 $this->ilErr->raiseError(get_class($this).
"::getPathId(): No endnode_id given! ",$this->ilErr->WARNING);
1239 if ($this->
__isMainTree() && isset($this->depth_cache[$a_endnode_id])
1240 && isset($this->parent_cache[$a_endnode_id]))
1242 $nodeDepth = $this->depth_cache[$a_endnode_id];
1243 $parentId = $this->parent_cache[$a_endnode_id];
1247 $types = array(
'integer',
'integer');
1248 $data = array($a_endnode_id,$this->tree_id);
1249 $query =
'SELECT t.depth, t.parent '.
1250 'FROM '.$this->table_tree.
' t '.
1251 'WHERE child = %s '.
1252 'AND '.$this->tree_pk.
' = %s ';
1255 if(
$res->numRows() == 0)
1261 $nodeDepth =
$row[
'depth'];
1262 $parentId =
$row[
'parent'];
1269 if ($nodeDepth == 1)
1271 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1272 if ($takeId) $pathIds[] = $a_endnode_id;
1274 else if ($nodeDepth == 2)
1276 $takeId = $takeId || $parentId == $a_startnode_id;
1277 if ($takeId) $pathIds[] = $parentId;
1278 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1279 if ($takeId) $pathIds[] = $a_endnode_id;
1281 else if ($nodeDepth == 3)
1283 $takeId = $takeId || $this->root_id == $a_startnode_id;
1285 $takeId = $takeId || $parentId == $a_startnode_id;
1286 if ($takeId) $pathIds[] = $parentId;
1287 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1288 if ($takeId) $pathIds[] = $a_endnode_id;
1290 else if ($nodeDepth < 32)
1301 $qSelect =
't1.child c0';
1303 for ($i = 1; $i < $nodeDepth - 2; $i++)
1305 $qSelect .=
', t'.$i.
'.parent c'.$i;
1306 $qJoin .=
' JOIN '.$this->table_tree.
' t'.$i.
' ON '.
1307 't'.$i.
'.child=t'.($i - 1).
'.parent AND '.
1311 $types = array(
'integer',
'integer');
1312 $data = array($this->tree_id,$parentId);
1313 $query =
'SELECT '.$qSelect.
' '.
1314 'FROM '.$this->table_tree.
' t0 '.$qJoin.
' '.
1315 'WHERE t0.'.$this->tree_pk.
' = %s '.
1316 'AND t0.child = %s ';
1321 if (
$res->numRows() == 0)
1327 $takeId = $takeId || $this->root_id == $a_startnode_id;
1329 for ($i = $nodeDepth - 4; $i >=0; $i--)
1331 $takeId = $takeId ||
$row[
'c'.$i] == $a_startnode_id;
1332 if ($takeId) $pathIds[] =
$row[
'c'.$i];
1334 $takeId = $takeId || $parentId == $a_startnode_id;
1335 if ($takeId) $pathIds[] = $parentId;
1336 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1337 if ($takeId) $pathIds[] = $a_endnode_id;
1363 $res = $ilDB->query(
'SELECT t.depth, t.parent, t.child '.
1364 'FROM '.$this->table_tree.
' t '.
1365 'WHERE '.$ilDB->in(
"child", $a_node_ids,
false,
"integer").
1366 'AND '.$this->tree_pk.
' = '.$ilDB->quote($this->tree_id,
"integer"));
1367 while (
$row = $ilDB->fetchAssoc(
$res))
1369 $this->depth_cache[
$row[
"child"]] = $row[
"depth"];
1370 $this->parent_cache[$row[
"child"]] = $row[
"parent"];
1385 if ($this->
isCacheUsed() && isset($this->path_id_cache[$a_endnode_id][$a_startnode_id]))
1388 return $this->path_id_cache[$a_endnode_id][$a_startnode_id];
1396 $this->path_id_cache[$a_endnode_id][$a_startnode_id] = $pathIds;
1425 if ($titlePath == null || count($titlePath) == 0)
1427 if ($a_startnode_id == 0)
1438 if ($a_startnode_id != null && $a_startnode_id != 0)
1442 $parent = $a_startnode_id;
1447 $nodePath = array();
1455 require_once(
'include/Unicode/UtfNormal.php');
1456 include_once
'./Services/Utilities/classes/class.ilStr.php';
1457 $inClause =
'd.title IN (';
1458 for ($i=0; $i < count($titlePath); $i++)
1461 if ($i > 0) $inClause .=
',';
1462 $inClause .= $ilDB->quote($titlePath[$i],
'text');
1467 if ($this->table_obj_reference)
1469 $joinClause =
'JOIN '.$this->table_obj_reference.
' r ON t.child = r.'.$this->ref_pk.
' '.
1470 'JOIN '.$this->table_obj_data.
' d ON r.'.$this->obj_pk.
' = d.'.
$this->obj_pk;
1474 $joinClause =
'JOIN '.$this->table_obj_data.
' d ON t.child = d.'.
$this->obj_pk;
1481 $q =
'SELECT t.depth, t.parent, t.child, d.'.$this->obj_pk.
' obj_id, d.type, d.title '.
1482 'FROM '.$this->table_tree.
' t '.
1484 'WHERE '.$inClause.
' '.
1485 'AND t.depth <= '.(count($titlePath)+count($nodePath)).
' '.
1487 'ORDER BY t.depth, t.child ASC';
1488 $r = $ilDB->query($q);
1499 for ($i = 0; $i < count($titlePath); $i++) {
1500 $pathElementFound =
false;
1501 foreach ($rows as
$row) {
1502 if ($row[
'parent'] == $parent &&
1508 $parent = $row[
'child'];
1509 $pathElementFound =
true;
1514 if (! $pathElementFound)
1546 $pathIds = $this->
getPathId($a_endnode_id, $a_startnode_id);
1549 if (count($pathIds) == 0)
1557 for ($i = 0; $i < count($pathIds); $i++)
1559 $types[] =
'integer';
1560 $data[] = $pathIds[$i];
1563 $query =
'SELECT t.depth,t.parent,t.child,d.obj_id,d.type,d.title '.
1564 'FROM '.$this->table_tree.
' t '.
1565 'JOIN '.$this->table_obj_reference.
' r ON r.ref_id = t.child '.
1566 'JOIN '.$this->table_obj_data.
' d ON d.obj_id = r.obj_id '.
1567 'WHERE '.$ilDB->in(
't.child',
$data,
false,
'integer').
' '.
1568 'ORDER BY t.depth ';
1572 $titlePath = array();
1573 while (
$row = $ilDB->fetchAssoc(
$res))
1575 $titlePath[] =
$row;
1591 $types = array(
'integer');
1592 $query =
'SELECT lft,rgt FROM '.$this->table_tree.
' '.
1593 'WHERE '.$this->tree_pk.
' = %s ';
1595 $res = $ilDB->queryF(
$query,$types,array($this->tree_id));
1596 while (
$row = $ilDB->fetchObject(
$res))
1602 $all = array_merge($lft,$rgt);
1603 $uni = array_unique($all);
1605 if (count($all) != count($uni))
1607 $message = sprintf(
'%s::checkTree(): Tree is corrupted!',
1610 $this->log->write($message,$this->log->FATAL);
1611 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1624 $query =
'SELECT * FROM '.$this->table_tree.
' '.
1625 'WHERE '.$this->tree_pk.
' = %s '.
1627 $r1 = $ilDB->queryF(
$query,array(
'integer'),array($this->tree_id));
1629 while (
$row = $ilDB->fetchAssoc($r1))
1632 if ((
$row[
"child"] == 0) && $a_no_zero_child)
1634 $this->ilErr->raiseError(get_class($this).
"::checkTreeChilds(): Tree contains child with ID 0!",$this->ilErr->WARNING);
1637 if ($this->table_obj_reference)
1640 $query =
'SELECT * FROM '.$this->table_obj_reference.
' WHERE '.$this->ref_pk.
' = %s ';
1641 $r2 = $ilDB->queryF(
$query,array(
'integer'),array(
$row[
'child']));
1644 if ($r2->numRows() == 0)
1646 $this->ilErr->raiseError(get_class($this).
"::checkTree(): No Object-to-Reference entry found for ID ".
1647 $row[
"child"].
"!",$this->ilErr->WARNING);
1649 if ($r2->numRows() > 1)
1651 $this->ilErr->raiseError(get_class($this).
"::checkTree(): More Object-to-Reference entries found for ID ".
1652 $row[
"child"].
"!",$this->ilErr->WARNING);
1656 $obj_ref = $ilDB->fetchAssoc($r2);
1658 $query =
'SELECT * FROM '.$this->table_obj_data.
' WHERE '.$this->obj_pk.
' = %s';
1659 $r3 = $ilDB->queryF(
$query,array(
'integer'),array($obj_ref[$this->obj_pk]));
1660 if ($r3->numRows() == 0)
1662 $this->ilErr->raiseError(get_class($this).
"::checkTree(): No child found for ID ".
1663 $obj_ref[$this->obj_pk].
"!",$this->ilErr->WARNING);
1665 if ($r3->numRows() > 1)
1667 $this->ilErr->raiseError(get_class($this).
"::checkTree(): More childs found for ID ".
1668 $obj_ref[$this->obj_pk].
"!",$this->ilErr->WARNING);
1675 $query =
'SELECT * FROM '.$this->table_obj_data.
' WHERE '.$this->obj_pk.
' = %s';
1676 $r2 = $ilDB->queryF(
$query,array(
'integer'),array(
$row[
'child']));
1678 if ($r2->numRows() == 0)
1680 $this->ilErr->raiseError(get_class($this).
"::checkTree(): No child found for ID ".
1681 $row[
"child"].
"!",$this->ilErr->WARNING);
1683 if ($r2->numRows() > 1)
1685 $this->ilErr->raiseError(get_class($this).
"::checkTree(): More childs found for ID ".
1686 $row[
"child"].
"!",$this->ilErr->WARNING);
1703 $query =
'SELECT MAX(depth) depth FROM '.$this->table_tree;
1707 return $row[
'depth'];
1722 $query =
'SELECT depth FROM '.$this->table_tree.
' '.
1723 'WHERE child = %s '.
1724 'AND '.$this->tree_pk.
' = %s ';
1725 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array($a_node_id,$this->tree_id));
1751 if (!isset($a_node_id))
1754 $this->ilErr->raiseError(get_class($this).
"::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
1760 $message = sprintf(
'%s::getNodeData(): No valid parameter given! $a_node_id: %s',
1764 $this->log->write($message,$this->log->FATAL);
1765 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1770 $query =
'SELECT * FROM '.$this->table_tree.
' '.
1772 'WHERE '.$this->table_tree.
'.child = %s '.
1773 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
1774 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
1776 $a_tree_pk === null ? $this->tree_id : $a_tree_pk));
1797 $data[
"desc"] = $a_row[
"description"];
1802 if (is_object($objDefinition))
1804 $translation_type = $objDefinition->getTranslationType(
$data[
"type"]);
1808 if ($translation_type ==
"sys")
1811 if (
$data[
"type"] ==
"rolf" and
$data[
"obj_id"] != ROLE_FOLDER_ID)
1813 $data[
"description"] = $lng->txt(
"obj_".
$data[
"type"].
"_local_desc").$data[
"title"].$data[
"desc"];
1814 $data[
"desc"] = $lng->txt(
"obj_".
$data[
"type"].
"_local_desc").$data[
"title"].$data[
"desc"];
1815 $data[
"title"] = $lng->txt(
"obj_".
$data[
"type"].
"_local");
1819 $data[
"title"] = $lng->txt(
"obj_".
$data[
"type"]);
1820 $data[
"description"] = $lng->txt(
"obj_".
$data[
"type"].
"_desc");
1821 $data[
"desc"] = $lng->txt(
"obj_".
$data[
"type"].
"_desc");
1825 elseif ($translation_type ==
"db")
1830 array_key_exists(
$data[
"obj_id"].
'.'.$lang_code, $this->translation_cache)) {
1832 $key =
$data[
"obj_id"].
'.'.$lang_code;
1833 $data[
"title"] = $this->translation_cache[$key][
'title'];
1834 $data[
"description"] = $this->translation_cache[$key][
'description'];
1835 $data[
"desc"] = $this->translation_cache[$key][
'desc'];
1841 $query =
'SELECT title,description FROM object_translation '.
1842 'WHERE obj_id = %s '.
1843 'AND lang_code = %s '.
1844 'AND NOT lang_default = %s';
1846 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer'),array(
1861 if ($this->
isCacheUsed() && count($this->translation_cache) < 1000)
1863 $key =
$data[
"obj_id"].
'.'.$lang_code;
1864 $this->translation_cache[$key] = array();
1865 $this->translation_cache[$key][
'title'] =
$data[
"title"] ;
1866 $this->translation_cache[$key][
'description'] =
$data[
"description"];
1867 $this->translation_cache[$key][
'desc'] =
$data[
"desc"];
1873 if(
$data[
'type'] ==
'crsr' or
$data[
'type'] ==
'catr')
1875 include_once(
'./Services/ContainerReference/classes/class.ilContainerReference.php');
1889 global $ilObjDataCache;
1891 if ($this->
isCacheUsed() && is_array($a_obj_ids) && is_object($ilObjDataCache))
1893 foreach ($a_obj_ids as $id)
1895 $this->translation_cache[$id.
'.'][
'title'] = $ilObjDataCache->lookupTitle($id);
1896 $this->translation_cache[$id.
'.'][
'description'] = $ilObjDataCache->lookupDescription($id);;
1897 $this->translation_cache[$id.
'.'][
'desc'] =
1898 $this->translation_cache[$id.
'.'][
'description'];
1915 if (!isset($a_node_id))
1918 #$this->ilErr->raiseError(get_class($this)."::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
1922 if ($this->
isCacheUsed() && isset($this->in_tree_cache[$a_node_id]))
1924 #$GLOBALS['ilLog']->write(__METHOD__.': Using in tree cache '.$a_node_id);
1926 return $this->in_tree_cache[$a_node_id];
1929 $query =
'SELECT * FROM '.$this->table_tree.
' '.
1930 'WHERE '.$this->table_tree.
'.child = %s '.
1931 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s';
1933 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
1937 if (
$res->numRows() > 0)
1941 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = true');
1942 $this->in_tree_cache[$a_node_id] =
true;
1950 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = false');
1951 $this->in_tree_cache[$a_node_id] =
false;
1968 if (!isset($a_node_id))
1971 $this->ilErr->raiseError(get_class($this).
"::getParentNodeData(): No node_id given! ",$this->ilErr->WARNING);
1974 if ($this->table_obj_reference)
1977 $innerjoin =
"JOIN ".$this->table_obj_reference.
" ON v.child=".$this->table_obj_reference.
".".$this->ref_pk.
" ".
1978 "JOIN ".$this->table_obj_data.
" ON ".$this->table_obj_reference.
".".$this->obj_pk.
"=".$this->table_obj_data.
".".$this->obj_pk.
" ";
1983 $innerjoin =
"JOIN ".$this->table_obj_data.
" ON v.child=".$this->table_obj_data.
".".$this->obj_pk.
" ";
1986 $query =
'SELECT * FROM '.$this->table_tree.
' s, '.$this->table_tree.
' v '.
1988 'WHERE s.child = %s '.
1989 'AND s.parent = v.child '.
1990 'AND s.lft > v.lft '.
1991 'AND s.rgt < v.rgt '.
1992 'AND s.'.$this->tree_pk.
' = %s '.
1993 'AND v.'.$this->tree_pk.
' = %s';
1994 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2013 if (!isset($a_startnode_id) or !isset($a_querynode_id))
2018 $query =
'SELECT * FROM '.$this->table_tree.
' s, '.$this->table_tree.
' v '.
2019 'WHERE s.child = %s '.
2020 'AND v.child = %s '.
2021 'AND s.'.$this->tree_pk.
' = %s '.
2022 'AND v.'.$this->tree_pk.
' = %s '.
2023 'AND v.lft BETWEEN s.lft AND s.rgt '.
2024 'AND v.rgt BETWEEN s.lft AND s.rgt';
2025 $res = $ilDB->queryF(
2027 array(
'integer',
'integer',
'integer',
'integer'),
2034 return $res->numRows();
2052 $message = sprintf(
'%s::addTree(): Operation not allowed on main tree! $a_tree_if: %s $a_node_id: %s',
2056 $this->log->write($message,$this->log->FATAL);
2057 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2060 if (!isset($a_tree_id))
2062 $this->ilErr->raiseError(get_class($this).
"::addTree(): No tree_id given! ",$this->ilErr->WARNING);
2065 if ($a_node_id <= 0)
2067 $a_node_id = $a_tree_id;
2070 $query =
'INSERT INTO '.$this->table_tree.
' ('.
2071 $this->tree_pk.
', child,parent,lft,rgt,depth) '.
2073 '(%s,%s,%s,%s,%s,%s)';
2074 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer'),array(
2096 if (!isset($a_type) or (!is_string($a_type)))
2098 $this->ilErr->raiseError(get_class($this).
"::getNodeDataByType(): Type not given or wrong datatype!",$this->ilErr->WARNING);
2106 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2107 'WHERE '.$this->tree_pk.
' = %s '.
2109 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2113 while (
$row = $ilDB->fetchObject(
$res))
2119 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2121 'WHERE '.$this->table_obj_data.
'.type = %s '.
2122 'AND '.$this->table_tree.
'.lft BETWEEN %s AND %s '.
2123 'AND '.$this->table_tree.
'.rgt BETWEEN %s AND %s '.
2124 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2125 $res = $ilDB->queryF(
$query,array(
'text',
'integer',
'integer',
'integer',
'integer',
'integer'),array(
2133 while(
$row = $ilDB->fetchAssoc(
$res))
2155 $message = sprintf(
'%s::removeTree(): Operation not allowed on main tree! $a_tree_if: %s',
2158 $this->log->write($message,$this->log->FATAL);
2159 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2163 $this->ilErr->raiseError(get_class($this).
"::removeTree(): No tree_id given! Action aborted",$this->ilErr->MESSAGE);
2166 $query =
'DELETE FROM '.$this->table_tree.
2167 ' WHERE '.$this->tree_pk.
' = %s ';
2168 $res = $ilDB->manipulateF(
$query,array(
'integer'),array($a_tree_id));
2185 $message = sprintf(
'%s::saveSubTree(): No valid parameter given! $a_node_id: %s',
2188 $this->log->write($message,$this->log->FATAL);
2189 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2200 #ilDB::_lockTables(array('tree' => 'WRITE',
2201 # 'object_reference' => 'WRITE'));
2206 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2207 'WHERE '.$this->tree_pk.
' = %s '.
2209 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2213 while(
$row = $ilDB->fetchObject(
$res))
2220 $query =
'SELECT child FROM '.$this->table_tree.
' '.
2221 'WHERE '.$this->tree_pk.
' = %s '.
2222 'AND lft BETWEEN %s AND %s ';
2223 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2228 $subnodes = array();
2229 while(
$row = $ilDB->fetchAssoc(
$res))
2231 $subnodes[] =
$row[
'child'];
2234 if(!count($subnodes))
2241 $ilDB->unlockTables();
2248 foreach($subnodes as $child)
2259 $query =
'UPDATE '.$this->table_tree.
' '.
2261 'WHERE '.$this->tree_pk.
' = %s '.
2262 'AND lft BETWEEN %s AND %s ';
2263 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer',
'integer',
'integer'),array(
2271 $ilDB->unlockTables();
2283 return $this->
isSaved($a_node_id);
2294 if ($this->
isCacheUsed() && isset($this->is_saved_cache[$a_node_id]))
2297 return $this->is_saved_cache[$a_node_id];
2300 $query =
'SELECT '.$this->tree_pk.
' FROM '.$this->table_tree.
' '.
2301 'WHERE child = %s ';
2302 $res = $ilDB->queryF(
$query,array(
'integer'),array($a_node_id));
2305 if (
$row[$this->tree_pk] < 0)
2309 $this->is_saved_cache[$a_node_id] =
true;
2317 $this->is_saved_cache[$a_node_id] =
false;
2333 if (!is_array($a_node_ids) || !$this->
isCacheUsed())
2338 $query =
'SELECT '.$this->tree_pk.
', child FROM '.$this->table_tree.
' '.
2339 'WHERE '.$ilDB->in(
"child", $a_node_ids,
false,
"integer");
2342 while (
$row = $ilDB->fetchAssoc(
$res))
2344 if (
$row[$this->tree_pk] < 0)
2348 $this->is_saved_cache[
$row[
"child"]] =
true;
2355 $this->is_saved_cache[
$row[
"child"]] =
false;
2372 if (!isset($a_parent_id))
2374 $this->ilErr->raiseError(get_class($this).
"::getSavedNodeData(): No node_id given!",$this->ilErr->WARNING);
2377 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2379 'WHERE '.$this->table_tree.
'.'.$this->tree_pk.
' < %s '.
2380 'AND '.$this->table_tree.
'.parent = %s';
2381 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2385 while(
$row = $ilDB->fetchAssoc(
$res))
2390 return $saved ? $saved : array();
2403 if (!isset($a_node_id))
2405 $this->ilErr->raiseError(get_class($this).
"::getParentId(): No node_id given! ",$this->ilErr->WARNING);
2408 $query =
'SELECT parent FROM '.$this->table_tree.
' '.
2409 'WHERE child = %s '.
2410 'AND '.$this->tree_pk.
' = %s ';
2411 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2416 return $row->parent;
2429 if (!isset($a_node_id))
2431 $this->ilErr->raiseError(get_class($this).
"::getLeftValued(): No node_id given! ",$this->ilErr->WARNING);
2434 $query =
'SELECT lft FROM '.$this->table_tree.
' '.
2435 'WHERE child = %s '.
2436 'AND '.$this->tree_pk.
' = %s ';
2437 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2454 if (!isset($a_node))
2456 $this->ilErr->raiseError(get_class($this).
"::getChildSequenceNumber(): No node_id given! ",$this->ilErr->WARNING);
2461 $query =
'SELECT count(*) cnt FROM '.$this->table_tree.
' '.
2466 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2468 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer',
'integer'),array(
2476 $query =
'SELECT count(*) cnt FROM '.$this->table_tree.
' '.
2480 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2482 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2502 $query =
'SELECT child FROM '.$this->table_tree.
' '.
2503 'WHERE parent = %s '.
2504 'AND '.$this->tree_pk.
' = %s ';
2505 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2509 $this->root_id =
$row->child;
2524 $this->root_id = $a_root_id;
2544 $this->tree_id = $a_tree_id;
2558 if (!isset($a_node_id))
2560 $this->ilErr->raiseError(get_class($this).
"::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
2564 $query =
'SELECT lft FROM '.$this->table_tree.
' '.
2565 'WHERE '.$this->table_tree.
'.child = %s '.
2566 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2567 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2571 $curr_node = $ilDB->fetchAssoc(
$res);
2575 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2578 'AND '.$this->table_obj_data.
'.type = %s '.
2579 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2582 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer'),array(
2589 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2592 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2595 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2600 if (
$res->numRows() < 1)
2622 if (!isset($a_node_id))
2624 $this->ilErr->raiseError(get_class($this).
"::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
2628 $query =
'SELECT lft FROM '.$this->table_tree.
' '.
2629 'WHERE '.$this->table_tree.
'.child = %s '.
2630 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2631 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2635 $curr_node = $ilDB->fetchAssoc(
$res);
2639 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2642 'AND '.$this->table_obj_data.
'.type = %s '.
2643 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2644 'ORDER BY lft DESC';
2646 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer'),array(
2653 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2656 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2657 'ORDER BY lft DESC';
2659 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2664 if (
$res->numRows() < 1)
2702 2 => array(
'name' => $this->table_obj_reference,
'type' =>
ilDB::LOCK_WRITE),
2704 4 => array(
'name' =>
'object_data',
'type' =>
ilDB::LOCK_WRITE,
'alias' =>
'od'),
2705 5 => array(
'name' =>
'container_reference',
'type' =>
ilDB::LOCK_WRITE,
'alias' =>
'cr')
2711 $ilDB->unlockTables();
2731 $query =
'UPDATE '.$this->table_tree.
' SET lft = %s WHERE child = %s';
2732 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer'),array(
2738 foreach ($childs as $child)
2740 $i = $this->
__renumber($child[
"child"],$i+1);
2745 if (count($childs) > 0)
2747 $i += $this->gap * 2;
2751 $query =
'UPDATE '.$this->table_tree.
' SET rgt = %s WHERE child = %s';
2752 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer'),array(
2772 $cache_key = $a_ref_id.
'.'.$a_type.
'.'.((int)$a_exclude_source_check);
2776 array_key_exists($cache_key, $this->parent_type_cache))
2778 return $this->parent_type_cache[$cache_key];
2782 $do_cache = ($this->
__isMainTree() && count($this->parent_type_cache) < 1000);
2789 $this->parent_type_cache[$cache_key] =
false;
2797 if($a_exclude_source_check)
2802 foreach(
$path as $node)
2805 if($node[
"type"] == $a_type)
2809 $this->parent_type_cache[$cache_key] = $node[
"child"];
2811 return $node[
"child"];
2817 $this->parent_type_cache[$cache_key] =
false;
2835 if($a_db_table ===
'tree')
2837 if($a_tree == 1 and $a_child == ROOT_FOLDER_ID)
2839 $message = sprintf(
'%s::_removeEntry(): Tried to delete root node! $a_tree: %s $a_child: %s',
2843 $ilLog->write($message,$ilLog->FATAL);
2844 $ilErr->raiseError($message,$ilErr->WARNING);
2848 $query =
'DELETE FROM '.$a_db_table.
' '.
2851 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer'),array(
2866 return $this->table_tree ===
'tree';
2882 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2885 'AND '.$this->tree_pk.
' = %s ';
2886 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2889 $a_node[$this->tree_pk]));
2891 $counter = (int) $lft_childs = array();
2892 while(
$row = $ilDB->fetchObject(
$res))
2894 $lft_childs[
$row->child] =
$row->parent;
2899 if($counter != count($lft_childs))
2901 $message = sprintf(
'%s::__checkTree(): Duplicate entries for "child" in maintree! $a_node_id: %s',
2904 $this->log->write($message,$this->log->FATAL);
2905 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2909 $parent_childs = array();
2921 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2922 'WHERE child = %s '.
2924 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2929 while(
$row = $ilDB->fetchObject(
$res))
2931 $parent_childs[$a_node_id] =
$row->parent;
2937 $message = sprintf(
'%s::__getSubTreeByParentRelation(): Multiple entries in maintree! $a_node_id: %s',
2940 $this->log->write($message,$this->log->FATAL);
2941 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2945 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2946 'WHERE parent = %s ';
2947 $res = $ilDB->queryF(
$query,array(
'integer'),array($a_node_id));
2949 while(
$row = $ilDB->fetchObject(
$res))
2961 ksort($parent_childs);
2963 if(count($lft_childs) != count($parent_childs))
2965 $message = sprintf(
'%s::__validateSubtrees(): (COUNT) Tree is corrupted! Left/Right subtree does not comply .'.
2966 'with parent relation',
2968 $this->log->write($message,$this->log->FATAL);
2969 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2972 foreach($lft_childs as $key => $value)
2974 if($parent_childs[$key] != $value)
2976 $message = sprintf(
'%s::__validateSubtrees(): (COMPARE) Tree is corrupted! Left/Right subtree does not comply '.
2977 'with parent relation',
2979 $this->log->write($message,$this->log->FATAL);
2980 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2982 if($key == ROOT_FOLDER_ID)
2984 $message = sprintf(
'%s::__validateSubtrees(): (ROOT_FOLDER) Tree is corrupted! Tried to delete root folder',
2986 $this->log->write($message,$this->log->FATAL);
2987 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
3008 #ilDB::_lockTables(array('tree' => 'WRITE'));
3015 $query =
'SELECT * FROM '.$this->table_tree.
' '.
3016 'WHERE ( child = %s OR child = %s ) '.
3018 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
3024 if(
$res->numRows() != 2)
3028 $ilDB->unlockTables();
3030 $this->log->write(__METHOD__.
' Objects not found in tree!',$this->log->FATAL);
3031 $this->ilErr->raiseError(
'Error moving node',$this->ilErr->WARNING);
3033 while(
$row = $ilDB->fetchObject(
$res))
3035 if(
$row->child == $a_source_id)
3037 $source_lft =
$row->lft;
3038 $source_rgt =
$row->rgt;
3039 $source_depth =
$row->depth;
3040 $source_parent =
$row->parent;
3044 $target_lft =
$row->lft;
3045 $target_rgt =
$row->rgt;
3046 $target_depth =
$row->depth;
3050 #var_dump("<pre>",$source_lft,$source_rgt,$source_depth,$target_lft,$target_rgt,$target_depth,"<pre>");
3052 if($target_lft >= $source_lft and $target_rgt <= $source_rgt)
3056 $ilDB->unlockTables();
3058 $this->log->write(__METHOD__.
' Target is child of source',$this->log->FATAL);
3059 $this->ilErr->raiseError(
'Error moving node',$this->ilErr->WARNING);
3064 $spread_diff = $source_rgt - $source_lft + 1;
3065 #var_dump("<pre>","SPREAD_DIFF: ",$spread_diff,"<pre>");
3067 $query =
'UPDATE '.$this->table_tree.
' SET '.
3068 'lft = CASE WHEN lft > %s THEN lft + %s ELSE lft END, '.
3069 'rgt = CASE WHEN rgt >= %s THEN rgt + %s ELSE rgt END '.
3071 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer',
'integer',
'integer',
'integer'),array(
3080 if($source_lft > $target_rgt)
3082 $where_offset = $spread_diff;
3083 $move_diff = $target_rgt - $source_lft - $spread_diff;
3088 $move_diff = $target_rgt - $source_lft;
3090 $depth_diff = $target_depth - $source_depth + 1;
3093 $query =
'UPDATE '.$this->table_tree.
' SET '.
3094 'parent = CASE WHEN parent = %s THEN %s ELSE parent END, '.
3097 'depth = depth + %s '.
3102 array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
'integer'),
3109 $source_lft + $where_offset,
3110 $source_rgt + $where_offset,
3114 $query =
'UPDATE '.$this->table_tree.
' SET '.
3115 'lft = CASE WHEN lft >= %s THEN lft - %s ELSE lft END, '.
3116 'rgt = CASE WHEN rgt >= %s THEN rgt - %s ELSE rgt END '.
3120 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
3122 $source_lft + $where_offset,
3124 $source_rgt +$where_offset,
3130 $ilDB->unlockTables();
3146 $query =
"SELECT t2.lft lft, t2.rgt rgt, t2.child child, type ".
3147 "FROM ".$this->table_tree.
" t1 ".
3148 "JOIN ".$this->table_tree.
" t2 ON (t2.lft BETWEEN t1.lft AND t1.rgt) ".
3149 "JOIN ".$this->table_obj_reference.
" obr ON t2.child = obr.ref_id ".
3150 "JOIN ".$this->table_obj_data.
" obd ON obr.obj_id = obd.obj_id ".
3151 "WHERE t1.child = ".$ilDB->quote($a_endnode_id,
'integer').
" ".
3152 "AND t1.".$this->tree_pk.
" = ".$ilDB->quote($this->tree_id,
'integer').
" ".
3153 "AND t2.".$this->tree_pk.
" = ".$ilDB->quote($this->tree_id,
'integer').
" ".
3159 $nodes[
$row->child][
'lft'] =
$row->lft;
3160 $nodes[
$row->child][
'rgt'] =
$row->rgt;
3161 $nodes[
$row->child][
'child']=
$row->child;
3162 $nodes[
$row->child][
'type'] =
$row->type;
3165 return (array) $nodes;