Files
Lesstime/src/Entity/TaskDocument.php
Matthieu 1d533d1d28 fix : allow ROLE_CLIENT to upload and view documents on client tickets
GetCollection/Get required ROLE_USER which ROLE_CLIENT doesn't have.
Added TaskDocumentProvider to scope client access to their own tickets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 14:17:48 +01:00

183 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Entity;
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\Post;
use App\EventListener\TaskDocumentListener;
use App\State\TaskDocumentProcessor;
use App\State\TaskDocumentProvider;
use DateTimeImmutable;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new GetCollection(paginationEnabled: false, security: "is_granted('ROLE_USER') or is_granted('ROLE_CLIENT')", provider: TaskDocumentProvider::class),
new Get(security: "is_granted('ROLE_USER') or is_granted('ROLE_CLIENT')", provider: TaskDocumentProvider::class),
new Post(
security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_CLIENT')",
processor: TaskDocumentProcessor::class,
deserialize: false,
),
new Delete(security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_CLIENT')"),
],
normalizationContext: ['groups' => ['task_document:read']],
denormalizationContext: ['groups' => ['task_document:write']],
order: ['id' => 'DESC'],
)]
#[ApiFilter(SearchFilter::class, properties: ['task' => 'exact'])]
#[ORM\Entity]
#[ORM\EntityListeners([TaskDocumentListener::class])]
class TaskDocument
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?int $id = null;
#[ORM\ManyToOne(targetEntity: Task::class, inversedBy: 'documents')]
#[ORM\JoinColumn(nullable: true, onDelete: 'CASCADE')]
#[Groups(['task_document:read', 'task_document:write'])]
private ?Task $task = null;
#[ORM\ManyToOne(targetEntity: ClientTicket::class, inversedBy: 'documents')]
#[ORM\JoinColumn(nullable: true, onDelete: 'CASCADE')]
#[Groups(['task_document:read', 'task_document:write'])]
private ?ClientTicket $clientTicket = null;
#[ORM\Column(length: 255)]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?string $originalName = null;
#[ORM\Column(length: 255)]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?string $fileName = null;
#[ORM\Column(length: 100)]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?string $mimeType = null;
#[ORM\Column]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?int $size = null;
#[ORM\Column(type: 'datetime_immutable')]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?DateTimeImmutable $createdAt = null;
#[ORM\ManyToOne(targetEntity: User::class)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
#[Groups(['task_document:read', 'task:read', 'client_ticket:read'])]
private ?User $uploadedBy = null;
public function getId(): ?int
{
return $this->id;
}
public function getTask(): ?Task
{
return $this->task;
}
public function setTask(?Task $task): static
{
$this->task = $task;
return $this;
}
public function getOriginalName(): ?string
{
return $this->originalName;
}
public function setOriginalName(string $originalName): static
{
$this->originalName = $originalName;
return $this;
}
public function getFileName(): ?string
{
return $this->fileName;
}
public function setFileName(string $fileName): static
{
$this->fileName = $fileName;
return $this;
}
public function getMimeType(): ?string
{
return $this->mimeType;
}
public function setMimeType(string $mimeType): static
{
$this->mimeType = $mimeType;
return $this;
}
public function getSize(): ?int
{
return $this->size;
}
public function setSize(int $size): static
{
$this->size = $size;
return $this;
}
public function getCreatedAt(): ?DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(DateTimeImmutable $createdAt): static
{
$this->createdAt = $createdAt;
return $this;
}
public function getUploadedBy(): ?User
{
return $this->uploadedBy;
}
public function setUploadedBy(?User $uploadedBy): static
{
$this->uploadedBy = $uploadedBy;
return $this;
}
public function getClientTicket(): ?ClientTicket
{
return $this->clientTicket;
}
public function setClientTicket(?ClientTicket $clientTicket): static
{
$this->clientTicket = $clientTicket;
return $this;
}
}