Skip to content

Commit

Permalink
[Serializer] Groups annotation/attribute on class
Browse files Browse the repository at this point in the history
  • Loading branch information
Brajk19 authored and fabpot committed Aug 1, 2023
1 parent fa38296 commit ef2c30c
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/Symfony/Component/Serializer/Annotation/Groups.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
*
* @Annotation
* @NamedArgumentConstructor
* @Target({"PROPERTY", "METHOD"})
* @Target({"PROPERTY", "METHOD", "CLASS"})
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY | \Attribute::TARGET_CLASS)]
class Groups
{
/**
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Serializer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
$reflectionClass = $classMetadata->getReflectionClass();
$className = $reflectionClass->name;
$loaded = false;
$classGroups = [];

$attributesMetadata = $classMetadata->getAttributesMetadata();

Expand All @@ -65,6 +66,11 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
$annotation->getTypeProperty(),
$annotation->getMapping()
));
continue;
}

if ($annotation instanceof Groups) {
$classGroups = $annotation->getGroups();
}
}

Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions src/Symfony/Component/Serializer/Tests/SerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 [
Expand Down

0 comments on commit ef2c30c

Please sign in to comment.