diff --git a/DependencyInjection/NelmioApiDocExtension.php b/DependencyInjection/NelmioApiDocExtension.php index 01fc733..1f303f0 100644 --- a/DependencyInjection/NelmioApiDocExtension.php +++ b/DependencyInjection/NelmioApiDocExtension.php @@ -131,6 +131,7 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI new Reference('jms_serializer.metadata_factory'), new Reference('jms_serializer.naming_strategy'), new Reference('nelmio_api_doc.model_describers.swagger_property_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]); diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index d7d13e7..45f5915 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -35,17 +35,21 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn private $swaggerPropertyAnnotationReader; + private $swaggerDefinitionAnnotationReader; + private $phpdocPropertyAnnotationsReader; public function __construct( MetadataFactoryInterface $factory, PropertyNamingStrategyInterface $namingStrategy, SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader, + SwaggerDefinitionAnnotationReader $swaggerDefinitionAnnotationReader, PhpdocPropertyAnnotationReader $phpdocPropertyAnnotationReader = null ) { $this->factory = $factory; $this->namingStrategy = $namingStrategy; $this->swaggerPropertyAnnotationReader = $swaggerPropertyAnnotationReader; + $this->swaggerDefinitionAnnotationReader = $swaggerDefinitionAnnotationReader; $this->phpdocPropertyAnnotationsReader = $phpdocPropertyAnnotationReader; } @@ -63,6 +67,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn $groupsExclusion = null !== $model->getGroups() ? new GroupsExclusionStrategy($model->getGroups()) : null; $schema->setType('object'); + $this->swaggerDefinitionAnnotationReader->updateWithSwaggerDefinitionAnnotation(new \ReflectionClass($className), $schema); $properties = $schema->getProperties(); foreach ($metadata->propertyMetadata as $item) { // filter groups diff --git a/ModelDescriber/ObjectModelDescriber.php b/ModelDescriber/ObjectModelDescriber.php index ee58483..1dea437 100644 --- a/ModelDescriber/ObjectModelDescriber.php +++ b/ModelDescriber/ObjectModelDescriber.php @@ -26,12 +26,16 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar private $swaggerPropertyAnnotationReader; + private $swaggerDefinitionAnnotationReader; + public function __construct( PropertyInfoExtractorInterface $propertyInfo, - SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader + SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader, + SwaggerDefinitionAnnotationReader $swaggerDefinitionAnnotationReader ) { $this->propertyInfo = $propertyInfo; $this->swaggerPropertyAnnotationReader = $swaggerPropertyAnnotationReader; + $this->swaggerDefinitionAnnotationReader = $swaggerDefinitionAnnotationReader; } public function describe(Model $model, Schema $schema) @@ -44,6 +48,7 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar if (null !== $model->getGroups()) { $context = ['serializer_groups' => $model->getGroups()]; } + $this->swaggerDefinitionAnnotationReader->updateWithSwaggerDefinitionAnnotation(new \ReflectionClass($class), $schema); $propertyInfoProperties = $this->propertyInfo->getProperties($class, $context); if (null === $propertyInfoProperties) { diff --git a/ModelDescriber/SwaggerDefinitionAnnotationReader.php b/ModelDescriber/SwaggerDefinitionAnnotationReader.php new file mode 100644 index 0000000..848a638 --- /dev/null +++ b/ModelDescriber/SwaggerDefinitionAnnotationReader.php @@ -0,0 +1,41 @@ +annotationsReader = $annotationsReader; + } + + public function updateWithSwaggerDefinitionAnnotation(\ReflectionClass $reflectionClass, Schema $schema) + { + /** @var SwgDefinition $swgDefinition */ + if (!$swgDefinition = $this->annotationsReader->getClassAnnotation($reflectionClass, SwgDefinition::class)) { + return; + } + + if (null !== $swgDefinition->required) { + $schema->setRequired($swgDefinition->required); + } + } +} diff --git a/ModelDescriber/SwaggerPropertyAnnotationReader.php b/ModelDescriber/SwaggerPropertyAnnotationReader.php index f6f5381..79492c8 100644 --- a/ModelDescriber/SwaggerPropertyAnnotationReader.php +++ b/ModelDescriber/SwaggerPropertyAnnotationReader.php @@ -14,7 +14,6 @@ namespace Nelmio\ApiDocBundle\ModelDescriber; use Doctrine\Common\Annotations\Reader; use EXSyst\Component\Swagger\Schema; use Swagger\Annotations\Property as SwgProperty; -use const Swagger\Annotations\UNDEFINED; /** * @internal @@ -30,31 +29,15 @@ class SwaggerPropertyAnnotationReader public function updateWithSwaggerPropertyAnnotation(\ReflectionProperty $reflectionProperty, Schema $property) { + /** @var SwgProperty $swgProperty */ if (!$swgProperty = $this->annotationsReader->getPropertyAnnotation($reflectionProperty, SwgProperty::class)) { return; } - if (null !== $swgProperty->type) { - $property->setType($swgProperty->type); - } - if (UNDEFINED !== $swgProperty->default) { - $property->setDefault($swgProperty->default); - } - if (null !== $swgProperty->enum) { - $property->setEnum($swgProperty->enum); + if (!$swgProperty->validate()) { + return; } - if (null !== $swgProperty->description) { - $property->setDescription($swgProperty->description); - } - if (null !== $swgProperty->title) { - $property->setTitle($swgProperty->title); - } - if (null !== $swgProperty->example) { - $property->setExample($swgProperty->example); - } - if (null !== $swgProperty->readOnly) { - $property->setReadOnly($swgProperty->readOnly); - } + $property->merge(\json_decode(\json_encode($swgProperty))); } } diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 117cf2d..97def1b 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -43,6 +43,10 @@ + + + + + diff --git a/Tests/Functional/Entity/JMSComplex.php b/Tests/Functional/Entity/JMSComplex.php index 9f308e4..a2d964d 100644 --- a/Tests/Functional/Entity/JMSComplex.php +++ b/Tests/Functional/Entity/JMSComplex.php @@ -12,9 +12,11 @@ namespace Nelmio\ApiDocBundle\Tests\Functional\Entity; use JMS\Serializer\Annotation as Serializer; +use Swagger\Annotations as SWG; /** * @Serializer\ExclusionPolicy("all") + * @SWG\Definition(required={"id", "user"}) */ class JMSComplex { diff --git a/Tests/Functional/Entity/JMSUser.php b/Tests/Functional/Entity/JMSUser.php index 07eb4fd..7a7dc7e 100644 --- a/Tests/Functional/Entity/JMSUser.php +++ b/Tests/Functional/Entity/JMSUser.php @@ -26,7 +26,7 @@ class JMSUser * @Serializer\Expose * @Serializer\Groups({"list"}) * - * @SWG\Property(description = "User id", required = true, readOnly = true, title = "userid", example=1, default = null) + * @SWG\Property(description = "User id", readOnly = true, title = "userid", example=1, default = null) */ private $id; @@ -35,7 +35,7 @@ class JMSUser * @Serializer\Expose * @Serializer\SerializedName("daysOnline") * - * @SWG\Property(default = 0) + * @SWG\Property(default = 0, minimum = 1, maximum = 300) */ private $daysOnline; @@ -85,7 +85,7 @@ class JMSUser * @Serializer\Expose * @Serializer\SerializedName("friendsNumber") * - * @SWG\Property(type = "string") + * @SWG\Property(type = "string", minLength = 1, maxLength = 100) */ private $friendsNumber; diff --git a/Tests/Functional/Entity/User.php b/Tests/Functional/Entity/User.php index cf14a3e..8529ec2 100644 --- a/Tests/Functional/Entity/User.php +++ b/Tests/Functional/Entity/User.php @@ -21,7 +21,7 @@ class User /** * @var int * - * @SWG\Property(description = "User id", required = true, readOnly = true, title = "userid", example=1, default = null) + * @SWG\Property(description = "User id", readOnly = true, title = "userid", example=1, default = null) */ private $id; @@ -35,7 +35,6 @@ class User * * @SWG\Property( * description = "User roles", - * required = true, * title = "roles", * example="[""ADMIN"",""SUPERUSER""]", * default = {"user"}, diff --git a/Tests/Functional/JMSFunctionalTest.php b/Tests/Functional/JMSFunctionalTest.php index e77a78f..9304a78 100644 --- a/Tests/Functional/JMSFunctionalTest.php +++ b/Tests/Functional/JMSFunctionalTest.php @@ -28,6 +28,8 @@ class JMSFunctionalTest extends WebTestCase 'daysOnline' => [ 'type' => 'integer', 'default' => 0, + 'minimum' => 1, + 'maximum' => 300, ], 'email' => [ 'type' => 'string', @@ -43,6 +45,8 @@ class JMSFunctionalTest extends WebTestCase ], 'friendsNumber' => [ 'type' => 'string', + 'maxLength' => 100, + 'minLength' => 1, ], 'friends' => [ 'type' => 'array', @@ -75,6 +79,10 @@ class JMSFunctionalTest extends WebTestCase 'user' => ['$ref' => '#/definitions/JMSUser2'], 'name' => ['type' => 'string'], ], + 'required' => [ + 'id', + 'user', + ], ], $this->getModel('JMSComplex')->toArray()); $this->assertEquals([