diff --git a/src/Entity/TaskDocument.php b/src/Entity/TaskDocument.php index b11364a..905bd9a 100644 --- a/src/Entity/TaskDocument.php +++ b/src/Entity/TaskDocument.php @@ -13,20 +13,21 @@ 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')"), - new Get(security: "is_granted('ROLE_USER')"), + 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')"), + new Delete(security: "is_granted('ROLE_ADMIN') or is_granted('ROLE_CLIENT')"), ], normalizationContext: ['groups' => ['task_document:read']], denormalizationContext: ['groups' => ['task_document:write']], diff --git a/src/State/TaskDocumentProvider.php b/src/State/TaskDocumentProvider.php new file mode 100644 index 0000000..5b24676 --- /dev/null +++ b/src/State/TaskDocumentProvider.php @@ -0,0 +1,81 @@ + + */ +final readonly class TaskDocumentProvider implements ProviderInterface +{ + public function __construct( + private EntityManagerInterface $entityManager, + private Security $security, + ) {} + + public function provide(Operation $operation, array $uriVariables = [], array $context = []): array|TaskDocument|null + { + $user = $this->security->getUser(); + assert($user instanceof User); + + $repo = $this->entityManager->getRepository(TaskDocument::class); + $isClient = $this->security->isGranted('ROLE_CLIENT') && !$this->security->isGranted('ROLE_ADMIN'); + + // Single item + if (isset($uriVariables['id'])) { + $document = $repo->find($uriVariables['id']); + if (null === $document) { + return null; + } + + if ($isClient) { + $ticket = $document->getClientTicket(); + if (null === $ticket || $ticket->getSubmittedBy() !== $user) { + return null; + } + } + + return $document; + } + + // Collection + $qb = $repo->createQueryBuilder('d') + ->orderBy('d.id', 'DESC') + ; + + if ($isClient) { + $qb->innerJoin('d.clientTicket', 'ct') + ->andWhere('ct.submittedBy = :user') + ->setParameter('user', $user) + ; + } + + // Apply filters from query parameters + $filters = $context['filters'] ?? []; + if (isset($filters['task'])) { + $qb->andWhere('d.task = :task') + ->setParameter('task', self::extractId($filters['task'])) + ; + } + if (isset($filters['clientTicket'])) { + $qb->andWhere('d.clientTicket = :clientTicket') + ->setParameter('clientTicket', self::extractId($filters['clientTicket'])) + ; + } + + return $qb->getQuery()->getResult(); + } + + private static function extractId(string $value): int + { + return is_numeric($value) ? (int) $value : (int) basename($value); + } +}