Opened 5 weeks ago
Last modified 3 weeks ago
#9328 assigned enhancement
Enhancement Request: Add query filter hooks to `BP_Messages_Thread::get_current_threads_for_user()`
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 15.0.0 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Messages | Keywords: | has-patch |
| Cc: |
Description (last modified by )
The Gap
BuddyPress's activity component has excellent query-level extensibility:
From BP_Activity_Activity::get() — lines 666, 682
$where_conditions = apply_filters( 'bp_activity_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql ); $join_sql = apply_filters( 'bp_activity_get_join_sql', $join_sql, $r, $select_sql, $from_sql, $where_sql );
These filters allow any addon to inject WHERE clauses and JOINs into the main activity query without modifying core. BuddyBoss's moderation system, for example, hooks into bp_activity_get_where_conditions to hide suspended content — all from addon-level code.
The messages component has no equivalent. BP_Messages_Thread::get_current_threads_for_user() builds its SQL in a $sql array (lines 790–794) and executes it directly:
$sql['select'] = 'SELECT m.thread_id, MAX(m.date_sent) AS date_sent';
$sql['from'] = "FROM {$bp->messages->table_name_recipients} r INNER JOIN {$bp->messages->table_name_messages} m ON m.thread_id = r.thread_id {$meta_query_sql['join']}";
$sql['where'] = "WHERE {$deleted_sql} {$user_id_sql} {$sender_sql} {$type_sql} {$search_sql} {$meta_query_sql['where']}";
$sql['misc'] = "GROUP BY m.thread_id ORDER BY date_sent DESC {$pag_sql}";
$thread_ids = $wpdb->get_results( implode( ' ', $sql ) );
The only filter (bp_messages_thread_current_threads) fires AFTER the query on the fully-constructed result set (line 841) — meaning addons must filter in PHP, not SQL. This is:
- A performance problem — filtering in PHP means fetching rows from the database that will be discarded, and constructing full
BP_Messages_Threadobjects for threads that are then thrown away. This gets worse as thread count grows. - An extensibility gap — addons that need custom thread filtering (archiving, priority inbox, moderation, read/unread management) have no clean way to modify the query
- Inconsistent with the activity API — activity has comprehensive pre-query filters; messages doesn't
Proposed Change
Add filter hooks to get_current_threads_for_user() before query execution, following the pattern established by BP_Activity_Activity::get():
After building $sql array (around line 794):
/**
* Filters the WHERE SQL for the current threads query.
*
* @since {next_version}
*
* @param string $where_sql Current WHERE clause.
* @param array $r Parsed query arguments.
* @param string $select_sql Current SELECT clause.
* @param string $from_sql Current FROM clause (includes JOINs).
*/
$sql['where'] = apply_filters( 'bp_messages_thread_get_where_conditions', $sql['where'], $r, $sql['select'], $sql['from'] );
/**
* Filters the FROM/JOIN SQL for the current threads query.
*
* @since {next_version}
*
* @param string $from_sql Current FROM clause (includes JOINs).
* @param array $r Parsed query arguments.
* @param string $select_sql Current SELECT clause.
* @param string $where_sql Current WHERE clause.
*/
$sql['from'] = apply_filters( 'bp_messages_thread_get_join_sql', $sql['from'], $r, $sql['select'], $sql['where'] );
Note on parameter style: In BP_Activity_Activity::get(), the WHERE conditions are passed as an array (joined to a string after the filter), whereas in the messages method they are already a string. This proposal preserves the existing messages code structure and filters the string directly, which is the minimal-change approach. If BP maintainers prefer, the messages SQL could also be refactored to use an array of conditions for parity with activity — but filtering the string is sufficient for all the use cases described below.
Scope
- ~12 lines added to one file (
class-bp-messages-thread.php) - Zero behavioral change — the filters pass through existing values by default
- Follows the pattern established by the activity component's existing filters
- The existing
bp_messages_thread_current_threadspost-query filter continues to work as-is
What This Enables for Addons
With these hooks, addon plugins can implement:
- Message archiving — Add
is_hiddencolumn tobp_messages_recipients, filterWHEREto excluder.is_hidden = 1 - Message soft-delete — Add
is_deletedcolumn tobp_messages_messages, filterFROM/JOINto exclude deleted messages from thread listing - Content moderation — Inject suspend/block conditions into thread queries
- Priority inbox — Filter by custom meta or thread properties
- Group messaging — Filter threads by group membership context
None of these features require core changes — they just need the ability to modify the query, which activity already provides but messages doesn't.
Prior Art
BuddyBoss Platform needed exactly these extension points. Because the hooks don't exist in BuddyPress core, BuddyBoss had to:
- Restructure
get_current_threads_for_user()entirely — they replaced it with a delegating call to a newget_threads_for_user()method containing ~400 lines of rewritten SQL logic - Add
is_hiddenandis_deletedcolumns directly into the restructured query conditions - Add their own filter hooks —
bp_messages_recipient_get_where_conditionsandbp_messages_recipient_get_join_sql— with signatures functionally identical to what this proposal suggests
The fact that BuddyBoss independently arrived at the same solution (pre-query filter hooks on the messages SQL) validates the need. If these hooks had existed in BuddyPress core, BuddyBoss could have achieved the same result from addon-level code without forking the class.
I'm happy to submit a PR for this change.
Attachments (1)
Change History (5)
#1
@
5 weeks ago
- Component changed from Core to Messages
- Description modified (diff)
- Summary changed from Feature Request: Add query filter hooks to `BP_Messages_Thread::get_current_threads_for_user()` to Enhancement Request: Add query filter hooks to `BP_Messages_Thread::get_current_threads_for_user()`
- Version 14.4.0 deleted
#2
@
5 weeks ago
- Description modified (diff)
Edited the description for readability. Slightly modified the Summary.
For reference, this started as a support forum topic, see Add query filter hooks to `BP_Messages_Thread::get_current_threads_for_user()`