diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index 1a06740..45ef620 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -14,7 +14,6 @@ namespace Nelmio\ApiDocBundle\ModelDescriber; use Doctrine\Common\Annotations\Reader; use EXSyst\Component\Swagger\Schema; use JMS\Serializer\Exclusion\GroupsExclusionStrategy; -use JMS\Serializer\Metadata\PropertyMetadata; use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use JMS\Serializer\SerializationContext; use Metadata\MetadataFactoryInterface; @@ -92,33 +91,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn continue; } - if ($nestedType = $this->getNestedTypeInArray($item)) { - list($type, $isHash) = $nestedType; - if ($isHash) { - $property->setType('object'); - - $typeDef = $this->findPropertyType($type, $groups); - - // in the case of a virtual property, set it as free object type - $property->merge(['additionalProperties' => $typeDef ?: []]); - - continue; - } else { - $property->setType('array'); - $property = $property->getItems(); - } - } else { - $type = $item->type['name']; - } - - $typeDef = $this->findPropertyType($type, $groups); - - // virtual property - if (!$typeDef) { - continue; - } - - $this->registerPropertyType($typeDef, $property); + $this->describeItem($item->type, $property, $groups); } } @@ -186,25 +159,40 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn } } - /** - * @param PropertyMetadata $item - * - * @return array|null - */ - private function getNestedTypeInArray(PropertyMetadata $item) + private function describeItem(array $type, $property, array $groups = null) { - if ('array' !== $item->type['name'] && 'ArrayCollection' !== $item->type['name']) { + if (list($nestedType, $isHash) = $this->getNestedTypeInArray($type)) { // @ todo update a bit getNestedTypeInArray and describe ($type = $item->type) + if ($isHash) { + $property->setType('object'); + // in the case of a virtual property, set it as free object type + $property->merge(['additionalProperties' => []]); + + $this->describeItem($nestedType, $property->getAdditionalProperties(), $groups); + + return; + } + + $property->setType('array'); + $this->describeItem($nestedType, $property->getItems(), $groups); + } + + if ($typeDef = $this->findPropertyType($type['name'], $groups)) { + $this->registerPropertyType($typeDef, $property); + } + } + + private function getNestedTypeInArray(array $type) + { + if ('array' !== $type['name'] && 'ArrayCollection' !== $type['name']) { return null; } - // array - if (isset($item->type['params'][1]['name'])) { - return [$item->type['params'][1]['name'], true]; + if (isset($type['params'][1]['name'])) { + return [$type['params'][1], true]; } - // array - if (isset($item->type['params'][0]['name'])) { - return [$item->type['params'][0]['name'], false]; + if (isset($type['params'][0]['name'])) { + return [$type['params'][0], false]; } return null; diff --git a/Tests/Functional/Entity/JMSUser.php b/Tests/Functional/Entity/JMSUser.php index f619a7e..9f457a9 100644 --- a/Tests/Functional/Entity/JMSUser.php +++ b/Tests/Functional/Entity/JMSUser.php @@ -126,6 +126,12 @@ class JMSUser */ private $status; + /** + * @Serializer\Type("array>") + * @Serializer\Expose + */ + private $latLonHistory; + public function setRoles($roles) { } diff --git a/Tests/Functional/JMSFunctionalTest.php b/Tests/Functional/JMSFunctionalTest.php index 6c9f2c7..4e264b3 100644 --- a/Tests/Functional/JMSFunctionalTest.php +++ b/Tests/Functional/JMSFunctionalTest.php @@ -83,6 +83,16 @@ class JMSFunctionalTest extends WebTestCase 'last_update' => [ 'type' => 'date', ], + 'lat_lon_history' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'number', + 'format' => 'float', + ], + ], + ], ], ], $this->getModel('JMSUser')->toArray()); }