From b9d568998736b06c0d91933244e9974729091520 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Sun, 2 Sep 2012 11:40:09 -0500 Subject: [PATCH] Introduce a default controller for pages with a _content request attribute. --- core/lib/Drupal/Core/CoreBundle.php | 1 + .../RouteProcessorSubscriber.php | 72 +++++++++++++++++++ core/lib/Drupal/Core/HtmlPageController.php | 57 +++++++++++++++ .../system/Tests/Routing/RouterTest.php | 12 ++++ .../Drupal/router_test/TestControllers.php | 11 ++- .../modules/router_test/router_test.module | 8 +++ 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php create mode 100644 core/lib/Drupal/Core/HtmlPageController.php diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php index 6437d697613..fceaf76ef8b 100644 --- a/core/lib/Drupal/Core/CoreBundle.php +++ b/core/lib/Drupal/Core/CoreBundle.php @@ -82,6 +82,7 @@ class CoreBundle extends Bundle $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\FinishResponseSubscriber()); $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RequestCloseSubscriber()); $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber()); + $dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RouteProcessorSubscriber()); $container->set('content_negotiation', $content_negotation); $dispatcher->addSubscriber(\Drupal\Core\ExceptionController::getExceptionListener($container)); diff --git a/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php new file mode 100644 index 00000000000..816366657fa --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php @@ -0,0 +1,72 @@ +getRequest(); + + if (!$request->attributes->has('_controller') && $request->attributes->has('_content')) { + $request->attributes->set('_controller', '\Drupal\Core\HtmlPageController::content'); + } + + } + + /** + * Registers the methods in this class that should be listeners. + * + * @return array + * An array of event listener definitions. + */ + static function getSubscribedEvents() { + // The RouterListener has priority 32, and we need to run after that. + $events[KernelEvents::REQUEST][] = array('onRequestSetController', 30); + + return $events; + } +} diff --git a/core/lib/Drupal/Core/HtmlPageController.php b/core/lib/Drupal/Core/HtmlPageController.php new file mode 100644 index 00000000000..000e9abe483 --- /dev/null +++ b/core/lib/Drupal/Core/HtmlPageController.php @@ -0,0 +1,57 @@ +getContentController($_content); + + $page_callback_result = call_user_func_array($content_controller, array()); + + return new Response(drupal_render_page($page_callback_result)); + } + + protected function getContentController($controller) { + if (is_array($controller) || (is_object($controller) && method_exists($controller, '__invoke'))) { + return $controller; + } + + if (FALSE === strpos($controller, ':')) { + if (method_exists($controller, '__invoke')) { + return new $controller; + } elseif (function_exists($controller)) { + return $controller; + } + } + + list($controller, $method) = $this->createController($controller); + + if (!method_exists($controller, $method)) { + throw new \InvalidArgumentException(sprintf('Method "%s::%s" does not exist.', get_class($controller), $method)); + } + + return array($controller, $method); + } + + protected function createController($controller) { + if (false === strpos($controller, '::')) { + throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller)); + } + + list($class, $method) = explode('::', $controller, 2); + + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + return array(new $class(), $method); + } + + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RouterTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RouterTest.php index a5449afc04c..ac7d5b7239b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/RouterTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RouterTest.php @@ -25,9 +25,21 @@ class RouterTest extends WebTestBase { ); } + /** + * Confirms that the router can get to a controller. + */ public function testCanRoute() { $this->drupalGet('router_test/test1'); $this->assertRaw('test1', 'The correct string was returned because the route was successful.'); } + /** + * Confirms that our default controller logic works properly. + */ + public function testDefaultController() { + $this->drupalGet('router_test/test2'); + $this->assertRaw('test2', 'The correct string was returned because the route was successful.'); + $this->assertRaw('', 'Page markup was found.'); + } + } diff --git a/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php b/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php index 1476e46de22..e6c5c9eb2ca 100644 --- a/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php +++ b/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php @@ -1,11 +1,16 @@ add('router_test_1', $route); + $route = new Route('router_test/test2', array( + '_content' => '\Drupal\router_test\TestControllers::test2' + )); + $collection->add('router_test_2', $route); + return $collection; }