From ead8174192eea97f52450e4984d59eb54ed76d2e Mon Sep 17 00:00:00 2001 From: "Marc J. Schmidt" Date: Tue, 10 Dec 2013 02:32:17 +0100 Subject: [PATCH] Outsourced the parsing of the classic phpDoc into a extra handler. This makes it possible to overwrite route-requirements/description through a own handler. Otherwise it's impossible e.g. to overwrite a `@param string $page` annotation via a own handler. --- Extractor/ApiDocExtractor.php | 67 ------------------- Extractor/Handler/PhpDocHandler.php | 100 ++++++++++++++++++++++++++++ Resources/config/services.xml | 6 ++ 3 files changed, 106 insertions(+), 67 deletions(-) create mode 100644 Extractor/Handler/PhpDocHandler.php diff --git a/Extractor/ApiDocExtractor.php b/Extractor/ApiDocExtractor.php index 630ad4c..8e172ca 100644 --- a/Extractor/ApiDocExtractor.php +++ b/Extractor/ApiDocExtractor.php @@ -253,20 +253,6 @@ class ApiDocExtractor // route $annotation->setRoute($route); - // description - if (null === $annotation->getDescription()) { - $comments = explode("\n", $annotation->getDocumentation()); - // just set the first line - $comment = trim($comments[0]); - $comment = preg_replace("#\n+#", ' ', $comment); - $comment = preg_replace('#\s+#', ' ', $comment); - $comment = preg_replace('#[_`*]+#', '', $comment); - - if ('@' !== substr($comment, 0, 1)) { - $annotation->setDescription($comment); - } - } - // input (populates 'parameters' for the formatters) if (null !== $input = $annotation->getInput()) { $parameters = array(); @@ -317,59 +303,6 @@ class ApiDocExtractor $annotation->setResponse($response); } - // requirements - $requirements = array(); - foreach ($route->getRequirements() as $name => $value) { - if ('_method' !== $name) { - $requirements[$name] = array( - 'requirement' => $value, - 'dataType' => '', - 'description' => '', - ); - } - if ('_scheme' == $name) { - $https = ('https' == $value); - $annotation->setHttps($https); - } - } - - $paramDocs = array(); - foreach (explode("\n", $this->commentExtractor->getDocComment($method)) as $line) { - if (preg_match('{^@param (.+)}', trim($line), $matches)) { - $paramDocs[] = $matches[1]; - } - if (preg_match('{^@deprecated\b(.*)}', trim($line), $matches)) { - $annotation->setDeprecated(true); - } - if (preg_match('{^@link\b(.*)}', trim($line), $matches)) { - $annotation->setLink($matches[1]); - } - } - - $regexp = '{(\w*) *\$%s\b *(.*)}i'; - foreach ($route->compile()->getVariables() as $var) { - $found = false; - foreach ($paramDocs as $paramDoc) { - if (preg_match(sprintf($regexp, preg_quote($var)), $paramDoc, $matches)) { - $requirements[$var]['dataType'] = isset($matches[1]) ? $matches[1] : ''; - $requirements[$var]['description'] = $matches[2]; - - if (!isset($requirements[$var]['requirement'])) { - $requirements[$var]['requirement'] = ''; - } - - $found = true; - break; - } - } - - if (!isset($requirements[$var]) && false === $found) { - $requirements[$var] = array('requirement' => '', 'dataType' => '', 'description' => ''); - } - } - - $annotation->setRequirements($requirements); - return $annotation; } diff --git a/Extractor/Handler/PhpDocHandler.php b/Extractor/Handler/PhpDocHandler.php new file mode 100644 index 0000000..fc72a93 --- /dev/null +++ b/Extractor/Handler/PhpDocHandler.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Nelmio\ApiDocBundle\Extractor\Handler; + +use Nelmio\ApiDocBundle\Extractor\HandlerInterface; +use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Symfony\Component\Routing\Route; +use Nelmio\ApiDocBundle\Util\DocCommentExtractor; + +class PhpDocHandler implements HandlerInterface +{ + /** + * @var DocCommentExtractor + */ + protected $commentExtractor; + + public function __construct(DocCommentExtractor $commentExtractor) + { + $this->commentExtractor = $commentExtractor; + } + + public function handle(ApiDoc $annotation, array $annotations, Route $route, \ReflectionMethod $method) + { + // description + if (null === $annotation->getDescription()) { + $comments = explode("\n", $annotation->getDocumentation()); + // just set the first line + $comment = trim($comments[0]); + $comment = preg_replace("#\n+#", ' ', $comment); + $comment = preg_replace('#\s+#', ' ', $comment); + $comment = preg_replace('#[_`*]+#', '', $comment); + + if ('@' !== substr($comment, 0, 1)) { + $annotation->setDescription($comment); + } + } + + // requirements + $requirements = $annotation->getRequirements(); + foreach ($route->getRequirements() as $name => $value) { + if (!isset($requirements[$name]) && '_method' !== $name) { + $requirements[$name] = array( + 'requirement' => $value, + 'dataType' => '', + 'description' => '', + ); + } + if ('_scheme' == $name) { + $https = ('https' == $value); + $annotation->setHttps($https); + } + } + + $paramDocs = array(); + foreach (explode("\n", $this->commentExtractor->getDocComment($method)) as $line) { + if (preg_match('{^@param (.+)}', trim($line), $matches)) { + $paramDocs[] = $matches[1]; + } + if (preg_match('{^@deprecated\b(.*)}', trim($line), $matches)) { + $annotation->setDeprecated(true); + } + if (preg_match('{^@link\b(.*)}', trim($line), $matches)) { + $annotation->setLink($matches[1]); + } + } + + $regexp = '{(\w*) *\$%s\b *(.*)}i'; + foreach ($route->compile()->getVariables() as $var) { + $found = false; + foreach ($paramDocs as $paramDoc) { + if (preg_match(sprintf($regexp, preg_quote($var)), $paramDoc, $matches)) { + $requirements[$var]['dataType'] = isset($matches[1]) ? $matches[1] : ''; + $requirements[$var]['description'] = $matches[2]; + + if (!isset($requirements[$var]['requirement'])) { + $requirements[$var]['requirement'] = ''; + } + + $found = true; + break; + } + } + + if (!isset($requirements[$var]) && false === $found) { + $requirements[$var] = array('requirement' => '', 'dataType' => '', 'description' => ''); + } + } + + $annotation->setRequirements($requirements); + } +} diff --git a/Resources/config/services.xml b/Resources/config/services.xml index cce11c4..da00c21 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -12,6 +12,7 @@ Nelmio\ApiDocBundle\Extractor\Handler\FosRestHandler Nelmio\ApiDocBundle\Extractor\Handler\JmsSecurityExtraHandler Nelmio\ApiDocBundle\Extractor\Handler\SensioFrameworkExtraHandler + Nelmio\ApiDocBundle\Extractor\Handler\PhpDocHandler @@ -46,6 +47,11 @@ + + + + +