Topic: Mifjs and Nested Sets
If you want to use this formidable script with nested sets (also referred to as modified preorder tree traversal) this is how you can do it:
Load hierarchy from database
1. First you need a table with lft and rgt values, see here for further details: http://dev.mysql.com/tech-resources/art
-data.html
2. Then you may want to query the database like this:
$sql = "SELECT node.title, (COUNT(parent.id) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.id
ORDER BY node.lft";
3. You need to change the resulting array a bit:
for($i=0;$i<count($urls);$i++) {
$urls[$i]["property"] = array("name"=>$urls[$i]['title']);
$urls[$i]["type"] = $type;
unset($urls[$i]["title"]);
}4. The function toHierarchy:
function _toHierarchy(&$collection) {
$trees = array();
$l = 0;
if (count($collection) > 0) {
$stack = array();
foreach ($collection as $node) {
$item = $node;
$item["children"] = array();
$l = count($stack);
while ($l > 0 && $stack[$l-1]['depth'] >= $item['depth']) {
array_pop($stack);
$l--;
}
if ($l == 0) {
$i = count($trees);
$trees[$i] = $item;
$stack[] = &$trees[$i];
} else {
$i = count($stack[$l-1]["children"]);
$stack[$l-1]["children"][$i]=$item;
$stack[]=&$stack[$l-1]["children"][$i];
}
}
}
return $trees;
}5. The last part is to load the json_encoded array via tree.load({someurl});
Save hierarchy to Database
1. First thing: you have to serialize the tree. The simpliest way is to alter Mif.Tree via Class.Refactor:
Mif.Tree = Class.refactor(Mif.Tree, {
serialize: function(items){
var that=this;
var serial = [];
if (!items) items = this.root.getChildren();
items.each(function(el, j){
serial[j] = {
id: el.UID,
url: encodeURIComponent(el.property.url),
name: el.property.name,
children: (el.getChildren()) ? that.serialize(el.getChildren()) : []
};
});
return serial;
}
});Adopted from here: http://pilon.nl/mootools/2008/12/19/sav otools-12/
2. To save the tree you need to get the new left and right values for each array item:
function saveTree() {
$m = json_decode(stripslashes($_REQUEST['m']));
$tree = (array)$m[0];
$sql = "DELETE FROM nested_category";
$db->setQuery($sql);
$db->query();
$sql = "ALTER TABLE nested_category AUTO_INCREMENT=0";
$db->setQuery($sql);
$db->query();
$this->rebuild_tree(&$tree, 1);
}
function rebuild_tree($parent, $left) {
$right = $left+1;
foreach ($parent["children"] as $child)
$right = $this->rebuild_tree((array)$child, $right);
$sql = "INSERT INTO nested_category (`lft`,`rgt`,`title`) VALUES($left, $right, '{$parent["name"]}')";
$db = &$this->db;
$db->setQuery($sql);
$db->query();
return $right+1;
}3. Saving like this surely is not the most elegant way (as we drop the whole table) but for small trees it's far less complex.
4. And off you go !
Please do not hesitate to ask questions and thanks again for this wonderful script (MifJS).
Cheers,
Jan