Skip to content

Commit

Permalink
feat(serializer): check in child classes attribute's groups for seria…
Browse files Browse the repository at this point in the history
…lization
  • Loading branch information
antoine-nedelec committed May 23, 2024
1 parent 002d8e5 commit 01d4c0f
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use ApiPlatform\Metadata\Exception\ResourceClassNotFoundException;
use ApiPlatform\Metadata\ResourceClassResolverInterface;
use ApiPlatform\Metadata\Util\ResourceClassInfoTrait;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface as SerializerClassMetadataFactoryInterface;

Expand All @@ -30,7 +31,7 @@ final class SerializerPropertyMetadataFactory implements PropertyMetadataFactory
{
use ResourceClassInfoTrait;

public function __construct(private readonly SerializerClassMetadataFactoryInterface $serializerClassMetadataFactory, private readonly PropertyMetadataFactoryInterface $decorated, ?ResourceClassResolverInterface $resourceClassResolver = null)
public function __construct(private readonly SerializerClassMetadataFactoryInterface $serializerClassMetadataFactory, private readonly PropertyMetadataFactoryInterface $decorated, ?ResourceClassResolverInterface $resourceClassResolver = null, private readonly ?bool $normalizeChildClassAttributeGroups = null)
{
$this->resourceClassResolver = $resourceClassResolver;
}
Expand Down Expand Up @@ -203,6 +204,18 @@ private function getClassSerializerGroups(string $class): array
$groups[] = $serializerAttributeMetadata->getGroups();
}

if (true === $this->normalizeChildClassAttributeGroups) {
foreach ($serializerClassMetadata->getReflectionClass()->getAttributes() as $reflectionAttribute) {
if (DiscriminatorMap::class !== $reflectionAttribute->getName()) {
continue;
}

foreach ($reflectionAttribute->getArguments()[0] as $class) {
$groups = [...$groups, $this->getClassSerializerGroups($class)];
}
}
}

return array_unique(array_merge(...$groups));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ private function registerCommonConfiguration(ContainerBuilder $container, array
$container->setParameter('api_platform.description', $config['description']);
$container->setParameter('api_platform.version', $config['version']);
$container->setParameter('api_platform.show_webby', $config['show_webby']);
$container->setParameter('api_platform.normalize_child_class_attribute_groups', $config['normalize_child_class_attribute_groups']);
$container->setParameter('api_platform.url_generation_strategy', $config['defaults']['url_generation_strategy'] ?? UrlGeneratorInterface::ABS_PATH);
$container->setParameter('api_platform.exception_to_status', $config['exception_to_status']);
$container->setParameter('api_platform.formats', $formats);
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Bundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->booleanNode('show_webby')->defaultTrue()->info('If true, show Webby on the documentation page')->end()
->booleanNode('event_listeners_backward_compatibility_layer')->defaultNull()->info('If true API Platform uses Symfony event listeners instead of providers and processors.')->end()
->booleanNode('use_symfony_listeners')->defaultNull()->info(sprintf('Uses Symfony event listeners instead of the %s.', MainController::class))->end()
->booleanNode('normalize_child_class_attribute_groups')->defaultNull()->info('Search in child classes groups for normalization')->end()
->scalarNode('name_converter')->defaultNull()->info('Specify a name converter to use.')->end()
->scalarNode('asset_package')->defaultNull()->info('Specify an asset package name to use.')->end()
->scalarNode('path_segment_name_generator')->defaultValue('api_platform.metadata.path_segment_name_generator.underscore')->info('Specify a path name generator to use.')->end()
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Bundle/Resources/config/metadata/property.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<argument type="service" id="serializer.mapping.class_metadata_factory" />
<argument type="service" id="api_platform.metadata.property.metadata_factory.serializer.inner" />
<argument type="service" id="api_platform.resource_class_resolver" />
<argument>%api_platform.normalize_child_class_attribute_groups%</argument>
</service>

<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">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
'use_symfony_listeners' => false,
'handle_symfony_errors' => false,
'enable_link_security' => false,
'normalize_child_class_attribute_groups' => null,
], $config);
}

Expand Down

0 comments on commit 01d4c0f

Please sign in to comment.