I can not understand how to fill the submenu in yii2 with data, I see that it is formed like this. It is logical to have two tables parentMenu (t1) and chaildMenu (t2) in t1 foreign key -> (t1) chaild_id and in t2 (parent_id) and somehow select with one query or two, but it's not clear how to form an array, in general, it is completely confused, tell me how to do?

$menuItems = [ ['label' => 'HOME', 'url' => ['/site/index']], ['label' => 'INFO', 'items' => [ ['label' => 'About US', 'url' => ['/about-us/index']], ['label' => 'The Game', 'url' => ['/the-game/index']], ]], ['label' => 'PRICES', 'url' => ['/site/prices']], ['label' => 'FOO', 'items' => [ ['label' => 'Foo', 'url' => ['/foo/index']], 

I only get a one-level menu from one table, but I cannot understand how to make it from two.

  `$items = Menu::find()->all(); foreach ($items as $item) { $result[] = [ 'label' => $item->title, 'url' => [$item->url], ]; } return $result; 

    1 answer 1

    Two tables do not have to do. If there is nesting, then add parent. After sampling the rows from the database, the sample itself must be rewound with a foric (perhaps use -> indexBy ('id'), did not try) to form arrays for nesting. And then use the function uroboros. An example is:

     $row[] = ['id' => '1', 'parent' => '0', 'label' => 'HOME1', 'url' => 'home1']; $row[] = ['id' => '2', 'parent' => '1', 'label' => 'HOME1-1', 'url' => 'home11']; $row[] = ['id' => '3', 'parent' => '1', 'label' => 'HOME1-1', 'url' => 'home11']; $row[] = ['id' => '4', 'parent' => '0', 'label' => 'HOME2', 'url' => 'home2']; $row[] = ['id' => '5', 'parent' => '4', 'label' => 'HOME2-2', 'url' => 'home22']; $row[] = ['id' => '6', 'parent' => '4', 'label' => 'HOME2-2', 'url' => 'home22']; $row[] = ['id' => '7', 'parent' => '0', 'label' => 'HOME3', 'url' => 'home3']; $row[] = ['id' => '8', 'parent' => '7', 'label' => 'HOME3-3', 'url' => 'home33']; $row[] = ['id' => '9', 'parent' => '7', 'label' => 'HOME3-3', 'url' => 'home33']; foreach($row as $r){ $rows[$r['parent']][] = $r; } function tree($rows, $parent){ $tre = ''; if(isset($rows[$parent])){ $tre = '<ul>'; foreach($rows[$parent] as $row){ $tre .= '<li>'; $tre .= '<a href="' . $row['url'] . '">' . $row['label']; $tre .= tree($rows, $row['id']); $tre .= '</a>'; $tre .= '</li>'; } $tre .= '</ul>'; } return $tre; } echo '<pre>'; echo tree($rows, 0); echo '</pre>'; 
    • I threw in here pastebin.com/RBMzG9VJ - fedornabilkin
    • it seems a bit wrong, here is this array (in my question), there are not all the children there. and there it turns out you need to check whether there are children or not. But I will try your example, thank you. - ProMix
    • The tree checks for descendants. If not, then they will not be able to disassemble the function. - fedornabilkin