PHPackages                             codiverum/yii2-abstracttree - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. codiverum/yii2-abstracttree

ActiveYii2-extension[Utility &amp; Helpers](/categories/utility)

codiverum/yii2-abstracttree
===========================

Extension contains abstract classes to provide base for tree structured data

2571[1 issues](https://github.com/codiverum/yii2-abstracttree/issues)PHP

Since Jul 16Pushed 10y ago1 watchersCompare

[ Source](https://github.com/codiverum/yii2-abstracttree)[ Packagist](https://packagist.org/packages/codiverum/yii2-abstracttree)[ RSS](/packages/codiverum-yii2-abstracttree/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

CodiVerum Yii2 Extension for hierarchy data
===========================================

[](#codiverum-yii2-extension-for-hierarchy-data)

Extension contains abstract classes making it easy to implement tree-structured data in Yii2 Framework. It has what's needed in hierarchical data:

- multiple root nodes
- selecting parent, children, siblings, ancestors, descendants (also by distance); easy for programmer and also for DBMS.
- modifying trees like adding nodes, removing nodes and moving nodes (with or without subtree); simple (it's based on `id_parent` value changes - all the work is done by `AbstractNode` class)

I have found other solutions implementing tree structured data (like nested sets) but I don't like using recursion or subqueries for frequent queries like selecting data. I created my own way (I haven't found that kind of solution).

I hope you'll find it useful and easy.

This is my first open-source work so I'll be glad to hear any suggestions. I'm sure this little library may be improved.

The basic design puts the data into two tables:

1. node:

```
id INT PRIMARY KEY auto_increment,
id_parent_node INT DEFAULT NULL,
node_level INT NOT NULL

```

2. node\_ancestor:

```
id_node INT NOT NULL,
id_ancestor_node INT NOT NULL,

```

Proper foreign keys are also set. Note that names may be easily customized (see migration section below)

Installation
------------

[](#installation)

The preferred way to install this extension is through [composer](http://getcomposer.org/download/).

Either run

```
php composer.phar require --prefer-dist codiverum/yii2-abstracttree "dev-master"

```

or add

```
"codiverum/yii2-abstracttree": "dev-master"

```

to the require section of your `composer.json` file.

Usage
-----

[](#usage)

Using this extension you can easily make:

- customized migration
- ready to use ActiveRecord classes

#### Migration

[](#migration)

To make migration, you should create new migration:

```
yii migrate/create migration_name

```

Your migration should extend `codiverum\abstracttree\migrations\AbstractTreeBaseMigration` class, for example:

```
use codiverum\abstracttree\migrations\AbstractTreeBaseMigration;
use yii\db\Schema;

class m150505_194334_category_tree extends AbstractTreeBaseMigration {

    public function up() {
        parent::up();
        $this->addForeignKey('fk_category_usercreated', 'category', 'id_user_created', '{{%user}}', 'id', 'SET NULL', 'CASCADE');
    }

    public function getExtraNodeTableColumns() {
        return [
            'id_user_created' => Schema::TYPE_INTEGER,
            'name' => Schema::TYPE_STRING . '(128) NOT NULL',
            'description' => Schema::TYPE_TEXT,
            'created_at' => Schema::TYPE_INTEGER,
            'updated_at' => Schema::TYPE_INTEGER
        ];
    }

    public function getNodeTableName() {
        return 'category';
    }
}
```

Then apply migration using command:

```
yii migrate

```

#### Models

[](#models)

Generate pivot table using Gii and you can leave it as is. After that you can use Gii to generate model for the main table or write it on you're own. Just make sure your class is extending `AbstractNode` class. If you did - you can delete relations created for default columns (not in `getExtraNodeTablesColumns` migration method) as they are already coverd in `AbstractNode` class. You may want to add to the description of your class (use your model class name instead of `Category`):

```
 * @property Category $parent
 * @property Category[] $ancestors
 * @property Category[] $descendants
 * @property Category[] $children
 * @property Category[] $siblings
```

For migration example above, `Category` class would look like this:

```
namespace common\models;

use codiverum\abstracttree\components\interfaces\TreeNodeInterface;
use codiverum\abstracttree\models\AbstractNode;
use Yii;
use yii\db\ActiveQuery;
use common\models\User;

/**
 * This is the model class for table "category".
 *
 * @property integer $id
 * @property integer $id_parent_category
 * @property integer $id_user_created
 * @property string $name
 * @property string $description
 * @property integer $created_at
 * @property integer $updated_at
 *
 * @property User $userCreated
 * @property Category $parent
 * @property Category[] $ancestors
 * @property Category[] $descendants
 * @property Category[] $children
 * @property Category[] $siblings
 */
class Category extends AbstractNode implements TreeNodeInterface {

    public function beforeSave($insert) {
        if ($insert) {
            $this->id_user_created = Yii::$app->user->id;
        }
        return parent::beforeSave($insert);
    }

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return 'category';
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['id_parent_category', 'category_level', 'id_user_created', 'created_at', 'updated_at'], 'integer'],
            [['name', 'category_level'], 'required'],
            [['description'], 'string'],
            [['name'], 'string', 'max' => 128],
            [['name', 'id_parent_category'], 'unique', 'targetAttribute' => ['name', 'id_parent_category'], 'message' => 'The combination of Id Parent Category and Name has already been taken.']
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => Yii::t('db', 'ID'),
            'id_parent_category' => Yii::t('db', 'Id Parent Category'),
            'id_user_created' => Yii::t('db', 'Id User Created'),
            'name' => Yii::t('db', 'Name'),
            'category_category_level' => Yii::t('db', 'Category Level'),
            'description' => Yii::t('db', 'Description'),
            'created_at' => Yii::t('db', 'Created At'),
            'updated_at' => Yii::t('db', 'Updated At'),
            'parent.name' => Yii::t('db', 'Parent'),
            'userCreated.display_name' => Yii::t('db', 'Author'),
            'category_level' => Yii::t('db', 'Level'),
            'parent' => Yii::t('db', 'Parent'),
            'userCreated' => Yii::t('db', 'Author'),
        ];
    }

    /**
     * @return ActiveQuery
     */
    public function getUserCreated() {
        return $this->hasOne(User::className(), ['id' => 'id_user_created']);
    }

}
```

That's it.

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance10

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/4b012aeb934161c53376d587e74c8436ce5b90ff45bd85ad87014f96cceb6b99?d=identicon)[codiverum](/maintainers/codiverum)

### Embed Badge

![Health badge](/badges/codiverum-yii2-abstracttree/health.svg)

```
[![Health](https://phpackages.com/badges/codiverum-yii2-abstracttree/health.svg)](https://phpackages.com/packages/codiverum-yii2-abstracttree)
```

###  Alternatives

[makeabledk/laravel-factory-enhanced

180118.6k4](/packages/makeabledk-laravel-factory-enhanced)[lukeraymonddowning/self-healing-urls

16715.9k](/packages/lukeraymonddowning-self-healing-urls)[yii2mod/yii2-sweet-alert

Alert widget based on SweetAlert extension {@link http://tristanedwards.me/sweetalert)

43154.0k2](/packages/yii2mod-yii2-sweet-alert)[heureka/inflection

Czech inflection library

6163.9k](/packages/heureka-inflection)[ptachoire/php-dmtx

Datamatrix r/w based on libdmtx &lt;http://www.libdmtx.org/&gt;

1868.3k](/packages/ptachoire-php-dmtx)[cybercog/yii2-google-analytics

Google Analytics Widget for the Yii2 framework

1677.1k2](/packages/cybercog-yii2-google-analytics)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
