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

Skip to content

[Serializer] Fix property name usage for denormalization #34035

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

Merged

Conversation

antograssiot
Copy link
Contributor

@antograssiot antograssiot commented Oct 18, 2019

Q A
Branch? 4.3
Bug fix? yes
New feature? no
Deprecations? no
Tickets
License MIT
Doc PR

Using the @SerializedName() and passing it an existing property name affects the deserialization even if @Groups() are not supposed to be involved.

How to reproduce

Given the following class

class Foo
{
    /**
     * @Group("list")
     */
    private $bar;

    public function setBar($bar)
    {
        $this->bar = $bar;
    }
    public function getBar()
    {
        return $this->bar;
    }
    /**
     * @Groups({"list:export"})
     * @SerializedName("bar")
     */
    public function getBarForExport()
    {
        return $this->bar.' Rocks';
    }
}

This allow us to change the content of the property based on the normalization context.

$obj = new Foo();
$obj->setBar('Api Platform');

$data = $normalizer->normalize($obj, null, ['groups' => ["list"]]);
// $data => ['bar' => 'Api Platform'] as expected

$data = $normalizer->normalize($obj, null, ['groups' => ["list:export"]]);
// $data => ['bar' => 'Api Platform Rocks'] as expected

$obj = $normalizer->denormalize(['bar' => 'Api Platform'], Foo::class, null, ['groups' => ['list']]);
// $obj->getBar()  would return null instead of 'Api Platform' as expected.

@antograssiot antograssiot force-pushed the serializer-metadata-aware-name-converter branch 3 times, most recently from 6da3264 to e4244b2 Compare October 18, 2019 17:35
@OskarStark
Copy link
Contributor

Did you mix things up? Group „a“ is only existent in the code change but not in the example in the PR header 🤔
Did you mean „list“ ?

@antograssiot
Copy link
Contributor Author

Did you mean „list“ ?

Yes indeed thanks I'll update

@nicolas-grekas
Copy link
Member

Should be for 3.4?

@antograssiot
Copy link
Contributor Author

Should be for 3.4?

MetadataAwareNameConverter was introduced in 4.2 @nicolas-grekas (#28505)
ref https://symfony.com/blog/new-in-symfony-4-2-simpler-custom-serialized-names

@antograssiot antograssiot force-pushed the serializer-metadata-aware-name-converter branch 2 times, most recently from 245dc23 to 6afeb2b Compare October 20, 2019 15:23
@nicolas-grekas
Copy link
Member

MetadataAwareNameConverter was introduced in 4.2

The patch doesn't change anything related to that, but changes AbstractObjectNormalizer.
It also applies to 3.4, so it would make sense to apply it to 3.4 then. That's my reasoning at least.
Why changing the behavior as a bug fix otherwise?

@nicolas-grekas nicolas-grekas added this to the 4.3 milestone Oct 23, 2019
@antograssiot antograssiot force-pushed the serializer-metadata-aware-name-converter branch from 6afeb2b to 4446b64 Compare October 31, 2019 20:57
@antograssiot antograssiot requested a review from dunglas as a code owner October 31, 2019 20:57
@antograssiot antograssiot force-pushed the serializer-metadata-aware-name-converter branch from 4446b64 to 39efcda Compare November 2, 2019 08:58
@antograssiot
Copy link
Contributor Author

The patch doesn't change anything related to that, but changes AbstractObjectNormalizer.
It also applies to 3.4, so it would make sense to apply it to 3.4 then. That's my reasoning at least.
Why changing the behavior as a bug fix otherwise?

I've updated the patch @nicolas-grekas as I think that the real underlying issue was in the MetadataAwareNameConverter caching system.
I understood that the static properties were introduced to improve performance but they are also causing this issue.

@fabpot fabpot force-pushed the serializer-metadata-aware-name-converter branch from 39efcda to 8ca4a3f Compare November 3, 2019 11:04
@fabpot
Copy link
Member

fabpot commented Nov 3, 2019

Thank you @antograssiot.

fabpot added a commit that referenced this pull request Nov 3, 2019
…antograssiot)

This PR was squashed before being merged into the 4.3 branch (closes #34035).

Discussion
----------

[Serializer] Fix property name usage for denormalization

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       |
| License       | MIT
| Doc PR        |

Using the `@SerializedName()` and passing it an existing property name affects the deserialization even if `@Groups()` are not supposed to be involved.

## How to reproduce

Given the following class
```php

class Foo
{
    /**
     * @group("list")
     */
    private $bar;

    public function setBar($bar)
    {
        $this->bar = $bar;
    }
    public function getBar()
    {
        return $this->bar;
    }
    /**
     * @groups({"list:export"})
     * @SerializedName("bar")
     */
    public function getBarForExport()
    {
        return $this->bar.' Rocks';
    }
}
```

This allow us to change the content of the property based on the normalization context.

```php
$obj = new Foo();
$obj->setBar('Api Platform');

$data = $normalizer->normalize($obj, null, ['groups' => ["list"]]);
// $data => ['bar' => 'Api Platform'] as expected

$data = $normalizer->normalize($obj, null, ['groups' => ["list:export"]]);
// $data => ['bar' => 'Api Platform Rocks'] as expected

$obj = $normalizer->denormalize(['bar' => 'Api Platform'], Foo::class, null, ['groups' => ['list']]);
// $obj->getBar()  would return null instead of 'Api Platform' as expected.
```

Commits
-------

8ca4a3f [Serializer] Fix property name usage for denormalization
@fabpot fabpot merged commit 8ca4a3f into symfony:4.3 Nov 3, 2019
@antograssiot antograssiot deleted the serializer-metadata-aware-name-converter branch November 3, 2019 12:20
@nicolas-grekas
Copy link
Member

This PR cannot be correct: the value that is put in the cache is now context-dependent, but the context is not used to compute the cache key. @antograssiot can you please have a look for a better fix?

@antograssiot
Copy link
Contributor Author

I'll send an update @nicolas-grekas

nicolas-grekas added a commit that referenced this pull request Nov 6, 2019
…rter cache (antograssiot)

This PR was merged into the 4.3 branch.

Discussion
----------

[Serializer] Use context to compute MetadataAwareNameConverter cache

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       |
| License       | MIT
| Doc PR        |

This is a follow up PR to #34035 to address @nicolas-grekas 's [comment](#34035 (comment))

The static cache has been re-introduced and the context is used to compute the cache key used for denormalization

Commits
-------

0ac5346 [Serializer] Use context to compute MetadataAwareNameConverter cache
@fabpot fabpot mentioned this pull request Nov 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants