This commit is contained in:
William DURAND 2013-11-14 10:28:42 +01:00
parent f94d6403f5
commit d7fd929379
13 changed files with 60 additions and 65 deletions

View File

@ -482,6 +482,7 @@ class ApiDoc
public function setDeprecated($deprecated) public function setDeprecated($deprecated)
{ {
$this->deprecated = (bool) $deprecated; $this->deprecated = (bool) $deprecated;
return $this; return $this;
} }

View File

@ -15,7 +15,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
class ExtractorHandlerCompilerPass implements CompilerPassInterface class ExtractorHandlerCompilerPass implements CompilerPassInterface
{ {
/** /**
@ -25,13 +24,11 @@ class ExtractorHandlerCompilerPass implements CompilerPassInterface
{ {
$handlers = array(); $handlers = array();
foreach ($container->findTaggedServiceIds('nelmio_api_doc.extractor.handler') as $id => $attributes) { foreach ($container->findTaggedServiceIds('nelmio_api_doc.extractor.handler') as $id => $attributes) {
// Adding handlers from tagged services
$handlers[] = new Reference($id); $handlers[] = new Reference($id);
} }
$definition = $container->getDefinition(
'nelmio_api_doc.extractor.api_doc_extractor' $container
); ->getDefinition('nelmio_api_doc.extractor.api_doc_extractor')
$definition->replaceArgument(4, $handlers); ->replaceArgument(4, $handlers);
} }
} }

View File

@ -23,7 +23,7 @@ use Nelmio\ApiDocBundle\Util\DocCommentExtractor;
class ApiDocExtractor class ApiDocExtractor
{ {
const ANNOTATION_CLASS = 'Nelmio\\ApiDocBundle\\Annotation\\ApiDoc'; const ANNOTATION_CLASS = 'Nelmio\\ApiDocBundle\\Annotation\\ApiDoc';
/** /**
* @var ContainerInterface * @var ContainerInterface
@ -46,22 +46,22 @@ class ApiDocExtractor
private $commentExtractor; private $commentExtractor;
/** /**
* @var array ParserInterface * @var ParserInterface[]
*/ */
protected $parsers = array(); protected $parsers = array();
/** /**
* @var array HandlerInterface * @var HandlerInterface[]
*/ */
protected $handlers; protected $handlers;
public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader, DocCommentExtractor $commentExtractor, array $handlers) public function __construct(ContainerInterface $container, RouterInterface $router, Reader $reader, DocCommentExtractor $commentExtractor, array $handlers)
{ {
$this->container = $container; $this->container = $container;
$this->router = $router; $this->router = $router;
$this->reader = $reader; $this->reader = $reader;
$this->commentExtractor = $commentExtractor; $this->commentExtractor = $commentExtractor;
$this->handlers = $handlers; $this->handlers = $handlers;
} }
/** /**
@ -141,7 +141,7 @@ class ApiDocExtractor
} }
$methodOrder = array('GET', 'POST', 'PUT', 'DELETE'); $methodOrder = array('GET', 'POST', 'PUT', 'DELETE');
usort($array, function($a, $b) use ($methodOrder) { usort($array, function ($a, $b) use ($methodOrder) {
if ($a['resource'] === $b['resource']) { if ($a['resource'] === $b['resource']) {
if ($a['annotation']->getRoute()->getPattern() === $b['annotation']->getRoute()->getPattern()) { if ($a['annotation']->getRoute()->getPattern() === $b['annotation']->getRoute()->getPattern()) {
$methodA = array_search($a['annotation']->getRoute()->getRequirement('_method'), $methodOrder); $methodA = array_search($a['annotation']->getRoute()->getRequirement('_method'), $methodOrder);
@ -282,8 +282,8 @@ class ApiDocExtractor
} }
} }
foreach($supportedParsers as $parser) { foreach ($supportedParsers as $parser) {
if($parser instanceof PostParserInterface) { if ($parser instanceof PostParserInterface) {
$mp = $parser->postParse($normalizedInput, $parameters); $mp = $parser->postParse($normalizedInput, $parameters);
$parameters = $this->mergeParameters($parameters, $mp); $parameters = $this->mergeParameters($parameters, $mp);
} }
@ -293,7 +293,7 @@ class ApiDocExtractor
if ('PUT' === $method) { if ('PUT' === $method) {
// All parameters are optional with PUT (update) // All parameters are optional with PUT (update)
array_walk($parameters, function($val, $key) use (&$data) { array_walk($parameters, function ($val, $key) use (&$data) {
$parameters[$key]['required'] = false; $parameters[$key]['required'] = false;
}); });
} }
@ -401,32 +401,32 @@ class ApiDocExtractor
* - Other string values are overridden by later parsers when present. * - Other string values are overridden by later parsers when present.
* - Array parameters are recursively merged. * - Array parameters are recursively merged.
* *
* @param array $p1 The pre-existing parameters array. * @param array $p1 The pre-existing parameters array.
* @param array $p2 The newly-returned parameters array. * @param array $p2 The newly-returned parameters array.
* @return array The resulting, merged array. * @return array The resulting, merged array.
*/ */
protected function mergeParameters($p1, $p2) protected function mergeParameters($p1, $p2)
{ {
$params = $p1; $params = $p1;
foreach($p2 as $propname => $propvalue) { foreach ($p2 as $propname => $propvalue) {
if(!isset($p1[$propname])) { if (!isset($p1[$propname])) {
$params[$propname] = $propvalue; $params[$propname] = $propvalue;
} else { } else {
$v1 = $p1[$propname]; $v1 = $p1[$propname];
foreach($propvalue as $name => $value) { foreach ($propvalue as $name => $value) {
if(is_array($value)) { if (is_array($value)) {
if(isset($v1[$name]) && is_array($v1[$name])) { if (isset($v1[$name]) && is_array($v1[$name])) {
$v1[$name] = $this->mergeParameters($v1[$name], $value); $v1[$name] = $this->mergeParameters($v1[$name], $value);
} else { } else {
$v1[$name] = $value; $v1[$name] = $value;
} }
} elseif(!is_null($value)) { } elseif (!is_null($value)) {
if(in_array($name, array('required', 'readonly'))) { if (in_array($name, array('required', 'readonly'))) {
$v1[$name] = $v1[$name] || $value; $v1[$name] = $v1[$name] || $value;
} elseif(in_array($name, array('requirement'))) { } elseif (in_array($name, array('requirement'))) {
if(isset($v1[$name])) { if (isset($v1[$name])) {
$v1[$name] .= ', ' . $value; $v1[$name] .= ', ' . $value;
} else { } else {
$v1[$name] = $value; $v1[$name] = $value;
@ -463,17 +463,18 @@ class ApiDocExtractor
/** /**
* Clears the temporary 'class' parameter from the parameters array before it is returned. * Clears the temporary 'class' parameter from the parameters array before it is returned.
* *
* @param array $array The source array. * @param array $array The source array.
* @return array The cleared array. * @return array The cleared array.
*/ */
protected function clearClasses($array) protected function clearClasses($array)
{ {
if(is_array($array)) { if (is_array($array)) {
unset($array['class']); unset($array['class']);
foreach($array as $name => $item) { foreach ($array as $name => $item) {
$array[$name] = $this->clearClasses($item); $array[$name] = $this->clearClasses($item);
} }
} }
return $array; return $array;
} }
} }

View File

@ -36,7 +36,7 @@ class FosRestHandler implements HandlerInterface
'dataType' => '', 'dataType' => '',
'description' => $annot->description, 'description' => $annot->description,
)); ));
} elseif($annot->default !== null) { } elseif ($annot->default !== null) {
$annotation->addFilter($annot->name, array( $annotation->addFilter($annot->name, array(
'requirement' => $annot->requirements, 'requirement' => $annot->requirements,
'description' => $annot->description, 'description' => $annot->description,

View File

@ -20,7 +20,7 @@ class MarkdownFormatter extends AbstractFormatter
{ {
$markdown = sprintf("### `%s` %s ###\n", $data['method'], $data['uri']); $markdown = sprintf("### `%s` %s ###\n", $data['method'], $data['uri']);
if(isset($data['deprecated']) && false !== $data['deprecated']) { if (isset($data['deprecated']) && false !== $data['deprecated']) {
$markdown .= "### This method is deprecated ###"; $markdown .= "### This method is deprecated ###";
$markdown .= "\n\n"; $markdown .= "\n\n";
} }

View File

@ -126,7 +126,7 @@ class JmsMetadataParser implements ParserInterface
'untilVersion' => $item->untilVersion, 'untilVersion' => $item->untilVersion,
); );
if(!is_null($dataType['class'])) { if (!is_null($dataType['class'])) {
$params[$name]['class'] = $dataType['class']; $params[$name]['class'] = $dataType['class'];
} }

View File

@ -19,7 +19,7 @@ interface ParserInterface
/** /**
* Return true/false whether this class supports parsing the given class. * Return true/false whether this class supports parsing the given class.
* *
* @param array $item containing the following fields: class, groups. Of which groups is optional * @param array $item containing the following fields: class, groups. Of which groups is optional
* @return boolean * @return boolean
*/ */
public function supports(array $item); public function supports(array $item);

View File

@ -56,23 +56,23 @@ class ValidationParser implements ParserInterface, PostParserInterface
$classdata = $this->factory->getMetadataFor($className); $classdata = $this->factory->getMetadataFor($className);
$properties = $classdata->getConstrainedProperties(); $properties = $classdata->getConstrainedProperties();
foreach($properties as $property) { foreach ($properties as $property) {
$vparams = array(); $vparams = array();
$pds = $classdata->getPropertyMetadata($property); $pds = $classdata->getPropertyMetadata($property);
foreach($pds as $propdata) { foreach ($pds as $propdata) {
$constraints = $propdata->getConstraints(); $constraints = $propdata->getConstraints();
foreach($constraints as $constraint) { foreach ($constraints as $constraint) {
$vparams = $this->parseConstraint($constraint, $vparams, $className); $vparams = $this->parseConstraint($constraint, $vparams, $className);
} }
} }
if(isset($vparams['format'])) { if (isset($vparams['format'])) {
$vparams['format'] = join(', ', $vparams['format']); $vparams['format'] = join(', ', $vparams['format']);
} }
foreach(array('dataType', 'readonly', 'required') as $reqprop) { foreach (array('dataType', 'readonly', 'required') as $reqprop) {
if(!isset($vparams[$reqprop])) { if (!isset($vparams[$reqprop])) {
$vparams[$reqprop] = null; $vparams[$reqprop] = null;
} }
} }
@ -88,8 +88,8 @@ class ValidationParser implements ParserInterface, PostParserInterface
*/ */
public function postParse(array $input, array $parameters) public function postParse(array $input, array $parameters)
{ {
foreach($parameters as $param => $data) { foreach ($parameters as $param => $data) {
if(isset($data['class']) && isset($data['children'])) { if (isset($data['class']) && isset($data['children'])) {
$input = array('class' => $data['class']); $input = array('class' => $data['class']);
$parameters[$param]['children'] = array_merge( $parameters[$param]['children'] = array_merge(
$parameters[$param]['children'], $this->postParse($input, $parameters[$param]['children']) $parameters[$param]['children'], $this->postParse($input, $parameters[$param]['children'])
@ -115,15 +115,15 @@ class ValidationParser implements ParserInterface, PostParserInterface
* - Choice (single and multiple, min and max) * - Choice (single and multiple, min and max)
* - Regex (match and non-match) * - Regex (match and non-match)
* *
* @param Constraint $constraint The constraint metadata object. * @param Constraint $constraint The constraint metadata object.
* @param array $vparams The existing validation parameters. * @param array $vparams The existing validation parameters.
* @return mixed The parsed list of validation parameters. * @return mixed The parsed list of validation parameters.
*/ */
protected function parseConstraint(Constraint $constraint, $vparams, $className) protected function parseConstraint(Constraint $constraint, $vparams, $className)
{ {
$class = substr(get_class($constraint), strlen('Symfony\\Component\\Validator\\Constraints\\')); $class = substr(get_class($constraint), strlen('Symfony\\Component\\Validator\\Constraints\\'));
switch($class) { switch ($class) {
case 'NotBlank': case 'NotBlank':
case 'NotNull': case 'NotNull':
$vparams['required'] = true; $vparams['required'] = true;
@ -142,10 +142,10 @@ class ValidationParser implements ParserInterface, PostParserInterface
break; break;
case 'Length': case 'Length':
$messages = array(); $messages = array();
if(isset($constraint->min)) { if (isset($constraint->min)) {
$messages[] = "min: {$constraint->min}"; $messages[] = "min: {$constraint->min}";
} }
if(isset($constraint->max)) { if (isset($constraint->max)) {
$messages[] = "max: {$constraint->max}"; $messages[] = "max: {$constraint->max}";
} }
$vparams['format'][] = '{length: ' . join(', ', $messages) . '}'; $vparams['format'][] = '{length: ' . join(', ', $messages) . '}';
@ -153,12 +153,12 @@ class ValidationParser implements ParserInterface, PostParserInterface
case 'Choice': case 'Choice':
$choices = $this->getChoices($constraint, $className); $choices = $this->getChoices($constraint, $className);
$format = '[' . join('|', $choices) . ']'; $format = '[' . join('|', $choices) . ']';
if($constraint->multiple) { if ($constraint->multiple) {
$messages = array(); $messages = array();
if(isset($constraint->min)) { if (isset($constraint->min)) {
$messages[] = "min: {$constraint->min} "; $messages[] = "min: {$constraint->min} ";
} }
if(isset($constraint->max)) { if (isset($constraint->max)) {
$messages[] = "max: {$constraint->max} "; $messages[] = "max: {$constraint->max} ";
} }
$vparams['format'][] = '{' . join ('', $messages) . 'choice of ' . $format . '}'; $vparams['format'][] = '{' . join ('', $messages) . 'choice of ' . $format . '}';
@ -167,7 +167,7 @@ class ValidationParser implements ParserInterface, PostParserInterface
} }
break; break;
case 'Regex': case 'Regex':
if($constraint->match) { if ($constraint->match) {
$vparams['format'][] = '{match: ' . $constraint->pattern . '}'; $vparams['format'][] = '{match: ' . $constraint->pattern . '}';
} else { } else {
$vparams['format'][] = '{not match: ' . $constraint->pattern . '}'; $vparams['format'][] = '{not match: ' . $constraint->pattern . '}';
@ -186,7 +186,7 @@ class ValidationParser implements ParserInterface, PostParserInterface
* @return array * @return array
* @throws \Symfony\Component\Validator\Exception\ConstraintDefinitionException * @throws \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/ */
protected function getChoices (Constraint $constraint, $className) protected function getChoices(Constraint $constraint, $className)
{ {
if ($constraint->callback) { if ($constraint->callback) {
if (is_callable(array($className, $constraint->callback))) { if (is_callable(array($className, $constraint->callback))) {

View File

@ -87,4 +87,4 @@ class FosRestHandlerTest extends WebTestCase
$this->assertArrayNotHasKey('default', $filter); $this->assertArrayNotHasKey('default', $filter);
} }
} }

View File

@ -80,10 +80,10 @@ class TestController
* *
* @ApiDoc() * @ApiDoc()
* *
* @param int $id A nice comment * @param int $id A nice comment
* @param int $page * @param int $page
* @param int $paramType The param type * @param int $paramType The param type
* @param int $param The param id * @param int $param The param id
*/ */
public function myCommentedAction() public function myCommentedAction()
{ {

View File

@ -7,7 +7,6 @@ use Nelmio\ApiDocBundle\Tests\Fixtures;
use Symfony\Component\Form\Extension\Core\CoreExtension; use Symfony\Component\Form\Extension\Core\CoreExtension;
use Symfony\Component\Form\FormFactory; use Symfony\Component\Form\FormFactory;
use Symfony\Component\Form\FormFactoryBuilder; use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Form\FormRegistry;
use Symfony\Component\Form\ResolvedFormTypeFactory; use Symfony\Component\Form\ResolvedFormTypeFactory;
class FormTypeParserTest extends \PHPUnit_Framework_TestCase class FormTypeParserTest extends \PHPUnit_Framework_TestCase

View File

@ -4,7 +4,6 @@ namespace NelmioApiDocBundle\Tests\Parser;
use Nelmio\ApiDocBundle\Tests\WebTestCase; use Nelmio\ApiDocBundle\Tests\WebTestCase;
use Nelmio\ApiDocBundle\Parser\ValidationParser; use Nelmio\ApiDocBundle\Parser\ValidationParser;
class ValidationParserTest extends WebTestCase class ValidationParserTest extends WebTestCase
{ {
protected $handler; protected $handler;
@ -24,12 +23,11 @@ class ValidationParserTest extends WebTestCase
{ {
$result = $this->parser->parse(array('class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\ValidatorTest')); $result = $this->parser->parse(array('class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\ValidatorTest'));
foreach($expected as $name => $value) { foreach ($expected as $name => $value) {
$this->assertEquals($value, $expected[$name]); $this->assertEquals($value, $expected[$name]);
} }
} }
public function dataTestParser() public function dataTestParser()
{ {
return array( return array(

View File

@ -14,7 +14,6 @@ namespace Nelmio\ApiDocBundle\Tests;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\DependencyInjection\Scope;
abstract class WebTestCase extends BaseWebTestCase abstract class WebTestCase extends BaseWebTestCase
{ {