Skip to:

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#3068 closed task (blessed) (fixed)

User engagements

Reported by: johnjamesjacoby's profile johnjamesjacoby Owned by: thebrandonallen's profile thebrandonallen
Milestone: 2.6 Priority: normal
Severity: normal Version: 0.7.2
Component: API - Engagements Keywords: has-patch


We've kept a count of unique user voices since the early days of bbPress. What we haven't done is keep an actual running tally of the user IDs themselves, to see what topics they've engaged in.

With the User Relationships API now in trunk, we can do this relatively easily.

Things to do:

  • Lift the base functionality from favorites & subscriptions
  • Hook it all in to new topic & reply creation
  • Only update voice counts when engagement changes

I'll attach a first-pass patch shortly.

Attachments (4)

bbpress-engagements.patch (11.3 KB) - added by johnjamesjacoby 7 years ago.
3068.1.voice_count_bump_functions.diff (7.3 KB) - added by thebrandonallen 7 years ago.
3068.1.voice_count_repair_upgrade_queries.diff (3.7 KB) - added by thebrandonallen 7 years ago.
3068.1.hooked_voice_count_update.diff (2.1 KB) - added by thebrandonallen 7 years ago.

Download all attachments as: .zip

Change History (37)

#1 @johnjamesjacoby
7 years ago

  • Owner set to thebrandonallen
  • Type changed from defect to task

#2 @johnjamesjacoby
7 years ago

In 6311:

Engagements: First pass at engagement user functions.

Also update favorite/subscription documentation where inaccurate.

See #3068.

#3 @johnjamesjacoby
7 years ago

  • Component changed from Component - Topics to API - Engagements
  • Keywords commit added; has-patch needs-refresh removed

First pass at the Engagements API imminent.

cc @thebrandonallen

#4 @johnjamesjacoby
7 years ago

In 6320:

Engagements: First pass at:

  • User profile section
  • Template parts changes
  • Rewrite rules support
  • Repair & upgrade tools
  • BuddyPress support
  • engagement slug setting

See #3068.

#5 @johnjamesjacoby
7 years ago

In 6321:

Engagements: Allow engagements to be toggled on/off, for forums that have not run the upgrade routine yet.

Also missed a spot in the BuddyPress integration.

See #3068.

#6 @johnjamesjacoby
7 years ago

In 6322:

Engagements: Add bbp_is_engagements_active to default options array.

See #3068.

#7 @johnjamesjacoby
7 years ago

In 6323:

Engagements: Fix copy/paste error in r6322.

See #3068.

#8 @johnjamesjacoby
7 years ago

In 6324:

Engagements: Prefer bbp_admin_upgrade_user_engagements() over the old repair tool.

See #3068.

#9 @johnjamesjacoby
7 years ago

In 6326:

Engagements/BuddyPress: Finish integration, and clean-up favorites & subscriptions support.

See #3068.

#10 @johnjamesjacoby
7 years ago

In 6327:

Engagements/BuddyPress: Add @since for changes in 2.6.0, and a bit more clean-up.

See #3068.

#11 @johnjamesjacoby
7 years ago

In 6330:

Engagements: Updates existing functions & unit tests:

  • Correct tests so that post_author of 0 does not get included in the overall count
  • Add user IDs to all topics & replies where voice counts are being tested
  • Update voice-count update function to use the new user-relationships API
  • Clean-up topic merge code to more efficiently migrate favorites, subscriptions, and engagements

See #3068.

#12 @johnjamesjacoby
7 years ago

In 6332:

Engagements: First pass at a user_query, which will be used for looping through users.

  • Introduces BBP_User_Query which extends WP_User_Query
  • Includes functions for use within template parts

See #3068.

#13 @johnjamesjacoby
7 years ago

In 6334:

Engagements: Integrate the user_query into favorites, subscriptions, and engagements.

  • Add to admin metabox avatar loops
  • Fix a few bugs in BBP_User_Query, and include a custom constructor to set the loop counter

See #3068.

#14 @thebrandonallen
7 years ago

  • Keywords has-patch added; commit removed

