Skip to content
World Wide Web Server edited this page Jul 4, 2012 · 25 revisions

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]

Modified Preorder Tree Traversal (or Nested Sets)

Place the MPTtree.php file in your models directory.

MPTtree Model

Load The Model

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())

Get Node

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

Update Node

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!'

Insert Node

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!

Move Node

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

Deleting Nodes

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!)

Validate Tree/Node

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

Download>

File:MPTtree.zip

Clone this wiki locally