1

I'm looking to write a function that takes an array of pages/categories (from a flat database result) and echo to a nested page/category <ul> (HTML unordered list) items based on the parent ids. I would like to do this recursively, so that any level of nesting can be done.

+-------+---------------+---------------------------+
|   id  |   parent_id   |           title           |
+-------+---------------+---------------------------+
|   1   |       0       |   Parent Page             |
|   2   |       1       |   Sub Page                |
|   3   |       2       |   Sub Sub Page            |
|   4   |       0       |   Another Parent Page     |
+-------+---------------+---------------------------+

And this is the array I would like to end up with to process in my view files:

Array
(
[0] => Array
    (
        [id] => 1
        [parent_id] => 0
        [title] => Parent Page
        [children] => Array
                    (
                        [0] => Array
                            (
                                [id] => 2
                                [parent_id] => 1
                                [title] => Sub Page
                                [children] => Array
                                            (
                                                [0] => Array
                                                    (
                                                        [id] => 3
                                                        [parent_id] => 1
                                                        [title] => Sub Sub Page
                                                    )
                                            )
                            )
                    )
    )
[1] => Array
    (
        [id] => 4
        [parent_id] => 0
        [title] => Another Parent Page
    )
)

I found this article which is SIMILAR but NOT DUPLICATE to the one I'm posting, which is where I found the below function which could help with the answer.

function buildTree(array $elements, $parentId = 0) {
$branch = array();

foreach ($elements as $element) {
    if ($element->parent_id == $parentId) {
        $children = buildTree($elements, $element->id);
        if ($children) {
            $element->children = $children;
        }
        $branch[] = $element;
    }
}

return $branch;
}

$tree = buildTree($rows);

EDIT:

I want to echo the data in the below structure:

<ul>
  <li><a href="#">Parent Page</a>
    <ul>
      <li><a href="#">Sub Page</a>
        <ul>
          <li><a href="#">Sub Sub Page</a>
        </ul>
        </li>
    </ul>
    </li>
    <li><a href="#">Another Parent Page</a>
    </li>
</ul>

1
  • I've added edits to make it more clear Commented Jul 20, 2015 at 11:29

2 Answers 2

1

Try this function and change as your requirement:

function buildTree(Array $data, $parent = 0) {
$tree = array();
foreach ($data as $d) {
    if ($d['parent'] == $parent) {
        $children = buildTree($data, $d['id']);
        // set a trivial key
        if (!empty($children)) {
            $d['_children'] = $children;
        }
        $tree[] = $d;
    }
}
return $tree;
}

function printTree($tree, $r = 0, $p = null) { 
foreach ($tree as $i => $t) {
    $dash = ($t['parent'] == 0) ? '' : str_repeat('-', $r) .' '; 
    printf("\t<option value='%d'>%s%s</option>\n", $t['id'], $dash, $t['name']);
    if ($t['parent'] == $p) {
        // reset $r
       $r = 0; 
    }
    if (isset($t['_children'])) {
        printTree($t['_children'],$sel, ++$r, $t['parent']);
    }
}
}
$rows = array('your array');

$tree = buildTree($rows);

print("<select name='selectionParentpage' class='just_textfield' id='selectionParentpage'><option value=''>--Select Page--</option>\n");
printTree($tree);
print("</select>");
Sign up to request clarification or add additional context in comments.

Comments

0

Here is what you can do for the view part

function displayRecursive($array){
    echo "<ul>";
        foreach($array as $value){
        echo "<li><a href='#'>".$value['name']."</a>";
            if(isset($value['children']) && !empty($value['children'])){
                displayRecursive($value['children']);
            }
        }
    echo "</ul>";
}

You can use something like this to get the treeview array:

    function recursive($parentId=0){

    $return = array();

    $titles=$this->db->query("
                SELECT      `t1`. * , `t2`.`id` AS `has_children`
                FROM        `titles` `t1`
                LEFT JOIN   `titles` `t2` ON ( `t1`.id = `t2`.`parent_id` )
                WHERE       `t1`.`parent_id` = '$parentId'
                GROUP BY    `t1`.`id` ")->result_array();
    if(!empty($titles)){          
        foreach ($titles as $k=>$title){
            $item = $title;
            if ($title['has_children']>0){
                $item['sub'] = self::recursive($title['id']);
            }
            array_push($return, $item);
        }
    }

    return $return;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.