.../EventSubscriber/DynamicPageCacheSubscriber.php | 44 +++++++++++----------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php b/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php index 35087b1..17c2f33 100644 --- a/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php +++ b/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php @@ -9,7 +9,6 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableMetadata; -use Drupal\Core\Cache\CacheableResponse; use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\EventSubscriber\MainContentViewSubscriber; use Drupal\Core\PageCache\RequestPolicyInterface; @@ -47,11 +46,19 @@ class DynamicPageCacheSubscriber implements EventSubscriberInterface { * Attribute name of the Dynamic Page Cache request policy result. * * @see onRouteMatch() - * @see onRespond() + * @see onResponse() */ const ATTRIBUTE_REQUEST_POLICY_RESULT = '_dynamic_page_cache_request_policy_result'; /** + * Attribute name of the controller's render array #cache check. + * + * @see onViewRenderArray() + * @see onResponse() + */ + const ATTRIBUTE_CONTROLLER_RESULT_RENDER_ARRAY_HAS_CACHEABILITY = '_dynamic_page_cache_controller_render_array_has_cacheability'; + + /** * Name of Dynamic Page Cache's response header. */ const HEADER = 'X-Drupal-Dynamic-Cache'; @@ -157,35 +164,17 @@ public function onRouteMatch(GetResponseEvent $event) { * @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event * The event to process. * - * @throws \LogicException + * @see ::onResponse() */ public function onViewRenderArray(GetResponseForControllerResultEvent $event) { $request = $event->getRequest(); $result = $event->getControllerResult(); - // Don't complain if Dynamic Page Cache's request subscriber did not fire, - // because that means it is impossible to have a Dynamic Page Cache hit, - // and hence complaining is unnecessary. - // @see ::onResponse() - if (!$request->attributes->has(self::ATTRIBUTE_REQUEST_POLICY_RESULT)) { - return; - } - - // Don't complain if the Dynamic Page Cache request & response policies are - // not met, because that means Dynamic Page Cache won't cache this response - // and hence complaining is unnecessary. - // @see onRouteMatch() - if ($request->attributes->get(self::ATTRIBUTE_REQUEST_POLICY_RESULT) === RequestPolicyInterface::DENY || $this->responsePolicy->check(new CacheableResponse(), $request) === ResponsePolicyInterface::DENY) { - return; - } - // Check if MainContentViewSubscriber would render this render array, i.e. // if this render array will in fact be converted into a response. if (is_array($result) && ($request->query->has(MainContentViewSubscriber::WRAPPER_FORMAT) || $request->getRequestFormat() == 'html')) { - // If #cache is not set, complain. - if (!isset($result['#cache'])) { - throw new \LogicException('The controller returned a render array without cacheability metadata. See https://www.drupal.org/developing/api/8/render/arrays/cacheability.'); - } + // If #cache is not set, complain later. + $request->attributes->set(self::ATTRIBUTE_CONTROLLER_RESULT_RENDER_ARRAY_HAS_CACHEABILITY, isset($result['#cache'])); } } @@ -194,6 +183,8 @@ public function onViewRenderArray(GetResponseForControllerResultEvent $event) { * * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event * The event to process. + * + * @throws \LogicException */ public function onResponse(FilterResponseEvent $event) { $response = $event->getResponse(); @@ -241,6 +232,13 @@ public function onResponse(FilterResponseEvent $event) { return; } + // If #cache was not set, complain. + // @see ::onViewRenderArray() + // If #cache is not set, complain. + if ($request->attributes->get(self::ATTRIBUTE_CONTROLLER_RESULT_RENDER_ARRAY_HAS_CACHEABILITY) === FALSE) { + throw new \LogicException('The controller returned a render array without cacheability metadata. See https://www.drupal.org/developing/api/8/render/arrays/cacheability.'); + } + // 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);