<?php
namespace App\EventSubscriber;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator;
use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\CheckUserInListInterface;
use App\Entity\UserTokenInterface;
use Doctrine\ORM\EntityManagerInterface;
use ReflectionException;
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;
class InjectUserSubscriber implements EventSubscriberInterface
{
/**
* @var Security
*/
private $security;
/**
* @var EntityManagerInterface
*/
private $manager;
public function __construct(Security $security, EntityManagerInterface $manager)
{
$this->security = $security;
$this->manager = $manager;
}
/**
* @return void
*
* @throws ReflectionException
*/
public function setUser(ViewEvent $event)
{
$object = $event->getControllerResult();
if (($object) && (!is_array($object))) {
$reflectionClass = new \ReflectionClass($object);
if ($reflectionClass->implementsInterface(UserTokenInterface::class)) {
if ($event->getRequest()->isMethod(Request::METHOD_POST) && $object->getId() === null) {
$uniqRelation = $object->setUserToken($this->security->getUser());
if ($uniqRelation !== null) {
$parentMethod = 'get'.ucfirst($uniqRelation['parent_name']);
$old_object = $this->manager->getRepository(get_class($object))->findOneBy([
$uniqRelation['property_name'] => $this->security->getUser(),
$uniqRelation['parent_name'] => $object->$parentMethod(),
]);
if ($old_object) {
$this->manager->remove($old_object);
$this->manager->flush();
if (isset($uniqRelation['uniq']) && $uniqRelation['uniq']) {
$event->setResponse(new JsonResponse([
'data' => [],
'message' => 'success',
'code' => 204,
]));
return;
}
}
}
}
if (method_exists($object, 'checkByUserToken')) {
$object->checkByUserToken($this->security->getUser());
}
}
if ($object instanceof Paginator && count($object) > 0) {
foreach ($object as $objet) {
$reflectionClass = new \ReflectionClass($objet);
if (!$reflectionClass->implementsInterface(CheckUserInListInterface::class)) {
return;
}
if (method_exists($objet, 'checkByUserToken')) {
$objet->checkByUserToken($this->security->getUser());
}
}
}
}
}
/**
* @return array<string, mixed>
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['setUser', EventPriorities::PRE_WRITE],
];
}
}