I have a block display of a View embedded in a Panels page which receives its contextual filters via query parameters to the page. See first screenshot.
I also chose to allow multiple values for this contextual filter. And in this case, the filter is in glossary mode (filtering on the first letter of the node title), but that is less important. See the second screenshot.
The first problem I noticed is that while filtering by a single value (?test[0]=0
) is working fine, trying to filter by multiple values (?test[0]=0&test[1]=1
) was throwing the following exception:
'Placeholders must have a trailing [] if they are to be expanded with an array of values.'
After some digging, I found #2401615, which dictates database placeholders for queries must end in []
if they are for an array of values, as they are in this case since I'm trying to apply an OR condition for multiple values on a filter. Ultimately, I found that the views handler for string arguments was not properly adding []
to the database placeholder if the arguments are an array of values. I was able to resolve this issue and thus eliminate the exception thrown by Drupal. I will attach a patch for this issue in my next comment.
However, even once that issue was resolved, multiple values for the contextual filter are still not working. The replacements for the placeholder are not making it into the final query, resulting in an empty IN condition:
SELECT node_field_data.created AS node_field_data_created, node_field_data.nid AS nid
FROM
{node_field_data} node_field_data
WHERE (( (SUBSTRING(node_field_data.title, 1, 1) IN()) )AND(( (node_field_data.status = '1') AND (node_field_data.type IN ('lab_test')) )))
ORDER BY node_field_data_created DESC
If I debug the condition for this query clause from the Condition::compile method, it looks like this:
I dug around more into the core database layer trying to figure this out, but I'm unable to determine if this is the correct structure for this query condition and/or why the replacement values are not making into the final query output. Any advice or pointers would be appreciated.
Comment | File | Size | Author |
---|---|---|---|
#4 | views-filters-multiple-params-2876802-4.patch | 567 bytes | mrkdboyd |
query-param-filter-condition.png | 106.34 KB | mrkdboyd | |
view-filter-more-settings.png | 84.27 KB | mrkdboyd | |
view-filter-query-param.png | 142.04 KB | mrkdboyd |
Comments
Comment #2
mrkdboyd CreditAttribution: mrkdboyd commentedComment #3
mrkdboyd CreditAttribution: mrkdboyd commentedComment #4
mrkdboyd CreditAttribution: mrkdboyd commentedHere is the patch to add
[]
to the database placeholder when there are multiple query parameters for a contextual filter.Comment #5
mrkdboyd CreditAttribution: mrkdboyd commentedComment #6
Lendude@mrkdboyd thanks for the report and the patch.
It would really help to get some steps to reproduce with just Drupal core. If this is a bug then we would also need a test to reproduce this.
Setting to needs review to trigger the testbot on the patch.
Comment #7
LendudeOk that didn't trigger anything :)
Back to needs work for tests.
Comment #8
mrkdboyd CreditAttribution: mrkdboyd commentedI can confirm that this is happening with just a Views page display as well, so no Panels involved. If you create a View with a page display matching the configuration in the screenshots above and try to use multiple query parameters
?test[0]=0&test[1]=1
as contextual filters to the view, you should see the Exception I noted above being thrown.Comment #9
mrkdboyd CreditAttribution: mrkdboyd commentedComment #10
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation commentedComment #11
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation commentedThe test for the file we are patching is
core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
,However I can see there is this test which looks to me like it handles this kind of situation for all default arguments:
core/modules/views/tests/src/Unit/Plugin/argument_default/QueryParameterTest.php
.So I'm not sure where we should be expanding the test coverage...
Comment #15
PanchoI can confirm following InvalidArgumentException:
for both 8.2.8 and 8.7.x in views with:
/admin/content?test[0]=T&test[1]=B
), or via regular parameter (/admin/content/T+B
) or in the View PreviewPatch #4 still applies and correctly fixes this bug. Tests are definitely needed.
Comment #16
TuWebO CreditAttribution: TuWebO at Metadrop commentedAs per comment in #15, changing the title to better match the issue.
Comment #19
diegoluisr CreditAttribution: diegoluisr commentedI solve this issue for my project as a workaround using "hook_views_query_alter()", this is not a solution for everybody but I hope some people find inspiration on it.
I have a view of bars in the city (cocktails related website) because the number of nodes is not a big one I need to group them into 3 characters sets ABC, DEF, GHI, JKL, MNO, PQR, STU, VWX, YZ, and I have a special group for numerical titles NUM, my contextual filter is set to "Content: Title"
Other configuration:
- default value from the query parameter 'ALL'
- "Glossary mode" enabled
- multiple values allowed
- single value is given (not using "+" or ",")
this is my code solution, in a custom module I had added a function that implements "hook_views_query_alter()"
I came to this solution by analyzing the where clause. This below block shows a single character query.
This second block shows the query using 3 characters "JKL"
This third block shows the view query altered by my code.
Comment #22
kristiaanvandeneyndeI can confirm this bug is still present. A very easy way to test this is to write a ViewsArgumentDefault plugin that returns multiple values. Set up any view that takes a contextual filter on a string value, then feed it a dummy ViewsArgumentDefault that returns "foo,bar,baz" and see the crash in all its glory :)
Comment #24
thomasmurphy CreditAttribution: thomasmurphy at Xequals commented