The search form at the top of the users listing in the Admin area (wp-admin/users.php) is limited and does not search all of the user meta fields, such as bio, instant messenger handles, etc. I’ve not been able to find a plugin that can add this.
Is anyone aware of a plugin or a function I could create that could expand this search for all the date in the _usermeta DB — ideally even extra fields create by a plugin or function.
Hi @user2041:
Clearly as you know you need to modify the search that’s performed which you can do by modifying the values in the instance of the
WP_User_Search
class used for the search (you can find the source code at/wp-admin/includes/user.php
if you’d like to study it.)The
WP_User_Search
ObjectHere’s what a
print_r()
of that object looks like with WordPress 3.0.3 when searching for the term “TEST
“ and without any other plugins that might affect it:The
pre_user_search
HookTo modify the values of the
WP_User_Search
object you’ll use the'pre_user_search'
hook which receives the current instance of the object; I calledprint_r()
from within that hook to get access to its values which I displayed above.The following example which you can copy to your theme’s
functions.php
file or you can use in a PHP file for a plugin you are writing adds the ability to search on the user’s description in addition to being able to search on the other fields. The function modifies thequery_from
and thequery_where
properties of the$user_search
object which you need to be comfortable with SQL to understand.Careful Modifying SQL in Hooks
The code in the
yoursite_pre_user_search()
function assumes that no other plugin has modified thequery_where
clause prior to it; if another plugin has modified the where clause such that replacing'WHERE 1=1 AND ('
with"WHERE 1=1 AND ({$description_where} OR"
no longer works then this will break too. It’s much harder to write a robust addition that cannot be broken by another plugin when modifying SQL like this, but it is what it is.Add Leading and Trailing Spaces when Inserting SQL in Hooks
Also note that when using SQL like this in WordPress it’s always a good idea to include leading and trailing spaces such a with
" INNER JOIN {$wpdb->usermeta} ON "
otherwise your SQL query might contain the following where there is no space before"INNER"
, which would of course fail:" FROM wp_postsINNER JOIN {$wpdb->usermeta} ON "
.Use
"{$wpdb->table_name"}
instead of Hardcoding Table NamesNext be sure to always using the
$wpdb
properties to reference table names in case the site has changed the table prefix from'wp_'
to something else. Thus it is better to refer to"{$wpdb->users}.ID"
(with double quotes, not single ones) instead of hardcoding"wp_users.ID"
.Limit the Query to Only When Search Terms Exist
Lastly be to only modify the query when there is a search term which you can test by inspecting
search_term
property of theWP_User_Search
object.The
yoursite_pre_user_search()
Function for'pre_user_search'
Searching Each Meta Key-Value Pair Requires a SQL
JOIN
Of course the likely reason WordPress doesn’t let you search on usermeta fields is that each one adds a SQL
JOIN
to the query and to a query with too many joins can be slow indeed. If you really need to search on many fields then I’d create a'_search_cache'
field in usermeta that collects all the other information into one usermeta field to require only one join to search it all.Leading Underscores in Meta Keys tell WordPress Not to Display
Note that leading underscore in
'_search_cache'
tells WordPress that this is an internal value and not something to ever display to the user.Create a Search Cache with the
'profile_update'
and'user_register'
HooksSo you’ll need to hook both
'profile_update'
and'user_register'
that are triggered on saving a user and registering a new user, respectively. You can grab all the meta keys and their values in those hooks (but omit those with values that are serialized or URL encoded arrays) and then concatenate them to store as one long meta value using the'_search_cache'
key.Store Meta as
'|'
Delimited Key-Value PairsI decided to grab all the key names and all their values and concatenate them into one big string with colons (“:”) separating the keys from the values and vertical bars (“|”) separating the key-value pairs like this (I’ve wrapped them across multiple lines so you can them without scrolled to the right):
Enables Specialized Searches on Meta Using
key:value
Adding the key and values as we did allows you to do searches like “
rich_editing:true
” to find everyone who has rich editing, or search for “phone:null
” to find those with no phone number.But Beware of Search Artifacts
Of course using this technique creates possibly unwanted search artifacts such as search for “business” and everyone will be listed. If this a problem then you might not want to use such a elaborate cache.
The
yoursite_profile_update()
Function for'profile_update'
and'user_register'
For function
yoursite_profile_update()
, likeyoursite_pre_user_search()
above can be copied to your theme’sfunctions.php
file or you can use in a PHP file for a plugin you are writing:Updated
yoursite_pre_user_search()
Function enabling a Single SQLJOIN
for Searching All Interesting Meta ValuesOf course for
yoursite_profile_update()
to have any effect you’ll need to modifyyoursite_pre_user_search()
to use the'_search_cache'
meta key instead of the description, which we have here (with the same caveats as mentioned above):I really appreciated MikeSchinkel’s approach and thorough explanation above. This was super-helpful. I couldn’t get it to work for me since pre_user_search has been deprecated and doesn’t actually work in 3.2. I tried just switching it out with pre_user_query but that didn’t work either. The thing is, it seems that $user_search->search_term doesn’t work anymore so I just used $_GET[‘s’]. I did some hacking away and was able to get this to work in 3.2. The only thing you need to set is your array of searchable metadata.
Hope this helps somebody.
FYI, for people searching on this topic (how to adjust the User panel search query) and finding this excellent page, WP_User_Search has been deprecated by WP_User_Query as of 3.1: http://codex.wordpress.org/Class_Reference/WP_User_Query.
Here is a solution to newest version of wordpress.
This is what I came up with for WordPress 4.7.1 which adds the wildcard search to all user meta data.
Basically we are just joining the users and user_meta tables on the user id and rebuilding the WHERE clause to include the search on the meta_value column.