<?php 
 
namespace App\Entity; 
 
use App\Controller\Action\ListDomainsWithStatusReportController; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use ApiPlatform\Metadata\ApiResource; 
use Symfony\Component\Serializer\Annotation\Groups; 
 
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; 
use ApiPlatform\Metadata\ApiFilter; 
use ApiPlatform\Metadata\Delete; 
use ApiPlatform\Metadata\Get; 
use ApiPlatform\Metadata\GetCollection; 
use ApiPlatform\Metadata\Post; 
use ApiPlatform\Metadata\Put; 
use App\Controller\Action\CategoryTreeAction; 
use App\Controller\Action\CategoryTreeFilterAction; 
 
#[ORM\Table(name: 'category')] 
#[ORM\Index(name: 'parent_id', columns: ['parent_id'])] 
#[ORM\Entity] 
#[ApiResource( 
    operations: [ 
        new GetCollection(), 
        new Get( 
            name: '_api_/categories/tree', 
            uriTemplate: '/categories/tree', 
            controller: CategoryTreeAction::class, 
            write: false, 
            read: false 
        ),  new Get( 
            name: '_api_/categories/tree/filter', 
            uriTemplate: '/categories/tree/filter', 
            controller: CategoryTreeFilterAction::class, 
            write: false, 
            read: false 
        ), 
        new Post(), 
        new Get(), 
        new Put(), 
        new Delete(), 
        new Post( 
            uriTemplate: '/domains_with_status', 
            controller: ListDomainsWithStatusReportController::class, 
            read: false, 
            write: false, 
            name: '_api_/domains_with_status' 
        ), 
    ], 
    normalizationContext: ['groups' => ['category.get', 'document.get']] 
) 
] 
#[ApiFilter( 
    SearchFilter::class, 
    properties: [ 
        'type' => 'exact' 
    ] 
)] 
class Category 
{ 
    //@maybe this should be converted to the new php8 enum supported feature 
    const THEME_TYPE = 'THEME'; 
    const DOMAIN_TYPE = 'DOMAIN'; 
    const SUB_DOMAIN_TYPE = 'SUB_DOMAIN'; 
 
    #[ORM\Column(name: 'id', type: 'integer', nullable: false)] 
    #[ORM\Id] 
    #[ORM\GeneratedValue(strategy: 'IDENTITY')] 
    #[Groups(['category.get', 'document.get', 'plan.get'])] 
    private int $id; 
 
    #[ORM\Column(name: 'type', type: 'string', length: 10, nullable: true)] 
    #[Groups('category.get', 'document.get', 'plan.get')] 
    private ?string $type = null; 
 
    #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'categories')] 
    #[Groups([ 'document.get'])] 
    private ?self $parent = null; 
 
    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: self::class)] 
 
    #[Groups('category.get')] 
    private Collection $categories; 
 
    #[ORM\Column(length: 255)] 
    #[Groups(['category.get', 'document.get', 'plan.get'])] 
    private ?string $name = null; 
 
    public function __construct() 
    { 
        $this->categories = new ArrayCollection(); 
    } 
 
    public function getId(): ?int 
    { 
        return $this->id; 
    } 
 
    public function getType(): ?string 
    { 
        return $this->type; 
    } 
 
    public function setType(?string $type): self 
    { 
        $this->type = $type; 
 
        return $this; 
    } 
 
    public function getParent(): ?self 
    { 
        return $this->parent; 
    } 
 
    public function setParent(?self $parent): self 
    { 
        $this->parent = $parent; 
 
        return $this; 
    } 
 
    /** 
     * @return Collection<int, self> 
     */ 
    public function getCategories(): Collection 
    { 
        return $this->categories; 
    } 
 
    public function addCategory(self $category): self 
    { 
        if (!$this->categories->contains($category)) { 
            $this->categories->add($category); 
            $category->setParent($this); 
        } 
 
        return $this; 
    } 
 
    public function removeCategory(self $category): self 
    { 
        if ($this->categories->removeElement($category)) { 
            // set the owning side to null (unless already changed) 
            if ($category->getParent() === $this) { 
                $category->setParent(null); 
            } 
        } 
 
        return $this; 
    } 
 
    public function getName(): ?string 
    { 
        return $this->name; 
    } 
 
    public function setName(string $name): self 
    { 
        $this->name = $name; 
 
        return $this; 
    } 
}