Skip to content

Commit d469bff

Browse files
committed
Merge pull request #640 from therealmikz/annotations-widening
Annotations widening
2 parents 40730c4 + db52ebc commit d469bff

File tree

7 files changed

+96
-18
lines changed

7 files changed

+96
-18
lines changed

Controller/Annotations/NoRoute.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/**
1515
* No Route annotation class
1616
* @Annotation
17-
* @Target("METHOD")
17+
* @Target({"METHOD","CLASS"})
1818
*/
1919
class NoRoute extends Route
2020
{

Controller/Annotations/QueryParam.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Represents a parameter that must be present in GET data.
1616
*
1717
* @Annotation
18-
* @Target("METHOD")
18+
* @Target({"CLASS", "METHOD"})
1919
* @author Alexander <[email protected]>
2020
*/
2121
class QueryParam extends Param

Request/ParamReader.php

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,19 @@ public function read(\ReflectionClass $reflection, $method)
4444
throw new \InvalidArgumentException(sprintf("Class '%s' has no method '%s' method.", $reflection->getName(), $method));
4545
}
4646

47-
return $this->getParamsFromMethod($reflection->getMethod($method));
47+
$methodParams = $this->getParamsFromMethod($reflection->getMethod($method));
48+
$classParams = $this->getParamsFromClass($reflection);
49+
return array_merge($methodParams, $classParams);
4850
}
49-
51+
5052
/**
51-
* {@inheritDoc}
53+
* Fetches parameters from provided annotation array (fetched from annotationReader)
54+
*
55+
* @param array $annotations
56+
* @return \FOS\RestBundle\Controller\Annotations\Param
5257
*/
53-
public function getParamsFromMethod(\ReflectionMethod $method)
58+
private function getParamsFromAnnotationArray(array $annotations)
5459
{
55-
$annotations = $this->annotationReader->getMethodAnnotations($method);
56-
5760
$params = array();
5861
foreach ($annotations as $annotation) {
5962
if ($annotation instanceof Param) {
@@ -63,4 +66,25 @@ public function getParamsFromMethod(\ReflectionMethod $method)
6366

6467
return $params;
6568
}
69+
70+
/**
71+
* {@inheritDoc}
72+
*/
73+
public function getParamsFromMethod(\ReflectionMethod $method)
74+
{
75+
$annotations = $this->annotationReader->getMethodAnnotations($method);
76+
77+
return $this->getParamsFromAnnotationArray($annotations);
78+
}
79+
80+
/**
81+
*
82+
* {@inheritDoc}
83+
*/
84+
public function getParamsFromClass(\ReflectionClass $class)
85+
{
86+
$annotations = $this->annotationReader->getClassAnnotations($class);
87+
88+
return $this->getParamsFromAnnotationArray($annotations);
89+
}
6690
}

Request/ParamReaderInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,12 @@ public function read(\ReflectionClass $reflection, $method);
3737
* @return array Param annotation objects of the method. Indexed by parameter name.
3838
*/
3939
public function getParamsFromMethod(\ReflectionMethod $method);
40+
41+
/**
42+
*
43+
* @param \ReflectionClass $class
44+
*
45+
* @return array Param annotation objects of the class. Indexed by parameter name.
46+
*/
47+
public function getParamsFromClass(\ReflectionClass $class);
4048
}

Routing/Loader/Reader/RestActionReader.php

100644100755
Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,16 @@ private function isMethodReadable(\ReflectionMethod $method)
235235
if ('_' === substr($method->getName(), 0, 1)) {
236236
return false;
237237
}
238-
239-
// if method has NoRoute annotation - skip
240-
if ($this->readMethodAnnotation($method, 'NoRoute')) {
238+
239+
$hasNoRouteMethod = (bool) $this->readMethodAnnotation($method, 'NoRoute');
240+
$hasNoRouteClass = (bool) $this->readClassAnnotation($method->getDeclaringClass(), 'NoRoute');
241+
242+
$hasNoRoute = $hasNoRoute = $hasNoRouteMethod || $hasNoRouteClass;
243+
// since NoRoute extends Route we need to exclude all the method NoRoute annotations
244+
$hasRoute = (bool) $this->readMethodAnnotation($method, 'Route') && !$hasNoRouteMethod;
245+
246+
// if method has NoRoute annotation and does not have Route annotation - skip
247+
if ($hasNoRoute && !$hasRoute) {
241248
return false;
242249
}
243250

@@ -426,6 +433,23 @@ private function readRouteAnnotation(\ReflectionMethod $reflection)
426433
}
427434
}
428435

