Index: activity.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/activity/activity.module,v
retrieving revision 1.1.2.2.2.30.2.42
diff -u -p -r1.1.2.2.2.30.2.42 activity.module
--- activity.module	27 Apr 2009 01:45:25 -0000	1.1.2.2.2.30.2.42
+++ activity.module	27 Apr 2009 13:35:36 -0000
@@ -1252,6 +1252,16 @@ function activity_theme() {
 }
 
 /**
+ * Implementation of hook_views_api().
+ */
+function activity_views_api() {
+  return array(
+    'api' => 2,
+    'path' => drupal_get_path('module','activity'),
+  );
+}
+
+/**
  * Theme function for displaying an activity page.
  */
 function theme_activity_page($activities, $table) {
@@ -1404,3 +1414,31 @@ function theme_activity_comments($activi
   }
   return $comments;
 }
+
+function activity_load($aid) {
+
+  // Build the sql and do the query. Wrapping it in db_rewrite_sql allows other
+  // modules to impose access restrictions on activity listings.
+  $sql = "SELECT activity.*, activity_targets.target_uid, activity_targets.target_role
+    FROM {activity_targets} activity_targets INNER JOIN {activity} activity ON activity.aid = activity_targets.aid
+    WHERE activity.aid = %d";
+
+  $row = db_fetch_array(db_query(db_rewrite_sql($sql, 'activity_targets', 'aid'), $aid));
+  if (!empty($row)) {
+    $row['data'] = unserialize($row['data']);
+    $row['data']['aid']	= $row['aid'];
+    $row['data']['uid']	= $row['uid'];
+    $row['data']['module'] = $row['module'];
+    $row['data']['type'] = $row['type'];
+    $row['data']['operation']	= ($row['data']['operation'] ? $row['data']['operation'] : $row['operation']);
+    $row['data']['created'] = $row['created'];
+
+    // Load Activity comments
+    $row['comments'] = activity_comments_load($row['aid']);
+
+    // Invoke activityapi
+    activity_invoke_activityapi($row, 'load');
+  }
+  
+  return $row;
+}
Index: activity.views.inc
===================================================================
RCS file: activity.views.inc
diff -N activity.views.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ activity.views.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,209 @@
+<?php
+
+/**
+ * Implementation of hook_views_data().
+ */
+function activity_views_data() {
+  $data = array();
+
+  $data['activity']['table']['group'] = t('Activity');
+  $data['activity']['table']['base'] = array(
+    'field' => 'aid',
+    'title' => t('Activity'),
+    'help' => t('Activity table stuff help'),
+  );
+
+  $data['activity']['aid'] = array(
+    'title' => t('Activity id'),
+    'help' => t('The id of the activity item'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+  );
+  $data['activity']['uid'] = array(
+    'title' => t('User id'),
+    'help' => t('The user id of the user who triggered the activity.'),
+    'filter' => array(
+      'handler' => 'views_handler_filter_user_current'
+    ),
+    'relationship' => array(
+      'handler' => 'views_handler_relationship',
+      'base' => 'users',
+      'relationship field' => 'uid',
+      'label' => t('Activity: Users'),
+    )
+  );
+  $data['activity']['module'] = array(
+    'title' => t('Module'),
+    'help' => t('The module that triggered the activity'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'activity_views_handler_filter_module',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+  $data['activity']['type'] = array(
+    'title' => t('Type'),
+    'help' => t('The type of activity'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'activity_views_handler_filter_type',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+  $data['activity']['operation'] = array(
+    'title' => t('Operation'),
+    'help' => t('The operation done'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'activity_views_handler_filter_operation',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+  );
+  $data['activity']['created'] = array(
+    'title' => t('Created'),
+    'help' => t('The date of the activity'),
+    'field' => array(
+      'handler' => 'views_handler_field_date',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_date',
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort_date',
+    ),
+  );
+  $data['activity']['data'] = array(
+    'title' => t('Data'),
+    'help' => t('The serialized data of the activity, user id, node id, etc...'),
+    'field' => array(
+      'handler' => 'activity_views_handler_field_serial',
+      'click sortable' => FALSE,
+    ),
+  );
+
+
+  $data['activity_targets']['table']['group'] = t('Activity');
+  $data['activity_targets']['table']['join'] = array(
+    'activity' => array(
+      'left_field' => 'aid',
+      'field' => 'aid',
+    ),
+  );
+  $data['activity_targets']['target_uid'] = array(
+    'title' => t('Target User'),
+    'help' => t('The user id to target'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'relationship' => array(
+      'handler' => 'views_handler_relationship',
+      'base' => 'users',
+      'relationship field' => 'uid',
+      'label' => t('Activity Target: Users'),
+    ),
+  );
+  $data['activity_targets']['target_role'] = array(
+    'title' => t('Target Role'),
+    'help' => t('The target role'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'filter' => array(
+      'handler' => 'activity_views_handler_filter_role',
+    ),
+    'sort' => array(
+      'handler' => 'activity_views_sort',
+    ),
+  );
+
+  return $data;
+}
+
+/**
+ * Implementation of hook_views_handler
+ */
+function activity_views_handlers() {
+  $handlers = array(
+    'info' => array(
+      'path' => drupal_get_path('module','activity') . '/views',
+    ),
+    'handlers' => array(
+      'activity_views_handler_field_serial' => array(
+        'parent' => 'views_handler_field',
+      ),
+      'activity_views_handler_filter_module' => array(
+        'parent' => 'views_handler_filter_in_operator',
+      ),
+      'activity_views_handler_filter_role' => array(
+        'parent' => 'views_handler_filter_in_operator',
+      ),
+      'activity_views_handler_filter_operation' => array(
+        'parent' => 'views_handler_filter_in_operator',
+      ),
+      'activity_views_handler_filter_type' => array(
+        'parent' => 'views_handler_filter_in_operator',
+      ),
+    ),
+  );
+
+  return $handlers;
+}
+
+/**
+ * Implementation of hook_views_plugins().
+ */
+function activity_views_plugins() {
+  return array(
+    'module' => 'activity',
+    'row' => array(
+      'activity' => array(
+        'title' => t('Activity'),
+        'help' => t('Display the activity with the standard activity view.'),
+        'handler' => 'activity_views_plugin_row_activity_view',
+        'path' => drupal_get_path('module', 'activity') . '/views',
+        'base' => array('activity'),
+        'theme' => 'views_view_row_activity',
+        'uses options' => TRUE,
+        'type' => 'normal',
+        'help topic' => 'style-activity',
+      ),
+    ),
+  );
+}
+
+/**
+ * Template handler for theme_views_view_row_activity().
+ */
+function template_preprocess_views_view_row_activity(&$vars) {
+  $options = $vars['options'];
+  $vars['activity'] = ''; // Make sure var is defined.
+  $aid = $vars['row']->aid;
+  if (!is_numeric($aid)) {
+    return;
+  }
+  $activity = activity_load($aid);
+  if (empty($activity)) {
+    return;
+  }
+  $vars['row']->activity_message = activity_token_replace($activity);
+}
Index: views/activity_views_handler_field_serial.inc
===================================================================
RCS file: views/activity_views_handler_field_serial.inc
diff -N views/activity_views_handler_field_serial.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/activity_views_handler_field_serial.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,110 @@
+<?php
+
+class activity_views_handler_field_serial extends views_handler_field {
+
+  function options_form(&$form,&$form_state) {
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Label'),
+      '#default_value' => isset($this->options['label']) ? $this->options['label'] : '',
+      '#description' => t('The label for this field that will be displayed to end users if the style requires it.'),
+    );
+
+    $form['exclude'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Exclude from display'),
+      '#default_value' => $this->options['exclude'],
+      '#description' => t('Check this box to not display this field, but still load it in the view.  Use this option to not show a grouping field in each record, or when doing advanced theming.'),
+    );
+
+    $form['link_object'] = array(
+      '#type' => 'radios',
+      '#title' => t('Link to object'),
+      '#description' => t('Link to the user id or node id'),
+      '#default_value' => $form_state['values']['link_object'] ? $form_state['values']['link_object'] : 1,
+      '#options' => array(0 => t('No'), 1 => t('Yes')),
+    );
+
+    $form['target_role'] = array(
+      '#type' => 'radios',
+      '#title' => t('Target Role'),
+      '#description' => t('The target role that the message is visible to.'),
+      '#default_value' => $form_state['values']['target_role'] ? $form_state['values']['target_role'] : 'all',
+      '#options' => array('all' => t('All'), 'author' => t('Author')),
+      '#multiple' => TRUE,
+    );
+
+    return $form;
+  }
+
+  function options_submit(&$form,&$form_state) { }
+
+  function render($values) {
+    $value = $values->{$this->field_alias};
+    $row = array();
+    $row = unserialize($value);
+
+    if (isset($values->aid) && isset($values->users_activity_uid) && isset($values->activity_module) && isset($values->activity_created) && isset($values->activity_operation) && isset($values->activity_type)) {
+      $row['aid'] = $values->aid;
+      $row['uid'] = $values->users_activity_uid;
+      $row['module'] = $values->activity_module;
+      $row['created'] = $values->activity_created;
+      $row['operation'] = $values->activity_operation;
+      $row['type'] = $values->activity_type;
+      $row['target_role'] = $this->options['target_role'];
+      $row['target_uid'] = $values->users_activity_uid;
+
+      $activity[] = $row;
+      activity_invoke_activityapi($activity,'load');
+
+      $var = "{$values->activity_module}_{$values->activity_type}_{$values->activity_operation}_{$this->options['target_role']}";
+
+      activity_invoke_activityapi($activity,'render');
+
+      $message = token_replace(variable_get($var, FALSE), $values->activity_module, $row);
+      return token_replace($message,'activity', $row);
+    }
+
+    $ret = $value; //FIXME: if there are no matches, then it displays the entire serialized object.
+    /* FIXME: This is a basic outline for displaying the serialized data field.
+       At the moment it only displays a link to the node, user, etc... Unless
+       the object is deleted, in which case it just displays the id number. */
+
+    if (isset($data['content-id'])  && $this->options['link_object'] == 1) {
+      $node = node_load($data['content-id']);
+      if ($node->nid) {
+        $ret = l($node->title,'node/'.$node->nid);
+      } else {
+        $ret = $data['content-id'];
+      }
+    } else if (isset($data['target-uid']) && $this->options['link_object'] == 1) {
+      $usr = user_load($data['target-uid']);
+      if ($usr->uid) {
+        $ret = l($usr->name,'user/'.$usr->uid);
+      } else {
+        $ret = $data['target-uid'];
+      }
+    } else if (isset($data['node-id']) && $this->options['link_object'] == 1) {
+      $node = node_load($data['node-id']);
+      if ($node->nid) {
+        $ret = l($data['node-title'],'node/'.$data['node-id']);
+      } else {
+        $ret = $data['node-id'];
+      }
+    } else if (isset($data['comment-cid']) && $this->options['link_object'] == 1) {
+      $node = node_load($data['parent-node-id']);
+      $c = _comment_load($data['comment-cid']); // FIXME: we shouldn't be using this function
+      if ($node->nid && $c->cid) {
+        $ret = l($data['comment-subject'],'node/'.$data['parent-node-id'].'/comment-'.$data['comment-cid']);
+      } else if($node->id && (!$c->cid)) {
+        $ret = l($data['comment-subject'],'node/'.$data['parent-node-id']);
+      } else {
+        $ret = $data['parent-node-id'] . ' comment #'.$data['comment-cid'];
+      }
+    } 
+
+    return $ret;
+  }
+
+}
+
Index: views/activity_views_handler_filter_module.inc
===================================================================
RCS file: views/activity_views_handler_filter_module.inc
diff -N views/activity_views_handler_filter_module.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/activity_views_handler_filter_module.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,24 @@
+<?php
+
+class activity_views_handler_filter_module extends views_handler_filter_in_operator {
+
+   function get_value_options() {
+     foreach (module_implements('activity_info') as $m) {
+       $modules[$m] = $m;
+     }
+     $this->value_options = $modules;
+   }
+
+}
+<?php
+
+class activity_views_handler_filter_module extends views_handler_filter_in_operator {
+
+   function get_value_options() {
+     foreach (module_implements('activity_info') as $m) {
+       $modules[$m] = $m;
+     }
+     $this->value_options = $modules;
+   }
+
+}
Index: views/activity_views_handler_filter_operation.inc
===================================================================
RCS file: views/activity_views_handler_filter_operation.inc
diff -N views/activity_views_handler_filter_operation.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/activity_views_handler_filter_operation.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,32 @@
+<?php
+
+class activity_views_handler_filter_operation extends views_handler_filter_in_operator {
+
+  function get_value_options() {
+    $activity_info = activity_get_info();
+    $operations = array();
+    foreach ($activity_info as $module => $info) {
+      foreach ($info['ops'] as $op => $name) {
+        $operations[$op] = $name;       
+      }
+    }
+    $this->value_options = $operations;
+  }
+
+}
+<?php
+
+class activity_views_handler_filter_operation extends views_handler_filter_in_operator {
+
+  function get_value_options() {
+    $activity_info = activity_get_info();
+    $operations = array();
+    foreach ($activity_info as $module => $info) {
+      foreach ($info['ops'] as $op => $name) {
+        $operations[$op] = $name;       
+      }
+    }
+    $this->value_options = $operations;
+  }
+
+}
Index: views/activity_views_handler_filter_role.inc
===================================================================
RCS file: views/activity_views_handler_filter_role.inc
diff -N views/activity_views_handler_filter_role.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/activity_views_handler_filter_role.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,18 @@
+<?php
+
+class activity_views_handler_filter_role extends views_handler_filter_in_operator {
+
+   function get_value_options() {
+     $this->value_options = array('all' => t('All'), 'author' => t('Author'));
+   }
+
+}
+<?php
+
+class activity_views_handler_filter_role extends views_handler_filter_in_operator {
+
+   function get_value_options() {
+     $this->value_options = array('all' => t('All'), 'author' => t('Author'));
+   }
+
+}
Index: views/activity_views_handler_filter_type.inc
===================================================================
RCS file: views/activity_views_handler_filter_type.inc
diff -N views/activity_views_handler_filter_type.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/activity_views_handler_filter_type.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,32 @@
+<?php
+
+class activity_views_handler_filter_type extends views_handler_filter_in_operator {
+
+  function get_value_options() {
+    $activity_info = activity_get_info();
+    $types = array();
+    foreach ($activity_info as $module => $info) {
+      foreach ($info['types'] as $type => $name) {
+        $types[$type] = $name;       
+      }
+    }
+    $this->value_options = $types;
+  }
+
+}
+<?php
+
+class activity_views_handler_filter_type extends views_handler_filter_in_operator {
+
+  function get_value_options() {
+    $activity_info = activity_get_info();
+    $types = array();
+    foreach ($activity_info as $module => $info) {
+      foreach ($info['types'] as $type => $name) {
+        $types[$type] = $name;       
+      }
+    }
+    $this->value_options = $types;
+  }
+
+}
Index: views/activity_views_plugin_row_activity_view.inc
===================================================================
RCS file: views/activity_views_plugin_row_activity_view.inc
diff -N views/activity_views_plugin_row_activity_view.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/activity_views_plugin_row_activity_view.inc	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,124 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Contains the activity view row style plugin.
+ */
+
+/**
+ * Plugin which performs an activity_view on the resulting object.
+ */
+class activity_views_plugin_row_activity_view extends views_plugin_row {
+
+  function init(&$view, &$display, $options = NULL) {
+    // Call init of base class.
+    parent::init(&$view, &$display, $options);
+    /*
+    if ($view->query === NULL) {
+      return;
+    }
+
+    // Clear the fields first
+    //$view->query->clear_fields();
+    $view->query->add_field('activity', 'aid', 'aid');
+    $view->query->add_field('activity', 'uid', 'uid');
+    $view->query->add_field('activity', 'module', 'module');
+    $view->query->add_field('activity', 'type', 'type');
+    $view->query->add_field('activity', 'operation', 'operation');
+    $view->query->add_field('activity', 'created', 'created');
+    $view->query->add_field('activity', 'data', 'data');
+    //$view->query->add_field('activity', 'nid', 'nid');
+    */
+
+  }
+
+  function uses_fields() {
+    $has_fields = !empty($this->definition['uses fields']);
+    return $has_fields;
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['messages'] = array('default' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['messages'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display messages'),
+      '#default_value' => $this->options['messages'],
+    );
+  }
+
+  /**
+   * Override the behavior of the render() function.
+   */
+  function render($row) {
+    return theme($this->theme_functions(), $this->view, $this->options, $row);
+  }
+
+}
+<?php
+// $Id$
+
+/**
+ * @file
+ * Contains the activity view row style plugin.
+ */
+
+/**
+ * Plugin which performs an activity_view on the resulting object.
+ */
+class activity_views_plugin_row_activity_view extends views_plugin_row {
+
+  function init(&$view, &$display, $options = NULL) {
+    // Call init of base class.
+    parent::init(&$view, &$display, $options);
+    /*
+    if ($view->query === NULL) {
+      return;
+    }
+
+    // Clear the fields first
+    //$view->query->clear_fields();
+    $view->query->add_field('activity', 'aid', 'aid');
+    $view->query->add_field('activity', 'uid', 'uid');
+    $view->query->add_field('activity', 'module', 'module');
+    $view->query->add_field('activity', 'type', 'type');
+    $view->query->add_field('activity', 'operation', 'operation');
+    $view->query->add_field('activity', 'created', 'created');
+    $view->query->add_field('activity', 'data', 'data');
+    //$view->query->add_field('activity', 'nid', 'nid');
+    */
+
+  }
+
+  function uses_fields() {
+    $has_fields = !empty($this->definition['uses fields']);
+    return $has_fields;
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['messages'] = array('default' => TRUE);
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['messages'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Display messages'),
+      '#default_value' => $this->options['messages'],
+    );
+  }
+
+  /**
+   * Override the behavior of the render() function.
+   */
+  function render($row) {
+    return theme($this->theme_functions(), $this->view, $this->options, $row);
+  }
+
+}
Index: views/views-view-row-activity.tpl.php
===================================================================
RCS file: views/views-view-row-activity.tpl.php
diff -N views/views-view-row-activity.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views/views-view-row-activity.tpl.php	27 Apr 2009 13:35:36 -0000
@@ -0,0 +1,14 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Default simple view template to display a single heartbeat.
+ *
+ * @ingroup views_templates
+ */
+?>
+<?php print $row->activity_message; ?>
+  
+<?php if ($info): ?>
+  <?php print $info; ?>
+<?php endif; ?>
