1
1
<?php
2
-
3
2
/*
4
3
* This file is part of the API Platform project.
5
4
*
22
21
use ApiPlatform \Metadata \Property \Factory \PropertyNameCollectionFactoryInterface ;
23
22
use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
24
23
use ApiPlatform \Metadata \ResourceClassResolverInterface ;
24
+ use ApiPlatform \Tests \Fixtures \TestBundle \Entity \Issue5793 \BagOfTests ;
25
25
use Symfony \Component \Serializer \NameConverter \NameConverterInterface ;
26
26
use Symfony \Component \Serializer \Normalizer \AbstractNormalizer ;
27
27
@@ -37,7 +37,6 @@ final class SchemaFactory implements SchemaFactoryInterface, SchemaFactoryAwareI
37
37
38
38
private ?SchemaFactoryInterface $ schemaFactory = null ;
39
39
// Edge case where the related resource is not readable (for example: NotExposed) but we have groups to read the whole related object
40
- public const FORCE_SUBSCHEMA = '_api_subschema_force_readable_link ' ;
41
40
public const OPENAPI_DEFINITION_NAME = 'openapi_definition_name ' ;
42
41
43
42
public function __construct (ResourceMetadataCollectionFactoryInterface $ resourceMetadataFactory , private readonly PropertyNameCollectionFactoryInterface $ propertyNameCollectionFactory , private readonly PropertyMetadataFactoryInterface $ propertyMetadataFactory , private readonly ?NameConverterInterface $ nameConverter = null , ?ResourceClassResolverInterface $ resourceClassResolver = null , ?array $ distinctFormats = null , private ?DefinitionNameFactoryInterface $ definitionNameFactory = null )
@@ -104,7 +103,7 @@ public function buildSchema(string $className, string $format = 'json', string $
104
103
/** @var \ArrayObject<string, mixed> $definition */
105
104
$ definition = new \ArrayObject (['type ' => 'object ' ]);
106
105
$ definitions [$ definitionName ] = $ definition ;
107
- if ($ description = $ operation ->getDescription ()) {
106
+ if ($ description = $ operation? ->getDescription()) {
108
107
$ definition ['description ' ] = $ description ;
109
108
}
110
109
@@ -114,7 +113,7 @@ public function buildSchema(string $className, string $format = 'json', string $
114
113
$ definition ['additionalProperties ' ] = false ;
115
114
}
116
115
117
- // see https://github.com/json-schema-org/json-schema-spec /pull/737
116
+ // see https://github.com/json-schema-org/json-schema-speMc /pull/737
118
117
if (Schema::VERSION_SWAGGER !== $ version && $ operation && $ operation ->getDeprecationReason ()) {
119
118
$ definition ['deprecated ' ] = true ;
120
119
}
@@ -128,6 +127,7 @@ public function buildSchema(string $className, string $format = 'json', string $
128
127
$ options = ['schema_type ' => $ type ] + $ this ->getFactoryOptions ($ serializerContext , $ validationGroups , $ operation instanceof HttpOperation ? $ operation : null );
129
128
foreach ($ this ->propertyNameCollectionFactory ->create ($ inputOrOutputClass , $ options ) as $ propertyName ) {
130
129
$ propertyMetadata = $ this ->propertyMetadataFactory ->create ($ inputOrOutputClass , $ propertyName , $ options );
130
+
131
131
if (!$ propertyMetadata ->isReadable () && !$ propertyMetadata ->isWritable ()) {
132
132
continue ;
133
133
}
@@ -137,13 +137,13 @@ public function buildSchema(string $className, string $format = 'json', string $
137
137
$ definition ['required ' ][] = $ normalizedPropertyName ;
138
138
}
139
139
140
- $ this ->buildPropertySchema ($ schema , $ definitionName , $ normalizedPropertyName , $ propertyMetadata , $ serializerContext , $ format , $ type );
140
+ $ this ->buildPropertySchema ($ schema , $ definitionName , $ normalizedPropertyName , $ propertyMetadata , $ serializerContext , $ format , $ type, $ inputOrOutputClass === BagOfTests::class );
141
141
}
142
142
143
143
return $ schema ;
144
144
}
145
145
146
- private function buildPropertySchema (Schema $ schema , string $ definitionName , string $ normalizedPropertyName , ApiProperty $ propertyMetadata , array $ serializerContext , string $ format , string $ parentType ): void
146
+ private function buildPropertySchema (Schema $ schema , string $ definitionName , string $ normalizedPropertyName , ApiProperty $ propertyMetadata , array $ serializerContext , string $ format , string $ parentType, $ t = null ): void
147
147
{
148
148
$ version = $ schema ->getVersion ();
149
149
if (Schema::VERSION_SWAGGER === $ version || Schema::VERSION_OPENAPI === $ version ) {
@@ -165,9 +165,13 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
165
165
$ extraProperties = $ propertyMetadata ->getExtraProperties () ?? [];
166
166
// see AttributePropertyMetadataFactory
167
167
if (true === ($ extraProperties [SchemaPropertyMetadataFactory::JSON_SCHEMA_USER_DEFINED ] ?? false )) {
168
+ if (true === $ serializerContext [self ::COMPUTE_REFERENCES ] ?? null ) {
169
+ return ;
170
+
171
+ }
172
+
168
173
// schema seems to have been declared by the user: do not override nor complete user value
169
174
$ schema ->getDefinitions ()[$ definitionName ]['properties ' ][$ normalizedPropertyName ] = new \ArrayObject ($ propertySchema );
170
-
171
175
return ;
172
176
}
173
177
@@ -178,14 +182,11 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
178
182
// or if property schema is already fully defined (type=string + format || enum)
179
183
$ propertySchemaType = $ propertySchema ['type ' ] ?? false ;
180
184
181
- if (Schema::UNKNOWN_TYPE === $ propertySchemaType && 'propertyCollectionIriOnlyRelation ' === $ normalizedPropertyName ) {
182
- dd ($ propertySchema , $ propertyMetadata );
183
- }
184
-
185
185
$ isUnknown = Schema::UNKNOWN_TYPE === $ propertySchemaType
186
186
|| ('array ' === $ propertySchemaType && Schema::UNKNOWN_TYPE === ($ propertySchema ['items ' ]['type ' ] ?? null ))
187
187
|| ('object ' === $ propertySchemaType && Schema::UNKNOWN_TYPE === ($ propertySchema ['additionalProperties ' ]['type ' ] ?? null ));
188
188
189
+ // Scalar properties
189
190
if (
190
191
!$ isUnknown && (
191
192
[] === $ types
@@ -194,6 +195,10 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
194
195
|| ($ propertySchema ['format ' ] ?? $ propertySchema ['enum ' ] ?? false )
195
196
)
196
197
) {
198
+ if (true === $ serializerContext [self ::COMPUTE_REFERENCES ]) {
199
+ return ;
200
+ }
201
+
197
202
if (isset ($ propertySchema ['$ref ' ])) {
198
203
unset($ propertySchema ['type ' ]);
199
204
}
@@ -208,6 +213,7 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
208
213
$ version = $ schema ->getVersion ();
209
214
$ refs = [];
210
215
$ isNullable = null ;
216
+ $ hasClassName = false ;
211
217
212
218
foreach ($ types as $ type ) {
213
219
$ subSchema = new Schema ($ version );
@@ -225,6 +231,7 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
225
231
continue ;
226
232
}
227
233
234
+ $ hasClassName = true ;
228
235
$ subSchemaFactory = $ this ->schemaFactory ?: $ this ;
229
236
$ subSchema = $ subSchemaFactory ->buildSchema ($ className , $ format , $ parentType , null , $ subSchema , $ serializerContext + [self ::FORCE_SUBSCHEMA => true ], false );
230
237
if (!isset ($ subSchema ['$ref ' ])) {
@@ -254,7 +261,12 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
254
261
$ refs [] = ['type ' => 'null ' ];
255
262
}
256
263
257
- if (($ c = \count ($ refs )) > 1 ) {
264
+ if (!$ hasClassName && (true === $ serializerContext [self ::COMPUTE_REFERENCES ] ?? null )) {
265
+ return ;
266
+ }
267
+
268
+ $ c = \count ($ refs );
269
+ if ($ c > 1 ) {
258
270
$ propertySchema ['anyOf ' ] = $ refs ;
259
271
unset($ propertySchema ['type ' ]);
260
272
} elseif (1 === $ c ) {
@@ -310,4 +322,19 @@ public function setSchemaFactory(SchemaFactoryInterface $schemaFactory): void
310
322
{
311
323
$ this ->schemaFactory = $ schemaFactory ;
312
324
}
325
+
326
+ // private function isObject($types): bool
327
+ // {
328
+ // foreach ($types as $type) {
329
+ // if ($type->getClassName()) {
330
+ // return true;
331
+ // }
332
+ //
333
+ // if ($type->getCollectionValueTypes() && ($r = $this->isObject($type->getCollectionValueTypes()))) {
334
+ // return $r;
335
+ // }
336
+ // }
337
+ //
338
+ // return false;
339
+ // }
313
340
}
0 commit comments