24
24
use ApiPlatform \Metadata \Resource \ResourceMetadataCollection ;
25
25
use ApiPlatform \Metadata \ResourceClassResolverInterface ;
26
26
use ApiPlatform \Metadata \Util \ResourceClassInfoTrait ;
27
+ use ApiPlatform \Tests \Fixtures \TestBundle \ApiResource \Issue5501 \Related ;
27
28
use Symfony \Component \PropertyInfo \Type ;
28
29
use Symfony \Component \Serializer \NameConverter \NameConverterInterface ;
29
30
use Symfony \Component \Serializer \Normalizer \AbstractNormalizer ;
@@ -38,6 +39,8 @@ final class SchemaFactory implements SchemaFactoryInterface
38
39
use ResourceClassInfoTrait;
39
40
private array $ distinctFormats = [];
40
41
42
+ // Edge case where the related resource is not readable (for example: NotExposed) but we have groups to read the whole related object
43
+ public const FORCE_SUBSCHEMA = '_api_subschema_force_readable_link ' ;
41
44
public const OPENAPI_DEFINITION_NAME = 'openapi_definition_name ' ;
42
45
43
46
public function __construct (private readonly TypeFactoryInterface $ typeFactory , ResourceMetadataCollectionFactoryInterface $ resourceMetadataFactory , private readonly PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , private readonly PropertyMetadataFactoryInterface $ propertyMetadataFactory , private readonly ?NameConverterInterface $ nameConverter = null , ResourceClassResolverInterface $ resourceClassResolver = null )
@@ -295,29 +298,23 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
295
298
}
296
299
297
300
$ inputOrOutput = ['class ' => $ className ];
301
+ $ inputOrOutput = Schema::TYPE_OUTPUT === $ type ? ($ operation ->getOutput () ?? $ inputOrOutput ) : ($ operation ->getInput () ?? $ inputOrOutput );
302
+ $ outputClass = ($ serializerContext [self ::FORCE_SUBSCHEMA ] ?? false ) ? ($ inputOrOutput ['class ' ] ?? $ inputOrOutput ->class ?? $ operation ->getClass ()) : ($ inputOrOutput ['class ' ] ?? $ inputOrOutput ->class ?? null );
298
303
299
- if ($ operation ) {
300
- $ inputOrOutput = Schema::TYPE_OUTPUT === $ type ? ($ operation ->getOutput () ?? $ inputOrOutput ) : ($ operation ->getInput () ?? $ inputOrOutput );
301
- }
302
-
303
- if (null === ($ inputOrOutput ['class ' ] ?? $ inputOrOutput ->class ?? null )) {
304
+ if (null === $ outputClass ) {
304
305
// input or output disabled
305
306
return null ;
306
307
}
307
308
308
- if (!$ operation ) {
309
- return [$ operation , $ serializerContext ?? [], [], $ inputOrOutput ['class ' ] ?? $ inputOrOutput ->class ];
310
- }
311
-
312
309
return [
313
310
$ operation ,
314
311
$ serializerContext ?? $ this ->getSerializerContext ($ operation , $ type ),
315
312
$ this ->getValidationGroups ($ operation ),
316
- $ inputOrOutput [ ' class ' ] ?? $ inputOrOutput -> class ,
313
+ $ outputClass ,
317
314
];
318
315
}
319
316
320
- private function findOperationForType (ResourceMetadataCollection $ resourceMetadataCollection , string $ type , Operation $ operation )
317
+ private function findOperationForType (ResourceMetadataCollection $ resourceMetadataCollection , string $ type , Operation $ operation ): Operation
321
318
{
322
319
// Find the operation and use the first one that matches criterias
323
320
foreach ($ resourceMetadataCollection as $ resourceMetadata ) {
0 commit comments