phpmysqljsonfancytreenested-set-model

Create JSON for Fancytree from a nested set model structure


I would like to display a data structure with the jquery plugin Fancytree. After a long search in Google, it seems that the best way to store a data structure in a database is the Nested Set Model (described on Stackoverflow here php / Mysql best tree structure ). However making the related nested JSON of such structure for display is quite difficult, I could not make it..

This consists to transform the following MySQL table :

| category_id | name | lft | rgt | depth |

| 1 | ELECTRONICS | 1 | 20 | 0 |

| 2 | TELEVISIONS | 2 | 9 | 1 |

| 3 | TUBE | 3 | 4 | 2 |

| 4 | LCD | 5 | 6 | 2 |

| 5 | PLASMA | 7 | 8 | 2 |

| 6 | PORTABLE ELECTRONICS | 10 | 19 | 1 |

| 7 | MP3 PLAYERS | 11 | 14 | 2 |

| 8 | FLASH | 12 | 13 | 3 |

| 9 | CD PLAYERS | 15 | 16 | 2 |

| 10 | 2 WAY RADIOS | 17 | 18 | 2 |

Into this JSON:

[{"key": "1", "title": "ELECTRONICS", "expanded": true, "children": [
    {"key": "2", "title": "TELEVISION", "expanded": true, "children": [
        {"key": "3", "title": "TUBE"},
        {"key": "4", "title": "LCD"},
        {"key": "5", "title": "PLASMA"}
    ]},
    {"key": "6", "title": "PORTABLE ELECTRONICS", "expanded": true, "children": [
        {"key": "7", "title": "MP3 PLAYERS", "expanded": true, "children": [{"key": "8", "title": "FLASH"}]},
        {"key": "9", "title": "CD PLAYERS"},
        {"key": "10", "title": "2 WAY RADIOS"}
    ]}
]}]

I would like to know whether it exists a simple way to transform the MySQL data into a hierarchical nested JSON? Thanks!


Solution

  • Finally, I managed to make my tree working by making the JSON little by little. I do not think it is proper since it is not made of object and array, but this seems to work fine

     <?php 
        if (!isset($DB_connection)) { require_once('../config/_db_connect.php'); } 
        $result = $DB_connection->prepare("SELECT node.category_id, node.name, 
         (COUNT(parent.name) - 1) AS depth FROM nested_category AS node,
          nested_category AS parent WHERE node.lft BETWEEN parent.lft 
          AND parent.rgt GROUP BY node.name ORDER BY node.lft;"); 
        $result->execute(); 
    
        $i = 0;
        $nb_open = 0;
        $current_level = '';
    
        echo "[{";
        while( $line = $result->fetch(PDO::FETCH_OBJ) )
        {                       
            if ($current_level == '') { $current_level = $line->depth; } 
    
            if ($current_level == $line->depth) { if ($i > 0) { echo " }, {"; } }
            elseif ($current_level < $line->depth) {
                echo ',  "children": [ { ';
                $nb_open = $nb_open + 1;
            }
            elseif ($current_level > $line->depth) {
                $nb_to_close = $current_level - $line->depth;
                for ($j = 1; $j <= $nb_to_close; $j++) {
                    $nb_open = $nb_open - 1;
                    echo " }]";
                }
                echo "}, {";
            }
    
            echo ' "title": "' . $line->name . '", "key": "' .
                  $line->category_id . '", "expanded": true';
            $current_level = $line->depth;
            $i++;
        }
    
        if ($nb_open>0) { for ($i = 1; $i <= $nb_open; $i++) { echo "}]"; } }
        echo "}]";
        ?>