Skip to content

Commit

Permalink
Handle circular references in DunglasApiParser
Browse files Browse the repository at this point in the history
Fixes nelmio#678, reverts nelmio#800
  • Loading branch information
teohhanhui committed Feb 18, 2016
1 parent 0754562 commit c1c711b
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions Parser/DunglasApiParser.php
Expand Up @@ -83,11 +83,14 @@ public function parse(array $item)
* @param ResourceInterface $resource
* @param string $entityClass
* @param string $io
* @param string[] $visited
*
* @return array
*/
private function parseClass(ResourceInterface $resource, $entityClass, $io)
private function parseClass(ResourceInterface $resource, $entityClass, $io, array $visited = array())
{
$visited[] = $entityClass;

$classMetadata = $this->classMetadataFactory->getMetadataFor(
$entityClass,
$resource->getNormalizationGroups(),
Expand All @@ -101,7 +104,7 @@ private function parseClass(ResourceInterface $resource, $entityClass, $io)
(!$attributeMetadata->isIdentifier() && $attributeMetadata->isReadable() && self::OUT_PREFIX === $io) ||
($attributeMetadata->isWritable() && self::IN_PREFIX === $io)
) {
$data[$attributeMetadata->getName()] = $this->parseAttribute($resource, $attributeMetadata, $io);
$data[$attributeMetadata->getName()] = $this->parseAttribute($resource, $attributeMetadata, $io, null, $visited);
}
}

Expand All @@ -115,10 +118,11 @@ private function parseClass(ResourceInterface $resource, $entityClass, $io)
* @param AttributeMetadataInterface $attributeMetadata
* @param string $io
* @param Type|null $type
* @param string[] $visited
*
* @return array
*/
private function parseAttribute(ResourceInterface $resource, AttributeMetadataInterface $attributeMetadata, $io, Type $type = null)
private function parseAttribute(ResourceInterface $resource, AttributeMetadataInterface $attributeMetadata, $io, Type $type = null, array $visited = array())
{
$data = array(
'dataType' => null,
Expand All @@ -143,7 +147,7 @@ private function parseAttribute(ResourceInterface $resource, AttributeMetadataIn
$data['actualType'] = DataTypes::COLLECTION;

if ($collectionType = $type->getCollectionType()) {
$subAttribute = $this->parseAttribute($resource, $attributeMetadata, $io, $collectionType);
$subAttribute = $this->parseAttribute($resource, $attributeMetadata, $io, $collectionType, $visited);
if (self::IRI === $subAttribute['dataType']) {
$data['dataType'] = 'array of IRIs';
$data['subType'] = DataTypes::STRING;
Expand Down Expand Up @@ -181,7 +185,7 @@ private function parseAttribute(ResourceInterface $resource, AttributeMetadataIn

$data['actualType'] = DataTypes::MODEL;
$data['subType'] = $class;
$data['children'] = $resource->getEntityClass() === $class ? [] : $this->parseClass($resource, $class, $io);
$data['children'] = in_array($class, $visited) ? [] : $this->parseClass($resource, $class, $io, $visited);

return $data;
}
Expand Down

0 comments on commit c1c711b

Please sign in to comment.