Skip to content

Commit ab47aab

Browse files
authored
Merge pull request #251 from symfony-cmf/provider-based-generator
have provider based generator support new mode too
2 parents d400fe5 + b54577b commit ab47aab

5 files changed

+67
-18
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
=========
33

4+
2.3.1
5+
-----
6+
7+
* ProviderBasedGenerator now also supports the `RouteObjectInterface::OBJECT_BASED_ROUTE_NAME`
8+
and `RouteObjectInterface::ROUTE_OBJECT`.
9+
410
2.3.0
511
-----
612

src/ContentAwareGenerator.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ public function generate($name, $parameters = [], $absolute = UrlGeneratorInterf
8080

8181
$route = $this->getBestLocaleRoute($name, $parameters);
8282
} elseif (RouteObjectInterface::OBJECT_BASED_ROUTE_NAME === $name) {
83-
if (array_key_exists(RouteObjectInterface::ROUTE_OBJECT, $parameters) && $parameters[RouteObjectInterface::ROUTE_OBJECT] instanceof SymfonyRoute) {
83+
if (array_key_exists(RouteObjectInterface::ROUTE_OBJECT, $parameters)
84+
&& $parameters[RouteObjectInterface::ROUTE_OBJECT] instanceof SymfonyRoute
85+
) {
8486
$route = $this->getBestLocaleRoute($parameters[RouteObjectInterface::ROUTE_OBJECT], $parameters);
8587
} else {
8688
$route = $this->getRouteByContent($name, $parameters);
@@ -98,8 +100,9 @@ public function generate($name, $parameters = [], $absolute = UrlGeneratorInterf
98100
}
99101

100102
$this->unsetLocaleIfNotNeeded($route, $parameters);
103+
$parameters[RouteObjectInterface::ROUTE_OBJECT] = $route;
101104

102-
return parent::generate($route, $parameters, $absolute);
105+
return parent::generate(RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, $parameters, $absolute);
103106
}
104107

105108
/**

src/ProviderBasedGenerator.php

+16
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,27 @@ public function __construct(RouteProviderInterface $provider, LoggerInterface $l
4444

4545
/**
4646
* {@inheritdoc}
47+
*
48+
* The CMF routing system used to allow to pass route objects as $name to generate the route.
49+
* Since Symfony 5.0, the UrlGeneratorInterface declares $name as string. We widen the contract
50+
* for BC but deprecate passing non-strings.
51+
* Instead, Pass the RouteObjectInterface::OBJECT_BASED_ROUTE_NAME as route name and the object
52+
* in the parameters with key RouteObjectInterface::ROUTE_OBJECT.
53+
*
54+
* @param mixed $name
4755
*/
4856
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
4957
{
58+
if (is_object($name)) {
59+
@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);
60+
}
5061
if ($name instanceof SymfonyRoute) {
5162
$route = $name;
63+
} elseif (RouteObjectInterface::OBJECT_BASED_ROUTE_NAME === $name
64+
&& array_key_exists(RouteObjectInterface::ROUTE_OBJECT, $parameters)
65+
&& $parameters[RouteObjectInterface::ROUTE_OBJECT] instanceof SymfonyRoute
66+
) {
67+
$route = $parameters[RouteObjectInterface::ROUTE_OBJECT];
5268
} elseif (null === $route = $this->provider->getRouteByName($name)) {
5369
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name));
5470
}

tests/Unit/Routing/ContentAwareGeneratorTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class ContentAwareGeneratorTest extends TestCase
5757
*/
5858
private $context;
5959

