Skip to content

Commit 6c405a6

Browse files
committed
Merge pull request #1493 from FriendsOfSymfony/CHPICK
Backport #1438
2 parents ca30cfb + bb92239 commit 6c405a6

File tree

7 files changed

+87
-28
lines changed

7 files changed

+87
-28
lines changed

Routing/Loader/Reader/RestActionReader.php

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ public function read(RestRouteCollection $collection, \ReflectionMethod $method,
292292
$requirements = [];
293293
$options = [];
294294
$host = '';
295-
$condition = null;
295+
$versionCondition = $this->getVersionCondition();
296296

297297
$annotations = $this->readRouteAnnotation($method);
298298
if (!empty($annotations)) {
@@ -316,13 +316,13 @@ public function read(RestRouteCollection $collection, \ReflectionMethod $method,
316316
$defaults = array_merge($defaults, $annotation->getDefaults());
317317
$host = $annotation->getHost();
318318
$schemes = $annotation->getSchemes();
319-
$condition = $this->getCondition($method, $annotation);
319+
$combinedCondition = $this->combineConditions($versionCondition, $annotation->getCondition());
320320

321321
$this->includeFormatIfNeeded($path, $requirements);
322322

323323
// add route to collection
324324
$route = new Route(
325-
$path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition
325+
$path, $defaults, $requirements, $options, $host, $schemes, $methods, $combinedCondition
326326
);
327327
$this->addRoute($collection, $routeName, $route, $isCollection, $isInflectable, $annotation);
328328
}
@@ -333,39 +333,41 @@ public function read(RestRouteCollection $collection, \ReflectionMethod $method,
333333

334334
// add route to collection
335335
$route = new Route(
336-
$path, $defaults, $requirements, $options, $host, [], $methods, $condition
336+
$path, $defaults, $requirements, $options, $host, [], $methods, $versionCondition
337337
);
338338
$this->addRoute($collection, $routeName, $route, $isCollection, $isInflectable);
339339
}
340340
}
341341

342342
/**
343-
* Determine the Route condition by combining Route annotations with Version annotation.
344-
*
345-
* @param \ReflectionMethod $method
346-
* @param RouteAnnotation $annotation
343+
* @return string|null
344+
*/
345+
private function getVersionCondition()
346+
{
347+
if (empty($this->versions)) {
348+
return;
349+
}
350+
351+
return sprintf("request.attributes.get('version') in ['%s']", implode("', '", $this->versions));
352+
}
353+
354+
/**
355+
* @param string|null $conditionOne
356+
* @param string|null $conditionTwo
347357
*
348-
* @return string
358+
* @return string|null
349359
*/
350-
private function getCondition(\ReflectionMethod $method, RouteAnnotation $annotation)
360+
private function combineConditions($conditionOne, $conditionTwo)
351361
{
352-
$condition = $annotation->getCondition();
353-
354-
if (!empty($this->versions)) {
355-
$versionCondition = "request.attributes.get('version') == (";
356-
$first = true;
357-
foreach ($this->versions as $version) {
358-
if (!$first) {
359-
$versionCondition .= ' or ';
360-
}
361-
$versionCondition .= '\''.$version.'\'';
362-
$first = false;
363-
}
364-
$versionCondition .= ')';
365-
$condition = $condition ? '('.$condition.') and '.$versionCondition : $versionCondition;
362+
if (null === $conditionOne) {
363+
return $conditionTwo;
364+
}
365+
366+
if (null === $conditionTwo) {
367+
return $conditionOne;
366368
}
367369

368-
return $condition;
370+
return sprintf('(%s) and (%s)', $conditionOne, $conditionTwo);
369371
}
370372

371373
/**

Tests/Fixtures/Controller/AnnotatedVersionUserController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,8 @@ public function v1UserAction()
3737
public function conditionalUserAction()
3838
{
3939
}
40+
41+
public function v3UserAction()
42+
{
43+
}
4044
}

Tests/Fixtures/Etalon/annotated_version_controller.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ v1_user:
22
path: /users/v1.{_format}
33
controller: ::v1UserAction
44
methods: [GET]
5-
condition: "request.attributes.get('version') == ('v1' or 'v3')"
5+
condition: "request.attributes.get('version') in ['v1', 'v3']"
66

77
conditional_user:
88
path: /users/conditional.{_format}
99
controller: ::conditionalUserAction
1010
methods: [GET]
11-
condition: "(context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i') and request.attributes.get('version') == ('v1' or 'v3')"
11+
condition: "(request.attributes.get('version') in ['v1', 'v3']) and (context.getMethod() in ['GET', 'HEAD'] and request.headers.get('User-Agent') matches '/firefox/i')"
12+
13+
v3_user:
14+
path: /users/v3.{_format}
15+
controller: ::v3UserAction
16+
methods: [GET]
17+
condition: "request.attributes.get('version') in ['v1', 'v3']"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSRestBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FOS\RestBundle\Tests\Functional\Bundle\TestBundle\Controller;
13+
14+
use FOS\RestBundle\Controller\Annotations\Get;
15+
use FOS\RestBundle\Controller\Annotations\Version;
16+
use FOS\RestBundle\Controller\Annotations\View;
17+
18+
/**
19+
* @author Ener-Getick <[email protected]>
20+
*
21+
* @Version({"1.2"})
22+
*/
23+
class Version2Controller
24+
{
25+
/**
26+
* @View("TestBundle:Version:version.html.twig")
27+
* @Get(path="/version")
28+
*/
29+
public function versionAction($version)
30+
{
31+
return array('version' => 'test annotation');
32+
}
33+
}

Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ test_serializer_error_invalid_form:
1414
path: /serializer-error/invalid-form.{_format}
1515
defaults: { _controller: TestBundle:SerializerError:invalidForm }
1616

17+
# Must be defined before test_version
1718
test_version2:
19+
resource: FOS\RestBundle\Tests\Functional\Bundle\TestBundle\Controller\Version2Controller
20+
type: rest
21+
22+
test_version:
1823
path: /version
1924
defaults: { _controller: TestBundle:Version:version }
2025
requirements:

Tests/Functional/VersionTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ public function setUp()
2323
$this->client = $this->createClient(['test_case' => 'Version']);
2424
}
2525

26+
public function testVersionAnnotation()
27+
{
28+
$this->client->request(
29+
'GET',
30+
'/version?query_version=1.2'
31+
);
32+
$this->assertContains('test annotation', $this->client->getResponse()->getContent());
33+
}
34+
2635
public function testCustomHeaderVersion()
2736
{
2837
$this->client->request(

Tests/Routing/Loader/RestRouteLoaderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public function testAnnotatedVersionUserFixture()
173173
$etalonRoutes = $this->loadEtalonRoutesInfo('annotated_version_controller.yml');
174174

175175
$this->assertTrue($collection instanceof RestRouteCollection);
176-
$this->assertEquals(2, count($collection->all()));
176+
$this->assertEquals(3, count($collection->all()));
177177

178178
foreach ($etalonRoutes as $name => $params) {
179179
$route = $collection->get($name);

0 commit comments

Comments
 (0)