-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing] support for array values in route defaults #11394
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
Conversation
We would also need to find a way to represent other datatypes in xml like |
@Tobion Do you think that both array types and different scalar types should be done in the same pull request? |
Yes because if we don't find a solution for all of them, I'd argue it's not worth implementing only one part. |
I don't fully agree. Even if you were not able to use integer, float or boolean values natively in XML, you would at least be able to retain the array structure. Scalar types can be casted in the controller. Achieving the same with arrays is not always that easy (at least with nested arrays). But I also don't think that it is too hard adding support for the other data types. So I will look into this tonight. |
@Tobion the XML loading in Symfony already converts values to boolean or number types when they look like that in the DI component. However, this is not applied in the routing loader (and applying it could be considered a BC break btw). However, this way to represent arrays looks good (a bit painful if you want to represent lists as you have to map the keys explicitly though) |
@stof I thought about adding an optional
We can make the |
The problem is that the first level needs a string key name. Otherwise you would have numeric defaults which won't work (because they get removed since preg_match also adds them). |
This will not support XSD validation with types, can it? So you could add a string within a |
Should be possible to validate that in the XSD.
No, unfortunately not. If we want that, we'll have to use different XML elements for each data type I guess. Another possibility I see is to introduce a new attribute like |
I think a solution that fully supports the mentioned data types both in the XML schema and in PHP and which is backward compatible requires some more work. What I would suggest for the moment, is creating a new An example configuration may then look like this: <defaults>
<string key="foo">bar</string>
<collection key="list">
<boolean>true</boolean>
<boolean>false</boolean>
<collection>
<string key="foobar">hash value</string>
</collection>
</collection>
<integer key="baz">10</integer>
</defaults> The process defaults would then be equal to this array: $defaults = array(
'foo' => 'bar',
'list' => array(
true,
false,
array('foobar' => 'hash value'),
),
'baz' => 10,
); The already existing What do you think? |
@xabbuh using a single |
Staying with multiple <default key="foo">
<string>bar</string>
</default>
<default key="list">
<collection>
<boolean>true</boolean>
<boolean>false</boolean>
<collection>
<string key="foobar">hash value</string>
</collection>
</collection>
</default>
<default key="baz">
<integer>10</integer>
</default> For backward compatibility, <default key="foo">
<string>bar</string>
</default> and <default key="foo">bar</default> would be equivalent. |
The last proposal was also what I had in mind. But I would propose to distinguish between arrays (as data structure, not PHPs implementation) and maps/associative arrays. So you can validate in XSD that elements inside maps require a |
That's a good point since mixing list and maps also isn't possible with YAML. So, we can simply use a If we agree on this, I will update the pull request to match this structure. |
Yeah I agree with |
@@ -217,14 +217,13 @@ private function parseConfigs(\DOMElement $node, $path) | |||
$condition = null; | |||
|
|||
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does anyone of you know if there was a special reason to use getElementsByTagNameNs()
instead of iterating over the DOMNodeList
in $node->childNodes
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to support namespaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that covered by the elements from the childNodes
too? It could then need some check for the namespaces afterwards but doesn't require to scan the complete subtree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea was to ignore elements from another namespace and not throw an exception for unknown tag. So one could extend the loader and xsd to support custom elements, like in FosRestBundle.
I think this won't work with childNodes because it also returns element from other namespaces within the current node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But throwing an exception contradicts this, doesn't it?
By the way, the new method just test for the elements local name. Should I add an additional check for the element's namespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only throw for unkown elements in same namespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, of course you're right. I updated the new code to also ignore elements with a different namespace.
I updated the code to support the several data types. |
$routeCollection = $loader->load('list_in_map_defaults.xml'); | ||
$route = $routeCollection->get('blog'); | ||
|
||
$this->assertEquals( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use assertSame everywhere, so the type and order is checked
I just noticed that the new |
{ | ||
switch ($node->localName) { | ||
case 'boolean': | ||
return 'true' === trim($node->nodeValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xsd:boolean also allwos 0 and 1 AFAIK. So this won't work again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also please add a test for all values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a test for false
. And as far as I know, you cannot use 1 and 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you added a test for false
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: Legal values for boolean are true, false, 1 (which indicates true), and 0 (which indicates false).
http://www.w3schools.com/schema/schema_dtypes_misc.asp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can check that again. But I'm pretty sure that the schemaValidateSource()
method reported an error for 0 and 1. But I can of course add support for 0 and 1 though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. It works with 0 and 1.
Can you please add a note about this in the routing changelog. Then I'm 👍 to merge this. |
As @Tobion pointed out in symfony#11394, true and 1 are valid values in boolean XML attributes. The XmlFileLoader didn't handle 1 values properly.
This PR was merged into the 2.3 branch. Discussion ---------- [Routing] fix handling of nullable XML attributes | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | As @Tobion pointed out in #11394, ``true`` and ``1`` are valid values in boolean XML attributes. The XmlFileLoader didn't handle ``1`` values properly. Commits ------- 7b4d4b6 fix handling of nullable XML attributes
@fabpot considering all other loaders except xml already "supported" array defaults, we have two ways to deal with this
I'd vote for 2. because its not a bc break and it should not be a problem in php to support arrays. we deprecated apache dumper where it would probably be tedious to support arrays. so thats not a problem. also the xml loader already explicitly supported |
The support for non-string values in other formats was not a conscious decision; it just happens to work because there is no restrictions in place. So, I'm still against this change. |
Well actually it was, at least for null: #7635 |
And according to RequestContext::setParameter a parameter can be |
Re-reading this old PR, I still thing that defaults should only be strings or null. When parsing a path, you can only get back strings anyway, so allowing defaults to be something else seems wrong to me. I'm in favor of deprecating the possibility to use any other kind of value. |
One point of routing is that you can change URIs without chaning the code to parse/generate them. Since array params can be used for query strings, at one point it would also make sense to allow arrays in the path. For example, URI templates standard supports that by expanding arrays to comma-separated values. |
Also with the introduction of scalar type hints, what if a controller parameter is typehinted to |
ok, you're right. Let's finish this one then. |
@Tobion strict types are irrelevant here, because the strict mode for arguments is determined by the calling code, not by the file declaring the controller, and the Kernel class (which is calling the controller) is not in strict mode |
@stof I know. But who says Symfony 4 will not add scalar type hints in certain places and maybe strict types? |
72a3f87
to
9eb6682
Compare
As pointed out in symfony/symfony-docs#4017, the XmlFileLoader was not capable of defining array default values. Additionally, this commit adds support for handling associative arrays, boolean, integer, float and string data types.
9eb6682
to
120b35c
Compare
rebased here, if I don't miss anything all comments made so far have already been addressed |
Thank you @xabbuh. |
…xabbuh) This PR was merged into the 3.2-dev branch. Discussion ---------- [Routing] support for array values in route defaults | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | As pointed out in symfony/symfony-docs#4017, the ``XmlFileLoader`` was not capable of defining array default values. - [x] array values - [x] integer values - [x] float values - [x] boolean Commits ------- 120b35c [Routing] data type support for defaults
Maybe we should rename |
…bbuh) This PR was merged into the 3.2-dev branch. Discussion ---------- [Routing] rename boolean and integer to bool and int | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #11394 (comment) | License | MIT | Doc PR | This addresses @Tobion's comment in #11394 (comment). @symfony/deciders What do you think? Should we change the element names to how we use the types in PHP code or should we stick with XML element names that rather match the types as defined by the XML schema? Commits ------- 808dcc8 rename boolean and integer to bool and int
This was initially removed in symfony#13361 and accidentally added again in symfony#11394.
This PR was merged into the 3.2 branch. Discussion ---------- [Routing] remove an unused routing fixture | Q | A | ------------- | --- | Branch? | 3.2 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | This was initially removed in #13361 and accidentally added again in #11394. Commits ------- 6f67221 [Routing] remove an unused routing fixture
As pointed out in symfony/symfony-docs#4017, the
XmlFileLoader
was not capable of defining array default values.