src/EventSubscriber/ApiSubscriber.php line 66

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Utils\ApiResponse;
  4. use App\Exceptions\Api\ApiException;
  5. use App\Controller\Api\BaseApiController;
  6. use App\Utils\Constants\ApiResponseMessages;
  7. use App\Exceptions\Api\ApiValidationException;
  8. use Symfony\Component\HttpKernel\KernelEvents;
  9. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  10. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  13. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  14. use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
  15. class ApiSubscriber implements EventSubscriberInterface {
  16.     /**
  17.      * Returns an array of event names this subscriber wants to listen to.
  18.      *
  19.      * The array keys are event names and the value can be:
  20.      *
  21.      *  * The method name to call (priority defaults to 0)
  22.      *  * An array composed of the method name to call and the priority
  23.      *  * An array of arrays composed of the method names to call and respective
  24.      *    priorities, or 0 if unset
  25.      *
  26.      * For instance:
  27.      *
  28.      *  * ['eventName' => 'methodName']
  29.      *  * ['eventName' => ['methodName', $priority]]
  30.      *  * ['eventName' => [['methodName1', $priority], ['methodName2']]]
  31.      *
  32.      * @return array The event names to listen to
  33.      */
  34.     public static function getSubscribedEvents(): array {
  35.         return [
  36.             KernelEvents::CONTROLLER => 'onKernelController',
  37.             KernelEvents::EXCEPTION => 'onKernelException'
  38.         ];
  39.     }
  40.     /**
  41.      * @param \Symfony\Component\HttpKernel\Event\ControllerEvent $event
  42.      */
  43.     public function onKernelController(ControllerEvent $event){
  44.         $request $event->getRequest();
  45.         if ($request->getContentType() != 'json' || !$request->getContent()) {
  46.             return;
  47.         }
  48.         $data json_decode($request->getContent(), true);
  49.         if (json_last_error() !== JSON_ERROR_NONE) {
  50.             throw new ApiException(ApiResponse::HTTP_BAD_REQUESTApiResponseMessages::MSG_INVALID_JSON);
  51.         }
  52.         $request->request->replace(is_array($data) ? $data : array());
  53.     }
  54.     /**
  55.      * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
  56.      */
  57.     public function onKernelException(ExceptionEvent  $event){
  58.         $fromApi false;
  59.         $ex $event->getThrowable();
  60.         $traces $ex->getTrace();
  61.         foreach($traces as $trace){
  62.             if (!array_key_exists('class'$trace))
  63.                 continue;
  64.             if (strpos($trace['class'], "App\\Controller\\Api\\") === 0) {
  65.                 $fromApi true;
  66.             }
  67.         }
  68.         if ($ex instanceof ApiValidationException) {
  69.             $code method_exists($ex"getStatusCode") ? $ex->getStatusCode() : 500;
  70.             $response = new ApiResponse(
  71.                 [
  72.                     "message" => $ex->getMessage(),
  73.                     "fields" => $ex->getFields()
  74.                 ],
  75.                 $code
  76.             );
  77.             $event->setResponse($response);
  78.         
  79.         } elseif ($_ENV['APP_ENV'] !== 'dev' && $ex instanceof NotFoundHttpException) {
  80.             $code method_exists($ex"getStatusCode") ? $ex->getStatusCode() : 404;
  81.             $response = new ApiResponse(
  82.                 [
  83.                     "message" => "Requested object is not found."
  84.                 ],
  85.                 $code
  86.             );
  87.             $event->setResponse($response);
  88.         
  89.         } elseif ($_ENV['APP_ENV'] !== 'dev' && ($fromApi || $ex instanceof ApiException)) {           
  90.             if (($ex instanceof FileException)
  91.                 && strpos($ex->file'FileService.php') !== false
  92.                 && is_array($ex->trace
  93.                 && strpos($ex->trace[1]['file'], 'src/Entity/News.php') !== false
  94.                 && $ex->trace[1]['function'] === 'upload') {
  95.                 // skip exception response; handle exception from controller to return custom response
  96.             
  97.             } else {
  98.                 $code method_exists($ex"getStatusCode") ? $ex->getStatusCode() : 500;
  99.                 $errType method_exists($ex"getErrType") ? $ex->getErrType() : '';
  100.                 $response = new ApiResponse(
  101.                     [
  102.                         "message" => $ex->getMessage(),
  103.                         "code" => $code,
  104.                         "type" => $errType
  105.                     ],
  106.                     $code
  107.                 );
  108.                 $event->setResponse($response);
  109.             }
  110.         }
  111.     }
  112. }