Your support helps keep this blog running! Secure payments via Paypal and Stripe.
Lately, my client requires me to add the ability to search by custom fields at the backend. Today I gonna share what I did.
There are three filters we will use.
Below is what page will be implemented.

You can add the code below to functions.php or your own plugin. $_GET[‘s’] is the search input on the edit page. The posts_distinct filter is needed to prevent duplicate data.
add_filter('posts_join', 'package_customfields_search_join');
function package_customfields_search_join($join)
{
global $pagenow, $wpdb;
if (is_admin() && 'edit.php' === $pagenow && 'packages' === $_GET['post_type'] && !empty($_GET['s'])) {
$join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
}
return $join;
}
add_filter('posts_where', 'package_customfields_search_where');
function package_customfields_search_where($where)
{
global $pagenow, $wpdb;
if (is_admin() && 'edit.php' === $pagenow && 'packages' === $_GET['post_type'] && !empty($_GET['s'])) {
$where = preg_replace(
"/\(\s*" . $wpdb->posts . ".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
"(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_value LIKE $1)",
$where
);
}
return $where;
}
add_filter('posts_distinct', 'package_search_distinct');
function package_search_distinct($where)
{
global $pagenow, $wpdb;
if (is_admin() && 'edit.php' === $pagenow && 'packages' === $_GET['post_type'] && !empty($_GET['s']) && is_search()) {
return "DISTINCT";
}
return $where;
}
Yeap! that’s it. If you are looking for adding the custom fields filter, you may check my post here.
Your support helps keep this blog running! Secure payments via Paypal and Stripe.