vendor/pimcore/pimcore/bundles/CoreBundle/EventListener/ResponseExceptionListener.php line 82

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  13.  */
  14. namespace Pimcore\Bundle\CoreBundle\EventListener;
  15. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  16. use Pimcore\Config;
  17. use Pimcore\Db\ConnectionInterface;
  18. use Pimcore\Document\Renderer\DocumentRenderer;
  19. use Pimcore\Http\Exception\ResponseException;
  20. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  21. use Pimcore\Model\Document;
  22. use Pimcore\Model\Site;
  23. use Pimcore\Templating\Renderer\ActionRenderer;
  24. use Psr\Log\LoggerAwareTrait;
  25. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
  29. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  30. use Symfony\Component\HttpKernel\KernelEvents;
  31. class ResponseExceptionListener implements EventSubscriberInterface
  32. {
  33.     use LoggerAwareTrait;
  34.     use PimcoreContextAwareTrait;
  35.     /**
  36.      * @var ActionRenderer
  37.      */
  38.     protected $documentRenderer;
  39.     /**
  40.      * @var bool
  41.      */
  42.     protected $renderErrorPage true;
  43.     /**
  44.      * @var Config
  45.      */
  46.     protected $config;
  47.     /**
  48.      * @var ConnectionInterface
  49.      */
  50.     protected $db;
  51.     /**
  52.      * @param DocumentRenderer $documentRenderer
  53.      * @param ConnectionInterface $db
  54.      * @param bool $renderErrorPage
  55.      */
  56.     public function __construct(DocumentRenderer $documentRendererConnectionInterface $dbConfig $config$renderErrorPage true)
  57.     {
  58.         $this->documentRenderer $documentRenderer;
  59.         $this->renderErrorPage = (bool)$renderErrorPage;
  60.         $this->db $db;
  61.         $this->config $config;
  62.     }
  63.     /**
  64.      * @inheritDoc
  65.      */
  66.     public static function getSubscribedEvents()
  67.     {
  68.         return [
  69.             KernelEvents::EXCEPTION => 'onKernelException'
  70.         ];
  71.     }
  72.     public function onKernelException(GetResponseForExceptionEvent $event)
  73.     {
  74.         $exception $event->getException();
  75.         // handle ResponseException (can be used from any context)
  76.         if ($exception instanceof ResponseException) {
  77.             $event->setResponse($exception->getResponse());
  78.             // a response was explicitely set -> do not continue to error page
  79.             return;
  80.         }
  81.         // further checks are only valid for default context
  82.         $request $event->getRequest();
  83.         if ($this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_DEFAULT)) {
  84.             if ($this->renderErrorPage) {
  85.                 $this->handleErrorPage($event);
  86.             }
  87.         }
  88.     }
  89.     protected function handleErrorPage(GetResponseForExceptionEvent $event)
  90.     {
  91.         if (\Pimcore::inDebugMode()) {
  92.             return;
  93.         }
  94.         $exception $event->getException();
  95.         $statusCode 500;
  96.         $headers = [];
  97.         if ($exception instanceof HttpExceptionInterface) {
  98.             $statusCode $exception->getStatusCode();
  99.             $headers $exception->getHeaders();
  100.         } else {
  101.             // only log exception if it's not intentional (like a NotFoundHttpException)
  102.             $this->logger->error($exception);
  103.         }
  104.         $errorPath $this->config['documents']['error_pages']['default'];
  105.         if (Site::isSiteRequest()) {
  106.             $site Site::getCurrentSite();
  107.             $errorPath $site->getErrorDocument();
  108.         }
  109.         $this->logToHttpErrorLog($event->getRequest(), $statusCode);
  110.         // Error page rendering
  111.         if (empty($errorPath)) {
  112.             $errorPath '/';
  113.         }
  114.         $document Document::getByPath($errorPath);
  115.         if (!$document instanceof Document\Page) {
  116.             // default is home
  117.             $document Document::getById(1);
  118.         }
  119.         try {
  120.             $response $this->documentRenderer->render($document, [
  121.                 'exception' => $exception
  122.             ]);
  123.         } catch (\Exception $e) {
  124.             // we are even not able to render the error page, so we send the client a unicorn
  125.             $response 'Page not found. ðŸ¦„';
  126.             $this->logger->emergency('Unable to render error page, exception thrown');
  127.             $this->logger->emergency($e);
  128.         }
  129.         $event->setResponse(new Response($response$statusCode$headers));
  130.     }
  131.     protected function logToHttpErrorLog(Request $request$statusCode)
  132.     {
  133.         $uri $request->getUri();
  134.         $exists $this->db->fetchOne('SELECT date FROM http_error_log WHERE uri = ?'$uri);
  135.         if ($exists) {
  136.             $this->db->query('UPDATE http_error_log SET `count` = `count` + 1, date = ? WHERE uri = ?', [time(), $uri]);
  137.         } else {
  138.             $this->db->insert('http_error_log', [
  139.                 'uri' => $uri,
  140.                 'code' => (int) $statusCode,
  141.                 'parametersGet' => serialize($_GET),
  142.                 'parametersPost' => serialize($_POST),
  143.                 'cookies' => serialize($_COOKIE),
  144.                 'serverVars' => serialize($_SERVER),
  145.                 'date' => time(),
  146.                 'count' => 1
  147.             ]);
  148.         }
  149.     }
  150. }