Problem/Motivation
The query parameter (query_parameter) plugin provides a Views default argument with a value taken from a query parameter from the current request. For instance, if the request has a query string such as ?foo=bar&baz=qux, by configuring the plugin to get the argument default value from the foo param, will return bar.
However, the request query string might look like ?foo[bar][baz]=qux. With the current code, setting the the param to foo[bar][baz] will return NULL instead of qux. The reason is that QueryParameter::getArgument() only checks for the 1st tier of query string parameters and is not able to process array structured values.
Steps to reproduce
See the tests.
Proposed resolution
- Convert the param name into an array: the
foo[bar][baz]will become['foo', 'bar', 'baz']. - Use
NestedArray::getValue()to vertically traverse the array and find the nested value.
Remaining tasks
None.
User interface changes
None.
API changes
None.
Data model changes
Site builders are able to store query param names having an array structure.
Release notes snippet
N/A
Original report
By providing a query parameter as contextual filter argument, we can already limit the referenceable entitities in an entity reference view, with #1699378: Allow tokens in entity reference views selection arguments being only an alternative approach.
In many cases we can use a simple ?key=value query parameter.
When creating a new entity in a dependent dropdown setting with two fields (the entity reference field_city depending on another field_country), we however might want to use the Prepopulate module to prepopulate both field_country and the (dependent) entity reference field_city. We could easily do so, setting both fields at the same time using a single query parameter for field_country that is also caught by the entity reference view and used to restrict the referenceable entities in field_city.
Prepopulate however expects all parameters in the ?edit[field_xyz] form in order to avoid name collisions, and our QueryParameter default argument doesn't support this kind of array structure. Or actually it does. The only problem is the
if ($current_request->query->has($this->options['query_param'])) {
clause, as the flattened edit[field_xyz] parameter is send to ParameterBag->has() which uses array_key_exists() to find the (string) needle in the (array) haystack. Which can't work.
I'm not sure if beyond Prepopulate module there is any use for this kind of array structure in query parameters, and clearly this could be solved by prepopulate module itself, by supplying an altered QueryParameter default argument plugin. On the other hand, why wouldn't we want to support this kind of array structure in Core views, plus the parse_str making this work isn't expensive at all.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | 3027705-nr-bot.txt | 197 bytes | needs-review-queue-bot |
| #2 | edit[field_xyz]_contextual_filter_query_parameter-3027705-2.patch | 1.01 KB | pancho |
Issue fork drupal-3027705
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
panchoComment #3
panchoComment #12
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #15
claudiu.cristeaComment #16
claudiu.cristeaAdded test coverage
Comment #17
claudiu.cristeaAdded CR https://www.drupal.org/node/3356132
Comment #18
smustgrave commentedCould the issue summary be updated to include what the proposed solution was.
Ran the tests locally without the fix and of the 3 news one
first =failed
second = failed
third = passed
Can you confirm the third one should still pass?
Thanks!
Comment #19
claudiu.cristeaYes, it's expected behaviour with the current code because the plugin is not able to handle query params such as
foo[bar]Updated the IS.
Comment #20
claudiu.cristeaAnd for me this looks like a bug.
Comment #21
smustgrave commentedThanks for clarifying!
Comment #27
catchCommitted/pushed to 11.x and cherry-picked back through to 9.5.x, thanks!
Comment #28
claudiu.cristeaPublished https://www.drupal.org/node/3356132