Library for Doctrine ORM releasing the nested set model tree.
- 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.
The preferred way to install this extension is through composer.
$ composer require bupy7/doctrine-nested-set "*"
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;
}
}
use Bupy7\Doctrine\NestedSet\NestedSetRepositoryAbstract;
class CategoryRepository extends NestedSetRepositoryAbstract
{
}
Tree example:
- PC
- - Motherboards
- - RAM
- - - DDR3
- - - DDR4
- - CPU
- Laptops
- Tablets
$categories = $categoryRepository->findAll();
// var_dump($categories);
//
// - PC
// - Motherboards
// - RAM
// - DDR3
// - DDR4
// - CPU
// - Laptops
// - Tablets
$parentCategory = $categoryRepository->findOneByName('RAM');
$children = $categoryRepository->findChildren($parentCategory);
// var_dump($children);
//
// - DDR3
// - DDR4
$parentCategory = $categoryRepository->findOneByName('PC');
$descendants = $categoryRepository->findDescendants($parentCategory);
// var_dump($children);
//
// - Motherboards
// - RAM
// - DDR3
// - DDR4
// - CPU
$childrenCategory = $categoryRepository->findOneByName('RAM');
$parent = $categoryRepository->findOneParent($childrenCategory);
// var_dump($parent);
//
// - PC
$roots = $categoryRepository->findRoots();
// var_dump($parent);
//
// - PC
// - Laptops
// - Tablets
$childrenCategory = $categoryRepository->findOneByName('DDR3');
$roots = $categoryRepository->findAncestors($childrenCategory);
// var_dump($parent);
//
// - RAM
// - PC
$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
$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
$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
$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
$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
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);
}
doctrine-nested-set is released under the BSD 3-Clause License.