Finally had a chance to go over this.

3068.1.voice_count_bump_functions.diff introduces voice count bumping functions, and some "maybe" update functions. These are then used to move the call to bbp_update_topic_voice_count() mostly out of bbp_update_reply_walker() and onto bbp_new_reply|bbp_{action}_reply hooks.

Using the "maybe" update functions prevents all the database churn caused by deleting/re-adding all _bbp_engagement post meta. There's no real raw performance boost here (about .05 seconds faster), but those with busy forums should see a lift. The maybe update functions only act on a single _bbp_engagement post meta item, and they only do this when absolutely needed.

I'm fine if we don't do this, but either way I'd like to see the update voice count function on a hook. I've got some ideas to get rid of all of the

if ( in_array( current_filter(), array( 'bbp_deleted_reply', 'save_post' ), true ) ) {
    // Update counts.

checks as well. Those will be on a separate ticket.

#15 @thebrandonallen
7 years ago

Attached patch 3068.1.voice_count_repair_upgrade_queries.diff improves the voice count repair/upgrade queries.


  • Adds a GROUP BY clause to weed out duplicate engagement entries for each topic
  • Removes unnecessary ORDER BY statement from when I was testing
  • Rename $voice_id_sql to $engagements_sql to better reflect what's actually contained


  • Adds a GROUP BY clause to weed out duplicate engagement entries for each topic
  • Use a single wpdb::query() rather than wpdb::get_results(), loop through each item, check its existence, add_post_meta(), then bump the updated count. wpdb::query() allows us to do all this in one take.

#16 @johnjamesjacoby
7 years ago

In 6340:

Engagements: Improve efficiency of upgrade & repair tools.

Props thebrandonallen. See #3068.

#17 @johnjamesjacoby
7 years ago

Awesome! Thanks for these. r6340 is a nice improvement, but I just had a thought after I reviewed it.

If we upgrade engagements this way, we aren't busting the post caches of each topic that's receiving the new _bbp_engagement meta keys. So, I think we'll still want to loop through them, or we need a way to invalidate the correct topic caches and their associated meta-data caches.

#18 @johnjamesjacoby
7 years ago

And getting rid of the current_filter() stuff would be nice.

#19 @thebrandonallen
7 years ago

Attached patch, 3068.1.hooked_voice_count_update.diff, moves bbp_update_voice_counts() to hooks, as a safer alternative to 3068.1.voice_count_bump_functions.diff.

#20 @johnjamesjacoby
7 years ago

  • Resolution set to fixed
  • Status changed from new to closed

In 6369:

Engagements: Move engagement count updates to action hooks.

Props thebrandonallen. Fixes #3068.

#21 @johnjamesjacoby
7 years ago

In 6516:

Engagements: Update bbp_update_topic_voice_count() to only count the number of existing engagements.

Recalculating the entire engagement tree for each topic is costly, should be done in its own dedicated function, and then only hooked in or executed when absolutely necessary.

This is easier to do with the engagements API that's new in 2.6. Recalculation function imminent.

See #3068.

#22 @johnjamesjacoby
7 years ago

In 6517:

Engagements: Introduce bbp_remove_user_from_all_objects().

This is useful for when a user is permanently deleted, or when all of their relationship(s) (of a certain type) need to be removed.

See #3068.

#23 @johnjamesjacoby
7 years ago

In 6518:

Engagements: Update bbp_add_user_object().

  • New phpdoc description
  • Add $unique parameter and default to true (this differs from the normal false default of add_metadata() because, by default, this API assumes no 1 user can have multiple relationships with the same object)
  • Pass $unique into apply_filters()

See #3068.

#24 @johnjamesjacoby
7 years ago

In 6519:

Moderators: Add an $object_type parameter to add/remove/delete functions.

In a future release, this will more easily allow objects like taxonomy-terms to have their own moderators, and is also necessary for future enhancements to the support forums where custom taxonomies are used for prevalently than in bbPress core currently.

See #3068, #459.

#25 @johnjamesjacoby
7 years ago

In 6520:

Engagements: Updates to phpdoc & helper functions.

  • New function to remove all users from an object
  • New function to remove all users from all objects
  • Remove references to taxonomy term storage (from original implementation)
  • Update phpdoc with more accurate descriptions of intended parameter usages

See #3068.

#26 @johnjamesjacoby
7 years ago

In 6521:

Engagements: Update phpdoc for bbp_add_user_to_object().

  • Replace add_post_meta() with add_metadata()

See #3068.

#27 @johnjamesjacoby
7 years ago

In 6522:

Engagements: Introduce 2 new functions for recalculating engagements.

  • bbp_get_topic_engagements_raw() to efficiently query for users who have engaged in a topic
  • bbp_recalculate_topic_engagements() to update all of the related meta-data

See #3068.

#28 @johnjamesjacoby
7 years ago

In 6525:

Engagements: Tracking is not just for public or closed topics.

This commit updates the engagement upgrade tool and recalculation helper functions to not be limited to public & closed post statuses. Engagements can happen on private or hidden topics also, including trash, spam, and so on.

The non-visible topics that a user is engaged in should be filtered out as needed when queried based on post_status or other various meta-data.

See #3068.

#29 @johnjamesjacoby
7 years ago

In 6529:

Engagements: Keep topic engagement counts up-to-date.

This changes the way the old 'voice count' works with the new engagements API in the following ways:

  • Introduce new function to update voice count meta when necessary
  • Modify recalculation function with a $force parameter, and only recalculate the counts when the engagements have changed by default
  • Hook the above functions in where appropriate, largely when deleting replies (this is a unique case where a fully deleted reply needs to check if the author of the current reply has a previously public reply in that same topic already, which should not trigger a recalculation.)
  • We are silently moving the bbp_delete_ actions onto the before_delete_post hook, so that all term & meta-data is available to them (which helps with race conditions mentioned in r6528)

Engagements are now hooked in and listening in the most efficient way possible, at least until a common & shared walker is introduced for the entire tree.

See: #3068.

#30 @johnjamesjacoby
7 years ago

In 6530:

Engagements: Update topic engagements when they are manually inserted.

This brings the _insert_ functions up to date with the _new_ equivalents.

See: #3068. Props netweb & unit-tests for catching this.

#31 @johnjamesjacoby
7 years ago

In 6534:

Engagements: Revert part of r6525, and adjust some actions.

  • Engagements will need to be "public only" for 2.6, and we can reconsider what private/hidden engagements look like later
  • Make sure that engagements are saved before voice counts are done
  • Use new is_public style wrapper function for topics & replies where appropriate
  • Remove a few current_filter() checks that should no longer be necessary with current action hook implementation
  • There may be more clean-up necessary here, but this is required to bring all unit-tests back to passing as they've been written, specifically things hooked to the bbp_insert_topic and bbp_insert_reply hooks

See #3068. Hat-tip netweb.

#32 @johnjamesjacoby
7 years ago

In 6723:

Engagements: abstract meta strategy into an overload'able class.

This change introduces a class and wrapper function to allow the meta strategy of the new user engagements API to be hot-swapped. This might be helpful on large installations where a dedicated database table makes more sense, or for integrations where features like "Favorites" or "Subscriptions" might already be delegated to other third-party membership plugins. Now, the caller class can be filtered to one that includes custom methods.

See #3068.

#33 @johnjamesjacoby
7 years ago

In 6725:

Subscriptions: Introduce bbp_get_email_addresses_from_user_ids() to chunk get_users() calls.

This changes the strategy used when querying for subscribed users so that not of them are queried at the same time, which could cause timeouts or out-of-memory issues when there are many users subscribed to a forum or topic.

By default, users are now queried in 100 user increments, and each 100 user chunk of email addresses gets merged into 1 large array and returned. The 100 default also has a filter, so it's somewhat configurable. Duplicate email addresses are strictly avoided, and user ID filters were moved to after the current user ID is removed from the array, which allows for third party plugins to add them back in if they'd like to include them.

See #3068.

Note: See TracTickets for help on using tickets.