marek_mar
02-15-2006, 08:03 PM
This class should handle the management of a MPTT tree.
Manual (sort of):
Make sure you have set the constants:
TABLE_DATA - The name of the table in which the tree data is stored.
FIELD_KEY - The name of the PRIMARY KEY column (the one with row id's).
FIELD_LEFT_ID - The name of the column in which the left id's are stored.
FIELD_RIGHT_ID - The name of the column in which the right id's are stored.
FIELD_LEVEL - The name of the column in which the elemts levels are stored.
Yes, all 4 columns are required in your table setup.
Method description:
mptt:mptt($link = null)
$link - (optional) MySQL link identifier.
mptt:add($parent, $child_num = 0, $misc_data = false)
Add an element to the tree as a child of $parent and as $child_num'th child. If $data is not supplied the insert id will be returned.
$parent - The id of the parent of the added object (0 for root).
$child_num - The new element will be placed as the $child_num'th child of the parent*.
$misc_data - An array containing other data to be added to the tree. If not set the function will return the insert id of the new row.
Returns bool(true) on success unless $misc_data is not set.
mptt::delete($id, $keep_children = false)
Deletes element $id with or without children. If children should be kept they will become children of $id's parent.
$id - The id of the element to delete.
$keep_children - If true the children of the deleted element will move to the parent of the deleted element.
Returns bool(true) on success.
mptt::move($id, $target_id, $child_num = 0)
Move a element (with children) $id, under element $target_id as the $child_num'th child of that element.
$id - The element to move
$target_id - The id of the new parent.
$child_num - The new element will be placed as the $child_num'th child of the parent*.
mptt::copy($id, $parent, $child_num = 0)
Copies element $id (with children) to $parent as the $child_mun'th child.
$id - The element to move
$parent - The id of the new parent.
$child_num - The new element will be placed as the $child_num'th child of the parent*.
mptt::swap($id1, $id2)
Swaps two elements and ONLY the elements!
$id1 and $id2 - Id's of the elements to swap.
mptt::check_consistency(&$errors=array()) // Kind of experimental. But worked in tests.
Check if all of the tree's left and right id's are correct.
$errors - This will hold an array of error messages if any messages accour (null otherwise).
Returns true if there are no errors.
*$child_num is by default 0.
0 means that the element will be inserted as the first child, 1 as the 2nd child and so on.
You can also use negative numbers. -1 would be the last child... pretty much like substr().
Code:
It was too large. Attached.
Example:
SQL & example data:
CREATE TABLE `data` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`title` varchar(200) NOT NULL,
`left_id` int(10) NOT NULL,
`right_id` int(10) NOT NULL,
`level` mediumint(8) unsigned NOT NULL,
UNIQUE KEY `id` (`id`)
);
# The same example as it was on aesthetic-theory
INSERT INTO `data` VALUES (1, 'Music', 1, 14, 1);
INSERT INTO `data` VALUES (2, 'Ludo', 2, 5, 2);
INSERT INTO `data` VALUES (3, 'self titled', 3, 4, 3);
INSERT INTO `data` VALUES (4, 'weezer', 6, 13, 2);
INSERT INTO `data` VALUES (5, 'pinkerton', 7, 12, 3);
INSERT INTO `data` VALUES (6, 'el scorcho lyrics', 8, 9, 4);
INSERT INTO `data` VALUES (7, 'pink triangle lyrics', 10, 11, 4);
INSERT INTO `data` VALUES (8, 'Foods', 15, 22, 1);
INSERT INTO `data` VALUES (9, 'Meat', 16, 21, 2);
INSERT INTO `data` VALUES (10, 'Steak', 17, 18, 3);
INSERT INTO `data` VALUES (11, 'ribs', 19, 20, 3);
PHP & HTML:
<?php
// Example
?>
<html>
<head>
<title>MPTT</title>
</head>
<body>
<form name="add" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
Parent ID: <input type="text" name="parent" /><br />
As child: <input type="text" name="child_num" value="0" /><br />
Title: <input type="text" name="title" /><br />
<input type="submit" name="add" value="Add" />
</form>
<form name="delete" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID: <input type="text" name="id" /><br />
Keep children? <input type="radio" name="keep_children" value="0" checked="checked" />No
<input type="radio" name="keep_children" value="1" />Yes<br />
<input type="submit" name="delete" value="Delete" />
</form>
<form name="move" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID: <input type="text" name="id" /><br />
Target: <input type="text" name="target_id" /><br />
As child: <input type="text" name="child_num" value="0" /><br />
<input type="submit" name="move" value="Move" />
</form>
<form name="copy" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID: <input type="text" name="id" /><br />
Target: <input type="text" name="target_id" /><br />
As child: <input type="text" name="child_num" value="0" /><br />
<input type="submit" name="copy" value="Copy" />
</form>
<form name="swap" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID1: <input type="text" name="id1" /><br />
ID2: <input type="text" name="id2" /><br />
<input type="submit" name="swap" value="Swap" />
</form>
<?php
error_reporting(E_ALL);
// DB constants
define('DB_HOST', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_DATABASE', 'mptt');
// connect to the database
$link = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD) or die (mysql_error());
mysql_select_db(DB_DATABASE) or die (mysql_error());
require 'class_mptt.php';
$mptt = new mptt($link);
if(isset($_POST['add']))
{
$mptt->add($_POST['parent'], $_POST['child_num'], array('title' => $_POST['title']));
}
elseif(isset($_POST['delete']))
{
$mptt->delete($_POST['id'], (bool) $_POST['keep_children']);
}
elseif(isset($_POST['move']))
{
$mptt->move($_POST['id'], $_POST['target_id'], $_POST['child_num']);
}
elseif(isset($_POST['copy']))
{
$mptt->copy($_POST['id'], $_POST['target_id'], $_POST['child_num']);
}
elseif(isset($_POST['swap']))
{
$mptt->swap($_POST['id1'], $_POST['id2']);
}
$sql = 'SELECT * FROM `' . TABLE_DATA . '` WHERE `id` > 0 ORDER BY `left_id` ASC';
$raw_result = mysql_query($sql) or die(mysql_error() . 'here');
while($item = mysql_fetch_array($raw_result))
{
print '<div style="margin-left: ' . $item['level'] . 'em;">' . $item['id'] . ' | ' . $item['title'] . ' - ' . $item['level'] . ' - {' . $item['left_id'] . ', ' . $item['right_id'] . '}</div>' . "\n";
}
if(!$mptt->check_consistency($errors))
{
print 'Tree is NOT consistant!<pre>';
var_dump($errors);
print '</pre>';
}
else
{
print 'Tree is consistant!';
}
?>
</body>
</html>
Manual (sort of):
Make sure you have set the constants:
TABLE_DATA - The name of the table in which the tree data is stored.
FIELD_KEY - The name of the PRIMARY KEY column (the one with row id's).
FIELD_LEFT_ID - The name of the column in which the left id's are stored.
FIELD_RIGHT_ID - The name of the column in which the right id's are stored.
FIELD_LEVEL - The name of the column in which the elemts levels are stored.
Yes, all 4 columns are required in your table setup.
Method description:
mptt:mptt($link = null)
$link - (optional) MySQL link identifier.
mptt:add($parent, $child_num = 0, $misc_data = false)
Add an element to the tree as a child of $parent and as $child_num'th child. If $data is not supplied the insert id will be returned.
$parent - The id of the parent of the added object (0 for root).
$child_num - The new element will be placed as the $child_num'th child of the parent*.
$misc_data - An array containing other data to be added to the tree. If not set the function will return the insert id of the new row.
Returns bool(true) on success unless $misc_data is not set.
mptt::delete($id, $keep_children = false)
Deletes element $id with or without children. If children should be kept they will become children of $id's parent.
$id - The id of the element to delete.
$keep_children - If true the children of the deleted element will move to the parent of the deleted element.
Returns bool(true) on success.
mptt::move($id, $target_id, $child_num = 0)
Move a element (with children) $id, under element $target_id as the $child_num'th child of that element.
$id - The element to move
$target_id - The id of the new parent.
$child_num - The new element will be placed as the $child_num'th child of the parent*.
mptt::copy($id, $parent, $child_num = 0)
Copies element $id (with children) to $parent as the $child_mun'th child.
$id - The element to move
$parent - The id of the new parent.
$child_num - The new element will be placed as the $child_num'th child of the parent*.
mptt::swap($id1, $id2)
Swaps two elements and ONLY the elements!
$id1 and $id2 - Id's of the elements to swap.
mptt::check_consistency(&$errors=array()) // Kind of experimental. But worked in tests.
Check if all of the tree's left and right id's are correct.
$errors - This will hold an array of error messages if any messages accour (null otherwise).
Returns true if there are no errors.
*$child_num is by default 0.
0 means that the element will be inserted as the first child, 1 as the 2nd child and so on.
You can also use negative numbers. -1 would be the last child... pretty much like substr().
Code:
It was too large. Attached.
Example:
SQL & example data:
CREATE TABLE `data` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`title` varchar(200) NOT NULL,
`left_id` int(10) NOT NULL,
`right_id` int(10) NOT NULL,
`level` mediumint(8) unsigned NOT NULL,
UNIQUE KEY `id` (`id`)
);
# The same example as it was on aesthetic-theory
INSERT INTO `data` VALUES (1, 'Music', 1, 14, 1);
INSERT INTO `data` VALUES (2, 'Ludo', 2, 5, 2);
INSERT INTO `data` VALUES (3, 'self titled', 3, 4, 3);
INSERT INTO `data` VALUES (4, 'weezer', 6, 13, 2);
INSERT INTO `data` VALUES (5, 'pinkerton', 7, 12, 3);
INSERT INTO `data` VALUES (6, 'el scorcho lyrics', 8, 9, 4);
INSERT INTO `data` VALUES (7, 'pink triangle lyrics', 10, 11, 4);
INSERT INTO `data` VALUES (8, 'Foods', 15, 22, 1);
INSERT INTO `data` VALUES (9, 'Meat', 16, 21, 2);
INSERT INTO `data` VALUES (10, 'Steak', 17, 18, 3);
INSERT INTO `data` VALUES (11, 'ribs', 19, 20, 3);
PHP & HTML:
<?php
// Example
?>
<html>
<head>
<title>MPTT</title>
</head>
<body>
<form name="add" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
Parent ID: <input type="text" name="parent" /><br />
As child: <input type="text" name="child_num" value="0" /><br />
Title: <input type="text" name="title" /><br />
<input type="submit" name="add" value="Add" />
</form>
<form name="delete" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID: <input type="text" name="id" /><br />
Keep children? <input type="radio" name="keep_children" value="0" checked="checked" />No
<input type="radio" name="keep_children" value="1" />Yes<br />
<input type="submit" name="delete" value="Delete" />
</form>
<form name="move" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID: <input type="text" name="id" /><br />
Target: <input type="text" name="target_id" /><br />
As child: <input type="text" name="child_num" value="0" /><br />
<input type="submit" name="move" value="Move" />
</form>
<form name="copy" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID: <input type="text" name="id" /><br />
Target: <input type="text" name="target_id" /><br />
As child: <input type="text" name="child_num" value="0" /><br />
<input type="submit" name="copy" value="Copy" />
</form>
<form name="swap" action="<?php print $_SERVER['PHP_SELF']; ?>" method="POST">
ID1: <input type="text" name="id1" /><br />
ID2: <input type="text" name="id2" /><br />
<input type="submit" name="swap" value="Swap" />
</form>
<?php
error_reporting(E_ALL);
// DB constants
define('DB_HOST', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_DATABASE', 'mptt');
// connect to the database
$link = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD) or die (mysql_error());
mysql_select_db(DB_DATABASE) or die (mysql_error());
require 'class_mptt.php';
$mptt = new mptt($link);
if(isset($_POST['add']))
{
$mptt->add($_POST['parent'], $_POST['child_num'], array('title' => $_POST['title']));
}
elseif(isset($_POST['delete']))
{
$mptt->delete($_POST['id'], (bool) $_POST['keep_children']);
}
elseif(isset($_POST['move']))
{
$mptt->move($_POST['id'], $_POST['target_id'], $_POST['child_num']);
}
elseif(isset($_POST['copy']))
{
$mptt->copy($_POST['id'], $_POST['target_id'], $_POST['child_num']);
}
elseif(isset($_POST['swap']))
{
$mptt->swap($_POST['id1'], $_POST['id2']);
}
$sql = 'SELECT * FROM `' . TABLE_DATA . '` WHERE `id` > 0 ORDER BY `left_id` ASC';
$raw_result = mysql_query($sql) or die(mysql_error() . 'here');
while($item = mysql_fetch_array($raw_result))
{
print '<div style="margin-left: ' . $item['level'] . 'em;">' . $item['id'] . ' | ' . $item['title'] . ' - ' . $item['level'] . ' - {' . $item['left_id'] . ', ' . $item['right_id'] . '}</div>' . "\n";
}
if(!$mptt->check_consistency($errors))
{
print 'Tree is NOT consistant!<pre>';
var_dump($errors);
print '</pre>';
}
else
{
print 'Tree is consistant!';
}
?>
</body>
</html>