4 include_once
'./Services/Tree/interfaces/interface.ilTreeImplementation.php';
27 $this->tree = $a_tree;
58 $node = $this->
getTree()->getNodeTreeData($a_node_id);
59 $query =
'SELECT child FROM '.$this->getTree()->getTreeTable().
' '.
60 'WHERE path BETWEEN '.
61 $ilDB->quote($node[
'path'],
'text').
' AND '.
62 $ilDB->quote($node[
'path'].
'.Z',
'text').
' '.
64 'AND '.$this->getTree()->getTreePk().
' = %s';
68 array(
'integer',
'integer'),
71 while(
$row = $ilDB->fetchAssoc(
$res))
73 $childs[] =
$row[
'child'];
75 return $childs ? $childs :
array();
86 if($a_node_a[
'child'] == $a_node_b[
'child'])
91 if(stripos($a_node_a[
'path'], $a_node_b[
'path'].
'.') === 0)
96 if(stripos($a_node_b[
'path'], $a_node_a[
'path'] .
'.') === 0)
101 $path_a = substr($a_node_a[
'path'],0,strrpos($a_node_a[
'path'],
'.'));
102 $path_b = substr($a_node_b[
'path'],0,strrpos($a_node_b[
'path'],
'.'));
106 if($a_node_a[
'path']
and (strcmp($path_a,$path_b) === 0))
130 if(is_array($a_types))
134 $type_str =
"AND ".$ilDB->in($this->
getTree()->getObjectDataTable().
".type", $a_types,
false,
"text");
137 else if(strlen($a_types))
139 $type_str =
"AND ".$this->getTree()->getObjectDataTable().
".type = ".$ilDB->quote($a_types,
"text");
143 if($type_str
or $a_force_join_reference)
145 $join = $this->
getTree()->buildJoin();
151 $fields = implode(
',',$a_fields);
157 'FROM '.$this->getTree()->getTreeTable().
' '.
159 'WHERE '.$this->getTree()->getTreeTable().
'.path '.
161 $ilDB->quote($a_node[
'path'],
'text').
' AND '.
162 $ilDB->quote($a_node[
'path'].
'.Z',
'text').
' '.
163 'AND '.$this->getTree()->getTreeTable().
'.'.$this->
getTree()->getTreePk().
' = '.$ilDB->quote($this->
getTree()->getTreeId(),
'integer').
' '.
165 'ORDER BY '.$this->getTree()->getTreeTable().
'.path';
181 $query =
'SELECT path FROM ' . $this->
getTree()->getTreeTable() .
' '.
182 'WHERE child = '. $ilDB->quote($a_endnode,
'integer').
' ';
186 while (
$row = $ilDB->fetchAssoc(
$res))
191 $pathIds = explode(
'.',
$path);
193 if ($a_startnode != 0)
195 while (count($pathIds) > 0 && $pathIds[0] != $a_startnode)
197 array_shift($pathIds);
215 $insert_node_callable =
function(
ilDBInterface $ilDB) use ($a_node_id, $a_parent_id, $a_pos)
220 $res = $ilDB->queryF(
221 'SELECT parent, depth, path FROM ' . $this->
getTree()->getTreeTable() .
' ' .
222 'WHERE child = %s '.
' '.
223 'AND ' . $this->
getTree()->getTreePk() .
' = %s',
array(
'integer',
'integer'),
227 $r = $ilDB->fetchObject(
$res);
229 if (
$r->parent === NULL)
236 if (
$r->depth >= $this->getMaximumPossibleDepth())
242 $parentPath =
$r->path;
243 $depth =
$r->depth + 1;
249 'child' =>
array(
'integer', $a_node_id),
250 'parent' =>
array(
'integer', $a_parent_id),
251 'lft' =>
array(
'integer', $lft),
252 'rgt' =>
array(
'integer', $rgt),
253 'depth' =>
array(
'integer', $depth),
254 'path' =>
array(
'text', $parentPath .
"." . $a_node_id)));
260 if ($this->
getTree()->__isMainTree())
262 $ilAtomQuery = $ilDB->buildAtomQuery();
263 $ilAtomQuery->addTableLock(
"tree");
265 $ilAtomQuery->addQueryCallable($insert_node_callable);
271 $insert_node_callable($ilDB);
287 $query =
'SELECT * FROM '.$this->getTree()->getTreeTable().
' '.
288 'WHERE '.$this->getTree()->getTreeTable().
'.child = %s '.
289 'AND '.$this->getTree()->getTreeTable().
'.'.$this->
getTree()->getTreePk().
' = %s ';
292 $this->
getTree()->getTreeId()));
295 $query =
'DELETE FROM '.$this->getTree()->getTreeTable().
' '.
296 'WHERE path BETWEEN '.$ilDB->quote(
$row[
'path'],
'text').
' '.
297 'AND '.$ilDB->quote(
$row[
'path'].
'.Z',
'text').
' '.
298 'AND '.$this->getTree()->getTreePk().
' = '.$ilDB->quote($this->
getTree()->getTreeId(),
'integer');
299 $ilDB->manipulate(
$query);
303 if($this->
getTree()->__isMainTree())
305 $ilAtomQuery = $ilDB->buildAtomQuery();
306 $ilAtomQuery->addTableLock(
'tree');
307 $ilAtomQuery->addQueryCallable($delete_tree_callable);
312 $delete_tree_callable($ilDB);
330 $node = $this->
getTree()->getNodeTreeData($a_node_id);
334 UPDATE ' . $this->
getTree()->getTreeTable().
' '.
335 'SET tree = %s' .
' '.
336 'WHERE ' . $this->
getTree()->getTreePk() .
' = %s ' .
337 'AND path BETWEEN %s AND %s',
338 array(
'integer',
'integer',
'text',
'text'),
339 array(-$a_node_id, $this->
getTree()->getTreeId(), $node[
'path'], $node[
'path'] .
'.Z'));
345 if ($this->
getTree()->__isMainTree())
347 $ilAtomQuery = $ilDB->buildAtomQuery();
348 $ilAtomQuery->addTableLock(
"tree");
350 $ilAtomQuery->addQueryCallable($move_to_trash_callable);
356 $move_to_trash_callable($ilDB);
371 public function moveTree($a_source_id, $a_target_id, $a_position)
375 $move_tree_callable =
function(
ilDBInterface $ilDB) use ($a_source_id, $a_target_id, $a_position)
381 'SELECT depth, child, parent, path FROM ' . $this->
getTree()->getTreeTable() .
' '.
382 'WHERE ' . $ilDB->in(
'child',
array($a_source_id, $a_target_id),
false,
'integer') .
' '.
383 'AND tree = ' . $ilDB->quote($this->
getTree()->getTreeId(),
'integer')
387 if ($ilDB->numRows(
$res) != 2)
393 while (
$row = $ilDB->fetchObject(
$res))
395 if (
$row->child == $a_source_id)
397 $source_path =
$row->path;
398 $source_depth =
$row->depth;
399 $source_parent =
$row->parent;
403 $target_path =
$row->path;
404 $target_depth =
$row->depth;
408 if ($target_depth >= $source_depth)
415 $res = $ilDB->queryF(
416 'SELECT MAX(depth) max_depth '.
417 'FROM ' . $this->
getTree()->getTreeTable() .
' '.
418 'WHERE path BETWEEN %s AND %s'.
' '.
420 array(
'text',
'text',
'integer'),
array($source_path, $source_path .
'.Z', $this->
getTree()->getTreeId()));
424 if (
$row->max_depth - $source_depth + $target_depth + 1 > $this->getMaximumPossibleDepth())
431 if (substr($target_path .
'.', 0, strlen($source_path) .
'.') == $source_path .
'.')
436 $depth_diff = $target_depth - $source_depth + 1;
440 UPDATE ' . $this->
getTree()->getTreeTable() .
' 441 SET parent = CASE WHEN parent = ' . $ilDB->quote($source_parent,
'integer') .
' 442 THEN ' . $ilDB->quote($a_target_id,
'integer') .
' 445 path = ' . $ilDB->concat(
array(
446 array($ilDB->quote($target_path,
'text'),
'text'),
447 array($ilDB->substr(
'path', strrpos(
'.' . $source_path,
'.')),
'text'))) .
' , 449 depth = depth + ' . $ilDB->quote($depth_diff,
'integer') .
' 451 WHERE path BETWEEN ' . $ilDB->quote($source_path,
'text') .
' 452 AND ' . $ilDB->quote($source_path .
'.Z',
'text') .
' 454 AND tree = ' . $ilDB->quote($this->
getTree()->getTreeId(),
'integer');
458 $ilDB->manipulate(
$query);
462 if ($this->
getTree()->__isMainTree())
464 $ilAtomQuery = $ilDB->buildAtomQuery();
465 $ilAtomQuery->addTableLock(
"tree");
466 $ilAtomQuery->addQueryCallable($move_tree_callable);
470 $move_tree_callable($ilDB);
481 $r = $ilDB->queryF(
'SELECT DISTINCT * FROM tree WHERE parent = %s',
array(
'integer'),
array(0));
483 while (
$row = $ilDB->fetchAssoc(
$r))
485 $success = self::createMaterializedPath(0,
'');
502 SET path = CONCAT(COALESCE(' . $ilDB->quote($parentPath,
'text') .
', \'\'), COALESCE( ' . $ilDB->cast(
"child",
"text") .
' , \'\')) 504 $r = $ilDB->manipulateF($q,
array(
'integer'),
array($parent));
506 $r = $ilDB->queryF(
'SELECT child FROM tree WHERE parent = %s',
array(
'integer'),
array($parent));
508 while (
$row = $ilDB->fetchAssoc(
$r))
510 self::createMaterializedPath(
$row[
'child'], $parentPath .
$row[
'child'] .
'.');
528 $query =
"SELECT t2.child child, type, t2.path path " .
529 "FROM " . $this->
getTree()->getTreeTable() .
" t1 " .
530 "JOIN " . $this->
getTree()->getTreeTable() .
" t2 ON (t2.path BETWEEN t1.path AND CONCAT(t1.path, '.Z')) " .
531 "JOIN " . $this->
getTree()->getTableReference() .
" obr ON t2.child = obr.ref_id " .
532 "JOIN " . $this->
getTree()->getObjectDataTable() .
" obd ON obr.obj_id = obd.obj_id " .
533 "WHERE t1.child = " . $ilDB->quote($a_endnode_id,
'integer') .
" " .
534 "AND t1." . $this->
getTree()->getTreePk() .
" = " . $ilDB->quote($this->
getTree()->getTreeId(),
'integer') .
" " .
535 "AND t2." . $this->
getTree()->getTreePk() .
" = " . $ilDB->quote($this->
getTree()->getTreeId(),
'integer') .
" " .
543 #$nodes[$row->child]['lft'] = $row->lft; 544 #$nodes[$row->child]['rgt'] = $row->rgt; 545 $nodes[
$row->child][
'child'] =
$row->child;
546 $nodes[
$row->child][
'type'] =
$row->type;
547 $nodes[
$row->child][
'path'] =
$row->path;
550 $depth_first_compare =
function($a, $b)
552 $a_exploded = explode(
'.', $a[
'path']);
553 #ilLoggerFactory::getLogger('tree')->debug(print_r($a_exploded,TRUE)); 554 $b_exploded = explode(
'.', $b[
'path']);
557 foreach($a_exploded as $num)
559 $a_padded .= (str_pad((
string) $num, 14,
'0', STR_PAD_LEFT));
562 foreach($b_exploded as $num)
564 $b_padded .= (str_pad((
string) $num, 14,
'0', STR_PAD_LEFT));
567 #ilLoggerFactory::getLogger('tree')->debug($a_padded); 568 return strcasecmp($a_padded, $b_padded);
571 #ilLoggerFactory::getLogger('tree')->debug(print_r($nodes,TRUE)); 573 uasort($nodes,$depth_first_compare);
575 #ilLoggerFactory::getLogger('tree')->debug(print_r($nodes,TRUE)); 577 return (
array) $nodes;
588 $query =
'select child from '.$this->getTree()->getTreeTable().
' child where not exists '.
590 'select child from '.$this->getTree()->getTreeTable().
' parent where child.parent = parent.child and '.
591 '(child.path BETWEEN parent.path AND CONCAT(parent.path,'.$ilDB->quote(
'Z',
'text').
') )'.
')'.
592 'and '.$this->getTree()->getTreePk().
' = '.$this->
getTree()->getTreeId().
' and child <> 1';
Thrown if invalid tree strucutes are found.
getMaximumPossibleDepth()
Get maximum possible depth.
deleteTree($a_node_id)
Delete a subtree.
static createMaterializedPath($parent, $parentPath)
static createFromParentReleation()
validateParentRelations()
Validaate parent relations.
getRelation($a_node_a, $a_node_b)
Get relation of two nodes.
getSubTreeQuery($a_node, $a_types='', $a_force_join_reference=true, $a_fields=array())
Get subtree query.
moveToTrash($a_node_id)
Move subtree to trash.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
Create styles array
The data for the language used.
getTree()
Get tree object.
moveTree($a_source_id, $a_target_id, $a_position)
move source subtree to target node
insertNode($a_node_id, $a_parent_id, $a_pos)
Insert new node under parent node.
getSubtreeInfo($a_endnode_id)
Base class for materialize path based trees Based on implementation of Werner Randelshofer.
static getLogger($a_component_id)
Get component logger.
getPathIds($a_endnode, $a_startnode=0)
Get path ids.
Interface for tree implementations Currrently nested set or materialize path.
getSubTreeIds($a_node_id)
Get subtree ids.
__construct(ilTree $a_tree)
Constructor.