16
16
use ApiPlatform \Core \Annotation \ApiProperty ;
17
17
use ApiPlatform \Core \Annotation \ApiResource ;
18
18
use ApiPlatform \SchemaGenerator \TypesGenerator ;
19
+ use Symfony \Component \OptionsResolver \Exception \InvalidOptionsException ;
20
+ use Symfony \Component \OptionsResolver \Options ;
21
+ use Symfony \Component \OptionsResolver \OptionsResolver ;
19
22
20
23
/**
21
24
* Generates API Platform core annotations.
22
25
*
23
26
* @author Kévin Dunglas <[email protected] >
24
27
*
25
- * @see https://github.com/api-platform/core
28
+ * @see https://github.com/api-platform/core
26
29
*/
27
30
final class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerator
28
31
{
@@ -31,17 +34,87 @@ final class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerat
31
34
*/
32
35
public function generateClassAnnotations (string $ className ): array
33
36
{
34
- $ resource = $ this ->classes [$ className ]['resource ' ];
37
+ $ class = $ this ->classes [$ className ];
38
+
39
+ $ resource = $ class ['resource ' ];
40
+
41
+ $ arguments = [sprintf ('iri="%s" ' , $ resource ->getUri ())];
42
+
43
+ if (isset ($ class ['operations ' ])) {
44
+ $ operations = $ this ->validateClassOperations ((array ) $ class ['operations ' ]);
45
+ foreach ($ operations as $ operationTarget => $ targetOperations ) {
46
+ $ targetArguments = [];
47
+ foreach ($ targetOperations as $ method => $ methodConfig ) {
48
+ $ methodConfig = $ this ->validateClassOperationMethodConfig ($ methodConfig );
49
+ $ methodArguments = [];
50
+ foreach ($ methodConfig as $ key => $ value ) {
51
+ $ methodArguments [] = sprintf ('"%s"="%s" ' , $ key , $ value );
52
+ }
53
+ $ targetArguments [] = sprintf ('"%s"={%s} ' , $ method , implode (', ' , $ methodArguments ));
54
+ }
55
+ $ arguments [] = sprintf ('%sOperations={%s} ' , $ operationTarget , implode (', ' , $ targetArguments ));
56
+ }
57
+ }
58
+
59
+ return [sprintf ('@ApiResource(%s) ' , implode (', ' , $ arguments ))];
60
+ }
61
+
62
+ /**
63
+ * Verifies that the operations config is valid.
64
+ *
65
+ * @param array $operations
66
+ *
67
+ * @return array
68
+ */
69
+ private function validateClassOperations (array $ operations )
70
+ {
71
+ $ resolver = new OptionsResolver ();
72
+ $ resolver ->setDefaults (['item ' => [], 'collection ' => []]);
73
+ $ resolver ->setAllowedTypes ('item ' , 'array ' );
74
+ $ resolver ->setAllowedTypes ('collection ' , 'array ' );
75
+
76
+ return $ resolver ->resolve ($ operations );
77
+ }
78
+
79
+ /**
80
+ * Validates the individual method config for an item/collection operation annotation.
81
+ *
82
+ * @param array $methodConfig
83
+ *
84
+ * @return array
85
+ */
86
+ private function validateClassOperationMethodConfig (array $ methodConfig )
87
+ {
88
+ $ resolver = new OptionsResolver ();
89
+
90
+ $ resolver ->setDefined (['method ' , 'route_name ' ]);
91
+ $ resolver ->setAllowedTypes ('method ' , 'string ' );
92
+ $ resolver ->setAllowedTypes ('route_name ' , 'string ' );
93
+ $ resolver ->setNormalizer (
94
+ 'route_name ' ,
95
+ function (Options $ options , $ value ) {
96
+ if (isset ($ options ['method ' ])) {
97
+ throw new InvalidOptionsException ('You must provide only \'method \' or \'route_name \', but not both ' );
98
+ }
99
+
100
+ return $ value ;
101
+ }
102
+ );
35
103
36
- return [ sprintf ( ' @ApiResource(iri="%s") ' , $ resource -> getUri ())] ;
104
+ return $ resolver -> resolve ( $ methodConfig ) ;
37
105
}
38
106
39
107
/**
40
108
* {@inheritdoc}
41
109
*/
42
110
public function generateFieldAnnotations (string $ className , string $ fieldName ): array
43
111
{
44
- return $ this ->classes [$ className ]['fields ' ][$ fieldName ]['isCustom ' ] ? [] : [sprintf ('@ApiProperty(iri="http://schema.org/%s") ' , $ fieldName )];
112
+ return $ this ->classes [$ className ]['fields ' ][$ fieldName ]['isCustom ' ] ? [] : [
113
+ sprintf (
114
+ '@ApiProperty(iri="http://schema.org/%s") ' ,
115
+ $ fieldName
116
+ ),
117
+ ];
45
118
}
46
119
47
120
/**
0 commit comments