Commit 99b39dc7 authored by alexpott's avatar alexpott

Issue #1963470 by effulgentsia, Crell, tim.plunkett, larowlan: Move controller...

Issue #1963470 by effulgentsia, Crell, tim.plunkett, larowlan: Move controller derivation to route enhancers (and just that).
parent c5d0a8ef
......@@ -257,11 +257,22 @@ services:
tags:
- { name: event_subscriber }
arguments: ['@settings']
router_processor_subscriber:
class: Drupal\Core\EventSubscriber\RouteProcessorSubscriber
route_enhancer.ajax:
class: Drupal\Core\Routing\Enhancer\AjaxEnhancer
arguments: ['@content_negotiation']
tags:
- { name: event_subscriber }
- { name: route_enhancer, priority: 20 }
- { name: legacy_route_enhancer, priority: 20 }
route_enhancer.form:
class: Drupal\Core\Routing\Enhancer\FormEnhancer
arguments: ['@content_negotiation']
tags:
- { name: route_enhancer, priority: 10 }
route_enhancer.page:
class: Drupal\Core\Routing\Enhancer\PageEnhancer
arguments: ['@content_negotiation']
tags:
- { name: route_enhancer, priority: 0 }
router_listener:
class: Symfony\Component\HttpKernel\EventListener\RouterListener
tags:
......
......@@ -28,11 +28,15 @@ public function process(ContainerBuilder $container) {
}
$router = $container->getDefinition('router.dynamic');
$services = array();
foreach ($container->findTaggedServiceIds('route_enhancer') as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$router->addMethodCall('addRouteEnhancer', array(new Reference($id), $priority));
}
$legacy_router = $container->getDefinition('legacy_router');
foreach ($container->findTaggedServiceIds('legacy_route_enhancer') as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$legacy_router->addMethodCall('addRouteEnhancer', array(new Reference($id), $priority));
}
}
}
<?php
/**
* @file
* Definition of Drupal\Core\EventSubscriber\RouteProcessorSubscriber.
*/
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;
use Drupal\Core\ContentNegotiation;
/**
* Listener to process request controller information.
*/
class RouteProcessorSubscriber implements EventSubscriberInterface {
protected $negotiation;
public function __construct(ContentNegotiation $negotiation) {
$this->negotiation = $negotiation;
}
/**
* Sets a default controller for a route if one was not specified.
*
* @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* Event that is created to create a response for a request.
*/
public function onRequestSetController(GetResponseEvent $event) {
$request = $event->getRequest();
// @todo This should all get converted into one or more RouteEnhancers.
if (!$request->attributes->has('_content') && $this->negotiation->getContentType($request) == 'drupal_ajax') {
$request->attributes->set('_content', $request->attributes->get('_controller'));
$request->attributes->set('_controller', '\Drupal\Core\AjaxController::content');
}
elseif (!$request->attributes->has('_controller') && $this->negotiation->getContentType($request) === 'html') {
if ($request->attributes->has('_form')) {
$request->attributes->set('_controller', '\Drupal\Core\HtmlFormController::content');
}
elseif ($request->attributes->has('_content')) {
$request->attributes->set('_controller', '\Drupal\Core\HtmlPageController::content');
}
else {
throw new \InvalidArgumentException('No valid subcontroller key was found');
}
}
}
/**
* 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;
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Routing\Enhancer\AjaxEnhancer.
*/
namespace Drupal\Core\Routing\Enhancer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
use Drupal\Core\ContentNegotiation;
/**
* Enhances an ajax route with the appropriate controller.
*/
class AjaxEnhancer implements RouteEnhancerInterface {
/**
* Content negotiation library.
*
* @var \Drupal\CoreContentNegotiation
*/
protected $negotiation;
/**
* Constructs a new \Drupal\Core\Routing\Enhancer\AjaxEnhancer object.
*
* @param \Drupal\Core\ContentNegotiation $negotiation
* The Content Negotiation service.
*/
public function __construct(ContentNegotiation $negotiation) {
$this->negotiation = $negotiation;
}
/**
* {@inheritdoc}
*/
public function enhance(array $defaults, Request $request) {
if (empty($defaults['_content']) && $this->negotiation->getContentType($request) == 'drupal_ajax') {
$defaults['_content'] = $defaults['_controller'];
$defaults['_controller'] = '\Drupal\Core\AjaxController::content';
}
return $defaults;
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Routing\Enhancer\FormEnhancer.
*/
namespace Drupal\Core\Routing\Enhancer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
use Drupal\Core\ContentNegotiation;
/**
* Enhances a form route with the appropriate controller.
*/
class FormEnhancer implements RouteEnhancerInterface {
/**
* Content negotiation library.
*
* @var \Drupal\CoreContentNegotiation
*/
protected $negotiation;
/**
* Constructs a new \Drupal\Core\Routing\Enhancer\FormEnhancer object.
*
* @param \Drupal\Core\ContentNegotiation $negotiation
* The Content Negotiation service.
*/
public function __construct(ContentNegotiation $negotiation) {
$this->negotiation = $negotiation;
}
/**
* {@inhertdoc}
*/
public function enhance(array $defaults, Request $request) {
if (empty($defaults['_controller']) && !empty($defaults['_form']) && $this->negotiation->getContentType($request) === 'html') {
$defaults['_controller'] = '\Drupal\Core\HtmlFormController::content';
}
return $defaults;
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Routing\Enhancer\PageEnhancer.
*/
namespace Drupal\Core\Routing\Enhancer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
use Drupal\Core\ContentNegotiation;
/**
* Enhances a page route with the appropriate controller.
*/
class PageEnhancer implements RouteEnhancerInterface {
/**
* Content negotiation library.
*
* @var \Drupal\CoreContentNegotiation
*/
protected $negotiation;
/**
* Constructs a new \Drupal\Core\Routing\Enhancer\PageEnhancer object.
*
* @param \Drupal\Core\ContentNegotiation $negotiation
* The Content Negotiation service.
*/
public function __construct(ContentNegotiation $negotiation) {
$this->negotiation = $negotiation;
}
/**
* {@inheritdoc}
*/
public function enhance(array $defaults, Request $request) {
if (empty($defaults['_controller']) && !empty($defaults['_content']) && $this->negotiation->getContentType($request) === 'html') {
$defaults['_controller'] = '\Drupal\Core\HtmlPageController::content';
}
return $defaults;
}
}
......@@ -124,4 +124,41 @@ public function testDynamicRoutes() {
$this->assertResponse(200);
$this->assertRaw('test5', 'The correct string was returned because the route was successful.');
}
/**
* Checks that a request with text/html response gets rendered as a page.
*/
public function testControllerResolutionPage() {
$this->drupalGet('/router_test/test10');
$this->assertRaw('abcde', 'Correct body was found.');
// Confirm that the page wrapping is being added, so we're not getting a
// raw body returned.
$this->assertRaw('</html>', 'Page markup was found.');
// In some instances, the subrequest handling may get confused and render
// a page inception style. This test verifies that is not happening.
$this->assertNoPattern('#</body>.*</body>#s', 'There was no double-page effect from a misrendered subrequest.');
}
/**
* Checks that an ajax request gets rendered as an Ajax response, by mime.
*
* @todo This test will not work until the Ajax enhancer is corrected. However,
* that is dependent on fixes to the Ajax system. Re-enable this test once
* http://drupal.org/node/1938980 is fixed.
*/
/*
public function testControllerResolutionAjax() {
// This will fail with a JSON parse error if the request is not routed to
// The correct controller.
$this->drupalGetAJAX('/router_test/test10', array(), array('Accept: application/vnd.drupal-ajax'));
$this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/json', 'Correct mime content type was returned');
$this->assertRaw('abcde', 'Correct body was found.');
}
*/
}
<?php
/**
* @file
* Contains \Drupal\router_test\TestContent.
*/
namespace Drupal\router_test;
/**
* Test controllers that are intended to be wrapped in a main controller.
*/
class TestContent {
/**
* Provides example content for testing route enhancers.
*/
public function test1() {
return 'abcde';
}
}
......@@ -53,3 +53,10 @@ router_test_9:
requirements:
_permission: 'access test7'
_access_router_test: 'TRUE'
router_test_10:
pattern: '/router_test/test10'
defaults:
_content: '\Drupal\router_test\TestContent::test1'
requirements:
_access: 'TRUE'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment