bupy7 / doctrine-nested-set
Nested sets for Doctrine ORM
Installs: 1 670
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 4
Forks: 1
Open Issues: 0
Requires
- php: ^7.1 || ^8.0
- doctrine/orm: ^2.6
Requires (Dev)
- doctrine/data-fixtures: ^1.3.3
- friendsofphp/php-cs-fixer: ^2.14.0
- php-coveralls/php-coveralls: ^2.1.0
- phpunit/phpunit: ^7.5.2 || ^9.5.4
README
Library for Doctrine ORM releasing the nested set model tree.
Features
- Multiple roots.
- Fetching all items.
- Fething children items.
- Fething descendant items.
- Fething a parent item.
- Fething root items.
- Fething ancestor items.
- Adding as last of some item.
- Adding as first of some item.
- TODO: Adding after some item.
- TODO: Adding before some item.
- Adding as a first root item.
- Adding as a last root item.
- Removing a item.
- TODO: Moving item after some item.
- TODO: Moving item before some item.
- TODO: Making as root item.
- TODO: Making as a child item of some parent item.
Install
The preferred way to install this extension is through composer.
$ composer require bupy7/doctrine-nested-set "*"
Configuration
Add entity
use Bupy7\Doctrine\NestedSet\NestedSetInterface; /** * @Entity(repositoryClass="CategoryRepository") */ class Category implements NestedSetInterface { /** * @Id * @Column(type="integer") * @GeneratedValue * @var int|null */ private $id; /** * @Column(type="integer", name="root_key") * @var int */ private $rootKey = 1; /** * @Column(type="integer") * @var int */ private $level = 1; /** * @Column(type="integer", name="left_key") * @var int */ private $leftKey; /** * @Column(type="integer", name="right_key") * @var int */ private $rightKey; /** * @Column(type="string") * @var string */ private $name; public function getId(): ?int { return $this->id; } public function setId($id): NestedSetInterface { $this->id = $id; return $this; } public function getRootKey(): int { return $this->rootKey; } public function setRootKey(int $rootKey): NestedSetInterface { $this->rootKey = $rootKey; return $this; } public function getLevel(): int { return $this->level; } public function setLevel(int $level): NestedSetInterface { $this->level = $level; return $this; } public function getLeftKey(): int { return $this->leftKey; } public function setLeftKey(int $leftKey): NestedSetInterface { $this->leftKey = $leftKey; return $this; } public function getRightKey(): int { return $this->rightKey; } public function setRightKey(int $rightKey): NestedSetInterface { $this->rightKey = $rightKey; return $this; } public function getName(): string { return $this->name; } public function setName(string $name): Category { $this->name = $name; return $this; } }
Add repository
use Bupy7\Doctrine\NestedSet\NestedSetRepositoryAbstract; class CategoryRepository extends NestedSetRepositoryAbstract { }
Usage
Tree example:
- PC
- - Motherboards
- - RAM
- - - DDR3
- - - DDR4
- - CPU
- Laptops
- Tablets
Fetching all items
$categories = $categoryRepository->findAll(); // var_dump($categories); // // - PC // - Motherboards // - RAM // - DDR3 // - DDR4 // - CPU // - Laptops // - Tablets
Fething children items
$parentCategory = $categoryRepository->findOneByName('RAM'); $children = $categoryRepository->findChildren($parentCategory); // var_dump($children); // // - DDR3 // - DDR4
Fething descendant items
$parentCategory = $categoryRepository->findOneByName('PC'); $descendants = $categoryRepository->findDescendants($parentCategory); // var_dump($children); // // - Motherboards // - RAM // - DDR3 // - DDR4 // - CPU
Fething a parent item
$childrenCategory = $categoryRepository->findOneByName('RAM'); $parent = $categoryRepository->findOneParent($childrenCategory); // var_dump($parent); // // - PC
Fething root items
$roots = $categoryRepository->findRoots(); // var_dump($parent); // // - PC // - Laptops // - Tablets
Fething ancestor items
$childrenCategory = $categoryRepository->findOneByName('DDR3'); $roots = $categoryRepository->findAncestors($childrenCategory); // var_dump($parent); // // - RAM // - PC
Adding as first of some item
$category = new Category(); $category->setName('DDR2'); $parentCategory = $categoryRepository->findOneByName('RAM'); $categoryRepository->prepend($category, $parentCategory); $entityManager->clear(); // optional, if you need
Result of tree:
- PC
- - Motherboards
- - RAM
- - - DDR2
- - - DDR3
- - - DDR4
- - CPU
- Laptops
- Tablets
Adding as last of some item
$category = new Category(); $category->setName('LGA 1151v2'); $parentCategory = $categoryRepository->findOneByName('CPU'); $categoryRepository->append($category, $parentCategory); $entityManager->clear(); // optional, if you need
Result of tree:
- PC
- - Motherboards
- - RAM
- - - DDR3
- - - DDR4
- - CPU
- - - LGA 1151v2
- Laptops
- Tablets
Adding as a first root item
$category = new Category(); $category->setName('Phones'); $categoryRepository->prepend($category); $entityManager->clear(); // optional, if you need
Result of tree:
- Phones
- PC
- - Motherboards
- - RAM
- - - DDR3
- - - DDR4
- - CPU
- Laptops
- Tablets
Adding as a last root item
$category = new Category(); $category->setName('Phones'); $categoryRepository->append($category); $entityManager->clear(); // optional, if you need
Result of tree:
- PC
- - Motherboards
- - RAM
- - - DDR3
- - - DDR4
- - CPU
- Laptops
- Tablets
- Phones
Removing a item
$category = $categoryRepository->findOneByName('CPU'); $categoryRepository->remove($category); $entityManager->clear(); // optional, if you need
Result of tree:
- PC
- - Motherboards
- - RAM
- - - DDR3
- - - DDR4
- Laptops
- Tablets
or remove with descendants:
$category = $categoryRepository->findOneByName('PC'); $categoryRepository->remove($category); $entityManager->clear(); // optional, if you need
Result of tree:
- Laptops
- Tablets
You may use transactions when it needs manually
use Doctrine\DBAL\TransactionIsolationLevel; // if you want to change isolation level // $oldIsolationLevel = $entityManager->getConnection()->getTransactionIsolation(); // $entityManager->getConnection()->setTransactionIsolation(TransactionIsolationLevel::SERIALIZABLE); $entityManager->beginTransaction(); try { $category = $categoryRepository->findOneByName('PC'); $categoryRepository->remove($category); $entityManager->commit(); $entityManager->clear(); // optional, if you need } catch (Exception $e) { $entityManager->rollback(); throw $e; } finally { // if you changed isolation level // $entityManager->getConnection()->setTransactionIsolation($oldIsolationLevel); }
License
doctrine-nested-set is released under the BSD 3-Clause License.