-
Notifications
You must be signed in to change notification settings - Fork 26
Trees
Information about SQL trees: http://dev.e-taller.net/dbtree/
TODO: Need create class for CI for work with trees!
=> a bit of inspiration...
- [url=http://pear.php.net/package/Tree]PEAR Tree Package[/url]
Place the MPTtree.php file in your models directory.
To load the model use the following code:
$this->load->model('MPTtree');
$this->MPTtree->set_table('Tablename');
Important: You must use the set_table() or set_opts() to initialize settings before you use the model.
You load the model as usual, but then you have to set the parameters (ie. tablename).
// Or instead of set_table()...
$this->MPTtree->set_opts('Tablename', 'Left column name', 'Right column name', 'Id column name', 'Title column name');
Everything except the tablename is required to specify (so you can skip the use of set_opts())
To fetch a node, you have to know at which lft (or whatever you call your left column) the node resides in. You usually get this information from data which you already have fetched from the database, a good start is the get_root() method. This method returns the table row containing the rootnode's data.
An example:
$root = $this->MPTtree->get_root();
print_r($root);
// Prints for example the following (depending on content in the database):
Array
(
[id] => 34,
[lft] => 1,
[rgt] => 6,
[title] => Root Page,
[content] => FOO BAR...,
)
From there we can easily continue by using the values we have:
$children = $this->MPTtree->get_children($root['lft'],$root['rgt']);
foreach($children as $child){
echo $child['title'] . "\n";
}
// May output:
Child 1
Child 2
Hey, i'm a child
Another title
...
...
But this only returns the first level children, to get all childrens (including grandchildren) we use get_decendants()
If we know a lft address, we can use it directly:
$node = $this->MPTtree->get_node(3);
If we want to know which nodes are parents to a given node, we can use get_parents():
$parents = $this->MPTtree->get_parents(3,4);
// The node from the previous example
foreach($parents as $parent){
echo $parent['title']; // Would produce "Parent 1" and "Root Page" (the closest related first)
}
For these examples we have used a table which for example may look like this:
| id | lft | rgt | title |
|---|---|---|---|
| 34 | 1 | 6 | Root Page |
| 445 | 2 | 5 | Parent 1 |
| 34 | 3 | 4 | A child |
To update a node simply use the update function:
$this->MPTtree->update_node(1,array('title' => 'The new Root Page!', 'content' => 'I am a string!'));
// Will set the title of the root node (with lft=1) to 'The new Root Page!' and the content field to 'I am a string!'
To insert a node you can use one of the following methods:
-
insert_root()
adds a root node
-
insert_node_before()
inserts the new node before the node with the lft specified
-
insert_node_after()
inserts the new node after the node with the lft specified
-
append_node()
inserts the node as the first child to the node with the lft specified
-
append_node_last()
inserts the node as the last child to the node with the lft specified
-
insert_node()
raw access, uses the source and target lfts directly !Discouraged!
All these are quite straightforward, all they need is a lft value and the data array (except for insert_root()).
For example:
$this->MPTtree->append_node(3,array('title' => 'A new child!'));
If this is used on the table used above, the result will be:
| id | lft | rgt | title |
|---|---|---|---|
| 34 | 1 | 8 | Root Page |
| 445 | 2 | 7 | Parent 1 |
| 34 | 3 | 6 | A child |
| 446 | 4 | 5 | A new child! |
The move node methods are also quite straightforward, they require the lft of the node to be moved and the lft of the node to be moved to.
To insert a node you can use one of the following methods:
-
move_node_before()
moves the first node before the other node
-
move_node_after()
moves the first node after the other node
-
move_node_append()
moves the first node to the position of first child to the other node
-
move_node_append_last()
moves first the node to the position of last child to the other noded
-
move_node()
raw access, uses the source and target lfts directly !Discouraged!
For example:
$this->MPTtree->move_node_before(4,2); // Moves A new child! to the position of first child of Poot Page
To delete a node you have two options:
- Delete a node and promote all subnodes, or
- Delete a whole subtree (node and all decendants).
The data required to perform a delete is only the lft value of the node to delete.
$this->MPTtree->delete_node(3); // deletes the node A child, promoting A new child!
// or:
$this->MPTtree->delete_branch(3); // deletes the node A child and the decendants of it (A new Child!)
To validate the tree you can use one of the following methods:
-
is_valid_node()
Returns true if the lft supplied lft is a valid node
-
validate()
Validates the tree, searches for gaps and duplicates (because they are the primary indicators of errors in tree)
-
display()
Prints a simple tree in HTML with the tree structure