From c5891a59b94060b77c522d68495ab0b27a3d5cd1 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Thu, 19 Apr 2012 16:23:26 +0200 Subject: [PATCH] Use action method description from docblock by default for description. Fixes #5 --- Annotation/ApiDoc.php | 8 +++ Extractor/ApiDocExtractor.php | 63 +++++++++++++++----- Tests/Extractor/ApiDocExtratorTest.php | 12 +++- Tests/Fixtures/Controller/TestController.php | 9 +++ Tests/Fixtures/app/config/routing.yml | 4 ++ 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/Annotation/ApiDoc.php b/Annotation/ApiDoc.php index 5e5a0aa..e87c88c 100644 --- a/Annotation/ApiDoc.php +++ b/Annotation/ApiDoc.php @@ -84,6 +84,14 @@ class ApiDoc return $this->description; } + /** + * @param string $description + */ + public function setDescription($description) + { + $this->description = $description; + } + /** * @return Boolean */ diff --git a/Extractor/ApiDocExtractor.php b/Extractor/ApiDocExtractor.php index 069601c..f2d60a0 100644 --- a/Extractor/ApiDocExtractor.php +++ b/Extractor/ApiDocExtractor.php @@ -12,6 +12,8 @@ namespace Nelmio\ApiDocBundle\Extractor; use Doctrine\Common\Annotations\Reader; +use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -56,16 +58,13 @@ class ApiDocExtractor $resources = array(); foreach ($this->router->getRouteCollection()->all() as $route) { - $method = $this->getReflectionMethod($route->getDefault('_controller')); - - if ($method) { - $annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS); - if ($annot) { + if ($method = $this->getReflectionMethod($route->getDefault('_controller'))) { + if ($annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS)) { if ($annot->isResource()) { $resources[] = $route->getPattern(); } - $array[] = array('annotation' => $annot, 'route' => $route); + $array[] = $this->getData($annot, $route, $method); } } } @@ -156,17 +155,53 @@ class ApiDocExtractor */ public function get($controller, $route) { - $method = $this->getReflectionMethod($controller); - if (!$method) { - return null; - } - - if ($annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS)) { - if ($route = $this->router->getRouteCollection()->get($route)) { - return array('annotation' => $annot, 'route' => $route); + if ($method = $this->getReflectionMethod($controller)) { + if ($annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS)) { + if ($route = $this->router->getRouteCollection()->get($route)) { + return $this->getData($annot, $route, $method); + } } } return null; } + + /** + * Allows to add more data to the ApiDoc object, and + * returns an array containing the following keys: + * - annotation + * - route + * + * @param ApiDoc $annotation + * @param Route $route + * @param ReflectionMethod $method + * @return array + */ + protected function getData(ApiDoc $annotation, Route $route, \ReflectionMethod $method) + { + if (null === $annotation->getDescription()) { + $comments = explode('\n', $this->getDocComment($method)); + // just set the first line + $annotation->setDescription($comments[0]); + } + + return array('annotation' => $annotation, 'route' => $route); + } + + 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 = str_replace("\n", "\\n", trim($comment)); + $comment = preg_replace("#[\t ]+#i", ' ', trim($comment)); + $comment = str_replace("\"", "\\\"", $comment); + + return $comment; + } } diff --git a/Tests/Extractor/ApiDocExtratorTest.php b/Tests/Extractor/ApiDocExtratorTest.php index 72659ee..fa3aec4 100644 --- a/Tests/Extractor/ApiDocExtratorTest.php +++ b/Tests/Extractor/ApiDocExtratorTest.php @@ -22,7 +22,7 @@ class ApiDocExtractorTest extends WebTestCase $data = $extractor->all(); $this->assertTrue(is_array($data)); - $this->assertCount(6, $data); + $this->assertCount(7, $data); foreach ($data as $d) { $this->assertTrue(is_array($d)); @@ -131,4 +131,14 @@ class ApiDocExtractorTest extends WebTestCase $this->assertNull($data); } + + public function testGetWithDocComment() + { + $container = $this->getContainer(); + $extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor'); + $data = $extractor->get('Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestController::myCommentedAction', 'test_route_5'); + + $this->assertNotNull($data); + $this->assertEquals('This method is useful to test if the getDocComment works.', $data['annotation']->getDescription()); + } } diff --git a/Tests/Fixtures/Controller/TestController.php b/Tests/Fixtures/Controller/TestController.php index 6f08397..9b7431d 100644 --- a/Tests/Fixtures/Controller/TestController.php +++ b/Tests/Fixtures/Controller/TestController.php @@ -51,4 +51,13 @@ class TestController public function anyAction() { } + + /** + * This method is useful to test if the getDocComment works. + * + * @ApiDoc() + */ + public function myCommentedAction() + { + } } diff --git a/Tests/Fixtures/app/config/routing.yml b/Tests/Fixtures/app/config/routing.yml index 1968e81..010845f 100644 --- a/Tests/Fixtures/app/config/routing.yml +++ b/Tests/Fixtures/app/config/routing.yml @@ -18,6 +18,10 @@ test_route_4: pattern: /any defaults: { _controller: NelmioApiDocTestBundle:Test:any, _format: json } +test_route_5: + pattern: /my-commented + defaults: { _controller: NelmioApiDocTestBundle:Test:myCommented } + test_service_route_1: pattern: /tests defaults: { _controller: nemlio.test.controller:indexAction, _format: json }