Inject the AnnotationsReader in Model describers instead of internal classes (#1203)

This commit is contained in:
Guilhem N 2018-01-24 19:58:38 +01:00 committed by GitHub
parent fe9d12772b
commit f193fdb1f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 100 deletions

View File

@ -130,9 +130,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI
->setArguments([ ->setArguments([
new Reference('jms_serializer.metadata_factory'), new Reference('jms_serializer.metadata_factory'),
new Reference('jms_serializer.naming_strategy'), new Reference('jms_serializer.naming_strategy'),
new Reference('nelmio_api_doc.model_describers.swagger_property_annotation_reader'), new Reference('annotation_reader'),
new Reference('nelmio_api_doc.model_describers.swagger_definition_annotation_reader'),
new Reference('nelmio_api_doc.model_describers.phpdoc_property_annotation_reader'),
]) ])
->addTag('nelmio_api_doc.model_describer', ['priority' => 50]); ->addTag('nelmio_api_doc.model_describer', ['priority' => 50]);
} }

View File

@ -0,0 +1,45 @@
<?php
/*
* This file is part of the NelmioApiDocBundle package.
*
* (c) Nelmio
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
use Doctrine\Common\Annotations\Reader;
use EXSyst\Component\Swagger\Schema;
/**
* @internal
*/
class AnnotationsReader
{
private $annotationsReader;
private $phpDocReader;
private $swgAnnotationsReader;
public function __construct(Reader $annotationsReader)
{
$this->annotationsReader = $annotationsReader;
$this->phpDocReader = new PropertyPhpDocReader();
$this->swgAnnotationsReader = new SwgAnnotationsReader($annotationsReader);
}
public function updateDefinition(\ReflectionClass $reflectionClass, Schema $schema)
{
$this->swgAnnotationsReader->updateDefinition($reflectionClass, $schema);
}
public function updateProperty(\ReflectionProperty $reflectionProperty, Schema $property)
{
$this->phpDocReader->updateProperty($reflectionProperty, $property);
$this->swgAnnotationsReader->updateProperty($reflectionProperty, $property);
}
}

View File

