combined hierarchical data docs(missing from TOC structure renaming)
This commit is contained in:
parent
c3439aeebb
commit
4a93637eb9
@ -1 +1,4 @@
|
||||
Not yet implemented
|
||||
Not yet implemented
|
||||
|
||||
|
||||
|
||||
|
@ -1 +1,404 @@
|
||||
This is an example to show how you would set up and use the doctrine tree interface with the NestedSet implementation (currently the most comprehensively supported by Doctrine)
|
||||
This is an example to show how you would set up and use the doctrine tree interface with the NestedSet implementation (currently the most comprehensively supported by Doctrine)
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
|
||||
require_once("path/to/Doctrine.php");
|
||||
|
||||
function __autoload($classname) {
|
||||
|
||||
return Doctrine::autoload($classname);
|
||||
|
||||
}
|
||||
|
||||
// define our tree
|
||||
class Menu extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
|
||||
$this->setTableName('menu');
|
||||
|
||||
// add this your table definition to set the table as NestedSet tree implementation
|
||||
$this->actsAsTree('NestedSet');
|
||||
|
||||
// you do not need to add any columns specific to the nested set implementation
|
||||
// these are added for you
|
||||
$this->hasColumn("name","string",30);
|
||||
|
||||
}
|
||||
|
||||
// this __toString() function is used to get the name for the path, see node::getPath
|
||||
public function __toString() {
|
||||
return $this->get('name');
|
||||
}
|
||||
}
|
||||
|
||||
// set connections to database
|
||||
$dsn = 'mysql:dbname=nestedset;host=localhost';
|
||||
$user = 'user';
|
||||
$password = 'pass';
|
||||
|
||||
try {
|
||||
$dbh = new PDO($dsn, $user, $password);
|
||||
} catch (PDOException $e) {
|
||||
echo 'Connection failed: ' . $e->getMessage();
|
||||
}
|
||||
|
||||
$manager = Doctrine_Manager::getInstance();
|
||||
|
||||
$conn = $manager->openConnection($dbh);
|
||||
|
||||
// create root
|
||||
$root = new Menu();
|
||||
$root->set('name', 'root');
|
||||
|
||||
$manager->getTable('Menu')->getTree()->createRoot($root);
|
||||
|
||||
// build tree
|
||||
$two = new Menu();
|
||||
$two->set('name', '2');
|
||||
$root->getNode()->addChild($two);
|
||||
|
||||
$one = new Menu();
|
||||
$one->set('name', '1');
|
||||
$one->getNode()->insertAsPrevSiblingOf($two);
|
||||
|
||||
// refresh as node's lft and rgt values have changed
|
||||
$two->refresh();
|
||||
|
||||
$three = new Menu();
|
||||
$three->set('name', '3');
|
||||
$three->getNode()->insertAsNextSiblingOf($two);
|
||||
$two->refresh();
|
||||
|
||||
$one_one = new Menu();
|
||||
$one_one->set('name', '1.1');
|
||||
$one_one->getNode()->insertAsFirstChildOf($one);
|
||||
$one->refresh();
|
||||
|
||||
$one_two = new Menu();
|
||||
$one_two->set('name', '1.2');
|
||||
$one_two->getNode()->insertAsLastChildOf($one);
|
||||
$one_two->refresh();
|
||||
|
||||
$one_two_one = new Menu();
|
||||
$one_two_one->set('name', '1.2.1');
|
||||
$one_two->getNode()->addChild($one_two_one);
|
||||
|
||||
$root->refresh();
|
||||
$four = new Menu();
|
||||
$four->set('name', '4');
|
||||
$root->getNode()->addChild($four);
|
||||
|
||||
$root->refresh();
|
||||
$five = new Menu();
|
||||
$five->set('name', '5');
|
||||
$root->getNode()->addChild($five);
|
||||
|
||||
$root->refresh();
|
||||
$six = new Menu();
|
||||
$six->set('name', '6');
|
||||
$root->getNode()->addChild($six);
|
||||
|
||||
output_message('initial tree');
|
||||
output_tree($root);
|
||||
|
||||
$one_one->refresh();
|
||||
$six->set('name', '1.0 (was 6)');
|
||||
$six->getNode()->moveAsPrevSiblingOf($one_one);
|
||||
|
||||
$one_two->refresh();
|
||||
$five->refresh();
|
||||
$five->set('name', '1.3 (was 5)');
|
||||
$five->getNode()->moveAsNextSiblingOf($one_two);
|
||||
|
||||
$one_one->refresh();
|
||||
$four->refresh();
|
||||
$four->set('name', '1.1.1 (was 4)');
|
||||
$four->getNode()->moveAsFirstChildOf($one_one);
|
||||
|
||||
$root->refresh();
|
||||
$one_two_one->refresh();
|
||||
$one_two_one->set('name', 'last (was 1.2.1)');
|
||||
$one_two_one->getNode()->moveAsLastChildOf($root);
|
||||
|
||||
output_message('transformed tree');
|
||||
output_tree($root);
|
||||
|
||||
$one_one->refresh();
|
||||
$one_one->deleteNode();
|
||||
|
||||
output_message('delete 1.1');
|
||||
output_tree($root);
|
||||
|
||||
// now test fetching root
|
||||
$tree_root = $manager->getTable('Menu')->getTree()->findRoot();
|
||||
output_message('testing fetch root and outputting tree from the root node');
|
||||
output_tree($tree_root);
|
||||
|
||||
// now test fetching the tree
|
||||
output_message('testing fetching entire tree using tree::fetchTree()');
|
||||
$tree = $manager->getTable('Menu')->getTree()->fetchTree();
|
||||
while($node = $tree->next())
|
||||
{
|
||||
output_node($node);
|
||||
}
|
||||
|
||||
// now test fetching the tree
|
||||
output_message('testing fetching entire tree using tree::fetchTree(), excluding root node');
|
||||
$tree = $manager->getTable('Menu')->getTree()->fetchTree(array('include_record' => false));
|
||||
while($node = $tree->next())
|
||||
{
|
||||
output_node($node);
|
||||
}
|
||||
|
||||
// now test fetching the branch
|
||||
output_message('testing fetching branch for 1, using tree::fetchBranch()');
|
||||
$one->refresh();
|
||||
$branch = $manager->getTable('Menu')->getTree()->fetchBranch($one->get('id'));
|
||||
while($node = $branch->next())
|
||||
{
|
||||
output_node($node);
|
||||
}
|
||||
|
||||
// now test fetching the tree
|
||||
output_message('testing fetching branch for 1, using tree::fetchBranch() excluding node 1');
|
||||
$tree = $manager->getTable('Menu')->getTree()->fetchBranch($one->get('id'), array('include_record' => false));
|
||||
while($node = $tree->next())
|
||||
{
|
||||
output_node($node);
|
||||
}
|
||||
|
||||
// now perform some tests
|
||||
output_message('descendants for 1');
|
||||
$descendants = $one->getNode()->getDescendants();
|
||||
while($descendant = $descendants->next())
|
||||
{
|
||||
output_node($descendant);
|
||||
}
|
||||
|
||||
// move one and children under two
|
||||
$two->refresh();
|
||||
$one->getNode()->moveAsFirstChildOf($two);
|
||||
|
||||
output_message('moved one as first child of 2');
|
||||
output_tree($root);
|
||||
|
||||
output_message('descendants for 2');
|
||||
$two->refresh();
|
||||
$descendants = $two->getNode()->getDescendants();
|
||||
while($descendant = $descendants->next())
|
||||
{
|
||||
output_node($descendant);
|
||||
}
|
||||
|
||||
output_message('number descendants for 2');
|
||||
echo $two->getNode()->getNumberDescendants() .'</br>';
|
||||
|
||||
output_message('children for 2 (notice excludes children of children, known as descendants)');
|
||||
$children = $two->getNode()->getChildren();
|
||||
while($child = $children->next())
|
||||
{
|
||||
output_node($child);
|
||||
}
|
||||
|
||||
output_message('number children for 2');
|
||||
echo $two->getNode()->getNumberChildren() .'</br>';
|
||||
|
||||
output_message('path to 1');
|
||||
$path = $one->getNode()->getPath(' > ');
|
||||
echo $path .'
|
||||
';
|
||||
|
||||
output_message('path to 1 (including 1)');
|
||||
$path = $one->getNode()->getPath(' > ', true);
|
||||
echo $path .'
|
||||
';
|
||||
|
||||
output_message('1 has parent');
|
||||
$hasParent = $one->getNode()->hasParent();
|
||||
$msg = $hasParent ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('parent to 1');
|
||||
$parent = $one->getNode()->getParent();
|
||||
if($parent->exists())
|
||||
{
|
||||
echo $parent->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
output_message('root isRoot?');
|
||||
$isRoot = $root->getNode()->isRoot();
|
||||
$msg = $isRoot ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('one isRoot?');
|
||||
$isRoot = $one->getNode()->isRoot();
|
||||
$msg = $isRoot ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('root hasParent');
|
||||
$hasParent = $root->getNode()->hasParent();
|
||||
$msg = $hasParent ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('root getParent');
|
||||
$parent = $root->getNode()->getParent();
|
||||
if($parent->exists())
|
||||
{
|
||||
echo $parent->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
output_message('get first child of root');
|
||||
$record = $root->getNode()->getFirstChild();
|
||||
if($record->exists())
|
||||
{
|
||||
echo $record->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
output_message('get last child of root');
|
||||
$record = $root->getNode()->getLastChild();
|
||||
if($record->exists())
|
||||
{
|
||||
echo $record->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
$one_two->refresh();
|
||||
|
||||
output_message('get prev sibling of 1.2');
|
||||
$record = $one_two->getNode()->getPrevSibling();
|
||||
if($record->exists())
|
||||
{
|
||||
echo $record->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
output_message('get next sibling of 1.2');
|
||||
$record = $one_two->getNode()->getNextSibling();
|
||||
if($record->exists())
|
||||
{
|
||||
echo $record->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
output_message('siblings of 1.2');
|
||||
$siblings = $one_two->getNode()->getSiblings();
|
||||
foreach($siblings as $sibling)
|
||||
{
|
||||
if($sibling->exists())
|
||||
echo $sibling->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
output_message('siblings of 1.2 (including 1.2)');
|
||||
$siblings = $one_two->getNode()->getSiblings(true);
|
||||
foreach($siblings as $sibling)
|
||||
{
|
||||
if($sibling->exists())
|
||||
echo $sibling->get('name') .'
|
||||
';
|
||||
}
|
||||
|
||||
$new = new Menu();
|
||||
$new->set('name', 'parent of 1.2');
|
||||
$new->getNode()->insertAsParentOf($one_two);
|
||||
|
||||
output_message('added a parent to 1.2');
|
||||
output_tree($root);
|
||||
|
||||
try {
|
||||
$dummy = new Menu();
|
||||
$dummy->set('name', 'dummy');
|
||||
$dummy->save();
|
||||
}
|
||||
catch (Doctrine_Exception $e)
|
||||
{
|
||||
output_message('You cannot save a node unless it is in the tree');
|
||||
}
|
||||
|
||||
try {
|
||||
$fake = new Menu();
|
||||
$fake->set('name', 'dummy');
|
||||
$fake->set('lft', 200);
|
||||
$fake->set('rgt', 1);
|
||||
$fake->save();
|
||||
}
|
||||
catch (Doctrine_Exception $e)
|
||||
{
|
||||
output_message('You cannot save a node with bad lft and rgt values');
|
||||
}
|
||||
|
||||
// check last remaining tests
|
||||
output_message('New parent is descendant of 1');
|
||||
$one->refresh();
|
||||
$res = $new->getNode()->isDescendantOf($one);
|
||||
$msg = $res ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('New parent is descendant of 2');
|
||||
$two->refresh();
|
||||
$res = $new->getNode()->isDescendantOf($two);
|
||||
$msg = $res ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('New parent is descendant of 1.2');
|
||||
$one_two->refresh();
|
||||
$res = $new->getNode()->isDescendantOf($one_two);
|
||||
$msg = $res ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('New parent is descendant of or equal to 1');
|
||||
$one->refresh();
|
||||
$res = $new->getNode()->isDescendantOfOrEqualTo($one);
|
||||
$msg = $res ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('New parent is descendant of or equal to 1.2');
|
||||
$one_two->refresh();
|
||||
$res = $new->getNode()->isDescendantOfOrEqualTo($one_two);
|
||||
$msg = $res ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
output_message('New parent is descendant of or equal to 1.3');
|
||||
$five->refresh();
|
||||
$res = $new->getNode()->isDescendantOfOrEqualTo($new);
|
||||
$msg = $res ? 'true' : 'false';
|
||||
echo $msg . '</br/>';
|
||||
|
||||
function output_tree($root)
|
||||
{
|
||||
// display tree
|
||||
// first we must refresh the node as the tree has been transformed
|
||||
$root->refresh();
|
||||
|
||||
// next we must get the iterator to traverse the tree from the root node
|
||||
$traverse = $root->getNode()->traverse();
|
||||
|
||||
output_node($root);
|
||||
// now we traverse the tree and output the menu items
|
||||
while($item = $traverse->next())
|
||||
{
|
||||
output_node($item);
|
||||
}
|
||||
|
||||
unset($traverse);
|
||||
}
|
||||
|
||||
function output_node($record)
|
||||
{
|
||||
echo str_repeat('-', $record->getNode()->getLevel()) . $record->get('name')
|
||||
. ' (has children:'.$record->getNode()->hasChildren().') '
|
||||
. ' (is leaf:'.$record->getNode()->isLeaf().') '.'<br/>';
|
||||
}
|
||||
|
||||
function output_message($msg)
|
||||
{
|
||||
echo "
|
||||
**//$msg//**".'
|
||||
';
|
||||
}
|
||||
</code>
|
@ -1,3 +1,98 @@
|
||||
|
||||
|
||||
The node interface, for inserting and manipulating nodes within the tree, is accessed on a record level. A full implementation of this interface will be as follows:
|
||||
The node interface, for inserting and manipulating nodes within the tree, is accessed on a record level. A full implementation of this interface will be as follows:
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
interface Doctrine_Node_Interface {
|
||||
|
||||
/**
|
||||
* insert node into tree
|
||||
*/
|
||||
public function insertAsParentOf(Doctrine_Record $dest);
|
||||
|
||||
public function insertAsPrevSiblingOf(Doctrine_Record $dest);
|
||||
|
||||
public function insertAsNextSiblingOf(Doctrine_Record $dest);
|
||||
|
||||
public function insertAsFirstChildOf(Doctrine_Record $dest);
|
||||
|
||||
public function insertAsLastChildOf(Doctrine_Record $dest);
|
||||
|
||||
public function addChild(Doctrine_Record $record);
|
||||
|
||||
/**
|
||||
* moves node (if has children, moves branch)
|
||||
*
|
||||
*/
|
||||
public function moveAsPrevSiblingOf(Doctrine_Record $dest);
|
||||
|
||||
public function moveAsNextSiblingOf(Doctrine_Record $dest);
|
||||
|
||||
public function moveAsFirstChildOf(Doctrine_Record $dest);
|
||||
|
||||
public function moveAsLastChildOf(Doctrine_Record $dest);
|
||||
|
||||
/**
|
||||
* node information
|
||||
*/
|
||||
public function getPrevSibling();
|
||||
|
||||
public function getNextSibling();
|
||||
|
||||
public function getSiblings($includeNode = false);
|
||||
|
||||
public function getFirstChild();
|
||||
|
||||
public function getLastChild();
|
||||
|
||||
public function getChildren();
|
||||
|
||||
public function getDescendants();
|
||||
|
||||
public function getParent();
|
||||
|
||||
public function getAncestors();
|
||||
|
||||
public function getPath($seperator = ' > ', $includeNode = false);
|
||||
|
||||
public function getLevel();
|
||||
|
||||
public function getNumberChildren();
|
||||
|
||||
public function getNumberDescendants();
|
||||
|
||||
/**
|
||||
* node checks
|
||||
*/
|
||||
public function hasPrevSibling();
|
||||
|
||||
public function hasNextSibling();
|
||||
|
||||
public function hasChildren();
|
||||
|
||||
public function hasParent();
|
||||
|
||||
public function isLeaf();
|
||||
|
||||
public function isRoot();
|
||||
|
||||
public function isEqualTo(Doctrine_Record $subj);
|
||||
|
||||
public function isDescendantOf(Doctrine_Record $subj);
|
||||
|
||||
public function isDescendantOfOrEqualTo(Doctrine_Record $subj);
|
||||
|
||||
public function isValidNode();
|
||||
|
||||
/**
|
||||
* deletes node and it's descendants
|
||||
*/
|
||||
public function delete();
|
||||
}
|
||||
|
||||
// if your model acts as tree you can retrieve the associated node object as follows
|
||||
$record = $manager->getTable('Model')->find($pk);
|
||||
$nodeObj = $record->getNode();
|
||||
</code>
|
@ -8,4 +8,30 @@ Now that Doctrine knows that this model acts as a tree, it will automatically ad
|
||||
|
||||
|
||||
|
||||
Doctrine has standard interface's for managing tree's, that are used by all the implementations. Every record in the table represents a node within the tree (the table), so doctrine provides two interfaces, Tree and Node.
|
||||
Doctrine has standard interface's for managing tree's, that are used by all the implementations. Every record in the table represents a node within the tree (the table), so doctrine provides two interfaces, Tree and Node.
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
class Menu extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
|
||||
$this->setTableName('menu');
|
||||
|
||||
// add this your table definition to set the table as NestedSet tree implementation
|
||||
// $implName is 'NestedSet' or 'AdjacencyList' or 'MaterializedPath'
|
||||
// $options is an assoc array of options, see implementation docs for options
|
||||
$this->option('treeImpl', $implName);
|
||||
$this->option('treeOptions', $options);
|
||||
|
||||
// you do not need to add any columns specific to the nested set implementation, these are added for you
|
||||
$this->hasColumn("name","string",30);
|
||||
|
||||
}
|
||||
|
||||
// this __toString() function is used to get the name for the path, see node::getPath()
|
||||
public function __toString() {
|
||||
return $this->get('name');
|
||||
}
|
||||
}
|
||||
</code>
|
@ -4,4 +4,49 @@ You can traverse a Tree in different ways, please see here for more information
|
||||
|
||||
|
||||
|
||||
The most common way of traversing a tree is Pre Order Traversal as explained in the link above, this is also what is known as walking the tree, this is the default approach when traversing a tree in Doctrine, however Doctrine does plan to provide support for Post and Level Order Traversal (not currently implemented)
|
||||
The most common way of traversing a tree is Pre Order Traversal as explained in the link above, this is also what is known as walking the tree, this is the default approach when traversing a tree in Doctrine, however Doctrine does plan to provide support for Post and Level Order Traversal (not currently implemented)
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
/*
|
||||
* traverse the entire tree from root
|
||||
*/
|
||||
$root = $manager->getTable('Model')->getTree()->fetchRoot();
|
||||
if($root->exists())
|
||||
{
|
||||
$tree = $root->traverse();
|
||||
while($node = $tree->next())
|
||||
{
|
||||
// output your tree here
|
||||
}
|
||||
}
|
||||
|
||||
// or the optimised approach using tree::fetchTree
|
||||
$tree = $manager->getTable('Model')->getTree()->fetchTree();
|
||||
while($node = $tree->next())
|
||||
{
|
||||
// output tree here
|
||||
}
|
||||
|
||||
/*
|
||||
* traverse a branch of the tree
|
||||
*/
|
||||
$record = $manager->getTable('Model')->find($pk);
|
||||
if($record->exists())
|
||||
{
|
||||
$branch = $record->traverse();
|
||||
while($node = $branch->next())
|
||||
{
|
||||
// output your tree here
|
||||
}
|
||||
}
|
||||
|
||||
// or the optimised approach
|
||||
$branch = $manager->getTable('Model')->getTree()->fetchBranch($pk);
|
||||
while($node = $branch->traverse())
|
||||
{
|
||||
// output your tree here
|
||||
}
|
||||
|
||||
</code>
|
@ -1,3 +1,35 @@
|
||||
|
||||
|
||||
The tree interface, for creating and accessing the tree, is accessed on a table level. A full implementation of this interface would be as follows:
|
||||
The tree interface, for creating and accessing the tree, is accessed on a table level. A full implementation of this interface would be as follows:
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
|
||||
interface Doctrine_Tree_Interface {
|
||||
|
||||
/**
|
||||
* creates root node from given record or from a new record
|
||||
*/
|
||||
public function createRoot(Doctrine_Record $record = null);
|
||||
|
||||
/**
|
||||
* returns root node
|
||||
*/
|
||||
public function findRoot($root_id = 1);
|
||||
|
||||
/**
|
||||
* optimised method to returns iterator for traversal of the entire tree from root
|
||||
*/
|
||||
public function fetchTree($options = array());
|
||||
|
||||
/**
|
||||
* optimised method that returns iterator for traversal of the tree from the given record's primary key
|
||||
*/
|
||||
public function fetchBranch($pk, $options = array());
|
||||
}
|
||||
|
||||
// if your model acts as tree you can retrieve the associated tree object as follows
|
||||
$treeObj = $manager->getTable('Model')->getTree();
|
||||
|
||||
</code>
|
@ -0,0 +1,4 @@
|
||||
|
||||
|
||||
|
||||
|
@ -1 +1,4 @@
|
||||
Not yet implemented
|
||||
Not yet implemented
|
||||
|
||||
|
||||
|
||||
|
@ -8,3 +8,7 @@ For more information, read here:
|
||||
|
||||
[http://www.sitepoint.com/article/hierarchical-data-database/2 http://www.sitepoint.com/article/hierarchical-data-database/2],
|
||||
[http://dev.mysql.com/tech-resources/articles/hierarchical-data.html http://dev.mysql.com/tech-resources/articles/hierarchical-data.html]
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,27 @@
|
||||
|
||||
|
||||
To set up your model as Nested Set, you must add the following code to your model's table definition.
|
||||
To set up your model as Nested Set, you must add the following code to your model's table definition.
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
class Menu extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
|
||||
$this->setTableName('menu');
|
||||
|
||||
// add this your table definition to set the table as NestedSet tree implementation
|
||||
$this->option('treeImpl', 'NestedSet');
|
||||
$this->option('treeOptions', array());
|
||||
|
||||
// you do not need to add any columns specific to the nested set implementation, these are added for you
|
||||
$this->hasColumn("name","string",30);
|
||||
|
||||
}
|
||||
|
||||
// this __toString() function is used to get the name for the path, see node::getPath()
|
||||
public function __toString() {
|
||||
return $this->get('name');
|
||||
}
|
||||
}
|
||||
</code>
|
@ -4,4 +4,33 @@ The nested implementation can be configured to allow your table to have multiple
|
||||
|
||||
|
||||
|
||||
The example below shows how to setup and use multiple roots based upon the set up above:
|
||||
The example below shows how to setup and use multiple roots based upon the set up above:
|
||||
|
||||
|
||||
|
||||
<code type="php">
|
||||
//use these options in the setTableDefinition
|
||||
$options = array('hasManyRoots' => true, // enable many roots
|
||||
'rootColumnName' => 'root_id'); // set root column name, defaults to 'root_id'
|
||||
|
||||
// To create new root nodes, if you have manually set the root_id, then it will be used
|
||||
// otherwise it will automatically use the next available root id
|
||||
$root = new Menu();
|
||||
$root->set('name', 'root');
|
||||
|
||||
// insert first root, will auto be assigned root_id = 1
|
||||
$manager->getTable('Menu')->getTree()->createRoot($root);
|
||||
|
||||
$another_root = new Menu();
|
||||
$another_root->set('name', 'another root');
|
||||
|
||||
// insert another root, will auto be assigned root_id = 2
|
||||
$manager->getTable('Menu')->getTree()->createRoot($another_root);
|
||||
|
||||
// fetching a specifc root
|
||||
$root = $manager->getTable('Menu')->getTree()->fetchRoot(1);
|
||||
$another_root = $manager->getTable('Menu')->getTree()->fetchRoot(2);
|
||||
|
||||
// fetching all roots
|
||||
$roots = $manager->getTable('Menu')->getTree()->fetchRoots();
|
||||
</code>
|
||||
|
Loading…
x
Reference in New Issue
Block a user