<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Participation;
use App\Service\CodeDotationService;
use App\Service\ConsolationPrizeService;
use App\Service\WinningTimeService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
final class ParticipationSubscriber implements EventSubscriberInterface
{
public function __construct(
private EntityManagerInterface $manager,
private ValidatorInterface $validator,
private WinningTimeService $drawService,
private ConsolationPrizeService $consolationService,
private CodeDotationService $codeService,
private Security $security
)
{
}
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => [
['checkExists', EventPriorities::PRE_WRITE],
['draw', EventPriorities::POST_WRITE],
['setUser', EventPriorities::PRE_VALIDATE],
],
];
}
public function checkExists(ViewEvent $event)
{
$this->manager
->getConnection()
->prepare('SET SQL_BIG_SELECTS=1')
->executeQuery()
;
// get new participation
$newPart = $event->getControllerResult();
if(!$newPart instanceof Participation) {
return;
}
// check participation exists with external_id
$partRepo = $this->manager->getRepository(Participation::class);
$existingPart = $partRepo
->findOneBy([
"operation" => $newPart->getOperation(),
"externalId" => $newPart->getExternalId()
])
;
// if not exists do nothing
if( !$existingPart instanceof Participation) {
return;
}
// if exists replace new one by existing one
$event->setControllerResult($existingPart);
}
public function draw(ViewEvent $event)
{
$participation = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$participation instanceof Participation || Request::METHOD_POST !== $method) {
return;
}
$violations = $this->validator->validate($participation);
if (0 !== count($violations)) {
throw new ValidationException($violations);
}
//// Fix doublons
$ig = $participation->getIg();
$cp = $participation->getConsolationPrize();
if( $ig || $cp ) {
$code = $participation->getCode();
if(!$code) {
$this->codeService->get($participation);
}
return;
}
/////
// this service flush data in db
$this->drawService->draw($participation);
if ($participation->getOperation()->getConsolation() && $participation->getStatus() === Participation::STATUS_LOST) {
// this service flush data in db
$this->consolationService->draw($participation);
}
$this->codeService->get($participation);
}
public function setUser(ViewEvent $event)
{
$user = $this->security->getUser();
$request = $event->getRequest();
$object = $event->getControllerResult();
$method = $request->getMethod();
if ($method !== Request::METHOD_POST)
{
return;
}
if (!$object instanceof Participation)
{
return;
}
if (!$user instanceof UserInterface) {
throw new AuthenticationException("Token expired");
}
$object->setUser($user);
}
}