mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-09 02:59:27 +03:00
abstracted docblock comment extraction, implemented in JmsMetadataParser to get parameter descriptions
This commit is contained in:
parent
65c634d32b
commit
8c3466f6ed
@ -18,6 +18,7 @@ use Symfony\Component\Routing\Route;
|
|||||||
use Symfony\Component\Routing\RouterInterface;
|
use Symfony\Component\Routing\RouterInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
||||||
|
|
||||||
class ApiDocExtractor
|
class ApiDocExtractor
|
||||||
{
|
{
|
||||||
@ -40,16 +41,22 @@ class ApiDocExtractor
|
|||||||
*/
|
*/
|
||||||
private $reader;
|
private $reader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Nelmio\ApiDocBundle\Util\DocCommentExtractor
|
||||||
|
*/
|
||||||
|
private $commentExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array \Nelmio\ApiDocBundle\Parser\ParserInterface
|
* @var array \Nelmio\ApiDocBundle\Parser\ParserInterface
|
||||||
*/
|
*/
|
||||||
private $parsers = array();
|
private $parsers = array();
|
||||||
|
|
||||||
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader)
|
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader, DocCommentExtractor $commentExtractor)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
$this->reader = $reader;
|
$this->reader = $reader;
|
||||||
|
$this->commentExtractor = $commentExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +215,7 @@ class ApiDocExtractor
|
|||||||
|
|
||||||
// description
|
// description
|
||||||
if (null === $annotation->getDescription()) {
|
if (null === $annotation->getDescription()) {
|
||||||
$comments = explode("\n", $this->getDocCommentText($method));
|
$comments = explode("\n", $this->commentExtractor->getDocCommentText($method));
|
||||||
// just set the first line
|
// just set the first line
|
||||||
$comment = trim($comments[0]);
|
$comment = trim($comments[0]);
|
||||||
$comment = preg_replace("#\n+#", ' ', $comment);
|
$comment = preg_replace("#\n+#", ' ', $comment);
|
||||||
@ -221,7 +228,7 @@ class ApiDocExtractor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// doc
|
// doc
|
||||||
$annotation->setDocumentation($this->getDocCommentText($method));
|
$annotation->setDocumentation($this->commentExtractor->getDocCommentText($method));
|
||||||
|
|
||||||
// input (populates 'parameters' for the formatters)
|
// input (populates 'parameters' for the formatters)
|
||||||
if (null !== $input = $annotation->getInput()) {
|
if (null !== $input = $annotation->getInput()) {
|
||||||
@ -271,7 +278,7 @@ class ApiDocExtractor
|
|||||||
}
|
}
|
||||||
|
|
||||||
$paramDocs = array();
|
$paramDocs = array();
|
||||||
foreach (explode("\n", $this->getDocComment($method)) as $line) {
|
foreach (explode("\n", $this->commentExtractor->getDocComment($method)) as $line) {
|
||||||
if (preg_match('{^@param (.+)}', trim($line), $matches)) {
|
if (preg_match('{^@param (.+)}', trim($line), $matches)) {
|
||||||
$paramDocs[] = $matches[1];
|
$paramDocs[] = $matches[1];
|
||||||
}
|
}
|
||||||
@ -308,45 +315,6 @@ class ApiDocExtractor
|
|||||||
return $annotation;
|
return $annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Reflector $reflected
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getDocComment(\Reflector $reflected)
|
|
||||||
{
|
|
||||||
$comment = $reflected->getDocComment();
|
|
||||||
|
|
||||||
// let's clean the doc block
|
|
||||||
$comment = str_replace('/**', '', $comment);
|
|
||||||
$comment = str_replace('*', '', $comment);
|
|
||||||
$comment = str_replace('*/', '', $comment);
|
|
||||||
$comment = str_replace("\r", '', trim($comment));
|
|
||||||
$comment = preg_replace("#^\n[ \t]+[*]?#i", "\n", trim($comment));
|
|
||||||
$comment = preg_replace("#[\t ]+#i", ' ', trim($comment));
|
|
||||||
$comment = str_replace("\"", "\\\"", $comment);
|
|
||||||
|
|
||||||
return $comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Reflector $reflected
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getDocCommentText(\Reflector $reflected)
|
|
||||||
{
|
|
||||||
$comment = $reflected->getDocComment();
|
|
||||||
|
|
||||||
// Remove PHPDoc
|
|
||||||
$comment = preg_replace('/^\s+\* @[\w0-9]+.*/msi', '', $comment);
|
|
||||||
|
|
||||||
// let's clean the doc block
|
|
||||||
$comment = str_replace('/**', '', $comment);
|
|
||||||
$comment = str_replace('*/', '', $comment);
|
|
||||||
$comment = preg_replace('/^\s*\* ?/m', '', $comment);
|
|
||||||
|
|
||||||
return trim($comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses annotations for a given method, and adds new information to the given ApiDoc
|
* Parses annotations for a given method, and adds new information to the given ApiDoc
|
||||||
* annotation. Useful to extract information from the FOSRestBundle annotations.
|
* annotation. Useful to extract information from the FOSRestBundle annotations.
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Nelmio\ApiDocBundle\Parser;
|
namespace Nelmio\ApiDocBundle\Parser;
|
||||||
|
|
||||||
use Metadata\MetadataFactoryInterface;
|
use Metadata\MetadataFactoryInterface;
|
||||||
|
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses the JMS metadata factory to extract input/output model information
|
* Uses the JMS metadata factory to extract input/output model information
|
||||||
@ -19,12 +20,23 @@ use Metadata\MetadataFactoryInterface;
|
|||||||
class JmsMetadataParser implements ParserInterface
|
class JmsMetadataParser implements ParserInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Metadata\MetadataFactoryInterface
|
||||||
|
*/
|
||||||
|
private $factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Nelmio\ApiDocBundle\Util\DocCommentExtractor
|
||||||
|
*/
|
||||||
|
private $commentExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor, requires JMS Metadata factory
|
* Constructor, requires JMS Metadata factory
|
||||||
*/
|
*/
|
||||||
public function __construct(MetadataFactoryInterface $factory)
|
public function __construct(MetadataFactoryInterface $factory, DocCommentExtractor $commentExtractor)
|
||||||
{
|
{
|
||||||
$this->factory = $factory;
|
$this->factory = $factory;
|
||||||
|
$this->commentExtractor = $commentExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,9 +160,9 @@ class JmsMetadataParser implements ParserInterface
|
|||||||
|
|
||||||
protected function getDescription($className, $propertyName)
|
protected function getDescription($className, $propertyName)
|
||||||
{
|
{
|
||||||
$description = "No description.";
|
$ref = new \ReflectionClass($className);
|
||||||
|
$extracted = $this->commentExtractor->getDocCommentText($ref->getProperty($propertyName));
|
||||||
//TODO: abstract docblock parsing utility and implement here
|
$description = !empty($extracted) ? $extracted : "No description.";
|
||||||
|
|
||||||
return $description;
|
return $description;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<services>
|
<services>
|
||||||
<service id="nelmio_api_doc.parser.jms_metadata_parser" class="%nelmio_api_doc.parser.jms_metadata_parser.class%">
|
<service id="nelmio_api_doc.parser.jms_metadata_parser" class="%nelmio_api_doc.parser.jms_metadata_parser.class%">
|
||||||
<argument type="service" id="jms_serializer.metadata_factory" />
|
<argument type="service" id="jms_serializer.metadata_factory" />
|
||||||
|
<argument type="service" id="nelmio_api_doc.doc_comment_extractor" />
|
||||||
<tag name="nelmio_api_doc.extractor.parser" />
|
<tag name="nelmio_api_doc.extractor.parser" />
|
||||||
</service>
|
</service>
|
||||||
</services>
|
</services>
|
||||||
|
@ -7,13 +7,17 @@
|
|||||||
<parameter key="nelmio_api_doc.extractor.api_doc_extractor.class">Nelmio\ApiDocBundle\Extractor\ApiDocExtractor</parameter>
|
<parameter key="nelmio_api_doc.extractor.api_doc_extractor.class">Nelmio\ApiDocBundle\Extractor\ApiDocExtractor</parameter>
|
||||||
<parameter key="nelmio_api_doc.form.extension.description_form_type_extension.class">Nelmio\ApiDocBundle\Form\Extension\DescriptionFormTypeExtension</parameter>
|
<parameter key="nelmio_api_doc.form.extension.description_form_type_extension.class">Nelmio\ApiDocBundle\Form\Extension\DescriptionFormTypeExtension</parameter>
|
||||||
<parameter key="nelmio_api_doc.twig.extension.extra_markdown.class">Nelmio\ApiDocBundle\Twig\Extension\MarkdownExtension</parameter>
|
<parameter key="nelmio_api_doc.twig.extension.extra_markdown.class">Nelmio\ApiDocBundle\Twig\Extension\MarkdownExtension</parameter>
|
||||||
|
<parameter key="nelmio_api_doc.doc_comment_extractor.class">Nelmio\ApiDocBundle\Util\DocCommentExtractor</parameter>
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
|
<service id='nelmio_api_doc.doc_comment_extractor' class='%nelmio_api_doc.doc_comment_extractor.class%' />
|
||||||
|
|
||||||
<service id="nelmio_api_doc.extractor.api_doc_extractor" class="%nelmio_api_doc.extractor.api_doc_extractor.class%">
|
<service id="nelmio_api_doc.extractor.api_doc_extractor" class="%nelmio_api_doc.extractor.api_doc_extractor.class%">
|
||||||
<argument type="service" id="service_container"/>
|
<argument type="service" id="service_container"/>
|
||||||
<argument type="service" id="router" />
|
<argument type="service" id="router" />
|
||||||
<argument type="service" id="annotation_reader" />
|
<argument type="service" id="annotation_reader" />
|
||||||
|
<argument type="service" id="nelmio_api_doc.doc_comment_extractor" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="nelmio_api_doc.form.extension.description_form_type_extension" class="%nelmio_api_doc.form.extension.description_form_type_extension.class%">
|
<service id="nelmio_api_doc.form.extension.description_form_type_extension" class="%nelmio_api_doc.form.extension.description_form_type_extension.class%">
|
||||||
|
@ -20,6 +20,8 @@ class JmsNested
|
|||||||
/**
|
/**
|
||||||
* Epic description.
|
* Epic description.
|
||||||
*
|
*
|
||||||
|
* With multiple lines.
|
||||||
|
*
|
||||||
* @JMS\Type("array<integer>")
|
* @JMS\Type("array<integer>")
|
||||||
*/
|
*/
|
||||||
public $baz;
|
public $baz;
|
||||||
|
@ -232,7 +232,9 @@ class SimpleFormatterTest extends WebTestCase
|
|||||||
'baz' => array(
|
'baz' => array(
|
||||||
'dataType' => 'array of integers',
|
'dataType' => 'array of integers',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'description' => 'No description.',
|
'description' => 'Epic description.
|
||||||
|
|
||||||
|
With multiple lines.',
|
||||||
'readonly' => false,
|
'readonly' => false,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -258,7 +260,9 @@ class SimpleFormatterTest extends WebTestCase
|
|||||||
'baz' => array(
|
'baz' => array(
|
||||||
'dataType' => 'array of integers',
|
'dataType' => 'array of integers',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'description' => 'No description.',
|
'description' => 'Epic description.
|
||||||
|
|
||||||
|
With multiple lines.',
|
||||||
'readonly' => false,
|
'readonly' => false,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
46
Util/DocCommentExtractor.php
Normal file
46
Util/DocCommentExtractor.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Util;
|
||||||
|
|
||||||
|
class DocCommentExtractor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param \Reflector $reflected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDocComment(\Reflector $reflected)
|
||||||
|
{
|
||||||
|
$comment = $reflected->getDocComment();
|
||||||
|
|
||||||
|
// let's clean the doc block
|
||||||
|
$comment = str_replace('/**', '', $comment);
|
||||||
|
$comment = str_replace('*', '', $comment);
|
||||||
|
$comment = str_replace('*/', '', $comment);
|
||||||
|
$comment = str_replace("\r", '', trim($comment));
|
||||||
|
$comment = preg_replace("#^\n[ \t]+[*]?#i", "\n", trim($comment));
|
||||||
|
$comment = preg_replace("#[\t ]+#i", ' ', trim($comment));
|
||||||
|
$comment = str_replace("\"", "\\\"", $comment);
|
||||||
|
|
||||||
|
return $comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Reflector $reflected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getDocCommentText(\Reflector $reflected)
|
||||||
|
{
|
||||||
|
$comment = $reflected->getDocComment();
|
||||||
|
|
||||||
|
// Remove PHPDoc
|
||||||
|
$comment = preg_replace('/^\s+\* @[\w0-9]+.*/msi', '', $comment);
|
||||||
|
|
||||||
|
// let's clean the doc block
|
||||||
|
$comment = str_replace('/**', '', $comment);
|
||||||
|
$comment = str_replace('*/', '', $comment);
|
||||||
|
$comment = preg_replace('/^\s*\* ?/m', '', $comment);
|
||||||
|
|
||||||
|
return trim($comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user