[eluser]coffey[/eluser]
This works for me and my set up. I have slightly adapted this now so I can quickly employ/trial different tree css/js.
I am a recent convert from asp/.net so I have yet to fathom the depths of php coding and its many built in methods so I am sure this could be a great deal slicker.
Hope this helps
Code:
/*
* Unlimited level node array
* example of array garnered from eg table below
* Array (
[0] => Array (
[id] => 1 [name] => welcome [nodelevel] => 1
[children] => Array (
[0] => Array ( [id] => 4 [name] => more welcome [nodelevel] => 2 [children] => ) ) )
[1] => Array (
[id] => 2 [name] => about us [nodelevel] => 1 [children] => )
[2] => Array (
[id] => 3 [name] => contact [nodelevel] => 1 [children] => )
+------+------------------+---------+-------------+
| id | name | p_id | section_id |
+------+------------------+---------+-------------+
| 1 | welcome | 0 | 1 |
+------+------------------+---------+-------------+
| 1 | about us | 0 | 1 |
+------+------------------+---------+-------------+
| 1 | contact | 0 | 1 |
+------+------------------+---------+-------------+
| 1 | more welcome | 1 | 1 |
+------+------------------+---------+-------------+
@param section_id - site has multiple sections each with its own menu list
@param p_id - parent id, the first level of each section has a parent id of 0
Separated building the html from the node array collection itself
so I could employ other menu trees more easily if required and also check
in a straigntforward way if the array was gathering the information correctly
by testing via print_r()
The node collection is recursive but with a check (hasChildren)
to see if the recursion is necessary
$this->load->library('treeview');
//set section id
$this->treeview->section_id = $section_id;
//call the menu
$data = $this->treeview->buildmenu();
*/
class Treeview
{
public $section_id = 1;
private $nodesql = "SELECT id, node, nodelevel FROM nodes ";
private $anchor = "/index.php/node/id/";
private $orderby = " order by p_id, runorder, id, node ";
function __construct()
{
$this->obj =& get_instance();
}
// built specifically for silver stripe tree menu
public function buildmenu()
{
// get the nodes array starting with the parent one
$menu_array = $this->get_menu_nodes();
$html='';
foreach ($menu_array as $menu)
{
if ($this->hasChildren($menu['id']))
{
$html.="<li class=\"closed\"><a href=\"".$this->anchor."/". $this->section_id . "/\">
" . $menu['node'] . "</a>\n<ul>\n";
$childarray = $menu['children'];
foreach ( $childarray as $child)
{
$html.="<li><a href=\"".$this->anchor . $child['id'] ."/" . $this->section_id . "/\">
" . $child['node'] . "</a></li>\n";
}
$html.= "</li>\n</ul>\n";
} else {
$html.="<li><a href=\"".$this->anchor .$menu['id']."/". $this->section_id . "/\">
" . $menu['node'] . "</a></li>\n";
}
}
return $html;
}
//starts the gathering the section's parent nodes
function get_menu_nodes()
{
$sql = "$this->nodesql ";
// First get top level nodes i.e. parent id = 0
$sql .= " WHERE section_id = $this->section_id and p_id = 0 ";
$sql .= $this->orderby;
$result = $this->build_menu_array($sql);
return $result;
}
//called if required by build_menu_array
//@param pid = collects nodes with this parent id
function get_child_nodes($pid)
{
// just get top level nodes initially
$sql = "$this->nodesql
WHERE p_id = $pid
$this->orderby";
$result = $this->build_menu_array($sql);
return $result;
}
//the recursive menu 'engine'
function build_menu_array($sql)
{
$query = $this->obj->db->query($sql);
foreach ($query->result_array() as $row)
{
$node_items = array();
$node_items['id'] = $row['id'];
$node_items['node'] = $row['node'];
$node_items['nodelevel'] = $row['nodelevel'];
// if the node has children get them now - recursive
// store in in children array
if ($this->hasChildren($row['id']))
{
$children = $this->get_child_nodes($row['id']);
$node_items['children'] = $children;
} else {
$node_items['children'] = '';
}
$node_array[] = $node_items;
}
return $node_array;
}
function hasChildren($id)
{
$bool = FALSE;
$sql = "Select id from nodes where p_id = $id";
$query = $this->obj->db->query($sql);
if ($query->num_rows() > 0) $bool = TRUE;
return $bool;
}
}
Cheers
Shane