8

I have a custom post type that includes many custom fields. I would like to add them as a search target to admin search.

Currently the admin search searches only the content and the title, I would like it to search these custom fields as well.

Is there a way to do that ?

1
  • I have been looking for this same thing for ages. I needed to search properties by ref number in the wordpress admin. Finally I found this brilliant plug-in: http://wordpress.org/plugins/search-everything/ Check it out; it can search any field and custom field! Commented Jun 27, 2013 at 10:24

2 Answers 2

6

It is possible, but you'll have to play a little bit with the actual query. As always, the furious posts_clauses filter comes to action:

function wpse_alter_posts_search( $pieces )
{
    global $wpdb;

    // Make the input save
    $search_string = like_escape( $_GET['s'] );

    // Your new WHERE clause
    $where  = $wpdb->prepare(
        "$wpdb->postmeta.%s LIKE %s",
        'YOUR_COLUMN', // Should match your col name 1)
        "%{$search_string}%"
    );

    // Not sure if this exactly the same on your install 2)
    $pieces['where'] = str_replace( 'AND (((', "AND ((({$where} ", $pieces['where'] );

    return $pieces;
}
add_filter( 'posts_clauses', 'wpse_alter_posts_search' );

NOTES

  1. Could be that you need to unserialize some parts to be search able.
  2. You better simply dump the $pieces to take a look into them, before altering the query (right after the $search_string was received).
4
  • Or posts_where :D Commented Mar 8, 2012 at 18:15
  • @StephenHarris I personally prefer the »alltogether« posts_clauses filter. No need to remember those (imho unnecessary) other filters...
    – kaiser
    Commented Mar 8, 2012 at 18:16
  • I guess like_escape should be a function that escapes the search string to like format. can you please add it ? I'me having problems with this... Commented Mar 9, 2012 at 13:20
  • Added like_escape()ed to the prepare(). And no: It doesn't reformat the input search string. It makes it just save for queries, like other esc_* functions do for other tasks.
    – kaiser
    Commented Mar 9, 2012 at 13:32
3

kaiser's answer got me on the right track but I had to join the postmeta table and add a group by as well.

Now like_escape is $wpdb->esc_like. Replace [your_post_type] with your post type and [your_postmeta_key] with your meta key:

//join postmeta for search
add_filter( 'posts_join' , function($join){
    global $wpdb;
    if(is_search() && is_admin() && $_GET['post_type'] == '[your_post_type]')
    {
     $join .= " LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";
    }
     return $join;
});

//search [your_postmeta_key] for search string
add_filter( 'posts_where', function( $where )
{
    global $wpdb;
    if(is_search() && is_admin() && $_GET['post_type'] == '[your_post_type]')
    {
        $searchstring = '%' . $wpdb->esc_like( $_GET['s'] ) . '%';
        //search [your_postmeta_key] as well
        $where .= $wpdb->prepare(" OR ($wpdb->postmeta.meta_key = '[your_postmeta_key]' AND $wpdb->postmeta.meta_value LIKE %s) ", $searchstring);   
    }
    return $where;
});

//group by post ID
add_filter( 'posts_groupby', function ($groupby, $query) {

    global $wpdb;
    if(is_search() && is_admin() && $_GET['post_type'] == '[your_post_type]')
    {
        $groupby = "{$wpdb->posts}.ID";
    }
    return $groupby;

}, 10, 2 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.