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->modelDescribers = $modelDescribers;
$this->api = $api; $this->api = $api;
$this->alternativeNames = array_reverse($alternativeNames); // last rule wins $this->alternativeNames = []; // last rule wins
foreach ($this->alternativeNames as $alternativeName => $criteria) { foreach (array_reverse($alternativeNames) as $alternativeName => $criteria) {
$this->doRegister(new Model(new Type('object', false, $criteria['type']), $criteria['groups']), $alternativeName); $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 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(); $hash = $model->getHash();
if (isset($this->names[$hash])) { if (!isset($this->models[$hash])) {
return '#/definitions/'.$this->names[$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 // 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); $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])) { if (isset($groups[$name]) && is_array($groups[$name])) {
$previousGroups = $groups; $previousGroups = $groups;
$groups = $model->getGroups()[$name]; $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 = $this->previousGroups[spl_object_hash($model)]; use this for jms/serializer 2.0
$groups = false === $this->propertyTypeUsesGroups($item->type) ? null : [GroupsExclusionStrategy::DEFAULT_GROUP]; $groups = false === $this->propertyTypeUsesGroups($item->type) ? null : [GroupsExclusionStrategy::DEFAULT_GROUP];
} elseif (is_array($groups)) { } elseif (is_array($groups)) {
@ -171,12 +171,11 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
return null; return null;
} }
$property->setRef($this->modelRegistry->register( $model = new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $type['name']), $groups);
new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $type['name']), $groups) $property->setRef($this->modelRegistry->register($model));
));
if ($previousGroups) { 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) 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']]; return $this->propertyTypeUseGroupsCache[$type['name']];
} }