<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Reservation;
use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
final class EntitySubscriber implements EventSubscriberInterface
{
public function __construct(
protected Security $security
) {}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => [
['checkLimit', EventPriorities::PRE_WRITE],
['addCreatedBy', EventPriorities::PRE_WRITE],
],
];
}
public function addCreatedBy(ViewEvent $httpEvent): void
{
$entity = $httpEvent->getControllerResult();
$method = $httpEvent->getRequest()->getMethod();
if (Request::METHOD_POST !== $method) {
return;
}
$user = $this->security->getUser();
if (!$user || !property_exists($entity, 'createdBy')) {
return;
}
$rp = new \ReflectionProperty($entity, 'createdBy');
$type = $rp->getType()->getName();
if ($type === User::class) {
$entity->createdBy = $user;
}
}
public function checkLimit(ViewEvent $httpEvent): void
{
$reservation = $httpEvent->getControllerResult();
$method = $httpEvent->getRequest()->getMethod();
if (!$reservation instanceof Reservation || Request::METHOD_POST !== $method) {
return;
}
$event = $reservation->event;
$seatLimit = $event->seatLimit;
if (!$seatLimit) {
return;
}
$count = $event->reservations->count();
if ($count >= $seatLimit) {
$httpEvent->setResponse(new JsonResponse(['message' => "Event's seat limit exceeded"], 400));
}
}
}