<?php
class Tree {
/**
* Instance of Creole
*/
private $db;
/**
* Constructor, initialize Creole
*
* @param $dsn
*/
public function __construct($dsn) {
$this->db = Creole::getConnection($dsn);;
}
/**
* Adds node to tree
*
* @param object_id Id of object in system (this is not db id)
* @param parent Id of parent - db id
*/
public function addNode($object_id, $parent) {
$rs = $this->db->executeQuery('SELECT `id`, `left`, `right` FROM tree WHERE `id`="' . $parent . '"');
if($rs->getRecordCount() == 0) {
$left = 1;
$right = 2;
} else {
while($rs->next()) {
$left = $rs->getInt('left');
$right = $rs->getInt('right');
$parentId = $rs->getInt('id');
}
}
$sql = 'UPDATE tree SET `right` = `right` +2 WHERE `right` >' . ($right - 1);
$this->db->executeQuery($sql);
$sql = 'UPDATE tree SET `left` = `left` +2 WHERE `left` > '. ($right - 1);
$this->db->executeQuery($sql);
$sql = 'INSERT INTO tree SET `left`=' . ($right - 1) .', `right`=' . $right . ', `object_id`="'. $object_id .'", `parent_id`="' . $parentId .'";';
$this->db->executeQuery($sql);
}
/**
* Adds root node
*
* @param object_id Id of object in system (this is not db id)
* @return boolean
*/
public function addRoot($object_id) {
$rs = $this->db->executeQuery('SELECT * FROM `tree` WHERE `parent_id` ="0"');
if($rs->getRecordCount() == 0) {
$this->db->executeQuery('INSERT INTO `tree` ( `id` , `object_id` , `left` , `right` ) VALUES ( '0', '' . $object_id . '', '1', '2')');
return true;
}
return false;
}
/**
* Removes node
*
* @param $id Id of node
*/
public function deleteNode($id) {
$rs = $this->db->executeQuery('SELECT `parent_id`, `left` FROM `tree` WHERE `id`="'. $id .'"');
while($rs->next()) {
$node['parent'] = $rs->getInt('parent_id');
$node['left'] = $rs->getInt('left');
}
$this->db->executeQuery('DELETE FROM `tree` WHERE `id`="' . $id . '" LIMIT 1');
$this->rebuild($node['parent'], $node['left'] - 1);
}
/**
* Rebuilds tree recursively
* If something goes wrong, you'll use this
*
* @param $parent Id of parent node
* @param $left Left
*/
public function rebuild($parent, $left) {
$right = $left+1;
$rs = $this->db->executeQuery('SELECT `id` FROM `tree` WHERE `parent_id`="' . $parent . '";');
while ($rs->next()) {
$right = $this->rebuild($rs->getInt('id'), $right);
}
$this->db->executeQuery('UPDATE tree SET `left`=' . $left . ', `right`=' . $right . ' WHERE `id`="' . $parent . '";');
return $right+1;
}
/**
* Test method
*
* @param $root Id of node which is root to display
*/
function display($root) {
$rs = $this->db->executeQuery('SELECT `left`, `right` FROM `tree` WHERE `id`="'.$root.'";');
while($rs->next()) {
$l = $rs->getInt('left');
$r = $rs->getInt('right');
}
$rs = $this->db->executeQuery('SELECT `object_id`, `left`, `right` FROM tree WHERE `left` BETWEEN '. $l .' AND ' . $r . ' ORDER BY `left` ASC;');
while ($rs->next()) {
while ($right[count($right)-1
] < $rs->getInt('right')) { }
}
echo str_repeat(' ',count($right)) . $rs->getString('object_id'). ' Left: ' . $rs->getInt('left') . ' Right: '. $rs->getInt('right') . "<br/>n";
$right[] = $rs->getInt('right');
}
}
/**
* Gets object id
*
* @param id of node
* @return object id
*/
public function getNode($id) {
$rs = $this->db->executeQuery('SELECT `object_id` FROM `tree` WHERE `id`="'.$id.'";');
while($rs->next()) {
return $rs->getInt('object_id');
}
}
}
?>
CREATE TABLE `tree` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL DEFAULT '0',
`object_id` int(11) NOT NULL DEFAULT '0',
`left` int(11) NOT NULL DEFAULT '0',
`right` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
Może komuś się przyda.
Object_id to nr obiektu w cmsie, równie dobrze możecie zastąpić to przez jakiś TEXT.