You are here

activity.module in Activity 5

Activity module: Allow users to see their friends' activity on the site.

File

activity.module
View source
<?php

/**
 * @file
 * Activity module: Allow users to see their friends' activity on the site.
 */

/**
 * Implementation of hook_perm().
 */
function activity_perm() {
  return array(
    'administer activity',
    'view activity',
  );
}

/**
 * Implementation of hook_menu().
 */
function activity_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'activity',
      'title' => t('activity'),
      'callback' => 'activity_page',
      'callback arguments' => array(
        arg(1),
      ),
      'access' => user_access('view activity'),
      'type' => MENU_CALLBACK,
    );
    $items[] = array(
      'path' => 'activity/feed',
      'callback' => 'activity_feed',
      'callback arguments' => array(
        arg(2),
      ),
      'access' => user_access('view activity'),
      'type' => MENU_CALLBACK,
    );
    $items[] = array(
      'path' => 'admin/settings/activity',
      'title' => t('Activity Settings'),
      'description' => t('Customize what will display on your users activity page.'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'activity_admin_settings',
      ),
      'access' => user_access('administer site configuration'),
    );
    $items[] = array(
      'path' => 'admin/settings/activity/implements',
      'title' => t('Choose modules'),
      'callback' => 'activity_admin_settings',
      'access' => user_access('administer site configuration'),
      'type' => MENU_DEFAULT_LOCAL_TASK,
    );
    $items[] = array(
      'path' => 'admin/settings/activity/tokens',
      'title' => t('Choose tokens'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'activity_admin_settings',
      ),
      'access' => user_access('administer site configuration'),
      'type' => MENU_LOCAL_TASK,
    );
  }
  return $items;
}
file_scan_directory(drupal_get_path('module', 'activity') . '/includes', '.*', array(), 'activity_include_module');
function activity_include_module($filename) {
  if (module_exists(basename($filename, '.inc'))) {
    include_once $filename;
  }
}

/**
 * Admin section
 */
function activity_admin_settings() {
  $includes = file_scan_directory(drupal_get_path('module', 'activity') . '/includes', '.*', array(
    'CVS',
  ), 'activity_include_module');
  foreach ($includes as $include) {
    $modules[] = module_invoke($include->name, 'activity_info');
  }
  if (!empty($modules)) {
    foreach ($modules as $module) {
      if (!empty($module)) {
        switch (arg(3)) {
          case 'tokens':
            if (variable_get('activity_' . $module['name'] . '_module', 0) == 1) {
              $output = "";
              foreach ($module['tokens'] as $token => $desc) {
                $output .= '[' . $token . ']: <span style="font-weight: normal">' . $desc . '</span><br/>';
              }
              $form['activity_' . $module['name'] . '_token'] = array(
                '#type' => 'fieldset',
                '#title' => $module['name'],
                '#collapsible' => true,
                '#collapsed' => true,
                '#description' => '<div class="messages" style="float:right"><h4>Available Tokens</h4>' . $output . '</div>',
              );
              foreach ($module['ops'] as $op) {
                foreach ($module['types'] as $type => $name) {
                  if (variable_get('activity_' . $module['name'] . '_' . $type, 0) == 1) {
                    $form['activity_' . $module['name'] . '_token']['activity_' . $module['name'] . '_' . $op . '_' . $type . '_token'] = array(
                      '#type' => 'textfield',
                      '#title' => t($op . ' ' . $name),
                      '#default_value' => variable_get('activity_' . $module['name'] . '_' . $op . '_' . $type . '_token', ''),
                    );
                  }
                }
                if (empty($module['types'])) {
                  $form['activity_' . $module['name'] . '_token']['activity_' . $module['name'] . '_' . $op . '_token'] = array(
                    '#type' => 'textfield',
                    '#title' => t($op),
                    '#default_value' => variable_get('activity_' . $module['name'] . '_' . $op . '_token', ''),
                  );
                }
              }
            }
            break;
          default:
            $form['activity_message_limit'] = array(
              '#type' => 'textfield',
              '#title' => 'Message Limit',
              '#description' => t('Set a limit for how many messages display on the activity display.'),
              '#default_value' => variable_get('activity_message_limit', 20),
            );
            $form['activity_' . $module['name']] = array(
              '#type' => 'fieldset',
              '#title' => $module['name'],
              '#collapsible' => true,
              '#collapsed' => false,
            );
            $form['activity_' . $module['name']]['activity_' . $module['name'] . '_module'] = array(
              '#type' => 'checkbox',
              '#title' => $module['name'],
              '#default_value' => variable_get('activity_' . $module['name'] . '_module', 0),
              '#description' => t('Check to enable activity tracking for this module.'),
            );
            if (!empty($module['types'])) {
              $form['activity_' . $module['name']]['activity_' . $module['name'] . '_type'] = array(
                '#type' => 'fieldset',
                '#title' => t('activity types'),
                '#collapsible' => true,
                '#collapsed' => true,
                '#description' => t('Check to enable activity tracking for this type of activity.'),
              );
              foreach ($module['types'] as $type => $name) {
                $form['activity_' . $module['name']]['activity_' . $module['name'] . '_type']['activity_' . $module['name'] . '_' . $type] = array(
                  '#type' => 'checkbox',
                  '#title' => $name,
                  '#default_value' => variable_get('activity_' . $module['name'] . '_' . $type, 0),
                );
              }
            }
            break;
        }
      }
    }
  }
  else {
    $form = array();
    drupal_set_message('No supported modules enabled. Check the activity/includes folder for supported modules.');
  }
  return system_settings_form($form);
}

