annotate core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\EventSubscriber;
Chris@0 4
Chris@0 5 use Drupal\Core\Access\AccessManagerInterface;
Chris@0 6 use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
Chris@0 7 use Drupal\Core\Config\ConfigFactoryInterface;
Chris@0 8 use Drupal\Core\Routing\AccessAwareRouterInterface;
Chris@0 9 use Drupal\Core\Routing\RedirectDestinationInterface;
Chris@0 10 use Drupal\Core\Url;
Chris@0 11 use Psr\Log\LoggerInterface;
Chris@0 12 use Symfony\Component\HttpFoundation\Response;
Chris@0 13 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
Chris@0 14 use Symfony\Component\HttpKernel\HttpKernelInterface;
Chris@0 15 use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
Chris@0 16
Chris@0 17 /**
Chris@0 18 * Exception subscriber for handling core custom HTML error pages.
Chris@0 19 */
Chris@0 20 class CustomPageExceptionHtmlSubscriber extends DefaultExceptionHtmlSubscriber {
Chris@0 21
Chris@0 22 /**
Chris@0 23 * The configuration factory.
Chris@0 24 *
Chris@0 25 * @var \Drupal\Core\Config\ConfigFactoryInterface
Chris@0 26 */
Chris@0 27 protected $configFactory;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * The access manager.
Chris@0 31 *
Chris@0 32 * @var \Drupal\Core\Access\AccessManagerInterface
Chris@0 33 */
Chris@0 34 protected $accessManager;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * Constructs a new CustomPageExceptionHtmlSubscriber.
Chris@0 38 *
Chris@0 39 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
Chris@0 40 * The configuration factory.
Chris@0 41 * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
Chris@0 42 * The HTTP Kernel service.
Chris@0 43 * @param \Psr\Log\LoggerInterface $logger
Chris@0 44 * The logger service.
Chris@0 45 * @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
Chris@0 46 * The redirect destination service.
Chris@0 47 * @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $access_unaware_router
Chris@0 48 * A router implementation which does not check access.
Chris@0 49 * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
Chris@0 50 * The access manager.
Chris@0 51 */
Chris@0 52 public function __construct(ConfigFactoryInterface $config_factory, HttpKernelInterface $http_kernel, LoggerInterface $logger, RedirectDestinationInterface $redirect_destination, UrlMatcherInterface $access_unaware_router, AccessManagerInterface $access_manager) {
Chris@0 53 parent::__construct($http_kernel, $logger, $redirect_destination, $access_unaware_router);
Chris@0 54 $this->configFactory = $config_factory;
Chris@0 55 $this->accessManager = $access_manager;
Chris@0 56 }
Chris@0 57
Chris@0 58 /**
Chris@0 59 * {@inheritdoc}
Chris@0 60 */
Chris@0 61 protected static function getPriority() {
Chris@0 62 return -50;
Chris@0 63 }
Chris@0 64
Chris@0 65 /**
Chris@0 66 * {@inheritdoc}
Chris@0 67 */
Chris@0 68 public function on403(GetResponseForExceptionEvent $event) {
Chris@0 69 $custom_403_path = $this->configFactory->get('system.site')->get('page.403');
Chris@0 70 if (!empty($custom_403_path)) {
Chris@0 71 $this->makeSubrequestToCustomPath($event, $custom_403_path, Response::HTTP_FORBIDDEN);
Chris@0 72 }
Chris@0 73 }
Chris@0 74
Chris@0 75 /**
Chris@0 76 * {@inheritdoc}
Chris@0 77 */
Chris@0 78 public function on404(GetResponseForExceptionEvent $event) {
Chris@0 79 $custom_404_path = $this->configFactory->get('system.site')->get('page.404');
Chris@0 80 if (!empty($custom_404_path)) {
Chris@0 81 $this->makeSubrequestToCustomPath($event, $custom_404_path, Response::HTTP_NOT_FOUND);
Chris@0 82 }
Chris@0 83 }
Chris@0 84
Chris@0 85 /**
Chris@0 86 * Makes a subrequest to retrieve the custom error page.
Chris@0 87 *
Chris@0 88 * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
Chris@0 89 * The event to process.
Chris@0 90 * @param string $custom_path
Chris@0 91 * The custom path to which to make a subrequest for this error message.
Chris@0 92 * @param int $status_code
Chris@0 93 * The status code for the error being handled.
Chris@0 94 */
Chris@0 95 protected function makeSubrequestToCustomPath(GetResponseForExceptionEvent $event, $custom_path, $status_code) {
Chris@0 96 $url = Url::fromUserInput($custom_path);
Chris@0 97 if ($url->isRouted()) {
Chris@0 98 $access_result = $this->accessManager->checkNamedRoute($url->getRouteName(), $url->getRouteParameters(), NULL, TRUE);
Chris@0 99 $request = $event->getRequest();
Chris@0 100
Chris@0 101 // Merge the custom path's route's access result's cacheability metadata
Chris@0 102 // with the existing one (from the master request), otherwise create it.
Chris@0 103 if (!$request->attributes->has(AccessAwareRouterInterface::ACCESS_RESULT)) {
Chris@0 104 $request->attributes->set(AccessAwareRouterInterface::ACCESS_RESULT, $access_result);
Chris@0 105 }
Chris@0 106 else {
Chris@0 107 $existing_access_result = $request->attributes->get(AccessAwareRouterInterface::ACCESS_RESULT);
Chris@0 108 if ($existing_access_result instanceof RefinableCacheableDependencyInterface) {
Chris@0 109 $existing_access_result->addCacheableDependency($access_result);
Chris@0 110 }
Chris@0 111 }
Chris@0 112
Chris@0 113 // Only perform the subrequest if the custom path is actually accessible.
Chris@0 114 if (!$access_result->isAllowed()) {
Chris@0 115 return;
Chris@0 116 }
Chris@0 117 }
Chris@0 118
Chris@0 119 $this->makeSubrequest($event, $custom_path, $status_code);
Chris@0 120 }
Chris@0 121
Chris@0 122 }