Merge pull request #1152 from dbu/jms-php-docblocks

parse phpdoc annotations in jms models
This commit is contained in:
Guilhem N 2017-12-21 17:12:42 +01:00 committed by GitHub
commit 8a57f39d01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 2 deletions

View File

@ -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]);
}

View File

@ -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);
}
}

View File

@ -0,0 +1,69 @@
<?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 EXSyst\Component\Swagger\Schema;
use EXSyst\Component\Swagger\Items;
use phpDocumentor\Reflection\DocBlock\Tags\Var_;
use phpDocumentor\Reflection\DocBlockFactory;
use phpDocumentor\Reflection\DocBlockFactoryInterface;
/**
* Extract information about properties of a model from the DocBlock comment.
*
* @internal
*/
class PhpdocPropertyAnnotationReader
{
private $docBlockFactory;
public function __construct(DocBlockFactoryInterface $docBlockFactory = null)
{
if (null === $docBlockFactory) {
$docBlockFactory = DocBlockFactory::createInstance();
}
$this->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());
}
}
}

View File

@ -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

View File

@ -54,6 +54,12 @@
<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">
<argument type="service" id="property_info" />
<argument type="service" id="nelmio_api_doc.model_describers.swagger_property_annotation_reader" />

View File

@ -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
*

View File

@ -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'],
],
],