From b54577be5f9dc2020c59028e092809fa77a683ce Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Mon, 4 May 2020 09:19:27 +0200 Subject: [PATCH] have provider based generator support new mode too --- CHANGELOG.md | 6 +++ src/ContentAwareGenerator.php | 7 ++- src/ProviderBasedGenerator.php | 16 ++++++ .../Routing/ContentAwareGeneratorTest.php | 2 +- .../Routing/ProviderBasedGeneratorTest.php | 54 +++++++++++++------ 5 files changed, 67 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aac044c..1493696c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Changelog ========= +2.3.1 +----- + +* ProviderBasedGenerator now also supports the `RouteObjectInterface::OBJECT_BASED_ROUTE_NAME` + and `RouteObjectInterface::ROUTE_OBJECT`. + 2.3.0 ----- diff --git a/src/ContentAwareGenerator.php b/src/ContentAwareGenerator.php index 2adb8582..f0f95881 100644 --- a/src/ContentAwareGenerator.php +++ b/src/ContentAwareGenerator.php @@ -80,7 +80,9 @@ public function generate($name, $parameters = [], $absolute = UrlGeneratorInterf $route = $this->getBestLocaleRoute($name, $parameters); } elseif (RouteObjectInterface::OBJECT_BASED_ROUTE_NAME === $name) { - if (array_key_exists(RouteObjectInterface::ROUTE_OBJECT, $parameters) && $parameters[RouteObjectInterface::ROUTE_OBJECT] instanceof SymfonyRoute) { + if (array_key_exists(RouteObjectInterface::ROUTE_OBJECT, $parameters) + && $parameters[RouteObjectInterface::ROUTE_OBJECT] instanceof SymfonyRoute + ) { $route = $this->getBestLocaleRoute($parameters[RouteObjectInterface::ROUTE_OBJECT], $parameters); } else { $route = $this->getRouteByContent($name, $parameters); @@ -98,8 +100,9 @@ public function generate($name, $parameters = [], $absolute = UrlGeneratorInterf } $this->unsetLocaleIfNotNeeded($route, $parameters); + $parameters[RouteObjectInterface::ROUTE_OBJECT] = $route; - return parent::generate($route, $parameters, $absolute); + return parent::generate(RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, $parameters, $absolute); } /** diff --git a/src/ProviderBasedGenerator.php b/src/ProviderBasedGenerator.php index b850c7d2..05a56a9d 100644 --- a/src/ProviderBasedGenerator.php +++ b/src/ProviderBasedGenerator.php @@ -44,11 +44,27 @@ public function __construct(RouteProviderInterface $provider, LoggerInterface $l /** * {@inheritdoc} + * + * The CMF routing system used to allow to pass route objects as $name to generate the route. + * Since Symfony 5.0, the UrlGeneratorInterface declares $name as string. We widen the contract + * for BC but deprecate passing non-strings. + * Instead, Pass the RouteObjectInterface::OBJECT_BASED_ROUTE_NAME as route name and the object + * in the parameters with key RouteObjectInterface::ROUTE_OBJECT. + * + * @param mixed $name */ public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) { + if (is_object($name)) { + @trigger_error('Passing an object as route name is deprecated since version 2.3. Pass the `RouteObjectInterface::OBJECT_BASED_ROUTE_NAME` as route name and the object in the parameters with key `RouteObjectInterface::ROUTE_OBJECT`', E_USER_DEPRECATED); + } if ($name instanceof SymfonyRoute) { $route = $name; + } elseif (RouteObjectInterface::OBJECT_BASED_ROUTE_NAME === $name + && array_key_exists(RouteObjectInterface::ROUTE_OBJECT, $parameters) + && $parameters[RouteObjectInterface::ROUTE_OBJECT] instanceof SymfonyRoute + ) { + $route = $parameters[RouteObjectInterface::ROUTE_OBJECT]; } elseif (null === $route = $this->provider->getRouteByName($name)) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); } diff --git a/tests/Unit/Routing/ContentAwareGeneratorTest.php b/tests/Unit/Routing/ContentAwareGeneratorTest.php index ea90f855..9882449a 100644 --- a/tests/Unit/Routing/ContentAwareGeneratorTest.php +++ b/tests/Unit/Routing/ContentAwareGeneratorTest.php @@ -57,7 +57,7 @@ class ContentAwareGeneratorTest extends TestCase */ private $context; - public function setUp() + public function setUp(): void { $this->contentDocument = $this->createMock(RouteReferrersReadInterface::class); $this->routeDocument = $this->getMockBuilder(RouteMock::class) diff --git a/tests/Unit/Routing/ProviderBasedGeneratorTest.php b/tests/Unit/Routing/ProviderBasedGeneratorTest.php index aa4c0cd1..529ffea7 100644 --- a/tests/Unit/Routing/ProviderBasedGeneratorTest.php +++ b/tests/Unit/Routing/ProviderBasedGeneratorTest.php @@ -49,7 +49,7 @@ class ProviderBasedGeneratorTest extends TestCase */ private $context; - public function setUp() + public function setUp(): void { $this->routeDocument = $this->createMock(Route::class); $this->routeCompiled = $this->createMock(CompiledRoute::class); @@ -59,58 +59,79 @@ public function setUp() $this->generator = new TestableProviderBasedGenerator($this->provider); } - public function testGenerateFromName() + public function testGenerateFromName(): void { $name = 'foo/bar'; $this->provider->expects($this->once()) ->method('getRouteByName') ->with($name) - ->will($this->returnValue($this->routeDocument)) + ->willReturn($this->routeDocument) ; $this->routeDocument->expects($this->once()) ->method('compile') - ->will($this->returnValue($this->routeCompiled)) + ->willReturn($this->routeCompiled) ; $this->assertEquals('result_url', $this->generator->generate($name)); } - public function testGenerateNotFound() + public function testGenerateNotFound(): void { $name = 'foo/bar'; $this->provider->expects($this->once()) ->method('getRouteByName') ->with($name) - ->will($this->returnValue(null)) + ->willReturn(null) ; $this->expectException(RouteNotFoundException::class); $this->generator->generate($name); } - public function testGenerateFromRoute() + public function testGenerateFromRoute(): void { $this->provider->expects($this->never()) ->method('getRouteByName') ; $this->routeDocument->expects($this->once()) ->method('compile') - ->will($this->returnValue($this->routeCompiled)) + ->willReturn($this->routeCompiled) + ; + + $url = $this->generator->generate(RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, [ + RouteObjectInterface::ROUTE_OBJECT => $this->routeDocument, + ]); + $this->assertEquals('result_url', $url); + } + + /** + * @group legacy + * + * @expectedDeprecation Passing an object as route name is deprecated since version 2.3. Pass the `RouteObjectInterface::OBJECT_BASED_ROUTE_NAME` as route name and the object in the parameters with key `RouteObjectInterface::ROUTE_OBJECT` + */ + public function testGenerateFromRouteLegacy(): void + { + $this->provider->expects($this->never()) + ->method('getRouteByName') + ; + $this->routeDocument->expects($this->once()) + ->method('compile') + ->willReturn($this->routeCompiled) ; $this->assertEquals('result_url', $this->generator->generate($this->routeDocument)); } - public function testSupports() + public function testSupports(): void { $this->assertTrue($this->generator->supports('foo/bar')); $this->assertTrue($this->generator->supports($this->routeDocument)); $this->assertFalse($this->generator->supports($this)); } - public function testGetRouteDebugMessage() + public function testGetRouteDebugMessage(): void { $this->assertContains('/some/key', $this->generator->getRouteDebugMessage(new RouteObject())); $this->assertContains('/de/test', $this->generator->getRouteDebugMessage(new Route('/de/test'))); @@ -121,7 +142,7 @@ public function testGetRouteDebugMessage() /** * Tests the generate method with passing in a route object into generate(). */ - public function testGenerateByRoute() + public function testGenerateByRoute(): void { $this->generator = new ProviderBasedGenerator($this->provider); @@ -137,7 +158,10 @@ public function testGenerateByRoute() $this->generator->setContext($context); $this->expectException(InvalidParameterException::class); - $this->generator->generate($route, ['number' => 'string']); + $this->generator->generate(RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, [ + RouteObjectInterface::ROUTE_OBJECT => $route, + 'number' => 'string', + ]); } } @@ -154,13 +178,13 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa class RouteObject implements RouteObjectInterface { - public function getRouteKey() + public function getRouteKey(): string { return '/some/key'; } - public function getContent() + public function getContent(): ?object { - return; + return null; } }