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 $GLOBALS[
'ilLog']->write(__METHOD__.
': Delete tree with node '. $a_node);
1018 if (!is_array($a_node))
1020 $this->ilErr->raiseError(get_class($this).
"::deleteTree(): Wrong datatype for node_data! ",$this->ilErr->WARNING);
1022 if($this->
__isMainTree() and $a_node[$this->tree_pk] === 1)
1024 if($a_node[
'lft'] <= 1 or $a_node[
'rgt'] <= 2)
1026 $message = sprintf(
'%s::deleteTree(): Invalid parameters given: $a_node["lft"]: %s, $a_node["rgt"] %s',
1031 $this->log->write($message,$this->log->FATAL);
1032 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1036 $message = sprintf(
'%s::deleteTree(): Check delete failed: $a_node["lft"]: %s, $a_node["rgt"] %s',
1040 $this->log->write($message,$this->log->FATAL);
1041 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1045 $diff = $a_node[
"rgt"] - $a_node[
"lft"] + 1;
1052 #ilDB::_lockTables(array('tree' => 'WRITE'));
1059 $query = sprintf(
'SELECT * FROM '.$this->table_tree.
' '.
1060 'WHERE child = %s '.
1061 'AND '.$this->tree_pk.
' = %s ',
1062 $ilDB->quote($a_node[
'child'],
'integer'),
1063 $ilDB->quote($a_node[$this->tree_pk],
'integer'));
1065 while(
$row = $ilDB->fetchObject($res))
1067 $a_node[
'lft'] =
$row->lft;
1068 $a_node[
'rgt'] =
$row->rgt;
1069 $diff = $a_node[
"rgt"] - $a_node[
"lft"] + 1;
1073 $query = sprintf(
'DELETE FROM '.$this->table_tree.
' '.
1074 'WHERE lft BETWEEN %s AND %s '.
1075 'AND rgt BETWEEN %s AND %s '.
1076 'AND '.$this->tree_pk.
' = %s',
1077 $ilDB->quote($a_node[
'lft'],
'integer'),
1078 $ilDB->quote($a_node[
'rgt'],
'integer'),
1079 $ilDB->quote($a_node[
'lft'],
'integer'),
1080 $ilDB->quote($a_node[
'rgt'],
'integer'),
1081 $ilDB->quote($a_node[$this->tree_pk],
'integer'));
1082 $res = $ilDB->manipulate(
$query);
1087 if ($a_node[$this->tree_pk] >= 0 && $a_node[
'rgt'] - $a_node[
'lft'] >= $this->gap * 2)
1091 $query = sprintf(
'UPDATE '.$this->table_tree.
' SET '.
1092 'lft = CASE WHEN lft > %s THEN lft - %s ELSE lft END, '.
1093 'rgt = CASE WHEN rgt > %s THEN rgt - %s ELSE rgt END '.
1094 'WHERE '.$this->tree_pk.
' = %s ',
1095 $ilDB->quote($a_node[
'lft'],
'integer'),
1096 $ilDB->quote($diff,
'integer'),
1097 $ilDB->quote($a_node[
'lft'],
'integer'),
1098 $ilDB->quote($diff,
'integer'),
1099 $ilDB->quote($a_node[$this->tree_pk],
'integer'));
1101 $res = $ilDB->manipulate(
$query);
1110 #$GLOBALS['ilLog']->write(__METHOD__.': Resetting in tree cache ');
1111 $ilDB->unlockTables();
1112 $this->in_tree_cache = array();
1129 $pathIds =& $this->
getPathId($a_endnode_id, $a_startnode_id);
1135 if (count($pathIds) == 0)
1140 $inClause =
'child IN (';
1141 for ($i=0; $i < count($pathIds); $i++)
1143 if ($i > 0) $inClause .=
',';
1144 $inClause .= $ilDB->quote($pathIds[$i],
'integer');
1149 'FROM '.$this->table_tree.
' '.
1151 'WHERE '.$inClause.
' '.
1152 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = '.$this->
ilDB->
quote($this->tree_id,
'integer').
' '.
1154 $r = $ilDB->query($q);
1156 $pathFull = array();
1164 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$row['child']);
1165 $this->in_tree_cache[
$row[
'child']] = $row[
'tree'] == 1;
1188 if (!isset($a_endnode_id))
1190 $this->ilErr->raiseError(get_class($this).
"::getPathId(): No endnode_id given! ",$this->ilErr->WARNING);
1193 $fields = array(
'integer',
'integer',
'integer');
1194 $data = array($a_endnode_id,$this->tree_id,$this->tree_id);
1196 $query =
"SELECT T2.child ".
1197 "FROM ".$this->table_tree.
" T1, ".$this->table_tree.
" T2 ".
1198 "WHERE T1.child = %s ".
1199 "AND T1.lft BETWEEN T2.lft AND T2.rgt ".
1200 "AND T1.".$this->tree_pk.
" = %s ".
1201 "AND T2.".$this->tree_pk.
" = %s ".
1202 "ORDER BY T2.depth";
1205 $takeId = $a_startnode_id == 0;
1206 while(
$row = $ilDB->fetchAssoc(
$res))
1208 if ($takeId ||
$row[
'child'] == $a_startnode_id)
1211 $pathIds[] =
$row[
'child'];
1214 return $pathIds ? $pathIds : array();
1232 $takeId = $a_startnode_id == 0;
1234 if (!isset($a_endnode_id))
1236 $this->ilErr->raiseError(get_class($this).
"::getPathId(): No endnode_id given! ",$this->ilErr->WARNING);
1241 if ($this->
__isMainTree() && isset($this->depth_cache[$a_endnode_id])
1242 && isset($this->parent_cache[$a_endnode_id]))
1244 $nodeDepth = $this->depth_cache[$a_endnode_id];
1245 $parentId = $this->parent_cache[$a_endnode_id];
1249 $types = array(
'integer',
'integer');
1250 $data = array($a_endnode_id,$this->tree_id);
1251 $query =
'SELECT t.depth, t.parent '.
1252 'FROM '.$this->table_tree.
' t '.
1253 'WHERE child = %s '.
1254 'AND '.$this->tree_pk.
' = %s ';
1257 if(
$res->numRows() == 0)
1263 $nodeDepth =
$row[
'depth'];
1264 $parentId =
$row[
'parent'];
1271 if ($nodeDepth == 1)
1273 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1274 if ($takeId) $pathIds[] = $a_endnode_id;
1276 else if ($nodeDepth == 2)
1278 $takeId = $takeId || $parentId == $a_startnode_id;
1279 if ($takeId) $pathIds[] = $parentId;
1280 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1281 if ($takeId) $pathIds[] = $a_endnode_id;
1283 else if ($nodeDepth == 3)
1285 $takeId = $takeId || $this->root_id == $a_startnode_id;
1287 $takeId = $takeId || $parentId == $a_startnode_id;
1288 if ($takeId) $pathIds[] = $parentId;
1289 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1290 if ($takeId) $pathIds[] = $a_endnode_id;
1292 else if ($nodeDepth < 32)
1303 $qSelect =
't1.child c0';
1305 for ($i = 1; $i < $nodeDepth - 2; $i++)
1307 $qSelect .=
', t'.$i.
'.parent c'.$i;
1308 $qJoin .=
' JOIN '.$this->table_tree.
' t'.$i.
' ON '.
1309 't'.$i.
'.child=t'.($i - 1).
'.parent AND '.
1313 $types = array(
'integer',
'integer');
1314 $data = array($this->tree_id,$parentId);
1315 $query =
'SELECT '.$qSelect.
' '.
1316 'FROM '.$this->table_tree.
' t0 '.$qJoin.
' '.
1317 'WHERE t0.'.$this->tree_pk.
' = %s '.
1318 'AND t0.child = %s ';
1323 if (
$res->numRows() == 0)
1329 $takeId = $takeId || $this->root_id == $a_startnode_id;
1331 for ($i = $nodeDepth - 4; $i >=0; $i--)
1333 $takeId = $takeId ||
$row[
'c'.$i] == $a_startnode_id;
1334 if ($takeId) $pathIds[] =
$row[
'c'.$i];
1336 $takeId = $takeId || $parentId == $a_startnode_id;
1337 if ($takeId) $pathIds[] = $parentId;
1338 $takeId = $takeId || $a_endnode_id == $a_startnode_id;
1339 if ($takeId) $pathIds[] = $a_endnode_id;
1365 $res = $ilDB->query(
'SELECT t.depth, t.parent, t.child '.
1366 'FROM '.$this->table_tree.
' t '.
1367 'WHERE '.$ilDB->in(
"child", $a_node_ids,
false,
"integer").
1368 'AND '.$this->tree_pk.
' = '.$ilDB->quote($this->tree_id,
"integer"));
1369 while (
$row = $ilDB->fetchAssoc(
$res))
1371 $this->depth_cache[
$row[
"child"]] = $row[
"depth"];
1372 $this->parent_cache[$row[
"child"]] = $row[
"parent"];
1387 if ($this->
isCacheUsed() && isset($this->path_id_cache[$a_endnode_id][$a_startnode_id]))
1390 return $this->path_id_cache[$a_endnode_id][$a_startnode_id];
1398 $this->path_id_cache[$a_endnode_id][$a_startnode_id] = $pathIds;
1427 if ($titlePath == null || count($titlePath) == 0)
1429 if ($a_startnode_id == 0)
1440 if ($a_startnode_id != null && $a_startnode_id != 0)
1444 $parent = $a_startnode_id;
1449 $nodePath = array();
1457 require_once(
'include/Unicode/UtfNormal.php');
1458 include_once
'./Services/Utilities/classes/class.ilStr.php';
1459 $inClause =
'd.title IN (';
1460 for ($i=0; $i < count($titlePath); $i++)
1463 if ($i > 0) $inClause .=
',';
1464 $inClause .= $ilDB->quote($titlePath[$i],
'text');
1469 if ($this->table_obj_reference)
1471 $joinClause =
'JOIN '.$this->table_obj_reference.
' r ON t.child = r.'.$this->ref_pk.
' '.
1472 'JOIN '.$this->table_obj_data.
' d ON r.'.$this->obj_pk.
' = d.'.
$this->obj_pk;
1476 $joinClause =
'JOIN '.$this->table_obj_data.
' d ON t.child = d.'.
$this->obj_pk;
1483 $q =
'SELECT t.depth, t.parent, t.child, d.'.$this->obj_pk.
' obj_id, d.type, d.title '.
1484 'FROM '.$this->table_tree.
' t '.
1486 'WHERE '.$inClause.
' '.
1487 'AND t.depth <= '.(count($titlePath)+count($nodePath)).
' '.
1489 'ORDER BY t.depth, t.child ASC';
1490 $r = $ilDB->query($q);
1501 for ($i = 0; $i < count($titlePath); $i++) {
1502 $pathElementFound =
false;
1503 foreach ($rows as
$row) {
1504 if ($row[
'parent'] == $parent &&
1510 $parent = $row[
'child'];
1511 $pathElementFound =
true;
1516 if (! $pathElementFound)
1548 $pathIds = $this->
getPathId($a_endnode_id, $a_startnode_id);
1551 if (count($pathIds) == 0)
1559 for ($i = 0; $i < count($pathIds); $i++)
1561 $types[] =
'integer';
1562 $data[] = $pathIds[$i];
1565 $query =
'SELECT t.depth,t.parent,t.child,d.obj_id,d.type,d.title '.
1566 'FROM '.$this->table_tree.
' t '.
1567 'JOIN '.$this->table_obj_reference.
' r ON r.ref_id = t.child '.
1568 'JOIN '.$this->table_obj_data.
' d ON d.obj_id = r.obj_id '.
1569 'WHERE '.$ilDB->in(
't.child',
$data,
false,
'integer').
' '.
1570 'ORDER BY t.depth ';
1574 $titlePath = array();
1575 while (
$row = $ilDB->fetchAssoc(
$res))
1577 $titlePath[] =
$row;
1593 $types = array(
'integer');
1594 $query =
'SELECT lft,rgt FROM '.$this->table_tree.
' '.
1595 'WHERE '.$this->tree_pk.
' = %s ';
1597 $res = $ilDB->queryF(
$query,$types,array($this->tree_id));
1598 while (
$row = $ilDB->fetchObject(
$res))
1604 $all = array_merge($lft,$rgt);
1605 $uni = array_unique($all);
1607 if (count($all) != count($uni))
1609 $message = sprintf(
'%s::checkTree(): Tree is corrupted!',
1612 $this->log->write($message,$this->log->FATAL);
1613 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1626 $query =
'SELECT * FROM '.$this->table_tree.
' '.
1627 'WHERE '.$this->tree_pk.
' = %s '.
1629 $r1 = $ilDB->queryF(
$query,array(
'integer'),array($this->tree_id));
1631 while (
$row = $ilDB->fetchAssoc($r1))
1634 if ((
$row[
"child"] == 0) && $a_no_zero_child)
1636 $this->ilErr->raiseError(get_class($this).
"::checkTreeChilds(): Tree contains child with ID 0!",$this->ilErr->WARNING);
1639 if ($this->table_obj_reference)
1642 $query =
'SELECT * FROM '.$this->table_obj_reference.
' WHERE '.$this->ref_pk.
' = %s ';
1643 $r2 = $ilDB->queryF(
$query,array(
'integer'),array(
$row[
'child']));
1646 if ($r2->numRows() == 0)
1648 $this->ilErr->raiseError(get_class($this).
"::checkTree(): No Object-to-Reference entry found for ID ".
1649 $row[
"child"].
"!",$this->ilErr->WARNING);
1651 if ($r2->numRows() > 1)
1653 $this->ilErr->raiseError(get_class($this).
"::checkTree(): More Object-to-Reference entries found for ID ".
1654 $row[
"child"].
"!",$this->ilErr->WARNING);
1658 $obj_ref = $ilDB->fetchAssoc($r2);
1660 $query =
'SELECT * FROM '.$this->table_obj_data.
' WHERE '.$this->obj_pk.
' = %s';
1661 $r3 = $ilDB->queryF(
$query,array(
'integer'),array($obj_ref[$this->obj_pk]));
1662 if ($r3->numRows() == 0)
1664 $this->ilErr->raiseError(get_class($this).
"::checkTree(): No child found for ID ".
1665 $obj_ref[$this->obj_pk].
"!",$this->ilErr->WARNING);
1667 if ($r3->numRows() > 1)
1669 $this->ilErr->raiseError(get_class($this).
"::checkTree(): More childs found for ID ".
1670 $obj_ref[$this->obj_pk].
"!",$this->ilErr->WARNING);
1677 $query =
'SELECT * FROM '.$this->table_obj_data.
' WHERE '.$this->obj_pk.
' = %s';
1678 $r2 = $ilDB->queryF(
$query,array(
'integer'),array(
$row[
'child']));
1680 if ($r2->numRows() == 0)
1682 $this->ilErr->raiseError(get_class($this).
"::checkTree(): No child found for ID ".
1683 $row[
"child"].
"!",$this->ilErr->WARNING);
1685 if ($r2->numRows() > 1)
1687 $this->ilErr->raiseError(get_class($this).
"::checkTree(): More childs found for ID ".
1688 $row[
"child"].
"!",$this->ilErr->WARNING);
1705 $query =
'SELECT MAX(depth) depth FROM '.$this->table_tree;
1709 return $row[
'depth'];
1724 $query =
'SELECT depth FROM '.$this->table_tree.
' '.
1725 'WHERE child = %s '.
1726 'AND '.$this->tree_pk.
' = %s ';
1727 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array($a_node_id,$this->tree_id));
1753 if (!isset($a_node_id))
1756 $this->ilErr->raiseError(get_class($this).
"::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
1762 $message = sprintf(
'%s::getNodeData(): No valid parameter given! $a_node_id: %s',
1766 $this->log->write($message,$this->log->FATAL);
1767 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
1772 $query =
'SELECT * FROM '.$this->table_tree.
' '.
1774 'WHERE '.$this->table_tree.
'.child = %s '.
1775 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
1776 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
1778 $a_tree_pk === null ? $this->tree_id : $a_tree_pk));
1799 $data[
"desc"] = $a_row[
"description"];
1804 if (is_object($objDefinition))
1806 $translation_type = $objDefinition->getTranslationType(
$data[
"type"]);
1810 if ($translation_type ==
"sys")
1813 if (
$data[
"type"] ==
"rolf" and
$data[
"obj_id"] != ROLE_FOLDER_ID)
1815 $data[
"description"] = $lng->txt(
"obj_".
$data[
"type"].
"_local_desc").$data[
"title"].$data[
"desc"];
1816 $data[
"desc"] = $lng->txt(
"obj_".
$data[
"type"].
"_local_desc").$data[
"title"].$data[
"desc"];
1817 $data[
"title"] = $lng->txt(
"obj_".
$data[
"type"].
"_local");
1821 $data[
"title"] = $lng->txt(
"obj_".
$data[
"type"]);
1822 $data[
"description"] = $lng->txt(
"obj_".
$data[
"type"].
"_desc");
1823 $data[
"desc"] = $lng->txt(
"obj_".
$data[
"type"].
"_desc");
1827 elseif ($translation_type ==
"db")
1832 array_key_exists(
$data[
"obj_id"].
'.'.$lang_code, $this->translation_cache)) {
1834 $key =
$data[
"obj_id"].
'.'.$lang_code;
1835 $data[
"title"] = $this->translation_cache[$key][
'title'];
1836 $data[
"description"] = $this->translation_cache[$key][
'description'];
1837 $data[
"desc"] = $this->translation_cache[$key][
'desc'];
1843 $query =
'SELECT title,description FROM object_translation '.
1844 'WHERE obj_id = %s '.
1845 'AND lang_code = %s '.
1846 'AND NOT lang_default = %s';
1848 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer'),array(
1863 if ($this->
isCacheUsed() && count($this->translation_cache) < 1000)
1865 $key =
$data[
"obj_id"].
'.'.$lang_code;
1866 $this->translation_cache[$key] = array();
1867 $this->translation_cache[$key][
'title'] =
$data[
"title"] ;
1868 $this->translation_cache[$key][
'description'] =
$data[
"description"];
1869 $this->translation_cache[$key][
'desc'] =
$data[
"desc"];
1875 if(
$data[
'type'] ==
'crsr' or
$data[
'type'] ==
'catr')
1877 include_once(
'./Services/ContainerReference/classes/class.ilContainerReference.php');
1891 global $ilObjDataCache;
1893 if ($this->
isCacheUsed() && is_array($a_obj_ids) && is_object($ilObjDataCache))
1895 foreach ($a_obj_ids as $id)
1897 $this->translation_cache[$id.
'.'][
'title'] = $ilObjDataCache->lookupTitle($id);
1898 $this->translation_cache[$id.
'.'][
'description'] = $ilObjDataCache->lookupDescription($id);;
1899 $this->translation_cache[$id.
'.'][
'desc'] =
1900 $this->translation_cache[$id.
'.'][
'description'];
1917 if (!isset($a_node_id))
1920 #$this->ilErr->raiseError(get_class($this)."::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
1924 if ($this->
isCacheUsed() && isset($this->in_tree_cache[$a_node_id]))
1926 #$GLOBALS['ilLog']->write(__METHOD__.': Using in tree cache '.$a_node_id);
1928 return $this->in_tree_cache[$a_node_id];
1931 $query =
'SELECT * FROM '.$this->table_tree.
' '.
1932 'WHERE '.$this->table_tree.
'.child = %s '.
1933 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s';
1935 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
1939 if (
$res->numRows() > 0)
1943 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = true');
1944 $this->in_tree_cache[$a_node_id] =
true;
1952 #$GLOBALS['ilLog']->write(__METHOD__.': Storing in tree cache '.$a_node_id.' = false');
1953 $this->in_tree_cache[$a_node_id] =
false;
1970 if (!isset($a_node_id))
1973 $this->ilErr->raiseError(get_class($this).
"::getParentNodeData(): No node_id given! ",$this->ilErr->WARNING);
1976 if ($this->table_obj_reference)
1979 $innerjoin =
"JOIN ".$this->table_obj_reference.
" ON v.child=".$this->table_obj_reference.
".".$this->ref_pk.
" ".
1980 "JOIN ".$this->table_obj_data.
" ON ".$this->table_obj_reference.
".".$this->obj_pk.
"=".$this->table_obj_data.
".".$this->obj_pk.
" ";
1985 $innerjoin =
"JOIN ".$this->table_obj_data.
" ON v.child=".$this->table_obj_data.
".".$this->obj_pk.
" ";
1988 $query =
'SELECT * FROM '.$this->table_tree.
' s, '.$this->table_tree.
' v '.
1990 'WHERE s.child = %s '.
1991 'AND s.parent = v.child '.
1992 'AND s.lft > v.lft '.
1993 'AND s.rgt < v.rgt '.
1994 'AND s.'.$this->tree_pk.
' = %s '.
1995 'AND v.'.$this->tree_pk.
' = %s';
1996 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2015 if (!isset($a_startnode_id) or !isset($a_querynode_id))
2020 $query =
'SELECT * FROM '.$this->table_tree.
' s, '.$this->table_tree.
' v '.
2021 'WHERE s.child = %s '.
2022 'AND v.child = %s '.
2023 'AND s.'.$this->tree_pk.
' = %s '.
2024 'AND v.'.$this->tree_pk.
' = %s '.
2025 'AND v.lft BETWEEN s.lft AND s.rgt '.
2026 'AND v.rgt BETWEEN s.lft AND s.rgt';
2027 $res = $ilDB->queryF(
2029 array(
'integer',
'integer',
'integer',
'integer'),
2036 return $res->numRows();
2054 $message = sprintf(
'%s::addTree(): Operation not allowed on main tree! $a_tree_if: %s $a_node_id: %s',
2058 $this->log->write($message,$this->log->FATAL);
2059 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2062 if (!isset($a_tree_id))
2064 $this->ilErr->raiseError(get_class($this).
"::addTree(): No tree_id given! ",$this->ilErr->WARNING);
2067 if ($a_node_id <= 0)
2069 $a_node_id = $a_tree_id;
2072 $query =
'INSERT INTO '.$this->table_tree.
' ('.
2073 $this->tree_pk.
', child,parent,lft,rgt,depth) '.
2075 '(%s,%s,%s,%s,%s,%s)';
2076 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer'),array(
2098 if (!isset($a_type) or (!is_string($a_type)))
2100 $this->ilErr->raiseError(get_class($this).
"::getNodeDataByType(): Type not given or wrong datatype!",$this->ilErr->WARNING);
2108 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2109 'WHERE '.$this->tree_pk.
' = %s '.
2111 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2115 while (
$row = $ilDB->fetchObject(
$res))
2121 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2123 'WHERE '.$this->table_obj_data.
'.type = %s '.
2124 'AND '.$this->table_tree.
'.lft BETWEEN %s AND %s '.
2125 'AND '.$this->table_tree.
'.rgt BETWEEN %s AND %s '.
2126 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2127 $res = $ilDB->queryF(
$query,array(
'text',
'integer',
'integer',
'integer',
'integer',
'integer'),array(
2135 while(
$row = $ilDB->fetchAssoc(
$res))
2157 $message = sprintf(
'%s::removeTree(): Operation not allowed on main tree! $a_tree_if: %s',
2160 $this->log->write($message,$this->log->FATAL);
2161 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2165 $this->ilErr->raiseError(get_class($this).
"::removeTree(): No tree_id given! Action aborted",$this->ilErr->MESSAGE);
2168 $query =
'DELETE FROM '.$this->table_tree.
2169 ' WHERE '.$this->tree_pk.
' = %s ';
2170 $res = $ilDB->manipulateF(
$query,array(
'integer'),array($a_tree_id));
2187 $message = sprintf(
'%s::saveSubTree(): No valid parameter given! $a_node_id: %s',
2190 $this->log->write($message,$this->log->FATAL);
2191 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2202 #ilDB::_lockTables(array('tree' => 'WRITE',
2203 # 'object_reference' => 'WRITE'));
2208 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2209 'WHERE '.$this->tree_pk.
' = %s '.
2211 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2215 while(
$row = $ilDB->fetchObject(
$res))
2222 $query =
'SELECT child FROM '.$this->table_tree.
' '.
2223 'WHERE '.$this->tree_pk.
' = %s '.
2224 'AND lft BETWEEN %s AND %s ';
2225 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2230 $subnodes = array();
2231 while(
$row = $ilDB->fetchAssoc(
$res))
2233 $subnodes[] =
$row[
'child'];
2236 if(!count($subnodes))
2243 $ilDB->unlockTables();
2250 foreach($subnodes as $child)
2261 $query =
'UPDATE '.$this->table_tree.
' '.
2263 'WHERE '.$this->tree_pk.
' = %s '.
2264 'AND lft BETWEEN %s AND %s ';
2265 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer',
'integer',
'integer'),array(
2273 $ilDB->unlockTables();
2285 return $this->
isSaved($a_node_id);
2296 if ($this->
isCacheUsed() && isset($this->is_saved_cache[$a_node_id]))
2299 return $this->is_saved_cache[$a_node_id];
2302 $query =
'SELECT '.$this->tree_pk.
' FROM '.$this->table_tree.
' '.
2303 'WHERE child = %s ';
2304 $res = $ilDB->queryF(
$query,array(
'integer'),array($a_node_id));
2307 if (
$row[$this->tree_pk] < 0)
2311 $this->is_saved_cache[$a_node_id] =
true;
2319 $this->is_saved_cache[$a_node_id] =
false;
2335 if (!is_array($a_node_ids) || !$this->
isCacheUsed())
2340 $query =
'SELECT '.$this->tree_pk.
', child FROM '.$this->table_tree.
' '.
2341 'WHERE '.$ilDB->in(
"child", $a_node_ids,
false,
"integer");
2344 while (
$row = $ilDB->fetchAssoc(
$res))
2346 if (
$row[$this->tree_pk] < 0)
2350 $this->is_saved_cache[
$row[
"child"]] =
true;
2357 $this->is_saved_cache[
$row[
"child"]] =
false;
2374 if (!isset($a_parent_id))
2376 $this->ilErr->raiseError(get_class($this).
"::getSavedNodeData(): No node_id given!",$this->ilErr->WARNING);
2379 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2381 'WHERE '.$this->table_tree.
'.'.$this->tree_pk.
' < %s '.
2382 'AND '.$this->table_tree.
'.parent = %s';
2383 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2387 while(
$row = $ilDB->fetchAssoc(
$res))
2392 return $saved ? $saved : array();
2405 $query =
'SELECT '.$this->table_obj_data.
'.obj_id FROM '.$this->table_tree.
' '.
2407 'WHERE '.$this->table_tree.
'.'.$this->tree_pk.
' < '.$ilDB->quote(0,
'integer').
' '.
2408 'AND '.$ilDB->in($this->table_obj_data.
'.obj_id', $a_obj_ids,
'',
'integer');
2410 while(
$row = $ilDB->fetchAssoc(
$res))
2412 $saved[] =
$row[
'obj_id'];
2415 return $saved ? $saved : array();
2428 if (!isset($a_node_id))
2430 $this->ilErr->raiseError(get_class($this).
"::getParentId(): No node_id given! ",$this->ilErr->WARNING);
2433 $query =
'SELECT parent FROM '.$this->table_tree.
' '.
2434 'WHERE child = %s '.
2435 'AND '.$this->tree_pk.
' = %s ';
2436 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2441 return $row->parent;
2454 if (!isset($a_node_id))
2456 $this->ilErr->raiseError(get_class($this).
"::getLeftValued(): No node_id given! ",$this->ilErr->WARNING);
2459 $query =
'SELECT lft FROM '.$this->table_tree.
' '.
2460 'WHERE child = %s '.
2461 'AND '.$this->tree_pk.
' = %s ';
2462 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2479 if (!isset($a_node))
2481 $this->ilErr->raiseError(get_class($this).
"::getChildSequenceNumber(): No node_id given! ",$this->ilErr->WARNING);
2486 $query =
'SELECT count(*) cnt FROM '.$this->table_tree.
' '.
2491 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2493 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer',
'integer'),array(
2501 $query =
'SELECT count(*) cnt FROM '.$this->table_tree.
' '.
2505 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2507 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2527 $query =
'SELECT child FROM '.$this->table_tree.
' '.
2528 'WHERE parent = %s '.
2529 'AND '.$this->tree_pk.
' = %s ';
2530 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2534 $this->root_id =
$row->child;
2549 $this->root_id = $a_root_id;
2569 $this->tree_id = $a_tree_id;
2583 if (!isset($a_node_id))
2585 $this->ilErr->raiseError(get_class($this).
"::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
2589 $query =
'SELECT lft FROM '.$this->table_tree.
' '.
2590 'WHERE '.$this->table_tree.
'.child = %s '.
2591 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2592 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2596 $curr_node = $ilDB->fetchAssoc(
$res);
2600 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2603 'AND '.$this->table_obj_data.
'.type = %s '.
2604 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2607 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer'),array(
2614 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2617 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2620 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2625 if (
$res->numRows() < 1)
2647 if (!isset($a_node_id))
2649 $this->ilErr->raiseError(get_class($this).
"::getNodeData(): No node_id given! ",$this->ilErr->WARNING);
2653 $query =
'SELECT lft FROM '.$this->table_tree.
' '.
2654 'WHERE '.$this->table_tree.
'.child = %s '.
2655 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s ';
2656 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2660 $curr_node = $ilDB->fetchAssoc(
$res);
2664 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2667 'AND '.$this->table_obj_data.
'.type = %s '.
2668 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2669 'ORDER BY lft DESC';
2671 $res = $ilDB->queryF(
$query,array(
'integer',
'text',
'integer'),array(
2678 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2681 'AND '.$this->table_tree.
'.'.$this->tree_pk.
' = %s '.
2682 'ORDER BY lft DESC';
2684 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2689 if (
$res->numRows() < 1)
2727 2 => array(
'name' => $this->table_obj_reference,
'type' =>
ilDB::LOCK_WRITE),
2729 4 => array(
'name' =>
'object_data',
'type' =>
ilDB::LOCK_WRITE,
'alias' =>
'od'),
2730 5 => array(
'name' =>
'container_reference',
'type' =>
ilDB::LOCK_WRITE,
'alias' =>
'cr')
2736 $ilDB->unlockTables();
2756 $query =
'UPDATE '.$this->table_tree.
' SET lft = %s WHERE child = %s';
2757 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer'),array(
2763 foreach ($childs as $child)
2765 $i = $this->
__renumber($child[
"child"],$i+1);
2770 if (count($childs) > 0)
2772 $i += $this->gap * 2;
2776 $query =
'UPDATE '.$this->table_tree.
' SET rgt = %s WHERE child = %s';
2777 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer'),array(
2797 $cache_key = $a_ref_id.
'.'.$a_type.
'.'.((int)$a_exclude_source_check);
2801 array_key_exists($cache_key, $this->parent_type_cache))
2803 return $this->parent_type_cache[$cache_key];
2807 $do_cache = ($this->
__isMainTree() && count($this->parent_type_cache) < 1000);
2814 $this->parent_type_cache[$cache_key] =
false;
2822 if($a_exclude_source_check)
2827 foreach(
$path as $node)
2830 if($node[
"type"] == $a_type)
2834 $this->parent_type_cache[$cache_key] = $node[
"child"];
2836 return $node[
"child"];
2842 $this->parent_type_cache[$cache_key] =
false;
2860 if($a_db_table ===
'tree')
2862 if($a_tree == 1 and $a_child == ROOT_FOLDER_ID)
2864 $message = sprintf(
'%s::_removeEntry(): Tried to delete root node! $a_tree: %s $a_child: %s',
2868 $ilLog->write($message,$ilLog->FATAL);
2869 $ilErr->raiseError($message,$ilErr->WARNING);
2873 $query =
'DELETE FROM '.$a_db_table.
' '.
2876 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer'),array(
2891 return $this->table_tree ===
'tree';
2907 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2910 'AND '.$this->tree_pk.
' = %s ';
2911 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
2914 $a_node[$this->tree_pk]));
2916 $counter = (int) $lft_childs = array();
2917 while(
$row = $ilDB->fetchObject(
$res))
2919 $lft_childs[
$row->child] =
$row->parent;
2924 if($counter != count($lft_childs))
2926 $message = sprintf(
'%s::__checkTree(): Duplicate entries for "child" in maintree! $a_node_id: %s',
2929 $this->log->write($message,$this->log->FATAL);
2930 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2934 $parent_childs = array();
2946 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2947 'WHERE child = %s '.
2949 $res = $ilDB->queryF(
$query,array(
'integer',
'integer'),array(
2954 while(
$row = $ilDB->fetchObject(
$res))
2956 $parent_childs[$a_node_id] =
$row->parent;
2962 $message = sprintf(
'%s::__getSubTreeByParentRelation(): Multiple entries in maintree! $a_node_id: %s',
2965 $this->log->write($message,$this->log->FATAL);
2966 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2970 $query =
'SELECT * FROM '.$this->table_tree.
' '.
2971 'WHERE parent = %s ';
2972 $res = $ilDB->queryF(
$query,array(
'integer'),array($a_node_id));
2974 while(
$row = $ilDB->fetchObject(
$res))
2986 ksort($parent_childs);
2988 if(count($lft_childs) != count($parent_childs))
2990 $message = sprintf(
'%s::__validateSubtrees(): (COUNT) Tree is corrupted! Left/Right subtree does not comply .'.
2991 'with parent relation',
2993 $this->log->write($message,$this->log->FATAL);
2994 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
2997 foreach($lft_childs as $key => $value)
2999 if($parent_childs[$key] != $value)
3001 $message = sprintf(
'%s::__validateSubtrees(): (COMPARE) Tree is corrupted! Left/Right subtree does not comply '.
3002 'with parent relation',
3004 $this->log->write($message,$this->log->FATAL);
3005 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
3007 if($key == ROOT_FOLDER_ID)
3009 $message = sprintf(
'%s::__validateSubtrees(): (ROOT_FOLDER) Tree is corrupted! Tried to delete root folder',
3011 $this->log->write($message,$this->log->FATAL);
3012 $this->ilErr->raiseError($message,$this->ilErr->WARNING);
3033 #ilDB::_lockTables(array('tree' => 'WRITE'));
3040 $query =
'SELECT * FROM '.$this->table_tree.
' '.
3041 'WHERE ( child = %s OR child = %s ) '.
3042 'AND '.$this->tree_pk.
' = %s ';
3043 $res = $ilDB->queryF(
$query,array(
'integer',
'integer',
'integer'),array(
3049 if(
$res->numRows() != 2)
3053 $ilDB->unlockTables();
3055 $this->log->write(__METHOD__.
' Objects not found in tree!',$this->log->FATAL);
3056 $this->ilErr->raiseError(
'Error moving node',$this->ilErr->WARNING);
3058 while(
$row = $ilDB->fetchObject(
$res))
3060 if(
$row->child == $a_source_id)
3062 $source_lft =
$row->lft;
3063 $source_rgt =
$row->rgt;
3064 $source_depth =
$row->depth;
3065 $source_parent =
$row->parent;
3069 $target_lft =
$row->lft;
3070 $target_rgt =
$row->rgt;
3071 $target_depth =
$row->depth;
3075 #var_dump("<pre>",$source_lft,$source_rgt,$source_depth,$target_lft,$target_rgt,$target_depth,"<pre>");
3077 if($target_lft >= $source_lft and $target_rgt <= $source_rgt)
3081 $ilDB->unlockTables();
3083 $this->log->write(__METHOD__.
' Target is child of source',$this->log->FATAL);
3084 $this->ilErr->raiseError(
'Error moving node',$this->ilErr->WARNING);
3089 $spread_diff = $source_rgt - $source_lft + 1;
3090 #var_dump("<pre>","SPREAD_DIFF: ",$spread_diff,"<pre>");
3092 $query =
'UPDATE '.$this->table_tree.
' SET '.
3093 'lft = CASE WHEN lft > %s THEN lft + %s ELSE lft END, '.
3094 'rgt = CASE WHEN rgt >= %s THEN rgt + %s ELSE rgt END '.
3095 'WHERE '.$this->tree_pk.
' = %s ';
3096 $res = $ilDB->manipulateF(
$query,array(
'integer',
'integer',
'integer',
'integer',
'integer'),array(
3105 if($source_lft > $target_rgt)
3107 $where_offset = $spread_diff;
3108 $move_diff = $target_rgt - $source_lft - $spread_diff;
3113 $move_diff = $target_rgt - $source_lft;
3115 $depth_diff = $target_depth - $source_depth + 1;
3118 $query =
'UPDATE '.$this->table_tree.
' SET '.
3119 'parent = CASE WHEN parent = %s THEN %s ELSE parent END, '.
3122 'depth = depth + %s '.
3125 'AND '.$this->tree_pk.
' = %s ';
3127 array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
'integer'),
3134 $source_lft + $where_offset,
3135 $source_rgt + $where_offset,
3139 $query =
'UPDATE '.$this->table_tree.
' SET '.
3140 'lft = CASE WHEN lft >= %s THEN lft - %s ELSE lft END, '.
3141 'rgt = CASE WHEN rgt >= %s THEN rgt - %s ELSE rgt END '.
3142 'WHERE '.$this->tree_pk.
' = %s ';
3145 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
3147 $source_lft + $where_offset,
3149 $source_rgt +$where_offset,
3155 $ilDB->unlockTables();
3158 global $ilAppEventHandler;
3160 $ilAppEventHandler->raise(
3164 'tree' => $this->table_tree,
3165 'source_id' => $a_source_id,
3166 'target_id' => $a_target_id)
3183 $query =
"SELECT t2.lft lft, t2.rgt rgt, t2.child child, type ".
3184 "FROM ".$this->table_tree.
" t1 ".
3185 "JOIN ".$this->table_tree.
" t2 ON (t2.lft BETWEEN t1.lft AND t1.rgt) ".
3186 "JOIN ".$this->table_obj_reference.
" obr ON t2.child = obr.ref_id ".
3187 "JOIN ".$this->table_obj_data.
" obd ON obr.obj_id = obd.obj_id ".
3188 "WHERE t1.child = ".$ilDB->quote($a_endnode_id,
'integer').
" ".
3189 "AND t1.".$this->tree_pk.
" = ".$ilDB->quote($this->tree_id,
'integer').
" ".
3190 "AND t2.".$this->tree_pk.
" = ".$ilDB->quote($this->tree_id,
'integer').
" ".
3196 $nodes[
$row->child][
'lft'] =
$row->lft;
3197 $nodes[
$row->child][
'rgt'] =
$row->rgt;
3198 $nodes[
$row->child][
'child']=
$row->child;
3199 $nodes[
$row->child][
'type'] =
$row->type;
3202 return (array) $nodes;