Introducing BP_User_Query

In r6314, the BP_User_Query class was introduced. BP_User_Query is a new way to query members in BuddyPress, modeled after WP_User_Query and designed to scale many, many times better than BP_Core_User::get_users(). The main function used for member queries in BuddyPress, bp_core_get_users(), has been refactored to use the new BP_User_Query by default, supporting the old BP_Core_User::get_users() as a legacy mode only. See #4060 for extensive discussion of the improvement and of the problems it’s designed to solve.

For the vast majority of BuddyPress installations, the switch to BP_User_Query will be completely seamless. The only break with backward compatibility concerns the filters 'bp_core_get_paged_users_sql' and 'bp_core_get_total_users_sql'. These filters are found in the deprecated BP_Core_User::get_users(), and are intended to allow plugins to modify the user SQL queries directly. Since BP_User_Query totally reworks the way these queries are constructed, there was no way to provide full backward compatibility.

The only two plugins in the wordpress.org plugin repository that use the filters in question are Achievements (by @djpaulgibbs) and BP Better Directories (by me), and they will be refactored to use BP_User_Query by the time BP 1.7 is marked stable.

If you’ve never heard of these filters, or you are certain that you’ve never used them, you can stop reading right now. Go svn up and have fun!

If you have used these filters to customize the SQL queries on a private project, you will need to take action before BP 1.7 is released. You have two options. (I’ll write up detailed examples on the Codex over the upcoming days and weeks – this is just a primer.)

  1. Rewrite your filters. BP_User_Query is designed to be flexible with respect to this kind of customization, so you have several options, depending on what your filters do. If you are adding more WHERE clauses to further limit the members returned by the queries, do the following: Run your own separate SQL query for those WHERE clauses, use the new pre-filter on query parameters – bp_pre_user_query_construct – and add the results of your query to the ‘exclude’ or ‘include’ parameters, as appropriate. If your filters are designed to change user ordering as well as limit the results returned, you can override BP_User_Query‘s user id query by passing a list of user ids to the ‘user_ids’ parameter. Neither of these methods require you to touch any of BP’s core SQL clauses – a major improvement. And if you need to do something even more customized, you can still modify the SQL directly, by using the bp_pre_user_query hook and manipulating the $uid_clauses array.
  2. If you are unable or unwilling to refactor your filters appropriately, you can force BP to use the legacy BP_Core_User::get_users() for user queries by filtering 'bp_use_legacy_user_query' and returning true. (Note that doing so will forgo the performance improvements of BP_User_Query. I don’t recommend using the legacy query if you can help it.)

Questions or concerns? Please leave a comment here. Found a bug? Please report it on Trac.