protected EarlyRenderingControllerWrapperSubscriber::wrapControllerExecutionInRenderContext($controller, array $arguments)
Wraps a controller execution in a render context.
Parameters
callable $controller: The controller to execute.
array $arguments: The arguments to pass to the controller.
Return value
mixed The return value of the controller.
Throws
\LogicException When early rendering has occurred in a controller that returned a Response or domain object that cares about attachments or cacheability.
See also
\Symfony\Component\HttpKernel\HttpKernel::handleRaw()
File
- core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php, line 118
Class
- EarlyRenderingControllerWrapperSubscriber
- Subscriber that wraps controllers, to handle early rendering.
Namespace
Drupal\Core\EventSubscriber
Code
protected function wrapControllerExecutionInRenderContext($controller, array $arguments) { $context = new RenderContext(); $response = $this->renderer->executeInRenderContext($context, function() use ($controller, $arguments) { // Now call the actual controller, just like HttpKernel does. return call_user_func_array($controller, $arguments); }); // If early rendering happened, i.e. if code in the controller called // drupal_render() outside of a render context, then the bubbleable metadata // for that is stored in the current render context. if (!$context->isEmpty()) { /** @var \Drupal\Core\Render\BubbleableMetadata $early_rendering_bubbleable_metadata */ $early_rendering_bubbleable_metadata = $context->pop(); // If a render array or AjaxResponse is returned by the controller, merge // the "lost" bubbleable metadata. if (is_array($response)) { BubbleableMetadata::createFromRenderArray($response) ->merge($early_rendering_bubbleable_metadata) ->applyTo($response); } elseif ($response instanceof AjaxResponse) { $response->addAttachments($early_rendering_bubbleable_metadata->getAttachments()); // @todo Make AjaxResponse cacheable in // https://www.drupal.org/node/956186. Meanwhile, allow contrib // subclasses to be. if ($response instanceof CacheableResponseInterface) { $response->addCacheableDependency($early_rendering_bubbleable_metadata); } } // If a non-Ajax Response or domain object is returned and it cares about // attachments or cacheability, then throw an exception: early rendering // is not permitted in that case. It is the developer's responsibility // to not use early rendering. elseif ($response instanceof AttachmentsInterface || $response instanceof CacheableResponseInterface || $response instanceof CacheableDependencyInterface) { throw new \LogicException(sprintf('The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: %s.', get_class($response))); } else { // A Response or domain object is returned that does not care about // attachments nor cacheability; for instance, a RedirectResponse. It is // safe to discard any early rendering metadata. } } return $response; }
Please login to continue.