From d9f1611f729782fe12a849748813eac27e45eef9 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 12 Aug 2020 11:06:17 +0200 Subject: [PATCH 1/5] Release version 3.7 --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48962a7..fb89ce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,14 @@ CHANGELOG ========= -3.7.0 (unreleased) ------------------- +3.7.0 +----- * Added `@SerializedName` annotation support and name converters when using Symfony >= 4.2. * Removed pattern added from the Expression Violation message. * Added FOSRestBundle 3.x support * Added `@SWG` annotations support at methods level in models + 3.3.0 ----- From 429d809f41630da13d30cee2c4aca5ebb5dedf2d Mon Sep 17 00:00:00 2001 From: Paul Dugas Date: Wed, 9 Sep 2020 02:27:47 -0400 Subject: [PATCH 2/5] Ignore ReflectionException for "magic" JMS\Accessor methods (#1715) * Update JMSModelDescriber.php Ignore ReflectionException thrown when getter or setter from JMS\ Accessor are "magic" methods. * Add tests to avoid future regressions * CS Co-authored-by: Guilhem Niot --- ModelDescriber/JMSModelDescriber.php | 13 ++++++++----- Tests/Functional/Entity/VirtualProperty.php | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index 0711be2..18e5382 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -93,11 +93,14 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn $reflections[] = new \ReflectionProperty($item->class, $item->name); } - if (null !== $item->getter) { - $reflections[] = new \ReflectionMethod($item->class, $item->getter); - } - if (null !== $item->setter) { - $reflections[] = new \ReflectionMethod($item->class, $item->setter); + try { + if (null !== $item->getter) { + $reflections[] = new \ReflectionMethod($item->class, $item->getter); + } + if (null !== $item->setter) { + $reflections[] = new \ReflectionMethod($item->class, $item->setter); + } + } catch (\ReflectionExceptions $ignored) { } $groups = $this->computeGroups($context, $item->type); diff --git a/Tests/Functional/Entity/VirtualProperty.php b/Tests/Functional/Entity/VirtualProperty.php index 3db68a1..e996256 100644 --- a/Tests/Functional/Entity/VirtualProperty.php +++ b/Tests/Functional/Entity/VirtualProperty.php @@ -37,9 +37,26 @@ class VirtualProperty */ private $user; + /** + * @Serializer\Accessor(getter="getFoo", setter="setFoo") + * @Serializer\Type("string") + * + * Ensures https://github.com/nelmio/NelmioApiDocBundle/issues/1708 is fixed. + */ + private $virtualprop; + public function __construct() { $this->user = new User(); $this->user->setEmail('dummy@test.com'); } + + public function __call(string $name, array $arguments) + { + if ('getFoo' === $name || 'setFoo' === $name) { + return 'Success'; + } + + throw new \LogicException(sprintf('%s::__call does not implement this function.', __CLASS__)); + } } From c1903db1097576cb00d90fd054a8da4cb1a86009 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 9 Sep 2020 08:35:01 +0200 Subject: [PATCH 3/5] Fix the JMSModelDescriber --- ModelDescriber/JMSModelDescriber.php | 11 +++++++---- Tests/Functional/Entity/VirtualProperty.php | 1 + Tests/Functional/JMSFunctionalTest.php | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index 18e5382..b20ca94 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -93,14 +93,17 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn $reflections[] = new \ReflectionProperty($item->class, $item->name); } - try { - if (null !== $item->getter) { + if (null !== $item->getter) { + try { $reflections[] = new \ReflectionMethod($item->class, $item->getter); + } catch (\ReflectionException $ignored) { } - if (null !== $item->setter) { + } + if (null !== $item->setter) { + try { $reflections[] = new \ReflectionMethod($item->class, $item->setter); + } catch (\ReflectionException $ignored) { } - } catch (\ReflectionExceptions $ignored) { } $groups = $this->computeGroups($context, $item->type); diff --git a/Tests/Functional/Entity/VirtualProperty.php b/Tests/Functional/Entity/VirtualProperty.php index e996256..52ab283 100644 --- a/Tests/Functional/Entity/VirtualProperty.php +++ b/Tests/Functional/Entity/VirtualProperty.php @@ -40,6 +40,7 @@ class VirtualProperty /** * @Serializer\Accessor(getter="getFoo", setter="setFoo") * @Serializer\Type("string") + * @Serializer\Expose * * Ensures https://github.com/nelmio/NelmioApiDocBundle/issues/1708 is fixed. */ diff --git a/Tests/Functional/JMSFunctionalTest.php b/Tests/Functional/JMSFunctionalTest.php index a9d581c..990f181 100644 --- a/Tests/Functional/JMSFunctionalTest.php +++ b/Tests/Functional/JMSFunctionalTest.php @@ -280,6 +280,9 @@ class JMSFunctionalTest extends WebTestCase 'email' => [ 'type' => 'string', ], + 'virtualprop' => [ + 'type' => 'string', + ], ], ], $this->getModel('VirtualProperty')->toArray()); } From 0da1909cb9aa42174dccdb06edc2a9bb17fb92da Mon Sep 17 00:00:00 2001 From: Alex Kalineskou Date: Mon, 31 Aug 2020 23:22:42 +0300 Subject: [PATCH 4/5] Add support for allowNull for Assert\NotBlank --- .../SymfonyConstraintAnnotationReader.php | 5 ++++ .../SymfonyConstraintAnnotationReaderTest.php | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php b/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php index 6143672..311bebe 100644 --- a/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php +++ b/ModelDescriber/Annotations/SymfonyConstraintAnnotationReader.php @@ -48,6 +48,11 @@ class SymfonyConstraintAnnotationReader foreach ($annotations as $annotation) { if ($annotation instanceof Assert\NotBlank || $annotation instanceof Assert\NotNull) { + if ($annotation instanceof Assert\NotBlank && $annotation->allowNull) { + // The field is optional + continue; + } + // The field is required if (null === $this->schema) { continue; diff --git a/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php b/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php index 55ea9ec..e30cb49 100644 --- a/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php +++ b/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php @@ -47,6 +47,34 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase $this->assertEquals($schema->getRequired(), ['property1', 'property2']); } + public function testOptionalProperty() + { + $entity = new class() { + /** + * @Assert\NotBlank(allowNull = true) + * @Assert\Length(min = 1) + */ + private $property1; + /** + * @Assert\NotBlank() + */ + private $property2; + }; + + $schema = new OA\Schema([]); + $schema->merge([new OA\Property(['property' => 'property1'])]); + $schema->merge([new OA\Property(['property' => 'property2'])]); + + $symfonyConstraintAnnotationReader = new SymfonyConstraintAnnotationReader(new AnnotationReader()); + $symfonyConstraintAnnotationReader->setSchema($schema); + + $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]); + $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property2'), $schema->properties[1]); + + // expect required to be numeric array with sequential keys (not [0 => ..., 2 => ...]) + $this->assertEquals($schema->required, ['property2']); + } + public function testAssertChoiceResultsInNumericArray() { define('TEST_ASSERT_CHOICE_STATUSES', [ From ab8c44f520a656ab6e6e32957fcc5b4cf0895d83 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 9 Sep 2020 08:52:15 +0200 Subject: [PATCH 5/5] Adapt https://github.com/nelmio/NelmioApiDocBundle/pull/1711 to 3.x --- .../SymfonyConstraintAnnotationReaderTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php b/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php index e30cb49..c781db1 100644 --- a/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php +++ b/Tests/ModelDescriber/Annotations/SymfonyConstraintAnnotationReaderTest.php @@ -61,18 +61,18 @@ class SymfonyConstraintAnnotationReaderTest extends TestCase private $property2; }; - $schema = new OA\Schema([]); - $schema->merge([new OA\Property(['property' => 'property1'])]); - $schema->merge([new OA\Property(['property' => 'property2'])]); + $schema = new Schema(); + $schema->getProperties()->set('property1', new Schema()); + $schema->getProperties()->set('property2', new Schema()); $symfonyConstraintAnnotationReader = new SymfonyConstraintAnnotationReader(new AnnotationReader()); $symfonyConstraintAnnotationReader->setSchema($schema); - $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->properties[0]); - $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property2'), $schema->properties[1]); + $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property1'), $schema->getProperties()->get('property1')); + $symfonyConstraintAnnotationReader->updateProperty(new \ReflectionProperty($entity, 'property2'), $schema->getProperties()->get('property2')); // expect required to be numeric array with sequential keys (not [0 => ..., 2 => ...]) - $this->assertEquals($schema->required, ['property2']); + $this->assertEquals($schema->getRequired(), ['property2']); } public function testAssertChoiceResultsInNumericArray()