diff --git a/Extractor/ApiDocExtractor.php b/Extractor/ApiDocExtractor.php index 7dfee71..b3cbcf4 100644 --- a/Extractor/ApiDocExtractor.php +++ b/Extractor/ApiDocExtractor.php @@ -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. diff --git a/Parser/JmsMetadataParser.php b/Parser/JmsMetadataParser.php index dfc592b..61961e9 100644 --- a/Parser/JmsMetadataParser.php +++ b/Parser/JmsMetadataParser.php @@ -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; } diff --git a/Resources/config/services.jms.xml b/Resources/config/services.jms.xml index cf61f8f..3f4f59f 100644 --- a/Resources/config/services.jms.xml +++ b/Resources/config/services.jms.xml @@ -10,6 +10,7 @@ + diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 90e8d67..09a8e25 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -7,13 +7,17 @@ Nelmio\ApiDocBundle\Extractor\ApiDocExtractor Nelmio\ApiDocBundle\Form\Extension\DescriptionFormTypeExtension Nelmio\ApiDocBundle\Twig\Extension\MarkdownExtension + Nelmio\ApiDocBundle\Util\DocCommentExtractor + + + diff --git a/Tests/Fixtures/Model/JmsNested.php b/Tests/Fixtures/Model/JmsNested.php index 9008446..ad29652 100644 --- a/Tests/Fixtures/Model/JmsNested.php +++ b/Tests/Fixtures/Model/JmsNested.php @@ -20,6 +20,8 @@ class JmsNested /** * Epic description. * + * With multiple lines. + * * @JMS\Type("array") */ public $baz; diff --git a/Tests/Formatter/SimpleFormatterTest.php b/Tests/Formatter/SimpleFormatterTest.php index 0caddcd..e9624c9 100644 --- a/Tests/Formatter/SimpleFormatterTest.php +++ b/Tests/Formatter/SimpleFormatterTest.php @@ -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, ) ) diff --git a/Util/DocCommentExtractor.php b/Util/DocCommentExtractor.php new file mode 100644 index 0000000..a06a587 --- /dev/null +++ b/Util/DocCommentExtractor.php @@ -0,0 +1,46 @@ +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); + } + +}