PHPackages                             allegiance-group/nested-set - 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. [Database &amp; ORM](/categories/database)
4. /
5. allegiance-group/nested-set

ActiveLibrary[Database &amp; ORM](/categories/database)

allegiance-group/nested-set
===========================

PHP library for manipulating and retrieving database records using nested set model technique to represent tree data structure

2.3.4(3y ago)02.4kBSD-3-ClausePHPPHP ^5.6 || ^7.0 || ^8

Since May 10Pushed 3y agoCompare

[ Source](https://github.com/Beaconfire/NestedSet)[ Packagist](https://packagist.org/packages/allegiance-group/nested-set)[ Docs](https://github.com/Beaconfire/NestedSet)[ RSS](/packages/allegiance-group-nested-set/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (4)Versions (20)Used By (0)

metalinspired\\NestedSet v2
===========================

[](#metalinspirednestedset-v2)

Introduction
------------

[](#introduction)

This is a fork of the repository by metalspired found at . This was created to apply the following patches: (Find nested set node id by custom data)\[\] (Prevent warnings in Drupal admin)\[\]

This library allows you to manipulate and retrieve database records using [nested set model](https://en.wikipedia.org/wiki/Nested_set_model) technique to represent tree data structure. It uses Laminas\\Db as underlying database abstraction layer.

Requirements
------------

[](#requirements)

- PHP &gt;= 5.6
- Laminas\\Db &gt;= 2.8

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

[](#installation)

```
$ composer require metalinspired/nested-set
```

Usage
=====

[](#usage)

(Hybrid) Nested Set
-------------------

[](#hybrid-nested-set)

Nested Set requires only `left` and `right` columns in table to represent a tree structure. Hybrid Nested Set requires additional `parent`, `ordering` and `depth` columns. This addition makes manipulation more complex but greatly simplifies retrieval of nodes. For example, in order to find siblings of a node we simply query for nodes with same parent, instead of using `join` to find parent and `join` to get parent's immediate descendants. `Ordering` column is used to represent natural order of nodes.

Config object
-------------

[](#config-object)

[Config](src/Config.php) class, as name suggests, is used to create an object with predefined configuration for manipulation/selection classes in this utility, and you do so by changing values of its public members. It also has three static methods that create instance of Config object and set its *$adapter* member to an *Laminas\\DB\\Adapter\\Driver* instance.

Example:

```
// Create Config object with DSN data
$config = Config::createWithDsn('mysql:dbname=some_database;host=localhost', 'some_user', 'some_password');

// Set table name
$config->table = 'some_table';

// If we don't want to retrieve all columns when using find methods
// we specify which columns we want to fetch
$config->columns = ['column1', 'column5', 'alias_of_column' => 'column7'];

// You can also instruct methods from Find class to include searching node in results
// For example, if you want to get children of node with id 5 including the node with id 5
$config->includeSearchingNode = true;
```

Manipulation
------------

[](#manipulation)

[HybridManipulate](src/HybridFind.php) and [Manipulate](src/Find.php) classes contain methods for creating (inserting), moving and deleting nodes in nested set model. It also has createRootNode method that creates a root node that serves as a container for all other nodes.

Example:

```
// Create an instance of Manipulate class
$manipulate = new Manipulate($config);

// Create a root node on an empty table
$rootId = $manipulate->createRootNode();

// Create a node
$node1 = $manipulate->insert($rootId, ['column1' => 'some data', 'column2' => 'some more data']);

// Create another node that is child/leaf of first node
$node2 = $manipulate->insert($node, ['column1' => 'child data', 'column2' => 'some more child data']);

// Move node2 so it is on same level as node1
$manipulate->moveAfter($node2, $node1);
// Or we could have moved it in front of node1
$manipulate->moveBefore($node2, $node1);

// Move node2 back to its original position (as child of node1)
$manipulate->moveMakeChild($node2, $root1);

// Delete a node (and all its children, if any)
$manipulate->delete($node);

// You can also empty a node by delete all of its descendants
// or enter a node identifier as second parameter to move descendants to a new location
$manipulate->clean($parentNode, $destinationNode);
```

Manipulation methods, excluding `insert`, can also accept array of node identifiers as their first argument, meaning you can `move`, `delete` and `clean` multiple nodes with just one call.

Example:

```
$manipulate->moveBefore([5,6,26,88], 33);
```

[HybridManipulate](src/HybridManipulate.php) class has extra method named `reorder`. It allows you to move a node within its parent by using order column value as destination instead of node identifier.

Retrieving records
------------------

[](#retrieving-records)

[HybridFind](src/HybridFind.php) and [Find](src/Find.php) classes contain methods for retrieving records and their names pretty much explain what they do. All you need is to provide them with node identifier (*$id* argument), all other arguments are options. For arguments list please refer to each function source;

```
// Create instance of Find class
$find = new Find($config);

$find->findAncestors();
$find->findParent();
$find->findDescendants();
$find->findChildren();
$find->findFirstChild();
$find->findLastChild();
$find->findSiblings();
$find->findNextSibling();
$find->findPreviousSibling();
```

Each of these methods have an (almost) equal get\*Query method (for example `getFindAncestorsQuery`) which returns [Select](https://github.com/zendframework/zend-db/blob/master/src/Sql/Select.php) object instead of [ResultInterface](https://github.com/zendframework/zend-db/blob/master/src/Adapter/Driver/ResultInterface.php). Unlike find methods these methods do not take identifier as argument but instead define an *:id* placeholder. For usage example simply look at one of find\* methods.

**Important note:** Unlike *$columns* or *$where* arguments, when using *$order* argument you must match column names with table `t` (`t` is an alias for table you are querying), for example:

```
$where = new Where();
$where->equalTo('column3', 'some_value');

$find->findChildren(3, ['alias' => 'column1', 'column2'], 't.column4 ASC', $where);
```

Factory
-------

[](#factory)

Factory encapsulates find and manipulate classes of `NestedSet` and `HybridNestedSet` in one class.

```
// Get factory from config object
$factory = $config->getFactory();

// Manually create factory
$factory = new Factory($config);

// Usage examples
$factory->find->findChild();
$factory->manipulate->moveAfter();
$factory->hybridFind->findAncestors();
$factory->hybridManipulate->moveBefore();
...
```

###  Health Score

32

—

LowBetter than 71% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor1

Top contributor holds 86.5% of commits — single point of failure

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.

###  Release Activity

Cadence

Every ~135 days

Recently: every ~448 days

Total

15

Last Release

1395d ago

Major Versions

1.0 → 2.02017-05-27

PHP version history (2 changes)1.0PHP ^5.6 || ^7.0

2.3.4PHP ^5.6 || ^7.0 || ^8

### Community

Maintainers

![](https://www.gravatar.com/avatar/7dcf1e43332d9852a4f1e503ad3bd3f5c09cdce860cc578e777ac0a453e7f006?d=identicon)[aveach.bfr](/maintainers/aveach.bfr)

---

Top Contributors

[![metalinspired](https://avatars.githubusercontent.com/u/18539473?v=4)](https://github.com/metalinspired "metalinspired (45 commits)")[![ajveach](https://avatars.githubusercontent.com/u/1852371?v=4)](https://github.com/ajveach "ajveach (7 commits)")

---

Tags

dbnested-set

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/allegiance-group-nested-set/health.svg)

```
[![Health](https://phpackages.com/badges/allegiance-group-nested-set/health.svg)](https://phpackages.com/packages/allegiance-group-nested-set)
```

###  Alternatives

[robmorgan/phinx

Phinx makes it ridiculously easy to manage the database migrations for your PHP app.

4.5k46.2M401](/packages/robmorgan-phinx)[spatie/laravel-translation-loader

Store your language lines in the database, yaml or other sources

8362.9M51](/packages/spatie-laravel-translation-loader)[aura/sqlquery

Object-oriented query builders for MySQL, Postgres, SQLite, and SQLServer; can be used with any database connection library.

4572.9M34](/packages/aura-sqlquery)[laminas/laminas-db

Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations

13922.5M206](/packages/laminas-laminas-db)[danielme85/laravel-log-to-db

Custom Laravel Log channel handler that can store log events to SQL or MongoDB databases. Uses Laravel native logging functionality.

135934.5k1](/packages/danielme85-laravel-log-to-db)[amphp/postgres

Asynchronous PostgreSQL client for Amp.

110509.8k27](/packages/amphp-postgres)

PHPackages © 2026

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