/**
 * function to get all buddy activity
 * @returns array of activity
 */
function activity_buddy_activity($account_id) {
  $buddies = array();
  $buddy_activity = array();

  // took activity_account from here
  $account = activity_account($account_id);

  #dsm($account, 'account returned after activity_account()');
  switch ($_GET['who']) {
    case 'me':

      // show what current user has done
      global $user;
      $me['uid'] = $user->uid;
      $me['name'] = $user->name;
      $me['mail'] = $user->mail;
      $me['online'] = 1;
      array_push($buddies, $me);
      break;
    case 'friends':

      // find who current user's buddies are = obj
      // $account must be int
      $buddies = buddylist_get_buddies($account);
      break;
    default:

      // find who current user's buddies are = obj
      $accounts = buddylist_get_buddies($account_id);

      // add current user to list of buddies
      foreach ($accounts as $account) {
        $account['online'] = 1;

        #dsm($account, 'account default');
        array_push($buddies, $account);

        #dsm($buddies, 'array push');
      }
      break;
  }

  #dsm($buddies, 'emty?');

  // see what activity each buddy has done
  if (!empty($buddies)) {
    foreach ($buddies as $buddy) {

      #dsm($buddy, 'buddy in loop');
      $query = db_query("SELECT * FROM {activity} WHERE uid = %d ORDER BY timestamp DESC", $buddy['uid']);
      while ($row = db_fetch_object($query)) {

        #dsm($row, 'row');

        // appending count to make the time stamp unique for sorting purposes
        $buddy_activity[$row->timestamp . $count] = $row;
        $count++;
      }
    }
  }

  // TODO: get this message from a setting
  $msg = 'buddy emtpy string';
  $buddy_activity = empty($buddy_activity) ? $msg : $buddy_activity;
  if (is_array($buddy_activity)) {
    return $buddy_activity;
  }
  else {
    return array(
      $msg,
    );
  }
}

/**
 * -- activity account --
 * find what user we're getting buddy activity for
 * @param uid
 * @return a user object
 */
function activity_account($account_to_load) {

  // if we're on a user profile page, make sure we load that user
  $q = explode('/', $_GET['q']);
  if (is_numeric($q[1])) {
    $account = user_load(array(
      'uid' => $q[1],
    ));
  }
  $account = $account->uid ? $account->uid : $account_to_load;
  if (!$account) {

    // there was no # passed from 'q' or $account_to_load
    global $user;
    $account = $user;
  }
  return $account;
}

/**
 * create a block for display
 * @param op
 * @param delta
 * @returns block HTML
 */
function activity_block($op = 'list', $delta = 0) {

  #dsm($op, view);
  global $user;
  if ($op == 'list') {
    $block[0]['info'] = t('Friend Activity');
    return $block;
  }
  elseif ($op == 'view') {
    $buddy_activity = activity_buddy_activity($user->uid);
    $block['content'] = theme('activity_page', $buddy_activity);
    return $block;
  }
}

/**
 * Menu callback to display the records in a page
 */
function activity_page() {
  global $user;
  $buddy_activity = activity_buddy_activity($user->uid);

  #dsm($user->uid);

  #dsm($buddy_activity);
  return theme('activity_page', $buddy_activity);
}

/**
 * theme function for displaying the users activity page
 */
function theme_activity_page($buddy_activity) {

  /*
   FORMAT:
    <h3>Today</h3>
    <ul class="activity-list">
      <li>Listening to my "Ultimate Britney Spears Playlist" on the iPod on the train. (via <a href="#">Twitter</a>) <span class="activity-time">10:00 pm</span></li>
      <li><a href="#">NateH</a> has added <a href="#">Webchick</a> to friends <span class="activity-time">9:00 pm</span></li>
      <li><a href="#">DanW</a> thinks you should be a fan of Justin Timberlake <a href="#">because</a> <span class="activity-time">8:00 pm</span></li>
    </ul>
  */
  $count = 0;
  arsort($buddy_activity);
  if (!empty($buddy_activity)) {
    foreach ($buddy_activity as $ba) {
      if ($count < variable_get('activity_message_limit', 20)) {
        $offset = strftime("%j") + strftime("%Y") * 365 - (strftime("%j", $ba->timestamp) + strftime("%Y", $ba->timestamp) * 365);
        $timeset = $offset > 0 && $offset != $prev_offset ? '<h3>' . _activity_off($ba->timestamp) . '</h3>' : '';
        $activity = activity_token_replace($ba);
        if ($activity) {
          $items[] = $timeset . $activity . ' <span class="activity-time">' . date('g:ia', $ba->timestamp) . '</span> ';
        }
        $prev_offset = $offset;
      }
      $count++;
    }
    return theme('item_list', $items, NULL, 'ul', array(
      'class' => 'activity-list',
    ));
  }
  else {
    return '';
  }
}

