<?php
namespace App\EventSubscriber;
use App\Service\RedirectionService;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use App\Exception\CacheHitResponse;
use App\Exception\ValidateException;
use App\Exception\ApiExceptionInterface;
use App\Exception\BadRequestException;
use App\Service\RequestService;
use App\Constant\Redirect301Helper;
class KernelExceptionSubscriber implements EventSubscriberInterface
{
/**
* @var RedirectionService
*/
private RedirectionService $redirectionService;
public function __construct(
RequestService $requestService,
ParameterBagInterface $params,
RedirectionService $redirectionService
) {
$this->requestService = $requestService;
$this->params = $params;
$this->redirectionService = $redirectionService;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::EXCEPTION => [
['onKernelException', 10],
['redirect301', 9],
],
];
}
public function redirect301(ExceptionEvent $event)
{
$exception = $event->getThrowable();
$request = $event->getRequest();
if ($exception instanceof NotFoundHttpException) {
$redirectUrl = $this->redirectionService->getRedirectUrl($request->getRequestUri());
if ($redirectUrl) {
$event->setResponse(
new RedirectResponse($redirectUrl, Response::HTTP_MOVED_PERMANENTLY)
);
}
}
}
public function onKernelException(ExceptionEvent $event)
{
if (!in_array('application/json', $event->getRequest()->getAcceptableContentTypes())) {
//return;
}
$pathUrl = $event->getRequest()->getRequestUri();
if(substr($pathUrl, -1) == '/'){
$pathUrl = substr($pathUrl, 0, -1);
}
if(in_array($pathUrl, array_keys(Redirect301Helper::link301()))){
$event->setResponse(new RedirectResponse(Redirect301Helper::link301()[$pathUrl]));
return;
}
$exception = $event->getThrowable();
$response = new JsonResponse();
if ($exception instanceof CacheHitResponse) {
$this->requestService->exception = $exception;
$event->allowCustomResponseCode();
$response->setStatusCode(($exception->getCode() == 500) ? 200 : $exception->getCode());
$response->setData(json_decode($exception->getMessage(), 1));
$response->headers->set('X-Cache-Hit', 'True');
$event->setResponse($response);
} else if ($exception instanceof ApiExceptionInterface) {
$responseData = $exception->getMessages();
if ($this->params->get('kernel.environment') == 'dev') {
$responseData['trace'] = [
'position' => $exception->getLine() . " of " . $exception->getFile(),
'stack' => $exception->getTrace()
];
}
$response->setStatusCode($responseData['code']);
$response->setData($responseData);
$event->setResponse($response);
$this->requestService->exception = $exception;
$this->requestService->exceptionCode = $responseData['code'];
$this
->requestService
->saveLog(
$event->getResponse()->getStatusCode(),
$event->getResponse()->getContent(),
null,
true
);
} else if ($exception instanceof ForeignKeyConstraintViolationException) {
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
$response->setData([
'error' => BadRequestException::ENTITY_DELETE_RELATION,
'code' => Response::HTTP_BAD_REQUEST
]);
$event->setResponse($response);
$this->requestService->exception = $exception;
$this->requestService->exceptionCode = Response::HTTP_BAD_REQUEST;
$this
->requestService
->saveLog(
$event->getResponse()->getStatusCode(),
$event->getResponse()->getContent(),
null,
true
);
} else if ($exception->getCode() === 500 || $exception->getCode() === 0) {
$this->requestService->exception = $exception;
$this->requestService->exceptionCode = 500;
/*$this
->requestService
->saveLog(
500,
'',
null,
true
);
*/
}
}
}