Skip to content

Commit

Permalink
prefix Node with Tree, to make it explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Dec 25, 2019
1 parent 55fb8a6 commit c34b9ae
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 83 deletions.
16 changes: 11 additions & 5 deletions docs/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,25 @@ declare(strict_types=1);
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Model\Tree\NodeInterface;
use Knp\DoctrineBehaviors\Model\Tree\NodeTrait;
use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface;
use Knp\DoctrineBehaviors\Model\Tree\TreeNodeTrait;

/**
* @ORM\Entity
*/
class Category implements NodeInterface
class Category implements TreeNodeInterface
{
use NodeTrait;
use TreeNodeTrait;

/**
* @ORM\Column(type="string")
* @var string
*/
private $name;

public function __toString() : string
{
return $this->...;
return (string) $this->name;
}
}
```
Expand Down
4 changes: 2 additions & 2 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ parameters:
- '#Property Knp\\DoctrineBehaviors\\Tests\\Fixtures\\Entity\\GeocodableEntity\:\:\$location has no typehint specified#'

# tests
- '#Offset 0 does not exist on array<Knp\\DoctrineBehaviors\\Contract\\Model\\Tree\\NodeInterface\>\|ArrayAccess\|null#'
- '#Offset 0 does not exist on array<Knp\\DoctrineBehaviors\\Contract\\Entity\\TreeNodeInterface\>\|ArrayAccess\|null#'

- '#Cannot call method addChildNode\(\) on Knp\\DoctrineBehaviors\\Contract\\Model\\Tree\\NodeInterface\|null#'
- '#Cannot call method addChildNode\(\) on Knp\\DoctrineBehaviors\\Contract\\Entity\\TreeNodeInterface\|null#'

# iterable
- '#Parameter \#1 \$translations of method Knp\\DoctrineBehaviors\\Tests\\Fixtures\\Entity\\TranslatableEntity\:\:setTranslations\(\) expects Doctrine\\Common\\Collections\\Collection&iterable<Knp\\DoctrineBehaviors\\Contract\\Entity\\TranslationInterface\>, array<int, Knp\\DoctrineBehaviors\\Contract\\Entity\\TranslationInterface\> given#'
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

declare(strict_types=1);

namespace Knp\DoctrineBehaviors\Contract\Model\Tree;
namespace Knp\DoctrineBehaviors\Contract\Entity;

use Doctrine\Common\Collections\Collection;

/**
* Tree\Node defines a set of needed methods
* to work with materialized path tree nodes
*/
interface NodeInterface
interface TreeNodeInterface
{
public function __toString(): string;

Expand Down
4 changes: 2 additions & 2 deletions src/EventSubscriber/TreeSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Knp\DoctrineBehaviors\Contract\Model\Tree\NodeInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface;

final class TreeSubscriber implements EventSubscriber
{
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();

if (! is_a($classMetadata->reflClass->getName(), NodeInterface::class, true)) {
if (! is_a($classMetadata->reflClass->getName(), TreeNodeInterface::class, true)) {
return;
}

Expand Down
11 changes: 0 additions & 11 deletions src/Model/Tree/NodeTrait.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
use Closure;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Knp\DoctrineBehaviors\Contract\Model\Tree\NodeInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface;
use LogicException;
use Nette\Utils\Json;

trait NodeMethodsTrait
trait TreeNodeMethodsTrait
{
/**
* @return string|int|null
Expand Down Expand Up @@ -78,7 +78,7 @@ public function isLeafNode(): bool
}

/**
* @return Collection|NodeInterface[]
* @return Collection|TreeNodeInterface[]
*/
public function getChildNodes(): Collection
{
Expand All @@ -90,62 +90,62 @@ public function getChildNodes(): Collection
return $this->childNodes;
}

public function addChildNode(NodeInterface $node): void
public function addChildNode(TreeNodeInterface $treeNode): void
{
$this->getChildNodes()->add($node);
$this->getChildNodes()->add($treeNode);
}

public function isIndirectChildNodeOf(NodeInterface $node): bool
public function isIndirectChildNodeOf(TreeNodeInterface $treeNode): bool
{
return $this->getRealMaterializedPath() !== $node->getRealMaterializedPath()
&& strpos($this->getRealMaterializedPath(), $node->getRealMaterializedPath()) === 0;
return $this->getRealMaterializedPath() !== $treeNode->getRealMaterializedPath()
&& strpos($this->getRealMaterializedPath(), $treeNode->getRealMaterializedPath()) === 0;
}

public function isChildNodeOf(NodeInterface $node): bool
public function isChildNodeOf(TreeNodeInterface $treeNode): bool
{
return $this->getParentMaterializedPath() === $node->getRealMaterializedPath();
return $this->getParentMaterializedPath() === $treeNode->getRealMaterializedPath();
}

public function setChildNodeOf(?NodeInterface $node = null): void
public function setChildNodeOf(?TreeNodeInterface $treeNode = null): void
{
$id = $this->getNodeId();
if (empty($id)) {
throw new LogicException('You must provide an id for this node if you want it to be part of a tree.');
}

$path = $node !== null
? rtrim($node->getRealMaterializedPath(), static::getMaterializedPathSeparator())
$path = $treeNode !== null
? rtrim($treeNode->getRealMaterializedPath(), static::getMaterializedPathSeparator())
: static::getMaterializedPathSeparator();
$this->setMaterializedPath($path);

if ($this->parentNode !== null) {
$this->parentNode->getChildNodes()->removeElement($this);
}

$this->parentNode = $node;
$this->parentNode = $treeNode;

if ($node !== null) {
if ($treeNode !== null) {
$this->parentNode->addChildNode($this);
}

foreach ($this->getChildNodes() as $child) {
/** @var NodeInterface $this */
/** @var TreeNodeInterface $this */
$child->setChildNodeOf($this);
}
}

public function getParentNode(): ?NodeInterface
public function getParentNode(): ?TreeNodeInterface
{
return $this->parentNode;
}

public function setParentNode(NodeInterface $node): void
public function setParentNode(TreeNodeInterface $treeNode): void
{
$this->parentNode = $node;
$this->parentNode = $treeNode;
$this->setChildNodeOf($this->parentNode);
}

public function getRootNode(): NodeInterface
public function getRootNode(): TreeNodeInterface
{
$parent = $this;
while ($parent->getParentNode() !== null) {
Expand Down Expand Up @@ -182,14 +182,14 @@ public function toJson(?Closure $prepare = null): string
public function toArray(?Closure $prepare = null, ?array &$tree = null): array
{
if ($prepare === null) {
$prepare = function (NodeInterface $node) {
$prepare = function (TreeNodeInterface $node) {
return (string) $node;
};
}
if ($tree === null) {
$tree = [
$this->getNodeId() => [
/** @var NodeInterface $this */
/** @var TreeNodeInterface $this */
'node' => $prepare($this),
'children' => [],
],
Expand All @@ -215,7 +215,7 @@ public function toArray(?Closure $prepare = null, ?array &$tree = null): array
public function toFlatArray(?Closure $prepare = null, ?array &$tree = null): array
{
if ($prepare === null) {
$prepare = function (NodeInterface $node) {
$prepare = function (TreeNodeInterface $node) {
$pre = $node->getNodeLevel() > 1 ? implode('', array_fill(0, $node->getNodeLevel(), '--')) : '';

return $pre . $node;
Expand All @@ -235,11 +235,11 @@ public function toFlatArray(?Closure $prepare = null, ?array &$tree = null): arr
}

/**
* @param NodeInterface $node
* @param TreeNodeInterface $node
*/
public function offsetSet($offset, $node): void
{
/** @var NodeInterface $this */
/** @var TreeNodeInterface $this */
$node->setChildNodeOf($this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
namespace Knp\DoctrineBehaviors\Model\Tree;

use Doctrine\Common\Collections\Collection;
use Knp\DoctrineBehaviors\Contract\Model\Tree\NodeInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface;

trait NodePropertiesTrait
trait TreeNodePropertiesTrait
{
/**
* @var string
*/
protected $materializedPath = '';

/**
* @var Collection|NodeInterface[]
* @var Collection|TreeNodeInterface[]
*/
private $childNodes;

/**
* @var NodeInterface|null
* @var TreeNodeInterface|null
*/
private $parentNode;
}
11 changes: 11 additions & 0 deletions src/Model/Tree/TreeNodeTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Knp\DoctrineBehaviors\Model\Tree;

trait TreeNodeTrait
{
use TreeNodeMethodsTrait;
use TreeNodePropertiesTrait;
}
12 changes: 6 additions & 6 deletions src/ORM/Tree/TreeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use ArrayAccess;
use Doctrine\ORM\QueryBuilder;
use Knp\DoctrineBehaviors\Contract\Model\Tree\NodeInterface;
use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface;

trait TreeTrait
{
Expand All @@ -30,7 +30,7 @@ public function getRootNodes(string $rootAlias = 't'): array
/**
* Returns a node hydrated with its children and parents
*
* @return NodeInterface[]|ArrayAccess|null
* @return TreeNodeInterface[]|ArrayAccess|null
*/
public function getTree(string $path = '', string $rootAlias = 't', array $extraParams = [])
{
Expand All @@ -39,18 +39,18 @@ public function getTree(string $path = '', string $rootAlias = 't', array $extra
return $this->buildTree($results);
}

public function getTreeExceptNodeAndItsChildrenQB(NodeInterface $node, string $rootAlias = 't')
public function getTreeExceptNodeAndItsChildrenQB(TreeNodeInterface $treeNode, string $rootAlias = 't')
{
return $this->getFlatTreeQB('', $rootAlias)
->andWhere($rootAlias . '.materializedPath NOT LIKE :except_path')
->andWhere($rootAlias . '.id != :id')
->setParameter('except_path', $node->getRealMaterializedPath() . '%')
->setParameter('id', $node->getId());
->setParameter('except_path', $treeNode->getRealMaterializedPath() . '%')
->setParameter('id', $treeNode->getId());
}

/**
* Extracts the root node and constructs a tree using flat resultset
* @return ArrayAccess|NodeInterface[]|null
* @return ArrayAccess|TreeNodeInterface[]|null
*/
public function buildTree(array $results)
{
Expand Down
24 changes: 6 additions & 18 deletions tests/Fixtures/Entity/TreeNodeEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,30 @@
namespace Knp\DoctrineBehaviors\Tests\Fixtures\Entity;

use ArrayAccess;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Model\Tree\NodeInterface;
use Knp\DoctrineBehaviors\Model\Tree\NodeTrait;
use Knp\DoctrineBehaviors\Contract\Entity\TreeNodeInterface;
use Knp\DoctrineBehaviors\Model\Tree\TreeNodeTrait;

/**
* @ORM\Entity(repositoryClass="Knp\DoctrineBehaviors\Tests\Fixtures\Repository\TreeNodeRepository")
*/
class TreeNodeEntity implements NodeInterface, ArrayAccess
class TreeNodeEntity implements TreeNodeInterface, ArrayAccess
{
use NodeTrait;

/**
* @var string
*/
public const PATH_SEPARATOR = '/';
use TreeNodeTrait;

/**
* @ORM\Column(type="string", length=255, nullable=true)
* @var string
*/
protected $name;
private $name;

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="NONE")
* @var int|null
*/
protected $id;

public function __construct(?int $id = null)
{
$this->id = $id;
$this->childNodes = new ArrayCollection();
}
private $id;

public function __toString(): string
{
Expand Down
Loading

0 comments on commit c34b9ae

Please sign in to comment.