Skip to content

Commit

Permalink
fix(jsonapi): handle multiple relation classes, unrelated unions
Browse files Browse the repository at this point in the history
  • Loading branch information
GwendolenLynch committed Apr 16, 2024
1 parent af61482 commit 9e89480
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions src/JsonApi/JsonSchema/SchemaFactory.php
Expand Up @@ -184,17 +184,21 @@ private function buildDefinitionPropertiesSchema(string $key, string $className,
$relatedDefinitions = [];
foreach ($properties as $propertyName => $property) {
if ($relation = $this->getRelationship($className, $propertyName, $serializerContext)) {
[$isOne, $hasOperations, $relatedClassName] = $relation;
if (false === $hasOperations) {
continue;
}
[$isOne, $relatedClasses] = $relation;
$refs = [];
foreach ($relatedClasses as $relatedClassName => $hasOperations) {
if (false === $hasOperations) {
continue;
}

$operation = $this->findOperation($relatedClassName, $type, $operation, $serializerContext);
$inputOrOutputClass = $this->findOutputClass($relatedClassName, $type, $operation, $serializerContext);
$serializerContext ??= $this->getSerializerContext($operation, $type);
$definitionName = $this->definitionNameFactory->create($relatedClassName, $format, $inputOrOutputClass, $operation, $serializerContext);
$ref = Schema::VERSION_OPENAPI === $schema->getVersion() ? '#/components/schemas/'.$definitionName : '#/definitions/'.$definitionName;
$relatedDefinitions[$propertyName] = ['$ref' => $ref];
$operation = $this->findOperation($relatedClassName, $type, $operation, $serializerContext);
$inputOrOutputClass = $this->findOutputClass($relatedClassName, $type, $operation, $serializerContext);
$serializerContext ??= $this->getSerializerContext($operation, $type);
$definitionName = $this->definitionNameFactory->create($relatedClassName, $format, $inputOrOutputClass, $operation, $serializerContext);
$ref = Schema::VERSION_OPENAPI === $schema->getVersion() ? '#/components/schemas/'.$definitionName : '#/definitions/'.$definitionName;
$refs[$ref] = '$ref';
}
$relatedDefinitions[$propertyName] = array_flip($refs);
if ($isOne) {
$relationships[$propertyName]['properties']['data'] = self::RELATION_PROPS;
continue;
Expand All @@ -203,7 +207,6 @@ private function buildDefinitionPropertiesSchema(string $key, string $className,
'type' => 'array',
'items' => self::RELATION_PROPS,
];
continue;
}
if ('id' === $propertyName) {
$attributes['_id'] = $property;
Expand Down Expand Up @@ -264,7 +267,7 @@ private function getRelationship(string $resourceClass, string $property, ?array
$types = $propertyMetadata->getBuiltinTypes() ?? [];
$isRelationship = false;
$isOne = $isMany = false;
$className = $hasOperations = null;
$relatedClasses = [];

foreach ($types as $type) {
if ($type->isCollection()) {
Expand All @@ -281,9 +284,9 @@ private function getRelationship(string $resourceClass, string $property, ?array
$operation = $resourceMetadata->getOperation();
// @see https://github.com/api-platform/core/issues/5501
// @see https://github.com/api-platform/core/pull/5722
$hasOperations ??= $operation->canRead();
$relatedClasses[$className] = $operation->canRead();
}

return $isRelationship ? [$isOne, $hasOperations, $className] : null;
return $isRelationship ? [$isOne, $relatedClasses] : null;
}
}

0 comments on commit 9e89480

Please sign in to comment.