diff --git a/Annotation/ApiDoc.php b/Annotation/ApiDoc.php index 760e174..ab2a8f0 100644 --- a/Annotation/ApiDoc.php +++ b/Annotation/ApiDoc.php @@ -153,6 +153,39 @@ class ApiDoc } } + if (isset($data['requirements'])) { + foreach ($data['requirements'] as $requirement) { + if (!isset($requirement['name'])) { + throw new \InvalidArgumentException('A "requirement" element has to contain a "name" attribute'); + } + + $name = $requirement['name']; + unset($requirement['name']); + + $this->addRequirement($name, $requirement); + } + } + + if (isset($data['parameters'])) { + foreach ($data['parameters'] as $parameter) { + if (!isset($parameter['name'])) { + throw new \InvalidArgumentException('A "parameter" element has to contain a "name" attribute'); + } + + if (!isset($parameter['dataType'])) { + throw new \InvalidArgumentException(sprintf( + '"%s" parameter element has to contain a "dataType" attribute', + $parameter['name'] + )); + } + + $name = $parameter['name']; + unset($parameter['name']); + + $this->addParameter($name, $parameter); + } + } + if (isset($data['output'])) { $this->output = $data['output']; } diff --git a/README.md b/README.md index b78d912..48b44be 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,26 @@ class YourController extends Controller public function postAction() { } + + /** + * @ApiDoc( + * description="Returns a collection of Object", + * requirements={ + * { + * "name"="limit", + * "dataType"="integer", + * "requirement"="\d+", + * "description"="how many objects to return" + * } + * }, + * parameters={ + * {"name"="categoryId", "dataType"="integer", "required"=true, "description"="category id"} + * } + * ) + */ + public function cgetAction($id) + { + } } ``` @@ -104,6 +124,10 @@ The following properties are available: * `filters`: an array of filters; +* `requirements`: an array of requirements; + +* `parameters`: an array of parameters; + * `input`: the input type associated to the method (currently this supports Form Types, classes with JMS Serializer metadata, and classes with Validation component metadata) useful for POST|PUT methods, either as FQCN or as form type (if it is registered in the form factory in the container). diff --git a/Resources/views/method.html.twig b/Resources/views/method.html.twig index c0917ec..eba8d20 100644 --- a/Resources/views/method.html.twig +++ b/Resources/views/method.html.twig @@ -123,10 +123,10 @@ {% if not infos.readonly %} {{ name }} - {{ infos.dataType }} + {{ infos.dataType is defined ? infos.dataType : '' }} {{ infos.required ? 'true' : 'false' }} {{ infos.format }} - {{ infos.description }} + {{ infos.description is defined ? infos.description : '' }} {% endif %} {% endfor %} diff --git a/Tests/Annotation/ApiDocTest.php b/Tests/Annotation/ApiDocTest.php index 3c7eb5f..e18fb1f 100644 --- a/Tests/Annotation/ApiDocTest.php +++ b/Tests/Annotation/ApiDocTest.php @@ -28,6 +28,8 @@ class ApiDocTest extends TestCase $this->assertFalse($annot->isResource()); $this->assertFalse($annot->getDeprecated()); $this->assertFalse(isset($array['description'])); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertNull($annot->getInput()); $this->assertFalse($array['authentication']); } @@ -47,6 +49,8 @@ class ApiDocTest extends TestCase $this->assertFalse($annot->isResource()); $this->assertFalse($annot->getDeprecated()); $this->assertFalse(isset($array['description'])); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertNull($annot->getInput()); } @@ -64,6 +68,8 @@ class ApiDocTest extends TestCase $this->assertFalse($annot->isResource()); $this->assertFalse($annot->getDeprecated()); $this->assertEquals($data['description'], $array['description']); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertNull($annot->getInput()); } @@ -82,6 +88,8 @@ class ApiDocTest extends TestCase $this->assertFalse($annot->isResource()); $this->assertFalse($annot->getDeprecated()); $this->assertEquals($data['description'], $array['description']); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertEquals($data['input'], $annot->getInput()); } @@ -102,6 +110,8 @@ class ApiDocTest extends TestCase $this->assertTrue($annot->isResource()); $this->assertTrue($annot->getDeprecated()); $this->assertEquals($data['description'], $array['description']); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertEquals($data['input'], $annot->getInput()); } @@ -121,6 +131,8 @@ class ApiDocTest extends TestCase $this->assertFalse(isset($array['filters'])); $this->assertFalse($annot->isResource()); $this->assertEquals($data['description'], $array['description']); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertEquals($data['deprecated'], $array['deprecated']); $this->assertEquals($data['input'], $annot->getInput()); } @@ -145,6 +157,8 @@ class ApiDocTest extends TestCase $this->assertEquals(array('a-filter' => array()), $array['filters']); $this->assertTrue($annot->isResource()); $this->assertEquals($data['description'], $array['description']); + $this->assertFalse(isset($array['requirements'])); + $this->assertFalse(isset($array['parameters'])); $this->assertEquals($data['deprecated'], $array['deprecated']); $this->assertNull($annot->getInput()); } @@ -232,4 +246,45 @@ class ApiDocTest extends TestCase $this->assertEquals($data['cache'], $array['cache']); } + + public function testConstructWithRequirements() + { + $data = array( + 'requirements' => array( + array( + 'name' => 'fooId', + 'requirement' => '\d+', + 'dataType' => 'integer', + 'description' => 'This requirement might be used withing action method directly from Request object' + ) + ) + ); + + $annot = new ApiDoc($data); + $array = $annot->toArray(); + + $this->assertTrue(is_array($array)); + $this->assertTrue(isset($array['requirements']['fooId'])); + $this->assertTrue(isset($array['requirements']['fooId']['dataType'])); + } + + public function testConstructWithParameters() + { + $data = array( + 'parameters' => array( + array( + 'name' => 'fooId', + 'dataType' => 'integer', + 'description' => 'Some description' + ) + ) + ); + + $annot = new ApiDoc($data); + $array = $annot->toArray(); + + $this->assertTrue(is_array($array)); + $this->assertTrue(isset($array['parameters']['fooId'])); + $this->assertTrue(isset($array['parameters']['fooId']['dataType'])); + } } diff --git a/Tests/Fixtures/Controller/TestController.php b/Tests/Fixtures/Controller/TestController.php index c9e1eae..a235b1d 100644 --- a/Tests/Fixtures/Controller/TestController.php +++ b/Tests/Fixtures/Controller/TestController.php @@ -198,4 +198,19 @@ class TestController public function jmsReturnNestedOutputAction() { } + + /** + * @ApiDoc( + * description="Returns a collection of Object", + * requirements={ + * {"name"="limit", "dataType"="integer", "requirement"="\d+", "description"="how many objects to return"} + * }, + * parameters={ + * {"name"="categoryId", "dataType"="integer", "required"=true, "description"="category id"} + * } + * ) + */ + public function cgetAction($id) + { + } }