Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add redirect to locale-prefix for partial match requests #4672

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 29 additions & 12 deletions src/Sulu/Bundle/RouteBundle/Routing/RouteProvider.php
Expand Up @@ -18,6 +18,7 @@
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface;
use Sulu\Bundle\RouteBundle\Model\RouteInterface;
use Sulu\Bundle\RouteBundle\Routing\Defaults\RouteDefaultsProviderInterface;
use Sulu\Component\Webspace\Analyzer\Attributes\RequestAttributes;
use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
use Symfony\Cmf\Component\Routing\RouteProviderInterface;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -68,13 +69,6 @@ class RouteProvider implements RouteProviderInterface
*/
private $routeCache = [];

/**
* @param RouteRepositoryInterface $routeRepository
* @param RequestAnalyzerInterface $requestAnalyzer
* @param RouteDefaultsProviderInterface $routeDefaultsProvider
* @param RequestStack $requestStack
* @param LazyLoadingValueHolderFactory $proxyFactory
*/
public function __construct(
RouteRepositoryInterface $routeRepository,
RequestAnalyzerInterface $requestAnalyzer,
Expand All @@ -98,7 +92,22 @@ public function getRouteCollectionForRequest(Request $request)
$path = $this->decodePathInfo($request->getPathInfo());

$collection = new RouteCollection();
$prefix = $this->requestAnalyzer->getResourceLocatorPrefix();
$path = $this->decodePathInfo($request->getPathInfo());

/** @var RequestAttributes|null $attributes */
$attributes = $request->attributes->get('_sulu');
if (!$attributes) {
return $collection;
}

$matchType = $attributes->getAttribute('matchType');
if (RequestAnalyzerInterface::MATCH_TYPE_REDIRECT == $matchType
|| RequestAnalyzerInterface::MATCH_TYPE_PARTIAL == $matchType
) {
return $collection;
}

$prefix = $attributes->getAttribute('resourceLocatorPrefix');

if (!empty($prefix) && 0 === strpos($path, $prefix)) {
$path = PathHelper::relativizePath($path, $prefix);
Expand Down Expand Up @@ -132,7 +141,7 @@ public function getRouteCollectionForRequest(Request $request)
return $collection;
}

$collection->add(self::ROUTE_PREFIX . $route->getId(), $this->createRoute($route, $request));
$collection->add(self::ROUTE_PREFIX . $route->getId(), $this->createRoute($route, $request, $attributes));

return $collection;
}
Expand Down Expand Up @@ -164,6 +173,14 @@ public function getRouteByName($name)
throw new RouteNotFoundException();
}

$request = $this->requestStack->getCurrentRequest();

/** @var RequestAttributes $attributes */
$attributes = $request->attributes->get('_sulu');
if (!$attributes) {
throw new RouteNotFoundException();
}

$routeId = substr($name, strlen(self::ROUTE_PREFIX));
if (array_key_exists($routeId, $this->symfonyRouteCache)) {
return $this->symfonyRouteCache[$routeId];
Expand All @@ -183,7 +200,7 @@ public function getRouteByName($name)
throw new RouteNotFoundException();
}

return $this->createRoute($route, $this->requestStack->getCurrentRequest());
return $this->createRoute($route, $request, $attributes);
}

/**
Expand All @@ -202,7 +219,7 @@ public function getRoutesByNames($names)
*
* @return Route
*/
protected function createRoute(RouteInterface $route, Request $request)
protected function createRoute(RouteInterface $route, Request $request, RequestAttributes $attributes)
{
$routePath = $this->decodePathInfo($request->getPathInfo());

Expand All @@ -212,7 +229,7 @@ protected function createRoute(RouteInterface $route, Request $request)
[
'_controller' => 'SuluWebsiteBundle:Redirect:redirect',
'url' => $request->getSchemeAndHttpHost()
. $this->requestAnalyzer->getResourceLocatorPrefix()
. $attributes->getAttribute('resourceLocatorPrefix')
. $route->getTarget()->getPath()
. ($request->getQueryString() ? ('?' . $request->getQueryString()) : ''),
]
Expand Down
Expand Up @@ -9,13 +9,15 @@
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\SuluBundle\Tests\Unit\Routing;
namespace Sulu\Bundle\RouteBundle\Tests\Unit\Routing;

use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface;
use Sulu\Bundle\RouteBundle\Model\RouteInterface;
use Sulu\Bundle\RouteBundle\Routing\Defaults\RouteDefaultsProviderInterface;
use Sulu\Bundle\RouteBundle\Routing\RouteProvider;
use Sulu\Component\Webspace\Analyzer\Attributes\RequestAttributes;
use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

Expand Down Expand Up @@ -53,8 +55,6 @@ protected function setUp()
$this->defaultsProvider = $this->prophesize(RouteDefaultsProviderInterface::class);
$this->requestStack = $this->prophesize(RequestStack::class);

$this->requestAnalyzer->getResourceLocatorPrefix()->willReturn('/de');

$this->routeProvider = new RouteProvider(
$this->routeRepository->reveal(),
$this->requestAnalyzer->reveal(),
Expand All @@ -70,20 +70,51 @@ public function testGetRouteCollectionForRequestNoRoute()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$this->routeRepository->findByPath('/test', 'de')->willReturn(null);

$collection = $this->routeProvider->getRouteCollectionForRequest($request->reveal());

$this->assertCount(0, $collection);
}

public function testGetRouteCollectionForRequestNoFullMatch()
{
$request = $this->prophesize(Request::class);
$request->getPathInfo()->willReturn('/test');
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_PARTIAL);

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$this->routeRepository->findByPath('/test', 'de')->shouldNotBeCalled();

$collection = $this->routeProvider->getRouteCollectionForRequest($request->reveal());

$this->assertCount(0, $collection);
}

