Skip to content

Commit 01d4c0f

Browse files
feat(serializer): check in child classes attribute's groups for serialization
1 parent 002d8e5 commit 01d4c0f

File tree

5 files changed

+18
-1
lines changed

5 files changed

+18
-1
lines changed

src/Metadata/Property/Factory/SerializerPropertyMetadataFactory.php

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\Metadata\Exception\ResourceClassNotFoundException;
1818
use ApiPlatform\Metadata\ResourceClassResolverInterface;
1919
use ApiPlatform\Metadata\Util\ResourceClassInfoTrait;
20+
use Doctrine\ORM\Mapping\DiscriminatorMap;
2021
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
2122
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface as SerializerClassMetadataFactoryInterface;
2223

@@ -30,7 +31,7 @@ final class SerializerPropertyMetadataFactory implements PropertyMetadataFactory
3031
{
3132
use ResourceClassInfoTrait;
3233

33-
public function __construct(private readonly SerializerClassMetadataFactoryInterface $serializerClassMetadataFactory, private readonly PropertyMetadataFactoryInterface $decorated, ?ResourceClassResolverInterface $resourceClassResolver = null)
34+
public function __construct(private readonly SerializerClassMetadataFactoryInterface $serializerClassMetadataFactory, private readonly PropertyMetadataFactoryInterface $decorated, ?ResourceClassResolverInterface $resourceClassResolver = null, private readonly ?bool $normalizeChildClassAttributeGroups = null)
3435
{
3536
$this->resourceClassResolver = $resourceClassResolver;
3637
}
@@ -203,6 +204,18 @@ private function getClassSerializerGroups(string $class): array
203204
$groups[] = $serializerAttributeMetadata->getGroups();
204205
}
205206

207+
if (true === $this->normalizeChildClassAttributeGroups) {
208+
foreach ($serializerClassMetadata->getReflectionClass()->getAttributes() as $reflectionAttribute) {
209+
if (DiscriminatorMap::class !== $reflectionAttribute->getName()) {
210+
continue;
211+
}
212+
213+
foreach ($reflectionAttribute->getArguments()[0] as $class) {
214+
$groups = [...$groups, $this->getClassSerializerGroups($class)];
215+
}
216+
}
217+
}
218+
206219
return array_unique(array_merge(...$groups));
207220
}
208221
}

src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

+1
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ private function registerCommonConfiguration(ContainerBuilder $container, array
257257
$container->setParameter('api_platform.description', $config['description']);
258258
$container->setParameter('api_platform.version', $config['version']);
259259
$container->setParameter('api_platform.show_webby', $config['show_webby']);
260+
$container->setParameter('api_platform.normalize_child_class_attribute_groups', $config['normalize_child_class_attribute_groups']);
260261
$container->setParameter('api_platform.url_generation_strategy', $config['defaults']['url_generation_strategy'] ?? UrlGeneratorInterface::ABS_PATH);
261262
$container->setParameter('api_platform.exception_to_status', $config['exception_to_status']);
262263
$container->setParameter('api_platform.formats', $formats);

src/Symfony/Bundle/DependencyInjection/Configuration.php

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public function getConfigTreeBuilder(): TreeBuilder
8888
->booleanNode('show_webby')->defaultTrue()->info('If true, show Webby on the documentation page')->end()
8989
->booleanNode('event_listeners_backward_compatibility_layer')->defaultNull()->info('If true API Platform uses Symfony event listeners instead of providers and processors.')->end()
9090
->booleanNode('use_symfony_listeners')->defaultNull()->info(sprintf('Uses Symfony event listeners instead of the %s.', MainController::class))->end()
91+
->booleanNode('normalize_child_class_attribute_groups')->defaultNull()->info('Search in child classes groups for normalization')->end()
9192
->scalarNode('name_converter')->defaultNull()->info('Specify a name converter to use.')->end()
9293
->scalarNode('asset_package')->defaultNull()->info('Specify an asset package name to use.')->end()
9394
->scalarNode('path_segment_name_generator')->defaultValue('api_platform.metadata.path_segment_name_generator.underscore')->info('Specify a path name generator to use.')->end()

src/Symfony/Bundle/Resources/config/metadata/property.xml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<argument type="service" id="serializer.mapping.class_metadata_factory" />
2222
<argument type="service" id="api_platform.metadata.property.metadata_factory.serializer.inner" />
2323
<argument type="service" id="api_platform.resource_class_resolver" />
24+
<argument>%api_platform.normalize_child_class_attribute_groups%</argument>
2425
</service>
2526

2627
<service id="api_platform.metadata.property.metadata_factory.cached" class="ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory" decorates="api_platform.metadata.property.metadata_factory" decoration-priority="-10" public="false">

tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
232232
'use_symfony_listeners' => false,
233233
'handle_symfony_errors' => false,
234234
'enable_link_security' => false,
235+
'normalize_child_class_attribute_groups' => null,
235236
], $config);
236237
}
237238

0 commit comments

Comments
 (0)