Search code examples
phphtmllistrecursionnested-lists

recrusive looping and printing category Tree with multipule children


I have multiple Questions about my approach to my problem and how to solve it etc.

Problem: I need to a function that loops through a category tree which could have up to 6 drop downs and also returns an HTML String that contain the name of category link and its sub category's

  1. Is the recursive function really the best approach to what I am doing? if not why and what should I be using instead of the recursive method?
  2. In my code I am trying to loop through the children of the parent and printing an HTML string that should look like thisul class="child first"><li class="parent"><a class="arrow-right" href="#">(parent name in the list)</a><ul class='child second'><li class="parent"><a class="arrow-right" href="#">(the name of the first sub child in parent)</a><ul class='child third'><li class="parent"><a href="#">last child of the previous sub child </a></li> which I am getting only when looping through the first child and after looping through the first child to the second every previous child gets duplicated for example: ul class="child first"><li class="parent"><a class="arrow-right" href="#">(parent name in the list)</a><ul class='child second'><li class="parent"><a class="arrow-right" href="#">(the name of the first sub child in parent)</a><ul class='child third'>ul class="child first"><li class="parent"><a class="arrow-right" href="#">(parent name in the list)</a><ul class='child second'><li class="parent"><a class="arrow-right" href="#">(the name of the first sub child in parent)</a><ul class='child third'><li class="parent"><a href="#">last child of the previous sub child </a></li> <ul class='child second'><li class="parent"><a class="arrow-right" href="#">(the name of the second sub child in parent)</a><ul class='child third'> and I know its because of the way I am calling the recursive function but I am lost and don't know how to call it otherwise.

My code:

    function loopingThroughTree($listAllEntries, $categoryTree, $i = 0): string
    {
    
        $childLists =
            [
                0 => 'second',
                1 => 'third',
                2 => 'fourth',
                3 => 'fifth',
                4 => 'sixth'
            ];
    
    
    
        foreach ($categoryTree['sub'] as $categoryLevel) {
    
                $children [] = $categoryLevel;
                if ($categoryLevel['sub'] != null) {
                    $listAllEntries .= '<li class="parent"><a class="'
                        . appendArrow($categoryLevel) . '" href="'
                        . $categoryLevel['link'] . '">' .
                        $categoryLevel['name'] .
                        "</a><ul class='child {$childLists[$i]}'>";
                    $i++;
                    $children[] = $listAllEntries;
                    $listAllEntries .= loopingThroughTree($listAllEntries, $categoryLevel, $i);
                } else {
                    $listAllEntries .= '<li class="parent"><a href="'
                        . $categoryLevel['link'] . '">' .
                        $categoryLevel['name'] .
                        '</a></li>';
                }
        }
    
    
        $listAllEntries .= "</ul>";
    
        return $listAllEntries;
    
    }
$listAllEntries = '<ul class="child first">';
loopingThroughTree(listAllEntires,categoryTree)

Note:(I know that my HTML strings are wrong its and that's because I am only focusing on the logic for the moment)

Example of what my list looks like:

parent => child[0]=>child[0]=>child[0]
                              child[1]
                              child[2]=>child[0]
                                        child[1]=>child[0]
                                                  child[1]
                                                  child[2]=>child[0]
                                                            child[1]
                                                            child[2]
                                        child[2]
                    child[1]
                    child[2]


          child[1]=>child[0]
                    child[1]
                    child[2]=>child[0]
                              child[1]
                              child[2]=>child[0]
                                        child[1]=>child[0]
                                                  child[1]
                                                  child[2]=>child[0]
                                                            child[1]
                                                            child[2]
                                        child[2]

Solution

  • I still don't know if my recursive function the best approach but I fixed the problem by looping through the children array and inserting the loop inside of my $listAllEntries string.

    function loopingThroughTree($listAllEntries, $categoryTree = null, $i = 0): string
    {
    
        $children = array();
    
        $childLists =
            [
                0 => 'second',
                1 => 'third',
                2 => 'fourth',
                3 => 'fifth',
                4 => 'sixth'
            ];
    
        foreach ($categoryTree['sub'] as $categoryLevel => $parent) {
            unset($categoryTree[$parent]);
                if ($parent['sub'] == null) {
                    $listAllEntries .= '<li class="parent"><a href="'
                        . $parent['link'] . '">' .
                        $parent['name'] .
                        '</a></li>';
                    $i = 0;
                }else {
                    $listAllEntries .= '<li class="parent"><a class="'
                        . appendArrow($parent) . '" href="'
                        . $parent['link'] . '">' .
                        $parent['name'] .
                        "</a><ul class='child {$childLists[$i]}'>";
                    ($categoryLevel != $i) ? $i++ : $i = 0;
                    $listAllEntries .= loopingThroughTree( $children, $parent, $i);
                }
            }
    
    
        $listAllEntries .= "</ul>";
        return trim($listAllEntries, "Array");
    
    }