Nested Sets Behavior for Yii 2
, (*1)
A modern nested sets behavior for the Yii framework utilizing the Modified Preorder Tree Traversal algorithm., (*2)
Installation
The preferred way to install this extension is through composer., (*3)
Either run, (*4)
$ composer require creocoder/yii2-nested-sets
or add, (*5)
"creocoder/yii2-nested-sets": "0.9.*"
to the require
section of your composer.json
file., (*6)
Migrations
Run the following command, (*7)
$ yii migrate/create create_menu_table
Open the /path/to/migrations/m_xxxxxx_xxxxxx_create_menu_table.php
file,
inside the up()
method add the following, (*8)
$this->createTable('{{%menu}}', [
'id' => Schema::TYPE_PK,
// 'tree' => Schema::TYPE_INTEGER,
'lft' => Schema::TYPE_INTEGER . ' NOT NULL',
'rgt' => Schema::TYPE_INTEGER . ' NOT NULL',
'depth' => Schema::TYPE_INTEGER . ' NOT NULL',
'name' => Schema::TYPE_STRING . ' NOT NULL',
]);
To use multiple tree mode uncomment tree
field., (*9)
Configuring
Configure model as follows, (*10)
use creocoder\nestedsets\NestedSetsBehavior;
class Menu extends \yii\db\ActiveRecord
{
public function behaviors() {
return [
'tree' => [
'class' => NestedSetsBehavior::className(),
// 'treeAttribute' => 'tree',
// 'leftAttribute' => 'lft',
// 'rightAttribute' => 'rgt',
// 'depthAttribute' => 'depth',
],
];
}
public function transactions()
{
return [
self::SCENARIO_DEFAULT => self::OP_ALL,
];
}
public static function find()
{
return new MenuQuery(get_called_class());
}
}
To use multiple tree mode uncomment treeAttribute
array key inside behaviors()
method., (*11)
Configure query class as follows, (*12)
use creocoder\nestedsets\NestedSetsQueryBehavior;
class MenuQuery extends \yii\db\ActiveQuery
{
public function behaviors() {
return [
NestedSetsQueryBehavior::className(),
];
}
}
Usage
Making a root node
To make a root node, (*13)
$countries = new Menu(['name' => 'Countries']);
$countries->makeRoot();
The tree will look like this, (*14)
- Countries
Prepending a node as the first child of another node
To prepend a node as the first child of another node, (*15)
$russia = new Menu(['name' => 'Russia']);
$russia->prependTo($countries);
The tree will look like this, (*16)
- Countries
- Russia
Appending a node as the last child of another node
To append a node as the last child of another node, (*17)
$australia = new Menu(['name' => 'Australia']);
$australia->appendTo($countries);
The tree will look like this, (*18)
- Countries
- Russia
- Australia
Inserting a node before another node
To insert a node before another node, (*19)
$newZeeland = new Menu(['name' => 'New Zeeland']);
$newZeeland->insertBefore($australia);
The tree will look like this, (*20)
- Countries
- Russia
- New Zeeland
- Australia
Inserting a node after another node
To insert a node after another node, (*21)
$unitedStates = new Menu(['name' => 'United States']);
$unitedStates->insertAfter($australia);
The tree will look like this, (*22)
- Countries
- Russia
- New Zeeland
- Australia
- United States
Getting the root nodes
To get all the root nodes, (*23)
$roots = Menu::find()->roots()->all();
Getting the leaves nodes
To get all the leaves nodes, (*24)
$leaves = Menu::find()->leaves()->all();
To get all the leaves of a node, (*25)
$countries = Menu::findOne(['name' => 'Countries']);
$leaves = $countries->leaves()->all();
Getting children of a node
To get all the children of a node, (*26)
$countries = Menu::findOne(['name' => 'Countries']);
$children = $countries->children()->all();
To get the first level children of a node, (*27)
$countries = Menu::findOne(['name' => 'Countries']);
$children = $countries->children(1)->all();
Getting parents of a node
To get all the parents of a node, (*28)
$countries = Menu::findOne(['name' => 'Countries']);
$parents = $countries->parents()->all();
To get the first parent of a node, (*29)
$countries = Menu::findOne(['name' => 'Countries']);
$parent = $countries->parents(1)->one();
Donating
Support this project and others by creocoder via gratipay., (*30)
, (*31)