Forums › Forums › Search & Filter Pro › Filter based on range of meta data values
- This topic has 9 replies, 2 voices, and was last updated 9 years, 11 months ago by Anonymous.
-
Anonymous(Private) January 6, 2015 at 2:03 pm #9823
All of my posts have two custom meta fields:
$field_A
and$field_B
. I’m needing to build a functionality where a user can input a value, say $value, and then only posts where $value lies in betweenfield_A
andfield_B
are shown. That is, I need to display posts where$field_A
< $value <$field_B
is true.From what I can see S&F pro doesn’t do this out of the package. Is there a relatively simple way of modifying the code so that I can do this? Is there a particular file I should be looking at if I want to try and implement this myself?
Thanks in advance,
DanAnonymous(Private) January 7, 2015 at 1:32 am #9873I’ve found that I can add the following lines to class-search-filter-get-results.php to get the results that I need.
$args['meta_query'][] = array('key'=>'field_A', 'value' => $value, 'type'=>'NUMERIC', 'compare' => '<='); $args['meta_query'][] = array('key'=>'field_B', 'value' => $value, 'type'=>'NUMERIC', 'compare' => '>=');
Obviously this is a very hacked-together solution and not necessarily the solution that I want to land on. It maybe helps to demonstrate what I’m trying to achieve, however I’d still like to be able to include inputs in the search from so that the user can specify the value of
$value
. Although I’m not an expert, I’m relatively comfortable using PHP, so I don’t really need a full solution that modifies the admin interface – I am happy editing code if I know where I should be looking.Ross Moderator(Private) January 8, 2015 at 9:15 pm #9969Hey Daniel
I think I follow you – I had another user request something similiar.
Basically they would have a range slider, where the bottom was compared against a specific meta key, and the top end was compared against another – is this the kind of thing you are talking about?
PS what line number do you insert the above code at?
Thanks
Anonymous(Private) January 8, 2015 at 11:45 pm #9976Hi Ross, thanks for the reply.
A range slider where the top and bottom numbers are compared against two different meta keys would work, however even simpler would be a simple single-value input field (text input? Drop down? etc.) where the single input is compared to two different meta keys.
What I am essentially trying to do is create an “opening hours” search for a bunch of restaurants. Each of my “restaurant” posts has an “open time” meta field and a “close time” meta field. Basically I want to be able to filter by displaying only restaurants that are open at a given time.
I inserted the above code at 95 (just above the
$query = new WP_Query($args)
line). Though this was more just for me to play around with the $args input to WP_query to help me understand what I can do with it (I have a little experience with PHP and WordPress, but not much). I have since removed the lines because it’s not a permanent solution.Ross Moderator(Private) January 9, 2015 at 12:24 am #9979Ah ok… I can see loads of potential in adding this kind of functionality to the plugin, you use a single input, or range slider, or all sorts of kinds of fields for numbers and comparing against 2 meta fields for upper and lower limits – this is pretty tricky even as a hack, but I’ll give it a go:
So lets go with a drop down (as it already exists) – so add a post meta field to the search form UI, choose the type “choice” and create a dropdown with the values you want available.
Next – head back to “class-search-filter-get-results.php”
Head to line 570 with the function
filter_meta_query_where
. Because we have a choice field type this meta query will get be added to the query here:else if($meta_query['type']=="value")
(line 602)What I would do is do a check for the meta field you set in S&F admin, and run some custom code instead… so this:
else if($meta_query['type']=="value") { $where .= " AND ((sf_meta_$meta_iter.meta_key = '".$meta_query['key']."' AND ("; $meta_val_arr = array(); foreach($meta_query['values'] as $value) { array_push($meta_val_arr, "sf_meta_$meta_iter.meta_value = '$value'"); } $where .= implode(" ".$meta_query['operator']." ", $meta_val_arr); $where .= ")))"; }
would be this:
else if($meta_query['type']=="value") { if($meta_query['key']=="SOME_KEY_NAME") //this will be the meta key you have chosen in your post meta field { $value = (int)$value; //cast value as a number //this part says - if the meta is under or equal to the value of the user input - so the field you choose in your post meta field, should be the closing time $where .= " AND ((sf_meta_$meta_iter.meta_key = '".$meta_query['key']."')"; $where .= " AND (sf_meta_$meta_iter.meta_value <= $value))" //this part says - if the meta second meta key (entered manually here) is over or equal to the value of the user input $where .= " AND ((sf_meta_$meta_iter.meta_key = 'SECOND_META KEY')"; $where .= " AND (sf_meta_$meta_iter.meta_value >= $value))" } else { $where .= " AND ((sf_meta_$meta_iter.meta_key = '".$meta_query['key']."' AND ("; $meta_val_arr = array(); foreach($meta_query['values'] as $value) { array_push($meta_val_arr, "sf_meta_$meta_iter.meta_value = '$value'"); } $where .= implode(" ".$meta_query['operator']." ", $meta_val_arr); $where .= ")))"; } }
The query itself is just an SQL WHERE clause… you should be able to tell and its just added to a string
$where
for running later on in WP.Copy and paste that new code above in an editor so you can read the comments properly – I think its pretty close to what you want as a hack just requires some tweaks from you ๐
Good luck!
Anonymous(Private) January 9, 2015 at 12:30 am #9981Thanks so much for that Ross – I really appreciate your great customer service! I am about to head off to work so I’ll have to wait until later this evening to give this a shot, but it gives me a great place to start. I’ll let you know how it goes! ๐
Ross Moderator(Private) January 9, 2015 at 12:32 am #9982Well see you on the other side, its nearly bed time for me ๐
Anonymous(Private) January 9, 2015 at 5:28 pm #10026Ok I’ve been playing around with the code you provided – it has been very helpful, both in terms of getting me to a workable solution, but also in helping me understand more about how the plugin works ๐
A couple of questions and comments:
- On the line
$value = (int)$value; //cast value as a number
it seems that $value is empty, because it is outside of the foreach loop where it takes values of$meta_query['values']
. I’ve changed it to$value = (int)$meta_queries['values'][0];
and it seems to work. - Looks like there are a couple of lines without a terminating semicolon (;). Easy fix ๐
- QUESTION: I’m a little confused about the
sf_meta_$meta_iter.meta_key
part. With the code as you’ve written, the$where
SQL clause ends up looking like the following I’ve shortened it to just show the relevant part:$where = "...AND ((sf_meta_1.meta_key = 'open_time') AND (sf_meta_1.meta_value <= $user_input_time)) AND ((sf_meta_1.meta_key = 'close_time') AND (sf_meta_1.meta_value >= $user_input_time))"
It looks like
sf_meta_1.meta_key
is being checked against both the “open time” and “close time” meta keys. Obviously it can’t be equal to both meta keys at the same time, so I found that the search would always return no results. Does this make sense? Is there an easy way to resolve this?
Thanks again,
DanRoss Moderator(Private) January 10, 2015 at 4:49 pm #10080Yup I follow you – its a bit out of support figuring this out but if I get a chance I’ll have another play and see what I can do ๐
Anonymous(Private) January 11, 2015 at 2:17 am #10086Yep I understand, and I appreciate the help you’ve already provided! ๐ I’ve managed to put together a working solution that allows users to select, independently, a day and a time, and then the plugin shows restaurants that are open at that day and time. Until I properly learn how to use ajax to build my own plugin, this will do ๐
- On the line
-
AuthorPosts