Extending admin search with post meta

Published Dec 14, 2017

The default search functionality in your WordPress admin is not based on post meta. To be able to search by post meta you need to extend the posts_join and posts_where query functions by adding a filter on both.

First I will add the filter for posts_join as follows:

/**
 * Join postmeta in admin post search
 *
 * @return string SQL join
 */
function gtp_post_search_join( $join ){
    global $pagenow, $wpdb;
    if ( is_admin() && $pagenow == 'edit.php' && ! empty( $_GET['post_type'] ) && $_GET['post_type'] == 'post' && ! empty( $_GET['s'] ) ) {
        $join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    return $join;
}
add_filter( 'posts_join', 'post_search_join' );

Then I add the filter for posts_where:

/**
 * Filtering the where clause in admin post search query
 *
 * @return string SQL WHERE
 */
function gtp_leads_search_where( $where ){
    global $pagenow, $wpdb;
    if ( is_admin() && $pagenow == 'edit.php' && ! empty( $_GET['post_type'] ) && $_GET['post_type'] == 'post' && ! 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_where', 'post_search_where' );

You can add these filters for every kind of post type by simply making the comparison with the $_GET[‘post_type’] to your post type instead of ‘post’.

Voila! You are now able to search in your admin by post meta values.

Discover and read more posts from Robbert Vermeulen
get started