V
V
Victor Umansky2017-03-19 03:35:26
Yii
Victor Umansky, 2017-03-19 03:35:26

Yii2 how to display categories from the database when they have subcategories with subcategories?

Good night everybody!
That's because I want to display my categories on the pictures, but I got confused with foreach and my head is already going bad.
c2deaab9fe5345f08d3dc5836cc3d3af.png
As you can see in the pictures there is
1 Spoiler these are the names of the category
2 The category has a subcategory, then it is without a checkbox, if the subcategory has its own subcategories, then they become checkboxes
Please tell me how to correctly implement this!
Example of my database how I store my categories:
id | parent_id | title
1 | 0 | Advertising
2 | 0 | Auto services
3 | 1 | Setting up contextual advertising
4 | 3 | SEO site optimization
5 | 3 | Advertising in social networks
6 | 1 | Promoter Services
7 | 6 | Merchandiser
9 | 6 | Promoter in supermarket
10| 6 | Sociological polls
11| 2 | Body repair
12| 2 | Tow Truck
13| 2 | Charging the battery
... | ...... | ......................................
How I want it to be

menu
     - menu
          - menu
          - menu
     - menu
          - menu
          - menu
menu
     - menu
          - menu
          - menu
     - menu
          - menu
          - menu

Thanks in advance!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Shamsudin Serderov, 2017-03-19
@Steein

$menu = Array( // Предполагалось, что он SQL SELECT
  Array('id'=>1,'title'=>'Menu 1',          'parent_id'=>null),
  Array('id'=>2,'title'=>'Sub 1.1',         'parent_id'=>1),
  Array('id'=>3,'title'=>'Sub 1.2',         'parent_id'=>1),
  Array('id'=>4,'title'=>'Sub 1.3',         'parent_id'=>1),
  Array('id'=>5,'title'=>'Menu 2',          'parent_id'=>null),
  Array('id'=>6,'title'=>'Sub 2.1',         'parent_id'=>5),
  Array('id'=>7,'title'=>'Sub Sub 2.1.1',   'parent_id'=>6),
  Array('id'=>8,'title'=>'Sub 2.2',         'parent_id'=>5),
  Array('id'=>9,'title'=>'Menu 3',          'parent_id'=>null),
);

function has_children($rows,$id) {
  foreach ($rows as $row) {
    if ($row['parent_id'] == $id)
      return true;
  }
  return false;
}
function build_menu($rows,$parent=0)
{  
  $result = "<ul>";
  foreach ($rows as $row)
  {
    if ($row['parent_id'] == $parent){
      $result.= "<li>{$row[title]}";
      if (has_children($rows,$row['id']))
        $result.= build_menu($rows,$row['id']);
      $result.= "</li>";
    }
  }
  $result.= "</ul>";

  return $result;
}
echo build_menu($menu);

<ul>
  <li>Menu 1<ul>
    <li>Sub 1.1</li>
    <li>Sub 1.2</li>
    <li>Sub 1.3</li>
  </ul></li>
  <li>Menu 2<ul>
    <li>Sub 2.1<ul>
      <li>Sub Sub 2.1.1</li>
    </ul></li>
    <li>Sub 2.2</li>
  </ul></li>
  <li>Menu 3</li>
</ul>

V
Viktor Umansky, 2017-03-20
@Uman

You need to make a widget, create a componets folder, and there CREATE FILE CategoryWidget.php
below is the code

<?php

namespace app\components;

use Yii;
use yii\base\Widget;
use app\models\Category;

class CategoryWidget extends Widget
{
    public $tpl;
    public $model;
    public $data;
    public $tree;
    public $menuHtml;

    public function init()
    {
        parent::init();
        if ($this->tpl === null) {
            $this->tpl = 'category';
        }
        $this->tpl .= '.php';
    }

    public function run()
    {
        // get cache
//        if ($this->tpl == 'category.php') {
//            $menu = Yii::$app->cache->get('category');
//            if ($menu) return $menu;
//        }

        $this->data = Category::find()
            ->indexBy('id')
            ->orderBy('sortOrder')
            ->asArray()
            ->all();
        $this->tree = $this->getTree();
        $this->menuHtml = $this->getMenuHtml($this->tree);
        // set cache
//        if ($this->tpl == 'category.php') {
//            Yii::$app->cache->set('category', $this->menuHtml, 60);
//        }
        return $this->menuHtml;
    }

    protected function getTree()
    {
        $tree = [];

        foreach ($this->data as $id => &$node) {
            if (!$node['parent_id']) {
                $tree[$id] = &$node;
            } else {
                $this->data[$node['parent_id']]['children'][$node['id']] = &$node;
            }
        }
        return $tree;
    }

    protected function getMenuHtml($tree){
        $str = '';
        foreach ($tree as $category) {
            $str .= $this->catToTemplate($category);
        }
        return $str;
    }

    protected function catToTemplate($category)
    {
        ob_start();
        include __DIR__ . '/category_tpl/' . $this->tpl;
        return ob_get_clean();
    }

}

then in the components folder we create another folder called category_tpl, there we create the category.php file
below is the code
<?= $category['title'] ?>
            <?php if (isset($category['children'])): ?><br/>
                <?= $this->getMenuHtml($category['children']) ?>
            <?php endif; ?>

Then in the view we render the widget
<?= CategoryWidget::widget(['tpl' => 'category']) ?>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question