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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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.