From 69d0c1651dc92c6bf4c706b447532d9c34cbcc56 Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Thu, 9 Mar 2017 13:29:01 +0100 Subject: [PATCH] Fix EZP-26961: No X-Location-Id header in redirections When a content has been renamed, the redirection emitted by the UrlAliasRouter must contain the X-Location-Id header. This adds the location id as a request attribute when the redirect URLAlias is found, and adds the header to the Response in the RequestListener. --- .../EventListener/RequestEventListener.php | 7 +++++- .../RequestEventListenerTest.php | 23 +++++++++++++++++++ .../Tests/Routing/UrlAliasRouterTest.php | 1 + .../MVC/Symfony/Routing/UrlAliasRouter.php | 3 +++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/eZ/Bundle/EzPublishCoreBundle/EventListener/RequestEventListener.php b/eZ/Bundle/EzPublishCoreBundle/EventListener/RequestEventListener.php index df7610a3098..dc3b5013eab 100644 --- a/eZ/Bundle/EzPublishCoreBundle/EventListener/RequestEventListener.php +++ b/eZ/Bundle/EzPublishCoreBundle/EventListener/RequestEventListener.php @@ -124,10 +124,15 @@ public function onKernelRequestRedirect(GetResponseEvent $event) $semanticPathinfo = $siteaccess->matcher->analyseLink($semanticPathinfo); } + $headers = []; + if ($request->attributes->has('locationId')) { + $headers[ 'X-Location-Id'] = $request->attributes->get('locationId'); + } $event->setResponse( new RedirectResponse( $semanticPathinfo . ($queryString ? "?$queryString" : ''), - 301 + 301, + $headers ) ); $event->stopPropagation(); diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/EventListener/RequestEventListenerTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/EventListener/RequestEventListenerTest.php index 57c8a418dcb..9ed34e6de63 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Tests/EventListener/RequestEventListenerTest.php +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/EventListener/RequestEventListenerTest.php @@ -156,6 +156,29 @@ public function testOnKernelRequestRedirect() $this->assertTrue($event->isPropagationStopped()); } + public function testOnKernelRequestRedirectWithLocationId() + { + $queryParameters = array('some' => 'thing'); + $cookieParameters = array('cookie' => 'value'); + $request = Request::create('/test_sa/foo/bar', 'GET', $queryParameters, $cookieParameters); + $semanticPathinfo = '/foo/something'; + $request->attributes->set('semanticPathinfo', $semanticPathinfo); + $request->attributes->set('needsRedirect', true); + $request->attributes->set('locationId', 123); + $request->attributes->set('siteaccess', new SiteAccess()); + + $event = new GetResponseEvent($this->httpKernel, $request, HttpKernelInterface::MASTER_REQUEST); + $this->requestEventListener->onKernelRequestRedirect($event); + $this->assertTrue($event->hasResponse()); + /** @var RedirectResponse $response */ + $response = $event->getResponse(); + $this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response); + $this->assertSame("$semanticPathinfo?some=thing", $response->getTargetUrl()); + $this->assertSame(301, $response->getStatusCode()); + $this->assertEquals(123, $response->headers->get('X-Location-Id')); + $this->assertTrue($event->isPropagationStopped()); + } + public function testOnKernelRequestRedirectPrependSiteaccess() { $queryParameters = array('some' => 'thing'); diff --git a/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/UrlAliasRouterTest.php b/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/UrlAliasRouterTest.php index 02a26d46e2b..c4a1ae493ff 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/UrlAliasRouterTest.php +++ b/eZ/Bundle/EzPublishCoreBundle/Tests/Routing/UrlAliasRouterTest.php @@ -196,6 +196,7 @@ public function testMatchRequestLocationCaseRedirectWithRootLocation() $this->assertSame($locationId, $request->attributes->get('locationId')); $this->assertTrue($request->attributes->get('needsRedirect')); $this->assertSame($path, $request->attributes->get('semanticPathinfo')); + $this->assertSame($locationId, $request->attributes->get('locationId')); } public function testMatchRequestLocationCaseRedirectWithRootRootLocation() diff --git a/eZ/Publish/Core/MVC/Symfony/Routing/UrlAliasRouter.php b/eZ/Publish/Core/MVC/Symfony/Routing/UrlAliasRouter.php index 4b7232b357a..cf76cbb4737 100644 --- a/eZ/Publish/Core/MVC/Symfony/Routing/UrlAliasRouter.php +++ b/eZ/Publish/Core/MVC/Symfony/Routing/UrlAliasRouter.php @@ -156,6 +156,9 @@ public function matchRequest(Request $request) // Specify not to prepend siteaccess while redirecting when applicable since it would be already present (see UrlAliasGenerator::doGenerate()) $request->attributes->set('prependSiteaccessOnRedirect', false); } elseif ($this->needsCaseRedirect($urlAlias, $requestedPath, $pathPrefix)) { + if ($urlAlias->destination instanceof Location) { + $request->attributes->set('locationId', $urlAlias->destination->id); + } $request->attributes->set('semanticPathinfo', $this->removePathPrefix($urlAlias->path, $pathPrefix)); $request->attributes->set('needsRedirect', true); }