2
2
3
3
namespace Astral \Serialize \OpenApi \Collections ;
4
4
5
+ use Astral \Serialize \Exceptions \NotFoundGroupException ;
5
6
use Astral \Serialize \OpenApi \Annotations \Headers ;
6
7
use Astral \Serialize \OpenApi \Annotations \OpenApi ;
7
8
use Astral \Serialize \OpenApi \Annotations \RequestBody ;
15
16
use Astral \Serialize \OpenApi \Storage \OpenAPI \RequestBodyStorage ;
16
17
use Astral \Serialize \OpenApi \Storage \OpenAPI \ResponseStorage ;
17
18
use Astral \Serialize \OpenApi \Storage \OpenAPI \SchemaStorage ;
19
+ use Astral \Serialize \Resolvers \GroupResolver ;
18
20
use Astral \Serialize \Serialize ;
21
+ use Astral \Serialize \SerializeContainer ;
19
22
use Astral \Serialize \Support \Factories \ContextFactory ;
20
23
use Psr \SimpleCache \InvalidArgumentException ;
21
24
use ReflectionMethod ;
@@ -34,6 +37,7 @@ public function __construct(
34
37
public array $ attributes ,
35
38
public RequestBody |null $ requestBody ,
36
39
public Response |null $ response ,
40
+ public GroupResolver $ groupResolver ,
37
41
) {
38
42
}
39
43
@@ -50,81 +54,149 @@ public function build(): Method
50
54
description:$ this ->summary ->description ?: ''
51
55
);
52
56
53
- $ openAPIMethod ->withRequestBody ($ this ->requestBody !== null ? $ this ->buildRequestBodyByAttribute () : $ this ->buildRequestBodyByParameters ());
54
- $ openAPIMethod ->addResponse (200 , $ this ->buildResponse ());
57
+ $ requestBody = $ this ->buildRequestBody (
58
+ className:$ this ->getRequestBodyClass (),
59
+ contentType:$ this ->requestBody ->contentType ?? ContentTypeEnum::JSON ,
60
+ groups: $ this ->requestBody ->groups ?? []
61
+ );
62
+
63
+ $ response = $ this ->buildResponse (
64
+ className:$ this ->getResponseClass (),
65
+ groups:$ this ->response ->groups ?? []
66
+ );
67
+
68
+ $ openAPIMethod ->withRequestBody ($ requestBody );
69
+ $ openAPIMethod ->addResponse (200 , $ response );
55
70
return $ openAPIMethod ;
56
71
}
57
72
58
- /**
59
- * @throws InvalidArgumentException
60
- */
61
- public function buildRequestBodyByAttribute (): RequestBodyStorage
62
- {
63
- $ openAPIRequestBody = new RequestBodyStorage ($ this ->requestBody ->contentType );
64
- $ schemaStorage = (new SchemaStorage ())->build ($ this ->buildParameterCollections ($ this ->requestBody ->className , $ this ->requestBody ->groups ));
65
- $ openAPIRequestBody ->withParameter ($ schemaStorage );
66
- return $ openAPIRequestBody ;
67
- }
68
73
69
- /**
70
- * @throws InvalidArgumentException
71
- */
72
- public function buildRequestBodyByParameters (): RequestBodyStorage
74
+ public function getRequestBodyClass (): string
73
75
{
74
- $ openAPIRequestBody = new RequestBodyStorage (ContentTypeEnum::JSON );
76
+ if ($ this ->requestBody ?->className){
77
+ return $ this ->requestBody ->className ;
78
+ }
79
+
75
80
$ methodParam = $ this ->reflectionMethod ->getParameters ()[0 ] ?? null ;
76
81
$ type = $ methodParam ?->getType();
77
82
$ requestBodyClass = $ type instanceof ReflectionNamedType ? $ type ->getName () : '' ;
78
83
if (is_subclass_of ($ requestBodyClass , Serialize::class)) {
79
- $ schemaStorage = (new SchemaStorage ())->build ($ this ->buildParameterCollections ($ requestBodyClass ));
84
+ return $ requestBodyClass ;
85
+ }
86
+
87
+ return '' ;
88
+ }
89
+
90
+
91
+ public function buildRequestBody (string $ className ,ContentTypeEnum $ contentType ,array $ groups = []): RequestBodyStorage
92
+ {
93
+ $ openAPIRequestBody = new RequestBodyStorage ($ contentType );
94
+ if (is_subclass_of ($ className , Serialize::class)) {
95
+ $ schemaStorage = (new SchemaStorage ())->build ($ this ->buildRequestParameterCollections ($ className ,$ groups ));
80
96
$ openAPIRequestBody ->withParameter ($ schemaStorage );
81
97
}
82
98
83
99
return $ openAPIRequestBody ;
84
100
}
85
101
86
- /**
87
- * @throws InvalidArgumentException
88
- */
89
- public function buildResponse (): ResponseStorage
102
+ public function getResponseClass (): string
90
103
{
104
+ if ($ this ->response ?->className){
105
+ return $ this ->response ->className ;
106
+ }
107
+
91
108
$ returnClass = $ this ->reflectionMethod ->getReturnType ();
92
109
$ returnClass = $ returnClass instanceof ReflectionNamedType ? $ returnClass ->getName () : null ;
93
- $ responseClass = match (true ) {
94
- $ this ->response !== null => $ this ->response ->className ,
95
- $ returnClass && is_subclass_of ($ returnClass , Serialize::class) => $ returnClass ,
96
- default => null ,
97
- };
110
+ if (is_subclass_of ($ returnClass , Serialize::class)) {
111
+ return $ returnClass ;
112
+ }
98
113
99
- $ responseStorage = new ResponseStorage ();
114
+ return '' ;
115
+ }
100
116
117
+ /**
118
+ * @throws InvalidArgumentException
119
+ */
120
+ public function buildResponse (string $ className ,array $ groups = []): ResponseStorage
121
+ {
122
+ $ responseStorage = new ResponseStorage ();
101
123
102
- if ($ responseClass ) {
103
- $ groups = $ this ->response && is_array ($ this ->response ->groups ) ? $ this ->response ->groups : ['default ' ];
104
- $ schemaStorage = (new SchemaStorage ())->build ($ this ->buildParameterCollections ($ responseClass , $ groups ));
124
+ if ($ className ) {
125
+ $ schemaStorage = (new SchemaStorage ())->build ($ this ->buildResponseParameterCollections ($ className ,$ groups ));
105
126
$ responseStorage ->withParameter ($ schemaStorage );
106
127
}
107
128
108
129
return $ responseStorage ;
109
130
}
110
131
132
+ /**
133
+ * @param string $className
134
+ * @param array $groups
135
+ * @return array<ParameterCollection>
136
+ * @throws InvalidArgumentException|NotFoundGroupException
137
+ */
138
+ public function buildRequestParameterCollections (string $ className , array $ groups = []): array
139
+ {
140
+
141
+ $ serializeContext = ContextFactory::build ($ className );
142
+ $ serializeContext ->setGroups ($ groups )->from ();
143
+ $ properties = $ serializeContext ->getGroupCollection ()->getProperties ();
144
+ $ groups = $ groups ?: [$ className ];
145
+
146
+ $ vols = [];
147
+ foreach ($ properties as $ property ) {
148
+
149
+
150
+ if ($ property ->isInputIgnoreByGroups ($ groups ) || !$ this ->groupResolver ->resolveExistsGroupsByDataCollection ($ property , $ groups , $ className )){
151
+ continue ;
152
+ }
153
+
154
+ $ vol = new ParameterCollection (
155
+ className: $ className ,
156
+ name: current ($ property ->getInputNamesByGroups ($ groups , $ className )),
157
+ types: $ property ->getTypes (),
158
+ type: ParameterTypeEnum::getByTypes ($ property ->getTypes ()),
159
+ openApiAnnotation: $ this ->getOpenApiAnnotation ($ property ->getAttributes ()),
160
+ required: !$ property ->isNullable (),
161
+ ignore: false ,
162
+ );
163
+
164
+ if ($ property ->getChildren ()) {
165
+ foreach ($ property ->getChildren () as $ children ) {
166
+ $ className = $ children ->getClassName ();
167
+ $ vol ->children [$ className ] = $ this ->buildRequestParameterCollections ($ className );
168
+ }
169
+ }
170
+
171
+ $ vols [] = $ vol ;
172
+ }
173
+
174
+ return $ vols ;
175
+ }
176
+
111
177
/**
112
178
* @param string $className
113
179
* @param array $groups
114
180
* @return array<ParameterCollection>
115
181
* @throws InvalidArgumentException
116
182
*/
117
- public function buildParameterCollections (string $ className , array $ groups = [' default ' ]): array
183
+ public function buildResponseParameterCollections (string $ className , array $ groups = []): array
118
184
{
119
185
$ serializeContext = ContextFactory::build ($ className );
120
186
$ serializeContext ->from ();
121
187
$ properties = $ serializeContext ->getGroupCollection ()->getProperties ();
188
+ $ groups = $ groups ?: [$ className ];
122
189
123
190
$ vols = [];
124
191
foreach ($ properties as $ property ) {
192
+
193
+ if ($ property ->isOutIgnoreByGroups ($ groups ) || !$ this ->groupResolver ->resolveExistsGroupsByDataCollection ($ property , $ groups , $ className )){
194
+ continue ;
195
+ }
196
+
125
197
$ vol = new ParameterCollection (
126
198
className: $ className ,
127
- name: current ($ property ->getInputNamesByGroups ($ groups , $ className )),
199
+ name: current ($ property ->getOutNamesByGroups ($ groups , $ className )),
128
200
types: $ property ->getTypes (),
129
201
type: ParameterTypeEnum::getByTypes ($ property ->getTypes ()),
130
202
openApiAnnotation: $ this ->getOpenApiAnnotation ($ property ->getAttributes ()),
@@ -135,7 +207,7 @@ className: $className,
135
207
if ($ property ->getChildren ()) {
136
208
foreach ($ property ->getChildren () as $ children ) {
137
209
$ className = $ children ->getClassName ();
138
- $ vol ->children [$ className ] = $ this ->buildParameterCollections ($ className );
210
+ $ vol ->children [$ className ] = $ this ->buildResponseParameterCollections ($ className );
139
211
}
140
212
}
141
213
0 commit comments