Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,122 @@ +<?php + +namespace Drupal\Core\EventSubscriber; + +use Drupal\Core\Access\AccessManagerInterface; +use Drupal\Core\Cache\RefinableCacheableDependencyInterface; +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Routing\AccessAwareRouterInterface; +use Drupal\Core\Routing\RedirectDestinationInterface; +use Drupal\Core\Url; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; +use Symfony\Component\Routing\Matcher\UrlMatcherInterface; + +/** + * Exception subscriber for handling core custom HTML error pages. + */ +class CustomPageExceptionHtmlSubscriber extends DefaultExceptionHtmlSubscriber { + + /** + * The configuration factory. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * The access manager. + * + * @var \Drupal\Core\Access\AccessManagerInterface + */ + protected $accessManager; + + /** + * Constructs a new CustomPageExceptionHtmlSubscriber. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The configuration factory. + * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel + * The HTTP Kernel service. + * @param \Psr\Log\LoggerInterface $logger + * The logger service. + * @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination + * The redirect destination service. + * @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $access_unaware_router + * A router implementation which does not check access. + * @param \Drupal\Core\Access\AccessManagerInterface $access_manager + * The access manager. + */ + public function __construct(ConfigFactoryInterface $config_factory, HttpKernelInterface $http_kernel, LoggerInterface $logger, RedirectDestinationInterface $redirect_destination, UrlMatcherInterface $access_unaware_router, AccessManagerInterface $access_manager) { + parent::__construct($http_kernel, $logger, $redirect_destination, $access_unaware_router); + $this->configFactory = $config_factory; + $this->accessManager = $access_manager; + } + + /** + * {@inheritdoc} + */ + protected static function getPriority() { + return -50; + } + + /** + * {@inheritdoc} + */ + public function on403(GetResponseForExceptionEvent $event) { + $custom_403_path = $this->configFactory->get('system.site')->get('page.403'); + if (!empty($custom_403_path)) { + $this->makeSubrequestToCustomPath($event, $custom_403_path, Response::HTTP_FORBIDDEN); + } + } + + /** + * {@inheritdoc} + */ + public function on404(GetResponseForExceptionEvent $event) { + $custom_404_path = $this->configFactory->get('system.site')->get('page.404'); + if (!empty($custom_404_path)) { + $this->makeSubrequestToCustomPath($event, $custom_404_path, Response::HTTP_NOT_FOUND); + } + } + + /** + * Makes a subrequest to retrieve the custom error page. + * + * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event + * The event to process. + * @param string $custom_path + * The custom path to which to make a subrequest for this error message. + * @param int $status_code + * The status code for the error being handled. + */ + protected function makeSubrequestToCustomPath(GetResponseForExceptionEvent $event, $custom_path, $status_code) { + $url = Url::fromUserInput($custom_path); + if ($url->isRouted()) { + $access_result = $this->accessManager->checkNamedRoute($url->getRouteName(), $url->getRouteParameters(), NULL, TRUE); + $request = $event->getRequest(); + + // Merge the custom path's route's access result's cacheability metadata + // with the existing one (from the master request), otherwise create it. + if (!$request->attributes->has(AccessAwareRouterInterface::ACCESS_RESULT)) { + $request->attributes->set(AccessAwareRouterInterface::ACCESS_RESULT, $access_result); + } + else { + $existing_access_result = $request->attributes->get(AccessAwareRouterInterface::ACCESS_RESULT); + if ($existing_access_result instanceof RefinableCacheableDependencyInterface) { + $existing_access_result->addCacheableDependency($access_result); + } + } + + // Only perform the subrequest if the custom path is actually accessible. + if (!$access_result->isAllowed()) { + return; + } + } + + $this->makeSubrequest($event, $custom_path, $status_code); + } + +}