select used parsers

This commit is contained in:
Piotr Antosik 2013-12-05 00:05:47 +01:00 committed by William DURAND
parent 2ceea4871a
commit 3fdbfbed1c
9 changed files with 246 additions and 14 deletions

View File

@ -269,23 +269,23 @@ class ApiDocExtractor
// input (populates 'parameters' for the formatters)
if (null !== $input = $annotation->getInput()) {
$parameters = array();
$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));
$parameters = $this->mergeParameters($parameters, $parser->parse($normalizedInput));
}
}
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)
);
}
}
@ -303,15 +303,15 @@ class ApiDocExtractor
// output (populates 'response' for the formatters)
if (null !== $output = $annotation->getOutput()) {
$response = array();
$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);
@ -477,4 +477,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

@ -24,7 +24,7 @@ class JmsSecurityExtraHandler implements HandlerInterface
foreach ($annotations as $annot) {
if ($annot instanceof PreAuthorize) {
$annotation->setAuthentication(true);
} else if ($annot instanceof Secure) {
} elseif ($annot instanceof Secure) {
$annotation->setAuthentication(true);
$annotation->setAuthenticationRoles(is_array($annot->roles) ? $annot->roles : explode(',', $annot->roles));
}

View File

@ -52,6 +52,7 @@ class ValidationParser implements ParserInterface, PostParserInterface
public function parse(array $input)
{
$className = $input['class'];
return $this->doParse($className, array());
}
@ -62,7 +63,7 @@ class ValidationParser implements ParserInterface, PostParserInterface
* @param array $visited
* @return array
*/
protected function doParse ($className, array $visited)
protected function doParse($className, array $visited)
{
$params = array();
$classdata = $this->factory->getMetadataFor($className);

View File

@ -229,7 +229,7 @@ you can specify which groups to use when generating the documentation by using t
If your `output` classes use [versioning capabilities of JMS Serializer](http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies#versioning-objects),
the versioning information will be automatically used when generating the documentation.
#### Form Types features ####
#### Form Types Features ####
If you use `FormFactoryInterface::createdNamed('', 'your_form_type'`, then by default the documentation will use
the form type name as the prefix (`your_form_type[param]` ... instead of just `param`).
@ -243,6 +243,28 @@ 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.
### Documentation on-the-fly ###
By calling an URL with the parameter `?_doc=1`, you will get the corresponding documentation if available.

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

@ -223,4 +223,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

@ -129,3 +129,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' =>