It puzzled me at first when I discovered that activity items are formatted as html before they are stored in the database. This reduces the workload upon retrieval but makes it almost impossible to edit the content of old entries.

Fortunately it is quite easy to change the way activity items are stored in the database. I’m going to use blog post activity items as an example, but this process is the same for just about every kind of activity item.

The first objective is to find the filter function that you want to hook into. For blog posts, look to line 385 of bp-blogs.php, inside function bp_blogs_record_post(). In general, to find these record functions, search the component core file for the string ‘record.’ This will point you to both the utility function that hands the array off to bp_activity_add(), and to the function that a specific user task initiates to record an activity.

The filter we are interested in is bp_blogs_activity_new_post, in the segment:

  1. bp_blogs_record_activity( array(
  2.                                 ‘user_id’ => (int)$post->post_author,
  3.                                 ‘content’ => apply_filters( ‘bp_blogs_activity_new_post’, $activity_content, &$post, $post_permalink ),
  4.                                 ‘primary_link’ => apply_filters( ‘bp_blogs_activity_new_post_primary_link’, $post_permalink, $post_id ),
  5.                                 ‘component_action’ => ‘new_blog_post’,
  6.                                 ‘item_id’ => $recorded_post_id,
  7.                                 ‘recorded_time’ => strtotime( $post->post_date )
  8.                         ) );

Now, in our plugin, or in custom.php, add the following:

  1. add_filter(‘bp_blogs_activity_new_post’, ‘my_process’, 2, 3 );
  2.  
  3. function my_process($activity_content, $post, $post_permalink){
  4.  
  5.         $activity_content = sprintf( __( ‘%s wrote a new blog post: %s’, ‘buddypress’ ), bp_core_get_userlink( (int)$post->post_author ), ‘<a href="’ . $post_permalink . ‘">’ . $post->post_title . ‘</a>’ );
  6.         $activity_content .= "
  7. <blockquote>
  8.  
  9. " . bp_create_excerpt( $post->post_content, 25 ) . "</blockquote>
  10. ";
  11.  
  12.         return $activity_content;
  13. }

Skip to the next heading if you understand filters, or don’t care!

I will take a minute to explain filters, because they are a useful but somewhat obscure concept in WordPress. Filters are like actions, in that they provide an access point into code running in the WordPress framework. Filters are different from actions in that they return a value. It helps to think of apply_filters() as being analogous to do_action(). The first argument of apply_filters() is the tag that an add_filter() action hooks into with its first argument. This is not unlike the relationship between add_action() and do_action().

The second to nth arguments in apply_filters() allow variables to be passed into your custom filter. Try and understand this diagram:

wp-filters

Information flow between apply_filters, add_filter, and custom filter function

Back to the task!

It would be nice if we could edit the individual components of $activity_content, but alas, it doesn’t have its own filter. That’s why some copying is necessary from the core file – but usually this code is pretty short, as you can see. It’s necessary to pass $post, $post_permalink into your filter function so that you can use these values in your activity content variable.

After returning the variable with your formatted feed, guess what, you’re done! apply_filters() will return the value of your function’s return.

Leave a Reply