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