View source
<?php
include 'heartbeat.common.inc';
spl_autoload_extensions('.inc');
function heartbeat_class_loader($class) {
heartbeat_include(strtolower($class));
}
spl_autoload_register('heartbeat_class_loader');
define('HEARTBEAT_PRIVATE', 0);
define('HEARTBEAT_PUBLIC_TO_ALL', 1);
define('HEARTBEAT_PUBLIC_TO_CONNECTED', 2);
define('HEARTBEAT_PUBLIC_TO_ADDRESSEE', 3);
function heartbeat_init() {
global $user;
if (!isset($user->heartbeat_relations)) {
$user->heartbeat_relations = array();
}
}
function heartbeat_perm() {
return array(
'configure heartbeat',
'configure heartbeat messages',
'delete heartbeat activity logs',
'view heartbeat messages',
);
}
function heartbeat_menu() {
$items = array();
$items['heartbeat/public'] = array(
'title' => 'public heartbeat page',
'description' => 'Public heartbeat page',
'page callback' => 'heartbeat_site_messages',
'access arguments' => array(
'view heartbeat messages',
),
);
$items['heartbeat/activity/personal'] = array(
'title' => 'Activity',
'description' => 'All activity from you and your connections',
'page callback' => 'heartbeat_connected_messages',
'access arguments' => array(
'view heartbeat messages',
),
);
$items['admin/settings/heartbeat'] = array(
'title' => 'heartbeat settings',
'description' => 'Administer settings for heartbeat.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'heartbeat_admin_settings',
),
'access arguments' => array(
'configure heartbeat',
),
'file' => 'heartbeat.admin.inc',
'weight' => -5,
);
$items['admin/settings/heartbeat/settings'] = array(
'title' => 'Heartbeat settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/settings/heartbeat/delete'] = array(
'title' => 'Delete activity logs',
'description' => 'Delete heartbeat activity logs.',
'page arguments' => array(
'heartbeat_delete_logs_confirm',
),
'access arguments' => array(
'delete heartbeat activity logs',
),
'file' => 'heartbeat.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 5,
);
$items['admin/build/heartbeat'] = array(
'title' => 'Heartbeat messages',
'description' => 'Administer messages for heartbeat.',
'weight' => -5,
'page callback' => 'heartbeat_messages_overview',
'access arguments' => array(
'configure heartbeat messages',
),
'file' => 'heartbeat.admin.inc',
);
$items['admin/build/heartbeat/list'] = array(
'title' => 'List',
'description' => 'Overview messages',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/build/heartbeat/add'] = array(
'title' => 'Add heartbeat message',
'description' => 'Administer message for heartbeat.',
'weight' => 1,
'type' => MENU_LOCAL_TASK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'heartbeat_messages_add',
),
'access arguments' => array(
'add heartbeat message',
),
'file' => 'heartbeat.admin.inc',
);
$items['admin/build/heartbeat/export'] = array(
'title' => 'Export',
'description' => 'Export messages to use as default.',
'weight' => 1,
'type' => MENU_LOCAL_TASK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'heartbeat_messages_export',
),
'access arguments' => array(
'configure heartbeat messages',
),
'file' => 'heartbeat.admin.inc',
);
$items['admin/build/heartbeat/edit/%'] = array(
'title' => 'Edit heartbeat message',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'heartbeat_messages_edit',
4,
),
'access arguments' => array(
'configure heartbeat messages',
),
'file' => 'heartbeat.admin.inc',
);
$items['admin/build/heartbeat/delete/%'] = array(
'title' => 'Delete heartbeat message',
'description' => 'Administer deletions of messages.',
'type' => MENU_CALLBACK,
'page callback' => 'heartbeat_messages_delete',
'page arguments' => array(
4,
),
'access arguments' => array(
'configure heartbeat messages',
),
'file' => 'heartbeat.admin.inc',
);
$items['heartbeat/heartbeat_activity_rules_default/js'] = array(
'title' => 'Callback to supply extra action variables as arguments',
'type' => MENU_CALLBACK,
'page callback' => 'heartbeat_activity_rules_action_message_id_js',
'access arguments' => array(
'configure heartbeat messages',
),
'file' => 'heartbeat.admin.inc',
);
$items['heartbeat/message_types/js'] = array(
'title' => 'Callback to supply textarea changes for messages',
'page callback' => 'heartbeat_message_type_js',
'access arguments' => array(
'configure heartbeat messages',
),
'type' => MENU_CALLBACK,
'file' => 'heartbeat.admin.inc',
);
$items['admin/settings/heartbeat/heartbeat_activity'] = array(
'title' => 'user activity settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'heartbeat_logs_admin_settings',
),
'access arguments' => array(
'configure user activity',
),
'type' => MENU_LOCAL_TASK,
'weight' => 6,
'file' => 'heartbeat.admin.inc',
);
$items['heartbeat/ahah/%'] = array(
'page callback' => 'heartbeat_activity_ahah',
'page arguments' => array(
2,
),
'access callback' => 'user_access',
'access arguments' => array(
'configure user activity',
),
'type' => MENU_CALLBACK,
'file' => 'heartbeat.admin.inc',
);
return $items;
}
function heartbeat_theme() {
return array(
'heartbeat_list' => array(
'arguments' => array(
'messages' => array(),
),
),
);
}
function heartbeat_block($op = 'list', $delta = 0, $edit = array()) {
if (!user_access('view heartbeat messages') || !variable_get('heartbeat_enabled', 1)) {
return FALSE;
}
$access_types = variable_get('heartbeat_access_types', array());
if ($op == 'list') {
foreach ($access_types as $key => $access_type) {
$blocks[$key]['info'] = ucfirst($access_type['name']);
$blocks[$key]['cache'] = BLOCK_CACHE_PER_USER;
}
return $blocks;
}
else {
if ($op == 'view') {
if (isset($access_types[$delta])) {
if ($access_types[$delta]['module'] != 'heartbeat') {
heartbeat_include($access_types[$delta]['class'], $access_types[$delta]['module']);
}
$accesstype = $access_types[$delta]['class'];
$context = new HeartbeatMessageBuilder(new $accesstype());
if (!$context
->hasErrors()) {
$messages = $context
->execute();
$block['subject'] = t($access_types[$delta]['name']);
$block['content'] = theme('heartbeat_list', $messages);
return $block;
}
}
}
else {
if ($op == 'configure') {
$class = strtolower($access_types[$delta]['class']);
$form['items'] = array(
'#type' => 'checkbox',
'#title' => t('Show activity for the displayed user on the user profile page'),
'#description' => t('By default heartbeat will show activity in relation to the
currently logged in user. With this setting enabled and only on the user profile page,
the messages will be shown in relation to the user profile.'),
'#default_value' => variable_get('heartbeat_show_user_profile_messages_' . $class, 0),
);
return $form;
}
else {
if ($op == 'save') {
$class = strtolower($access_types[$delta]['class']);
variable_set('heartbeat_show_user_profile_messages_' . $class, $edit['heartbeat_show_user_profile_messages_' . $class]);
}
}
}
}
}
function theme_heartbeat_list($messages) {
return _heartbeat_build_block($messages);
}
function heartbeat_heartbeat_message_info() {
$info = array(
2 => array(
'message' => '!username has updated !node_type "!node_title"',
'message_concat' => '!username has updated %node_title%',
'message_id' => 'heartbeat_edit_node',
'message_type' => 'normal',
'concat_args' => array(
'type' => 'summary',
'group_by' => 'user',
'group_target' => 'node_title',
'merge_separator' => ', ',
'merge_end_separator' => ' and ',
'perms' => '0',
),
'module' => 'node',
'description' => 'When editing a node, log the users activity',
'variables' => array(
'@username' => '[node:author-name-url]',
'@node_type' => '[node:type]',
'@node_title' => '[node:title-link]',
),
),
3 => array(
'message_id' => 'heartbeat_add_node',
'message_type' => 'normal',
'message' => '!username has added !node_type !node_title.',
'message_concat' => '!username has added the following !nodetypes: %node_title%.',
'concat_args' => array(
'type' => 'summary',
'group_by' => 'user',
'merge_target' => 'node_title',
'merge_separator' => ',',
'merge_end_separator' => 'and ',
'perms' => '0',
),
'module' => 'node',
'description' => 'User adds a node, save user activity',
'variables' => array(
'@username' => '[user:user-name-url]',
'@node_type' => '[node:type]',
'@node_title' => '[node:title-link]',
'@nodetypes' => '[node:type]s',
),
),
4 => array(
'message_id' => 'heartbeat_add_comment',
'message_type' => 'normal',
'message' => '!username replied on !title.',
'message_concat' => '!username replied on !title.',
'concat_args' => array(
'type' => 'count',
'merge_target' => 'times',
'merge_separator' => '',
'merge_end_separator' => '',
'perms' => '0',
),
'module' => 'comment',
'description' => 'user replied on some content',
'variables' => array(
'@username' => '[user:user-name-url] ',
'@title' => '[node:title-link]',
),
),
5 => array(
'message_id' => 'heartbeat_edit_comment',
'message_type' => 'normal',
'message' => '!username changed his comment on !title.',
'message_concat' => '!username changed his comment on !title several times (%times%).',
'concat_args' => array(
'type' => 'count',
'merge_target' => 'times',
'merge_separator' => '',
'merge_end_separator' => '',
'perms' => '0',
),
'module' => 'comment',
'description' => 'user changed his comment',
'variables' => array(
'@username' => '[user:user-name-url]',
'@title' => '[node:title-link]',
),
),
6 => array(
'message_id' => 'heartbeat_edit_account',
'message_type' => 'normal',
'message' => '!username\'s personal account page has been changed.',
'message_concat' => '',
'concat_args' => array(
'type' => 'single',
'merge_target' => '',
'merge_separator' => '',
'merge_end_separator' => '',
'perms' => '0',
),
'module' => 'user',
'description' => 'user changed his/her account',
'variables' => array(
'@username' => '[user:user-name-url]',
),
),
);
return $info;
}
function heartbeat_heartbeat_register_access_types() {
return array(
0 => array(
'name' => 'Personal Heartbeat',
'class' => 'PrivateHeartbeat',
'path' => 'includes/privateheartbeat.inc',
'module' => 'heartbeat',
),
1 => array(
'name' => 'Public Heartbeat',
'class' => 'PublicHeartbeat',
'path' => 'includes/publicheartbeat.inc',
'module' => 'heartbeat',
),
2 => array(
'name' => 'Heartbeat activity for user relations',
'class' => 'ConnectedHeartbeat',
'path' => 'includes/connectedheartbeat.inc',
'module' => 'heartbeat',
),
);
}
function heartbeat_api_log($message_id, $uid, $uid_target = 0, $nid = 0, $variables = array()) {
$data = array();
$data['message_id'] = $message_id;
$data['uid'] = $uid;
$data['uid_target'] = $uid_target;
$data['nid_target'] = $nid;
$message = heartbeat_load_message($data['message_id']);
$data['message'] = $message->message;
$data['message_concat'] = $message->message_concat;
if (!empty($variables) && is_array($variables)) {
$data['variables'] = heartbeat_encode_message_variables($variables);
}
return heartbeat_log($data);
}
function heartbeat_token_list($type = 'all') {
$tokens = array();
if ($type == 'boolean') {
$tokens['boolean']['1-or-0'] = t("1 for true, 0 for false");
}
if ($type == 'rules_data_type_heartbeat_message_id') {
$tokens['heartbeat_message']['message-id-raw'] = t("The message chosen by the user in raw");
$tokens['heartbeat_message']['message-id'] = t("The message chosen by the user");
}
if ($type == 'rules_data_type_heartbeat_access') {
$tokens['heartbeat_message']['message-access'] = t("The message access chosen by user");
}
if ($type == 'heartbeat_message') {
$tokens['heartbeat']['heartbeat-message-raw'] = t("The logged heartbeat message in raw format");
}
if ($type == 'node') {
$tokens['node']['title-link'] = t("The node's title with a link to it");
$tokens['node']['author-name-url'] = t("The users name with a link to it");
}
if ($type == 'user') {
$tokens['user']['user-name-url'] = t("The currently logged-in username with a link to it");
$tokens['user']['user-profile-url'] = t("The currently logged-in username with a link to his/her profile page. <strong>USE ONLY when url-path is set to profile/username </strong>");
}
return $tokens;
}
function heartbeat_token_values($type, $object = NULL, $options = array()) {
$values = array();
switch ($type) {
case 'boolean':
$values['1-or-0'] = $object ? '1' : '0';
break;
case 'rules_data_type_heartbeat_message_id':
$values['message-id'] = $object;
$values['message-id-raw'] = (int) $object;
break;
case 'rules_data_type_heartbeat_access':
$values['message-access'] = (int) $object;
break;
case 'heartbeat_message':
$values['heartbeat-message-raw'] = check_plain($object->message);
break;
case 'node':
$values['title-link'] = l($object->title, 'node/' . $object->nid);
$values['author-name-url'] = l($object->name, 'user/' . $object->uid, array(
'attributes' => array(
'class' => 'user',
),
));
break;
case 'user':
$values['user-name-url'] = l($object->name, 'user/' . $object->uid, array(
'attributes' => array(
'class' => 'user',
),
));
$values['user-profile-url'] = l($object->name, 'profile/' . $object->name, array(
'attributes' => array(
'class' => 'user',
),
));
break;
case 'global':
break;
}
return $values;
}
function heartbeat_check_access_types() {
$types = module_invoke_all('heartbeat_register_access_types');
if (!empty($types)) {
foreach ($types as $key => $type) {
require_once drupal_get_path('module', $type['module']) . '/' . $type['path'];
if (!class_exists($type['class'])) {
watchdog('heartbeat', t('No class found for') . $type['class'], array(), WATCHDOG_ERROR);
unset($types[$key]);
}
}
}
variable_set('heartbeat_access_types', $types);
}
function heartbeat_gather_messages() {
$info_default = module_invoke_all('heartbeat_message_info');
$defaults_lookup = array();
foreach ($info_default as $default) {
$defaults_lookup[$default['message_id']] = TRUE;
}
$info_cache = heartbeat_messages('all', false, false);
foreach ($info_cache as $key => $cached) {
if (!isset($defaults_lookup[$cached['message_id']]) && !$cached['custom']) {
heartbeat_messages_uninstall($cached['message_id'], 'message');
unset($info_cache[$key]);
}
}
$info = _heartbeat_array_udiff($info_default, $info_cache);
$info = heartbeat_messages_install($info);
return $info;
}
function heartbeat_log($data, $args = array()) {
$heartbeat_activity = new HeartbeatActivity($data);
return $heartbeat_activity
->save($args);
}
function heartbeat_connected_messages() {
$context = new HeartbeatMessageBuilder(new ConnectedHeartbeat());
$messages = $context
->execute();
return theme('heartbeat_block_private', $messages);
}
function heartbeat_site_messages() {
$context = new HeartbeatMessageBuilder(new PublicHeartbeat());
$messages = $context
->execute();
return theme('heartbeat_block_private', $messages);
}
function heartbeat_include($file, $module = 'heartbeat') {
static $loaded = array();
$file = strtolower($file);
$path = drupal_get_path('module', $module) . '/includes/' . $file . '.inc';
if (!isset($loaded[$file]) && is_file($path)) {
require $path;
$loaded[$file] = TRUE;
}
return $loaded[$file];
}
function heartbeat_messages_install($objects) {
foreach ($objects as $record) {
$record = (object) $record;
if (isset($record->concat_args) && is_array($record->concat_args)) {
$record->concat_args = heartbeat_encode_message_variables($record->concat_args);
}
if (isset($record->variables) && is_array($record->variables)) {
$record->variables = heartbeat_encode_message_variables($record->variables);
}
db_query("INSERT INTO {heartbeat_messages} (\n message_id, message_type, message, message_concat, concat_args, perms, description, module, variables)\n VALUES ('%s', '%s', '%s', '%s','%s', %d, '%s', '%s', '%s') ", $record->message_id, $record->message_type, $record->message, $record->message_concat, $record->concat_args, $record->perms, $record->description, $record->module, $record->variables);
}
return $objects;
}
function heartbeat_messages_uninstall($id, $type = 'module') {
if ($type == 'module') {
db_query("DELETE FROM {heartbeat_messages} WHERE module = '%s'", $id);
}
if ($type == 'message') {
db_query("DELETE FROM {heartbeat_messages} WHERE message_id = '%s'", $id);
}
}
function _heartbeat_build_block($messages) {
if (empty($messages)) {
return '<p>' . t('<em>No activity yet.</em>') . '</p>';
}
$content = '';
$content .= _heartbeat_messages_format_interval($messages);
if (isset($messages->info)) {
$content .= _heartbeat_activity_get_info();
}
return $content;
}
function heartbeat_get_related_uids($uid) {
$uids = $related_uids = array();
$uids[$uid] = $uid;
$related_uids = module_invoke_all('heartbeat_related_uid_info', $uid);
if (count($related_uids) > 0) {
foreach ($related_uids as $rel_uid) {
$uids[$rel_uid] = $rel_uid;
}
}
return $uids;
}
function heartbeat_messages($module = 'all', $reset = false, $objects = true) {
static $messages;
if (empty($messages) || $reset == true) {
$messages = array();
if ($module == 'all') {
$result = db_query("SELECT * FROM {heartbeat_messages} ORDER BY module, description ");
}
else {
$result = db_query("SELECT * FROM {heartbeat_messages} WHERE module = '%s' ", $module);
}
while ($row = db_fetch_array($result)) {
if ($objects) {
$messages[] = new HeartbeatActivity($row);
}
else {
$messages[] = $row;
}
}
}
return $messages;
}
function heartbeat_get_messages($type = 'all', $reset = false) {
static $messages;
if ($type == 'all') {
$messages = heartbeat_messages('all', $reset, true);
$reset = false;
}
if ($type != 'all' && (empty($messages) || $reset)) {
$messages = array();
$result = db_query("SELECT * FROM {heartbeat_messages} WHERE message_type = '%s'", $type);
while ($row = db_fetch_array($result)) {
$messages[] = new HeartbeatActivity($row);
}
}
return $messages;
}
function heartbeat_get_message_types() {
$types = variable_get('message_types', array(
'normal',
));
return drupal_map_assoc($types);
}
function heartbeat_load_message($hid) {
if (!is_numeric($hid)) {
$where = " message_id = '%s' ";
$hid = (string) $hid;
}
else {
$where = " hid = %d ";
}
$result = db_query("SELECT * from {heartbeat_messages} WHERE " . $where . " LIMIT 1", $hid);
$message = db_fetch_object($result);
return $message;
}
function heartbeat_load_message_instance($uaid) {
return db_fetch_object(db_query("SELECT * from {heartbeat_activity} WHERE uaid = %d LIMIT 1", $uaid));
}
function _heartbeat_who_is_private_user($op) {
switch ($op) {
case 'current':
global $user;
$uid = $user->uid;
break;
case 'argument':
$url_uid = args(1);
$uid = is_numeric($url_uid) ? $url_uid : 0;
break;
case 'all':
$uid = 0;
break;
default:
if (is_numeric($op)) {
$uid = $op;
}
}
return $uid;
}
function _heartbeat_access_type_options() {
return array(
HEARTBEAT_PRIVATE => t('Only the activity performed by the logged-in user'),
HEARTBEAT_PUBLIC_TO_ALL => t('Public to everyone'),
HEARTBEAT_PUBLIC_TO_ADDRESSEE => t('Public to the actor and the addressee. For specific user-user activity'),
HEARTBEAT_PUBLIC_TO_CONNECTED => t('friendlist, og, ... connected or related'),
);
}
function _heartbeat_activity_get_info() {
$sitename = ucfirst(variable_get('site_name', 'this site'));
$num_users = db_result(db_query("SELECT COUNT(uid) AS 'users' FROM {users} WHERE status= 1"));
$content .= '<div class="heartbeat_info_text">';
$content .= t('!sitename counts !num_users users', array(
'!sitename' => $sitename,
'!num_users' => $num_users,
));
$content .= '</div>';
return $content;
}