-
Notifications
You must be signed in to change notification settings - Fork 41
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
Multiple add_where_expression clauses in hook_views_query_alter use same argument #6858
Multiple add_where_expression clauses in hook_views_query_alter use same argument #6858
Comments
Yes, I've seen this behavior also in db_select() built queries. I don't think there is a way to address this, as this is a problem with PHP's PDO placeholder replacement, and placeholders must be unique (you can't use the placeholder with different values in the same query). Instead, what I do with db_select queries is define a different placeholder for each type, as in etc. |
Wow, that looks like one of those views riddles. I tried to dig as deep as I could, but... 🤪 However, there seems to be an easy fix: make sure you're using different placeholder names in your loop, like just adding numbers like so: function foobar_views_query_alter(&$view, &$query) {
if ($query->base_table != 'node') {
return;
}
$filter_content_type = array_keys(node_type_get_types());
$type_edit_permissions = array();
foreach ($filter_content_type as $type) {
$type_edit_permissions[$type] = user_access('edit any ' . $type . ' content');
}
$query->set_where_group('AND', 'custom');
$i = 0;// <-!
foreach ($type_edit_permissions as $type => $edit) {
if (!$edit) {
$placeholder = ":type_$i";// Avoid using the *same* placeholder name.
$query->add_where_expression('custom', "node.type != $placeholder", array($placeholder => $type));
$i++;// <-!
}
}
} Yes, I simplified this further, to see some actual result with an unprivileged user. The "magic thing" is And, yes, what @argiepiano suggests would be an alternative (using the name). |
Hehe, I could have saved some time, if I looked at this issue's progress earlier. 😉 I was just too deep in the layers to check my notification mails. 🤫 |
I've added a PR to improve the documentation for this function including a link to the relevant PDO documentation page on PHP.net |
Perhaps this should also be added to |
This would also be true for a lot of other functions outside Views - for example for method |
It wasn't that well known as I didn't know it and was scratching my head for hours wondering why the function wasn't working. |
LGTM! |
Documenting that is a great idea! 👍 |
Description of the bug
I'm working on a module and encountered an odd situation. I'm attempting to create an
OR
group of clause statements using$query->add_where_expression()
withinhook_views_query_alter()
The queries are more complex, but for simplicity, the bit that is failing is substituting arguments. Take the following line:
Now I loop through each type, but the resulting SQL only has the first $type for every condition even though the $query object after this, viewed through dpm(), looks correct and has the right arguments for each type.
The following statement works, but I thought variables should always be added into SQL using arguments. There is no user input for the source of this variable so no real risk in doing that but still seems the wrong way.
See also https://www.drupal.org/project/views/issues/2854660
Another drupal issue has a comment with an
add_where_expression
built with the variables embedded in the statement.It looks like
views_plugin_query_default::build_condition()
is where the processing happens and it doesn't look like it is handling arguments per condition.I can see this not being a problem if the variables are from a safe source, but if they are going to take in user input then this limitation is not ideal. Also, using arguments to include variables in SQL is the recommended way to do it, so it is hard to see that this would be working as designed.
If however, this is working as designed, then it should probably be documented as such as this is an exception from the normal way of building SQL.
NOTE: The example given here is simplistic and is probably feasible without this, but I am doing more complex WHERE statements that need to be there for a module to do its stuff. The simple example is to illustrate the bug without too many steps or dependencies.
Steps To Reproduce
To reproduce the behavior:
dpm()
objects and the SQLActual behavior
While
$query
object is correct, SQL statement uses the first type for each conditionExpected behavior
Arguments work on each
add_where_expression()
function instance independently in the generated SQL statement:Additional information
Add any other information that could help, such as:
The text was updated successfully, but these errors were encountered: