2013-06-10 17:18:17 -07:00
< ? php
2013-07-02 21:57:09 -07:00
/*
* This file is part of the NelmioApiDocBundle .
*
* ( c ) Nelmio < hello @ nelm . io >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2013-06-10 17:18:17 -07:00
namespace Nelmio\ApiDocBundle\Parser ;
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
use Nelmio\ApiDocBundle\DataTypes ;
2013-11-06 15:25:10 +01:00
use Symfony\Component\Validator\Exception\ConstraintDefinitionException ;
2015-11-30 19:19:17 +01:00
use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface ;
use Symfony\Component\Validator\MetadataFactoryInterface as LegacyMetadataFactoryInterface ;
2013-06-10 17:18:17 -07:00
use Symfony\Component\Validator\Constraint ;
2013-11-07 14:11:09 +01:00
use Symfony\Component\Validator\Constraints\Type ;
2013-06-10 17:18:17 -07:00
2013-07-02 21:57:09 -07:00
/**
* Uses the Symfony Validation component to extract information about API objects .
*/
class ValidationParser implements ParserInterface , PostParserInterface
2013-06-10 17:18:17 -07:00
{
/**
* @ var \Symfony\Component\Validator\MetadataFactoryInterface
*/
protected $factory ;
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
protected $typeMap = array (
2014-06-17 17:05:00 -07:00
'integer' => DataTypes :: INTEGER ,
'int' => DataTypes :: INTEGER ,
'scalar' => DataTypes :: STRING ,
'numeric' => DataTypes :: INTEGER ,
'boolean' => DataTypes :: BOOLEAN ,
'string' => DataTypes :: STRING ,
'float' => DataTypes :: FLOAT ,
'double' => DataTypes :: FLOAT ,
'long' => DataTypes :: INTEGER ,
'object' => DataTypes :: MODEL ,
'array' => DataTypes :: COLLECTION ,
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
'DateTime' => DataTypes :: DATETIME ,
);
2013-07-02 21:57:09 -07:00
/**
* Requires a validation MetadataFactory .
*
2015-11-30 19:19:17 +01:00
* @ param MetadataFactoryInterface | LegacyMetadataFactoryInterface $factory
2013-07-02 21:57:09 -07:00
*/
2015-11-30 19:19:17 +01:00
public function __construct ( $factory )
2013-06-10 17:18:17 -07:00
{
2015-11-30 19:19:17 +01:00
if ( ! ( $factory instanceof MetadataFactoryInterface ) && ! ( $factory instanceof LegacyMetadataFactoryInterface )) {
throw new \InvalidArgumentException ( 'Argument 1 of %s constructor must be either an instance of Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface or Symfony\Component\Validator\MetadataFactoryInterface.' );
}
2013-06-10 17:18:17 -07:00
$this -> factory = $factory ;
}
/**
* { @ inheritdoc }
*/
public function supports ( array $input )
{
$className = $input [ 'class' ];
return $this -> factory -> hasMetadataFor ( $className );
}
/**
* { @ inheritdoc }
*/
public function parse ( array $input )
{
$className = $input [ 'class' ];
2013-12-11 01:59:59 +01:00
2015-07-01 14:01:44 +03:00
$parsed = $this -> doParse ( $className , array ());
2019-04-24 16:42:22 +03:00
if ( ! isset ( $input [ 'name' ]) || empty ( $input [ 'name' ])) {
return $parsed ;
}
2015-10-22 14:42:59 +02:00
2019-04-24 16:42:22 +03:00
if ( class_exists ( $className )) {
$parts = explode ( '\\' , $className );
$dataType = sprintf ( 'object (%s)' , end ( $parts ));
} else {
$dataType = sprintf ( 'object (%s)' , $className );
2015-07-01 14:01:44 +03:00
}
2019-04-24 16:42:22 +03:00
return array (
$input [ 'name' ] => array (
'dataType' => $dataType ,
'actualType' => DataTypes :: MODEL ,
'class' => $className ,
'subType' => $dataType ,
'required' => null ,
'readonly' => null ,
'children' => $parsed ,
'default' => null ,
),
);
2013-11-07 14:11:09 +01:00
}
2013-06-10 17:18:17 -07:00
2013-11-07 14:11:09 +01:00
/**
* Recursively parse constraints .
*
* @ param $className
* @ param array $visited
* @ return array
*/
2013-12-11 01:59:59 +01:00
protected function doParse ( $className , array $visited )
2013-11-07 14:11:09 +01:00
{
$params = array ();
2013-06-10 17:18:17 -07:00
$classdata = $this -> factory -> getMetadataFor ( $className );
2013-06-30 18:46:00 -07:00
$properties = $classdata -> getConstrainedProperties ();
2013-06-10 17:18:17 -07:00
2014-06-26 12:27:47 -07:00
$refl = $classdata -> getReflectionClass ();
$defaults = $refl -> getDefaultProperties ();
2013-11-14 10:28:42 +01:00
foreach ( $properties as $property ) {
2013-06-30 18:46:00 -07:00
$vparams = array ();
2014-06-26 12:27:47 -07:00
$vparams [ 'default' ] = isset ( $defaults [ $property ]) ? $defaults [ $property ] : null ;
2013-06-30 18:46:00 -07:00
$pds = $classdata -> getPropertyMetadata ( $property );
2013-11-14 10:28:42 +01:00
foreach ( $pds as $propdata ) {
2013-06-30 18:46:00 -07:00
$constraints = $propdata -> getConstraints ();
2013-06-10 17:18:17 -07:00
2013-11-14 10:28:42 +01:00
foreach ( $constraints as $constraint ) {
2013-11-07 14:11:09 +01:00
$vparams = $this -> parseConstraint ( $constraint , $vparams , $className , $visited );
2013-06-30 18:46:00 -07:00
}
2013-06-10 17:18:17 -07:00
}
2013-11-14 10:28:42 +01:00
if ( isset ( $vparams [ 'format' ])) {
2013-06-10 17:18:17 -07:00
$vparams [ 'format' ] = join ( ', ' , $vparams [ 'format' ]);
}
2013-06-30 18:46:00 -07:00
2014-08-04 09:42:48 -07:00
foreach ( array ( 'dataType' , 'readonly' , 'required' , 'subType' ) as $reqprop ) {
2013-11-14 10:28:42 +01:00
if ( ! isset ( $vparams [ $reqprop ])) {
2013-06-30 18:46:00 -07:00
$vparams [ $reqprop ] = null ;
}
}
2013-11-07 14:11:09 +01:00
// check for nested classes with All constraint
if ( isset ( $vparams [ 'class' ]) && ! in_array ( $vparams [ 'class' ], $visited ) && null !== $this -> factory -> getMetadataFor ( $vparams [ 'class' ])) {
$visited [] = $vparams [ 'class' ];
$vparams [ 'children' ] = $this -> doParse ( $vparams [ 'class' ], $visited );
}
2014-08-04 09:42:48 -07:00
$vparams [ 'actualType' ] = isset ( $vparams [ 'actualType' ]) ? $vparams [ 'actualType' ] : DataTypes :: STRING ;
2013-06-30 18:46:00 -07:00
$params [ $property ] = $vparams ;
}
return $params ;
}
2013-07-02 21:57:09 -07:00
/**
* { @ inheritDoc }
*/
public function postParse ( array $input , array $parameters )
2013-06-30 18:46:00 -07:00
{
2013-11-14 10:28:42 +01:00
foreach ( $parameters as $param => $data ) {
if ( isset ( $data [ 'class' ]) && isset ( $data [ 'children' ])) {
2013-06-30 18:46:00 -07:00
$input = array ( 'class' => $data [ 'class' ]);
2013-06-30 21:28:40 -07:00
$parameters [ $param ][ 'children' ] = array_merge (
$parameters [ $param ][ 'children' ], $this -> postParse ( $input , $parameters [ $param ][ 'children' ])
);
$parameters [ $param ][ 'children' ] = array_merge (
$parameters [ $param ][ 'children' ], $this -> parse ( $input , $parameters [ $param ][ 'children' ])
);
2013-06-30 18:46:00 -07:00
}
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
}
2013-07-02 21:57:09 -07:00
/**
* Create a valid documentation parameter based on an individual validation Constraint .
* Currently supports :
* - NotBlank / NotNull
* - Type
* - Email
* - Url
* - Ip
* - Length ( min and max )
* - Choice ( single and multiple , min and max )
* - Regex ( match and non - match )
*
2013-11-14 10:28:42 +01:00
* @ param Constraint $constraint The constraint metadata object .
* @ param array $vparams The existing validation parameters .
* @ return mixed The parsed list of validation parameters .
2013-07-02 21:57:09 -07:00
*/
2013-11-07 14:11:09 +01:00
protected function parseConstraint ( Constraint $constraint , $vparams , $className , & $visited = array ())
2013-06-10 17:18:17 -07:00
{
$class = substr ( get_class ( $constraint ), strlen ( 'Symfony\\Component\\Validator\\Constraints\\' ));
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: STRING ;
2014-06-26 12:27:47 -07:00
$vparams [ 'subType' ] = null ;
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
2013-11-14 10:28:42 +01:00
switch ( $class ) {
2013-06-10 17:18:17 -07:00
case 'NotBlank' :
2013-11-14 11:12:58 +01:00
$vparams [ 'format' ][] = '{not blank}' ;
2013-06-10 17:18:17 -07:00
case 'NotNull' :
$vparams [ 'required' ] = true ;
break ;
case 'Type' :
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
if ( isset ( $this -> typeMap [ $constraint -> type ])) {
$vparams [ 'actualType' ] = $this -> typeMap [ $constraint -> type ];
}
2013-06-10 17:18:17 -07:00
$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 ;
2013-08-30 11:59:57 +01:00
case 'Date' :
$vparams [ 'format' ][] = '{Date YYYY-MM-DD}' ;
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: DATE ;
2013-08-30 11:59:57 +01:00
break ;
case 'DateTime' :
$vparams [ 'format' ][] = '{DateTime YYYY-MM-DD HH:MM:SS}' ;
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: DATETIME ;
2013-08-30 11:59:57 +01:00
break ;
case 'Time' :
$vparams [ 'format' ][] = '{Time HH:MM:SS}' ;
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: TIME ;
2013-08-30 11:59:57 +01:00
break ;
2019-04-24 16:42:22 +03:00
case 'Range' :
$messages = array ();
if ( isset ( $constraint -> min )) {
$messages [] = " >= { $constraint -> min } " ;
}
if ( isset ( $constraint -> max )) {
$messages [] = " <= { $constraint -> max } " ;
}
$vparams [ 'format' ][] = '{range: {' . join ( ', ' , $messages ) . '}}' ;
break ;
2013-06-10 17:18:17 -07:00
case 'Length' :
$messages = array ();
2013-11-14 10:28:42 +01:00
if ( isset ( $constraint -> min )) {
2013-06-10 17:18:17 -07:00
$messages [] = " min: { $constraint -> min } " ;
}
2013-11-14 10:28:42 +01:00
if ( isset ( $constraint -> max )) {
2013-06-10 17:18:17 -07:00
$messages [] = " max: { $constraint -> max } " ;
}
2019-04-24 16:42:22 +03:00
$vparams [ 'format' ][] = '{length: {' . join ( ', ' , $messages ) . '}}' ;
2013-06-10 17:18:17 -07:00
break ;
case 'Choice' :
2013-11-06 15:25:10 +01:00
$choices = $this -> getChoices ( $constraint , $className );
$format = '[' . join ( '|' , $choices ) . ']' ;
2013-11-14 10:28:42 +01:00
if ( $constraint -> multiple ) {
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: COLLECTION ;
$vparams [ 'subType' ] = DataTypes :: ENUM ;
2013-06-10 17:18:17 -07:00
$messages = array ();
2013-11-14 10:28:42 +01:00
if ( isset ( $constraint -> min )) {
2013-06-10 17:18:17 -07:00
$messages [] = " min: { $constraint -> min } " ;
}
2013-11-14 10:28:42 +01:00
if ( isset ( $constraint -> max )) {
2013-06-10 17:18:17 -07:00
$messages [] = " max: { $constraint -> max } " ;
}
$vparams [ 'format' ][] = '{' . join ( '' , $messages ) . 'choice of ' . $format . '}' ;
} else {
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: ENUM ;
2013-06-10 17:18:17 -07:00
$vparams [ 'format' ][] = $format ;
}
break ;
case 'Regex' :
2013-11-14 10:28:42 +01:00
if ( $constraint -> match ) {
2013-07-02 21:57:09 -07:00
$vparams [ 'format' ][] = '{match: ' . $constraint -> pattern . '}' ;
} else {
$vparams [ 'format' ][] = '{not match: ' . $constraint -> pattern . '}' ;
}
2013-06-10 17:18:17 -07:00
break ;
2013-11-07 14:11:09 +01:00
case 'All' :
foreach ( $constraint -> constraints as $childConstraint ) {
if ( $childConstraint instanceof Type ) {
$nestedType = $childConstraint -> type ;
$exp = explode ( " \\ " , $nestedType );
if ( ! class_exists ( $nestedType )) {
$nestedType = substr ( $className , 0 , strrpos ( $className , '\\' ) + 1 ) . $nestedType ;
if ( ! class_exists ( $nestedType )) {
continue ;
}
}
2014-06-17 17:05:00 -07:00
$vparams [ 'dataType' ] = sprintf ( " array of objects (%s) " , end ( $exp ));
Unified data types [actualType and subType]
This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410.
This PR aims to provide a uniform way of declaring data-types of parameters for
parsers and handlers to follow. In turn, this would allow formatters to
determine data-types in a cleaner and less volatile manner. (See use-case that
can be improved with this PR:
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103)
This is possible by the addition two properties to each property item in
`response`, and `parameters` fields in each API endpoint produced by the
`ApiDocExtractor`:
* `actualType` Contains a value from one of the `DataTypes` class constants.
* `subType` Can contain either `null`, or any other `DataTypes` class constant.
This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein
`subType` would specify the type of the collection items. It is also relevant
when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an
identifier of the model (the FQCN or anything the parser would wish to specify)
Examples:
```php
array(
'id' => array(
'dataType' => 'integer',
'actualType' => DataTypes::INTEGER,
'subType' => null,
),
'profile' => array(
'dataType' => 'object (Profile)',
'actualType' => DataTypes::MODEL,
'subType' => 'Foo\Entity\Profile',
'children' => array(
'name' => array(
'dataType' => 'string',
'actualType' => DataTypes::STRING,
'subType' => null,
),
'birthDate' => array(
'dataType' => 'date',
'actualType' => DataTypes::DATE,
'subType' => null,
),
)
),
'languages' => array(
'dataType' => 'array of strings',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::STRING,
),
'roles' => array(
'dataType' => 'array of choices',
'actualType' => DataTypes::COLLECTION,
'subType' => DataTypes::ENUM,
),
'groups' => array(
'dataType' => 'array of objects (Group)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Group',
),
'profileRevisions' => array(
'dataType' => 'array of objects (Profile)',
'actualType' => DataTypes::COLLECTION,
'subType' => 'Foo\Entity\Profile',
),
'address' => array(
'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)',
'actualType' => DataTypes::MODEL,
'subType' => 'a_type_a_custom_JMS_serializer_handler_handles',
),
);
```
When a formatter omits the `dataType` property or leaves it blank, it is
inferred within `ApiDocExtractor` before everything is passed to formatters.
2014-06-17 17:05:00 -07:00
$vparams [ 'actualType' ] = DataTypes :: COLLECTION ;
2014-06-17 17:05:00 -07:00
$vparams [ 'subType' ] = $nestedType ;
$vparams [ 'class' ] = $nestedType ;
2013-11-07 14:11:09 +01:00
if ( ! in_array ( $nestedType , $visited )) {
$visited [] = $nestedType ;
$vparams [ 'children' ] = $this -> doParse ( $nestedType , $visited );
}
}
}
break ;
2013-06-10 17:18:17 -07:00
}
return $vparams ;
}
2013-11-06 15:25:10 +01:00
/**
* Return Choice constraint choices .
*
2014-06-25 08:46:01 +02:00
* @ param Constraint $constraint
2013-11-06 15:25:10 +01:00
* @ param $className
* @ return array
* @ throws \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
2013-11-14 10:28:42 +01:00
protected function getChoices ( Constraint $constraint , $className )
2013-11-06 15:25:10 +01:00
{
if ( $constraint -> callback ) {
if ( is_callable ( array ( $className , $constraint -> callback ))) {
$choices = call_user_func ( array ( $className , $constraint -> callback ));
} elseif ( is_callable ( $constraint -> callback )) {
$choices = call_user_func ( $constraint -> callback );
} else {
throw new ConstraintDefinitionException ( 'The Choice constraint expects a valid callback' );
}
} else {
$choices = $constraint -> choices ;
}
return $choices ;
}
}