60-
public function setUp()
60+
public function setUp(): void
6161
{
6262
$this->contentDocument = $this->createMock(RouteReferrersReadInterface::class);
6363
$this->routeDocument = $this->getMockBuilder(RouteMock::class)

tests/Unit/Routing/ProviderBasedGeneratorTest.php

+39-15
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class ProviderBasedGeneratorTest extends TestCase
4949
*/
5050
private $context;
5151

52-
public function setUp()
52+
public function setUp(): void
5353
{
5454
$this->routeDocument = $this->createMock(Route::class);
5555
$this->routeCompiled = $this->createMock(CompiledRoute::class);
@@ -59,58 +59,79 @@ public function setUp()
5959
$this->generator = new TestableProviderBasedGenerator($this->provider);
6060
}
6161

62-
public function testGenerateFromName()
62+
public function testGenerateFromName(): void
6363
{
6464
$name = 'foo/bar';
6565

6666
$this->provider->expects($this->once())
6767
->method('getRouteByName')
6868
->with($name)
69-
->will($this->returnValue($this->routeDocument))
69+
->willReturn($this->routeDocument)
7070
;
7171
$this->routeDocument->expects($this->once())
7272
->method('compile')
73-
->will($this->returnValue($this->routeCompiled))
73+
->willReturn($this->routeCompiled)
7474
;
7575

7676
$this->assertEquals('result_url', $this->generator->generate($name));
7777
}
7878

79-
public function testGenerateNotFound()
79+
public function testGenerateNotFound(): void
8080
{
8181
$name = 'foo/bar';
8282

8383
$this->provider->expects($this->once())
8484
->method('getRouteByName')
8585
->with($name)
86-
->will($this->returnValue(null))
86+
->willReturn(null)
8787
;
8888

8989
$this->expectException(RouteNotFoundException::class);
9090
$this->generator->generate($name);
9191
}
9292

93-
public function testGenerateFromRoute()
93+
public function testGenerateFromRoute(): void
9494
{
9595
$this->provider->expects($this->never())
9696
->method('getRouteByName')
9797
;
9898
$this->routeDocument->expects($this->once())
9999
->method('compile')
100-
->will($this->returnValue($this->routeCompiled))
100+
->willReturn($this->routeCompiled)
101+
;
102+
103+
$url = $this->generator->generate(RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, [
104+
RouteObjectInterface::ROUTE_OBJECT => $this->routeDocument,
105+
]);
106+
$this->assertEquals('result_url', $url);
107+
}
108+
109+
/**
110+
* @group legacy
111+
*
112+
* @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`
113+
*/
114+
public function testGenerateFromRouteLegacy(): void
115+
{
116+
$this->provider->expects($this->never())
117+
->method('getRouteByName')
118+
;
119+
$this->routeDocument->expects($this->once())
120+
->method('compile')
121+
->willReturn($this->routeCompiled)
101122
;
102123

103124
$this->assertEquals('result_url', $this->generator->generate($this->routeDocument));
104125
}
105126

106-
public function testSupports()
127+
public function testSupports(): void
107128
{
108129
$this->assertTrue($this->generator->supports('foo/bar'));
109130
$this->assertTrue($this->generator->supports($this->routeDocument));
110131
$this->assertFalse($this->generator->supports($this));
111132
}
112133

113-
public function testGetRouteDebugMessage()
134+
public function testGetRouteDebugMessage(): void
114135
{
115136
$this->assertContains('/some/key', $this->generator->getRouteDebugMessage(new RouteObject()));
116137
$this->assertContains('/de/test', $this->generator->getRouteDebugMessage(new Route('/de/test')));
@@ -121,7 +142,7 @@ public function testGetRouteDebugMessage()
121142
/**
122143
* Tests the generate method with passing in a route object into generate().
123144
*/
124-
public function testGenerateByRoute()
145+
public function testGenerateByRoute(): void
125146
{
126147
$this->generator = new ProviderBasedGenerator($this->provider);
127148

@@ -137,7 +158,10 @@ public function testGenerateByRoute()
137158
$this->generator->setContext($context);
138159

139160
$this->expectException(InvalidParameterException::class);
140-
$this->generator->generate($route, ['number' => 'string']);
161+
$this->generator->generate(RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, [
162+
RouteObjectInterface::ROUTE_OBJECT => $route,
163+
'number' => 'string',
164+
]);
141165
}
142166
}
143167

@@ -154,13 +178,13 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
154178

155179
class RouteObject implements RouteObjectInterface
156180
{
157-
public function getRouteKey()
181+
public function getRouteKey(): string
158182
{
159183
return '/some/key';
160184
}
161185

162-
public function getContent()
186+
public function getContent(): ?object
163187
{
164-
return;
188+
return null;
165189
}
166190
}

0 commit comments

Comments
 (0)