Merge PR #288 from piotrantosik/feature/selectparsers

This commit is contained in:
William DURAND 2013-12-28 18:42:51 +01:00
commit 627130637d
7 changed files with 243 additions and 11 deletions

View File

@ -256,12 +256,10 @@ class ApiDocExtractor
// input (populates 'parameters' for the formatters)
if (null !== $input = $annotation->getInput()) {
$parameters = array();
$normalizedInput = $this->normalizeClassParameter($input);
$supportedParsers = array();
$parameters = array();
foreach ($this->parsers as $parser) {
foreach ($this->getParsers($normalizedInput) as $parser) {
if ($parser->supports($normalizedInput)) {
$supportedParsers[] = $parser;
$parameters = $this->mergeParameters($parameters, $parser->parse($normalizedInput));
@ -270,8 +268,10 @@ class ApiDocExtractor
foreach ($supportedParsers as $parser) {
if ($parser instanceof PostParserInterface) {
$mp = $parser->postParse($normalizedInput, $parameters);
$parameters = $this->mergeParameters($parameters, $mp);
$parameters = $this->mergeParameters(
$parameters,
$parser->postParse($normalizedInput, $parameters)
);
}
}
@ -290,14 +290,14 @@ class ApiDocExtractor
// output (populates 'response' for the formatters)
if (null !== $output = $annotation->getOutput()) {
$response = array();
$normalizedOutput = $this->normalizeClassParameter($output);
foreach ($this->parsers as $parser) {
foreach ($this->getParsers($normalizedOutput) as $parser) {
if ($parser->supports($normalizedOutput)) {
$response = $this->mergeParameters($response, $parser->parse($normalizedOutput));
}
}
$response = $this->clearClasses($response);
$annotation->setResponse($response);
@ -410,4 +410,20 @@ class ApiDocExtractor
return $array;
}
private function getParsers(array $parameters)
{
if (isset($parameters['parsers'])) {
$parsers = array();
foreach ($this->parsers as $parser) {
if (in_array(get_class($parser), $parameters['parsers'])) {
$parsers[] = $parser;
}
}
} else {
$parsers = $this->parsers;
}
return $parsers;
}
}

View File

@ -257,6 +257,29 @@ input = {
}
```
=======
#### Used Parsers ####
By default, all registered parsers are used, but sometimes you may want to
define which parsers you want to use. The `parsers` attribute is used to
configure a list of parsers that will be used:
```
output={
"class" = "Acme\Bundle\Entity\User",
"parsers" = {
"Nelmio\ApiDocBundle\Parser\JmsMetadataParser",
"Nelmio\ApiDocBundle\Parser\ValidationParser"
}
}
```
In this case the parsers `JmsMetadataParser` and `ValidationParser` are used to
generate returned data.
This feature also works for both the `input` and `output` properties.
### On-The-Fly Documentation
By calling an URL with the parameter `?_doc=1`, you will get the corresponding

View File

@ -15,7 +15,7 @@ use Nelmio\ApiDocBundle\Tests\WebTestCase;
class ApiDocExtractorTest extends WebTestCase
{
const ROUTES_QUANTITY = 22;
const ROUTES_QUANTITY = 24;
public function testAll()
{
@ -215,4 +215,40 @@ class ApiDocExtractorTest extends WebTestCase
$annotation->getDeprecated()
);
}
public function testOutputWithSelectedParsers()
{
$container = $this->getContainer();
$extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor');
$annotation = $extractor->get('Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestController::zReturnSelectedParsersOutputAction', 'test_route_19');
$this->assertNotNull($annotation);
$output = $annotation->getOutput();
$parsers = $output['parsers'];
$this->assertEquals(
"Nelmio\\ApiDocBundle\\Parser\\JmsMetadataParser",
$parsers[0]
);
$this->assertEquals(
"Nelmio\\ApiDocBundle\\Parser\\ValidationParser",
$parsers[1]
);
$this->assertCount(2, $parsers);
}
public function testInputWithSelectedParsers()
{
$container = $this->getContainer();
$extractor = $container->get('nelmio_api_doc.extractor.api_doc_extractor');
$annotation = $extractor->get('Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestController::zReturnSelectedParsersInputAction', 'test_route_20');
$this->assertNotNull($annotation);
$input = $annotation->getInput();
$parsers = $input['parsers'];
$this->assertEquals(
"Nelmio\\ApiDocBundle\\Parser\\FormTypeParser",
$parsers[0]
);
$this->assertCount(1, $parsers);
}
}

View File

@ -232,4 +232,33 @@ class TestController
public function cgetAction($id)
{
}
/**
* @ApiDoc(
* input={
* "class"="Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType",
* "parsers"={
* "Nelmio\ApiDocBundle\Parser\FormTypeParser",
* }
* }
* )
*/
public function zReturnSelectedParsersInputAction()
{
}
/**
* @ApiDoc(
* output={
* "class"="Nelmio\ApiDocBundle\Tests\Fixtures\Model\MultipleTest",
* "parsers"={
* "Nelmio\ApiDocBundle\Parser\JmsMetadataParser",
* "Nelmio\ApiDocBundle\Parser\ValidationParser"
* }
* }
* )
*/
public function zReturnSelectedParsersOutputAction()
{
}
}

View File

@ -133,3 +133,11 @@ test_route_18:
test_route_named_resource:
pattern: /named-resource
defaults: { _controller: NelmioApiDocTestBundle:Test:namedResource }
test_route_19:
pattern: /z-return-selected-parsers-output
defaults: { _controller: NelmioApiDocTestBundle:Test:zReturnSelectedParsersOutput }
test_route_20:
pattern: /z-return-selected-parsers-input
defaults: { _controller: NelmioApiDocTestBundle:Test:zReturnSelectedParsersInput }

View File

@ -473,6 +473,54 @@ param1:
### `ANY` /z-return-jms-and-validator-output ###
#### Response ####
bar:
* type: DateTime
objects[]:
* type: array of objects (Test)
objects[][a]:
* type: string
objects[][b]:
* type: DateTime
number:
* type: DateTime
### `ANY` /z-return-selected-parsers-input ###
#### Parameters ####
a:
* type: string
* required: true
* description: A nice description
b:
* type: string
* required: false
c:
* type: boolean
* required: true
### `ANY` /z-return-selected-parsers-output ###
#### Response ####
bar:

View File

@ -861,6 +861,78 @@ With multiple lines.',
)
),
'authenticationRoles' => array(),
),
16 =>
array(
'method' => "ANY",
'uri' => "/z-return-selected-parsers-input",
'https' => false,
'authentication' => false,
'deprecated' => false,
'authenticationRoles' => array(),
'parameters' =>
array(
'a' => array(
'dataType' => 'string',
'required' => true,
'description' => 'A nice description',
'readonly' => false,
),
'b' => array(
'dataType' => 'string',
'required' => false,
'description' => '',
'readonly' => false,
),
'c' => array(
'dataType' => 'boolean',
'required' => true,
'description' => '',
'readonly' => false,
),
)
),
17 =>
array(
'method' => "ANY",
'uri' => "/z-return-selected-parsers-output",
'https' => false,
'authentication' => false,
'deprecated' => false,
'response' => array (
'bar' => array(
'dataType' => 'DateTime',
'required' => null,
'readonly' => null
),
'number' => array(
'dataType' => 'DateTime',
'required' => false,
'description' => '',
'readonly' => false,
'sinceVersion' => null,
'untilVersion' => null
),
'objects' => array(
'dataType' => 'array of objects (Test)',
'readonly' => null,
'required' => null,
'children' => array(
'a' => array(
'dataType' => 'string',
'format' => '{length: min: foo}, {not blank}',
'required' => true,
'readonly' => null
),
'b' => array(
'dataType' => 'DateTime',
'required' => null,
'readonly' => null
)
)
)
),
'authenticationRoles' => array(),
)
),
'/tests2' =>