mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 15:51:48 +03:00
Added parsing of @param doc blocks. Fixes #8
This commit is contained in:
parent
2a36274a75
commit
d1be0d5093
@ -179,16 +179,29 @@ class ApiDocExtractor
|
||||
*/
|
||||
protected function getData(ApiDoc $annotation, Route $route, \ReflectionMethod $method)
|
||||
{
|
||||
$docblock = $this->getDocComment($method);
|
||||
|
||||
if (null === $annotation->getDescription()) {
|
||||
$comments = explode("\n @", $this->getDocComment($method));
|
||||
$comments = explode("\n @", $docblock);
|
||||
// just set the first line
|
||||
$comment = trim($comments[0]);
|
||||
$comment = preg_replace("#[\n]+#", ' ', $comment);
|
||||
$comment = preg_replace('#[ ]+#', ' ', $comment);
|
||||
|
||||
$annotation->setDescription($comment);
|
||||
if ('@' !== substr($comment, 0, 1)) {
|
||||
$annotation->setDescription($comment);
|
||||
}
|
||||
}
|
||||
|
||||
$paramDocs = array();
|
||||
foreach (explode("\n", $docblock) as $line) {
|
||||
if (preg_match('{^@param (.+)}', trim($line), $matches)) {
|
||||
$paramDocs[] = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
$route->addOptions(array('_paramDocs' => $paramDocs));
|
||||
|
||||
return array('annotation' => $annotation, 'route' => $route);
|
||||
}
|
||||
|
||||
|
@ -78,12 +78,46 @@ abstract class AbstractFormatter implements FormatterInterface
|
||||
{
|
||||
$method = $route->getRequirement('_method');
|
||||
$data = array(
|
||||
'method' => $method ?: 'ANY',
|
||||
'uri' => $route->compile()->getPattern(),
|
||||
'requirements' => $route->compile()->getRequirements(),
|
||||
'method' => $method ?: 'ANY',
|
||||
'uri' => $route->compile()->getPattern(),
|
||||
);
|
||||
|
||||
unset($data['requirements']['_method']);
|
||||
$requirements = array();
|
||||
foreach ($route->compile()->getRequirements() as $name => $value) {
|
||||
if ('_method' !== $name) {
|
||||
$requirements[$name] = array(
|
||||
'value' => $value,
|
||||
'type' => '',
|
||||
'description' => '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $paramDocs = $route->getOption('_paramDocs')) {
|
||||
$regexp = '{(\w*) *\$%s +(.*)}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]['type'] = isset($matches[1]) ? $matches[1] : '';
|
||||
$requirements[$var]['description'] = $matches[2];
|
||||
|
||||
if (!isset($requirements[$var]['value'])) {
|
||||
$requirements[$var]['value'] = '';
|
||||
}
|
||||
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($requirements[$var]) && false === $found) {
|
||||
$requirements[$var] = array('value' => '', 'type' => '', 'description' => '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data['requirements'] = $requirements;
|
||||
|
||||
if (null !== $formType = $apiDoc->getFormType()) {
|
||||
$data['parameters'] = $this->parser->parse(new $formType());
|
||||
|
@ -29,8 +29,19 @@ class MarkdownFormatter extends AbstractFormatter
|
||||
if (isset($data['requirements']) && !empty($data['requirements'])) {
|
||||
$markdown .= "#### Requirements ####\n\n";
|
||||
|
||||
foreach ($data['requirements'] as $name => $value) {
|
||||
$markdown .= sprintf("* %s: %s\n", $name, $value);
|
||||
foreach ($data['requirements'] as $name => $infos) {
|
||||
$markdown .= sprintf("**%s**\n\n", $name);
|
||||
|
||||
if (!empty($infos['value'])) {
|
||||
$markdown .= sprintf(" - Value: %s\n", $infos['value']);
|
||||
}
|
||||
|
||||
if (!empty($infos['type'])) {
|
||||
$markdown .= sprintf(" - Type: %s\n", $infos['type']);
|
||||
}
|
||||
if (!empty($infos['description'])) {
|
||||
$markdown .= sprintf(" - Description: %s\n", $infos['description']);
|
||||
}
|
||||
}
|
||||
|
||||
$markdown .= "\n";
|
||||
|
@ -22,13 +22,17 @@
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in data.requirements %}
|
||||
{% for name, infos in data.requirements %}
|
||||
<tr>
|
||||
<td>{{ key }}</td>
|
||||
<td>{{ value }}</td>
|
||||
<td>{{ name }}</td>
|
||||
<td>{{ infos.value }}</td>
|
||||
<td>{{ infos.type }}</td>
|
||||
<td>{{ infos.description }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -22,7 +22,7 @@ class ApiDocExtractorTest extends WebTestCase
|
||||
$data = $extractor->all();
|
||||
|
||||
$this->assertTrue(is_array($data));
|
||||
$this->assertCount(7, $data);
|
||||
$this->assertCount(8, $data);
|
||||
|
||||
foreach ($data as $d) {
|
||||
$this->assertTrue(is_array($d));
|
||||
|
@ -57,8 +57,17 @@ class TestController
|
||||
* And, it supports multilines until the first '@' char.
|
||||
*
|
||||
* @ApiDoc()
|
||||
*
|
||||
* @param int $id A nice comment
|
||||
*/
|
||||
public function myCommentedAction()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @ApiDoc()
|
||||
*/
|
||||
public function yetAnotherAction()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -15,13 +15,19 @@ test_route_3:
|
||||
defaults: { _controller: NelmioApiDocTestBundle:Test:another }
|
||||
|
||||
test_route_4:
|
||||
pattern: /any
|
||||
pattern: /any/{foo}
|
||||
defaults: { _controller: NelmioApiDocTestBundle:Test:any, _format: json }
|
||||
|
||||
test_route_5:
|
||||
pattern: /my-commented
|
||||
pattern: /my-commented/{id}
|
||||
defaults: { _controller: NelmioApiDocTestBundle:Test:myCommented }
|
||||
|
||||
test_route_6:
|
||||
pattern: /yet-another/{id}
|
||||
defaults: { _controller: NelmioApiDocTestBundle:Test:yetAnother }
|
||||
requirements:
|
||||
id: \d+
|
||||
|
||||
test_service_route_1:
|
||||
pattern: /tests
|
||||
defaults: { _controller: nemlio.test.controller:indexAction, _format: json }
|
||||
|
@ -102,14 +102,36 @@ b:
|
||||
_Action without HTTP verb_
|
||||
|
||||
|
||||
### `ANY` /any ###
|
||||
### `ANY` /any/{foo} ###
|
||||
|
||||
_Action without HTTP verb_
|
||||
|
||||
#### Requirements ####
|
||||
|
||||
### `ANY` /my-commented ###
|
||||
**foo**
|
||||
|
||||
|
||||
|
||||
### `ANY` /my-commented/{id} ###
|
||||
|
||||
_This method is useful to test if the getDocComment works. And, it supports multilines until the first '@' char._
|
||||
|
||||
#### Requirements ####
|
||||
|
||||
**id**
|
||||
|
||||
- Type: int
|
||||
- Description: A nice comment
|
||||
|
||||
|
||||
### `ANY` /yet-another/{id} ###
|
||||
|
||||
|
||||
#### Requirements ####
|
||||
|
||||
**id**
|
||||
|
||||
- Value: \d+
|
||||
MARKDOWN;
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
|
@ -139,21 +139,32 @@ class SimpleFormatterTest extends WebTestCase
|
||||
1 =>
|
||||
array(
|
||||
'method' => 'ANY',
|
||||
'uri' => '/any',
|
||||
'uri' => '/any/{foo}',
|
||||
'requirements' =>
|
||||
array(
|
||||
'foo' => array('type' => '', 'description' => '', 'value' => ''),
|
||||
),
|
||||
'description' => 'Action without HTTP verb',
|
||||
),
|
||||
2 =>
|
||||
array(
|
||||
'method' => 'ANY',
|
||||
'uri' => '/my-commented',
|
||||
'uri' => '/my-commented/{id}',
|
||||
'requirements' =>
|
||||
array(
|
||||
'id' => array('type' => 'int', 'description' => 'A nice comment', 'value' => '')
|
||||
),
|
||||
'description' => 'This method is useful to test if the getDocComment works. And, it supports multilines until the first \'@\' char.',
|
||||
),
|
||||
3 =>
|
||||
array(
|
||||
'method' => 'ANY',
|
||||
'uri' => '/yet-another/{id}',
|
||||
'requirements' =>
|
||||
array(
|
||||
'id' => array('type' => '', 'description' => '', 'value' => '\d+')
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user