vendor/drosalys/api-bundle/src/EventSubscriber/ActionResponseSubscriber.php line 62

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the drosalys/api-bundle package.
  4.  *
  5.  * (c) Benjamin Georgeault
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Drosalys\Bundle\ApiBundle\EventSubscriber;
  11. use Drosalys\Bundle\ApiBundle\Action\Action;
  12. use Drosalys\Bundle\ApiBundle\Action\Info\EventInfo;
  13. use Drosalys\Bundle\ApiBundle\Event\AbstractViewEvent;
  14. use Drosalys\Bundle\ApiBundle\Event\PostPersistEvent;
  15. use Drosalys\Bundle\ApiBundle\Event\PostBuildResponseEvent;
  16. use Drosalys\Bundle\ApiBundle\Event\PrePersistEvent;
  17. use Drosalys\Bundle\ApiBundle\Event\PreBuildResponseEvent;
  18. use Drosalys\Bundle\ApiBundle\Event\ReplaceBuildResponseEvent;
  19. use Drosalys\Bundle\ApiBundle\Event\ReplacePersistEvent;
  20. use Drosalys\Bundle\ApiBundle\Persister\PersisterHandler\PersisterHandlerInterface;
  21. use Drosalys\Bundle\ApiBundle\Request\ActionRequestTrait;
  22. use Drosalys\Bundle\ApiBundle\Response\ResponseHandler\ResponseHandlerInterface;
  23. use Drosalys\Bundle\ApiBundle\Routing\Attributes\AbstractRoute;
  24. use Psr\EventDispatcher\EventDispatcherInterface;
  25. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\Event\ViewEvent;
  29. use Symfony\Component\HttpKernel\KernelEvents;
  30. /**
  31.  * Class ActionResponseSubscriber
  32.  *
  33.  * @author Benjamin Georgeault
  34.  */
  35. class ActionResponseSubscriber implements EventSubscriberInterface
  36. {
  37.     use ActionRequestTrait;
  38.     /**
  39.      * ActionResponseSubscriber constructor.
  40.      * @param ResponseHandlerInterface[] $responseHandlers
  41.      * @param PersisterHandlerInterface[] $persisterHandlers
  42.      */
  43.     public function __construct(
  44.         private EventDispatcherInterface $dispatcher,
  45.         private iterable $responseHandlers,
  46.         private iterable $persisterHandlers,
  47.     ) {
  48.     }
  49.     public static function getSubscribedEvents(): array
  50.     {
  51.         return [
  52.             KernelEvents::VIEW => ['__invoke'63],
  53.         ];
  54.     }
  55.     public function __invoke(ViewEvent $event): void
  56.     {
  57.         if (null === $action $this->retrieveActionFromRequest($request $event->getRequest())) {
  58.             return;
  59.         }
  60.         $this->applyPersister($action$request$data $event->getControllerResult());
  61.         if (null !== $response $this->buildResponse($action$request$data)) {
  62.             $event->setResponse($response);
  63.         }
  64.     }
  65.     private function buildResponse(Action $actionRequest $requestmixed $data): ?Response
  66.     {
  67.         if ((null !== $info $action->getBuildResponseInfo()) && ($info->hasReplace())) {
  68.             return ($info->getReplace())(new ReplaceBuildResponseEvent($action$request$data));
  69.         }
  70.         foreach ($this->responseHandlers as $handler) {
  71.             if ($handler->support($action$request$data)) {
  72.                 if ((null !== $info $action->getBuildResponseInfo()) && ($info->hasPre())) {
  73.                     ($info->getPre())(new PreBuildResponseEvent($action$request$data));
  74.                 }
  75.                 $this->dispatcher->dispatch(new PreBuildResponseEvent($action$request$data));
  76.                 $response $handler->buildResponse($action$request$data);
  77.                 if ((null !== $info) && ($info->hasPost())) {
  78.                     ($info->getPost())(new PostBuildResponseEvent($action$request$data$response));
  79.                 }
  80.                 $this->dispatcher->dispatch(new PostBuildResponseEvent($action$request$data$response));
  81.                 return $response;
  82.             }
  83.         }
  84.         return null;
  85.     }
  86.     private function applyPersister(Action $actionRequest $requestmixed $data): void
  87.     {
  88.         if ($request->attributes->has(DeserializeActionControllerSubscriber::REQUEST_ERROR_KEY)) {
  89.             return;
  90.         }
  91.         if ((null !== $info $action->getPersistInfo()) && ($info->hasReplace())) {
  92.             ($info->getReplace())(new ReplacePersistEvent($action$request$data));
  93.             return;
  94.         }
  95.         if (null === $action->getDeserializeInfo() && $action->getMethod() !== AbstractRoute::DELETE) {
  96.             return;
  97.         }
  98.         foreach ($this->persisterHandlers as $handler) {
  99.             if ($handler->support($action$request$data)) {
  100.                 if ((null !== $info) && ($info->hasPre())) {
  101.                     ($info->getPre())(new PrePersistEvent($action$request$data));
  102.                 }
  103.                 $this->dispatcher->dispatch(new PrePersistEvent($action$request$data));
  104.                 $handler->persist($action$request$data);
  105.                 if ((null !== $info) && ($info->hasPost())) {
  106.                     ($info->getPost())(new PostPersistEvent($action$request$data));
  107.                 }
  108.                 $this->dispatcher->dispatch(new PostPersistEvent($action$request$data));
  109.                 break;
  110.             }
  111.         }
  112.     }
  113. }