WordPress Search by custom fields together with custom filter in custom post admin list

I have plugin for custom post list with custom post filter by customfields. Filters works fine together (filter date range and by 1 custom field)!

I’m using:

add_filter(‘parse_query’, array($this, ‘my_query_filter_’), 10);
add_action(‘restrict_manage_posts’, array($this, ‘my_show_filter’), 10);

And using Search also works fine together – returns correct custom posts searching by

(customfield_key = “key1” and customfield_value = “value1” and customfield_key = “key2” and customfield_value BETWEEN “value2” AND “value3”) AND title LIKE “%s%”

But problem starts when I’m trying to achieve that search works for all customfield values and title and works together with filter like this:

(customfield_key = “key1” and customfield_value = “value1” and customfield_key = “key2” and customfield_value BETWEEN “value2” AND “value3”) AND (title LIKE “%s%” OR customfield_value LIKE “%s%”)

When searching around found that need to ad postmeta table using filter ‘posts_join’, changing where query with filter ‘posts_where’ and prevent duplicates by filter ‘posts_distinct’.
OK, join is clear (found in several threads this solution):

function search_join($join) {
global $wpdb;
if ((is_search())) {
$join .= ‘ LEFT JOIN ‘ . $wpdb->postmeta . ‘ ON ‘ . $wpdb->posts . ‘.ID = ‘ . $wpdb->postmeta . ‘.post_id ‘;
}
return $join;
}

But for me it seems that if at least 1 filter is used then joining is duplicated – one from parse_query filter (when using filter) and one from posts_join filter when using search! And it breaks the query… Bellow is where function (as well as distinct)…

I’m missing smth, can not figure out how to achieve what I need!

function search_where($where) {
global $pagenow, $wpdb, $typenow;
if (isset($_GET[‘post_type’])) {
$type = $_GET[‘post_type’];
}
if (isset($_GET[‘date_from’]) && (!empty($_GET[‘date_from’]))) {
$date_from = $_GET[‘date_from’];
}
else {
$date_from = ‘1000-01-01’;
}
if (isset($_GET[‘date_to’]) && (!empty($_GET[‘date_to’]))) {
$date_to = $_GET[‘date_to’];
}
else {
$date_to = ‘3000-12-31’;
}
$customfield = $_GET[‘filter_by_customfield’];
$customfield_where = ”;
if ($customfield != 0) {
$customfield_where = ‘ AND ‘ . $wpdb->postmeta . ‘.meta_key = ‘customfield’ AND ‘ . $wpdb->postmeta . ‘.meta_value = ‘ . $customfield . ‘ ‘;
}
$search_phrase = ”;
if (isset($_GET[‘s’]) && (!empty($_GET[‘s’]))) {
$search_phrase = ‘(‘ . $wpdb->posts . ‘.post_title LIKE ‘%’ . $search_phrase . ‘%’ OR ‘ . $wpdb->postmeta . ‘.meta_value LIKE ‘%’ . $search_phrase . ‘%’) AND ‘;
}
if ($typenow == ‘my_custom_post’) {
if (is_search()) {
$where .= ‘ AND (‘ . $wpdb->postmeta . ‘.meta_key = ‘custom_field_date’ AND ‘ . $wpdb->postmeta . ‘.meta_value BETWEEN ‘ . $date_from . ‘ AND ‘ . $date_to . ‘ ‘ . $dcustomfield_where . ‘) ‘;
}
}
}
function search_distinct($where) {
global $wpdb;
if (is_search()) {
return ‘DISTINCT’;
}
return $where;
}
add_action(‘posts_join’, array($this, ‘search_join’));
add_action(‘posts_where’, array($this, ‘search_where’), 10, 2);
add_action(‘posts_distinct’, array($this, ‘search_distinct’));

I hope that smdb will find the bug in the code or solution with which I’m trying to achieve that I want! 😉

Read more here:: WordPress Search by custom fields together with custom filter in custom post admin list

Leave a Reply

Your email address will not be published. Required fields are marked *