Skip to content

Commit db088fd

Browse files
committed
Add support for native PHP8 QueryParam, FileParam and RequestParam attributes
1 parent 9a17f71 commit db088fd

File tree

7 files changed

+290
-49
lines changed

7 files changed

+290
-49
lines changed

Controller/Annotations/FileParam.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
* Represents a file that must be present.
2222
*
2323
* @Annotation
24+
* @NamedArgumentConstructor
2425
* @Target("METHOD")
2526
*
2627
* @author Ener-Getick <[email protected]>
2728
*/
29+
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
2830
class FileParam extends AbstractParam
2931
{
3032
/** @var bool */
@@ -39,6 +41,32 @@ class FileParam extends AbstractParam
3941
/** @var bool */
4042
public $map = false;
4143

44+
/**
45+
* @param mixed $requirements
46+
* @param mixed $default
47+
*/
48+
public function __construct(
49+
string $name = '',
50+
bool $strict = true,
51+
$requirements = null,
52+
bool $image = false,
53+
bool $map = false,
54+
?string $key = null,
55+
$default = null,
56+
string $description = '',
57+
bool $nullable = false
58+
) {
59+
$this->strict = $strict;
60+
$this->requirements = $requirements;
61+
$this->image = $image;
62+
$this->map = $map;
63+
$this->name = $name;
64+
$this->key = $key;
65+
$this->default = $default;
66+
$this->description = $description;
67+
$this->nullable = $nullable;
68+
}
69+
4270
/**
4371
* {@inheritdoc}
4472
*/

Controller/Annotations/QueryParam.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,42 @@
1717
* Represents a parameter that must be present in GET data.
1818
*
1919
* @Annotation
20+
* @NamedArgumentConstructor
2021
* @Target({"CLASS", "METHOD"})
2122
*
2223
* @author Alexander <[email protected]>
2324
*/
25+
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
2426
class QueryParam extends AbstractScalarParam
2527
{
28+
/**
29+
* @param mixed $requirements
30+
* @param mixed $default
31+
*/
32+
public function __construct(
33+
string $name = '',
34+
?string $key = null,
35+
$requirements = null,
36+
$default = null,
37+
array $incompatibles = [],
38+
string $description = '',
39+
bool $strict = false,
40+
bool $map = false,
41+
bool $nullable = false,
42+
bool $allowBlank = true
43+
) {
44+
$this->name = $name;
45+
$this->key = $key;
46+
$this->requirements = $requirements;
47+
$this->default = $default;
48+
$this->incompatibles = $incompatibles;
49+
$this->description = $description;
50+
$this->strict = $strict;
51+
$this->map = $map;
52+
$this->nullable = $nullable;
53+
$this->allowBlank = $allowBlank;
54+
}
55+
2656
/**
2757
* {@inheritdoc}
2858
*/

Controller/Annotations/RequestParam.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,46 @@
1717
* Represents a parameter that must be present in POST data.
1818
*
1919
* @Annotation
20+
* @NamedArgumentConstructor
2021
* @Target("METHOD")
2122
*
2223
* @author Jordi Boggiano <[email protected]>
2324
* @author Boris Guéry <[email protected]>
2425
*/
26+
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_METHOD)]
2527
class RequestParam extends AbstractScalarParam
2628
{
2729
/** @var bool */
2830
public $strict = true;
2931

32+
/**
33+
* @param mixed $requirements
34+
* @param mixed $default
35+
*/
36+
public function __construct(
37+
string $name = '',
38+
?string $key = null,
39+
$requirements = null,
40+
$default = null,
41+
string $description = '',
42+
array $incompatibles = [],
43+
bool $strict = false,
44+
bool $map = false,
45+
bool $nullable = false,
46+
bool $allowBlank = true
47+
) {
48+
$this->name = $name;
49+
$this->key = $key;
50+
$this->requirements = $requirements;
51+
$this->default = $default;
52+
$this->description = $description;
53+
$this->incompatibles = $incompatibles;
54+
$this->strict = $strict;
55+
$this->map = $map;
56+
$this->nullable = $nullable;
57+
$this->allowBlank = $allowBlank;
58+
}
59+
3060
/**
3161
* {@inheritdoc}
3262
*/

Request/ParamReader.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,15 @@ public function read(\ReflectionClass $reflection, string $method): array
5050
*/
5151
public function getParamsFromMethod(\ReflectionMethod $method): array
5252
{
53-
$annotations = $this->annotationReader->getMethodAnnotations($method);
53+
$annotations = [];
54+
if (\PHP_VERSION_ID >= 80000) {
55+
$annotations = $this->getParamsFromAttributes($method);
56+
}
57+
58+
$annotations = array_merge(
59+
$annotations,
60+
$this->annotationReader->getMethodAnnotations($method) ?? []
61+
);
5462

5563
return $this->getParamsFromAnnotationArray($annotations);
5664
}
@@ -60,7 +68,15 @@ public function getParamsFromMethod(\ReflectionMethod $method): array
6068
*/
6169
public function getParamsFromClass(\ReflectionClass $class): array
6270
{
63-
$annotations = $this->annotationReader->getClassAnnotations($class);
71+
$annotations = [];
72+
if (\PHP_VERSION_ID >= 80000) {
73+
$annotations = $this->getParamsFromAttributes($class);
74+
}
75+
76+
$annotations = array_merge(
77+
$annotations,
78+
$this->annotationReader->getClassAnnotations($class) ?? []
79+
);
6480

6581
return $this->getParamsFromAnnotationArray($annotations);
6682
}
@@ -79,4 +95,20 @@ private function getParamsFromAnnotationArray(array $annotations): array
7995

8096
return $params;
8197
}
98+
99+
/**
100+
* @param \ReflectionClass|\ReflectionMethod $reflection
101+
*
102+
* @return ParamInterface[]
103+
*/
104+
private function getParamsFromAttributes($reflection): array
105+
{
106+
$params = [];
107+
foreach ($reflection->getAttributes(ParamInterface::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
108+
$param = $attribute->newInstance();
109+
$params[$param->getName()] = $param;
110+
}
111+
112+
return $params;
113+
}
82114
}

