Group queries have been rewritten for BP 2.7

BuddyPress 2.7 will introduce a number of major changes to the code that underlies group queries – specifically, BP_Groups_Group::get(). Most of these changes will be invisible to users and developers, but anyone using filters to modify the underlying SQL may experience backward compatibility breaks in certain cases.

The main motivator for the changes is performance. Over the past few releases, BuddyPress has been following WordPress in moving its object queries to the “split” model, where one query gets the IDs matching the query parameters, and the second query gets the objects corresponding to the matched IDs. Split queries are generally less memory-intensive, and make it easier to phase in various improvements to caching. The changes we’ve made for BP 2.7 should lead to a huge performance improvement on sites using persistent caching; when querying groups, not only are group objects now fetched from the cache when available, but the ID queries themselves are cached as well. See 5451 for more information.

All normal uses of the bp_has_groups() stack, including groups_get_groups() and BP_Groups_Group::get(), should be 100% backward compatible. Plugins that use the bp_groups_get_total_groups_sql or bp_groups_get_paged_groups_sql filters may require an update for BP 2.7 compatibility. Filter callbacks will break in the following cases:

  • The callback assumes the old comma-separated JOIN syntax: SELECT ... FROM wp_bp_groups g, wp_bp_groups_groupmeta gm1 .... The SQL now uses the more verbose JOIN syntax: SELECT ... FROM wp_bp_groups g JOIN wp_bp_groups_groupmeta gm ON ( g.id = gm.group_id ) ...
  • The callback assumes SELECT * instead of SELECT id
  • The callback requires access to the groupmeta tables that were previously joined for ‘last_activity’ and ‘total_member_count’ (gm1 and gm2). These tables are now only JOINed during the main query when required by the type or orderby parameter. Access to the last_activity and total_member_count properties of group objects is unchanged.
  • The callback expects the second parameter – the $sql array – to have a specific format. Previously, the $sql array had keys that corresponded to various WHERE conditions, but the array was assembled haphazardly, and some values were not included. Now, the top-level items in the $sql array are the main clauses of the SQL query (‘select’, ‘from’, ‘where’, etc) and the WHERE conditions are grouped in the $sql['where'] key. If your plugin filters the SQL string conditionally – for example, when performing a search – you are encouraged to use the third parameter, the $r array of arguments passed to the query method, as the canonical source for query information.

In this comment, I outlined a list of plugins from GitHub and wordpress.org that may be affected by the change. If you see your name on that list, consider yourself pinged.

Though it shouldn’t result in any backward compatibility breaks (except in cases of odd type checking), it’s also worth noting that items returned from BP_Groups_Group::get() are now BP_Groups_Group objects.

Questions about the new query format, or how to make your plugin compatible with BP 2.7? Please leave comments in this thread.

#2-7, #groups