Using WP_User_Query To Get a User By Display Name

September 19, 2012 - 6 minutes read

Brian Krogsgard has recently asked a quite interesting question on Twitter that drew my attention:

Since I love challenges, especially ones that involves getting your hands dirty with code, I went on a short journey deep down into darkest places of WordPress core.

What are you talking about?

Let me explain. At first, I couldn’t believe that the WP_User_Query (Core) class does not give you an option to query users by Display Name. A quick reminder what Display Name is, since WordPress gives you 3 different ways to store user names.

  • First and Last Name
  • Nickname
  • Display Name
And this is how it looks like in the Dashboard:

So many options for… one single name!

So, you might ask “How come you can’t query users by their Display Name?”, and my answer will be — “Why the heck should I know?”. But, I don’t give up quickly. And neither should you.

Here’s the actual code, so you can get a better understanding of how it works [gist].

<?php

function maor_twitter_run_wp_user_search_query() {
	/* There's a reason we're adding the action from here, you'll see later why. */
	add_action( 'pre_user_query', 'maor_twitter_help_main' );

	/* Create a new WP_User_Query object, limit recordset to 10 */
	$wp_user_search = new WP_User_Query(
		array(
			'number' => 10
		)
	);

	/* Make sure to remove this action since it may affect other user queries around the site. */
	remove_action( 'pre_user_query', 'maor_twitter_help_main' );

	/* Get them users! */
	$users = $wp_user_search->get_results();

	/* If $users is not null or an empty array, go on */
	if ( ! empty( $users ) ) {
		foreach ( $users as $user ) {
			printf( "My display_name is %s. My ID number is %d.", $user->display_name, $user->ID );
		}
	}
}
add_action( 'init', 'maor_twitter_run_wp_user_search_query' );

function maor_twitter_help_main( $query ) {
	global $wpdb;

	/* The display_name value you're looking to match */
	$display_name = 'Coen';

	/* Search can either be for an exact match or a partial match */
	if ( $use_like_syntax = true ) {
		$query->query_where .= $wpdb->prepare( " AND $wpdb->users.display_name LIKE %s", '%' . like_escape( $display_name ) . '%' );
	} else {
		$query->query_where .= $wpdb->prepare( " AND $wpdb->users.display_name = %s", $display_name );
	}
}

Breaking It Down

The way I chose to hack the way the query works is using the pre_user_query action (It almost seems like no one is using this action, I have tried to Google it).
Right before we perform the query, we hook into pre_user_query. Basically this action will pass to the callback function the entire object (WP_User_Query) by reference, so you can easily modify its properties without the need to return it.

As a matter of searching for a Display Name, it is up to you. You can either search within the display_name (Using SQL’s LIKE), or match a value against it. So if you’re looking for Dave Coen, and you’re expecting one or more results, you might choose to go with the “equals to” option.

If you’re unsure about what the user name is and you want as many relevant results as possible, go with the LIKE syntax. Notice we’re using like_escape() for security measures. like_escape() will replace any occurrence of %‘s and _‘s with \% and \_ respectively — and all of that, my folks, is for security measures only (Never should you underestimate security — especially when it involves database queries!).

Now we just append our new query additions to $query_where which is contained within the main query object (We’re using an action, so there’s no need to return the object). Right after that, using remove_action() we remove the action we just registered moments ago, maor_twitter_help_main, because we don’t want other user queries on the site to be involved with this hack.

/* Make sure to remove this action, as it may affect other user queries around the site. */
remove_action( 'pre_user_query', 'maor_twitter_help_main' );

The rest is no different than what you’re used to. Simply loop through the results (right after checking if you have any…), and use them as you wish. I got a little creative today, so this is what I have chosen to print.

foreach ( $users as $user ) {
	printf( "My display_name is %s. My ID number is %d.", $user->display_name, $user->ID );
}

Alright, these were my 2 cents for today. Hope you have learned something new!

Be sure to visit again for more coverage on WordPress advanced topics as well as follow me on Twitter. I am constantly tweeting about new posts I write and other WordPress killer stuff.

If you have a different approach for Brian’s question, please share it in the comments. I’d be happy to learn more about it, as I am far from being perfect.

Tags: , , ,