Handle circular references in DunglasApiParser

Fixes #678, reverts #800
This commit is contained in:
Teoh Han Hui 2016-02-18 23:18:43 +08:00
parent 07545629aa
commit c1c711bc26

View File

@ -83,11 +83,14 @@ class DunglasApiParser implements ParserInterface
* @param ResourceInterface $resource * @param ResourceInterface $resource
* @param string $entityClass * @param string $entityClass
* @param string $io * @param string $io
* @param string[] $visited
* *
* @return array * @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( $classMetadata = $this->classMetadataFactory->getMetadataFor(
$entityClass, $entityClass,
$resource->getNormalizationGroups(), $resource->getNormalizationGroups(),
@ -101,7 +104,7 @@ class DunglasApiParser implements ParserInterface
(!$attributeMetadata->isIdentifier() && $attributeMetadata->isReadable() && self::OUT_PREFIX === $io) || (!$attributeMetadata->isIdentifier() && $attributeMetadata->isReadable() && self::OUT_PREFIX === $io) ||
($attributeMetadata->isWritable() && self::IN_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);
} }
} }
@ -115,10 +118,11 @@ class DunglasApiParser implements ParserInterface
* @param AttributeMetadataInterface $attributeMetadata * @param AttributeMetadataInterface $attributeMetadata
* @param string $io * @param string $io
* @param Type|null $type * @param Type|null $type
* @param string[] $visited
* *
* @return array * @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( $data = array(
'dataType' => null, 'dataType' => null,
@ -143,7 +147,7 @@ class DunglasApiParser implements ParserInterface
$data['actualType'] = DataTypes::COLLECTION; $data['actualType'] = DataTypes::COLLECTION;
if ($collectionType = $type->getCollectionType()) { if ($collectionType = $type->getCollectionType()) {
$subAttribute = $this->parseAttribute($resource, $attributeMetadata, $io, $collectionType); $subAttribute = $this->parseAttribute($resource, $attributeMetadata, $io, $collectionType, $visited);
if (self::IRI === $subAttribute['dataType']) { if (self::IRI === $subAttribute['dataType']) {
$data['dataType'] = 'array of IRIs'; $data['dataType'] = 'array of IRIs';
$data['subType'] = DataTypes::STRING; $data['subType'] = DataTypes::STRING;
@ -181,7 +185,7 @@ class DunglasApiParser implements ParserInterface
$data['actualType'] = DataTypes::MODEL; $data['actualType'] = DataTypes::MODEL;
$data['subType'] = $class; $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; return $data;
} }