Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ObjectNormalizer is not provided with serializer default_context #57316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
slava-petrov opened this issue Jun 4, 2024 · 4 comments
Closed

ObjectNormalizer is not provided with serializer default_context #57316

slava-petrov opened this issue Jun 4, 2024 · 4 comments

Comments

@slava-petrov
Copy link

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

@HypeMC
Copy link
Contributor

HypeMC commented Jun 4, 2024

Duplicate of #56875.

Could you see if #57273 fixes your issue?

@slava-petrov
Copy link
Author

@HypeMC , thanks for the fast reply

Yes, #57273 fixes my issue, it's actually really close to what I suggested above as a possible solution

Do you have any idea when this fix will be provided for 6.4 version?

I assume that currently I will have to add some workaround to make it work until this fix is released

@HypeMC
Copy link
Contributor

HypeMC commented Jun 4, 2024

Do you have any idea when this fix will be provided for 6.4 version?

No, but bug fix versions are released approximately every month, so once the PR is merged, it shouldn't take long.

I assume that currently I will have to add some workaround to make it work until this fix is released

You can stick to 6.4.7 until then, if I'm not mistaking, the bug is not present in that version.

@slava-petrov
Copy link
Author

Thanks for a suggestion

fabpot added a commit that referenced this issue Jun 15, 2024
…normalizers (HypeMC)

This PR was merged into the 5.4 branch.

Discussion
----------

[FrameworkBundle] Fix setting default context for certain normalizers

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #56875, fix #57316
| License       | MIT

Caused by #54791. The main problem is that `$context` defaults to `[]` instead of `$defaultContext`. There's a test to check this, but it didn't work when `circular_reference_handler` or `max_depth_handler` were not `null`.

I also found an issue with `serializer.normalizer.property`. Since it’s not tagged with `serializer.normalizer`, which, to my understanding, is intentional, it would never have the default context bound to it.

Commits
-------

f903893 [FrameworkBundle] Fix setting default context for certain normalizers
@fabpot fabpot closed this as completed Jun 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants