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

added optional expression parameter to the ReadOnly annotation #1178

Closed
wants to merge 5 commits into from

Conversation

helmut1337
Copy link

@helmut1337 helmut1337 commented Mar 25, 2020

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

Hello,
for my project I needed some way to dynamically define if a property is ReadOnly or not.
So I implemented the ExpressionParser the same way as the @exclude annotation does.

Similar features has also been asked here some years ago. It's not possible with groups though.
schmittjoh/JMSSerializerBundle#628

@goetas
Copy link
Collaborator

goetas commented Mar 26, 2020

Hi. Thanks for your contribution.
Can you please implement the same logic for the other two drivers (yml and xml)?

/**
* {@inheritDoc}
*/
public function shouldSkipPropertyOnDeserialize(PropertyMetadata $property, Context $navigatorContext): bool
Copy link
Collaborator

@goetas goetas Mar 26, 2020

Choose a reason for hiding this comment

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

I believe that this method can be moved into shouldSkipProperty and use the $navigatorContext to understand if we are in "deserialization". In this way we do not need a new public method in this class.

Copy link
Author

Choose a reason for hiding this comment

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

good idea, I've changed that

optimzed shouldSkipProperty and removed shouldSkipPropertyOnDeserialize
@helmut1337
Copy link
Author

Hey,

I've now also added this functionality to the XML and YML drivers.

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! Great work so far! Can you also add tests please? (and update the XML/YML reference in https://github.com/schmittjoh/serializer/tree/master/doc/reference ?)

}
}

/*
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you avoid commenting code please?

Copy link
Author

Choose a reason for hiding this comment

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

oops sorry, forgot to remove that block

@goetas
Copy link
Collaborator

goetas commented Mar 28, 2020

See https://github.com/schmittjoh/serializer/pull/1178/files#r399651332 that suggests a bit different approach.

@goetas
Copy link
Collaborator

goetas commented Mar 28, 2020

to fix automatically CS issues, you can run vendor/bin/phpcbf

@@ -68,6 +69,7 @@ protected function loadMetadataFromFile(\ReflectionClass $class, string $path):
$exclude = $elem->attributes()->exclude;
$excludeAll = null !== $exclude ? 'true' === strtolower((string) $exclude) : false;
$classAccessType = (string) ($elem->attributes()->{'access-type'} ?: PropertyMetadata::ACCESS_TYPE_PROPERTY);
$readOnlyClass = $elem->attributes()->{'read-only'};
Copy link
Author

Choose a reason for hiding this comment

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

for some weird reason I really cannot find out, I cannot do parseExpression() here, because if re-use the variable $readOnlyClass in the property-loop it is only working for the first call. On the second call then, I'm getting error on unserializing the cache. But if I do parseExpression() inside the property-loop it works fine.
Makes really no sense to me.

Copy link
Collaborator

Choose a reason for hiding this comment

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

you should cast to string the xml node

Copy link
Author

Choose a reason for hiding this comment

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

If you look into my previous commit, I'm doing that there.
I've noticed that it was actually only working for the caching-call. The second call fails with error:

Return value of JMS\Serializer\Metadata\PropertyMetadata::unserializeProperties() must be of the type string, null returned [] []

It's really weird because if I do the exact same thing inside of the property-loop, it is working.
So putting the block on line 90-96 (previous commit) into the loop starting at line 174, it works..

It's just confusing me and I wanted to find out how this happens.
But it does not really matter because doing parseExpression on every porperty will maybe only affect the performance on when creating cache

$pMetadata->readOnlyIf = null;
$readOnly = null === $pElem->attributes()->{'read-only'} ? $readOnlyClass : $pElem->attributes()->{'read-only'};
if(null !== $readOnly) {
if ($readOnly === 'true' || $readOnly === 'false') {
Copy link
Author

Choose a reason for hiding this comment

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

Thought of also parsing the true/false values as expression. But I guess it's not good for performance.

Copy link
Collaborator

Choose a reason for hiding this comment

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

here performance are not a concern as this is done only once, then data are cached

Copy link
Author

Choose a reason for hiding this comment

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

as I saw it is only caching the expression-string and not the result, which makes sense because the expression should be evaluated on deserialize to be dynamically.
And then it would always evalute expressions with "true" and "false" on deserialize.
Not sure if this will produce impact at all though.

@helmut1337
Copy link
Author

Removed read-only-if tag in yml and xml. read-only is now also parsing expressions.
guess I'm done :)

@helmut1337 helmut1337 requested a review from goetas March 30, 2020 19:55
@helmut1337
Copy link
Author

hey,
wanted to ask if there's anything missing from my side?

@Sorato95
Copy link

when this will be merged?

@helmut1337 helmut1337 closed this Mar 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants