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.)
- 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
WHEREclauses 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 overrideBP_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 thebp_pre_user_queryhook and manipulating the $uid_clauses array. - 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 returningtrue. (Note that doing so will forgo the performance improvements ofBP_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.
David Bisset 3:07 am on September 7, 2012 Permalink |
Saw “BP_User_Query” on @bptrac and i went “hhmmmm…”. Very cool and love to see how this speeds things up and scales.
Boone B. Gorges 3:09 am on September 7, 2012 Permalink |
Check out https://buddypress.trac.wordpress.org/ticket/4060 to see some of the numbers – it’s really a huge improvement. And the parallel structure to WP_User_Query is going to make it way more approachable for WP developers. Win!
imath 3:55 am on September 7, 2012 Permalink
Wow!! Simply amazing !! Great work : “bravo”
David Bisset 12:46 pm on September 7, 2012 Permalink
Those numbers are certainly impressive. And it looks like backwards compatibility is good as well.
Ray 4:07 am on September 24, 2012 Permalink |
Was just doing a little testing on a few custom BP loops on a displayed user’s page.
I found that if you previously only used the “
include” parameter in the members loop or activity loop, in BP 1.7, you’ll also need to add “user_id=0” to your querystring.The reason why is If you don’t set “
user_id“, then BP will automatically populate that with the displayed user’s ID, which is not what we want.So here’s an example:
Boone B. Gorges 12:44 pm on September 24, 2012 Permalink |
Crud. Will you open a bug ticket, Ray?
Ray 7:17 am on September 26, 2012 Permalink
This isn’t really a new bug per se; this is actually caused by the BP loops trying to be “smart” by autopopulating the “
user_id” parameter if on a displayed user’s page.eg. https://buddypress.trac.wordpress.org/browser/trunk/bp-activity/bp-activity-template.php#L315
https://buddypress.trac.wordpress.org/browser/trunk/bp-members/bp-members-template.php#L277
I’ve had a bit of an issue with this in the past with trying to use another members loop as a widget on a displayed user’s page and had to workaround this.
The problem with potentially removing this
user_idautopopulation is plugins that rely on this functionality.One way of working around this is to do a check in BP_User_Query. See if the
includeparameter is passed and if so, we hardcodeuser_idto0.How does that sound, Boone?
BuddyPress 1.7 - LightSpeed 7:09 am on April 11, 2013 Permalink |
[...] http://bpdevel.wordpress.com/2012/09/07/introducing-bp_user_query/ [...]