2013-06-10 17:18:17 -07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Nelmio\ApiDocBundle\Parser;
|
|
|
|
|
|
|
|
use Nelmio\ApiDocBundle\Parser\ParserInterface;
|
|
|
|
use Symfony\Component\Validator\MetadataFactoryInterface;
|
|
|
|
use Symfony\Component\Validator\Constraint;
|
|
|
|
|
2013-06-30 18:46:00 -07:00
|
|
|
class ValidationParser implements ParserInterface
|
2013-06-10 17:18:17 -07:00
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var \Symfony\Component\Validator\MetadataFactoryInterface
|
|
|
|
*/
|
|
|
|
protected $factory;
|
|
|
|
|
|
|
|
public function __construct(MetadataFactoryInterface $factory)
|
|
|
|
{
|
|
|
|
$this->factory = $factory;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function supports(array $input)
|
|
|
|
{
|
|
|
|
$className = $input['class'];
|
|
|
|
|
|
|
|
return $this->factory->hasMetadataFor($className);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function parse(array $input)
|
|
|
|
{
|
2013-06-30 18:46:00 -07:00
|
|
|
$params = array();
|
2013-06-10 17:18:17 -07:00
|
|
|
$className = $input['class'];
|
|
|
|
|
|
|
|
$classdata = $this->factory->getMetadataFor($className);
|
2013-06-30 18:46:00 -07:00
|
|
|
$properties = $classdata->getConstrainedProperties();
|
2013-06-10 17:18:17 -07:00
|
|
|
|
2013-06-30 18:46:00 -07:00
|
|
|
foreach($properties as $property) {
|
|
|
|
$vparams = array();
|
|
|
|
$pds = $classdata->getPropertyMetadata($property);
|
|
|
|
foreach($pds as $propdata) {
|
|
|
|
$constraints = $propdata->getConstraints();
|
2013-06-10 17:18:17 -07:00
|
|
|
|
2013-06-30 18:46:00 -07:00
|
|
|
foreach($constraints as $constraint) {
|
|
|
|
$vparams = $this->parseConstraint($constraint, $vparams);
|
|
|
|
}
|
2013-06-10 17:18:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if(isset($vparams['format'])) {
|
|
|
|
$vparams['format'] = join(', ', $vparams['format']);
|
|
|
|
}
|
2013-06-30 18:46:00 -07:00
|
|
|
|
|
|
|
foreach(array('dataType', 'readonly', 'required') as $reqprop) {
|
|
|
|
if(!isset($vparams[$reqprop])) {
|
|
|
|
$vparams[$reqprop] = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$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']);
|
|
|
|
}
|
2013-06-10 17:18:17 -07:00
|
|
|
}
|
|
|
|
|
2013-06-30 18:46:00 -07:00
|
|
|
return $parameters;
|
2013-06-10 17:18:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function parseConstraint(Constraint $constraint, $vparams)
|
|
|
|
{
|
|
|
|
$class = substr(get_class($constraint), strlen('Symfony\\Component\\Validator\\Constraints\\'));
|
|
|
|
|
|
|
|
switch($class) {
|
|
|
|
case 'NotBlank':
|
|
|
|
case 'NotNull':
|
|
|
|
$vparams['required'] = true;
|
|
|
|
break;
|
|
|
|
case 'Type':
|
|
|
|
$vparams['dataType'] = $constraint->type;
|
|
|
|
break;
|
|
|
|
case 'Email':
|
|
|
|
$vparams['format'][] = '{email address}';
|
|
|
|
break;
|
|
|
|
case 'Url':
|
|
|
|
$vparams['format'][] = '{url}';
|
|
|
|
break;
|
|
|
|
case 'Ip':
|
|
|
|
$vparams['format'][] = '{ip address}';
|
|
|
|
break;
|
|
|
|
case 'Length':
|
|
|
|
$messages = array();
|
|
|
|
if(isset($constraint->min)) {
|
|
|
|
$messages[] = "min: {$constraint->min}";
|
|
|
|
}
|
|
|
|
if(isset($constraint->max)) {
|
|
|
|
$messages[] = "max: {$constraint->max}";
|
|
|
|
}
|
|
|
|
$vparams['format'][] = '{length: ' . join(', ', $messages) . '}';
|
|
|
|
break;
|
|
|
|
case 'Choice':
|
|
|
|
$format = '[' . join('|', $constraint->choices) . ']';
|
|
|
|
if($constraint->multiple) {
|
|
|
|
$messages = array();
|
|
|
|
if(isset($constraint->min)) {
|
|
|
|
$messages[] = "min: {$constraint->min} ";
|
|
|
|
}
|
|
|
|
if(isset($constraint->max)) {
|
|
|
|
$messages[] = "max: {$constraint->max} ";
|
|
|
|
}
|
|
|
|
$vparams['format'][] = '{' . join ('', $messages) . 'choice of ' . $format . '}';
|
|
|
|
} else {
|
|
|
|
$vparams['format'][] = $format;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'Regex':
|
|
|
|
if($constraint->match) {
|
|
|
|
$vparams['format'][] = '{match: ' . $constraint->pattern . '}';
|
|
|
|
} else {
|
|
|
|
$vparams['format'][] = '{not match: ' . $constraint->pattern . '}';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $vparams;
|
|
|
|
}
|
|
|
|
}
|