mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-08 18:49:26 +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\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
||||
|
||||
class ApiDocExtractor
|
||||
{
|
||||
@ -40,16 +41,22 @@ class ApiDocExtractor
|
||||
*/
|
||||
private $reader;
|
||||
|
||||
/**
|
||||
* @var \Nelmio\ApiDocBundle\Util\DocCommentExtractor
|
||||
*/
|
||||
private $commentExtractor;
|
||||
|
||||
/**
|
||||
* @var array \Nelmio\ApiDocBundle\Parser\ParserInterface
|
||||
*/
|
||||
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->router = $router;
|
||||
$this->reader = $reader;
|
||||
$this->commentExtractor = $commentExtractor;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,7 +215,7 @@ class ApiDocExtractor
|
||||
|
||||
// description
|
||||
if (null === $annotation->getDescription()) {
|
||||
$comments = explode("\n", $this->getDocCommentText($method));
|
||||
$comments = explode("\n", $this->commentExtractor->getDocCommentText($method));
|
||||
// just set the first line
|
||||
$comment = trim($comments[0]);
|
||||
$comment = preg_replace("#\n+#", ' ', $comment);
|
||||
@ -221,7 +228,7 @@ class ApiDocExtractor
|
||||
}
|
||||
|
||||
// doc
|
||||
$annotation->setDocumentation($this->getDocCommentText($method));
|
||||
$annotation->setDocumentation($this->commentExtractor->getDocCommentText($method));
|
||||
|
||||
// input (populates 'parameters' for the formatters)
|
||||
if (null !== $input = $annotation->getInput()) {
|
||||
@ -271,7 +278,7 @@ class ApiDocExtractor
|
||||
}
|
||||
|
||||
$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)) {
|
||||
$paramDocs[] = $matches[1];
|
||||
}
|
||||
@ -308,45 +315,6 @@ class ApiDocExtractor
|
||||
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
|
||||
* annotation. Useful to extract information from the FOSRestBundle annotations.
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Nelmio\ApiDocBundle\Parser;
|
||||
|
||||
use Metadata\MetadataFactoryInterface;
|
||||
use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
|
||||
|
||||
/**
|
||||
* Uses the JMS metadata factory to extract input/output model information
|
||||
@ -19,12 +20,23 @@ use Metadata\MetadataFactoryInterface;
|
||||
class JmsMetadataParser implements ParserInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Metadata\MetadataFactoryInterface
|
||||
*/
|
||||
private $factory;
|
||||
|
||||
/**
|
||||
* @var \Nelmio\ApiDocBundle\Util\DocCommentExtractor
|
||||
*/
|
||||
private $commentExtractor;
|
||||
|
||||
/**
|
||||
* Constructor, requires JMS Metadata factory
|
||||
*/
|
||||
public function __construct(MetadataFactoryInterface $factory)
|
||||
public function __construct(MetadataFactoryInterface $factory, DocCommentExtractor $commentExtractor)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
$this->commentExtractor = $commentExtractor;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,9 +160,9 @@ class JmsMetadataParser implements ParserInterface
|
||||
|
||||
protected function getDescription($className, $propertyName)
|
||||
{
|
||||
$description = "No description.";
|
||||
|
||||
//TODO: abstract docblock parsing utility and implement here
|
||||
$ref = new \ReflectionClass($className);
|
||||
$extracted = $this->commentExtractor->getDocCommentText($ref->getProperty($propertyName));
|
||||
$description = !empty($extracted) ? $extracted : "No description.";
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
<services>
|
||||
<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="nelmio_api_doc.doc_comment_extractor" />
|
||||
<tag name="nelmio_api_doc.extractor.parser" />
|
||||
</service>
|
||||
</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.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.doc_comment_extractor.class">Nelmio\ApiDocBundle\Util\DocCommentExtractor</parameter>
|
||||
</parameters>
|
||||
|
||||
<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%">
|
||||
<argument type="service" id="service_container"/>
|
||||
<argument type="service" id="router" />
|
||||
<argument type="service" id="annotation_reader" />
|
||||
<argument type="service" id="nelmio_api_doc.doc_comment_extractor" />
|
||||
</service>
|
||||
|
||||
<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.
|
||||
*
|
||||
* With multiple lines.
|
||||
*
|
||||
* @JMS\Type("array<integer>")
|
||||
*/
|
||||
public $baz;
|
||||
|
@ -232,7 +232,9 @@ class SimpleFormatterTest extends WebTestCase
|
||||
'baz' => array(
|
||||
'dataType' => 'array of integers',
|
||||
'required' => false,
|
||||
'description' => 'No description.',
|
||||
'description' => 'Epic description.
|
||||
|
||||
With multiple lines.',
|
||||
'readonly' => false,
|
||||
)
|
||||
)
|
||||
@ -258,7 +260,9 @@ class SimpleFormatterTest extends WebTestCase
|
||||
'baz' => array(
|
||||
'dataType' => 'array of integers',
|
||||
'required' => false,
|
||||
'description' => 'No description.',
|
||||
'description' => 'Epic description.
|
||||
|
||||
With multiple lines.',
|
||||
'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