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