Skip to content
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

Support conditional exclude for classes #1099

Merged
merged 4 commits into from
Apr 19, 2020
Merged

Support conditional exclude for classes #1099

merged 4 commits into from
Apr 19, 2020

Conversation

arneee
Copy link
Contributor

@arneee arneee commented Jun 21, 2019

Hi,

after further checking #1098, I've noticed that this functionality just isn't there yet. I've created a first draft PR for supporting condtional excludes on class level.

The PR includes the changes in class metadata and SerializationGraphNavigator as well as the annotation driver.

Still missing is:

  • Evaluate condition in DeserializationGraphNavigator
  • Other Metadata drivers
  • Unit tests

While all existing tests are passing, I was not able to add the corresponding unit tests for this case. I'm also not sure if there are any unintended side effects by not completely excluding the class if there is an @exclude annotation like it is done at the moment, but keeping it and do the evaluation during serialization.

Thanks for your help!

Q A
Bug fix? no
New feature? yes
Doc updated no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #1098
License MIT

@goetas
Copy link
Collaborator

goetas commented Jun 21, 2019

Very nice addition! Thanks a lot!
Will to a proper review in the next days.

@goetas goetas self-assigned this Jun 21, 2019
@arneee
Copy link
Contributor Author

arneee commented Jun 21, 2019

Hi Asmir,

Cool, thanks! 👍

The PR definitely still needs some work, but since I only used this library yesterday for the first time, I'm not sure how to do the missing parts, especiallcy the unit tests.

Regards,

Arne

Copy link
Collaborator

@goetas goetas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I found some time to review this.

The base-intuition is good and I think you are on the right direction.

The other drivers (xml and yaml) are still missing and tests.

For tests a good starting point can be:

You can probably add a property of PersonSecret that is an object and uses class based exclusion rules.

src/Metadata/ClassMetadata.php Outdated Show resolved Hide resolved
@arneee
Copy link
Contributor Author

arneee commented Apr 9, 2020

Hi @goetas ,

i was working on this again and run into a issue. While serialization works fine, there is one problem during deserialization.

/**
 * @Serializer\Exclude(if="object.expired != true")
 */
class PersonAccount {

    /**
     * @Serializer\Type("string")
     */
    public $name;

    /**
     * @Serializer\Type("boolean")
     */
    public $expired;

}

During deserialize() we come to the point where the exclude-If expression is being evaluated. Unfortunately the object is null, since the deserialization has not happened yet and therefore the expression fails.

I see two options.

  1. Deserialize the object first (including all the properties, childs, etc.) and then evaluate the expression. That would also require to add the object in the DeserializationContext (currently it is only present in the SerializationContext)
  2. Skip the exclude during deserialization

What is your opinion on this? Thanks!

@goetas
Copy link
Collaborator

goetas commented Apr 12, 2020

This is a known issue, and @Serializer\Exclude(if="object && object.expired != true") should do the job. Do you think is enough?

@arneee
Copy link
Contributor Author

arneee commented Apr 12, 2020

That would be the easiest solution. For my use case that would be perfectly fine, since I'm interested in serialization only anyway. For the library I don't know, should deserialization offer the same functionality like serialization? If this is ok for you, it's fine for me.

@arneee arneee closed this Apr 12, 2020
@arneee
Copy link
Contributor Author

arneee commented Apr 12, 2020

Ok, hope I got this right and in sync now.

I've tried to get it working with the solution you have suggested before, but I wasn't able to completely skip the relevant objects during deserialization. If an object was skipped by a class level exclude-if, the array of the parent element still contained a null item.

For now I've removed the Exclude-If on deserialization, it only works during serialization.

@arneee arneee reopened this Apr 12, 2020
Copy link
Collaborator

@goetas goetas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks much better! We'll done.

Can you please add some tests for the Metadata in xml and yaml?

src/Exclusion/ExpressionLanguageExclusionStrategy.php Outdated Show resolved Hide resolved
src/Metadata/ClassMetadata.php Show resolved Hide resolved
* Added tests for the drivers
* Misc
@arneee
Copy link
Contributor Author

arneee commented Apr 18, 2020

Can you please add some tests for the Metadata in xml and yaml?

Done (and now the drivers are actually working). 😃

@arneee arneee marked this pull request as ready for review April 18, 2020 18:04
@arneee arneee requested a review from goetas April 18, 2020 18:23
Copy link
Collaborator

@goetas goetas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Can you please fix the code style issue (you can just run vendor/bin/phpcbf), after that I think it is ready to be merged!

@arneee
Copy link
Contributor Author

arneee commented Apr 18, 2020

Looks good! Can you please fix the code style issue (you can just run vendor/bin/phpcbf), after that I think it is ready to be merged!

It is coming from GraphNavigatorTest, which I didn't change. phpcbf does not find anything on my installation ("No fixable errors were found")

Tried to change this part manually, let's see what travis says... still strange.

@goetas goetas merged commit 6c1a951 into schmittjoh:master Apr 19, 2020
@goetas
Copy link
Collaborator

goetas commented Apr 19, 2020

Thanks a lot for your excellent work! very very nice! :)

@arneee
Copy link
Contributor Author

arneee commented Apr 19, 2020

Hi Asmir,
Thanks for the merge, unfortunately I've noticed a mistake on my side. Currently the condition is inverted, means Exclude(if="false") will actually exclude it. This was due to a copy mistake from Expose in the drivers as well as confusing test. I have simplified the test to make it more clear and fixed the drivers. I will create a new PR.

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.

3 participants