Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tree] Include name "tree" in naming #475

Merged
merged 1 commit into from
Dec 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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