RouteAccessResponseSubscriber.php 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. <?php
  2. namespace Drupal\Core\EventSubscriber;
  3. use Drupal\Core\Cache\CacheableResponseInterface;
  4. use Drupal\Core\Routing\AccessAwareRouterInterface;
  5. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  6. use Symfony\Component\HttpKernel\KernelEvents;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. /**
  9. * Response subscriber to bubble the route's access result's cacheability.
  10. *
  11. * During routing, access checking is performed. The corresponding access result
  12. * is stored in the Request object's attributes, just like the matching route
  13. * object is. In case of a cacheable response, the route's access result also
  14. * determined the content of the response, and therefore the cacheability of the
  15. * route's access result should also be applied to the resulting response.
  16. *
  17. * @see \Drupal\Core\Routing\AccessAwareRouterInterface::ACCESS_RESULT
  18. * @see \Drupal\Core\Routing\AccessAwareRouter::matchRequest()
  19. * @see \Drupal\Core\Routing\AccessAwareRouter::checkAccess()
  20. */
  21. class RouteAccessResponseSubscriber implements EventSubscriberInterface {
  22. /**
  23. * Bubbles the route's access result' cacheability metadata.
  24. *
  25. * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
  26. * The event to process.
  27. */
  28. public function onRespond(FilterResponseEvent $event) {
  29. if (!$event->isMasterRequest()) {
  30. return;
  31. }
  32. $response = $event->getResponse();
  33. if (!$response instanceof CacheableResponseInterface) {
  34. return;
  35. }
  36. $request = $event->getRequest();
  37. $access_result = $request->attributes->get(AccessAwareRouterInterface::ACCESS_RESULT);
  38. $response->addCacheableDependency($access_result);
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public static function getSubscribedEvents() {
  44. // Priority 10, so that it runs before FinishResponseSubscriber, which will
  45. // expose the cacheability metadata in the form of headers.
  46. $events[KernelEvents::RESPONSE][] = ['onRespond', 10];
  47. return $events;
  48. }
  49. }