<?php
declare(strict_types=0);
/*
* WellCommerce Foundation
*
* This file is part of the WellCommerce package.
*
* (c) Adam Piotrowski <adam@wellcommerce.org>, Adrian Potepa <adrian@wellcommerce.org>
*
* For the full copyright and license information,
* please view the LICENSE file that was distributed with this source code.
*/
namespace WellCommerce\Bundle\AppBundle\EventListener;
use Doctrine\Common\Util\Debug;
use Doctrine\ORM\QueryBuilder;
use Psr\Container\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use WellCommerce\Bundle\AppBundle\Entity\Redirect;
use WellCommerce\Bundle\CoreBundle\DependencyInjection\AbstractServiceSubscriber;
use WhiteOctober\BreadcrumbsBundle\Model\Breadcrumbs;
/**
* Class ExceptionSubscriber
*
* @author Adam Piotrowski <adam@wellcommerce.org>
*/
class ExceptionSubscriber extends AbstractServiceSubscriber implements EventSubscriberInterface
{
protected $breadcrumbs;
public function __construct(ContainerInterface $locator, Breadcrumbs $breadcrumbs)
{
parent::__construct($locator);
$this->breadcrumbs = $breadcrumbs;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::EXCEPTION => ['onKernelException', 0],
];
}
public function onKernelException(ExceptionEvent $event)
{
if (false === $this->getKernel()->isDebug()) {
$this->getThemeStorage()->setCurrentTheme($this->getShopStorage()->getCurrentShop()->getTheme());
$exception = $event->getThrowable();
$request = $event->getRequest();
$pathInfo = $request->getPathInfo();
$requestUri = $request->getRequestUri();
if (substr($pathInfo, -1, 1) === '/') {
$url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri);
$response = new RedirectResponse($url, 301);
$event->setResponse($response);
} else {
$redirect = $this->getRedirect($request);
if ($redirect instanceof Redirect) {
$response = new RedirectResponse($redirect->getTarget(), $redirect->getStatus());
$event->setResponse($response);
} else {
$this->breadcrumbs->clear();
$this->breadcrumbs->addRouteItem('homepage.heading.index', 'front.home_page.index', [], 0);
if ($exception instanceof HttpExceptionInterface) {
$this->breadcrumbs->addItem('Niepoprawny adres strony');
$content = $this->getTemplatingHelper()->render('WellCommerceAppBundle:Front/Exception:404.html.twig', [
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
'exception' => $exception,
]);
} else {
$this->breadcrumbs->addItem('Błąd strony');
$content = $this->getTemplatingHelper()->render('WellCommerceAppBundle:Front/Exception:500.html.twig', [
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
'exception' => $exception,
]);
}
$response = new Response();
$response->setContent($content);
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
$response->headers->set('X-Robots-Tag', 'noindex', true);
$event->setResponse($response);
}
}
}
}
public function getRedirect(Request $request): ?Redirect
{
$path = urldecode($request->getPathInfo());
$repository = $this->getEntityManager()->getRepository(Redirect::class);
/** @var QueryBuilder $queryBuilder */
$queryBuilder = $repository->createQueryBuilder('redirect');
$queryBuilder->andWhere('REGEXP(:path, redirect.source) = true');
$queryBuilder->orderBy('redirect.hierarchy', 'ASC');
$queryBuilder->setParameter('path', $path);
$query = $queryBuilder->getQuery();
$result = $query->getResult();
if (!empty($result)) {
if (count($result) === 1) {
return current($result);
}
/** @var Redirect $redirect */
foreach ($result as $redirect) {
if ($redirect->getSource() === $path) {
return $redirect;
}
}
}
return null;
}
}