436+
/**
437+
* Reads class annotations.
438+
*
439+
* @param ReflectionClass $reflection controller class
440+
* @param string $annotationName annotation name
441+
*
442+
* @return Annotation|null
443+
*/
444+
private function readClassAnnotation(\ReflectionClass $reflection, $annotationName)
445+
{
446+
$annotationClass = "FOS\\RestBundle\\Controller\\Annotations\\$annotationName";
447+
448+
if ($annotation = $this->annotationReader->getClassAnnotation($reflection, $annotationClass)) {
449+
return $annotation;
450+
}
451+
}
452+
429453
/**
430454
* Reads method annotations.
431455
*

Routing/Loader/Reader/RestControllerReader.php

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public function read(\ReflectionClass $reflection)
100100
}
101101

102102
/**
103-
* Reads
103+
* Reads class annotations.
104104
*
105105
* @param ReflectionClass $reflection controller class
106106
* @param string $annotationName annotation name

Tests/Request/ParamReaderTest.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,48 @@ public function setup()
3131
{
3232
$annotationReader = $this->getMock('Doctrine\Common\Annotations\Reader');
3333

34-
$annotations = array();
34+
$methodAnnotations = array();
3535
$foo = new QueryParam;
3636
$foo->name = 'foo';
3737
$foo->requirements = '\d+';
3838
$foo->description = 'The foo';
39-
$annotations[] = $foo;
39+
$methodAnnotations[] = $foo;
4040

4141
$bar = new QueryParam;
4242
$bar->name = 'bar';
4343
$bar->requirements = '\d+';
4444
$bar->description = 'The bar';
45-
$annotations[] = $bar;
45+
$methodAnnotations[] = $bar;
4646

47-
$annotations[] = new NamePrefix(array());
47+
$methodAnnotations[] = new NamePrefix(array());
4848

4949
$annotationReader
5050
->expects($this->any())
5151
->method('getMethodAnnotations')
52-
->will($this->returnValue($annotations));
52+
->will($this->returnValue($methodAnnotations));
5353

54+
$classAnnotations = array();
55+
56+
$baz = new QueryParam;
57+
$baz->name = 'baz';
58+
$baz->requirements = '\d+';
59+
$baz->description = 'The baz';
60+
$classAnnotations[] = $baz;
61+
62+
$mikz = new QueryParam;
63+
$mikz->name = 'mikz';
64+
$mikz->requirements = '\d+';
65+
$mikz->description = 'The real mikz';
66+
$classAnnotations[] = $mikz;
67+
68+
$not = new NamePrefix(array());
69+
$classAnnotations[] = $not;
70+
71+
$annotationReader
72+
->expects($this->any())
73+
->method('getClassAnnotations')
74+
->will($this->returnValue($classAnnotations));
75+
5476
$this->paramReader = new ParamReader($annotationReader);
5577
}
5678

@@ -61,7 +83,7 @@ public function testReadsOnlyParamAnnotations()
6183
{
6284
$annotations = $this->paramReader->read(new \ReflectionClass(__CLASS__), 'setup');
6385

64-
$this->assertCount(2, $annotations);
86+
$this->assertCount(4, $annotations);
6587

6688
foreach ($annotations as $name => $annotation) {
6789
$this->assertThat($annotation, $this->isInstanceOf('FOS\RestBundle\Controller\Annotations\Param'));

0 commit comments

Comments
 (0)