/**
 * menu callback to return a feed of a signed in user's activity page
 */
function activity_feed($user_name) {
  $account = user_load(array(
    'name' => $user_name,
  ));
  $buddy_activity = activity_buddy_activity($account->uid);
  drupal_set_header('Content-Type: text/xml; charset=utf-8');
  print theme('activity_feed', $buddy_activity);
  exit;
}
function theme_activity_feed($buddy_activity) {
  global $base_url;
  $channel = array(
    'version' => '2.0',
    'title' => variable_get('site_name', 'drupal') . ' - ' . variable_get('site_slogan', ''),
    'link' => $base_url,
    'description' => variable_get('site_mission', ''),
    'language' => $GLOBALS['locale'],
  );
  arsort($buddy_activity);
  if (!empty($buddy_activity)) {
    foreach ($buddy_activity as $ba) {
      $item_title = $ba->module;
      $item_tokens = unserialize($ba->tokens);
      $link = l($item_tokens['node-title'], 'node/' . $item_tokens['node-id']);
      $item_text = activity_token_replace($ba);
      $items .= format_rss_item($item->title, $link, $item_text);
    }
  }
  $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
  $output .= "<rss version=\"" . $channel["version"] . "\" xml:base=\"" . $base_url . "\">\n";
  $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
  $output .= "</rss>\n";
  return $output;
}

/**
 * determine what the message should say
 */
function activity_token_replace($activity) {

  // what tokens are available for this module
  if (variable_get('activity_' . $activity->module . '_module', 0) == 1) {

    #dsm($activity);

    // FORMAT: (array)token => value
    $tokens = unserialize($activity->tokens);

    #dsm($tokens);

    // FORMAT: [user] did [something] to [what]
    if (variable_get('activity_' . $activity->module . '_' . $activity->action . '_' . $activity->type . '_token', FALSE)) {
      $pattern = variable_get('activity_' . $activity->module . '_' . $activity->action . '_' . $activity->type . '_token', 0);
    }
    else {
      $pattern = variable_get('activity_' . $activity->module . '_' . $activity->action . '_token', 0);
    }

    #dsm($pattern);

    // user-link
    if (strstr($pattern, 'user-link') !== FALSE) {
      $tokens['user-link'] = l($tokens['user-name'], 'user/' . $tokens['user-id']);
    }

    // buddy-link
    if (strstr($pattern, 'buddy-link') !== FALSE) {
      $tokens['buddy-link'] = l($tokens['buddy-name'], 'user/' . $tokens['buddy-id']);
    }

    // node-title-link
    if (strstr($pattern, 'node-title-link') !== FALSE) {
      $tokens['node-title-link'] = l($tokens['node-title'], 'node/' . $tokens['node-id']);
    }
    foreach ($tokens as $key => $val) {
      $pattern = str_replace('[' . $key . ']', $val, $pattern);
    }
    return $pattern;
  }
  else {
    $tokens = unserialize($activity->tokens);
    return $tokens['contents'];
  }
}

/**
 * function that does all the recording
 */
function activity_insert($module, $type, $action, $tokens) {
  global $user;
  $aid = db_next_id('activity');
  db_query("INSERT INTO {activity} VALUES(%d, %d, '%s', '%s', '%s', '%s', %d)", $aid, $user->uid, $module, $type, $action, serialize($tokens), time());
}

/**
 * date formatter
 */
function _activity_off($date) {
  $offset = strftime("%j") + strftime("%Y") * 365 - (strftime("%j", $date) + strftime("%Y", $date) * 365);
  if ($offset > 7) {
    $offset = strftime("%V") + strftime("%Y") * 52 - (strftime("%V", $date) + strftime("%Y", $date) * 52);
    $end = $offset != 0 ? $offset > 1 ? $offset . " weeks ago" : "a week ago" : "Today";
  }
  else {
    $end = $offset != 0 ? $offset > 1 ? "{$offset} days ago" : "Yesterday" : "Today";
  }
  return $end;
}

Functions

Namesort descending Description
activity_account -- activity account -- find what user we're getting buddy activity for
activity_admin_settings Admin section
activity_block create a block for display
activity_buddy_activity function to get all buddy activity @returns array of activity
activity_feed menu callback to return a feed of a signed in user's activity page
activity_include_module
activity_insert function that does all the recording
activity_menu Implementation of hook_menu().
activity_page Menu callback to display the records in a page
activity_perm Implementation of hook_perm().
activity_token_replace determine what the message should say
theme_activity_feed
theme_activity_page theme function for displaying the users activity page
_activity_off date formatter