14
14
namespace ApiPlatform \JsonSchema ;
15
15
16
16
use ApiPlatform \Api \ResourceClassResolverInterface ;
17
+ use ApiPlatform \Exception \OperationNotFoundException ;
17
18
use ApiPlatform \Metadata \ApiProperty ;
18
19
use ApiPlatform \Metadata \CollectionOperationInterface ;
19
20
use ApiPlatform \Metadata \HttpOperation ;
20
21
use ApiPlatform \Metadata \Operation ;
21
22
use ApiPlatform \Metadata \Property \Factory \PropertyMetadataFactoryInterface ;
22
23
use ApiPlatform \Metadata \Property \Factory \PropertyNameCollectionFactoryInterface ;
23
24
use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
25
+ use ApiPlatform \Metadata \Resource \ResourceMetadataCollection ;
24
26
use ApiPlatform \OpenApi \Factory \OpenApiFactory ;
25
27
use ApiPlatform \Util \ResourceClassInfoTrait ;
26
28
use Symfony \Component \PropertyInfo \Type ;
@@ -270,7 +272,14 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
270
272
}
271
273
272
274
if (null === $ operation ) {
273
- $ operation = $ this ->resourceMetadataFactory ->create ($ className )->getOperation ();
275
+ $ resourceMetadataCollection = $ this ->resourceMetadataFactory ->create ($ className );
276
+ try {
277
+ $ operation = $ resourceMetadataCollection ->getOperation ();
278
+ } catch (OperationNotFoundException $ e ) {
279
+ $ operation = new HttpOperation ();
280
+ }
281
+
282
+ $ operation = $ this ->findOperationForType ($ resourceMetadataCollection , $ type , $ operation );
274
283
} else {
275
284
// The best here is to use an Operation when calling `buildSchema`, we try to do a smart guess otherwise
276
285
if (!$ operation ->getClass ()) {
@@ -279,20 +288,7 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
279
288
if ($ operation ->getName ()) {
280
289
$ operation = $ resourceMetadataCollection ->getOperation ($ operation ->getName ());
281
290
} else {
282
- // Guess the operation and use the first one that matches criterias
283
- foreach ($ resourceMetadataCollection as $ resourceMetadata ) {
284
- foreach ($ resourceMetadata ->getOperations () ?? [] as $ op ) {
285
- if ($ operation instanceof CollectionOperationInterface && $ op instanceof CollectionOperationInterface) {
286
- $ operation = $ op ;
287
- break 2 ;
288
- }
289
-
290
- if (Schema::TYPE_INPUT === $ type && \in_array ($ op ->getMethod (), ['POST ' , 'PATCH ' , 'PUT ' ], true )) {
291
- $ operation = $ op ;
292
- break 2 ;
293
- }
294
- }
295
- }
291
+ $ operation = $ this ->findOperationForType ($ resourceMetadataCollection , $ type , $ operation );
296
292
}
297
293
}
298
294
}
@@ -320,6 +316,26 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
320
316
];
321
317
}
322
318
319
+ private function findOperationForType (ResourceMetadataCollection $ resourceMetadataCollection , string $ type , Operation $ operation )
320
+ {
321
+ // Find the operation and use the first one that matches criterias
322
+ foreach ($ resourceMetadataCollection as $ resourceMetadata ) {
323
+ foreach ($ resourceMetadata ->getOperations () ?? [] as $ op ) {
324
+ if ($ operation instanceof CollectionOperationInterface && $ op instanceof CollectionOperationInterface) {
325
+ $ operation = $ op ;
326
+ break 2 ;
327
+ }
328
+
329
+ if (Schema::TYPE_INPUT === $ type && \in_array ($ op ->getMethod (), ['POST ' , 'PATCH ' , 'PUT ' ], true )) {
330
+ $ operation = $ op ;
331
+ break 2 ;
332
+ }
333
+ }
334
+ }
335
+
336
+ return $ operation ;
337
+ }
338
+
323
339
private function getSerializerContext (Operation $ operation , string $ type = Schema::TYPE_OUTPUT ): array
324
340
{
325
341
return Schema::TYPE_OUTPUT === $ type ? ($ operation ->getNormalizationContext () ?? []) : ($ operation ->getDenormalizationContext () ?? []);
0 commit comments