add_filter() logic parenthesis
-
Hello!
I cannot to figure out how to apply logical parenthesis to custom filters I add to List_Query.
I have several fields on search form (Combo Multi Search plugin), if filter is set by the user the fields are added to the query using AND logic, right? Then, I want to add custom filter, only one field, but some times it have several search values which should be constructed using OR, but connected to previous filters from the form using AND. I do it in action ‘pdb-list_query_object’ in the loop, like this:if ( !empty($available_users) ) { foreach ($available_users as $u_login) { $query_filter->add_filter('user_login', '=', $u_login, 'OR'); } }And this way the search result is incorrect due the absence of parenthesis around the OR statements. Tell me if I misunderstood the whole concept.
What would be the right way of doing it?
-
It is supposed to add the parentheses automatically, I need to test this to see if there is a problem.
You can check to see exactly the query that is getting used if you turn debugging on (plugin settings under the advanced tab) and check the debugging log after displaying your list.
In order to get the AND, you need to set “Enable Filter Mode” in the Combo Multisearch settings.
Roland, I followed you suggestion and enabled debug mode. Here is an example of the query that was generated after applying filter for list view.
PDb_List::_setup_iteration list query: SELECT p.id, p.full_name, p.qualification, p.work_country, p.wage, p.country, p.native_language, p.additional_languages, p.details FROM wp_participants_database p WHERE (p.role = “user” AND p.approved = “yes” AND p.work_country LIKE “%Austria%” AND p.user_login = “2@mail.com”) OR p.user_login = “1@mail.com” ORDER BY p.date_updated DESC
so, this part comes from the shortcode
p.role = “user” AND p.approved = “yes”
this part is from filter form
p.work_country LIKE “%Austria%”
and the last part
p.user_login = “2@mail.com” OR p.user_login = “1@mail.com”
was added in action ‘pdb-list_query_object’ I was talking about in previous post.
As you can see first value of custom filter goes in parenthesis with the filter from the form, I was expecting to see something like this:
SELECT p.id, p.full_name, p.qualification, p.work_country, p.wage, p.country, p.native_language, p.additional_languages, p.details FROM wp_participants_database p WHERE p.role = “user” AND p.approved = “yes” AND p.work_country LIKE “%Austria%” AND (p.user_login = “2@mail.com” OR p.user_login = “1@mail.com”) ORDER BY p.date_updated DESC
P.S. “Enable Filter Mode” option is ON, and always was
OK, that is very helpful, I’ll need to dive deeper into this to see what the solution might be.
So far, I am unable to get your result in my tests. You are using the latest versions of Participants Database and Combo Multisearch, I assume.
Where are you placing the code that modifies the query object?
Hi, Roland!
Yes, both plugins have the latest versions are installed.
I have placed the action ‘pdb-list_query_object’ in my functions.php file in the following manner:function filter_by_avalability_dates($query_filter) { //....here goes logic to populate string array $available_users if ( !empty($available_users) ) { foreach ($available_users as $u_login) { $query_filter->add_filter('user_login', '=', $u_login, 'OR'); } } } add_action('pdb-list_query_object', 'filter_by_avalability_dates');The only line where I alter the query object in my function is
$query_filter->add_filter('user_login', '=', $u_login, 'OR');To display the list of participants I placed a shortcode on the page.
echo do_shortcode("[pdb_list template=custom filter='role=user&approved=yes']");Let me know if you need any other information.
How did you place the “echo do_shortcode” code on the page? Did you use a plugin that lets you place php in your content? I need to try to replicate the exact circumstance because so far, I am not seeing the problem in my tests.
Actually, looking at your shortcode, I don’t see why you would need to use the whole do_shortcode thing….there are no dynamic values in your shortcode. Did you try it with just the shortcode on the page?
I’m using theme’s page template to display the list. It has some logic in php and html markup. Since I put the shortcode in php, I have to use echo do_shortcode(…); function.
But, the issue lies somewhere else. I simplified everything by removing the usage of templates, but the problem is still there.
So, here are the steps to reproduce the problem:1. I created blank page and placed shortcode [pdb_list template=multisearch] directly to its content. No php, no html, no templates this time.
2. In my functions.php, I removed all unnecessary logic and the loop where i altered the query list object, and just used constants in action, like this:function filter_by_avalability_dates($query_filter) { $query_filter->add_filter('user_login', '=', '2@mail.com', 'OR'); $query_filter->add_filter('user_login', '=', '1@mail.com', 'OR'); } add_action('pdb-list_query_object', 'filter_by_avalability_dates');That is it! Now, on my search form I set filter for only one field, any field, and have this result in my debug log.
(just where portion of the query)WHERE (p.work_country LIKE "%Austria%" AND p.user_login = "2@mail.com") OR p.user_login = "1@mail.com"The expected result would be:
WHERE p.work_country LIKE "%Austria%" AND (p.user_login = "2@mail.com" OR p.user_login = "1@mail.com")See the difference? I don’t know how you might have different result in your tests? I definitely doing something wrong.
If I change OR to AND for the first value (only for an experiment):function filter_by_avalability_dates($query_filter) { $query_filter->add_filter('user_login', '=', '2@mail.com', 'AND'); $query_filter->add_filter('user_login', '=', '1@mail.com', 'OR'); } add_action('pdb-list_query_object', 'filter_by_avalability_dates');The query would be
WHERE (p.work_country LIKE "%Austria%" AND p.user_login = "2@mail.com" AND p.user_login = "1@mail.com")As you can see, in parenthesis goes only expressions joined using AND. I would like to put parenthesis around ORs.
Hmmm…are you using the pdb-list_query_parens_logic filter? It looks like you have that filter set to return false, which will parenthesize AND statements. If that filter returns true (the default) it will parenthesize OR statements.
No, I don’t mess with the pdb-list_query_parens_logic filter in my code.
But, after you told me about its existence, I added following lines to my functions.php file.function ff_parenthesize_or_statements() { return true; } add_filter( 'pdb-list_query_parens_logic', 'ff_parenthesize_or_statements' );Not sure if it’s the right way of using it. But it didn’t change the query, the parenthesis are still around AND statements.
What else can I try to find the origin of this behavior?
Ok, so is one of your multisearch fields a “ranged” search…that is, a numeric field that shows up as two inputs?
Yes, indeed! But, I don’t set the values for those search fields during this experiment, they are just left out blank.
Yes, well, it looks like there can be issues with the query if there are ranged search fields configured in multisearch. This is something I need to issue an update for, it turns out this particular setup is not something I’ve tested before, so the bug went unnoticed.
I will get an update to Combo Multisearch out very soon that fixes this.
Great! Thanks a lot!
The topic ‘add_filter() logic parenthesis’ is closed to new replies.