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

Handle array format for dateHandler #1108

Merged
merged 6 commits into from
Jan 24, 2020
Merged

Handle array format for dateHandler #1108

merged 6 commits into from
Jan 24, 2020

Conversation

VincentLanglet
Copy link
Contributor

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

@goetas
Copy link
Collaborator

goetas commented Jul 28, 2019

Hi!
First of all, thanks for your contribution! I apologize, but somehow missed this PR.

Can you add some tests for this? I'm really not able to understand how this works...

@VincentLanglet
Copy link
Contributor Author

I made a mistake. All is good now and I added tests.
Does this helps you ?

params can still be ['Y-m-d'] but now can be [['Y-m-d'], ['Y/m/d'], ...].
In this case we try to serialize with the format 'Y-m-d', then, in case of failure, 'Y/m/d', and so on.

@goetas
Copy link
Collaborator

goetas commented Jul 28, 2019

I think here is missing the update on the type parser. How to provide this new type definition via @Type annotation as example?

@VincentLanglet
Copy link
Contributor Author

@goetas I wanted to be used this way

@JMS\Type("DateTime<'Y-m-d\TH:i:s'>")
@JMS\Type("DateTime<null, null, 'Y-m-d\TH:i:s'>")
@JMS\Type("DateTime<['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']>")
@JMS\Type("DateTime<null, null, ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']>")

Are you saying ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP'] is not actually parsed as a php array ?

@goetas
Copy link
Collaborator

goetas commented Jul 28, 2019

Are you saying ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP'] is not actually parsed as a php array ?

Exactly. I think this has to be implemented.

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Jul 28, 2019

Exactly. I think this has to be implemented.

Do you know how it works and what is needed to be added/changed.

I see in both Xml and Json deserialisation visitor the function.

public function visitArray($data, array $type): array

So it seems like it's already implemented.
If it's not, I really don't know if I'll be able to add this feature...

@goetas
Copy link
Collaborator

goetas commented Jul 28, 2019

In https://github.com/schmittjoh/serializer/tree/master/src/Type you have the classes responsible for the type parsing. They convert the type definition syntax in the array of parameters passed to the visitors.