Resources/doc/annotations-reference.rst

Lines changed: 110 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,126 @@ Param fetcher
77
QueryParam
88
~~~~~~~~~~
99

10-
.. code-block:: php
11-
12-
use FOS\RestBundle\Controller\Annotations\QueryParam;
13-
14-
/**
15-
* @QueryParam(
16-
* name="",
17-
* key=null,
18-
* requirements="",
19-
* incompatibles={},
20-
* default=null,
21-
* description="",
22-
* strict=false,
23-
* map=false,
24-
* nullable=false
25-
* )
26-
*/
10+
.. tabs::
11+
12+
.. tab:: Annotations
13+
14+
.. code-block:: php
15+
16+
use FOS\RestBundle\Controller\Annotations\QueryParam;
17+
18+
/**
19+
* @QueryParam(
20+
* name="",
21+
* key=null,
22+
* requirements="",
23+
* incompatibles={},
24+
* default=null,
25+
* description="",
26+
* strict=false,
27+
* map=false,
28+
* nullable=false
29+
* )
30+
*/
31+
32+
.. tab:: Attributes
33+
34+
.. code-block:: php
35+
36+
use FOS\RestBundle\Controller\Annotations\QueryParam;
37+
38+
#[QueryParam(
39+
name: '',
40+
key: null,
41+
requirements: '',
42+
incompatibles: [],
43+
default: null,
44+
description: '',
45+
strict: false,
46+
map: false,
47+
nullable: false
48+
)]
2749
2850
RequestParam
2951
~~~~~~~~~~~~
3052

31-
.. code-block:: php
53+
.. tabs::
3254

33-
use FOS\RestBundle\Controller\Annotations\RequestParam;
55+
.. tab:: Annotations
3456

35-
/**
36-
* @RequestParam(
37-
* name="",
38-
* key=null,
39-
* requirements="",
40-
* default=null,
41-
* description="",
42-
* strict=true,
43-
* map=false,
44-
* nullable=false
45-
* )
46-
*/
57+
.. code-block:: php
58+
59+
use FOS\RestBundle\Controller\Annotations\RequestParam;
60+
61+
/**
62+
* @RequestParam(
63+
* name="",
64+
* key=null,
65+
* requirements="",
66+
* default=null,
67+
* description="",
68+
* strict=true,
69+
* map=false,
70+
* nullable=false
71+
* )
72+
*/
73+
74+
.. tab:: Attributes
75+
76+
.. code-block:: php
77+
78+
use FOS\RestBundle\Controller\Annotations\RequestParam;
79+
80+
#[RequestParam(
81+
name: '',
82+
key: null,
83+
requirements: '',
84+
default: null,
85+
description: '',
86+
strict: true,
87+
map: false,
88+
nullable: false
89+
)]
4790
4891
FileParam
4992
~~~~~~~~~
5093

51-
.. code-block:: php
52-
53-
use FOS\RestBundle\Controller\Annotations\FileParam;
54-
55-
/**
56-
* @FileParam(
57-
* name="",
58-
* key=null,
59-
* requirements={},
60-
* default=null,
61-
* description="",
62-
* strict=true,
63-
* nullable=false,
64-
* image=false
65-
* )
66-
*/
94+
.. tabs::
95+
96+
.. tab:: Annotations
97+
98+
.. code-block:: php
99+
100+
use FOS\RestBundle\Controller\Annotations\FileParam;
101+
102+
/**
103+
* @FileParam(
104+
* name="",
105+
* key=null,
106+
* requirements={},
107+
* default=null,
108+
* description="",
109+
* strict=true,
110+
* nullable=false,
111+
* image=false
112+
* )
113+
*/
114+
.. tab:: Attributes
115+
116+
.. code-block:: php
117+
118+
use FOS\RestBundle\Controller\Annotations\FileParam;
119+
120+
#[FileParam(
121+
name: '',
122+
key: null,
123+
requirements: [],
124+
default: null,
125+
description: '',
126+
strict: true,
127+
nullable: false,
128+
image: false
129+
)]
67130
68131
View
69132
----

Tests/Fixtures/Controller/ParamsAnnotatedController.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,14 @@ class ParamsAnnotatedController
3535
public function getArticlesAction(ParamFetcher $paramFetcher)
3636
{
3737
}
38+
39+
#[QueryParam(name: 'page', requirements: '\d+', default: '1', description: 'Page of the overview')]
40+
#[RequestParam(name: 'byauthor', requirements: '[a-z]+', description: 'by author', incompatibles: ['search'], strict: true)]
41+
#[QueryParam(name: 'filters', requirements: '\d+', default: '1', description: 'Page of the overview')]
42+
#[FileParam(name: 'avatar', requirements: ['mimeTypes' => 'application/json'], image: true)]
43+
#[FileParam(name: 'foo', strict: false)]
44+
#[FileParam(name: 'bar', map: true)]
45+
public function getArticlesAttributesAction(ParamFetcher $paramFetcher)
46+
{
47+
}
3848
}

0 commit comments

Comments
 (0)