public function testGetRouteCollectionForRequestNoSupport()
{
$request = $this->prophesize(Request::class);
$request->getPathInfo()->willReturn('/de/test');
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getId()->willReturn(1);
$routeEntity->getEntityClass()->willReturn('Example');
Expand All @@ -104,6 +135,12 @@ public function testGetRouteCollectionForRequestUnpublished()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
$routeEntity->getEntityId()->willReturn('1');
Expand All @@ -128,6 +165,12 @@ public function testGetRouteCollectionForRequest()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
$routeEntity->getEntityId()->willReturn('1');
Expand Down Expand Up @@ -157,6 +200,12 @@ public function testGetRouteCollectionForRequestWithFormat()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('json');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
$routeEntity->getEntityId()->willReturn('1');
Expand Down Expand Up @@ -186,6 +235,12 @@ public function testGetRouteCollectionForRequestWithUmlauts()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
$routeEntity->getEntityId()->willReturn('1');
Expand Down Expand Up @@ -215,6 +270,12 @@ public function testGetRouteCollectionForRequestTwice()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
$routeEntity->getEntityId()->willReturn('1');
Expand Down Expand Up @@ -243,10 +304,17 @@ public function testGetRouteCollectionForRequestWithHistory()
$request = $this->prophesize(Request::class);
$request->getPathInfo()->willReturn('/de/test');
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');
$request->getQueryString()->willReturn('test=1');
$request->getSchemeAndHttpHost()->willReturn('http://www.sulu.io');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$targetEntity = $this->prophesize(RouteInterface::class);
$targetEntity->getPath()->willReturn('/test-2');

Expand Down Expand Up @@ -280,10 +348,17 @@ public function testGetRouteCollectionForRequestWithHistoryWithoutQueryString()
$request = $this->prophesize(Request::class);
$request->getPathInfo()->willReturn('/de/test');
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');
$request->getQueryString()->willReturn(null);
$request->getSchemeAndHttpHost()->willReturn('http://www.sulu.io');
$request->getRequestFormat()->willReturn('html');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$targetEntity = $this->prophesize(RouteInterface::class);
$targetEntity->getPath()->willReturn('/test-2');

Expand Down Expand Up @@ -319,7 +394,11 @@ public function testGetRouteCollectionForRequestNoPrefix()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('html');

$this->requestAnalyzer->getResourceLocatorPrefix()->willReturn(null);
$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn(null);

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
Expand Down Expand Up @@ -350,6 +429,12 @@ public function testGetRouteCollectionForRequestEndingDot()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn(null);

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$collection = $this->routeProvider->getRouteCollectionForRequest($request->reveal());

$this->assertCount(0, $collection);
Expand All @@ -362,6 +447,12 @@ public function testGetRouteCollectionForRequestWithoutFormatExtension()
$request->getLocale()->willReturn('de');
$request->getRequestFormat()->willReturn('json');

$attributes = $this->prophesize(RequestAttributes::class);
$attributes->getAttribute('matchType')->willReturn(RequestAnalyzerInterface::MATCH_TYPE_FULL);
$attributes->getAttribute('resourceLocatorPrefix')->willReturn('/de');

$request->reveal()->attributes = new ParameterBag(['_sulu' => $attributes->reveal()]);

$routeEntity = $this->prophesize(RouteInterface::class);
$routeEntity->getEntityClass()->willReturn('Example');
$routeEntity->getEntityId()->willReturn('1');
Expand Down