The type parsing is implemented using the hoa lexer and parser (see https://github.com/hoaproject/Compiler)

@VincentLanglet
Copy link
Contributor Author

In https://github.com/schmittjoh/serializer/tree/master/src/Type you have the classes responsible for the type parsing. They convert the type definition syntax in the array of parameters passed to the visitors.

Yes, the type visitor call visitCompoundType which returns

[
    'name' => $nameToken->getValueValue(),
    'params' => array_map(
        function (TreeNode $node) use ($handle, $eldnah) {
            return $node->accept($this, $handle, $eldnah);
        },
        $parameters
    ),
];

When you look at the accept function of the hoa project, it calls the visit of the Visitor.
And in the DeserializationVisitorInterface of you project, there is already a function visitArray. So it's seems already implemented.

Can you check again ?
Or at least give a failing test with array params I need to fix ?

@VincentLanglet
Copy link
Contributor Author

@goetas You maybe missed my previous message

@goetas
Copy link
Collaborator

goetas commented Aug 11, 2019

So it's seems already implemented.

Most probably is not. You can see here the tests for it https://github.com/schmittjoh/serializer/blob/master/tests/Serializer/Type/ParserTest.php#L36

You can try to add here strings following your syntax and check if they pass.

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Aug 11, 2019

It seems good to me this way 0ff06b7

It's the same syntax than

'array<Foo\Bar, Baz\Boo>'

@goetas
Copy link
Collaborator

goetas commented Aug 12, 2019

Yeah, but the foundation of your proposal is based on this syntax: DateTime<null, null, ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']>, that is not tested and most probably not working.

Can you test this?

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Aug 12, 2019

Yeah, but the foundation of your proposal is based on this syntax: DateTime<null, null, ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']>, that is not tested and most probably not working.

Can you test this?

Damned ! I forgot what I wanted to test...
I fixed it : 72f15d1

Still working

@VincentLanglet
Copy link
Contributor Author

@goetas I'm sorry, how should I understand your emoji ?
Why are you confused ?

@goetas
Copy link
Collaborator

goetas commented Aug 18, 2019

I'm confused because the grammar file has no instructions on how to handle []... so will have to check it on my own when will have some time

@VincentLanglet
Copy link
Contributor Author

I'm confused because the grammar file has no instructions on how to handle []... so will have to check it on my own when will have some time

I understand. Indeed, [] is surely not handled.
But no need to handle [] if you handle array<>.

DateTime<null, null, array<'Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP'>> is good enough.

@VincentLanglet
Copy link
Contributor Author

Hi @goetas, do you have time to check it on your own ?

@goetas
Copy link
Collaborator

goetas commented Sep 17, 2019

I had a look, and as said in #1108 (comment)
DateTime<null, null, ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']> is not handled.

DateTime<null, null, array<'Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP'>>, with array has a different semantic meaning.

@Majkl578 Could you help us to have the parser supporting [] array definitions?

@goetas
Copy link
Collaborator

goetas commented Sep 17, 2019

Ideally the tests case to pass should be

        yield [
            'DateTime<null, null, [\'Y-m-d\TH:i:s\', \'Y-m-d\TH:i:sP\']>',
            $type('DateTime', [null, null, ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']]),
        ];

@VincentLanglet
Copy link
Contributor Author

DateTime<null, null, array<'Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP'>>, with array has a different semantic meaning.

What are the semantic meaning differences between array and [] ? This is surprising me

@goetas
Copy link
Collaborator

goetas commented Sep 17, 2019

array is a type. used for the handlers. while [] are just parameters for the current type.

@Majkl578
Copy link
Contributor

@goetas Is this what you had in mind? #1125

@goetas
Copy link
Collaborator

goetas commented Sep 19, 2019

@VincentLanglet If you look at #1125 , @Majkl578 did exactly what you need!

@VincentLanglet
Copy link
Contributor Author

Great ! Thanks @Majkl578

@VincentLanglet
Copy link
Contributor Author

HI @goetas What are the step now ?

  1. Merging Accept arrays as type attribute values #1125
  2. Merging this PR

Am I missing something ?

@@ -79,6 +79,10 @@ public function validTypesProvider(): iterable
'array<Foo\Bar, Baz\Boo>',
$type('array', [['name' => 'Foo\Bar', 'params' => []], ['name' => 'Baz\Boo', 'params' => []]]),
];
yield [
'DateTime<null, null, array<\'Y-m-d\TH:i:s\', \'Y-m-d\TH:i:sP\'>>',
$type('DateTime', [null, null, ['name' => 'array', 'params' => ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP']]]),
Copy link
Collaborator

Choose a reason for hiding this comment

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

They should be tested together to make sure it works as expected.

Your current branch is not compatible with #1125.
If you checkout #1125 and and test it with your code, it will fail.

DateTime<null, null, ['Y-m-d\TH:i:s', 'Y-m-d\TH:i:sP'], will produce an array format that your getDeserializationFormatsAndTimeZones will not be able to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wouldn't be easier if the #1125 branch was merge into master ?

@VincentLanglet
Copy link
Contributor Author

VincentLanglet commented Dec 9, 2019

@goetas Rebased, Fixed, And tested with #1125

And I tried to update the doc

@VincentLanglet
Copy link
Contributor Author

Hi @goetas , happy new year.
I think everything is ready in this PR. Do you have some time to look at ?

@@ -463,6 +466,11 @@ Examples:
*/
private $endAt;

/**
* @Type("DateTime<['Y-m-d', 'Y/m/d']>")
Copy link
Collaborator

@goetas goetas Jan 12, 2020

Choose a reason for hiding this comment

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

This is not correct. Serialization does not accept more than one format. The feature you are building makes sense only for de-serialization.
I think we should throw some error if this is used for serialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

DateTime<'formats'>

is a shortcut for

DateTime<'formats', null, 'formats'>

that's why I allowed the syntax.

But for serialization I used the first valid format.

If I only allow the third parameter to be an array, it means that someone who only care bout de-serialization, will write

@Type("DateTime<'Y-m-d'>")

To deserialize only one format, and

@Type("DateTime<'Foo', 'Bar', ['Y-m-d', 'Y/m/d']>")

To handle multiple syntax. I found this a little sad...

Copy link
Collaborator

Choose a reason for hiding this comment

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

I can understand that, but DateTime<['Y-m-d', 'Y/m/d']> is wrong since the serialization does not accept multiple formats. it will always pick the first.

But to be hones, thinking it twice, I start to like this feature less and less.

I had a similar problem in the past and i solved it with a custom date handler (see https://github.com/goetas-webservices/xsd2php-runtime/blob/master/src/Jms/Handler/XmlSchemaDateHandler.php#L86)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can only allow the syntax DateTime<'Foo', 'Bar', ['Y-m-d', 'Y/m/d']> if preferred.

But to be hones, thinking it twice, I start to like this feature less and less.

It would be nice to make your choice, I took time working on it and I prefer to know now if I taking more time on it will be useless.

I had a similar problem in the past and i solved it with a custom date handler

I feel like, it's really hard to write a custom date handler for someone starting with the library.
When only using the annotation (like we do in our company), it's so much easier to use an array that writing a whole custom dateHandler.

@goetas
Copy link
Collaborator

goetas commented Jan 12, 2020

See #1108 (comment) and I think an integration test would be a good thing to do, something like

public function testDateTimeImmutable($key, $value, $type)

Providing two date formats, the first should fail, and the second should succeed.

@VincentLanglet
Copy link
Contributor Author

@goetas

@Type("DateTime<['Y-m-d', 'Y/m/d']>")

Is now not supported

And there is an integration test

@goetas goetas merged commit 5286388 into schmittjoh:master Jan 24, 2020
@goetas
Copy link
Collaborator

goetas commented Jan 24, 2020

thank you @VincentLanglet for your work and your patience!

@VincentLanglet VincentLanglet deleted the handleArray branch January 27, 2020 13:41
mgrundkoetter added a commit to ujamii/openimmo that referenced this pull request Feb 4, 2020
mgrundkoetter added a commit to ujamii/openimmo that referenced this pull request Mar 10, 2020
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