mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-03-10 09:36:10 +03:00
Built parse-merging into the ApiDocExtractor.
Wired up a "post-parse" pass to allow recursive parsing across multiple parsers.
This commit is contained in:
parent
0913157399
commit
5e1549a29d
@ -268,10 +268,17 @@ class ApiDocExtractor
|
||||
|
||||
$normalizedInput = $this->normalizeClassParameter($input);
|
||||
|
||||
$parameters = array();
|
||||
foreach ($this->parsers as $parser) {
|
||||
if ($parser->supports($normalizedInput)) {
|
||||
$parameters = $parser->parse($normalizedInput);
|
||||
break;
|
||||
$parameters = $this->mergeParameters($parameters, $parser->parse($normalizedInput));
|
||||
}
|
||||
}
|
||||
|
||||
foreach($this->parsers as $parser) {
|
||||
if($parser->supports($normalizedInput) && method_exists($parser, 'postParse')) {
|
||||
$mp = $parser->postParse($normalizedInput, $parameters);
|
||||
$parameters = $this->mergeParameters($parameters, $mp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +301,6 @@ class ApiDocExtractor
|
||||
foreach ($this->parsers as $parser) {
|
||||
if ($parser->supports($normalizedOutput)) {
|
||||
$response = $parser->parse($normalizedOutput);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,6 +380,45 @@ class ApiDocExtractor
|
||||
return array_merge($defaults, $input);
|
||||
}
|
||||
|
||||
protected function mergeParameters($p1, $p2)
|
||||
{
|
||||
$params = array();
|
||||
|
||||
foreach($p2 as $propname => $propvalue) {
|
||||
if(!isset($p1[$propname])) {
|
||||
$params[$propname] = $propvalue;
|
||||
} else {
|
||||
$v1 = $p1[$propname];
|
||||
|
||||
foreach($propvalue as $name => $value) {
|
||||
if(is_array($value)) {
|
||||
if(isset($v1[$name]) && is_array($v1[$name])) {
|
||||
$v1[$name] = $this->mergeParameters($v1[$name], $value);
|
||||
} else {
|
||||
$v1[$name] = $value;
|
||||
}
|
||||
} elseif(!is_null($value)) {
|
||||
if(in_array($name, array('required', 'readonly'))) {
|
||||
$v1[$name] = $v1[$name] || $value;
|
||||
} elseif($name == 'requirement') {
|
||||
if(isset($v1[$name])) {
|
||||
$v1[$name] .= ', ' . $value;
|
||||
} else {
|
||||
$v1[$name] = $value;
|
||||
}
|
||||
} else {
|
||||
$v1[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$params[$propname] = $v1;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses annotations for a given method, and adds new information to the given ApiDoc
|
||||
* annotation. Useful to extract information from the FOSRestBundle annotations.
|
||||
|
@ -69,10 +69,10 @@ abstract class AbstractFormatter implements FormatterInterface
|
||||
$newName = $this->getNewName($name, $info, $parentName);
|
||||
|
||||
$newParams[$newName] = array(
|
||||
'description' => $info['description'],
|
||||
'dataType' => $info['dataType'],
|
||||
'readonly' => $info['readonly'],
|
||||
'required' => $info['required'],
|
||||
'description' => array_key_exists('description', $info) ? $info['description'] : null,
|
||||
'format' => array_key_exists('format', $info) ? $info['format'] : null,
|
||||
'sinceVersion' => array_key_exists('sinceVersion', $info) ? $info['sinceVersion'] : null,
|
||||
'untilVersion' => array_key_exists('untilVersion', $info) ? $info['untilVersion'] : null,
|
||||
|
@ -87,7 +87,6 @@ class FormTypeParser implements ParserInterface
|
||||
|
||||
private function parseForm($form, $prefix = null)
|
||||
{
|
||||
$className = get_class($form);
|
||||
$parameters = array();
|
||||
foreach ($form as $name => $child) {
|
||||
$config = $child->getConfig();
|
||||
@ -133,6 +132,8 @@ class FormTypeParser implements ParserInterface
|
||||
'description' => $config->getAttribute('description'),
|
||||
'readonly' => $config->getDisabled(),
|
||||
);
|
||||
} else {
|
||||
$parameters[$name]['class'] = $type;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -126,6 +126,10 @@ class JmsMetadataParser implements ParserInterface
|
||||
'untilVersion' => $item->untilVersion,
|
||||
);
|
||||
|
||||
if(!is_null($dataType['class'])) {
|
||||
$params[$name]['class'] = $dataType['class'];
|
||||
}
|
||||
|
||||
// if class already parsed, continue, to avoid infinite recursion
|
||||
if (in_array($dataType['class'], $visited)) {
|
||||
continue;
|
||||
|
@ -6,7 +6,7 @@ use Nelmio\ApiDocBundle\Parser\ParserInterface;
|
||||
use Symfony\Component\Validator\MetadataFactoryInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
class SymfonyValidationParser implements ParserInterface
|
||||
class ValidationParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\Validator\MetadataFactoryInterface
|
||||
@ -33,26 +33,49 @@ class SymfonyValidationParser implements ParserInterface
|
||||
*/
|
||||
public function parse(array $input)
|
||||
{
|
||||
$vparams = array();
|
||||
$params = array();
|
||||
$className = $input['class'];
|
||||
|
||||
$classdata = $this->factory->getMetadataFor($className);
|
||||
$properties = $classdata->getConstrainedProperties();
|
||||
|
||||
if($classdata->hasPropertyMetadata($name)) {
|
||||
$propdata = $classdata->getPropertyMetadata($name);
|
||||
$propdata = reset($propdata);
|
||||
foreach($properties as $property) {
|
||||
$vparams = array();
|
||||
$pds = $classdata->getPropertyMetadata($property);
|
||||
foreach($pds as $propdata) {
|
||||
$constraints = $propdata->getConstraints();
|
||||
|
||||
foreach($constraints as $constraint) {
|
||||
$vparams = $this->parseConstraint($constraint, $vparams);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($vparams['format'])) {
|
||||
$vparams['format'] = join(', ', $vparams['format']);
|
||||
}
|
||||
|
||||
foreach(array('dataType', 'readonly', 'required') as $reqprop) {
|
||||
if(!isset($vparams[$reqprop])) {
|
||||
$vparams[$reqprop] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $vparams;
|
||||
$params[$property] = $vparams;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function postParse(array $input, $parameters)
|
||||
{
|
||||
foreach($parameters as $param => $data) {
|
||||
if(isset($data['class']) && isset($data['children'])) {
|
||||
$input = array('class' => $data['class']);
|
||||
$parameters[$param]['children'] = $this->parse($input, $parameters[$param]['children']);
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
protected function parseConstraint(Constraint $constraint, $vparams)
|
@ -5,7 +5,7 @@
|
||||
|
||||
<parameters>
|
||||
<parameter key="nelmio_api_doc.parser.form_type_parser.class">Nelmio\ApiDocBundle\Parser\FormTypeParser</parameter>
|
||||
<parameter key="nelmio_api_doc.parser.symfony_validation_parser.class">Nelmio\ApiDocBundle\Parser\SymfonyValidationParser</parameter>
|
||||
<parameter key="nelmio_api_doc.parser.validation_parser.class">Nelmio\ApiDocBundle\Parser\ValidationParser</parameter>
|
||||
<parameter key="nelmio_api_doc.formatter.abstract_formatter.class">Nelmio\ApiDocBundle\Formatter\AbstractFormatter</parameter>
|
||||
<parameter key="nelmio_api_doc.formatter.markdown_formatter.class">Nelmio\ApiDocBundle\Formatter\MarkdownFormatter</parameter>
|
||||
<parameter key="nelmio_api_doc.formatter.simple_formatter.class">Nelmio\ApiDocBundle\Formatter\SimpleFormatter</parameter>
|
||||
@ -19,7 +19,7 @@
|
||||
<argument type="service" id="form.registry" />
|
||||
<tag name="nelmio_api_doc.extractor.parser" />
|
||||
</service>
|
||||
<service id="nelmio_api_doc.parser.symfony_validation_parser" class="%nelmio_api_doc.parser.symfony_validation_parser.class%">
|
||||
<service id="nelmio_api_doc.parser.validation_parser" class="%nelmio_api_doc.parser.validation_parser.class%">
|
||||
<argument type="service" id="validator.mapping.class_metadata_factory"/>
|
||||
<tag name="nelmio_api_doc.extractor.parser" />
|
||||
</service>
|
||||
|
Loading…
x
Reference in New Issue
Block a user