mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 23:59:26 +03:00
Merge pull request #1797 from nelmio/BACKPORT
Added support for constraint attributes
This commit is contained in:
commit
5e6140cd65
@ -13,6 +13,7 @@ namespace Nelmio\ApiDocBundle\ModelDescriber\Annotations;
|
||||
|
||||
use Doctrine\Common\Annotations\Reader;
|
||||
use EXSyst\Component\Swagger\Schema;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
@ -37,16 +38,12 @@ class SymfonyConstraintAnnotationReader
|
||||
|
||||
/**
|
||||
* Update the given property and schema with defined Symfony constraints.
|
||||
*
|
||||
* @param \ReflectionProperty|\ReflectionMethod $reflection
|
||||
*/
|
||||
public function updateProperty($reflection, Schema $property)
|
||||
{
|
||||
if ($reflection instanceof \ReflectionProperty) {
|
||||
$annotations = $this->annotationsReader->getPropertyAnnotations($reflection);
|
||||
} else {
|
||||
$annotations = $this->annotationsReader->getMethodAnnotations($reflection);
|
||||
}
|
||||
|
||||
foreach ($annotations as $annotation) {
|
||||
foreach ($this->getAnnotations($reflection) as $annotation) {
|
||||
if ($annotation instanceof Assert\NotBlank || $annotation instanceof Assert\NotNull) {
|
||||
// To support symfony/validator < 4.3
|
||||
if ($annotation instanceof Assert\NotBlank && \property_exists($annotation, 'allowNull') && $annotation->allowNull) {
|
||||
@ -128,4 +125,22 @@ class SymfonyConstraintAnnotationReader
|
||||
$property->setPattern($newPattern);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionProperty|\ReflectionMethod $reflection
|
||||
*/
|
||||
private function getAnnotations($reflection): \Traversable
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
foreach ($reflection->getAttributes(Constraint::class, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
|
||||
yield $attribute->newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
if ($reflection instanceof \ReflectionProperty) {
|
||||
yield from $this->annotationsReader->getPropertyAnnotations($reflection);
|
||||
} elseif ($reflection instanceof \ReflectionMethod) {
|
||||
yield from $this->annotationsReader->getMethodAnnotations($reflection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,24 +47,16 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
||||
$this->assertEquals($schema->getRequired(), ['property1', 'property2']);
|
||||
}
|
||||
|
||||
public function testOptionalProperty()
|
||||
/**
|
||||
* @param object $entity
|
||||
* @dataProvider provideOptionalProperty
|
||||
*/
|
||||
public function testOptionalProperty($entity)
|
||||
{
|
||||
if (!\property_exists(Assert\NotBlank::class, 'allowNull')) {
|
||||
$this->markTestSkipped('NotBlank::allowNull was added in symfony/validator 4.3.');
|
||||
}
|
||||
|
||||
$entity = new class() {
|
||||
/**
|
||||
* @Assert\NotBlank(allowNull = true)
|
||||
* @Assert\Length(min = 1)
|
||||
*/
|
||||
private $property1;
|
||||
/**
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
private $property2;
|
||||
};
|
||||
|
||||
$schema = new Schema();
|
||||
$schema->getProperties()->set('property1', new Schema());
|
||||
$schema->getProperties()->set('property2', new Schema());
|
||||
@ -79,21 +71,37 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
||||
$this->assertEquals($schema->getRequired(), ['property2']);
|
||||
}
|
||||
|
||||
public function testAssertChoiceResultsInNumericArray()
|
||||
public function provideOptionalProperty(): iterable
|
||||
{
|
||||
define('TEST_ASSERT_CHOICE_STATUSES', [
|
||||
1 => 'active',
|
||||
2 => 'blocked',
|
||||
]);
|
||||
|
||||
$entity = new class() {
|
||||
yield 'Annotations' => [new class() {
|
||||
/**
|
||||
* @Assert\NotBlank(allowNull = true)
|
||||
* @Assert\Length(min = 1)
|
||||
* @Assert\Choice(choices=TEST_ASSERT_CHOICE_STATUSES)
|
||||
*/
|
||||
private $property1;
|
||||
};
|
||||
/**
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
private $property2;
|
||||
}];
|
||||
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
yield 'Attributes' => [new class() {
|
||||
#[Assert\NotBlank(allowNull: true)]
|
||||
#[Assert\Length(min: 1)]
|
||||
private $property1;
|
||||
#[Assert\NotBlank]
|
||||
private $property2;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $entity
|
||||
* @dataProvider provideAssertChoiceResultsInNumericArray
|
||||
*/
|
||||
public function testAssertChoiceResultsInNumericArray($entity)
|
||||
{
|
||||
$schema = new Schema();
|
||||
$schema->getProperties()->set('property1', new Schema());
|
||||
|
||||
@ -105,4 +113,28 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase
|
||||
// expect enum to be numeric array with sequential keys (not [1 => "active", 2 => "active"])
|
||||
$this->assertEquals($schema->getProperties()->get('property1')->getEnum(), ['active', 'blocked']);
|
||||
}
|
||||
|
||||
public function provideAssertChoiceResultsInNumericArray(): iterable
|
||||
{
|
||||
define('TEST_ASSERT_CHOICE_STATUSES', [
|
||||
1 => 'active',
|
||||
2 => 'blocked',
|
||||
]);
|
||||
|
||||
yield 'Annotations' => [new class() {
|
||||
/**
|
||||
* @Assert\Length(min = 1)
|
||||
* @Assert\Choice(choices=TEST_ASSERT_CHOICE_STATUSES)
|
||||
*/
|
||||
private $property1;
|
||||
}];
|
||||
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
yield 'Attributes' => [new class() {
|
||||
#[Assert\Length(min: 1)]
|
||||
#[Assert\Choice(choices: TEST_ASSERT_CHOICE_STATUSES)]
|
||||
private $property1;
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user