<?php
declare(strict_types=1);
namespace App\Shop\Doctrine\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Shop\Doctrine\Repository\TaxonomyRepository;
use App\Shop\Filter\TaxonomyFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\Table;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* @Gedmo\Tree(type="nested")
*/
#[ApiResource(
collectionOperations: ['get'],
itemOperations: ['get'],
attributes: ['pagination_enabled' => false],
normalizationContext: ['groups' => ['read']]
)]
#[ApiFilter(TaxonomyFilter::class)]
#[Entity(repositoryClass: TaxonomyRepository::class)]
#[Table(name: '`shop_taxonomy`')]
class Taxonomy
{
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
#[Groups(['read', 'product'])]
private ?int $id = null;
#[Column]
#[NotBlank]
#[Groups(['read', 'product'])]
private string $name;
/**
* @Gedmo\TreeLevel
*/
#[Column(name: 'lvl', type: 'integer')]
#[Groups('read')]
private int $level;
/**
* @Gedmo\TreeLeft
*/
#[Column(name: 'lft', type: 'integer')]
private int $left;
/**
* @Gedmo\TreeRight
*/
#[Column(name: 'rgt', type: 'integer')]
private int $right;
#[Groups('read')]
private int $numberOfProducts = 0;
/**
* @Gedmo\TreeParent
*/
#[ManyToOne(targetEntity: Taxonomy::class, inversedBy: 'children')]
private ?Taxonomy $parent = null;
/**
* @var Collection<int, Taxonomy>
*/
#[OneToMany(mappedBy: 'parent', targetEntity: Taxonomy::class)]
#[Groups('read')]
private Collection $children;
/**
* @var Collection<int, Product>
*/
#[OneToMany(mappedBy: 'taxonomy', targetEntity: Product::class, fetch: 'EXTRA_LAZY')]
private Collection $products;
public function __construct()
{
$this->children = new ArrayCollection();
$this->products = new ArrayCollection();
}
public function __toString(): string
{
return $this->getName();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getLevel(): int
{
return $this->level;
}
public function setLevel(int $level): void
{
$this->level = $level;
}
public function getLeft(): int
{
return $this->left;
}
public function setLeft(int $left): void
{
$this->left = $left;
}
public function getRight(): int
{
return $this->right;
}
public function setRight(int $right): void
{
$this->right = $right;
}
public function getParent(): ?Taxonomy
{
return $this->parent;
}
public function setParent(?Taxonomy $parent): void
{
$this->parent = $parent;
}
/**
* @return Collection<int, Taxonomy>
*/
public function getChildren(): Collection
{
return $this->children;
}
/**
* @return Collection<int, Product>
*/
public function getProducts(): Collection
{
return $this->products;
}
/**
* @return array<int|string, array<string, int|string|null>|int|string>
*/
public function getTree(): array
{
$data = [
'key' => $this->id,
'name' => $this->name,
'rootdistance' => $this->level,
'children' => $this->children->count(),
];
if (null !== $this->parent) {
$data['parent'] = $this->parent->id;
}
return array_merge(
[$data],
...$this->children->map(static fn (Taxonomy $taxonomy) => $taxonomy->getTree())->toArray()
);
}
public function getNumberOfProducts(): int
{
return $this->numberOfProducts;
}
public function setNumberOfProducts(int $numberOfProducts): void
{
$this->numberOfProducts = $numberOfProducts;
}
}