feat : generalize TaskDocumentProcessor for client tickets
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
||||
new GetCollection(paginationEnabled: false, security: "is_granted('ROLE_USER')"),
|
||||
new Get(security: "is_granted('ROLE_USER')"),
|
||||
new Post(
|
||||
security: "is_granted('ROLE_ADMIN')",
|
||||
security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_CLIENT')",
|
||||
processor: TaskDocumentProcessor::class,
|
||||
deserialize: false,
|
||||
),
|
||||
|
||||
@@ -6,12 +6,14 @@ namespace App\State;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use App\Entity\ClientTicket;
|
||||
use App\Entity\Task;
|
||||
use App\Entity\TaskDocument;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
@@ -50,18 +52,41 @@ final readonly class TaskDocumentProcessor implements ProcessorInterface
|
||||
throw new BadRequestHttpException('File size exceeds 50 MB limit.');
|
||||
}
|
||||
|
||||
$taskIri = $request->request->get('task');
|
||||
$taskIri = $request->request->get('task');
|
||||
$clientTicketIri = $request->request->get('clientTicket');
|
||||
|
||||
if (null === $taskIri || '' === $taskIri) {
|
||||
throw new BadRequestHttpException('Task IRI is required.');
|
||||
if ((null === $taskIri || '' === $taskIri) && (null === $clientTicketIri || '' === $clientTicketIri)) {
|
||||
throw new BadRequestHttpException('Either task or clientTicket IRI is required.');
|
||||
}
|
||||
|
||||
// Extract task ID from IRI (e.g., "/api/tasks/42" -> 42)
|
||||
$taskId = (int) basename((string) $taskIri);
|
||||
$task = $this->entityManager->getRepository(Task::class)->find($taskId);
|
||||
$task = null;
|
||||
$clientTicket = null;
|
||||
|
||||
if (null === $task) {
|
||||
throw new BadRequestHttpException('Task not found.');
|
||||
if (null !== $taskIri && '' !== $taskIri) {
|
||||
// Extract task ID from IRI (e.g., "/api/tasks/42" -> 42)
|
||||
$taskId = (int) basename((string) $taskIri);
|
||||
$task = $this->entityManager->getRepository(Task::class)->find($taskId);
|
||||
|
||||
if (null === $task) {
|
||||
throw new BadRequestHttpException('Task not found.');
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $clientTicketIri && '' !== $clientTicketIri) {
|
||||
$clientTicketId = (int) basename((string) $clientTicketIri);
|
||||
$clientTicket = $this->entityManager->getRepository(ClientTicket::class)->find($clientTicketId);
|
||||
|
||||
if (null === $clientTicket) {
|
||||
throw new BadRequestHttpException('Client ticket not found.');
|
||||
}
|
||||
|
||||
// Ownership validation for ROLE_CLIENT
|
||||
if (!$this->security->isGranted('ROLE_ADMIN')) {
|
||||
$currentUser = $this->security->getUser();
|
||||
if ($clientTicket->getSubmittedBy() !== $currentUser) {
|
||||
throw new AccessDeniedHttpException('You can only upload documents to your own tickets.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Capture file metadata BEFORE move() — move invalidates the temp file
|
||||
@@ -80,6 +105,7 @@ final readonly class TaskDocumentProcessor implements ProcessorInterface
|
||||
|
||||
$document = new TaskDocument();
|
||||
$document->setTask($task);
|
||||
$document->setClientTicket($clientTicket);
|
||||
$document->setOriginalName($originalName);
|
||||
$document->setFileName($fileName);
|
||||
$document->setMimeType($mimeType);
|
||||
|
||||
Reference in New Issue
Block a user