Make sure alternative names use the exact names specified (#1384)

* Make sure alternative names use the exact name specified

* Document the feature

* Cs
This commit is contained in:
Guilhem N 2018-08-26 22:15:44 +02:00 committed by GitHub
parent df9893428e
commit 31ae375ab5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 33 deletions

View File

@ -91,9 +91,12 @@ final class Configuration implements ConfigurationInterface
->children()
->scalarNode('alias')->isRequired()->end()
->scalarNode('type')->isRequired()->end()
->arrayNode('groups')
->defaultValue([])
->variablePrototype()->end()
->variableNode('groups')
->defaultValue(null)
->validate()
->ifTrue(function ($v) { return null !== $v && !is_array($v); })
->thenInvalid('Model groups must be either `null` or an array.')
->end()
->end()
->arrayNode('areas')
->defaultValue([])

View File

@ -41,16 +41,28 @@ final class ModelRegistry
$this->modelDescribers = $modelDescribers;
$this->api = $api;
$this->alternativeNames = array_reverse($alternativeNames); // last rule wins
foreach ($this->alternativeNames as $alternativeName => $criteria) {
$this->doRegister(new Model(new Type('object', false, $criteria['type']), $criteria['groups']), $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];
}
$this->names[$hash] = $name = $this->generateModelName($model);
$this->names[$hash] = $name = ($name ?? $this->generateModelName($model));
$this->models[$hash] = $model;
$this->unregistered[] = $hash;
@ -99,7 +111,7 @@ final class ModelRegistry
{
$definitions = $this->api->getDefinitions();
$name = $base = $this->getAlternativeName($model) ?? $this->getTypeShortName($model->getType());
$name = $base = $this->getTypeShortName($model->getType());
$i = 1;
while ($definitions->has($name)) {
@ -110,27 +122,6 @@ final class ModelRegistry
return $name;
}
/**
* @param Model $model
*
* @return string|null
*/
private function getAlternativeName(Model $model)
{
$type = $model->getType();
foreach ($this->alternativeNames as $alternativeName => $criteria) {
if (
Type::BUILTIN_TYPE_OBJECT === $type->getBuiltinType() &&
$type->getClassName() === $criteria['type'] &&
$criteria['groups'] == $model->getGroups()
) {
return $alternativeName;
}
}
return null;
}
private function getTypeShortName(Type $type): string
{
if (null !== $type->getCollectionValueType()) {

View File

@ -26,3 +26,26 @@ In this case the class ``App\Entity\User`` will be aliased into:
- ``MainUser_light`` when the group is equal to ``light``
- ``MainUser_secret`` for the ``private`` area
- ``MainUser`` for the ``private`` area when the group is equal to ``standard``
.. tip::
This allows to use normal references instead of ``@Model``. Notably, you can specify
the groups used for a model once in config and then refer to its alternative name:
.. code-block:: yaml
nelmio_api_doc:
models:
names: [ { alias: MyModel, type: App\MyModel, groups: [light] }]
.. code-block:: php
class HomeController
{
/**
* @SWG\Response(response=200, @SWG\Schema(ref="MyModel"))
*/
public function indexAction()
{
}
}

View File

@ -92,7 +92,7 @@ class ConfigurationTest extends TestCase
[
'alias' => 'Foo3',
'type' => 'App\Foo',
'groups' => [],
'groups' => null,
'areas' => [],
],
[
@ -104,7 +104,7 @@ class ConfigurationTest extends TestCase
[
'alias' => 'Foo1',
'type' => 'App\\Foo',
'groups' => [],
'groups' => null,
'areas' => ['internal'],
],
[

View File

@ -53,11 +53,11 @@ class NelmioApiDocExtensionTest extends TestCase
$this->assertEquals([
'Foo1' => [
'type' => 'App\\Foo',
'groups' => [],
'groups' => null,
],
'Test1' => [
'type' => 'App\\Test',
'groups' => [],
'groups' => null,
],
], $methodCall[1][0]);
$foundMethodCall = true;
@ -72,11 +72,11 @@ class NelmioApiDocExtensionTest extends TestCase
$this->assertEquals([
'Foo1' => [
'type' => 'App\\Bar',
'groups' => [],
'groups' => null,
],
'Test1' => [
'type' => 'App\\Test',
'groups' => [],
'groups' => null,
],
], $methodCall[1][0]);
$foundMethodCall = true;

View File

@ -80,7 +80,7 @@ class ModelRegistryTest extends TestCase
],
],
[
'#/definitions/Foo1',
'#/definitions/ModelRegistryTest',
null,
[
'Foo1' => [
@ -89,6 +89,16 @@ class ModelRegistryTest extends TestCase
],
],
],
[
'#/definitions/Foo1',
[],
[
'Foo1' => [
'type' => self::class,
'groups' => [],
],
],
],
];
}