8000 ObjectNormalizer is not provided with serializer default_context · Issue #57316 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
ObjectNormalizer is not provided with serializer default_context #57316
Closed
@slava-petrov

Description

@slava-petrov

Symfony version(s) affected

6.4.8

Description

When default_context is set in framework.yaml globally - Symfony\Component\Serializer\Normalizer\ObjectNormalizer is missing them in specific circumstances. I have declared this in framework.yaml

image

Symfony\Component\Serializer\DependencyInjection\SerializerPass.php does the binding

$definition->setBindings(['array $defaultContext' => new BoundArgument($defaultContext, false)] + $definition->getBindings());

But after bin/console c:c ObjectNormalizer has an empty array passed to $defaultContext

new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer($c, $d, $b, $e, new \Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata($c), NULL, [], $e)

That's what is passed after cache clearing in App_KernelDevDebugContainer.php.

If I manually enable autowiring in services.yaml like this:

image

binding works and defaultContext is passed there. But looks like generally the issue is that bindings conflict with arguments setting somewhere during building process. Because, for example, ProblemNormalizer has $defaultContext passed correctly and it is not autowired by default as well.

My expectation is to have defaultContext passed there by default if it is configured globally for ObjectNormalizer

How to reproduce

  1. Setup clean symfony 6.4.8. symfony new 64lts --version="6.4.8"
  2. Install via composer serializer and property-access. composer require symfony/serializer, composer require symfony/property-access
  3. Set dev environment and APP_DEBUG=true
  4. Add this to framework.yaml
     serializer:
        default_context:
            disable_type_enforcement: true
            skip_null_values: true
    
  5. bin/console c:c

Check ObjectNormalizer declaration in container. $defaultContext is empty.

Possible Solution

I see several options to solve this.

Looks like on this line we already have $defaultContext variable containing empty array or globally set default_context if configured. And it is a bit weird that $defaultContext variable will be considered only if circular_reference_handler or max_depth_handler exist.

image

And in case if these two options are missing - empty $context variable is set to ObjectNormalizer 6th argument. if we set $defaultContext here instead of declaring empty $context - it will work.

        $defaultContext = $config['default_context'] ?? [];

        if ($defaultContext) {
            $container->setParameter('serializer.default_context', $defaultContext);
        }

        $arguments = $container->getDefinition('serializer.normalizer.object')->getArguments();

        if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
            $defaultContext += ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
            $container->getDefinition('serializer.normalizer.object')->setArgument(5, null);
        }

        if ($config['max_depth_handler'] ?? false) {
            $defaultContext += ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])];
        }

        $container->getDefinition('serializer.normalizer.object')->setArgument(6, $defaultContext);
  1. Make ObjectNormalizer autowired by default

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0