Answer the question
In order to leave comments, you need to log in
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.
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
Answer the question
In order to leave comments, you need to log in
$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>
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();
}
}
<?= $category['title'] ?>
<?php if (isset($category['children'])): ?><br/>
<?= $this->getMenuHtml($category['children']) ?>
<?php endif; ?>
<?= CategoryWidget::widget(['tpl' => 'category']) ?>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question