From 3f66888f00048158ff30f5caf6556fb25e075ca9 Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Thu, 7 Nov 2013 16:17:23 +0100 Subject: [PATCH] Add PostParserInterface to JmsMetadataParser to get ValidatorParser found children parsed. --- Extractor/ApiDocExtractor.php | 10 ++++++ Parser/JmsMetadataParser.php | 36 ++++++++++++++++++- Tests/Fixtures/Model/MultipleTest.php | 5 +++ Tests/Formatter/MarkdownFormatterTest.php | 24 +++++++++++++ Tests/Formatter/SimpleFormatterTest.php | 42 +++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) diff --git a/Extractor/ApiDocExtractor.php b/Extractor/ApiDocExtractor.php index 6f051a8..13d66b8 100644 --- a/Extractor/ApiDocExtractor.php +++ b/Extractor/ApiDocExtractor.php @@ -293,14 +293,24 @@ class ApiDocExtractor // output (populates 'response' for the formatters) if (null !== $output = $annotation->getOutput()) { $response = array(); + $supportedParsers = array(); + $normalizedOutput = $this->normalizeClassParameter($output); foreach ($this->getParsers($normalizedOutput) as $parser) { if ($parser->supports($normalizedOutput)) { + $supportedParsers[] = $parser; $response = $this->mergeParameters($response, $parser->parse($normalizedOutput)); } } + foreach($supportedParsers as $parser) { + if($parser instanceof PostParserInterface) { + $mp = $parser->postParse($normalizedOutput, $response); + $response = $this->mergeParameters($response, $mp); + } + } + $response = $this->clearClasses($response); $annotation->setResponse($response); diff --git a/Parser/JmsMetadataParser.php b/Parser/JmsMetadataParser.php index 8af8432..f408733 100644 --- a/Parser/JmsMetadataParser.php +++ b/Parser/JmsMetadataParser.php @@ -22,7 +22,7 @@ use JMS\Serializer\Naming\PropertyNamingStrategyInterface; /** * Uses the JMS metadata factory to extract input/output model information */ -class JmsMetadataParser implements ParserInterface +class JmsMetadataParser implements ParserInterface, PostParserInterface { /** * @var \Metadata\MetadataFactoryInterface @@ -206,6 +206,40 @@ class JmsMetadataParser implements ParserInterface return in_array($type, array('boolean', 'integer', 'string', 'float', 'double', 'array', 'DateTime')); } + /** + * {@inheritDoc} + */ + public function postParse(array $input, array $parameters) + { + return $this->doPostParse($parameters); + } + + /** + * Recursive `doPostParse` to avoid circular post parsing. + * + * @param array $parameters + * @param array $visited + * @return array + */ + protected function doPostParse (array $parameters, array $visited = array()) + { + foreach($parameters as $param => $data) { + if(isset($data['class']) && isset($data['children']) && !in_array($data['class'], $visited)) { + $visited[] = $data['class']; + + $input = array('class' => $data['class'], 'groups' => isset($data['groups']) ? $data['groups'] : array()); + $parameters[$param]['children'] = array_merge( + $parameters[$param]['children'], $this->doPostParse($parameters[$param]['children'], $visited) + ); + $parameters[$param]['children'] = array_merge( + $parameters[$param]['children'], $this->doParse($input['class'], $visited, $input['groups']) + ); + } + } + + return $parameters; + } + /** * Check the various ways JMS describes values in arrays, and * get the value type in the array diff --git a/Tests/Fixtures/Model/MultipleTest.php b/Tests/Fixtures/Model/MultipleTest.php index 4942cf1..2a4b3e0 100644 --- a/Tests/Fixtures/Model/MultipleTest.php +++ b/Tests/Fixtures/Model/MultipleTest.php @@ -20,6 +20,11 @@ class MultipleTest */ public $baz; + /** + * @JMS\Type("Nelmio\ApiDocBundle\Tests\Fixtures\Model\Test") + */ + public $related; + /** * @Assert\Type(type="array") * @Assert\All({ diff --git a/Tests/Formatter/MarkdownFormatterTest.php b/Tests/Formatter/MarkdownFormatterTest.php index afec19d..f0a8870 100644 --- a/Tests/Formatter/MarkdownFormatterTest.php +++ b/Tests/Formatter/MarkdownFormatterTest.php @@ -489,6 +489,18 @@ number: * type: DateTime +related: + + * type: object (Test) + +related[a]: + + * type: string + +related[b]: + + * type: DateTime + ### `ANY` /z-return-selected-parsers-input ### @@ -536,6 +548,18 @@ objects[][b]: number: * type: DateTime + +related: + + * type: object (Test) + +related[a]: + + * type: string + +related[b]: + + * type: DateTime MARKDOWN; $this->assertEquals($expected, $result); diff --git a/Tests/Formatter/SimpleFormatterTest.php b/Tests/Formatter/SimpleFormatterTest.php index dfa5b5e..157314e 100644 --- a/Tests/Formatter/SimpleFormatterTest.php +++ b/Tests/Formatter/SimpleFormatterTest.php @@ -849,6 +849,27 @@ With multiple lines.', 'readonly' => null ) ) + ), + 'related' => array( + 'dataType' => 'object (Test)', + 'readonly' => false, + 'required' => false, + 'description' => '', + 'sinceVersion' => null, + 'untilVersion' => 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(), @@ -921,6 +942,27 @@ With multiple lines.', 'readonly' => null ) ) + ), + 'related' => array( + 'dataType' => 'object (Test)', + 'readonly' => false, + 'required' => false, + 'description' => '', + 'sinceVersion' => null, + 'untilVersion' => 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(),