diff --git a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php index 637d48d5f60941cab3203944d79e444d3538151b..cec3c49935e13134921424b4c2dc93e8e6ad1569 100644 --- a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php @@ -10,6 +10,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -44,15 +45,25 @@ public function __construct(ContentNegotiation $negotiation) { */ public function onView(GetResponseForControllerResultEvent $event) { - $request = $event->getRequest(); - - $method = 'on' . $this->negotiation->getContentType($request); - - if (method_exists($this, $method)) { - $event->setResponse($this->$method($event)); + // For a master request, we process the result and wrap it as needed. + // For a subrequest, all we want is the string value. We assume that + // is just an HTML string from a controller, so wrap that into a response + // object. The subrequest's response will get dissected and placed into + // the larger page as needed. + if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) { + $request = $event->getRequest(); + + $method = 'on' . $this->negotiation->getContentType($request); + + if (method_exists($this, $method)) { + $event->setResponse($this->$method($event)); + } + else { + $event->setResponse(new Response('Unsupported Media Type', 415)); + } } else { - $event->setResponse(new Response('Unsupported Media Type', 415)); + $event->setResponse(new Response($event->getControllerResult())); } } diff --git a/core/lib/Drupal/Core/HtmlPageController.php b/core/lib/Drupal/Core/HtmlPageController.php index bfc6d578b62fddb84a59ee9971f44a201d25e14a..b087b82c67d88309a0aa5a81ef473eb7d4a70cb8 100644 --- a/core/lib/Drupal/Core/HtmlPageController.php +++ b/core/lib/Drupal/Core/HtmlPageController.php @@ -22,11 +22,20 @@ public function setContainer(ContainerInterface $container = NULL) { public function content(Request $request, $_content) { - $content_controller = $this->getContentController($_content); - - $page_callback_result = call_user_func_array($content_controller, array()); - - return new Response(drupal_render_page($page_callback_result)); + // @todo When we have a Generator, we can replace the forward() call with + // a render() call, which would handle ESI and hInclude as well. That will + // require an _internal route. For examples, see: + // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/internal.xml + // https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php + $attributes = $request->attributes; + $controller = $attributes->get('_content'); + $attributes->remove('system_path'); + $attributes->remove('_content'); + $response = $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all()); + + $page_content = $response->getContent(); + + return new Response(drupal_render_page($page_content)); } protected function getContentController($controller) {