private function parseProperty(ResourceMetadata $resourceMetadata, PropertyMetadata $propertyMetadata, $io, Type $type = null, array $visited = [])
{
$data = ['dataType' => null, 'required' => $propertyMetadata->isRequired(), 'description' => $propertyMetadata->getDescription(), 'readonly' => !$propertyMetadata->isWritable()];
if (null === $type && null === ($type = $propertyMetadata->getType())) {
// Default to string
$data['dataType'] = DataTypes::STRING;
return $data;
}
if ($type->isCollection()) {
$data['actualType'] = DataTypes::COLLECTION;
if ($collectionType = $type->getCollectionValueType()) {
$subProperty = $this->parseProperty($resourceMetadata, $propertyMetadata, $io, $collectionType, $visited);
if (self::TYPE_IRI === $subProperty['dataType']) {
$data['dataType'] = 'array of IRIs';
$data['subType'] = DataTypes::STRING;
return $data;
}
$data['subType'] = $subProperty['subType'];
if (isset($subProperty['children'])) {
$data['children'] = $subProperty['children'];
}
}
return $data;
}
$builtinType = $type->getBuiltinType();
if ('object' === $builtinType) {
$className = $type->getClassName();
if (is_subclass_of($className, \DateTimeInterface::class)) {
$data['dataType'] = DataTypes::DATETIME;
$data['format'] = sprintf('{DateTime %s}', \DateTime::RFC3339);
return $data;
}
try {
$this->resourceMetadataFactory->create($className);
} catch (ResourceClassNotFoundException $e) {
$data['actualType'] = DataTypes::MODEL;
$data['subType'] = $className;
return $data;
}
if (self::OUT_PREFIX === $io && true !== $propertyMetadata->isReadableLink() || self::IN_PREFIX === $io && true !== $propertyMetadata->isWritableLink()) {
$data['dataType'] = self::TYPE_IRI;
$data['actualType'] = DataTypes::STRING;
return $data;
}
$data['actualType'] = DataTypes::MODEL;
$data['subType'] = $className;
$data['children'] = in_array($className, $visited) ? [] : $this->parseResource($resourceMetadata, $className, $io);
return $data;
}
$data['dataType'] = self::TYPE_MAP[$builtinType] ?? DataTypes::STRING;
return $data;
}