A
A
Alexander Bulatov2017-08-03 12:44:35
Yii
Alexander Bulatov, 2017-08-03 12:44:35

Outputting a multi-level menu from a database in Yii2?

Hello everyone who came to my question.
Situation: It is
necessary to display a multi-level menu from the database, while it is necessary to be able to specify a symbolic code in the layout in order to get the menu that is needed in a particular place.
Data:
There is a database and there are two tables in it: the
first (menu list) the
796ff1c917d7466baa8e82e34584d962.png
second (menu items)
47e69af7ba1c40acb6f164b5b32c0d21.png
In the layout, the output is as follows:

<?php
    NavBar::begin([
        'brandLabel' => 'My Company',
        'brandUrl' => Yii::$app->homeUrl,
        'options' => [
            'class' => 'navbar-inverse',
        ],
    ]);
    
    echo Nav::widget([
        'options' => ['class' => 'navbar-nav'],
        'items' => \app\modules\manager\models\MenuItemsModel::viewMenuItems(),
    ]);
    
    NavBar::end();
    ?>

In the model that is chained in the items parameter, the code is as follows:
private static function getMenuItems()
    {
        $items = [];
        
        $code = 'top-menu';
        
        $query_menu = MenuModel::find()
                        ->andWhere(['code' => $code, 'status' => 1])
                        //->andWhere([])
                        ->one();
        
        $query = self::find()
                    ->andWhere([
                        'menu_id' => $query_menu->id,
                        'status' => 1
                     ])
                    ->all();
        
        foreach ($query as $item)
        {
            if ( empty($items[$item->parent_id]) )
            {
                $items[$items->parent_id] = [];
            }
            
            $items[$item->parent_id][] = $item->attributes;
        }
        
        return $items;
    }
    
    /*
     * @inheritdoc
     */
    public static function viewMenuItems($parentId = 0)
    {        
        $array = self::getMenuItems();
        
        if ( empty($array[$parentId]) ) { return; }
        
        for ( $i = 0; $i < count($array[$parentId]); $i++ )
        {
            $result[] = [
                'label' => $array[$parentId][$i]['name'],
                'url' => $array[$parentId][$i]['url_item'],
                'items' => self::viewMenuItems($array[$parentId][$i]['id'])
            ];
        }
        
        return $result;
    }

Question:
how to specify this symbolic code not in the body of the method, but in the layout, that is, in the layout or in the view ? Already tried to pass the get-parameter, but the system is very swearing.
$code = 'top-menu';

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Bulatov, 2017-10-16
@alexanderbulatov

I decided to keep it simple and traditional. Like this (may be useful to someone):
In view

if ( Choice_Menu::viewMenuItemsTop('top-menu') ) {
        echo Nav::widget([
            'options' => ['class' => 'navbar-nav'],
            'items' => Choice_Menu::viewMenuItemsTop('top-menu'),
        ]);
    }

The entire Choice_Menu class and its methods are designed like this
namespace app\modules\manager\models;

use app\modules\manager\models\MenuModel;
use app\modules\manager\models\MenuItemsModel;

/**
 * Description of Choice_Menu
 *
 * @author Максимус
 */
class Choice_Menu 
{
    /**
     * @inheritdoc
     */
    private static function getMenuItemsTop($nameMenu)
    {
        $items = [];
        
        $code = $nameMenu;
        
        $query_menu = MenuModel::find()
                        ->andWhere(['code' => $code, 'status' => 1])
                        ->one();
        
        $query = MenuItemsModel::find()
                    ->andWhere([
                        'menu_id' => $query_menu->id,
                        'status' => 1
                     ])
                    ->all();
        
        foreach ($query as $item)
        {
            if ( empty($items[$item->parent_id]) )
            {
                $items[$items->parent_id] = [];
            }
            
            $items[$item->parent_id][] = $item->attributes;
        }
        
        return $items;
    }
    
    /*
     * @inheritdoc
     */
    public static function viewMenuItemsTop($nameMenu, $parentId = 0)
    {        
        $array = self::getMenuItemsTop($nameMenu);
        
        if ( empty($array[$parentId]) ) { return; }
        
        for ( $i = 0; $i < count($array[$parentId]); $i++ )
        {
            $result[] = [
                'label' => $array[$parentId][$i]['name'],
                'url' => [$array[$parentId][$i]['url_item'].'/index'],
                'items' => self::viewMenuItemsTop($array[$parentId][$i]['id'], $nameMenu)
            ];
        }
        
        return $result;
    }
}

A
Alexey Likhachev, 2017-08-11
@Playbot

in the corresponding view via parameters

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question