1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Joli\Jane\OpenApi\Generator; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\Inflector\Inflector; |
6
|
|
|
use Joli\Jane\Generator\Context\Context; |
7
|
|
|
use Joli\Jane\Runtime\Reference; |
8
|
|
|
use Joli\Jane\OpenApi\Model\BodyParameter; |
9
|
|
|
use Joli\Jane\OpenApi\Model\FormDataParameterSubSchema; |
10
|
|
|
use Joli\Jane\OpenApi\Model\HeaderParameterSubSchema; |
11
|
|
|
use Joli\Jane\OpenApi\Model\PathParameterSubSchema; |
12
|
|
|
use Joli\Jane\OpenApi\Model\QueryParameterSubSchema; |
13
|
|
|
use Joli\Jane\OpenApi\Operation\Operation; |
14
|
|
|
use Joli\Jane\Reference\Resolver; |
15
|
|
|
use PhpParser\Node\Arg; |
16
|
|
|
use PhpParser\Node\Expr; |
17
|
|
|
use PhpParser\Node\Name; |
18
|
|
|
use PhpParser\Node\Param; |
19
|
|
|
use PhpParser\Node\Scalar; |
20
|
|
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; |
21
|
|
|
|
22
|
|
|
trait InputGeneratorTrait |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var Parameter\BodyParameterGenerator |
26
|
|
|
*/ |
27
|
|
|
protected $bodyParameterGenerator; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var Parameter\FormDataParameterGenerator |
31
|
|
|
*/ |
32
|
|
|
protected $formDataParameterGenerator; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var Parameter\HeaderParameterGenerator |
36
|
|
|
*/ |
37
|
|
|
protected $headerParameterGenerator; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var Parameter\PathParameterGenerator |
41
|
|
|
*/ |
42
|
|
|
protected $pathParameterGenerator; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var Parameter\QueryParameterGenerator |
46
|
|
|
*/ |
47
|
|
|
protected $queryParameterGenerator; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @return DenormalizerInterface |
51
|
|
|
*/ |
52
|
|
|
abstract protected function getDenormalizer(); |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Create the query param statements and documentation |
56
|
|
|
* |
57
|
|
|
* @param Operation $operation |
58
|
|
|
* |
59
|
|
|
* @return array |
60
|
|
|
*/ |
61
|
12 |
|
protected function createQueryParamStatements(Operation $operation) |
62
|
|
|
{ |
63
|
12 |
|
$queryParamDocumentation = []; |
64
|
12 |
|
$queryParamVariable = new Expr\Variable('queryParam'); |
65
|
|
|
$queryParamStatements = [ |
66
|
12 |
|
new Expr\Assign($queryParamVariable, new Expr\New_(new Name('QueryParam'))) |
67
|
|
|
]; |
68
|
|
|
|
69
|
12 |
|
if ($operation->getOperation()->getParameters()) { |
70
|
6 |
|
foreach ($operation->getOperation()->getParameters() as $parameter) { |
71
|
6 |
|
if ($parameter instanceof Reference) { |
72
|
1 |
|
$parameter = $this->resolveParameter($parameter); |
73
|
|
|
} |
74
|
|
|
|
75
|
6 |
View Code Duplication |
if ($parameter instanceof FormDataParameterSubSchema) { |
|
|
|
|
76
|
1 |
|
$queryParamStatements = array_merge($queryParamStatements, $this->formDataParameterGenerator->generateQueryParamStatements($parameter, $queryParamVariable)); |
77
|
1 |
|
$queryParamDocumentation[] = $this->formDataParameterGenerator->generateQueryDocParameter($parameter); |
78
|
|
|
} |
79
|
|
|
|
80
|
6 |
View Code Duplication |
if ($parameter instanceof HeaderParameterSubSchema) { |
|
|
|
|
81
|
1 |
|
$queryParamStatements = array_merge($queryParamStatements, $this->headerParameterGenerator->generateQueryParamStatements($parameter, $queryParamVariable)); |
82
|
1 |
|
$queryParamDocumentation[] = $this->headerParameterGenerator->generateQueryDocParameter($parameter); |
83
|
|
|
} |
84
|
|
|
|
85
|
6 |
View Code Duplication |
if ($parameter instanceof QueryParameterSubSchema) { |
|
|
|
|
86
|
2 |
|
$queryParamStatements = array_merge($queryParamStatements, $this->queryParameterGenerator->generateQueryParamStatements($parameter, $queryParamVariable)); |
87
|
6 |
|
$queryParamDocumentation[] = $this->queryParameterGenerator->generateQueryDocParameter($parameter); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
|
92
|
12 |
|
return [$queryParamDocumentation, $queryParamStatements, $queryParamVariable]; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Create parameters for the method and their documentation |
97
|
|
|
* |
98
|
|
|
* @param Operation $operation |
99
|
|
|
* @param string[] $queryParamDocumentation |
100
|
|
|
* @param Context $context |
101
|
|
|
* |
102
|
|
|
* @return array |
103
|
|
|
*/ |
104
|
12 |
|
protected function createParameters(Operation $operation, $queryParamDocumentation, Context $context) |
105
|
|
|
{ |
106
|
12 |
|
$documentationParams = []; |
107
|
12 |
|
$methodParameters = []; |
108
|
|
|
|
109
|
12 |
|
if ($operation->getOperation()->getParameters()) { |
110
|
6 |
View Code Duplication |
foreach ($operation->getOperation()->getParameters() as $key => $parameter) { |
|
|
|
|
111
|
6 |
|
if ($parameter instanceof Reference) { |
112
|
1 |
|
$parameter = $this->resolveParameter($parameter); |
113
|
|
|
} |
114
|
|
|
|
115
|
6 |
|
if ($parameter instanceof PathParameterSubSchema) { |
|
|
|
|
116
|
3 |
|
$methodParameters[] = $this->pathParameterGenerator->generateMethodParameter($parameter, $context, $operation->getReference() . '/parameters/' . $key); |
117
|
6 |
|
$documentationParams[] = sprintf(' * @param %s', $this->pathParameterGenerator->generateDocParameter($parameter, $context, $operation->getReference() . '/parameters/' . $key)); |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
6 |
View Code Duplication |
foreach ($operation->getOperation()->getParameters() as $key => $parameter) { |
|
|
|
|
122
|
6 |
|
if ($parameter instanceof Reference) { |
123
|
1 |
|
$parameter = $this->resolveParameter($parameter); |
124
|
|
|
} |
125
|
|
|
|
126
|
6 |
|
if ($parameter instanceof BodyParameter) { |
|
|
|
|
127
|
3 |
|
$methodParameters[] = $this->bodyParameterGenerator->generateMethodParameter($parameter, $context, $operation->getReference() . '/parameters/' . $key); |
128
|
6 |
|
$documentationParams[] = sprintf(' * @param %s', $this->bodyParameterGenerator->generateDocParameter($parameter, $context, $operation->getReference() . '/parameters/' . $key)); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
133
|
12 |
|
if (!empty($queryParamDocumentation)) { |
134
|
2 |
|
$documentationParams[] = " * @param array \$parameters {"; |
135
|
|
|
$documentationParams = array_merge($documentationParams, array_map(function ($doc) { |
136
|
2 |
|
return " * " . $doc; |
137
|
2 |
|
}, $queryParamDocumentation)); |
138
|
2 |
|
$documentationParams[] = " * }"; |
139
|
|
|
} else { |
140
|
12 |
|
$documentationParams[] = " * @param array \$parameters List of parameters"; |
141
|
|
|
} |
142
|
|
|
|
143
|
12 |
|
$documentationParams[] = " * @param string \$fetch Fetch mode (object or response)"; |
144
|
|
|
|
145
|
12 |
|
$methodParameters[] = new Param('parameters', new Expr\Array_()); |
146
|
12 |
|
$methodParameters[] = new Param('fetch', new Expr\ConstFetch(new Name('self::FETCH_OBJECT'))); |
147
|
|
|
|
148
|
12 |
|
return [$documentationParams, $methodParameters]; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Create all statements around url transformation |
153
|
|
|
* |
154
|
|
|
* @param Operation $operation |
155
|
|
|
* @param Expr\Variable $queryParamVariable |
156
|
|
|
* |
157
|
|
|
* @return array |
158
|
|
|
*/ |
159
|
12 |
|
protected function createUrlStatements(Operation $operation, $queryParamVariable) |
160
|
|
|
{ |
161
|
12 |
|
$urlVariable = new Expr\Variable('url'); |
162
|
|
|
// url = /path |
163
|
|
|
$statements = [ |
164
|
12 |
|
new Expr\Assign($urlVariable, new Scalar\String_($operation->getPath())) |
165
|
|
|
]; |
166
|
|
|
|
167
|
12 |
|
if ($operation->getOperation()->getParameters()) { |
168
|
6 |
|
foreach ($operation->getOperation()->getParameters() as $parameter) { |
169
|
6 |
|
if ($parameter instanceof Reference) { |
170
|
1 |
|
$parameter = $this->resolveParameter($parameter); |
171
|
|
|
} |
172
|
|
|
|
173
|
6 |
|
if ($parameter instanceof PathParameterSubSchema) { |
|
|
|
|
174
|
|
|
// $url = str_replace('{param}', $param, $url) |
|
|
|
|
175
|
3 |
|
$statements[] = new Expr\Assign($urlVariable, new Expr\FuncCall(new Name('str_replace'), [ |
176
|
3 |
|
new Arg(new Scalar\String_('{' . $parameter->getName() . '}')), |
177
|
3 |
|
new Arg(new Expr\FuncCall(new Name('urlencode'), [ |
178
|
3 |
|
new Arg(new Expr\Variable(Inflector::camelize($parameter->getName()))), |
179
|
|
|
])), |
180
|
6 |
|
new Arg($urlVariable) |
181
|
|
|
])); |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
// url = url . ? . $queryParam->buildQueryString |
187
|
12 |
|
$statements[] = new Expr\Assign($urlVariable, new Expr\BinaryOp\Concat( |
188
|
12 |
|
$urlVariable, |
189
|
12 |
|
new Expr\BinaryOp\Concat( |
190
|
12 |
|
new Scalar\String_('?'), |
191
|
12 |
|
new Expr\MethodCall($queryParamVariable, 'buildQueryString', [new Arg(new Expr\Variable('parameters'))]) |
192
|
|
|
) |
193
|
|
|
)); |
194
|
|
|
|
195
|
12 |
|
return [$statements, $urlVariable]; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* Create body statements |
200
|
|
|
* |
201
|
|
|
* @param Operation $operation |
202
|
|
|
* @param Expr\Variable $queryParamVariable |
203
|
|
|
* @param Context $context |
204
|
|
|
* |
205
|
|
|
* @return array |
206
|
|
|
*/ |
207
|
12 |
|
protected function createBodyStatements(Operation $operation, $queryParamVariable, Context $context) |
208
|
|
|
{ |
209
|
12 |
|
$bodyParameter = null; |
210
|
12 |
|
$bodyVariable = new Expr\Variable('body'); |
211
|
12 |
|
$parameterKey = 0; |
212
|
|
|
|
213
|
12 |
|
if ($operation->getOperation()->getParameters()) { |
214
|
6 |
|
foreach ($operation->getOperation()->getParameters() as $key => $parameter) { |
215
|
6 |
|
if ($parameter instanceof BodyParameter) { |
|
|
|
|
216
|
3 |
|
$bodyParameter = $parameter; |
217
|
6 |
|
$parameterKey = $key; |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
12 |
|
if (null === $bodyParameter) { |
223
|
|
|
// $body = $queryParam->buildFormDataString($parameters); |
|
|
|
|
224
|
|
|
return [[ |
225
|
10 |
|
new Expr\Assign($bodyVariable, new Expr\MethodCall($queryParamVariable, 'buildFormDataString', [new Arg(new Expr\Variable('parameters'))])) |
226
|
10 |
|
], $bodyVariable]; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
// $body = $this->serializer->serialize($parameter); |
|
|
|
|
230
|
3 |
|
if ($bodyParameter->getSchema() instanceof Reference || $context->getRegistry()->hasClass($operation->getReference() . '/parameters/' . $parameterKey)) { |
231
|
|
|
return [ |
232
|
|
|
[ |
233
|
2 |
|
new Expr\Assign( |
234
|
2 |
|
$bodyVariable, |
235
|
2 |
|
new Expr\MethodCall( |
236
|
2 |
|
new Expr\PropertyFetch(new Expr\Variable('this'), 'serializer'), |
237
|
2 |
|
'serialize', |
238
|
|
|
[ |
239
|
2 |
|
new Arg(new Expr\Variable(Inflector::camelize($bodyParameter->getName()))), |
240
|
2 |
|
new Arg(new Scalar\String_('json')) |
241
|
|
|
] |
242
|
|
|
) |
243
|
|
|
) |
244
|
|
|
], |
245
|
2 |
|
$bodyVariable |
246
|
|
|
]; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
// $body = $parameter |
250
|
|
|
return [[ |
251
|
2 |
|
new Expr\Assign($bodyVariable, new Expr\Variable(Inflector::camelize($bodyParameter->getName()))) |
252
|
2 |
|
], $bodyVariable]; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* Create headers statements |
257
|
|
|
* |
258
|
|
|
* @param Operation $operation |
259
|
|
|
* @param Expr\Variable $queryParamVariable |
260
|
|
|
* |
261
|
|
|
* @return array |
262
|
|
|
*/ |
263
|
12 |
|
protected function createHeaderStatements(Operation $operation, $queryParamVariable) |
264
|
|
|
{ |
265
|
12 |
|
$headerVariable = new Expr\Variable('headers'); |
266
|
|
|
|
267
|
|
|
$headers = [ |
268
|
12 |
|
new Expr\ArrayItem( |
269
|
12 |
|
new Scalar\String_($operation->getHost()), |
270
|
12 |
|
new Scalar\String_('Host') |
271
|
|
|
), |
272
|
|
|
]; |
273
|
|
|
|
274
|
12 |
|
$produces = $operation->getOperation()->getProduces(); |
275
|
|
|
|
276
|
12 |
|
if ($produces && in_array("application/json", $produces)) { |
277
|
2 |
|
$headers[] |
278
|
2 |
|
= new Expr\ArrayItem( |
279
|
2 |
|
new Expr\Array_( |
280
|
|
|
[ |
281
|
2 |
|
new Expr\ArrayItem( |
282
|
2 |
|
new Scalar\String_("application/json") |
283
|
|
|
), |
284
|
|
|
] |
285
|
|
|
), |
286
|
2 |
|
new Scalar\String_('Accept') |
287
|
|
|
); |
288
|
|
|
} |
289
|
|
|
|
290
|
12 |
|
$consumes = $operation->getOperation()->getProduces(); |
291
|
|
|
|
292
|
12 |
|
if ($operation->getOperation()->getParameters() && $consumes) { |
293
|
1 |
|
$bodyParameters = array_filter( |
294
|
1 |
|
$operation->getOperation()->getParameters(), |
295
|
|
|
function ($parameter) { |
296
|
1 |
|
return $parameter instanceof BodyParameter; |
|
|
|
|
297
|
1 |
|
} |
298
|
|
|
); |
299
|
|
|
|
300
|
1 |
|
if (count($bodyParameters) > 0 && in_array("application/json", $consumes)) { |
301
|
1 |
|
$headers[] |
302
|
1 |
|
= new Expr\ArrayItem( |
303
|
1 |
|
new Scalar\String_("application/json"), |
304
|
1 |
|
new Scalar\String_('Content-Type') |
305
|
|
|
); |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
return [ |
310
|
|
|
[ |
311
|
12 |
|
new Expr\Assign( |
312
|
12 |
|
$headerVariable, |
313
|
12 |
|
new Expr\FuncCall(new Name('array_merge'), [ |
314
|
12 |
|
new Arg( |
315
|
12 |
|
new Expr\Array_( |
316
|
12 |
|
$headers |
317
|
|
|
) |
318
|
|
|
), |
319
|
12 |
|
new Arg(new Expr\MethodCall($queryParamVariable, 'buildHeaders', [new Arg(new Expr\Variable('parameters'))])) |
320
|
|
|
]) |
321
|
|
|
) |
322
|
|
|
], |
323
|
12 |
|
$headerVariable |
324
|
|
|
]; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* @param Reference $parameter |
329
|
|
|
* |
330
|
|
|
* @return BodyParameter|HeaderParameterSubSchema|FormDataParameterSubSchema|QueryParameterSubSchema|PathParameterSubSchema |
331
|
|
|
*/ |
332
|
|
|
protected function resolveParameter(Reference $parameter) |
333
|
|
|
{ |
334
|
1 |
|
return $parameter->resolve(function ($value) { |
335
|
1 |
View Code Duplication |
if (isset($value->{'in'}) and $value->{'in'} == 'body') { |
|
|
|
|
336
|
|
|
return $this->getDenormalizer()->denormalize($value, 'Joli\\Jane\\OpenApi\\Model\\BodyParameter'); |
337
|
|
|
} |
338
|
1 |
View Code Duplication |
if (isset($value->{'in'}) and $value->{'in'} == 'header') { |
|
|
|
|
339
|
|
|
return $this->getDenormalizer()->denormalize($value, 'Joli\\Jane\\OpenApi\\Model\\HeaderParameterSubSchema'); |
340
|
|
|
} |
341
|
1 |
View Code Duplication |
if (isset($value->{'in'}) and $value->{'in'} == 'formData') { |
|
|
|
|
342
|
|
|
return $this->getDenormalizer()->denormalize($value, 'Joli\\Jane\\OpenApi\\Model\\FormDataParameterSubSchema'); |
343
|
|
|
} |
344
|
1 |
View Code Duplication |
if (isset($value->{'in'}) and $value->{'in'} == 'query') { |
|
|
|
|
345
|
|
|
return $this->getDenormalizer()->denormalize($value, 'Joli\\Jane\\OpenApi\\Model\\QueryParameterSubSchema'); |
346
|
|
|
} |
347
|
1 |
View Code Duplication |
if (isset($value->{'in'}) and $value->{'in'} == 'path') { |
|
|
|
|
348
|
1 |
|
return $this->getDenormalizer()->denormalize($value, 'Joli\\Jane\\OpenApi\\Model\\PathParameterSubSchema'); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
return $value; |
352
|
1 |
|
}); |
353
|
|
|
} |
354
|
|
|
} |
355
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.