<?php
namespace App\EventListener\ControlPanel;
use App\Application\DTO\JsonApi\Error;
use App\Application\DTO\JsonApi\JsonApiDocument;
use App\Application\Service\Factory\SerializerFactory;
use App\Application\Service\Helper\ControlPanelLogWriterService;
use App\Application\Service\Helper\TranslatorService;
use App\Entity\System\Language;
use App\Exception\ControlPanel\ControlpanelException;
use App\Exception\ControlPanel\ControlPanelNotFoundException;
use App\Exception\ControlPanel\JsonApiException;
use App\Model\Controlpanel\Response\WebJsonApiResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class ControlpanelExceptionListener
{
private TranslatorInterface $translator;
private ControlPanelLogWriterService $logWriterService;
private SerializerInterface $serializer;
private RequestStack $requestStack;
public function __construct(
TranslatorInterface $translator,
ControlPanelLogWriterService $logWriterService,
SerializerFactory $serializerFactory,
RequestStack $requestStack
) {
$this->translator = $translator;
$this->logWriterService = $logWriterService;
$this->serializer = $serializerFactory::getWebJsonAPISerializer();
$this->requestStack = $requestStack;
}
/**
* @throws \App\Exception\JsonApiException
* @throws \Exception
*/
public function onKernelException(ExceptionEvent $exceptionEvent): void
{
$exception = $exceptionEvent->getThrowable();
$request = $exceptionEvent->getRequest();
$isoCode = $this->requestStack->getSession()->get('lang', Language::ENGLISH_ISO);
if ($exception instanceof ControlPanelNotFoundException) {
$exceptionEvent->setResponse(new Response('', Response::HTTP_NOT_FOUND));
}
if ($exception instanceof ControlpanelException) {
foreach ($exception->getErrors() as $error) {
$error->setTitle($this->translator->trans($error->getTitle(), [], TranslatorService::MESSAGES_DOMAIN, $isoCode));
}
$jsonApiDocument = new JsonApiDocument(null, $exception->getErrors());
$serializedResponse = $this->serializer->serialize($jsonApiDocument, 'json');
$this->logWriterService->logResponse($request->getRealMethod(), $request->attributes->get('_route'), $serializedResponse, ControlPanelLogWriterService::WARNING);
$exceptionEvent->setResponse(new WebJsonApiResponse($jsonApiDocument, $exception->getStatusCode(), ['Content-Type' => 'application/vnd.api+json']));
}
if ($exception instanceof JsonApiException) {
$title = $this->translator->trans($exception->getMessage(), [], TranslatorService::MESSAGES_DOMAIN, $isoCode);
$status = (string)Response::HTTP_BAD_REQUEST;
$error = new Error(null, null, null, $status, $title);
$jsonApiDocument = new JsonApiDocument(null, [$error]);
$serializedResponse = $this->serializer->serialize($jsonApiDocument, 'json');
$this->logWriterService->logResponse($request->getRealMethod(), $request->attributes->get('_route'), $serializedResponse, ControlPanelLogWriterService::WARNING);
$exceptionEvent->setResponse(new WebJsonApiResponse($jsonApiDocument, Response::HTTP_BAD_REQUEST, ['Content-Type' => 'application/vnd.api+json']));
}
}
}