PHP Traversing mySQL Node tree
I'm having trouble trying to move nodes or parent nodes up or down ... not that good at math.
CREATE TABLE IF NOT EXISTS `pages` ( `page-id` mediumint(8) unsigned
NOT NULL AUTO_INCREMENT,
page-left
mediumint (8) unsigned NOT NULL,page-right
smallint (8) unsigned NOT NULL,page-title
text NOT NULL,page-content
text NOT NULL,page-time
int (11) unsigned NOT NULL,page-slug
text NOT NULL,page-template
text NOT NULL,page-parent
mediumint (8) unsigned NOT NULL,page-type
text NOT NULL, PRIMARY KEY (page-id
)) ENGINE = MyISAM DEFAULT CHARSET = latin1;INSERT INTO
pages
(page-id
,page-left
,page-right
,page-title
,page-content
,page-time
,page-slug
,page-template
,page-parent
,page-type
) VALUES (17, 1, 6, '1', '0,' PARENT ',' ', 0' '), (18, 2, 5, '2', '', 0, 'SUB', '', 17, ''), (19, 3, 4, 3 ',' ', 0,' SUB-SUB ',' ', 18,' ' ), (20, 7, 8, '5', '', 0, 'TEST', '', 0, '');
As an example, how would I move TEST above PARENT and say move SUB below SUB-SUB, playing with the page IDs / left / right? No code required, just help with SQL concept or math for it, help me figure out how best to move it ...
a source to share
So basically you want to convert an adjacency list to a nested set? First update the adjacency list (i.e. update the page_parent values to the correct values for your new tree) and then do the transform below.
Using PHP (base code, untested):
class Tree
{
private $count = 0;
private $data = array();
/**
* Rebuild nested set
*
* @param $rawData array Raw tree data
*/
public function rebuild($rawData)
{
$this->data = $rawData;
$this->count = 1;
$this->traverse(0);
}
private function traverse($id)
{
$lft = $this->count;
$this->count++;
if (isset($this->data[$id])) {
$kid = $this->data[$id];
if ($kid) {
foreach ($kid as $c) {
$this->traverse($c);
}
}
}
$rgt = $this->count;
$this->count++;
// TODO: Update left and right values to $lft & $rgt in your DB for page_id $id
...
}
}
When you call this, $ rawData should contain an array of IDs indexed by the parent ID, you can create it (based on the table structure) like this ($ db should contain an active PDO connection object):
$sql = 'SELECT page_id, page_parent FROM pages ORDER BY page_parent';
$stmt = $db->prepare($sql);
$rawData = array();
$stmt->execute();
while ($row = $stmt->fetch()) {
$parent = $row['page_parent'];
$child = $row['page_id'];
if (!array_key_exists($parent, $rawData)) {
$rawData[$parent] = array();
}
$rawData[$parent][] = $child;
}
To convert, you need something like:
$tree = new Tree();
$tree->rebuild($rawData);
So basically you are creating an array containing all the nodes in the tree, indexed by the parent, which will be recursively traversed to determine the correct left and right values on the node.
BTW You can do this in plain SQL (after you adapt the table and column names): http://bytes.com/topic/mysql/answers/638123-regenerate-nested-set-using-parent_id-structure
a source to share