- 🇮🇳India mohit_aghera Rajkot
I think we need to do some work on the solution.
The option that is used in the patch #23 is removed now.
Issue that removed the option: https://www.drupal.org/node/981870 →I am able to reproduce the issue. However slightly confused whether I took right steps to reproduce the issue.
I'm going to upload the issue along with the test-only patch and a fix. - 🇳🇱Netherlands Lendude Amsterdam
Works fine without the exposed filter, only breaks for me using the exposed filter first.
Uh use facets module? ;)
- 🇺🇸United States luckydad
Thank you to all who contribute to Drupal and this community. I am migrating a Drupal 7 site to Drupal 10.x whose main navigation is a view with geographic hierarchy contextual filters similar to original post. My view has exact same problem where "all" is being added to View Summary links and the "all" breaks the view. When I remove "all" from the URL the view works. I can also confirm everything in #31 above. Tried to replicate and share in a simplytest.me site but simplytest.me one click deploys not working. When I changed
$parameters[$variable_name] = '*';
to
$parameters[$variable_name] = '';
in
core/modules/views/src/ViewExecutable.php
line 2030
my view works.
Thanks Daniel Schaefer for your original post. I thought I was doing something wrong. And thanks mohit_aghera. - 🇬🇷Greece idimopoulos
Ok, I am having a similar issue, not with summary links, but with the exposed filters block. But I think the underlying problem is probably more or less the same with this ticket.
I have also checked the issues
https://www.drupal.org/project/drupal/issues/3175725 🐛 With a taxonomy term view Exposed form in block has incorrect action URL /taxonomy/term/all, not taking into account term id and breaking filtering without AJAX / JS Needs work
https://www.drupal.org/project/views_data_export/issues/3214504 →
https://www.drupal.org/project/drupal/issues/2840283 🐛 Problem with action path for embedded forms Needs work and
https://www.drupal.org/project/drupal/issues/3454813 🐛 NULL contextual argument should be skipped during views URL generation Active and they all seem to be quite similar.As per #22, @gnosis, it seems you have replicated fine and concluded to the correct problem. I am not sure why it works that way and why the exception value is enforced without "exception" (pun intended).
So, my case:
I have a view with a URLnode/%node/assignments
.
I have 2 contextual filters. One about the node from the URL, and one for the current user - the current user targets directly a field in the views, so is not represented by a named parameter in the URL.
I have a few exposed filters so an exposed filter form. I am not using summary links or NULL arguments as in the other issues but the end result is the same.
What happens, is that at some point, during the form build, the code ends up incore/modules/views/src/Form/ViewsExposedForm.php:135
:$form_action = $view->getUrl()->toString();
In the
::getUrl()
, if the path does not contain a named parameter (in my case%node
), it just escapes early, so no problem there. So I guess All of the above issues and yours are using views with named parameters.
Next, comes the weird part. Since there is a named parameter, the view tries to resolve them. However, the$variables = $route->compile()->getVariables();
inweb/core/modules/views/src/ViewExecutable.php:2019
returns an array such as that:
- Returns the amount of arguments according to the contextual filters (in my case 2).
- Attempts to replace the amount of arguments from the list of named parameters in the URL (in my case, the%node
matches the first contextual filter, which is the node from the URL).
So, in my case, returnsarray ( 0 => 'node' 1 => 'arg_1' )
I have tested it with more arguments and indeed, it seems the array is populated by the list of named parameters in the URL + the difference in number between the named parameters and the contextual filter. Note that this is only replicable to me if the number of contextual filters are greater than the number of named parameters, and at least 1 named parameter exists.
Then comes the thing that is worked around in #23 because it iterates through these parameters, and simply fills in the list with the arguments available but forces empty arguments to get the exception value.
Now, the way I see it, there are more than one problems:
* Inconsistent behavior based on URLs - clicking apply changes the URL if there are named parameters and does not if not.
* Contextual filter exceptions are enforced and there is no way to disabled them. Even if left empty, for some reason we have the * as a callback which is also URL encoded in the result, so it also does not look nice.
* Security implications (minor)? Consider that in my case, the current user (which is a "hardcoded" filter) is changed in "all" which makes the view to show additional content (that is reduced to minor of course because views respect permissions but still).The solution from #23 does solve the issue by allowing to set an empty string to the exception value and skip the argument.
In my case, I also thought to reuse some of the::_buildArguments()
method and ended with something like thisforeach ($variables as $variable_name) { if (empty($args)) { // Try to never put % in a URL; use the wildcard instead. if ($id) { if (!empty($this->argument[$id]->options['default_argument_type'])) { $argument = $this->argument[$id]; if ($argument->broken() || $argument->hasDefaultArgument()) { continue; } } if (!empty($this->argument[$id]->options['exception']['value'])) { $parameters[$variable_name] = $this->argument[$id]->options['exception']['value']; } }
Though i don't know if this breaks something. The idea is that some contextual filters, like the current user, are placed because they have some sort of static-ish value and should not be overridden. However, I can think of many ways of why this might not be true.
Bottom line is that in my opinion, the exception value should be optional.