Skip to content

Commit 2c5fc99

Browse files
fix: review
1 parent df9d7fa commit 2c5fc99

File tree

5 files changed

+69
-43
lines changed

5 files changed

+69
-43
lines changed

features/openapi/docs.feature

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Feature: Documentation support
9898
And the "playMode" property for the OpenAPI class "VideoGame" should be equal to:
9999
"""
100100
{
101+
"owl:maxCardinality": 1,
101102
"type": "string",
102103
"format": "iri-reference"
103104
}
@@ -308,13 +309,14 @@ Feature: Documentation support
308309
And the "resourceRelated" property for the OpenAPI class "Resource" should be equal to:
309310
"""
310311
{
311-
"readOnly":true,
312-
"anyOf":[
312+
"owl:maxCardinality": 1,
313+
"readOnly": true,
314+
"anyOf": [
313315
{
314-
"$ref":"#/components/schemas/ResourceRelated"
316+
"$ref": "#/components/schemas/ResourceRelated"
315317
},
316318
{
317-
"type":"null"
319+
"type": "null"
318320
}
319321
]
320322
}

src/Hydra/Serializer/DocumentationNormalizer.php

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -310,53 +310,77 @@ private function getHydraOperation(HttpOperation $operation, string $prefixedSho
310310
/**
311311
* Gets the range of the property.
312312
*/
313-
private function getRange(ApiProperty $propertyMetadata): ?string
313+
private function getRange(ApiProperty $propertyMetadata): array|string|null
314314
{
315315
$jsonldContext = $propertyMetadata->getJsonldContext();
316316

317317
if (isset($jsonldContext['@type'])) {
318318
return $jsonldContext['@type'];
319319
}
320320

321-
$types = $propertyMetadata->getBuiltinTypes() ?? [];
321+
$builtInTypes = $propertyMetadata->getBuiltinTypes() ?? [];
322+
$types = [];
322323

323-
foreach ($types as $type) {
324+
foreach ($builtInTypes as $type) {
324325
if ($type->isCollection() && null !== $collectionType = $type->getCollectionValueTypes()[0] ?? null) {
325326
$type = $collectionType;
326327
}
327328

328329
switch ($type->getBuiltinType()) {
329330
case Type::BUILTIN_TYPE_STRING:
330-
return 'xmls:string';
331+
if (!\in_array('xmls:string', $types, true)) {
332+
$types[] = 'xmls:string';
333+
}
334+
break;
331335
case Type::BUILTIN_TYPE_INT:
332-
return 'xmls:integer';
336+
if (!\in_array('xmls:integer', $types, true)) {
337+
$types[] = 'xmls:integer';
338+
}
339+
break;
333340
case Type::BUILTIN_TYPE_FLOAT:
334-
return 'xmls:decimal';
341+
if (!\in_array('xmls:decimal', $types, true)) {
342+
$types[] = 'xmls:decimal';
343+
}
344+
break;
335345
case Type::BUILTIN_TYPE_BOOL:
336-
return 'xmls:boolean';
346+
if (!\in_array('xmls:boolean', $types, true)) {
347+
$types[] = 'xmls:boolean';
348+
}
349+
break;
337350
case Type::BUILTIN_TYPE_OBJECT:
338351
if (null === $className = $type->getClassName()) {
339-
return null;
352+
continue 2;
340353
}
341354

342355
if (is_a($className, \DateTimeInterface::class, true)) {
343-
return 'xmls:dateTime';
356+
if (!\in_array('xmls:dateTime', $types, true)) {
357+
$types[] = 'xmls:dateTime';
358+
}
359+
break;
344360
}
345361

346362
if ($this->resourceClassResolver->isResourceClass($className)) {
347363
$resourceMetadata = $this->resourceMetadataFactory->create($className);
348364
$operation = $resourceMetadata->getOperation();
349365

350-
if (!$operation instanceof HttpOperation) {
351-
return "#{$operation->getShortName()}";
366+
if (!$operation instanceof HttpOperation || !$operation->getTypes()) {
367+
if (!\in_array("#{$operation->getShortName()}", $types, true)) {
368+
$types[] = "#{$operation->getShortName()}";
369+
}
370+
break;
352371
}
353372

354-
return $operation->getTypes()[0] ?? "#{$operation->getShortName()}";
373+
$types = array_unique(array_merge($types, $operation->getTypes()));
374+
break;
355375
}
356376
}
357377
}
358378

359-
return null;
379+
if ([] === $types) {
380+
return null;
381+
}
382+
383+
return 1 === \count($types) ? $types[0] : $types;
360384
}
361385

362386
/**
@@ -461,15 +485,6 @@ private function getProperty(ApiProperty $propertyMetadata, string $propertyName
461485
'domain' => $prefixedShortName,
462486
];
463487

464-
$types = $propertyMetadata->getBuiltinTypes() ?? [];
465-
466-
foreach ($types as $type) {
467-
if (!$type->isCollection() && (null !== $className = $type->getClassName()) && $this->resourceClassResolver->isResourceClass($className)) {
468-
$propertyData['owl:maxCardinality'] = 1;
469-
break;
470-
}
471-
}
472-
473488
$property = [
474489
'@type' => 'hydra:SupportedProperty',
475490
'hydra:property' => $propertyData,
@@ -487,7 +502,7 @@ private function getProperty(ApiProperty $propertyMetadata, string $propertyName
487502
$property['hydra:description'] = $description;
488503
}
489504

490-
if ($deprecationReason = $propertyMetadata->getDeprecationReason()) {
505+
if ($propertyMetadata->getDeprecationReason()) {
491506
$property['owl:deprecated'] = true;
492507
}
493508

src/JsonSchema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ public function create(string $resourceClass, string $property, array $options =
116116
$className = $valueType->getClassName();
117117
}
118118

119+
if (!\array_key_exists('owl:maxCardinality', $propertySchema) &&
120+
!$isCollection
121+
&& null !== $className
122+
&& $this->resourceClassResolver->isResourceClass($className)
123+
) {
124+
$propertySchema['owl:maxCardinality'] = 1;
125+
}
126+
119127
$propertyType = $this->getType(new Type($builtinType, $type->isNullable(), $className, $isCollection, $keyType, $valueType), $propertyMetadata->isReadableLink());
120128
if (!\in_array($propertyType, $valueSchema, true)) {
121129
$valueSchema[] = $propertyType;
@@ -142,24 +150,24 @@ public function create(string $resourceClass, string $property, array $options =
142150

143151
private function getType(Type $type, ?bool $readableLink = null): array
144152
{
145-
if (!$type->isCollection()) {
146-
return $this->addNullabilityToTypeDefinition($this->makeBasicType($type, $readableLink), $type);
147-
}
153+
if (!$type->isCollection()) {
154+
return $this->addNullabilityToTypeDefinition($this->typeToArray($type, $readableLink), $type);
155+
}
148156

149-
$keyType = $type->getCollectionKeyTypes()[0] ?? null;
150-
$subType = ($type->getCollectionValueTypes()[0] ?? null) ?? new Type($type->getBuiltinType(), false, $type->getClassName(), false);
157+
$keyType = $type->getCollectionKeyTypes()[0] ?? null;
158+
$subType = ($type->getCollectionValueTypes()[0] ?? null) ?? new Type($type->getBuiltinType(), false, $type->getClassName(), false);
151159

152-
if (null !== $keyType && Type::BUILTIN_TYPE_STRING === $keyType->getBuiltinType()) {
153-
return $this->addNullabilityToTypeDefinition([
154-
'type' => 'object',
155-
'additionalProperties' => $this->getType($subType, $readableLink),
156-
], $type);
157-
}
160+
if (null !== $keyType && Type::BUILTIN_TYPE_STRING === $keyType->getBuiltinType()) {
161+
return $this->addNullabilityToTypeDefinition([
162+
'type' => 'object',
163+
'additionalProperties' => $this->getType($subType, $readableLink),
164+
], $type);
165+
}
158166

159-
return $this->addNullabilityToTypeDefinition([
160-
'type' => 'array',
161-
'items' => $this->getType($subType, $readableLink),
162-
], $type);
167+
return $this->addNullabilityToTypeDefinition([
168+
'type' => 'array',
169+
'items' => $this->getType($subType, $readableLink),
170+
], $type);
163171
}
164172

165173
private function typeToArray(Type $type, ?bool $readableLink = null): array

src/JsonSchema/SchemaFactory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ private function buildPropertySchema(Schema $schema, string $definitionName, str
191191

192192
$subSchema = $this->buildSchema($className, $format, Schema::TYPE_OUTPUT, null, $subSchema, $serializerContext, false);
193193
$propertySchema['anyOf'] = [['$ref' => $subSchema['$ref']], ['type' => 'null']];
194+
// prevent "type" and "anyOf" conflict
194195
unset($propertySchema['type']);
195196
break;
196197
}

src/Metadata/Property/Factory/SerializerPropertyMetadataFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ private function transformLinkStatus(ApiProperty $propertyMetadata, array $norma
125125

126126
// if property is not a resource relation, don't set link status (as it would have no meaning)
127127
if (null === $relatedClass || !$this->isResourceClass($relatedClass)) {
128-
return $propertyMetadata;
128+
continue;
129129
}
130130

131131
// find the resource class

0 commit comments

Comments
 (0)