Skip to content

Commit

Permalink
add redirect to locale-prefix for partial match requests
Browse files Browse the repository at this point in the history
  • Loading branch information
wachterjohannes authored and alexander-schranz committed Sep 18, 2019
1 parent 9bb2ec3 commit dea9b71
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 31 deletions.
29 changes: 29 additions & 0 deletions UPGRADE.md
@@ -1,5 +1,34 @@
# Upgrade

## master

### RouteProvider

The method `Sulu\Bundle\RouteBundle\Routing\RouteProvider::__construct` has removed the second parameter.

__Before:__

```
public function __construct(
RouteRepositoryInterface $routeRepository,
RequestAnalyzerInterface $requestAnalyzer,
RouteDefaultsProviderInterface $routeDefaultsProvider,
RequestStack $requestStack,
LazyLoadingValueHolderFactory $proxyFactory = null
)
```

__After:__

```
public function __construct(
RouteRepositoryInterface $routeRepository,
RouteDefaultsProviderInterface $routeDefaultsProvider,
RequestStack $requestStack,
LazyLoadingValueHolderFactory $proxyFactory = null
)
```

## 1.6.24

### Collection Repository count function changed
Expand Down
1 change: 0 additions & 1 deletion src/Sulu/Bundle/RouteBundle/Resources/config/routing.xml
Expand Up @@ -20,7 +20,6 @@

<service id="sulu_route.routing.provider" class="Sulu\Bundle\RouteBundle\Routing\RouteProvider">
<argument type="service" id="sulu.repository.route"/>
<argument type="service" id="sulu_core.webspace.request_analyzer"/>
<argument type="service" id="sulu_route.routing.defaults_provider"/>
<argument type="service" id="request_stack"/>
<argument type="service" id="sulu_route.routing.proxy_factory"/>
Expand Down
48 changes: 29 additions & 19 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 All @@ -38,11 +39,6 @@ class RouteProvider implements RouteProviderInterface
*/
private $routeRepository;

/**
* @var RequestAnalyzerInterface
*/
private $requestAnalyzer;

/**
* @var RouteDefaultsProviderInterface
*/
Expand All @@ -68,22 +64,13 @@ 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,
RouteDefaultsProviderInterface $routeDefaultsProvider,
RequestStack $requestStack,
LazyLoadingValueHolderFactory $proxyFactory = null
) {
$this->routeRepository = $routeRepository;
$this->requestAnalyzer = $requestAnalyzer;
$this->routeDefaultsProvider = $routeDefaultsProvider;
$this->requestStack = $requestStack;

Expand All @@ -98,7 +85,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 +134,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 +166,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 +193,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 +212,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 +222,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
106 changes: 95 additions & 11 deletions src/Sulu/Bundle/RouteBundle/Tests/Unit/Routing/RouteProviderTest.php
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 All @@ -31,11 +33,6 @@ class RouteProviderTest extends \PHPUnit_Framework_TestCase
*/
private $routeRepository;

/**
* @var RequestAnalyzerInterface
*/
private $requestAnalyzer;

/**
* @var RouteDefaultsProviderInterface
*/
Expand All @@ -49,15 +46,11 @@ class RouteProviderTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->routeRepository = $this->prophesize(RouteRepositoryInterface::class);
$this->requestAnalyzer = $this->prophesize(RequestAnalyzerInterface::class);
$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(),
$this->defaultsProvider->reveal(),
$this->requestStack->reveal()
);
Expand All @@ -70,20 +63,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 +128,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 +158,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 +193,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 +228,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 +263,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 +297,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 +341,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 +387,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 +422,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 +440,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

0 comments on commit dea9b71

Please sign in to comment.