diff --git a/core/core.services.yml b/core/core.services.yml index e2939e907ef12881edb9fe831ba7631289953546..f330708af808b7bfba25eb616f68ceecc32f84d5 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -890,6 +890,11 @@ services: class: Drupal\Core\EventSubscriber\RouteMethodSubscriber tags: - { name: event_subscriber } + psr_response_view_subscriber: + class: Drupal\Core\EventSubscriber\PsrResponseSubscriber + arguments: ['@psr7.http_foundation_factory'] + tags: + - { name: event_subscriber } # Main content view subscriber plus the renderers it uses. main_content_view_subscriber: diff --git a/core/lib/Drupal/Core/EventSubscriber/PsrResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PsrResponseSubscriber.php new file mode 100644 index 0000000000000000000000000000000000000000..eb0818c873af83c9cb9640f6fc1e13e0c3b626a6 --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/PsrResponseSubscriber.php @@ -0,0 +1,62 @@ +httpFoundationFactory = $http_foundation_factory; + } + + /** + * Converts a PSR-7 response to a Symfony response. + * + * @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event + * The Event to process. + */ + public function onKernelView(GetResponseForControllerResultEvent $event) { + $controller_result = $event->getControllerResult(); + + if ($controller_result instanceof ResponseInterface) { + $event->setResponse($this->httpFoundationFactory->createResponse($controller_result)); + } + + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[KernelEvents::VIEW][] = ['onKernelView']; + return $events; + } + +} diff --git a/core/modules/system/src/Tests/Routing/RouterTest.php b/core/modules/system/src/Tests/Routing/RouterTest.php index b945676744f54b31485e36dfd6e13eda9c86c8d2..207049f2ad7282a50b92974aa29c0c120860f194 100644 --- a/core/modules/system/src/Tests/Routing/RouterTest.php +++ b/core/modules/system/src/Tests/Routing/RouterTest.php @@ -199,6 +199,15 @@ public function testRouterMatching() { $this->assertText('Route not matched.'); } + /** + * Tests that a PSR-7 response works. + */ + public function testRouterResponsePsr7() { + $this->drupalGet('/router_test/test23'); + $this->assertResponse(200); + $this->assertText('test23'); + } + /** * Tests the user account on the DIC. */ diff --git a/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml b/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml index 5debfc219c08ed961254a96ead4b39d0b89a86b5..36a70171c3109aad933ea36d55a5ce9f4091d531 100644 --- a/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml +++ b/core/modules/system/tests/modules/router_test_directory/router_test.routing.yml @@ -141,6 +141,13 @@ router_test.22: requirements: _role: 'anonymous' +router_test.23: + path: '/router_test/test23' + defaults: + _controller: '\Drupal\router_test\TestControllers::test23' + requirements: + _access: 'TRUE' + router_test.hierarchy_parent: path: '/menu-test/parent' defaults: diff --git a/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php b/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php index 614c9a85046e92d4949a0351769521a046bb00b4..f3ff517039de0a26df5056408eba7e666fac5c5e 100644 --- a/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php +++ b/core/modules/system/tests/modules/router_test_directory/src/TestControllers.php @@ -12,6 +12,8 @@ use Drupal\user\UserInterface; use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\HttpFoundation\Response; +use Zend\Diactoros\Response\HtmlResponse; + /** * Controller routines for testing the routing system. @@ -102,6 +104,10 @@ public function test21() { return new CacheableResponse('test21'); } + public function test23() { + return new HtmlResponse('test23'); + } + /** * Throws an exception. * diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/PsrResponseSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/PsrResponseSubscriberTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2e3552ef4e1f4b98f4fa788d242d7828b843c29a --- /dev/null +++ b/core/tests/Drupal/Tests/Core/EventSubscriber/PsrResponseSubscriberTest.php @@ -0,0 +1,99 @@ +getMock('Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface', [], [], '', NULL); + $factory + ->expects($this->any()) + ->method('createResponse') + ->willReturn($this->getMock('Symfony\Component\HttpFoundation\Response')); + + $this->httpFoundationFactoryMock = $factory; + + $this->psrResponseSubscriber = new PsrResponseSubscriber($this->httpFoundationFactoryMock); + } + + /** + * Tests altering and finished event. + * + * @covers ::onKernelView + */ + public function testConvertsControllerResult() { + $event = $this->createEventMock($this->getMock('Psr\Http\Message\ResponseInterface')); + $event + ->expects($this->once()) + ->method('setResponse') + ->with($this->isInstanceOf('Symfony\Component\HttpFoundation\Response')); + $this->psrResponseSubscriber->onKernelView($event); + } + + + /** + * Tests altering and finished event. + * + * @covers ::onKernelView + */ + public function testDoesNotConvertControllerResult() { + $event = $this->createEventMock([]); + $event + ->expects($this->never()) + ->method('setResponse'); + $this->psrResponseSubscriber->onKernelView($event); + $event = $this->createEventMock(NULL); + $event + ->expects($this->never()) + ->method('setResponse'); + $this->psrResponseSubscriber->onKernelView($event); + } + + /** + * Sets up an alias event that return $controllerResult. + * + * @param mixed $controller_result + * The return Object. + * + * @return \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent|\PHPUnit_Framework_MockObject_MockObject + * A mock object to test. + */ + protected function createEventMock($controller_result) { + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent', [], [], '', NULL); + $event + ->expects($this->once()) + ->method('getControllerResult') + ->willReturn($controller_result); + return $event; + } + +}