Question

I need to create a search page that will display anything related to the supplied search. i.e. comments containing it, events, posts, CPTs and users with that name.

How can I search for users in the site who's first or last name contains the search phrase ?

Was it helpful?

Solution

Searching the main table

Simply use WP_User_Query with a search argument.

So if you want to search for example for a user with a keyword in his user_email or similar columns from the {$wpdb->prefix}users table, then you can do the following:

$users = new WP_User_Query( array(
    'search'         => '*'.esc_attr( $your_search_string ).'*',
    'search_columns' => array(
        'user_login',
        'user_nicename',
        'user_email',
        'user_url',
    ),
) );
$users_found = $users->get_results();

Keep in mind that * is a wildcard. So restricting for example the user_email to a single domain would give you the following search string: *@example.com.

The search string has some "magic" features: The search_columns defaults to...

  • user_email if @ is present in the search arg.
  • user_login and ID if the search arg is numeric
  • user_url if the search string contains http:// or https://
  • or ... user_login and user_nicename if a string is present.

All those defaults are only set if no search_columns argument was specified.

Searching the meta table

If you want to search by for example first_name or last_name, then you'll have to do a meta_query as they're not part of the main table:

$search_string = esc_attr( trim( get_query_var('s') ) );
$users = new WP_User_Query( array(
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $search_string,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $search_string,
            'compare' => 'LIKE'
        )
    )
) );
$users_found = $users->get_results();

Make sure you retrieve the right search string. Normally that would be get_query_var('s');, but it could - depending on your form name/id as well be something different that you might want to retrieve using $_GET['user_search'] for example. Make sure to properly esacpe it and remove unwanted white space from the beginning and end of the string.

Keep in mind that this is an array( array() ) as there's the relation key. If you just want to have a single key searched, it might be easier to just go with the following:

$search_string = esc_attr( trim( get_query_var('s') ) );
$users = new WP_User_Query( array(
    'meta_key'     => 'first_name',
    'meta_value'   => $search_string,
    'meta_compare' => 'LIKE',
) );
$users_found = $users->get_results();

Final query

The result might look close to the following:

$search_string = esc_attr( trim( get_query_var('s') ) );
$users = new WP_User_Query( array(
    'search'         => "*{$search_string}*",
    'search_columns' => array(
        'user_login',
        'user_nicename',
        'user_email',
        'user_url',
    ),
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $search_string,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $search_string,
            'compare' => 'LIKE'
        )
    )
) );
$users_found = $users->get_results();

OTHER TIPS

This helped me instead of kaiser's answer: https://laubsterboy.com/blog/2015/07/search-wordpress-users-by-name/

But in this solution $wpdb->escape($usermeta_keys) function generated an error, so I simply used $usermeta_keys.

Custom solution

I know my answer is late, but i was looking for the same thing and build it with some help of @kaiser his answer. I'm only going to display the title, link and excerpt/user email, but you can expand this in the way you want offcourse.

Custom array

I started by creating an empty array:

$search_results = array();

User search

Then moved on with the 'WP_User_Query' which uses the user-input ($search_results) for filtering.

$search_string = esc_attr( trim( get_query_var('s') ) );
$users = new WP_User_Query( array(
    'search'         => "*{$search_string}*",
    'search_columns' => array(
        'user_login',
        'user_nicename',
        'user_email',
        'user_url',
    ),
) );

Fill our array with user data

Now we gonna fill this query in our empty ($search_results) array.

if (!empty($users->results)) :
    foreach ($users->results as $user => $value) :
        $tmp_array = array();
        $data = $value->data;
        $user_id = $data->ID;
        $tmp_array['link'] = get_the_author_link($user_id); 
        $tmp_array['text'] = $data->user_url;
        $tmp_array['title'] = $data->display_name;
        $search_results[] = $tmp_array;
    endforeach;
endif;

Fill our array with post/page data

We also want the 'normal' search form that searches for pages and post to still work, so we need to loop over this as well. While we do this, we are also gonna fill our ($search_results) array with this data:

$query_string = esc_attr($query_string);
$search = new WP_Query($query_string);
if ( $search->have_posts() ) :
    while ( $search->have_posts() ) : $search->the_post();
        $tmp_array = array();
        $tmp_array['link'] = get_the_permalink();; 
        $tmp_array['title'] = get_the_title();
        $tmp_array['text'] = get_the_excerpt();
        $search_results[] = $tmp_array;
    endwhile;
endif;

Loop over our array

Now we have an array that contains user info and post/page details. The last thing we need to do now is looping over it, so the user sees the results he searched for:

<?php if(!empty($search_results)): ?>
    <?php foreach ($search_results as $result) : ?>
        <a class="search-item" href="<?php echo $result['link']; ?>">
            <h2 class="search-title"><?php echo $result['title']; ?></h2>
            <span class="search-text"><?php echo $result['text']; ?></span>
        </a>
    <?php endforeach; ?>
<?php else: ?>
<div class="nothing-found">
    <h3><?php echo 'No results found.'; ?></h3>
</div>
<?php endif; ?>

Done!

Recently when I was working on a large scale project, my clients were facing problems while searching users with their first name, last name, business name/company name.

So I thought, lets create a plugin and combine my front-end skills with Php. I decided to go with VueJs and Axios to accomplish my mission.

https://wordpress.org/plugins/robust-user-search/

This plugin allow users to search by : Username, First name, Last name, Email or Business Name.

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top