Restore jms nested groups feature (#1402)

* fix missing variable definition

* fix caching typo

* do not pre allocate reserved names

* use model hash instead of spl hash

* register later the model
This commit is contained in:
Asmir Mustafic 2018-10-10 17:24:13 +02:00 committed by Guilhem N
parent cd40d556cb
commit 7f78ef9ba6
2 changed files with 25 additions and 25 deletions

View File

@ -40,36 +40,30 @@ final class ModelRegistry
{
$this->modelDescribers = $modelDescribers;
$this->api = $api;
$this->alternativeNames = array_reverse($alternativeNames); // last rule wins
$this->alternativeNames = []; // last rule wins
foreach ($this->alternativeNames as $alternativeName => $criteria) {
$this->doRegister(new Model(new Type('object', false, $criteria['type']), $criteria['groups']), $alternativeName);
foreach (array_reverse($alternativeNames) as $alternativeName => $criteria) {
$this->alternativeNames[] = $model = new Model(new Type('object', false, $criteria['type']), $criteria['groups']);
$this->names[$model->getHash()] = $alternativeName;
$this->api->getDefinitions()->get($alternativeName);
}
}
public function register(Model $model): string
{
return $this->doRegister($model);
}
/**
* Private method allowing to enforce the model name for alternative names.
*/
private function doRegister(Model $model, string $name = null)
{
$hash = $model->getHash();
if (isset($this->names[$hash])) {
return '#/definitions/'.$this->names[$hash];
if (!isset($this->models[$hash])) {
$this->models[$hash] = $model;
$this->unregistered[] = $hash;
}
if (!isset($this->names[$hash])) {
$this->names[$hash] = $this->generateModelName($model);
}
$this->names[$hash] = $name = ($name ?? $this->generateModelName($model));
$this->models[$hash] = $model;
$this->unregistered[] = $hash;
// Reserve the name
$this->api->getDefinitions()->get($name);
$this->api->getDefinitions()->get($this->names[$hash]);
return '#/definitions/'.$name;
return '#/definitions/'.$this->names[$hash];
}
/**
@ -104,6 +98,13 @@ final class ModelRegistry
$this->api->getDefinitions()->set($name, $schema);
}
if (0 === count($this->unregistered)) {
foreach ($this->alternativeNames as $model) {
$this->register($model);
}
$this->alternativeNames = [];
}
}
}

View File

@ -81,7 +81,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
if (isset($groups[$name]) && is_array($groups[$name])) {
$previousGroups = $groups;
$groups = $model->getGroups()[$name];
} elseif (!isset($groups[$name]) && !empty($this->previousGroups[spl_object_hash($model)])) {
} elseif (!isset($groups[$name]) && !empty($this->previousGroups[$model->getHash()])) {
// $groups = $this->previousGroups[spl_object_hash($model)]; use this for jms/serializer 2.0
$groups = false === $this->propertyTypeUsesGroups($item->type) ? null : [GroupsExclusionStrategy::DEFAULT_GROUP];
} elseif (is_array($groups)) {
@ -171,12 +171,11 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
return null;
}
$property->setRef($this->modelRegistry->register(
new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $type['name']), $groups)
));
$model = new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $type['name']), $groups);
$property->setRef($this->modelRegistry->register($model));
if ($previousGroups) {
$this->previousGroups[spl_object_hash($model)] = $previousGroups;
$this->previousGroups[$model->getHash()] = $previousGroups;
}
}
}
@ -205,7 +204,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
*/
private function propertyTypeUsesGroups(array $type)
{
if (!array_key_exists($type['name'], $this->propertyTypeUseGroupsCache)) {
if (array_key_exists($type['name'], $this->propertyTypeUseGroupsCache)) {
return $this->propertyTypeUseGroupsCache[$type['name']];
}