/**
* Resolve schema references to object
*
* @param array $schema segment Api specifications
* @param mixed $specObject optional object schema view
* @return DetailResponse|ListResponse
*/
protected function resolveReferences($schema, $specObject = null)
{
$ref = '$ref';
if (array_key_exists($ref, $schema)) {
$refPath = explode('/', ltrim($schema[$ref], '#/'));
unset($schema[$ref]);
$object = AbstractSpecObject::init($refPath[1]);
if (is_null($specObject)) {
$specObject = $object;
} else {
$specObject->entity = $object;
foreach ($schema as $key => $value) {
$specObject->{$key} = $value;
}
}
$schema = $this->getPath(...$refPath);
} else {
if (is_null($specObject)) {
$specObject = new Property();
}
$object = $specObject;
}
if (array_key_exists('items', $schema)) {
$object->items = $this->resolveReferences($schema['items']);
unset($schema['items']);
}
if (array_key_exists('properties', $schema)) {
foreach ($schema['properties'] as $nameProp => $prop) {
if (!array_key_exists('type', $prop)) {
$prop['type'] = $nameProp;
}
$object->{$nameProp} = $this->resolveReferences($prop, new Property($nameProp));
}
unset($schema['properties']);
}
if (array_key_exists('x-concreteTypes', $schema)) {
foreach ($schema['x-concreteTypes'] as $prop) {
$enumObject = $this->resolveReferences($prop);
$object->concreteTypes[$enumObject->getObjectName()] = $enumObject;
}
unset($schema['x-concreteTypes']);
}
foreach ($schema as $key => $value) {
$object->{$key} = $value;
}
return $specObject;
}