@ -9,34 +9,30 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Nelmio\ApiDocBundle\ModelDescriber; namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
use EXSyst\Component\Swagger\Schema; use EXSyst\Component\Swagger\Schema;
use phpDocumentor\Reflection\DocBlock\Tags\Var_; use phpDocumentor\Reflection\DocBlock\Tags\Var_;
use phpDocumentor\Reflection\DocBlockFactory; use phpDocumentor\Reflection\DocBlockFactory;
use phpDocumentor\Reflection\DocBlockFactoryInterface;
/** /**
* Extract information about properties of a model from the DocBlock comment. * Extract information about properties of a model from the DocBlock comment.
* *
* @internal * @internal
*/ */
class PhpdocPropertyAnnotationReader class PropertyPhpDocReader
{ {
private $docBlockFactory; private $docBlockFactory;
public function __construct(DocBlockFactoryInterface $docBlockFactory = null) public function __construct()
{ {
if (null === $docBlockFactory) { $this->docBlockFactory = DocBlockFactory::createInstance();
$docBlockFactory = DocBlockFactory::createInstance();
}
$this->docBlockFactory = $docBlockFactory;
} }
/** /**
* Update the Swagger information with information from the DocBlock comment. * Update the Swagger information with information from the DocBlock comment.
*/ */
public function updateWithPhpdoc(\ReflectionProperty $reflectionProperty, Schema $property) public function updateProperty(\ReflectionProperty $reflectionProperty, Schema $property)
{ {
try { try {
$docBlock = $this->docBlockFactory->create($reflectionProperty); $docBlock = $this->docBlockFactory->create($reflectionProperty);

View File

@ -9,16 +9,17 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Nelmio\ApiDocBundle\ModelDescriber; namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
use Doctrine\Common\Annotations\Reader; use Doctrine\Common\Annotations\Reader;
use EXSyst\Component\Swagger\Schema; use EXSyst\Component\Swagger\Schema;
use Swagger\Annotations\Definition as SwgDefinition; use Swagger\Annotations\Definition as SwgDefinition;
use Swagger\Annotations\Property as SwgProperty;
/** /**
* @internal * @internal
*/ */
class SwaggerDefinitionAnnotationReader class SwgAnnotationsReader
{ {
private $annotationsReader; private $annotationsReader;
@ -27,7 +28,7 @@ class SwaggerDefinitionAnnotationReader
$this->annotationsReader = $annotationsReader; $this->annotationsReader = $annotationsReader;
} }
public function updateWithSwaggerDefinitionAnnotation(\ReflectionClass $reflectionClass, Schema $schema) public function updateDefinition(\ReflectionClass $reflectionClass, Schema $schema)
{ {
/** @var SwgDefinition $swgDefinition */ /** @var SwgDefinition $swgDefinition */
if (!$swgDefinition = $this->annotationsReader->getClassAnnotation($reflectionClass, SwgDefinition::class)) { if (!$swgDefinition = $this->annotationsReader->getClassAnnotation($reflectionClass, SwgDefinition::class)) {
@ -38,4 +39,18 @@ class SwaggerDefinitionAnnotationReader
$schema->setRequired($swgDefinition->required); $schema->setRequired($swgDefinition->required);
} }
} }
public function updateProperty(\ReflectionProperty $reflectionProperty, Schema $property)
{
/** @var SwgProperty $swgProperty */
if (!$swgProperty = $this->annotationsReader->getPropertyAnnotation($reflectionProperty, SwgProperty::class)) {
return;
}
if (!$swgProperty->validate()) {
return;
}
$property->merge(json_decode(json_encode($swgProperty)));
}
} }

View File

@ -11,6 +11,7 @@
namespace Nelmio\ApiDocBundle\ModelDescriber; namespace Nelmio\ApiDocBundle\ModelDescriber;
use Doctrine\Common\Annotations\Reader;
use EXSyst\Component\Swagger\Schema; use EXSyst\Component\Swagger\Schema;
use JMS\Serializer\Exclusion\GroupsExclusionStrategy; use JMS\Serializer\Exclusion\GroupsExclusionStrategy;
use JMS\Serializer\Metadata\PropertyMetadata; use JMS\Serializer\Metadata\PropertyMetadata;
@ -20,6 +21,7 @@ use Metadata\MetadataFactoryInterface;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
use Nelmio\ApiDocBundle\Model\Model; use Nelmio\ApiDocBundle\Model\Model;
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
use Symfony\Component\PropertyInfo\Type; use Symfony\Component\PropertyInfo\Type;
/** /**
@ -30,27 +32,17 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
use ModelRegistryAwareTrait; use ModelRegistryAwareTrait;
private $factory; private $factory;
private $namingStrategy; private $namingStrategy;
private $annotationsReader;
private $swaggerPropertyAnnotationReader;
private $swaggerDefinitionAnnotationReader;
private $phpdocPropertyAnnotationsReader;
public function __construct( public function __construct(
MetadataFactoryInterface $factory, MetadataFactoryInterface $factory,
PropertyNamingStrategyInterface $namingStrategy, PropertyNamingStrategyInterface $namingStrategy,
SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader, Reader $reader
SwaggerDefinitionAnnotationReader $swaggerDefinitionAnnotationReader,
PhpdocPropertyAnnotationReader $phpdocPropertyAnnotationReader = null
) { ) {
$this->factory = $factory; $this->factory = $factory;
$this->namingStrategy = $namingStrategy; $this->namingStrategy = $namingStrategy;
$this->swaggerPropertyAnnotationReader = $swaggerPropertyAnnotationReader; $this->annotationsReader = new AnnotationsReader($reader);
$this->swaggerDefinitionAnnotationReader = $swaggerDefinitionAnnotationReader;
$this->phpdocPropertyAnnotationsReader = $phpdocPropertyAnnotationReader;
} }
/** /**
@ -67,7 +59,8 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
$groupsExclusion = null !== $model->getGroups() ? new GroupsExclusionStrategy($model->getGroups()) : null; $groupsExclusion = null !== $model->getGroups() ? new GroupsExclusionStrategy($model->getGroups()) : null;
$schema->setType('object'); $schema->setType('object');
$this->swaggerDefinitionAnnotationReader->updateWithSwaggerDefinitionAnnotation(new \ReflectionClass($className), $schema); $this->annotationsReader->updateDefinition(new \ReflectionClass($className), $schema);
$properties = $schema->getProperties(); $properties = $schema->getProperties();
foreach ($metadata->propertyMetadata as $item) { foreach ($metadata->propertyMetadata as $item) {
// filter groups // filter groups
@ -80,10 +73,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn
// read property options from Swagger Property annotation if it exists // read property options from Swagger Property annotation if it exists
if (null !== $item->reflection) { if (null !== $item->reflection) {
if ($this->phpdocPropertyAnnotationsReader) { $this->annotationsReader->updateProperty($item->reflection, $property);
$this->phpdocPropertyAnnotationsReader->updateWithPhpdoc($item->reflection, $property);
}
$this->swaggerPropertyAnnotationReader->updateWithSwaggerPropertyAnnotation($item->reflection, $property);
} }
if (null !== $property->getType()) { if (null !== $property->getType()) {

View File

@ -11,10 +11,12 @@
namespace Nelmio\ApiDocBundle\ModelDescriber; namespace Nelmio\ApiDocBundle\ModelDescriber;
use Doctrine\Common\Annotations\Reader;
use EXSyst\Component\Swagger\Schema; use EXSyst\Component\Swagger\Schema;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
use Nelmio\ApiDocBundle\Model\Model; use Nelmio\ApiDocBundle\Model\Model;
use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface; use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
use Symfony\Component\PropertyInfo\Type; use Symfony\Component\PropertyInfo\Type;
@ -23,19 +25,16 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar
use ModelRegistryAwareTrait; use ModelRegistryAwareTrait;
private $propertyInfo; private $propertyInfo;
private $annotationsReader;
private $swaggerPropertyAnnotationReader;
private $swaggerDefinitionAnnotationReader; private $swaggerDefinitionAnnotationReader;
public function __construct( public function __construct(
PropertyInfoExtractorInterface $propertyInfo, PropertyInfoExtractorInterface $propertyInfo,
SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader, Reader $reader
SwaggerDefinitionAnnotationReader $swaggerDefinitionAnnotationReader
) { ) {
$this->propertyInfo = $propertyInfo; $this->propertyInfo = $propertyInfo;
$this->swaggerPropertyAnnotationReader = $swaggerPropertyAnnotationReader; $this->annotationsReader = new AnnotationsReader($reader);
$this->swaggerDefinitionAnnotationReader = $swaggerDefinitionAnnotationReader;
} }
public function describe(Model $model, Schema $schema) public function describe(Model $model, Schema $schema)
@ -48,7 +47,7 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar
if (null !== $model->getGroups()) { if (null !== $model->getGroups()) {
$context = ['serializer_groups' => $model->getGroups()]; $context = ['serializer_groups' => $model->getGroups()];
} }
$this->swaggerDefinitionAnnotationReader->updateWithSwaggerDefinitionAnnotation(new \ReflectionClass($class), $schema); $this->annotationsReader->updateDefinition(new \ReflectionClass($class), $schema);
$propertyInfoProperties = $this->propertyInfo->getProperties($class, $context); $propertyInfoProperties = $this->propertyInfo->getProperties($class, $context);
if (null === $propertyInfoProperties) { if (null === $propertyInfoProperties) {
@ -60,7 +59,7 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar
// read property options from Swagger Property annotation if it exists // read property options from Swagger Property annotation if it exists
if (property_exists($class, $propertyName)) { if (property_exists($class, $propertyName)) {
$this->swaggerPropertyAnnotationReader->updateWithSwaggerPropertyAnnotation( $this->annotationsReader->updateProperty(
new \ReflectionProperty($class, $propertyName), new \ReflectionProperty($class, $propertyName),
$property $property
); );

View File

@ -1,43 +0,0 @@
<?php
/*
* This file is part of the NelmioApiDocBundle package.
*
* (c) Nelmio
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Nelmio\ApiDocBundle\ModelDescriber;
use Doctrine\Common\Annotations\Reader;
use EXSyst\Component\Swagger\Schema;
use Swagger\Annotations\Property as SwgProperty;
/**
* @internal
*/
class SwaggerPropertyAnnotationReader
{
private $annotationsReader;
public function __construct(Reader $annotationsReader)
{
$this->annotationsReader = $annotationsReader;
}
public function updateWithSwaggerPropertyAnnotation(\ReflectionProperty $reflectionProperty, Schema $property)
{
/** @var SwgProperty $swgProperty */
if (!$swgProperty = $this->annotationsReader->getPropertyAnnotation($reflectionProperty, SwgProperty::class)) {
return;
}
if (!$swgProperty->validate()) {
return;
}
$property->merge(\json_decode(\json_encode($swgProperty)));
}
}

View File

@ -39,24 +39,9 @@
</service> </service>
<!-- Model Describers --> <!-- Model Describers -->
<service id="nelmio_api_doc.model_describers.swagger_property_annotation_reader" class="Nelmio\ApiDocBundle\ModelDescriber\SwaggerPropertyAnnotationReader" public="false">
<argument type="service" id="annotation_reader" />
</service>
<service id="nelmio_api_doc.model_describers.swagger_definition_annotation_reader" class="Nelmio\ApiDocBundle\ModelDescriber\SwaggerDefinitionAnnotationReader" public="false">
<argument type="service" id="annotation_reader" />
</service>
<service
id="nelmio_api_doc.model_describers.phpdoc_property_annotation_reader"
class="Nelmio\ApiDocBundle\ModelDescriber\PhpdocPropertyAnnotationReader"
public="false"
/>
<service id="nelmio_api_doc.model_describers.object" class="Nelmio\ApiDocBundle\ModelDescriber\ObjectModelDescriber" public="false"> <service id="nelmio_api_doc.model_describers.object" class="Nelmio\ApiDocBundle\ModelDescriber\ObjectModelDescriber" public="false">
<argument type="service" id="property_info" /> <argument type="service" id="property_info" />
<argument type="service" id="nelmio_api_doc.model_describers.swagger_property_annotation_reader" /> <argument type="service" id="annotation_reader" />
<argument type="service" id="nelmio_api_doc.model_describers.swagger_definition_annotation_reader" />
<tag name="nelmio_api_doc.model_describer" /> <tag name="nelmio_api_doc.model_describer" />
</service> </service>