Introduce a default controller for pages with a _content request attribute.
parent
0bd8eed2cc
commit
b9d5689987
|
@ -82,6 +82,7 @@ class CoreBundle extends Bundle
|
||||||
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\FinishResponseSubscriber());
|
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\FinishResponseSubscriber());
|
||||||
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RequestCloseSubscriber());
|
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RequestCloseSubscriber());
|
||||||
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber());
|
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber());
|
||||||
|
$dispatcher->addSubscriber(new \Drupal\Core\EventSubscriber\RouteProcessorSubscriber());
|
||||||
$container->set('content_negotiation', $content_negotation);
|
$container->set('content_negotiation', $content_negotation);
|
||||||
$dispatcher->addSubscriber(\Drupal\Core\ExceptionController::getExceptionListener($container));
|
$dispatcher->addSubscriber(\Drupal\Core\ExceptionController::getExceptionListener($container));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Definition of Drupal\Core\EventSubscriber\RouterListener.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\EventSubscriber;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
|
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||||
|
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drupal-specific Router listener.
|
||||||
|
*
|
||||||
|
* This is the bridge from the kernel to the UrlMatcher.
|
||||||
|
*/
|
||||||
|
class RouteProcessorSubscriber implements EventSubscriberInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Matcher object for this listener.
|
||||||
|
*
|
||||||
|
* This property is private in the base class, so we have to hack around it.
|
||||||
|
*
|
||||||
|
* @var Symfony\Component\Router\Matcher\UrlMatcherInterface
|
||||||
|
*/
|
||||||
|
protected $urlMatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Logging object for this listener.
|
||||||
|
*
|
||||||
|
* This property is private in the base class, so we have to hack around it.
|
||||||
|
*
|
||||||
|
* @var Symfony\Component\HttpKernel\Log\LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a default controller for a route if one was not specified.
|
||||||
|
*/
|
||||||
|
public function onRequestSetController(GetResponseEvent $event) {
|
||||||
|
$request = $event->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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Core;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
|
||||||
|
class HtmlPageController {
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -25,9 +25,21 @@ class RouterTest extends WebTestBase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirms that the router can get to a controller.
|
||||||
|
*/
|
||||||
public function testCanRoute() {
|
public function testCanRoute() {
|
||||||
$this->drupalGet('router_test/test1');
|
$this->drupalGet('router_test/test1');
|
||||||
$this->assertRaw('test1', 'The correct string was returned because the route was successful.');
|
$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('</html>', 'Page markup was found.');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Definition of Drupal\router_test\TestControllers.
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Drupal\router_test;
|
namespace Drupal\router_test;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of TestControllers
|
* Controller routines for testing the routing system.
|
||||||
*/
|
*/
|
||||||
class TestControllers {
|
class TestControllers {
|
||||||
|
|
||||||
|
@ -13,5 +18,9 @@ class TestControllers {
|
||||||
return new Response('test1');
|
return new Response('test1');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test2() {
|
||||||
|
return "test2";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_router_info().
|
||||||
|
*/
|
||||||
function router_test_route_info() {
|
function router_test_route_info() {
|
||||||
$collection = new RouteCollection();
|
$collection = new RouteCollection();
|
||||||
|
|
||||||
|
@ -11,5 +14,10 @@ function router_test_route_info() {
|
||||||
));
|
));
|
||||||
$collection->add('router_test_1', $route);
|
$collection->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;
|
return $collection;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue