From ef2c30cab1d8e501ad4c42c4cc105e451648a293 Mon Sep 17 00:00:00 2001 From: Brajk19 Date: Fri, 3 Mar 2023 21:44:53 +0100 Subject: [PATCH] [Serializer] Groups annotation/attribute on class --- .../Serializer/Annotation/Groups.php | 4 +- src/Symfony/Component/Serializer/CHANGELOG.md | 1 + .../Mapping/Loader/AnnotationLoader.php | 10 +++ .../Fixtures/Annotations/GroupClassDummy.php | 62 +++++++++++++++++++ .../Fixtures/Attributes/GroupClassDummy.php | 56 +++++++++++++++++ .../Loader/AnnotationLoaderTestCase.php | 18 ++++++ .../Serializer/Tests/SerializerTest.php | 22 +++++++ 7 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupClassDummy.php create mode 100644 src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupClassDummy.php diff --git a/src/Symfony/Component/Serializer/Annotation/Groups.php b/src/Symfony/Component/Serializer/Annotation/Groups.php index 5b16f567c3547..f1ea6f76b9bc3 100644 --- a/src/Symfony/Component/Serializer/Annotation/Groups.php +++ b/src/Symfony/Component/Serializer/Annotation/Groups.php @@ -18,11 +18,11 @@ * * @Annotation * @NamedArgumentConstructor - * @Target({"PROPERTY", "METHOD"}) + * @Target({"PROPERTY", "METHOD", "CLASS"}) * * @author Kévin Dunglas */ -#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)] +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY | \Attribute::TARGET_CLASS)] class Groups { /** diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 4ab3defddc1bb..0fb810b06bcb9 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * Deprecate Doctrine annotations support in favor of native attributes * Deprecate passing an annotation reader to the constructor of `AnnotationLoader` + * Allow the `Groups` attribute/annotation on classes 6.3 --- diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php index 94d0f45dcb1f7..fdeda08b2be39 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php @@ -56,6 +56,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool $reflectionClass = $classMetadata->getReflectionClass(); $className = $reflectionClass->name; $loaded = false; + $classGroups = []; $attributesMetadata = $classMetadata->getAttributesMetadata(); @@ -65,6 +66,11 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool $annotation->getTypeProperty(), $annotation->getMapping() )); + continue; + } + + if ($annotation instanceof Groups) { + $classGroups = $annotation->getGroups(); } } @@ -75,6 +81,10 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool } if ($property->getDeclaringClass()->name === $className) { + foreach ($classGroups as $group) { + $attributesMetadata[$property->name]->addGroup($group); + } + foreach ($this->loadAnnotations($property) as $annotation) { if ($annotation instanceof Groups) { foreach ($annotation->getGroups() as $group) { diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupClassDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupClassDummy.php new file mode 100644 index 0000000000000..e977326132259 --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Annotations/GroupClassDummy.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures\Annotations; + +use Symfony\Component\Serializer\Annotation\Groups; + +/** + * @Groups({"a"}) + */ +class GroupClassDummy +{ + /** + * @Groups({"b"}) + */ + private $foo; + + /** + * @Groups({"c", "d"}) + */ + private $bar; + + private $baz; + + public function getFoo() + { + return $this->foo; + } + + public function setFoo($foo): void + { + $this->foo = $foo; + } + + public function getBar() + { + return $this->bar; + } + + public function setBar($bar): void + { + $this->bar = $bar; + } + + public function getBaz() + { + return $this->baz; + } + + public function setBaz($baz): void + { + $this->baz = $baz; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupClassDummy.php b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupClassDummy.php new file mode 100644 index 0000000000000..68289a9a854be --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/Attributes/GroupClassDummy.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures\Attributes; + +use Symfony\Component\Serializer\Annotation\Groups; + +#[Groups('a')] +class GroupClassDummy +{ + #[Groups('b')] + private $foo; + + #[Groups(['c', 'd'])] + private $bar; + + private $baz; + + public function getFoo() + { + return $this->foo; + } + + public function setFoo($foo): void + { + $this->foo = $foo; + } + + public function getBar() + { + return $this->bar; + } + + public function setBar($bar): void + { + $this->bar = $bar; + } + + public function getBaz() + { + return $this->baz; + } + + public function setBaz($baz): void + { + $this->baz = $baz; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php index 40d5e3cfee5de..69b486177712c 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/Loader/AnnotationLoaderTestCase.php @@ -192,6 +192,24 @@ public function testIgnoreGetterWithRequiredParameterIfIgnoreAnnotationIsNotUsed self::assertArrayHasKey('extraValue2', $attributes); } + public function testLoadGroupsOnClass() + { + $classMetadata = new ClassMetadata($this->getNamespace().'\GroupClassDummy'); + $this->loader->loadClassMetadata($classMetadata); + + $attributesMetadata = $classMetadata->getAttributesMetadata(); + + self::assertCount(3, $classMetadata->getAttributesMetadata()); + + self::assertArrayHasKey('foo', $attributesMetadata); + self::assertArrayHasKey('bar', $attributesMetadata); + self::assertArrayHasKey('baz', $attributesMetadata); + + self::assertSame(['a', 'b'], $attributesMetadata['foo']->getGroups()); + self::assertSame(['a', 'c', 'd'], $attributesMetadata['bar']->getGroups()); + self::assertSame(['a'], $attributesMetadata['baz']->getGroups()); + } + abstract protected function createLoader(): AnnotationLoader; abstract protected function getNamespace(): string; diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index 8c5c89a674d24..a50662a24a512 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -1278,6 +1278,28 @@ public function testNoCollectDenormalizationErrorsWithWrongEnumOnConstructor() } } + public function testGroupsOnClassSerialization() + { + $obj = new Fixtures\Attributes\GroupClassDummy(); + $obj->setFoo('foo'); + $obj->setBar('bar'); + $obj->setBaz('baz'); + + $serializer = new Serializer( + [ + new ObjectNormalizer(), + ], + [ + 'json' => new JsonEncoder(), + ] + ); + + $this->assertSame( + '{"foo":"foo","bar":"bar","baz":"baz"}', + $serializer->serialize($obj, 'json', ['groups' => ['a']]) + ); + } + public static function provideCollectDenormalizationErrors(): array { return [ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy