Skip to content

aaiyo/yii2-nested-sets

 
 

Repository files navigation

Nested Sets Behavior for Yii 2

Build Status Code Coverage Packagist Version Total Downloads

A modern nested sets behavior for the Yii framework utilizing the Modified Preorder Tree Traversal algorithm.

Installation

The preferred way to install this extension is through composer.

Either run

$ composer require creocoder/yii2-nested-sets

or add

"creocoder/yii2-nested-sets": "0.9.*"

to the require section of your composer.json file.

Migrations

Run the following command

$ 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

$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.

Configuring

Configure model as follows

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.

Configure query class as follows

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

$countries = new Menu(['name' => 'Countries']);
$countries->makeRoot();

The tree will look like this

- Countries

Prepending a node as the first child of another node

To prepend a node as the first child of another node

$russia = new Menu(['name' => 'Russia']);
$russia->prependTo($countries);

The tree will look like this

- Countries
    - Russia

Appending a node as the last child of another node

To append a node as the last child of another node

$australia = new Menu(['name' => 'Australia']);
$australia->appendTo($countries);

The tree will look like this

- Countries
    - Russia
    - Australia

Inserting a node before another node

To insert a node before another node

$newZeeland = new Menu(['name' => 'New Zeeland']);
$newZeeland->insertBefore($australia);

The tree will look like this

- Countries
    - Russia
    - New Zeeland
    - Australia

Inserting a node after another node

To insert a node after another node

$unitedStates = new Menu(['name' => 'United States']);
$unitedStates->insertAfter($australia);

The tree will look like this

- Countries
    - Russia
    - New Zeeland
    - Australia
    - United States

Getting the root nodes

To get all the root nodes

$roots = Menu::find()->roots()->all();

Getting the leaves nodes

To get all the leaves nodes

$leaves = Menu::find()->leaves()->all();

To get all the leaves of a node

$countries = Menu::findOne(['name' => 'Countries']);
$leaves = $countries->leaves()->all();

Getting children of a node

To get all the children of a node

$countries = Menu::findOne(['name' => 'Countries']);
$children = $countries->children()->all();

To get the first level children of a node

$countries = Menu::findOne(['name' => 'Countries']);
$children = $countries->children(1)->all();

Getting parents of a node

To get all the parents of a node

$countries = Menu::findOne(['name' => 'Countries']);
$parents = $countries->parents()->all();

To get the first parent of a node

$countries = Menu::findOne(['name' => 'Countries']);
$parent = $countries->parents(1)->one();

Donating

Support this project and others by creocoder via gratipay.

Support via Gratipay

About

The nested sets behavior for the Yii framework.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%