diff --git a/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php b/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php index 322191afe4a..cc44bb0fb04 100644 --- a/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php +++ b/src/Bridge/NelmioApiDoc/Parser/ApiPlatformParser.php @@ -90,11 +90,14 @@ public function parse(array $item) : array * @param ResourceMetadata $resourceMetadata * @param string $resourceClass * @param string $io + * @param string[] $visited * * @return array */ - private function parseClass(ResourceMetadata $resourceMetadata, string $resourceClass, string $io) : array + private function parseClass(ResourceMetadata $resourceMetadata, string $resourceClass, string $io, array $visited = []) : array { + $visited[] = $resourceClass; + $attributes = $resourceMetadata->getAttributes(); $options = []; $data = []; @@ -114,7 +117,7 @@ private function parseClass(ResourceMetadata $resourceMetadata, string $resource ($propertyMetadata->isReadable() && self::OUT_PREFIX === $io) || ($propertyMetadata->isWritable() && self::IN_PREFIX === $io) ) { - $data[$name] = $this->parseProperty($resourceMetadata, $propertyMetadata, $io); + $data[$name] = $this->parseProperty($resourceMetadata, $propertyMetadata, $io, null, $visited); } } @@ -128,10 +131,11 @@ private function parseClass(ResourceMetadata $resourceMetadata, string $resource * @param PropertyMetadata $propertyMetadata * @param string $io * @param Type|null $type + * @param string[] $visited * * @return array */ - private function parseProperty(ResourceMetadata $resourceMetadata, PropertyMetadata $propertyMetadata, $io, Type $type = null) + private function parseProperty(ResourceMetadata $resourceMetadata, PropertyMetadata $propertyMetadata, $io, Type $type = null, array $visited = []) { $data = [ 'dataType' => null, @@ -155,16 +159,16 @@ private function parseProperty(ResourceMetadata $resourceMetadata, PropertyMetad $data['actualType'] = DataTypes::COLLECTION; if ($collectionType = $type->getCollectionValueType()) { - $subAttribute = $this->parseProperty($resourceMetadata, $propertyMetadata, $io, $collectionType); - if (self::IRI === $subAttribute['dataType']) { + $subProperty = $this->parseProperty($resourceMetadata, $propertyMetadata, $io, $collectionType, $visited); + if (self::IRI === $subProperty['dataType']) { $data['dataType'] = 'array of IRIs'; $data['subType'] = DataTypes::STRING; return $data; } - $data['subType'] = $subAttribute['subType']; - $data['children'] = $subAttribute['children']; + $data['subType'] = $subProperty['subType']; + $data['children'] = $subProperty['children']; } return $data; @@ -193,7 +197,7 @@ private function parseProperty(ResourceMetadata $resourceMetadata, PropertyMetad $data['actualType'] = DataTypes::MODEL; $data['subType'] = $className; - $data['children'] = $this->parseClass($resourceMetadata, $className, $io); + $data['children'] = in_array($className, $visited) ? [] : $this->parseClass($resourceMetadata, $className, $io, $visited); return $data; }