You are here

public function DynamicPageCacheSubscriber::onResponse in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber::onResponse()

Stores a response in case of a Dynamic Page Cache miss, if cacheable.

Parameters

\Symfony\Component\HttpKernel\Event\FilterResponseEvent $event: The event to process.

File

core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php, line 157
Contains \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber.

Class

DynamicPageCacheSubscriber
Returns cached responses as early and avoiding as much work as possible.

Namespace

Drupal\dynamic_page_cache\EventSubscriber

Code

public function onResponse(FilterResponseEvent $event) {
  $response = $event
    ->getResponse();

  // Dynamic Page Cache only works with cacheable responses. It does not work
  // with plain Response objects. (Dynamic Page Cache needs to be able to
  // access and modify the cacheability metadata associated with the
  // response.)
  if (!$response instanceof CacheableResponseInterface) {
    return;
  }

  // There's no work left to be done if this is a Dynamic Page Cache hit.
  if ($response->headers
    ->get(self::HEADER) === 'HIT') {
    return;
  }

  // There's no work left to be done if this is an uncacheable response.
  if (!$this
    ->shouldCacheResponse($response)) {

    // The response is uncacheable, mark it as such.
    $response->headers
      ->set(self::HEADER, 'UNCACHEABLE');
    return;
  }

  // Don't cache the response if Dynamic Page Cache's request subscriber did
  // not fire, because that means it is impossible to have a Dynamic Page
  // Cache hit. (This can happen when the master request is for example a 403
  // or 404, in which case a subrequest is performed by the router. In that
  // case, it is the subrequest's response that is cached by Dynamic Page
  // Cache, because the routing happens in a request subscriber earlier than
  // Dynamic Page Cache's and immediately sets a response, i.e. the one
  // returned by the subrequest, and thus causes Dynamic Page Cache's request
  // subscriber to not fire for the master request.)
  // @see \Drupal\Core\Routing\AccessAwareRouter::checkAccess()
  // @see \Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber::on403()
  $request = $event
    ->getRequest();
  if (!$request->attributes
    ->has(self::ATTRIBUTE_REQUEST_POLICY_RESULT)) {
    return;
  }

  // Don't cache the response if the Dynamic Page Cache request & response
  // policies are not met.
  // @see onRouteMatch()
  if ($request->attributes
    ->get(self::ATTRIBUTE_REQUEST_POLICY_RESULT) === RequestPolicyInterface::DENY || $this->responsePolicy
    ->check($response, $request) === ResponsePolicyInterface::DENY) {
    return;
  }

  // Embed the response object in a render array so that RenderCache is able
  // to cache it, handling cache redirection for us.
  $response_as_render_array = $this
    ->responseToRenderArray($response);
  $this->renderCache
    ->set($response_as_render_array, $this->dynamicPageCacheRedirectRenderArray);

  // The response was generated, mark the response as a cache miss. The next
  // time, it will be a cache hit.
  $response->headers
    ->set(self::HEADER, 'MISS');
}