<?php
namespace App\EventSubscriber\PressSite;
use App\Service\PressSite\AppContext;
use App\Service\PressSite\DomainAwareManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Twig\Environment;
/**
* Class ExceptionSubscriber.
*/
class ExceptionSubscriber implements EventSubscriberInterface
{
/**
* The twig templating environment.
*
* @var \Twig\Environment
*/
private $twig;
/**
* The custom context helper.
*
* @var \App\Service\PressSite\AppContext
*/
private $appContext;
/**
* The custom service providing helper domain related methods.
*
* @var \App\Service\PressSite\DomainAwareManager
*/
private $domainAwareManager;
/**
* The current environment value.
*
* @var string
*/
private $currentEnvironment;
/**
* ExceptionSubscriber constructor.
*
* @param \Twig\Environment $twig
* The twig templating environment
* @param \App\Service\PressSite\AppContext $appContext
* The custom context helper
* @param \App\Service\PressSite\DomainAwareManager $domainAwareManager
* The domain aware manager
* @param string $currentEnvironment
* The current environment value - either "dev", "test" or "prod"
*/
public function __construct(
Environment $twig,
AppContext $appContext,
DomainAwareManager $domainAwareManager,
string $currentEnvironment
) {
$this->twig = $twig;
$this->appContext = $appContext;
$this->domainAwareManager = $domainAwareManager;
$this->currentEnvironment = $currentEnvironment;
}
public static function getSubscribedEvents()
{
return [
ExceptionEvent::class => 'onKernelException',
];
}
/**
* Public callback for the exception event.
*
* Responsible for providing friendly "Not Found" page, only for the PR sites.
*
* @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
* The instance of the dispatched event
*/
public function onKernelException(ExceptionEvent $event): void
{
// If the exception is occurring on site other than a PR one, then we do not provide custom template.
// If the exception is different than the Not Found one, then we do not provide custom template.
// If the current environment is not a production one, then we keep the default verbose template.
// If we don't have a valid domain instance (one that would indicate that we are currently on a
// PR site, then we keep the default template. That case will occur on AWS, because there we use
// one container with both PR and VOD API feature flags enabled).
if (
!$this->appContext->isPressSiteEnabled()
|| !$this->domainAwareManager->getCurrentByHostnameAndLocale()
|| !$event->getThrowable() instanceof NotFoundHttpException
|| 'dev' === $this->currentEnvironment
) {
return;
}
$request = $event->getRequest();
// The request locale could fallback to the default one "en" when an exception
// is being throw, since the route is not recognized, it may not intercept
// correctly the locale in the address bar.
if (!$this->domainAwareManager->supportsLanguage($request->getLocale())) {
$request->setLocale(
$this->domainAwareManager
->getCurrentByHostnameAndLocale()
->getLanguageCode()
);
}
$response = new Response();
$response->setContent($this->twig->render('press_site/exception/error404.html.twig'));
$event->setResponse($response);
}
}