-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing][FrameworkBundle] Allow configurable query encoding type in UrlGenerator #27969
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
[Routing][FrameworkBundle] Allow configurable query encoding type in UrlGenerator #27969
Conversation
b1fd637
to
d4d210c
Compare
d4d210c
to
01c65c8
Compare
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'm not entirely sure if this covers all use-cases. What if you generate a URL to an external page which doesn't follow the same encoding type? Should we add a reserved key for that in the parameters list perhaps?
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Outdated
Show resolved
Hide resolved
* | ||
* @return int | ||
*/ | ||
public function getQueryEncType(); |
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.
This method is not used, should it really be added?
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 see my comment in the main thread.
src/Symfony/Component/Routing/Generator/ConfigurableQueryEncTypeInterface.php
Outdated
Show resolved
Hide resolved
f03f7a9
to
feac7fd
Compare
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.
Thanks for the feedback!
I understand your concern, but I am not convinced it falls within the scope of this change. Because the URL generator currently uses a hard-coded value, not being able to change the encoding type is already a limitation. I am less concerned with that limitation than I am with being able to change the encoding type deep inside the URL generator class in a simple way.
That said, you can actually now change the encoding type on the fly if you are so inclined. For instance, it is now possible to do something like,
$originalEncoding = $generator->getQueryEncodingType();
$generator->setQueryEncodingType($preferredEncoding);
$url = $generator->generateUrl(...$args);
$generator->setQueryEncodingType($originalEncoding);
I am not convinced that is the most elegant way of handling this situation, but it is the reason the getQueryEncodingType
method is included in the ConfigurableQueryEncodingTypeInterface
.
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Routing/Generator/ConfigurableQueryEncTypeInterface.php
Outdated
Show resolved
Hide resolved
* | ||
* @return int | ||
*/ | ||
public function getQueryEncType(); |
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 see my comment in the main thread.
6058e86
to
f1bf418
Compare
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.
Can you decorate the generator and simply str_replace('%20', '+', parent::doGenerate(...)
to achieve the same?
src/Symfony/Component/Routing/Generator/ConfigurableQueryEncodingTypeInterface.php
Outdated
Show resolved
Hide resolved
It would require a more complex block of code than that in order to execute the replacement only on the query component of the URL — So it could be something like this: $url = parent::doGenerate(...);
$parts = parse_url($url);
if (isset($parts['query'])) {
$search = $parts['query'];
$replace = str_replace('%20', '+', $search);
$url = str_replace($search, $replace, $url);
} For reliability I would be more comfortable with something like if (isset($parts['query'])) {
$parts['query'] = str_replace('%20', '+', $parts['query']);
$url = '';
if (isset($parts['scheme'])) {
$url .= $parts['scheme'];
}
if (isset($parts['host'])) {
...
}
if (isset($parts['port'])) {
...
}
...
} But to me that starts to be excessively redundant with the heavy lifting |
e69f459
to
0c6b5e6
Compare
I don't think a global config is appropriate for this. Using RFC 1738 depends on the mime type of the page and you could even mix links with encoding RFC 1738 and RFC 3986 in the same page if you need to. So a global config would not fit there.
You can provide a custom template for the pagination in the KnpPaginatorBundle that uses + for spaces: https://github.com/KnpLabs/KnpPaginatorBundle/blob/f4ece5b347121b9fe13166264f197f90252d4bd2/Twig/Extension/PaginationExtension.php#L46 |
Btw, the PR with the implementation and description is excellent. Good job! I just don't think this is the right solution to the problem. |
Thanks, @Tobion. I was trying to make a good argument by anticipating counterarguments — but ultimately, I would not have created the pull request if I did not feel that the framework should let the developer have control over which query encoding type is used and avoid complex workarounds. I understand that RFC 1738 may be considered outdated, and RFC 3986 is the default for good reason. But I want to copy what Google does! 😄
This is a point @iltar also raised, and it’s a good one. But I don’t understand how it is a relevant criticism of this PR, because you can’t do this currently. As I see it, there are four options:
Are you suggesting we skip 3 and proceed straight to 4? Or do you feel that the framework should continue to use RFC 3986 exclusively and leave it to developers to find alternate ways of achieving RFC 1738 links? |
Honestly, I'm fine with this feature. I don't see why we should force RFC 3986 over RFC 1738. Changing globally is fine to me. At least there are no practical downsides I know about. @Tobion I feel like you're suggesting there are differences related to the mime content type, can you elaborate? |
b6e3ff0
to
661eaa9
Compare
661eaa9
to
c0cf250
Compare
8a68f40
to
296314f
Compare
2ed84ae
to
d93fa0c
Compare
d93fa0c
to
42e7c4b
Compare
Can't we make RFC1738 the hardcoded behavior instead of RFC 3986 actually, for the query part only? |
42e7c4b
to
741d99b
Compare
That was the original behavior before #19639 was merged, since the Undoing that change would nullify the discussion and decisions in #19625 and #19639. It would also create a BC break for anyone who made adjustments because of the previous BC break (#20856). |
ff34dc8
to
33581f8
Compare
9c49978
to
d451b22
Compare
d451b22
to
1a3eab4
Compare
af038a8
to
26dc8ef
Compare
26dc8ef
to
94d59fe
Compare
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.
Time to move forward here.
OK on my side. @symfony/deciders?
Global configs are a dead end IMO. Let's say I write a reusable bundle and generate links to a controller. I cannot even assume anymore that I can read links properly that I generated myself. |
I agree with @Tobion here |
I'm closing as won't fix: the currently generated URLs work fine so the matter is purely cosmetic, and we didn't reach an agreement to find the best way this should be configurable if it should. |
This PR introduces a change that makes it very easy for developers to use RFC 1738 if they choose.
I have seen #19625, but I believe there are cases when PHP_QUERY_RFC1738 may be preferred even if the generator is not used in a form context, strictly speaking. One such case is search — it can begin with an actual form, but subsequent facet and pagination links can simply be generated. Pagination and related search links in Google use RFC 1738, as do pagination and “Pro Tip!” recommendation links on GitHub.
While we could simply replace
%20
with+
after generating facet URLs, it becomes much more complicated to accomplish the same effect in pagination links if you are using a bundle like KnpPaginatorBundle.Extending the generator class seems excessive, as it would require copying over 150 lines of code to override the
doGenerate
method just to change one parameter.