From 867e7707f5b5e68a56de654bfc0eb140d45ca0e2 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Sun, 2 Sep 2012 13:59:53 -0500 Subject: [PATCH] Pass the _content callback as a proper controller through HttpKernel::forward(). --- .../Core/EventSubscriber/ViewSubscriber.php | 21 ++++++++++++++----- core/lib/Drupal/Core/HtmlPageController.php | 15 ++++++++++--- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php index 637d48d5f60..cec3c49935e 100644 --- a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php @@ -10,6 +10,7 @@ namespace Drupal\Core\EventSubscriber; 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 @@ class ViewSubscriber implements EventSubscriberInterface { */ public function onView(GetResponseForControllerResultEvent $event) { - $request = $event->getRequest(); + // 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); + $method = 'on' . $this->negotiation->getContentType($request); - if (method_exists($this, $method)) { - $event->setResponse($this->$method($event)); + 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 bfc6d578b62..b087b82c67d 100644 --- a/core/lib/Drupal/Core/HtmlPageController.php +++ b/core/lib/Drupal/Core/HtmlPageController.php @@ -22,11 +22,20 @@ class HtmlPageController implements ContainerAwareInterface { public function content(Request $request, $_content) { - $content_controller = $this->getContentController($_content); + // @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_callback_result = call_user_func_array($content_controller, array()); + $page_content = $response->getContent(); - return new Response(drupal_render_page($page_callback_result)); + return new Response(drupal_render_page($page_content)); } protected function getContentController($controller) {