Apache Zeta Components Manual :: File Source for db_parent_child.php
Source for file db_parent_child.php
Documentation is available at db_parent_child.php
* File containing the ezcTreeDbParentChild class.
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version //autogentag//
* @package TreeDatabaseTiein
* ezcTreeDbParentChild implements a tree backend which stores parent/child
* information in a simple table containing the node's ID and its parent's ID.
* The table that stores the index (configured using the $indexTableName argument
* of the {@link __construct} method) should contain at least two fields. The
* first one 'id' will contain the node's ID, the second one 'parent_id' the ID
* of the node's parent. Both fields should be of the same database field type.
* Supported field types are either integer or a string type.
* In order to use auto-generated IDs, the 'id' field needs to be an
* auto-incrementing integer field, by using either an auto-increment field, or
* @property-read ezcTreeDbDataStore $store
* The data store that is used for retrieving/storing data.
* @property string $nodeClassName
* Which class is used as tree node - this class *must* inherit
* @package TreeDatabaseTiein
* @version //autogentag//
* Creates a new ezcTreeDbParentChild object.
* The different arguments to the method configure which database
* connection ($dbh) is used to access the database and the $indexTableName
* argument which table is used to retrieve the relation data from. The
* $store argument configure which data store is used with this tree.
* It is up to the user to create the database table and make sure it is
* @param ezcDbHandler $dbh
* @param string $indexTableName
* @param ezcTreeDbDataStore $store
public static function create( ezcDbHandler $dbh, $indexTableName, ezcTreeDbDataStore $store )
* Runs SQL to get all the children of the node with ID $nodeId as a PDO
$q =
$db->createSelectQuery();
// WHERE parent_id = $nodeId
$q->select( 'id, parent_id' )
->where( $q->expr->eq( 'parent_id', $q->bindValue( $nodeId ) ) );
* Adds the children nodes of the node with ID $nodeId to the
* @param ezcTreeNodeList $list
private function addChildNodesDepthFirst( ezcTreeNodeList $list, $nodeId )
$list->addNode( new $className( $this, $record['id'] ) );
$this->addChildNodesDepthFirst( $list, $record['id'] );
* Returns all the children of the node with ID $nodeId.
* @return ezcTreeNodeList
$list->addNode( new $className( $this, $record['id'] ) );
* Returns all the nodes in the path from the root node to the node with ID
* $nodeId, including those two nodes.
* @return ezcTreeNodeList
$nodes[] =
new $className( $this, $nodeId );
while ( $nodeId !=
null )
$nodes[] =
new $className( $this, $nodeId );
* Returns the node with ID $nodeId and all its children, sorted according to
* the {@link http://en.wikipedia.org/wiki/Depth-first_search Depth-first sorting}
* @return ezcTreeNodeList
$list->addNode( new $className( $this, $nodeId ) );
$this->addChildNodesDepthFirst( $list, $nodeId );
* Alias for fetchSubtreeDepthFirst().
* @return ezcTreeNodeList
* Adds the children nodes of the node with ID $nodeId to the
* @param ezcTreeNodeList $list
foreach ( $childRecords as $record )
$list->addNode( new $className( $this, $record['id'] ) );
foreach ( $childRecords as $record )
* Returns the node with ID $nodeId and all its children, sorted according to
* the {@link http://en.wikipedia.org/wiki/Breadth-first_search Breadth-first sorting}
* @return ezcTreeNodeList
$list->addNode( new $className( $this, $nodeId ) );
* Returns the number of direct children of the node with ID $nodeId.
$q =
$db->createSelectQuery();
// WHERE parent_id = $nodeId
$q->select( 'count(id)' )
->where( $q->expr->eq( 'parent_id', $q->bindValue( $nodeId ) ) );
return (int)
$s->fetchColumn( 0 );
* Adds the number of children with for the node with ID $nodeId nodes to
* Returns the number of children of the node with ID $nodeId, recursively.
* Returns the distance from the root node to the node with ID $nodeId.
while ( $nodeId !==
null )
* Returns whether the node with ID $nodeId has children.
* Returns whether the node with ID $childId is a direct child of the node
* @param string $parentId
public function isChildOf( $childId, $parentId )
$parentId = (string)
$parentId;
return $parentId ===
$nodeId;
* Returns whether the node with ID $childId is a direct or indirect child
* of the node with ID $parentId.
* @param string $parentId
$parentId = (string)
$parentId;
if ( $parentId ===
$nodeId )
} while ( $nodeId !==
null );
* Returns whether the nodes with IDs $child1Id and $child2Id are siblings
* (ie, they share the same parent).
* @param string $child1Id
* @param string $child2Id
return $nodeId1 ===
$nodeId2 && (string)
$child1Id !== (string)
$child2Id;
* Sets a new node as root node, this also wipes out the whole tree.
* @param ezcTreeNode $node
$q =
$db->createDeleteQuery();
$this->store->deleteDataForAllNodes();
$q =
$db->createInsertQuery();
->set( 'parent_id', "null" )
->set( 'id', $q->bindValue( $node->id ) );
$this->store->storeDataForNode( $node, $node->data );
* Creates the query to insert an empty node into the database, so that the last-inserted ID can be obtained.
$q =
$db->createInsertQuery();
->set( 'parent_id', $q->bindValue( null ) );
* Adds the node $childNode as child of the node with ID $parentId.
* @param string $parentId
* @param ezcTreeNode $childNode
public function addChild( $parentId, ezcTreeNode $childNode )
$this->addTransactionItem( new ezcTreeTransactionItem( ezcTreeTransactionItem::ADD, $childNode, null, $parentId ) );
$q->set( 'parent_id', $q->bindValue( $parentId ) )
->set( 'id', $q->bindValue( $childNode->id ) );
$this->store->storeDataForNode( $childNode, $childNode->data );
* Deletes all nodes in the node list $list.
* @param ezcTreeNodeList $list
private function deleteNodes( ezcTreeNodeList $list )
$q =
$db->createDeleteQuery();
$nodeIdList[] = (string)
$nodeId;
// DELETE FROM indexTable
// WHERE id in ( $list );
$q->where( $q->expr->in( 'id', $nodeIdList ) );
* Deletes the node with ID $nodeId from the tree, including all its children.
public function delete( $nodeId )
$this->addTransactionItem( new ezcTreeTransactionItem( ezcTreeTransactionItem::DELETE, null, $nodeId ) );
$this->deleteNodes( $nodeList );
$this->store->deleteDataForNodes( $nodeList );
* Moves the node with ID $nodeId as child to the node with ID $targetParentId.
* @param string $targetParentId
public function move( $nodeId, $targetParentId )
$this->addTransactionItem( new ezcTreeTransactionItem( ezcTreeTransactionItem::MOVE, null, $nodeId, $targetParentId ) );
$q =
$db->createUpdateQuery();
->set( 'parent_id', $q->bindValue( $targetParentId ) )
->where( $q->expr->eq( 'id', $q->bindValue( $nodeId ) ) );
* Fixates the transaction.