Posting Activity from Plugins
bp_activity_add()
This function was introduced in BuddyPress 1.1, it’s located in /bp-activity/bp-activity-functions.php at line 997 (version 1.7-beta1). It needs an array of arguments and returns the activity id once created by the method BP_Activity_Activity::save()
BuddyPress uses some aliases to call this function from its different components as detailed in this chart :
Functions | Components | Types | @uses |
---|---|---|---|
bp_activity_post_update() | activity | activity_update | bp_activity_add() |
bp_activity_new_comment() | activity | activity_comment | |
bp_xprofile_new_avatar_activity() | xprofile | new_avatar | |
bp_core_new_user_activity | xprofile | new_member | |
friends_record_activity() | friends | friendship_accepted friendship_created |
|
groups_record_activity() | groups | created_group joined_group new_forum_topic new_forum_post |
|
bp_blogs_record_activity() | blogs | new_blog new_blog_post new_blog_comment |
In the following chart, the array of arguments the function bp_activity_add() needs is detailled :
Arguments | Default value | Explanation |
---|---|---|
id | false | If an id is passed, then the activity will be updated with the value of other arguments |
action | ” | The activity action – e.g. “Jon Doe posted an update” |
content | ” | The content of the activity item e.g. “BuddyPress is awesome guys!” |
component | false | The identifier of the component (groups, activity, blogs, xprofile) |
type | false | The activity type e.g. activity_update, joined_group, new_member… |
primary_link | ” | The primary URL for this item |
user_id | bp_loggedin_user_id() | The user to record the activity for. |
item_id | false | The id of the specific item being recorded, e.g. a group_id |
secondary_item_id | false | A second id used to further filter e.g. a topic_id |
recorded_time | bp_core_current_time() | The GMT time that this activity was recorded |
hide_sitewide | false | If true, the activity will be hidden from the sitewide activity |
is_spam | false | Is this activity item to be marked as spam? |
The hide_sitewide argument is responsible for the visibility of the activity. If set to true, the activity won’t show in the sitewide activities (Activity Directory).
It means the activity will be “private” and only visible for the logged in user when viewing his profile activities (if the argument user_id is the logged in user id) and for the displayed hidden or private group when viewing its activity page (if the component argument is ‘groups’ and the argument ‘item_id’ is the one of the group displayed.
Hooking Activities in plugins.
If the Activity component is active ( bp_is_active( ‘activity’ ) ), it can be interesting to hook the bp_activity_add function to fire some actions just after the activity has been recorded. It informs us about what just happened. For instance, we could automate a mail to inform the community admin of the creation of new groups :
function bp_plugin_hook_activity_add( $args ) { // sends an email to admin to inform him of a group creation if( $args['type'] == 'created_group' ) wp_mail( get_option( 'admin_email' ), 'New group!', $args['action'], 'Content-Type: text/html' ); } add_action( 'bp_activity_add', 'bp_plugin_hook_activity_add', 10, 1 );
The advantage in this case is that we take benefit of the action argument to get some useful information such as the group creator and the permalink to the group. Of course, if the Activity component is not active, then we need to hook ‘groups_group_create_complete’ and build a mail thanks to the group_id that this hook comes with.
In the Activity component, the 2 aliases ( bp_activity_post_update & bp_activity_new_comment ) have their own hooks, so we can rely on them to be sure, for instance in the first case, an activity update has just been recorded.
function bp_plugin_hook_activity_posted_update( $content, $user_id, $activity_id ) { // this is a silly example : just to illustrate !! $activity_count = get_user_meta( $user_id, 'silly_activity_counter' ); $activity_count = empty( $activity_count ) ? 1 : intval( $activity_count ) + 1 ; update_user_meta( $user_id, 'silly_activity_counter', $activity_count ); } add_action( 'bp_activity_posted_update', 'bp_plugin_hook_activity_posted_update', 10, 3 );
Of course we could use an equivalent function to count the activity comments of a user by relying on the ‘bp_activity_comment_posted’ hook.
Concerning, the other aliases, we need to hook bp_activity_add(). So we’ll have to check for the component argument or the type argument in order to, for instance, add some actions in case of a new topic update or more globally of a group update.
function bp_plugin_hook_group_activity( $args ) { if( $args['type'] == 'new_forum_topic' ) // a new topic has been posted !! if( $args['component'] == 'groups' ) // a new group update has been posted !! } add_action( 'bp_activity_add', 'bp_plugin_hook_group_activity', 11, 1 );
Once again, as explained earlier, if the activity component is not active, and if you need to fire some actions, for the different types (in other words events) listed in the first chart, you’ll need to rely on other hooks (e.g. : ‘groups_group_create_complete’, ‘bp_core_activated_user’…). But It’s an article about playing with activities, so i’ll focus on it 😉
Finally we can hook an activity before it has been saved. Although i discourage its use to modify the value of the activity arguments, community admins can use a particular hook to neutralize some mini activities if they wish to. Mini activities don’t have content and are used to log simple events such as the creation of a group, the fact that a member became a member of a group, etc. Lately, i was asked how to avoid recording activities when members are becoming friends or when a member joins a group. This can be achieve by hooking ‘bp_activity_before_save’.
function bp_plugin_dont_save_minis( $activity_object ) { // friendship_created is fired when a member accepts a friend request // joined_group is fired when a member joins a group. $exclude = array( 'friendship_created', 'joined_group'); // if the activity type is empty, it stops BuddyPress BP_Activity_Activity::save() function if( in_array( $activity_object->type, $exclude ) ) $activity_object->type = false; } add_action('bp_activity_before_save', 'bp_plugin_dont_save_minis', 10, 1 );
Recording activities for a custom component.
Well it’s quite easy, we just need to use the function bp_activity_add() and to customize its arguments regarding our component need.
function bp_plugin_record_activity() { $activity_id = bp_activity_add( array( 'action' => 'bp plugin action', 'content' => 'bp plugin content', /* the component argument will be set to our component's identifier */ 'component' => 'bp_plugin', /* the type argument will be set to our component's type */ 'type' => 'bp_plugin_update', ) ); return $activity_id; }
Now to take a full benefit of our custom activities, we also need to customize the available options of the activity filters that are located in the sitewide Activity directory, in the user’s profile activity page and in the group’s activity page :
function bp_plugin_activity_filter() { ?> <option value="bp_plugin_update"><?php _e( 'BP plugin update' ); ?></option> <?php } // Activity Directory add_action( 'bp_activity_filter_options', 'bp_plugin_activity_filter' ); // member's profile activity add_action( 'bp_member_activity_filter_options', 'bp_plugin_activity_filter' ); // Group's activity add_action( 'bp_group_activity_filter_options', 'bp_plugin_activity_filter' );
We should also think about the very nice admin interface introduced in BuddyPress 1.6. To customize its activity types filter, we just need to register our plugin type by hooking ‘bp_register_activity_actions’ :
function bp_plugin_activity_actions() { $bp = buddypress(); /************************************************************************** for the purpose of this tutorial we arbitrary set the $bp->component->id !important you have to use the BP_Component class to do so See : https://codex.buddypress.org/bp_component/ ***************************************************************************/ $bp->bp_plugin = new stdClass(); $bp->bp_plugin->id = 'bp_plugin'; // Bail if activity is not active if ( ! bp_is_active( 'activity' ) ) return false; bp_activity_set_action( $bp->bp_plugin->id, 'bp_plugin_update', __( 'BP plugin update' ) ); } add_action( 'bp_register_activity_actions', 'bp_plugin_activity_actions' );
Finally if your component’s plugin deals with a custom post type, you can also take benefit of the Site Tracking component to automatically record an activity. Personaly, in this case, i prefer to build my own function to control the activity arguments. But you could filter the hooks ‘bp_blogs_record_post_post_types’ and ‘bp_blogs_record_comment_post_types’ in order to generate an activity with a type argument of “new_blog_post” when a custom post type is published and of “new_blog_comment” when a comment is posted on your custom post type.
function bp_plugin_custom_post_type( $post_type ) { $post_type[] = 'bp_plugin_post_type'; return $post_type; } add_filter( 'bp_blogs_record_post_post_types', 'bp_plugin_custom_post_type', 10, 1); add_filter( 'bp_blogs_record_comment_post_types', 'bp_plugin_custom_post_type', 10, 1);
Fully enjoy bp_activity_set_action()
In the previous section, you’ve seen how to use this function to add the custom plugin activity action to the dropdown filters of the Activity Administration screens.
Since BuddyPress 2.0 and 2.1, this function has evolved and has now 3 more parameters to help plugin developers to have more control on :
- the activity action strings (2.0): for a better compatibility with multilingual sites
- the dropdown filters on front-end (2.1): if BP Theme Compat is in use or if the custom template is using the function
bp_activity_show_filters()
to generate the options instead of directly hardcoding them in the templates.
function bp_plugin_activity_actions() { $bp = buddypress(); /************************************************************************** for the purpose of this tutorial we arbitrary set the $bp->component->id !important you have to use the BP_Component class to do so See : https://codex.buddypress.org/bp_component/ ***************************************************************************/ $bp->bp_plugin = new stdClass(); $bp->bp_plugin->id = 'bp_plugin'; bp_activity_set_action( $bp->bp_plugin->id, // The unique string ID of the component the activity action is attached to 'bp_plugin_update', // the action type __( 'BP plugin update', 'plugin-domain' ), // the action description used in Activity Administration screens dropdown filters 'bp_plugin_format_bp_plugin_update', // A callable function for formatting the action string __( 'BP plugin update', 'plugin-domain' ), // the action label of the activity front-end dropdown filters array( 'activity', 'member' ) // Activity stream contexts where the filter should appear ); } add_action( 'bp_register_activity_actions', 'bp_plugin_activity_actions' ); /** * Callable function for formatting the action string * Since 2.0 activity action strings are generated dynamically, for a better compatibility with multilingual sites */ function bp_plugin_format_bp_plugin_update( $action = '', $activity = null ) { $action = sprintf( __( '%s shared a new BP plugin update', 'plugin-domain' ), bp_core_get_userlink( $activity->user_id ) ); return $action; }
As you can see in the above code, you can set the callable function for formatting the action string using the 4th argument of bp_activity_set_action()
You can also set the 5th and 6th argument instead of using the 'bp_activity_filter_options'
hook to set the label and the contexts where your option will appear in the available dropdowns :
''
: will not display your option in front-endarray( 'activity' )
: will display your option only in the activity directoryarray( 'activity', 'member' )
: will display your option in the activity directory and in the member’s activity pagearray( 'activity', 'member', 'member_groups' )
: will display your option in the activity directory, in the member’s activity page and member’s groups activity pagearray( 'activity', 'groups' )
: will display your option in the activity directory and in the single group’s activity page.
Please note that this possibility was introduced in BuddyPress 2.1. It will work for the configs using the templates included in BuddyPress (BP Theme Compat). Some BuddyPress Themes might not have updated their activity templates (activity/index.php
, groups\single\activity.php
, members\single\activity.php
).