stefano-tree

Framework agnostic Nested Set (MPTT) implementation for PHP

Github stars Tracking Chart

Tree

Latest Stable Version
Test Status
Coverage Status
Scrutinizer Code Quality
License
Total Downloads
Monthly Downloads

Donate on PayPal

Nested Set implementation for PHP.

Live demo

Features

  • NestedSet(MPTT - Modified Pre-order Tree Traversal)
  • Support scopes (multiple independent tree in one db table)
  • Rebuild broken tree
  • Tested with MySQL/MariaDB and PostgreSQL but should work with any database vendor which support transaction
  • Supported PDO, Zend Framework 1, Zend Framework 2, Doctrine 2 DBAL. It is easy to implement support for any framework
  • Support nested transaction

Dependencies

  • This library has no external dependencies. Can work with pure PHP.

Installation

Run following command in terminal

composer require stefano/stefano-tree

Create Tree Adapter, key, type, required, default value, note, :-----------------, :----:, :------:, :------------, :----------------------------------------------------, tableName, string, yes, idColumnName, string, yes, leftColumnName, string, no, lft, rightColumnName, string, no, rgt, levelColumnName, string, no, level, parentIdColumnName, string, no, parent_id, sequenceName, string, see note, Required for PostgreSQL, scopeColumnName, string, see note, If empty scope support is disabled, dbSelectBuilder, callable, no, see Join table example below, ```

use \StefanoTree\NestedSet;

$options = array(
'tableName' => 'tree_traversal',
'idColumnName' => 'tree_traversal_id',
// other options
);

$dbAdapter = pure \PDO, Zend1 Db Adapter, Zend2 Db Adapter, Doctrine DBAL Connection or any class which implements StefanoTree\NestedSet\Adapter\AdapterInterface interface

$tree = new NestedSet($options, $dbAdapter);


- You can join table.

$options = array(
'tableName' => 'tree_traversal',
'idColumnName' => 'tree_traversal_id',
'dbSelectBuilder' => function() {
// You can use any "callable" like function or object
// Select must be without where or order part
return 'SELECT tree_traversal.*, m.something, ...'
.' FROM tree_traversal'
.' LEFT JOIN metadata AS m ON tree_traversal.id=m.tree_id';
},
// other options
);

$tree = new NestedSet($options, $dbAdapter);


## API

### Creating nodes

- Create root node

use StefanoTree\Exception\ValidationException;

try {
$data = array(
// values
// id_column_name => uuid
);

// create root node.
$rootNodeId = $tree->createRootNode($data);

// create root node. Second param "$scope" is required only if scope support is enabled.
$rootNodeId = $tree->createRootNode($data, $scope);    

} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


- Create new node. You can create new node at 4 different locations.

![placements](./doc/placements.png)

use StefanoTree\Exception\ValidationException;

try {
$targetNodeId = 10;

$data = array(
    // values
    // id_column_name => uuid 
);

$nodeId = $tree->addNodePlacementTop($targetNodeId, $data, $tree::PLACEMENT_CHILD_TOP);
$nodeId = $tree->addNodePlacementChildBottom($targetNodeId, $data, $tree::PLACEMENT_CHILD_BOTTOM);
$nodeId = $tree->addNodePlacementTop($targetNodeId, $data, $tree::PLACEMENT_TOP);
$nodeId = $tree->addNodePlacementBottom($targetNodeId, $data, $tree::PLACEMENT_BOTTOM);

} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


### Update Node

use StefanoTree\Exception\ValidationException;

try {
$targetNodeId = 10;

$data = array(
    // values
);

$tree->updateNode($targetNodeId, $data);

} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


### Move node

- You can move node at 4 different locations.

![placements](./doc/placements.png)

use StefanoTree\Exception\ValidationException;

try {
$sourceNodeId = 15;
$targetNodeId = 10;

$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_CHILD_TOP);
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_CHILD_BOTTOM);
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_TOP);
$tree->moveNode($sourceNodeId, $targetNodeId, $tree::PLACEMENT_BOTTOM);

} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


### Delete node or branch

use StefanoTree\Exception\ValidationException;

try {
$nodeId = 15;

$tree->deleteBranch($nodeId);

} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


### Getting nodes

- Get descendants

$nodeId = 15;

// all descendants
$tree->getDescendantsQueryBuilder()
->get($nodeId);

// all descendants result as nested array
$tree->getDescendantsQueryBuilder()
->get($nodeId, true);

// only children
$tree->getDescendantsQueryBuilder()
->excludeFirstNLevel(1)
->levelLimit(1)
->get($nodeId);

// exclude first level($nodeId) from result
$tree->getDescendants()
->excludeFirstNLevel(1)
->get($nodeId);

// exclude first two levels from result
$tree->getDescendantsQueryBuilder()
->excludeFirstNLevel(2)
->get($nodeId);

// return first 4 level
$tree->getDescendantsQueryBuilder()
->levelLimit(4)
->get($nodeId);

// exclude branch from result
$tree->getDescendantsQueryBuilder()
->excludeBranch(22)
->get($nodeId);


- Get Ancestors

$nodeId = 15;

// get all
$tree->getAncestorsQueryBuilder()
->get($nodeId);

// get all as nested array
$tree->getAncestorsQueryBuilder()
->get($nodeId, true);

// exclude last node($nodeId) from result
$tree->getAncestorsQueryBuilder()
->excludeLastNLevel(1)
->get($nodeId);

// exclude first two levels from result
$tree->getAncestorsQueryBuilder()
->excludeFirstNLevel(2)
->get($nodeId);


### Validation and Rebuild broken tree

- Check if tree is valid

use StefanoTree\Exception\ValidationException;

try {
$satus = $tree->isValid($rootNodeId);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


- Rebuild broken tree

use StefanoTree\Exception\ValidationException;

try {
$tree->rebuild($rootNodeId);
} catch (ValidationException $e) {
$errorMessage = $e->getMessage();
}


## Contributing

Any contributions are welcome. If you find any issue don't hesitate to open a new issue or send a pull request.

Overview

Name With Ownercepa/webthumbnail
Primary LanguagePHP
Program languagePHP (Language Count: 1)
Platform
License:
Release Count4
Last Release Namewebthumbnail-2.1 (Posted on 2012-11-25 13:08:50)
First Release Namewebthumbnail-1.0.0 (Posted on 2012-05-06 11:46:23)
Created At2012-04-20 15:50:11
Pushed At2018-02-24 18:36:47
Last Commit At2018-02-24 19:36:43
Stargazers Count49
Watchers Count6
Fork Count11
Commits Count15
Has Issues Enabled
Issues Count8
Issue Open Count6
Pull Requests Count0
Pull Requests Open Count0
Pull Requests Close Count0
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private
To the top