How to create a custom activity view

Although heartbeat comes with default pages and blocks, it can be handy to create your own custom views. There are two approaches to make that happen. Installing the views ui module for drupal and creating your own views, or writing your own block in a custom module, using the heartbeat functions and classes.

Creating your own views with the views ui

Because views2 is such a cool module with all its hooks, handlers and api functions, I provided integration for that too.  The only thing here is that you can’t use fields because the merging can only work when having all the fields of both used tables.

Underneath we create a view step by step:

  • Create a view with type heartbeat

    Create a view with type heartbeat

    Type a name, description and choose heartbeat as tag. Obviously we choose “heartbeat” as view_type

  • Decide if it is a page or block display and give it a name, title, admin name (path for pages)
  • Select style and choose the heartbeat row plugin (if this in some way is not appearing, the row style plugin was not found)
  • Select relationships and create a relation with heartbeat messages (require that relationship!)

    Select the heartbeat row style plugin

    Select the heartbeat row style plugin

  • Choose a filter for the language
  • Choose a filter for the access type and fill in required settings
  • Choose addtional filters if you want
  • Save, preview

If this does not work, please post a issue.

Writing your own implementation of hook_block for heartbeat activity

Make an implementation of hook_block and copy this code.  This is the code of the message list restricted with the ConnectedHeartbeat AccessState.  It is this state that you can create yourself. Your class extension can override some hook methods that build the sql. Here is what you must have at least in your hook block:

  1.   switch($op) {
  2.     case ‘list’:
  3.         $blocks[0][‘info’] = t(‘Your custom heartbeat block’);
  4.         $blocks[0][‘cache’] = BLOCK_CACHE_PER_USER; // works great with block_cache_alter
  5.         return $blocks;
  6.     case ‘view’:
  7.       switch($delta) {
  8.         case 0:
  9.           heartbeat_include(‘heartbeatmessagebuilder’);
  10.           $context = new HeartbeatMessageBuilder(new ConnectedHeartbeat());
  11.           $messages = $context->execute();
  12.           if($messages) {
  13.             $block[’subject’] = t(‘My custom heartbeat’);
  14.             $block[‘content’] = theme(‘heartbeat_block_private’, $messages);
  15.             return $block;
  16.           }

The theme callback is good in most cases, but as you might have guessed, even that function is for you to modify.  For this you can look at the heartbeat theme function(s) to build your own.

But what if the HeartbeatState objects don’t fit your needs? In this case you can create your own implementation of HeartbeatState.  Let’s say for instance you want a State that is public for all, because you want to filter messages afterwards, for instance to perform access callbacks to the node context in some cases. Let’s call it MyPublicHeartbeat, the you would have something like this:

  1. /**
  2.  * Class PublicHeartbeat
  3.  * Concrete class to prepare messages for all users
  4.  * Filtering and deletion of duplicates not in sql
  5.  *
  6.  */
  7. class PublicHeartbeat extends HeartbeatAccess {
  8.  
  9.   protected $_access = HEARTBEAT_PUBLIC_TO_ALL;
  10.  
  11.   /**
  12.    * Implementation of dressUpMessages().
  13.    *
  14.    * @param object HeartbeatParser $heartbeat
  15.    *   The state of the viewed message sets
  16.    * @return object HeartbeatParser $heartbeat
  17.    */
  18.   public function dressUpMessages(HeartbeatParser $heartbeat) {
  19.     $heartbeatInfo = $heartbeat->get_info();
  20.     $heartbeatInfo->uid = 0;
  21.     $heartbeatInfo->limit_view = variable_get(‘heartbeat_block_public_items_max’, 25);
  22.     $heartbeatInfo->user_relations = $heartbeatInfo->uid;
  23.     $heartbeat->set_info($heartbeatInfo);
  24.  
  25.     $sql = $heartbeatInfo->sql_start;
  26.     // logic to fetch messages public to all
  27.     $sql.= " AND ua.uid > %d  AND ua.access > 0 ";
  28.     $sql.= $heartbeatInfo->sql_end;
  29.     $result = db_query_range($sql, $heartbeatInfo->language, $heartbeatInfo->uid,
  30.       $heartbeatInfo->start_time, 0,$heartbeatInfo->limit_sql);
  31.     while($heartbeat_row = db_fetch_object($result) ) {
  32.       $heartbeat->raw_messages[$heartbeat_row->uaid] = $heartbeat_row;
  33.     }
  34.     return $heartbeat;
  35.   }
  36. }

The methods you see here are “hook”-methods of a class, much like the hooks of drupal. This only means you “can” override the methods but you don’t have to.
In the example above the sql does not limit or filter much.  Most of the time this does not fit our needs, so we should be able to delete duplicate messages or messages that don’t belong there.

To fix this, there are some heartbeat function hooks you can use to alter the message sets that will be shown. You could do an implementation of hook_messages_alter and return an array of messages that will be unset. Example:

  1. /**
  2.  * Implementation of hook_heartbeat_messages_alter()
  3.  */
  4. function friendlist_activity_heartbeat_messages_alter(& $raw_messages, HeartbeatAccess $state) {
  5.   $duplicates = array();
  6.   return $duplicates;
  7. }

Loop through the raw_messages and use the message properties and the HeartbeatAccess state to do some logic on why a message should be removed from view.

Remark: Use the dsm function of the devel module to see the properties. This will certainly speed up your custom development.

This entry was posted on Friday, May 1st, 2009 at 4:24 pm and is filed under Drupal, Heartbeat. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Responses to “How to create a custom activity view”

  1. Ben Says:

    First thank you for the wonderful heartbeat module providing this amount of flexibilty. The tutorial is great.
    I regognized that with the heartbeat views style, no fields are available for the views. So I wonder if its somehow possible, either by views or theming to show userpictures instead of usernames…
    Thank for your support
    Regards,
    Ben

  2. Stalski Says:

    It certainly is possible, because i tried it myself. If I remember correctly, I made my own token to be used in one of the messages.
    I don’t know by heart if there is a user-picture token already, provided by token module itself, but as i said, it is very easy to create your own custom tokens. The same way you could make messages like:
    “Fred added pictures to myfirstalbum : picture1, picture2, picture3. I once posted example code in the issue queue. You can take a look at that to see how I implemented such tokens at http://drupal.org/node/370574.

Leave a Reply