Files
speedBB/api/src/Entity/Forum.php

206 lines
5.1 KiB
PHP

<?php
namespace App\Entity;
use ApiPlatform\Doctrine\Orm\Filter\ExistsFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\State\ForumPositionProcessor;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
//use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Attribute\Groups;
use Symfony\Component\Validator\Constraints as Assert;
#[ORM\Entity]
#[ORM\HasLifecycleCallbacks]
#[ORM\Table(indexes: [
new ORM\Index(name: 'idx_forum_parent_position', columns: ['parent_id', 'position']),
new ORM\Index(name: 'idx_forum_type', columns: ['type']),
])]
#[ApiFilter(SearchFilter::class, properties: ['parent' => 'exact', 'type' => 'exact'])]
#[ApiFilter(ExistsFilter::class, properties: ['parent'])]
#[ApiResource(
operations : [
new Get(),
new GetCollection(),
new Post(security: "is_granted('ROLE_ADMIN')", processor: ForumPositionProcessor::class),
new Patch(security: "is_granted('ROLE_ADMIN')", processor: ForumPositionProcessor::class),
new Delete(security: "is_granted('ROLE_ADMIN')")
],
normalizationContext : ['groups' => ['forum:read']],
denormalizationContext: ['groups' => ['forum:write']],
order : ['position' => 'ASC']
)]
class Forum
{
public const TYPE_CATEGORY = 'category';
public const TYPE_FORUM = 'forum';
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['forum:read', 'thread:read'])]
private ?int $id = null;
#[ORM\Column(length: 100)]
#[Assert\NotBlank]
#[Groups(['forum:read', 'forum:write', 'thread:read'])]
private ?string $name = null;
#[ORM\Column(type: 'text', nullable: true)]
#[Groups(['forum:read', 'forum:write'])]
private ?string $description = null;
#[ORM\Column(length: 20)]
#[Assert\Choice(choices: [self::TYPE_CATEGORY, self::TYPE_FORUM])]
#[Groups(['forum:read', 'forum:write'])]
private string $type = self::TYPE_CATEGORY;
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
#[Assert\Expression(
"this.getParent() === null or this.getParent().isCategory()",
message: "Parent must be a category."
)]
#[Groups(['forum:read', 'forum:write'])]
private ?self $parent = null;
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: self::class)]
#[Groups(['forum:read'])]
private Collection $children;
#[ORM\OneToMany(mappedBy: 'forum', targetEntity: Thread::class)]
#[Groups(['forum:read'])]
private Collection $threads;
#[ORM\Column]
#[Groups(['forum:read'])]
private int $position = 0;
#[ORM\Column]
#[Groups(['forum:read'])]
private ?\DateTimeImmutable $createdAt = null;
#[ORM\Column]
#[Groups(['forum:read'])]
private ?\DateTimeImmutable $updatedAt = null;
public function __construct()
{
$this->children = new ArrayCollection();
$this->threads = new ArrayCollection();
}
#[ORM\PrePersist]
public function onCreate(): void
{
$now = new \DateTimeImmutable();
$this->createdAt = $now;
$this->updatedAt = $now;
}
#[ORM\PreUpdate]
public function onUpdate(): void
{
$this->updatedAt = new \DateTimeImmutable();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
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, Forum>
*/
public function getChildren(): Collection
{
return $this->children;
}
public function getPosition(): int
{
return $this->position;
}
public function setPosition(int $position): self
{
$this->position = $position;
return $this;
}
/**
* @return Collection<int, Thread>
*/
public function getThreads(): Collection
{
return $this->threads;
}
public function isCategory(): bool
{
return $this->type === self::TYPE_CATEGORY;
}
public function isForum(): bool
{
return $this->type === self::TYPE_FORUM;
}
}