Search code examples
recursionparent-childmenu-items

Algorithm to Save Items with Parent-Child Relationship to Database


I need help designing the logic of an app that I am working on. The application should enable users to create mindmaps and save them to a mysql database for later editing. Each mindmap is made up of inter-related nodes, meaning a node should have a parent node and the id of the mindmap to which it belongs. I am stuck here. How can I save the nodes to the database and be able to query and rebuild the mindmap tree from the query results.

Root
   Child1
   Child2
      GrandChild1
    GreatGrandChild1
    GreatGrandChild1
   Child3
      GrandChild2

I need an algorithm, that can save the nodes and also be able to figure out the relationships/order of items similar to the Tree that I have given. This is very much like how menus are saved and retrieved in Wordpress but I can't find the right logic to do this. I know there are really great people here. Please help.


Solution

  • I finally found a solution. Here's my full code.

    require_once('config.php');//db conn
    $connect = mysql_connect(DB_HOST, DB_USER, DB_PASS);
    mysql_select_db(DB_NAME);
    $nav_query = MYSQL_QUERY("SELECT * FROM `nodes` ORDER BY `id`");
    $tree = "";                         // Clear the directory tree
    $depth = 1;                         // Child level depth.
    $top_level_on = 1;               // What top-level category are we on?
    $exclude = ARRAY();               // Define the exclusion array
    ARRAY_PUSH($exclude, 0);     // Put a starting value in it
    
    WHILE ( $nav_row = MYSQL_FETCH_ARRAY($nav_query) )
    {
         $goOn = 1;               // Resets variable to allow us to continue building out the tree.
         FOR($x = 0; $x < COUNT($exclude); $x++ )          // Check to see if the new item has been used
         {
              IF ( $exclude[$x] == $nav_row['id'] )
              {
                   $goOn = 0;
                   BREAK;                    // Stop looking b/c we already found that it's in the exclusion list and we can't continue to process this node
              }
         }
         IF ( $goOn == 1 )
         {
              $tree .= $nav_row['name'] . "<br>";                    // Process the main tree node
              ARRAY_PUSH($exclude, $nav_row['id']);          // Add to the exclusion list
              IF ( $nav_row['id'] < 6 )
              { $top_level_on = $nav_row['id']; }
    
              $tree .= build_child($nav_row['id']);          // Start the recursive function of building the child tree
         }
    }
    
    FUNCTION build_child($oldID)               // Recursive function to get all of the children...unlimited depth
    {
        $tempTree='<ul>';
         GLOBAL $exclude, $depth;               // Refer to the global array defined at the top of this script
         $child_query = MYSQL_QUERY("SELECT * FROM `nodes` WHERE parent_id=" . $oldID);
         WHILE ( $child = MYSQL_FETCH_ARRAY($child_query) )
         {
              IF ( $child['id'] != $child['parent_id'] )
              {
                   FOR ( $c=0;$c<$depth;$c++ )               // Indent over so that there is distinction between levels
                   { $tempTree .= "&nbsp;"; }
                   $tempTree .= "<li>" . $child['name'] . "</li>";
                   $depth++;          // Incriment depth b/c we're building this child's child tree  (complicated yet???)
                   $tempTree .= build_child($child['id']);          // Add to the temporary local tree
                   $depth--;          // Decrement depth b/c we're done building the child's child tree.
                   ARRAY_PUSH($exclude, $child['id']);               // Add the item to the exclusion list
              }
         }
    
         RETURN $tempTree.'</ul>';          // Return the entire child tree
    }
    
    ECHO $tree;
    
    ?>
    

    This is based on the piece of code found here http://psoug.org/snippet/PHP-Recursive-function-to-generate-a-parentchild-tree_338.html I hope this helps someone as well