diff --git a/DependencyInjection/NelmioApiDocExtension.php b/DependencyInjection/NelmioApiDocExtension.php index 7b05be4..cfc2796 100644 --- a/DependencyInjection/NelmioApiDocExtension.php +++ b/DependencyInjection/NelmioApiDocExtension.php @@ -94,6 +94,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.phpdoc_property_annotation_reader'), ]) ->addTag('nelmio_api_doc.model_describer', ['priority' => 50]); } diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index 6e81f13..47b0bb9 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -35,14 +35,18 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn private $swaggerPropertyAnnotationReader; + private $phpdocPropertyAnnotationsReader; + public function __construct( MetadataFactoryInterface $factory, PropertyNamingStrategyInterface $namingStrategy, - SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader + SwaggerPropertyAnnotationReader $swaggerPropertyAnnotationReader, + PhpdocPropertyAnnotationReader $phpdocPropertyAnnotationReader ) { $this->factory = $factory; $this->namingStrategy = $namingStrategy; $this->swaggerPropertyAnnotationReader = $swaggerPropertyAnnotationReader; + $this->phpdocPropertyAnnotationsReader = $phpdocPropertyAnnotationReader; } /** @@ -103,6 +107,7 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn // read property options from Swagger Property annotation if it exists if (null !== $item->reflection) { + $this->phpdocPropertyAnnotationsReader->updateWithPhpdoc($item->reflection, $realProp); $this->swaggerPropertyAnnotationReader->updateWithSwaggerPropertyAnnotation($item->reflection, $realProp); } } diff --git a/ModelDescriber/PhpdocPropertyAnnotationReader.php b/ModelDescriber/PhpdocPropertyAnnotationReader.php new file mode 100644 index 0000000..2f30700 --- /dev/null +++ b/ModelDescriber/PhpdocPropertyAnnotationReader.php @@ -0,0 +1,69 @@ +docBlockFactory = $docBlockFactory; + } + + /** + * Update the Swagger information with information from the DocBlock comment. + * + * @param \ReflectionProperty $reflectionProperty + * @param Items|Schema $property + */ + public function updateWithPhpdoc(\ReflectionProperty $reflectionProperty, $property) + { + try { + $docBlock = $this->docBlockFactory->create($reflectionProperty); + } catch (\Exception $e) { + // ignore + return; + } + + if (!$title = $docBlock->getSummary()) { + /** @var Var_ $var */ + foreach ($docBlock->getTagsByName('var') as $var) { + if (!$description = $var->getDescription()) { + continue; + } + $title = $description->render(); + if ($title) break; + } + } + if ($property->getTitle() === null && $title) { + $property->setTitle($title); + } + if ($property->getDescription() === null && $docBlock->getDescription() && $docBlock->getDescription()->render()) { + $property->setDescription($docBlock->getDescription()->render()); + } + } +} diff --git a/README.md b/README.md index 0b76436..3066e29 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,8 @@ serialization groups when using the Symfony serializer. ### If you're using the JMS Serializer The metadata of the JMS serializer are used by default to describe your -models. Note that PHP doc blocks aren't supported in this case. +models. Additional information is extracted from the PHP doc block comment, +but the property types must be specified in the JMS annotations. In case you prefer using the [Symfony PropertyInfo component](https://symfony.com/doc/current/components/property_info.html) (you won't be able to use JMS serialization groups), you can disable JMS serializer diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 00443e4..401b78d 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -54,6 +54,12 @@ + + diff --git a/Tests/Functional/Entity/JMSUser.php b/Tests/Functional/Entity/JMSUser.php index acf96cb..ba5c77d 100644 --- a/Tests/Functional/Entity/JMSUser.php +++ b/Tests/Functional/Entity/JMSUser.php @@ -89,6 +89,11 @@ class JMSUser private $bestFriend; /** + * Whether this user is enabled or disabled. + * + * Only enabled users may be used in actions. + * + * @var string * @Serializer\Type("string") * @Serializer\Expose * diff --git a/Tests/Functional/JMSFunctionalTest.php b/Tests/Functional/JMSFunctionalTest.php index 01d28a1..ff653e0 100644 --- a/Tests/Functional/JMSFunctionalTest.php +++ b/Tests/Functional/JMSFunctionalTest.php @@ -55,6 +55,8 @@ class JMSFunctionalTest extends WebTestCase ], 'status' => [ 'type' => 'string', + 'title' => 'Whether this user is enabled or disabled.', + 'description' => 'Only enabled users may be used in actions.', 'enum' => ['disabled', 'enabled'], ], ],