7

I realize improving WordPress's search function is a huge can of worms, but the ONLY additional thing I need it to do is to show results when I search for an author's name.

For example, if we have an author named Katie Johnson, and I search for Katie, I get results where her name is listed in the CONTENT, but not results that she POSTED.

This seems like a simple problem, and yet I haven't yet found a solution to it.

Thanks.

3 Answers 3

6

Maybe you can try adding your condition directly in the query string, using something like this

function wpse_29570_where_filter($where){
        global $wpdb;
        if( is_search() ) {
            $search= get_query_var('s');
            $query=$wpdb->prepare("SELECT user_id  FROM $wpdb->usermeta WHERE ( meta_key='first_name' AND meta_value LIKE '%%%s%%' ) or ( meta_key='last_name' AND meta_value LIKE '%%%s%%' )", $search ,$search);
            $authorID= $wpdb->get_var( $query );

            if($authorID){
                $where = "  AND  ( wp_posts.post_author = {$authorID} ) ";
            }

         }
         return $where;
    }

    add_filter('posts_where','wpse_29570_where_filter');
10
  • I understand what you're trying to do here, but it unfortunately, is not working for me. This actually unsets the query string and then sets author_name to nothing. I believe the results are EVERYTHING that's been posted.
    – zack
    Sep 27, 2011 at 14:41
  • Updated my answer to something that could work better
    – hacksy
    Sep 27, 2011 at 15:44
  • 1
    I updated to this code, and it doesn't seem to be returning all the results from the user. While it does return SOME results, I'm not sure which ones its picking and which ones are being left out, or WHY. Basically, the results for a search of a user's name and the archive for that user are drastically different.
    – zack
    Sep 27, 2011 at 18:22
  • 1
    @Jake you are right :) , I guess at that time I forgot to remove that line when testing. Updated the answer
    – hacksy
    Oct 15, 2016 at 4:43
  • 2
    The $where = should probably be $where .= May 3, 2018 at 14:19
1

I couldn't get either of those answers to work for me, but I found this: https://danielbachhuber.com/2012/02/07/include-posts-by-matching-authors-in-your-search-results/

Worked without any edits. Here's the code incase the link is ever out of date:

    /**
 * Include posts from authors in the search results where
 * either their display name or user login matches the query string
 *
 * @author danielbachhuber
 */
add_filter( 'posts_search', 'db_filter_authors_search' );
function db_filter_authors_search( $posts_search ) {

    // Don't modify the query at all if we're not on the search template
    // or if the LIKE is empty
    if ( !is_search() || empty( $posts_search ) )
        return $posts_search;

    global $wpdb;
    // Get all of the users of the blog and see if the search query matches either
    // the display name or the user login
    add_filter( 'pre_user_query', 'db_filter_user_query' );
    $search = sanitize_text_field( get_query_var( 's' ) );
    $args = array(
        'count_total' => false,
        'search' => sprintf( '*%s*', $search ),
        'search_fields' => array(
            'display_name',
            'user_login',
        ),
        'fields' => 'ID',
    );
    $matching_users = get_users( $args );
    remove_filter( 'pre_user_query', 'db_filter_user_query' );
    // Don't modify the query if there aren't any matching users
    if ( empty( $matching_users ) )
        return $posts_search;
    // Take a slightly different approach than core where we want all of the posts from these authors
    $posts_search = str_replace( ')))', ")) OR ( {$wpdb->posts}.post_author IN (" . implode( ',', array_map( 'absint', $matching_users ) ) . ")))", $posts_search );
    return $posts_search;
}
/**
 * Modify get_users() to search display_name instead of user_nicename
 */
function db_filter_user_query( &$user_query ) {

    if ( is_object( $user_query ) )
        $user_query->query_where = str_replace( "user_nicename LIKE", "display_name LIKE", $user_query->query_where );
    return $user_query;
}
1
0

Improving on @hacksy's answer, I have used the same block of code but changing it to successfully search company name using the WP Job Manager plugin.

function add_author_to_search($where) {
    global $wpdb;
    if( is_search() ) { // Check if a search is made
        $search = get_query_var('s');
        $like = '%' . $wpdb->esc_like( $search ) . '%';
        $query = $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE ( meta_key='first_name' AND lower(meta_value) LIKE '%%%s%%' ) OR ( meta_key='last_name' AND lower(meta_value) LIKE '%%%s%%' ) OR ( meta_key='_company_name' AND lower(meta_value) LIKE '%%%s%%' )", $search, $search, $search);
        $authorID = $wpdb->get_var( $query );

        if ($authorID) { // If a user_id matches a user
            $where .= " OR " .$wpdb->posts. ".post_author = {$authorID} AND " .$wpdb->posts. ".post_name LIKE '" .$like. "'"; // Add to query of function: $GLOBALS[$WP_QUERY_VAR]->request
        }
     }
     return $where;
}

add_filter('posts_where','add_author_to_search');

What it does is search the meta_key column of the first_name, last_name, and _company_name values then check for a value under the meta_value to see if it matches the search query. If a user_id is found, the SQL search query is appended to search for the post_author ID and if the slug of the company is found under the post_name column.

1
  • Good call on the esc_like, but shouldn't you be using that in $query too?
    – Rup
    Apr 21, 2021 at 9:33

Your Answer

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

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