7.x-1.x branch
Module file for heartbeat activity. Basic hook implementations and helper functions will be found here.
heartbeat.streams.inc for functions on the streams
heartbeat.entity.inc for the definition of the entities/types.
| Name | Description |
|---|---|
| HeartbeatCtoolsObject | Class HeartbeatCtoolsObject |
| HeartbeatMessagePool | Class to keep HeartbeatActivity messages in a pool so plugins and such can get the message instead of reloading them. |
| InvalidHeartbeatCrudOperationException | Heartbeat invalid crud data exception. |
| PagerActivity | Query extender for heartbeat pager queries. |
| Name | Description |
|---|---|
| heartbeat_activity_delete | Deletes a heartbeat activity messages. |
| heartbeat_activity_load | Function to load one activity message. |
| heartbeat_activity_load_multiple | Load multiple activity records by user activity ID's. |
| heartbeat_activity_view | heartbeat_activity_view(). |
| heartbeat_allowed_html_tags | |
| heartbeat_api_log | API function to log a message from custom code |
| heartbeat_api_most_active_users | API function to retrieve the most active users. |
| heartbeat_block_configure | Implements hook_block_configure(). |
| heartbeat_block_info | Implements hook_block_info(). |
| heartbeat_block_save | Implements hook_block_save(). |
| heartbeat_block_view | Implements hook_block_view(). |
| heartbeat_cron | Implements hook_cron(). Delete too old message if this option is set and logs where the node does not exist anymore. |
| heartbeat_ctools_modal_prepare | Helper function to prepare a custom CTools Modal window. |
| heartbeat_ctools_plugin_api | Implements hook_ctools_plugin_api(). |
| heartbeat_decode_message_variables | Decode heartbeat message variables |
| heartbeat_ds_layout_info | Implements hook_ds_layout_info(). |
| heartbeat_encode_message_variables | Encode heartbeat message variables |
| heartbeat_forms | Implements hook_forms(). All heartbeat template forms share the same form handler. |
| heartbeat_form_user_profile_form_alter | Implements hook_form_FORM_ID_alter(). |
| heartbeat_heartbeat_activity_view | Implements hook_heartbeat_activity_view(). |
| heartbeat_heartbeat_related_uids | Implements hook_heartbeat_related_uids(). |
| heartbeat_help | Implements hook_help(). |
| heartbeat_image_default_styles | Implements hook_image_default_styles(). |
| heartbeat_init | Implements hook_init(). |
| heartbeat_log | User activity logger function |
| heartbeat_menu | Implements hook_menu(). |
| heartbeat_message_id_title | Function to load the title of message template pages. |
| heartbeat_message_template_delete | Function to delete heartbeat message templates. |
| heartbeat_message_template_load | Function to load heartbeat message templates. |
| heartbeat_modules_enabled | Implements hook_modules_enabled($modules). |
| heartbeat_node_delete | Implements hook_node_delete(). |
| heartbeat_permission | Implements hook_permission(). |
| heartbeat_preprocess_views_view | Preprocess the primary theme implementation for a view. |
| heartbeat_print_json | Helper function to print JSON data. |
| heartbeat_related_uids | Returns a set of users related to a central user. |
| heartbeat_stream_more_link | Helper function for a more link on streams (older messages) Should only be called when hasMoreMessages resulted to TRUE |
| heartbeat_templates_names | Get the heartbeat template messages names. |
| heartbeat_template_set_defaults | Set the default values for a heartbeat_template. |
| heartbeat_theme | Implements hook_theme(). |
| heartbeat_user_delete | Implements hook_user_delete(). |
| heartbeat_user_templates | Add the heartbeat template field to the user edit form. |
| heartbeat_user_templates_load | Helper function to load heartbeat user template settings. |
| heartbeat_user_templates_submit | Submit handler to save a users profile templates. |
| heartbeat_views_api | Implementation of hook_views_api(). |
| template_preprocess_heartbeat_activity | Process variables for heartbeat-activity.tpl.php. |
| theme_activity_pager | Returns HTML for a query pager for heartbeat activity. |
| theme_heartbeat_activity_avatar | The function for the avatar in a heartbeat activity message. |
| theme_heartbeat_buttons | Theme function for messages buttons. |
| theme_heartbeat_list | Theme function for a list of heartbeat activity messages. |
| theme_heartbeat_message_user_select_form | Theme function for the user profile form. |
| theme_heartbeat_time_ago | Theme function for the timestamp of a message. |
| _heartbeat_activity_get_access | Returns the permission to log a Message based on the access of the Template or the User setting. |
| _heartbeat_activity_load | Function to load one activity message. |
| _heartbeat_map_assoc | Helper function to map a array to dropdown with a field and value for the options |
| _heartbeat_message_delete_access | Helper function to check if a user has access to delete a message |
| _heartbeat_message_has_access | Helper function to check access on an Access type activity stream |
| _heartbeat_perms_options | Helper function to get the options for perm types |
| _heartbeat_user_load | Helper function to load the users from static cache. There should be something in core to handle this. |
| _theme_time_ago | Heartbeat typical time ago |
| _theme_user_message_select_form | Helper theme function for the activity selection in the user profile form |
| Name | Description |
|---|---|
| HEARTBEAT_NONE | |
| HEARTBEAT_PRIVATE | |
| HEARTBEAT_PUBLIC_TO_ADDRESSEE | |
| HEARTBEAT_PUBLIC_TO_ALL | |
| HEARTBEAT_PUBLIC_TO_CONNECTED |
- <?php
-
- /**
- * @file
- * Module file for heartbeat activity.
- * Basic hook implementations and helper functions will be found here.
- *
- * @see heartbeat.streams.inc for functions on the streams
- * @see heartbeat.entity.inc for the definition of the entities/types.
- *
- */
-
- /**
- * Message access
- *
- * What people can see and are entitled to see. This permission
- * on messages can be set as default per Heartbeat stream but
- * can be overriden in the configuration of a heartbeat message.
- */
-
- // Always block from display
- define('HEARTBEAT_NONE', -1);
-
- // Display only activity messages that are mine or addressed to me
- define('HEARTBEAT_PRIVATE', 0);
-
- // Only the person that is chosen by the actor, can see the message
- define('HEARTBEAT_PUBLIC_TO_ADDRESSEE', 1);
-
- // Display activity message of all my user relations, described in contributed modules
- define('HEARTBEAT_PUBLIC_TO_CONNECTED', 2);
-
- // Everyone can see this activity message, unless this type of message is set to private
- define('HEARTBEAT_PUBLIC_TO_ALL', 4);
-
- /**
- * Heartbeat message states to describe how they were built
- */
-
- /**
- * @file
- * Heartbeat module file
- */
- module_load_include('inc', 'heartbeat', 'heartbeat.streams');
- module_load_include('inc', 'heartbeat', 'heartbeat.entity');
-
- /**
- * Implements hook_help().
- */
- function heartbeat_help($path, $arg) {
- switch ($path) {
- case 'admin/help#heartbeat':
- $output = '';
- $output .= '<h3>' . t('About') . '</h3>';
- return $output;
- case 'admin/structure/heartbeat':
- return '<p>' . t('Heartbeat activity lets you create streams, composed together with message templates that are parsed into activity messages.') . '</p>';
- }
- }
-
- /**
- * Implements hook_init().
- */
- function heartbeat_init() {
- drupal_add_js(array('heartbeat_language' => $GLOBALS['language']->language), "setting");
- // Define the valid uri so javascript knows what to call.
- drupal_add_js(array('heartbeat_poll_url' => url('heartbeat/js/poll', array('absolute' => TRUE))), "setting");
- }
-
- /**
- * Implements hook_cron().
- * Delete too old message if this option is set and logs where
- * the node does not exist anymore.
- */
- function heartbeat_cron() {
-
- $uaids = array();
- $cron_delete_time = variable_get('heartbeat_activity_log_cron_delete', 2678400);
- $keep_latest_number = variable_get('heartbeat_activity_records_per_user', 10);
-
- $microseconds = microtime();
-
- // Delete activity older than the expiration date, while
- // keeping the latest X for each user.
- if ($cron_delete_time) {
-
- $expire = $_SERVER['REQUEST_TIME'] - $cron_delete_time;
-
- // Activity Ids that can not be removed (latest activity per user)
- $keep_uaids = array(0 => 0);
-
- // Calculate the latest activity for each user.
- $result = db_query("SELECT
- t1.uid,
- t1.uaid as 'uaid',
- COUNT(*) as 'rows_per_user',
- t1.timestamp as 'real_date',
- MIN(t2.timestamp) as 'oldest_date',
- count(t2.uid) AS 'count'
- FROM {heartbeat_activity} AS t1
- INNER JOIN {heartbeat_activity} AS t2 ON t1.uid = t2.uid AND t2.timestamp >= t1.timestamp
- WHERE (t1.timestamp, t1.uaid) < (t2.timestamp, t2.uaid)
- GROUP BY t1.uid, t1.uaid HAVING COUNT(t2.uid) <= :latest
- ORDER BY t1.uid, t1.uaid, t1.timestamp DESC", array(':latest' => $keep_latest_number));
-
- // $users = db_query("SELECT uid FROM {users} WHERE status = 1");
- // $query = array();
- // $args = array();
- // foreach ($users as $key => $account) {
- // $query[] = " ( SELECT uid, uaid FROM {heartbeat_activity} WHERE uid = :uid_$key ORDER BY uaid DESC LIMIT 0, :latest ) ";
- // $args[':uid_' . $key] = $account->uid;
- // $args[':latest'] = (int) $keep_latest_number;
- // }
- //
- // $result = db_query(implode("UNION", $query), $args);
-
- foreach ($result as $row) {
- $keep_uaids[$row->uaid] = $row->uaid;
- }
-
- //$arguments = array_merge(array($expire), $keep_uaids);
- $delete_result = db_query("SELECT uaid FROM {heartbeat_activity}
- WHERE timestamp < :expire AND uaid NOT IN (:uaids) ", array(':expire' => $expire, ':uaids' => $keep_uaids));
- foreach ($delete_result as $row) {
- $uaids[] = $row->uaid;
- }
-
- }
-
- if (!empty($uaids)) {
- heartbeat_activity_delete($uaids);
- }
-
- $microseconds_final = microtime();
- watchdog('cron', 'Cron finished in %secs seconds', array('%secs' => $microseconds_final - $microseconds));
-
- }
-
- /**
- * Implements hook_menu().
- */
- function heartbeat_menu() {
-
- $items = array();
-
- // Menu page callbacks for each heartbeat stream.
- $streams = heartbeat_stream_config_load_all(TRUE);
- foreach ($streams as $class => $stream) {
- if (!empty($stream->stream_path)) {
- $items[$stream->stream_path] = array(
- 'title' => $stream->title,
- 'description' => $stream->name . ' page',
- 'page callback' => 'heartbeat_messages_page',
- 'page arguments' => array($stream->class),
- 'access callback' => 'heartbeat_stream_has_access',
- 'access arguments' => array($stream->class),
- 'file' => 'heartbeat.pages.inc',
- 'type' => MENU_CALLBACK,
- );
- }
-
- if (!empty($stream->stream_profile_path)) {
- $items['user/%user/' . $stream->stream_profile_path] = array(
- 'title' => $stream->title,
- 'page callback' => 'heartbeat_messages_page',
- 'page arguments' => array($stream->class, '0', 1),
- 'access callback' => 'heartbeat_stream_has_access',
- 'access arguments' => array($stream->class),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'heartbeat.pages.inc',
- 'weight' => 50,
- );
- }
-
- }
-
- // Display one activity entity.
- $items['heartbeat/message/%heartbeat_activity'] = array(
- 'title' => 'Single message',
- 'description' => 'Activity message',
- 'page callback' => 'heartbeat_message_activity',
- 'page arguments' => array(2),
- 'access callback' => '_heartbeat_message_has_access',
- 'access arguments' => array(2),
- 'file' => 'heartbeat.pages.inc',
- );
-
- // Ajax driven callback to delete activity
- $items['heartbeat/%ctools_js/activity/delete/%heartbeat_activity'] = array(
- 'title' => 'Delete activity',
- 'page callback' => 'heartbeat_activity_modal_delete',
- 'page arguments' => array(1, 4),
- 'access callback' => '_heartbeat_message_delete_access',
- 'access arguments' => array(4),
- 'file' => 'heartbeat.pages.inc',
- 'type' => MENU_CALLBACK,
- );
-
- $items['heartbeat/js/poll'] = array(
- 'page callback' => 'heartbeat_activity_poll',
- 'access callback' => 'user_access',
- 'access arguments' => array('view heartbeat messages'),
- 'type' => MENU_CALLBACK,
- 'file' => 'heartbeat.pages.inc',
- );
-
- $items['heartbeat/js/older'] = array(
- 'page callback' => 'heartbeat_activity_older',
- 'access callback' => 'user_access',
- 'access arguments' => array('view heartbeat messages'),
- 'type' => MENU_CALLBACK,
- 'file' => 'heartbeat.pages.inc',
- );
-
- return $items;
-
- }
-
- /**
- * Implements hook_permission().
- */
- function heartbeat_permission() {
- $permissions = array(
- 'admin heartbeat templates' => array(
- 'title' => t('Administer heartbeat templates'),
- 'description' => t('Manage the heartbeat templates.')
- ),
- 'admin heartbeat delete all' => array(
- 'title' => t('Delete all activity'),
- 'description' => t('Master permission to delete all activity.')
- ),
- 'admin heartbeat delete own' => array(
- 'title' => t('Delete own activity'),
- 'description' => t('Permission for the actor to delete own activity.')
- ),
- 'view heartbeat messages' => array(
- 'title' => t('View activity'),
- 'description' => t('Global permission to view heartbeat activity.')
- ),
- 'access heartbeat activity profiles' => array(
- 'title' => t('Access heartbeat activity profiles'),
- 'description' => t('Permission to see user profiles or links to the user profile.')
- ),
- );
-
- foreach (heartbeat_stream_config_load_all(TRUE) as $streamConfig) {
- $permissions['view ' . $streamConfig->name . ' stream'] = array(
- 'title' => t('View activity in ' . $streamConfig->name),
- 'description' => t('Stream access: ' . $streamConfig->name . '.')
- );
-
- }
- return $permissions;
-
- }
-
- /**
- * Implements hook_user_delete().
- */
- function heartbeat_user_delete($account) {
-
- // Delete messages from removed users.
- $query = db_select('heartbeat_activity', 'ha');
- $query->addField('ha', 'uaid');
- $query->condition(db_or()
- ->condition('uid', $account->uid)
- ->condition('uid_target', $account->uid));
- foreach ($query->execute() as $row_object) {
- $uaids[] = $row_object->uaid;
- }
- if (!empty($uaids)) {
- heartbeat_activity_delete($uaids);
- }
-
- }
-
- /**
- * Implements hook_theme().
- */
- function heartbeat_theme() {
- return array(
- 'heartbeat_activity' => array(
- 'render element' => 'elements',
- 'template' => 'heartbeat-activity'
- ),
- 'heartbeat_activity_avatar' => array(
- 'variables' => array('heartbeatactivity' => NULL, 'uri' => NULL),
- ),
- 'activity_pager' => array(
- 'variables' => array('stream' => NULL),
- ),
- 'heartbeat_list' => array(
- 'variables' => array('stream' => NULL, 'content' => NULL),
- ),
- 'heartbeat_buttons' => array(
- 'variables' => array('heartbeat_activity' => NULL),
- ),
- 'heartbeat_time_ago' => array(
- 'variables' => array('heartbeat_activity' => NULL),
- ),
- 'heartbeat_message_user_select_form' => array(
- 'render element' => 'form',
- ),
- );
- }
-
- /**
- * Implements hook_block_info().
- */
- function heartbeat_block_info() {
-
- $blocks = array();
- $streams = heartbeat_stream_config_load_all(TRUE);
-
- // A block for each stream.
- foreach ($streams as $key => $stream_config) {
- if ($stream_config->has_block) {
- $blocks[$stream_config->class]['info'] = drupal_ucfirst($stream_config->title);
- }
- }
-
- // Heartbeat most active users.
- $blocks['heartbeat_active_users']['info'] = t('Heartbeat most active users');
-
- return $blocks;
-
- }
-
- /**
- * Implements hook_block_view().
- */
- function heartbeat_block_view($delta = '') {
-
- if ($delta == 'heartbeat_active_users') {
- $block['subject'] = t('Most active users');;
- $block['content'] = drupal_render(heartbeat_api_most_active_users(variable_get('heartbeat_active_users', 'default')));
- return $block;
- }
-
- // For blocks calling this page in general.
- $account = NULL;
- if (variable_get('heartbeat_show_user_profile_messages_' . $delta, 0) && arg(0) == 'user' && is_numeric(arg(1))) {
- $account = user_load(arg(1));
- }
-
- if ($heartbeatStream = heartbeat_stream($delta, FALSE, $account)) {
-
- if (variable_get('exclude_og_' . $delta, 0)) {
- $heartbeatStream->excludeOg(TRUE);
- }
-
- heartbeat_stream_build($heartbeatStream);
- $block_content = heartbeat_stream_view($heartbeatStream, $heartbeatStream->config->block_view_mode);
-
- if (!empty($block_content)) {
-
- $content = array();
- $content['#theme'] = 'heartbeat_list';
- $content['#stream'] = $heartbeatStream;
- $content['#content'] = $block_content;
- $content['#attached']['js'][] = drupal_get_path('module', 'heartbeat') . '/js/heartbeat.js';
- if (variable_get('heartbeat_include_default_style', 1)) {
- $content['#attached']['css'][] = drupal_get_path('module', 'heartbeat') . '/css/heartbeat.css';
- }
- // Dirty hack to fix polled streams when no js/css can be included on custom ajax command.
- $content['#attached']['css'][] = drupal_get_path('module', 'heartbeat') . '/layouts/heartbeat_2col/heartbeat_2col.css';
- $block['content'] = $content;
- }
-
- $block['subject'] = t($heartbeatStream->config->title);
-
- }
- else {
- return NULL;
- }
-
- return $block;
-
- }
-
- /**
- * Implements hook_block_configure().
- */
- function heartbeat_block_configure($delta = '') {
-
- if ($delta == 'heartbeat_active_users') {
- $info = entity_get_info('user');
- $options = array('default' => t('default')) + drupal_map_assoc(array_keys($info['view modes']));
- $form = array('view_mode' => array(
- '#type' => 'select',
- '#title' => t('Select view mode to render the users.'),
- '#default_value' => variable_get('heartbeat_active_users', 'default'),
- '#options' => $options,
- ));
- }
- else {
-
- $stream = heartbeat_stream_config_load($delta);
- $form = array('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_' . drupal_strtolower($stream->class), 0),
- ));
- if (module_exists('heartbeat_og')) {
- $form['exclude_og'] = array(
- '#type' => 'checkbox',
- '#title' => t('Exclude messages within Organic Group context.'),
- '#default_value' => variable_get('exclude_og_' . drupal_strtolower($stream->class), 0),
- );
- }
-
- }
-
- return $form;
- }
-
- /**
- * Implements hook_block_save().
- */
- function heartbeat_block_save($delta = '', $edit = array()) {
-
- if ($delta == 'heartbeat_active_users') {
- variable_set('heartbeat_active_users', (isset($edit['view_mode']) ? $edit['view_mode'] : 'default'));
- return;
- }
-
- $stream = heartbeat_stream_config_load($delta);
- variable_set('heartbeat_show_user_profile_messages_' . drupal_strtolower($stream->class), $edit['items']);
- variable_set('exclude_og_' . drupal_strtolower($stream->class), $edit['exclude_og']);
- }
-
- /**
- * Implements hook_node_delete().
- */
- function heartbeat_node_delete($node) {
-
- // Delete messages from deleted nodes.
- $query = db_select('heartbeat_activity', 'ha');
- $query->addField('ha', 'uaid');
- $query->condition('nid', $node->nid);
- foreach ($query->execute() as $row_object) {
- $uaids[] = $row_object->uaid;
- }
- if (!empty($uaids)) {
- heartbeat_activity_delete($uaids);
- }
-
- }
-
- /**
- * Implements hook_form_FORM_ID_alter().
- */
- function heartbeat_form_user_profile_form_alter(&$form, &$form_state) {
- if ($form['#user_category'] == 'account') {
- $profile_templates = variable_get('heartbeat_profile_message_templates', array());
- if (count($profile_templates)) {
- $form_state['heartbeat_templates'] = array();
- foreach (heartbeat_templates_names() as $id => $description) if (isset($profile_templates[$id])) {
- $form_state['heartbeat_templates'][$id] = $description;
- }
- heartbeat_user_templates($form, $form_state);
- }
- return $form;
- }
- }
-
- /**
- * Implements hook_heartbeat_related_uids().
- */
- function heartbeat_heartbeat_related_uids($uid) {
-
- $uids = array();
-
- if (module_exists('flag_friend')) {
- foreach (flag_friend_get_friends($uid) as $account) {
- $uids[$account->uid] = $account->uid;
- }
- }
-
- if (module_exists('user_relationships')) {
- $result = user_relationships_load(array('user' => $uid, 'approved' => 1));
- foreach ($result as $account) {
- $uids[$account->requestee_id] = $account->requestee_id;
- }
- }
-
- return $uids;
-
- }
-
- /**
- * Add the heartbeat template field to the user edit form.
- */
- function heartbeat_user_templates(&$form, &$form_state) {
-
- $account = $form['#user'];
-
- // The heartbeat privacy settings.
- $form['heartbeat'] = array(
- '#type' => 'fieldset',
- '#title' => t('Activity settings'),
- '#weight' => 7,
- '#collapsible' => TRUE,
- );
-
- $templates = heartbeat_user_templates_load($account->uid);
-
- // Privacy settings for streams.
- $form['heartbeat']['privacy'] = array('#tree' => TRUE);
- $form['heartbeat']['privacy']['default_template'] = array(
- '#type' => 'radios',
- '#title' => t("Privacy settings"),
- '#description' => t("This setting will apply to status updates to the profile when no access restriction is known (E.g. activity being logged from external sources)."),
- '#options' => _heartbeat_perms_options(),
- '#default_value' => isset($templates['0']) ? $templates['0']->status : HEARTBEAT_PRIVATE,
- );
-
- // Privacy settings on Heartbeat Templates.
- $form['heartbeat']['templates'] = array('#tree' => TRUE);
- foreach ($form_state['heartbeat_templates'] as $template_id => $description) {
-
- $template = heartbeat_message_template_load($template_id);
- $form['heartbeat']['templates'][$template_id] = array(
- '#type' => 'select',
- '#title' => $description,
- '#default_value' => isset($templates[$template_id]) ? $templates[$template_id]->status : HEARTBEAT_PUBLIC_TO_ALL,
- '#options' => _heartbeat_perms_options(TRUE, $template->perms),
- );
-
- }
-
- $hook = 'heartbeat_user_settings';
- foreach (module_implements($hook) as $module) {
- $function = $module .'_'. $hook;
- $function($form, $form_state);
- }
-
- $form['#submit'][] = 'heartbeat_user_templates_submit';
-
- }
-
- /**
- * Submit handler to save a users profile templates.
- */
- function heartbeat_user_templates_submit($form, $form_state) {
-
- if (!empty($form_state['values']['templates'])) {
-
- // Message templates for user will have the options:
- // HEARTBEAT_NONE, HEARTBEAT_PRIVATE, HEARTBEAT_PUBLIC_TO_ALL, HEARTBEAT_PUBLIC_TO_CONNECTED.
- db_delete('heartbeat_user_templates')
- ->condition('uid', $form['#user']->uid)
- ->execute();
- foreach ($form_state['values']['templates'] as $template_id => $permission) {
- db_insert('heartbeat_user_templates')
- ->fields(array('uid', 'message_id', 'status'), array($form['#user']->uid, $template_id, $permission))
- ->execute();
- }
- if (isset($form_state['values']['privacy']['default_template'])) {
- db_insert('heartbeat_user_templates')
- ->fields(array('uid', 'message_id', 'status'), array($form['#user']->uid, "0", $form_state['values']['privacy']['default_template']))
- ->execute();
- }
-
- }
-
- }
-
- /**
- * Helper function to load heartbeat user template settings.
- */
- function heartbeat_user_templates_load($uid) {
-
- $result = db_query("SELECT message_id, status FROM {heartbeat_user_templates} WHERE uid = :uid ", array(':uid' => $uid));
-
- $templates = array();
- foreach ($result as $row) {
- $templates[$row->message_id] = $row;
- }
-
- return $templates;
-
- }
-
- /**
- * Implements hook_ctools_plugin_api().
- */
- function heartbeat_ctools_plugin_api($owner, $api) {
- if ($owner == 'heartbeat' && $api == 'heartbeat') {
- return array('version' => 1);
- }
- }
-
- /**
- * Implementation of hook_views_api().
- */
- function heartbeat_views_api() {
- return array(
- 'api' => 3,
- 'path' => drupal_get_path('module', 'heartbeat'),
- );
- }
-
- /**
- * heartbeat_activity_view().
- *
- * @param String $message
- * The activity message object.
- */
- function heartbeat_activity_view($message, $view_mode = NULL) {
-
- if (isset($view_mode)) {
- $message->view_mode = $view_mode;
- }
-
- // Remove previously built content, if exists.
- $message->content = array();
-
- // Build fields content.
- field_attach_prepare_view('heartbeat_activity', array($message->uaid => $message), $message->view_mode, $message->language);
- entity_prepare_view('heartbeat_activity', array($message->uaid => $message), $message->language);
-
- $build = array(
- '#theme' => 'heartbeat_activity',
- '#heartbeat_activity' => $message,
- '#view_mode' => $message->view_mode,
- '#language' => $message->language,
- );
-
- $build += field_attach_view('heartbeat_activity', $message, $message->view_mode, $message->language);
-
- // Populate $message->content with a render() array.
- $hook = 'heartbeat_activity_view';
- foreach (module_implements($hook) as $module) {
- $function = $module . '_' . $hook;
- if (function_exists($function)) {
- $result = $function($message, $message->view_mode, $message->language);
- }
- }
- $build += $message->content;
- // We don't need duplicate rendering info in $message->content.
- unset($message->content);
-
- // Allow modules to modify the structured activity message.
- $type = 'heartbeat_activity';
- drupal_alter(array('heartbeat_activity_view', 'entity_view'), $build, $type);
-
- return $build;
-
- }
-
- /**
- * Implements hook_heartbeat_activity_view().
- *
- * @param HeartbeatActivity $heartbeatActivity
- * The activity message object.
- */
- function heartbeat_heartbeat_activity_view(HeartbeatActivity $heartbeatActivity, $view_mode = 'full', $language = NULL) {
-
- // Avatar.
- if (!empty($heartbeatActivity->actor->picture)) {
- if (is_numeric($heartbeatActivity->actor->picture)) {
- $uri = file_load($heartbeatActivity->actor->picture)->uri;
- }
- else {
- $uri = $heartbeatActivity->actor->picture->uri;
- }
- $heartbeatActivity->content['avatar'] = theme('heartbeat_activity_avatar', array('heartbeatactivity' => $heartbeatActivity, 'uri' => $uri));
- }
- // Default avatar.
- elseif (variable_get('user_picture_default', '')) {
- $heartbeatActivity->content['avatar'] = theme('heartbeat_activity_avatar', array('heartbeatactivity' => $heartbeatActivity, 'uri' => variable_get('user_picture_default', '')));
- }
-
- if ($heartbeatActivity->uid > 0 && $heartbeatActivity->actor) {
- $heartbeatActivity->content['username'] = array(
- '#markup' => theme('username', array('account' => $heartbeatActivity->actor)),
- );
- }
-
- // Activity message.
- $filter = new stdClass();
- $filter->settings = array('filter_url_length' => 60);
- $heartbeatActivity->content['message'] = array(
- '#attributes' => array('class' => array('activity-message')),
- '#title' => t('Heartbeat activity message'),
- '#markup' => _filter_url($heartbeatActivity->message, $filter),
- );
-
- // Timestamp of occurrence.
- $heartbeatActivity->content['time'] = array(
- '#title' => t('Activity on'),
- '#markup' => theme('heartbeat_time_ago', array('heartbeat_activity' => $heartbeatActivity)),
- );
-
- // Buttons for this message.
- $heartbeatActivity->content['buttons'] = array(
- '#markup' => theme('heartbeat_buttons', array('heartbeat_activity' => $heartbeatActivity)),
- );
-
- }
-
- /**
- * Process variables for heartbeat-activity.tpl.php.
- */
- function template_preprocess_heartbeat_activity(&$variables) {
-
- $variables['view_mode'] = $variables['elements']['#view_mode'];
- $variables['heartbeat_activity'] = $variables['elements']['#heartbeat_activity'];
- $message = $variables['heartbeat_activity'];
-
- $variables['content'] = array();
-
- // Prepare $content variable for template file.
- foreach (element_children($variables['elements']) as $key) {
- $variables['content'][$key] = $variables['elements'][$key];
- }
- $variables['classes_array'][] = $variables['zebra'];
- $variables['classes_array'][] = 'heartbeat-activity-' . $message->uaid;
- $variables['classes_array'][] = $message->message_id;
-
- $variables['attributes_array']['id'] = 'heartbeat-activity-' . $message->uaid;
-
- // Preprocess fields.
- field_attach_preprocess('heartbeat_activity', $message, $variables['elements'], $variables);
-
- }
-
- /**
- * Implements hook_image_default_styles().
- */
- function heartbeat_image_default_styles() {
- $styles = array();
-
- $styles['activity_avatar'] = array(
- 'effects' => array(
- array(
- 'name' => 'image_scale',
- 'data' => array('width' => 50, 'height' => 50, 'upscale' => 1),
- 'weight' => 0,
- ),
- )
- );
-
- return $styles;
- }
-
- /**
- * Implements hook_ds_layout_info().
- */
- function heartbeat_ds_layout_info() {
-
- $layouts = array(
- 'heartbeat_2col' => array(
- 'label' => t('Template with left/right for activity'),
- 'path' => drupal_get_path('module', 'heartbeat') . '/layouts/heartbeat_2col',
- 'regions' => array(
- 'heartbeat_left' => t('Left'),
- 'heartbeat_content' => t('Content'),
- 'heartbeat_footer' => t('Footer'),
- ),
- 'css' => TRUE,
- ),
- );
-
- return $layouts;
-
- }
-
- /**
- * Implements hook_modules_enabled($modules).
- */
- function heartbeat_modules_enabled($modules) {
- // Add the heartbeat in_group field if it does not exist yet.
- if (in_array('og', $modules) && db_table_exists('og')) {
- db_query("UPDATE {heartbeat_activity} SET in_group = 1 WHERE nid IN (SELECT DISTINCT etid FROM {og})");
- db_query("UPDATE {heartbeat_activity} SET in_group = 1 WHERE nid_target IN (SELECT DISTINCT etid FROM {og})");
- }
- }
-
- /**
- * Preprocess the primary theme implementation for a view.
- */
- function heartbeat_preprocess_views_view(&$vars) {
-
- $view = $vars['view'];
-
- if ($view->base_table == 'heartbeat_activity') {
-
- $vars['classes_array'][] = 'heartbeat-stream';
- $vars['classes_array'][] = 'heartbeat-messages-wrapper';
- $vars['classes_array'][] = 'heartbeat-stream-viewsactivity';
-
- }
-
- }
-
- /**
- * Heartbeat API functions.
- */
-
- /**
- * API function to retrieve the most active users.
- *
- * @param String $language
- * The language for the activity.
- * @param Integer $count
- * The count number / limit.
- */
- function heartbeat_api_most_active_users($view_mode, $count = 5, $language = NULL) {
-
- /*if (!isset($language)) {
- $language = $GLOBALS['language']->language;
- }*/
-
- $uids = array();
- $result = db_query_range("SELECT uid, COUNT(uaid) AS 'count' FROM {heartbeat_activity} WHERE uid > 0 GROUP BY uid ORDER BY count DESC ", 0, $count);
- foreach ($result as $row) {
- $uids[$row->uid] = $row->count;
- }
-
- $accounts = user_load_multiple(array_keys($uids));
- $users = array();
- foreach ($accounts as $account) {
- $users[$account->uid . '_' . $uids[$account->uid]] = user_view($account, $view_mode, $language);
- }
-
- return $users;
-
- }
-
- /**
- * API function to log a message from custom code
- *
- * @param string $message_id
- * Id of the message that is known in the message
- * @param integer $uid
- * Actor or user performing the activity
- * @param integer $uid_target [optional]
- * user id of the target user if present. Target users can be an addresse or a
- * user relation transaction with the actor $uid
- * @param integer $nid [optional]
- * Node id for content (for context node)
- * @param integer $nid_target [optional]
- * Node id for content that is related to other content
- * @param array $variables [optional]
- * Variables can be used if you used them in the used message. Take care to use
- * the @-sign for words that are prefix with the question mark sign in the messages
- * @param integer $access
- * The access to restrict the message
- */
- function heartbeat_api_log($message_id, $uid, $uid_target = 0, $nid = 0, $nid_target = 0, $variables = array(), $access = NULL, $time = 0, $in_group = 0) {
-
- $template = heartbeat_message_template_load($message_id);
-
- // Access can be given but usually we calculate it from Template Permissions
- // and overridable with the setting of the user.
- if (!isset($access) || !is_numeric($access)) {
- $access = _heartbeat_activity_get_access($uid, $template);
- }
-
- $data = array();
- // Normal form values
- $data['message_id'] = $message_id;
- $data['uid'] = $uid;
- $data['uid_target'] = $uid_target;
- $data['nid'] = $nid;
- $data['nid_target'] = $nid_target;
- $data['cid'] = isset($variables['cid']) ? $variables['cid'] : 0;
- $data['access'] = $access;
- $data['in_group'] = $in_group;
- $data['timestamp'] = $time == 0 ? $_SERVER['REQUEST_TIME'] : $time;
- $data['variables'] = $variables;
-
- return heartbeat_log($data);
-
- }
-
- /**
- * User activity logger function
- * @param The data to add one row
- */
- function heartbeat_log($data, $args = array()) {
-
- // Relational message of heartbeat messages
- $template = heartbeat_message_template_load($data['message_id']);
- $heartbeatactivity = new HeartbeatActivity($data, $template);
-
- // Prepare the fields.
- field_attach_presave('heartbeat_activity', $heartbeatactivity);
- module_invoke_all('heartbeat_activity_presave', $heartbeatactivity);
-
- // Save the record to the activity table.
- $saved = $heartbeatactivity->save($args);
-
- // Save fields.
- field_attach_insert("heartbeat_activity", $heartbeatactivity);
-
- // Invoke the heartbeat activity hooks.
- module_invoke_all("entity_insert", $heartbeatactivity, 'heartbeat_activity');
- module_invoke_all("heartbeat_activity_insert", $heartbeatactivity);
-
- return $saved;
-
- }
-
- /**
- * Returns a set of users related to a central user.
- */
- function heartbeat_related_uids($uid) {
-
- static $uids;
-
- if (!isset($uids[$uid])) {
-
- $uids[$uid] = array($uid => $uid);
-
- foreach (module_implements('heartbeat_related_uids') as $module) {
- $function = $module . '_heartbeat_related_uids';
- if (function_exists($function)) {
- $uids[$uid] += $function($uid);
- }
- }
- $uids[$uid] = array_unique($uids[$uid]);
-
- }
-
- return $uids[$uid];
-
- }
-
- /**
- * Function to load one activity message.
- */
- function heartbeat_activity_load($uaid) {
- return HeartbeatMessagePool::getInstance()->getMessage($uaid);
- }
-
- /**
- * Implements hook_forms().
- * All heartbeat template forms share the same form handler.
- */
- function heartbeat_forms($form_id, $args) {
- $forms = array();
-
- if (preg_match('/^heartbeat_activity_form_/', $form_id)) {
- $forms[$form_id] = array(
- 'callback' => 'heartbeat_activity_form',
- );
- }
-
- return $forms;
- }
-
- /**
- * Class to keep HeartbeatActivity messages in a pool so
- * plugins and such can get the message instead of reloading them.
- */
- class HeartbeatMessagePool {
-
- private static $instance = NULL;
- private $activity = array();
-
- /**
- * Constructor.
- */
- private function __construct() {
- }
-
- /**
- * getInstance().
- */
- public static function getInstance() {
- if (!isset(self::$instance)) {
- self::$instance = new HeartbeatMessagePool();
- }
- return self::$instance;
- }
-
- /**
- * getMessage().
- */
- public function getMessage($uaid) {
-
- if (!isset($this->activity[$uaid])) {
- $activity = _heartbeat_activity_load($uaid);
- if (!empty($activity)) {
- $this->addMessage($activity);
- return $this->activity[$uaid];
- }
- else {
- return NULL;
- }
- }
- else {
- return $this->activity[$uaid];
- }
-
- }
-
- /**
- * addMessage().
- */
- public function addMessage($heartbeatActivity) {
- if (isset($heartbeatActivity)) {
- if (!isset($this->activity[$heartbeatActivity->uaid])) {
- $this->activity[$heartbeatActivity->uaid] = $heartbeatActivity;
- }
- }
- }
-
- }
-
- /**
- * Function to load one activity message.
- */
- function _heartbeat_activity_load($uaid) {
-
- if (is_numeric($uaid)) {
- $activities = heartbeat_activity_load_multiple(array($uaid), array());
- return $activities ? $activities[$uaid] : $activities;
- }
-
- return FALSE;
-
- }
-
- /**
- * Load multiple activity records by user activity ID's.
- */
- function heartbeat_activity_load_multiple($uaids = array(), $conditions = array()) {
-
- $entities = entity_load('heartbeat_activity', $uaids, $conditions);
-
- $activities = array();
- foreach ($uaids as $uaid) {
-
- if (isset($entities[$uaid]) && $template = heartbeat_message_template_load($entities[$uaid]->message_id)) {
-
- $message = new HeartbeatActivity($entities[$uaid], $template);
- $message->count = 1;
- $activities[$uaid] = $message;
-
- HeartbeatMessagePool::getInstance()->addMessage($message);
-
- }
-
- }
-
- return $activities;
- }
-
- /**
- * Deletes a heartbeat activity messages.
- * @param Array $uaids
- * User activity IDs
- * @param Boolean $all
- * Indicates whether all activity should be deleted.
- */
- function heartbeat_activity_delete($uaids = array(), $all = FALSE) {
-
- // We don't delete all messages when not intended.
- if (empty($uaids) && $all == FALSE) {
- return;
- }
-
- $query = db_delete('heartbeat_activity');
-
- if (!empty($uaids) && $all == FALSE) {
- $query->condition('uaid', $uaids, 'IN');
- }
-
- $query->execute();
- //->where(" ha.message_id NOT IN (:messages) ", array(':messages' => $denied_messages));
-
- // Allow modules to respond to the deleting of a heartbeat activity message.
- module_invoke_all('heartbeat_activity_delete', $uaids, $all);
-
- }
-
- /**
- * Get the heartbeat template messages names.
- */
- function heartbeat_templates_names() {
-
- $names = array();
- ctools_include('export');
- foreach(ctools_export_crud_load_all('heartbeat_messages') as $template) {
- $names[$template->message_id] = $template->description;
- }
-
- return $names;
-
- }
-
- /**
- * Function to delete heartbeat message templates.
- * @param $id Int/String The target value to delete on
- * @param $type String The key field to perform delete query on
- * message : default
- * module : only defined by that module
- */
- function heartbeat_message_template_delete(HeartbeatMessageTemplate $template) {
- $template->delete();
- field_attach_delete_bundle('heartbeat_activity_template', $template->message_id);
- entity_get_controller('heartbeat_activity_template')->resetCache();
- cache_clear_all();
- }
-
- /**
- * Function to load heartbeat message templates.
- *
- * @param $id Int/String The target value to delete on
- * @param $type String The key field to perform delete query on
- * message : default
- * module : only defined by that module
- */
- function heartbeat_message_template_load($message_id) {
- ctools_include('export');
- return ctools_export_crud_load('heartbeat_messages', $message_id);
- }
-
- /**
- * Function to load the title of message template pages.
- */
- function heartbeat_message_id_title($template) {
- return $template->message_id;
- }
-
- /**
- * Set the default values for a heartbeat_template.
- *
- * The defaults are for a type defined through hook_heartbeat_template_info().
- * When populating a custom template $info should have the 'custom'
- * key set to 1.
- *
- * @param $info
- * An object or array containing values to override the defaults.
- *
- * @return
- * A heartbeat template object.
- */
- function heartbeat_template_set_defaults($info = array()) {
- $template = &drupal_static(__FUNCTION__);
-
- if (!isset($template)) {
- $template = new HeartbeatMessageTemplate();
- }
-
- $new_template = clone $template;
- $info = (array) $info;
- foreach ($info as $key => $data) {
- $new_template->$key = $data;
- }
- if (empty($new_template->module)) {
- $new_template->module = $new_template->base == 'heartbeat_content' ? 'heartbeat' : '';
- }
- $new_template->orig_type = isset($info['template']) ? $info['template'] : '';
-
- return $new_template;
- }
-
- /**
- * Query extender for heartbeat pager queries.
- *
- */
- class PagerActivity extends SelectQueryExtender {
-
- public $lastActivityId = 0;
-
- /**
- * The limit for this pager.
- */
- protected $limit = 0;
-
- public function __construct(SelectQueryInterface $query, DatabaseConnection $connection) {
- parent::__construct($query, $connection);
-
- // Add pager tag. Do this here to ensure that it is always added before
- // preExecute() is called.
- $this->addTag('pager');
- }
-
- /**
- * Override the execute method.
- *
- * Before we run the query, we need to add pager-based range() instructions
- * to it.
- */
- public function execute() {
-
- // Add convenience tag to mark that this is an extended query. We have to
- // do this in the constructor to ensure that it is set before preExecute()
- // gets called.
- if (!$this->preExecute($this)) {
- return NULL;
- }
-
- // A NULL limit is the "kill switch" for pager queries.
- if (empty($this->limit)) {
- return;
- }
-
- //$total_items = $this->getCountQuery()->execute()->fetchField();
- //$current_page = pager_default_initialize($total_items, $this->limit, $this->element);
- $this->range(0, $this->limit);
-
- // Now that we've added our pager-based range instructions, run the query normally.
- return $this->query->execute();
- }
-
- /**
- * Sets the last uaid
- */
- public function setLastActivityId($lastActivityId) {
- $this->lastActivityId = $lastActivityId;
- $this->query->condition('ha.uaid', $this->lastActivityId, '>');
- }
-
- /**
- * Sets the offset timestamps.
- */
- public function setOffsetTime($before, $after = 0) {
- $this->query->condition('ha.timestamp', $before, '<');
-
- if ($after > 0) {
- $this->query->condition('ha.timestamp', $_SERVER['REQUEST_TIME'] - $after, '>');
- }
- }
-
- /**
- * Specify the maximum number of elements per page for this query.
- *
- * The default if not specified is 10 items per page.
- *
- * @param $limit
- * An integer specifying the number of elements per page. If passed a false
- * value (FALSE, 0, NULL), the pager is disabled.
- */
- public function limit($limit = 10) {
- $this->limit = $limit;
- return $this;
- }
- }
-
- /**
- * Class HeartbeatCtoolsObject
- *
- * Ctools abstract class to inherit base properties.
- *
- */
- abstract class HeartbeatCtoolsObject {
-
- // The API version that this object implements.
- public $api_version = 1;
-
- // A boolean for whether the object is disabled.
- public $disabled = FALSE;
-
- // For objects that live in code, the module which provides the default object.
- public $export_module = '';
-
- // A bitmask representation of an object current storage. You can use this bitmask
- // in combination with the EXPORT_IN_CODE and EXPORT_IN_DATABASE constants to test
- // for an object's storage in your code.
- public $export_type = 0;
-
- // A boolean for whether the object lives only in code.
- public $in_code_only = FALSE;
-
- // The schema API table that this object belongs to.
- public $table = '';
-
- // A string representing the storage type of this object. Can be one of the following:
- // * Normal is an object that lives only in the database.
- // * Overridden is an object that lives in the database and is overriding the exported
- // configuration of a corresponding object in code.
- // * Default is an object that lives only in code.
- public $type = 'Overridden';
-
- }
-
-
- /**
- * Theme functions and helpers.
- */
-
- /**
- * The function for the avatar in a heartbeat activity message.
- */
- function theme_heartbeat_activity_avatar($variables) {
- $filepath = $variables['uri'];
- $alt = t("@user's picture", array('@user' => format_username($variables['heartbeatactivity']->actor)));
- if (module_exists('image') && file_valid_uri($filepath)) {
- $markup = theme('image_style', array(
- 'style_name' => 'activity_avatar',
- 'path' => $filepath,
- 'alt' => $alt,
- 'title' => $alt,
- 'attributes' => array('class' => 'avatar'),
- ));
- }
- else {
- $markup = theme('image', array(
- 'path' => $filepath,
- 'alt' => $alt,
- 'title' => $alt,
- 'attributes' => array('class' => 'avatar'),
- ));
- }
- return array('#markup' => $markup);
-
- }
-
- /**
- * Theme function for a list of heartbeat activity messages.
- */
- function theme_heartbeat_list($variables) {
-
- $heartbeatStream = $variables['stream'];
-
- if (!$heartbeatStream || !$heartbeatStream->hasAccess()) {
- return '';
- }
-
- global $user, $language;
- $content = '';
-
- $content .= $heartbeatStream->prefix;
-
- if (!isset($heartbeatStream->config) || empty($heartbeatStream->config->class)) {
-
- $content .= drupal_render($variables['content']);
-
- }
- else {
-
- $content .= '<div id="heartbeat-stream-' . $heartbeatStream->config->class . '" class="heartbeat-' . ($heartbeatStream->isPage() ? 'page' : 'block') . ' heartbeat-stream heartbeat-stream-' . $heartbeatStream->config->class . '">';
- $content .= '<div class="heartbeat-messages-wrapper">';
-
- if (empty($heartbeatStream->messages)) {
-
- $content .= '<p class="heartbeat-empty"><em>' . t('No activity yet.') . '</em></p>';
-
- }
- else {
-
- $content .= drupal_render($variables['content']);
-
- }
-
- $content .= '</div></div>';
-
- }
-
- $content .= $heartbeatStream->suffix;
-
- return $content;
- }
-
- /**
- * Theme function for the timestamp of a message.
- */
- function theme_heartbeat_time_ago($variables) {
-
- $message = $variables['heartbeat_activity'];
-
- $time_info = '';
-
- if ($message->show_message_times) {
- $message_date = _theme_time_ago($message->timestamp);
- if ($message->target_count <= 1 || $message->show_message_times_grouped) {
-
- $time_info .= '<span class="heartbeat-time-ago">';
- $time_info .= l($message_date, 'heartbeat/message/' . $message->uaid, array('html' => TRUE));
- $time_info .= '</span>';
-
- }
- }
-
- return $time_info;
- }
-
- /**
- * Theme function for messages buttons.
- *
- * @param $variables
- * Array of variables available for output.
- */
- function theme_heartbeat_buttons($variables) {
- $output = '';
- foreach($variables['heartbeat_activity']->buttons as $button) {
- $output .= $button;
- }
- return $output;
- }
-
- /**
- * Theme function for the user profile form.
- *
- * @param $variables
- * Array of variables available for output.
- */
- function theme_heartbeat_message_user_select_form($variables) {
-
- $form = $variables['form'];
-
- $rows = array();
- foreach (element_children($form) as $key) {
- $row = array();
- if (isset($form[$key]['title']) && is_array($form[$key]['title'])) {
- $row[] = drupal_render($form[$key]['title']);
- $row[] = drupal_render($form[$key]['access']);
- }
- $rows[] = $row;
- }
-
- $headers = array(t('Message types'), t('Operations'));
- $output = theme('table', array('headers' => $headers, 'rows' => $rows));
-
- return $output;
- }
-
- /**
- * Helper theme function for the activity selection
- * in the user profile form
- */
- function _theme_user_message_select_form($title, $settings) {
-
- if (empty($settings)) {
- $settings = array();
- }
-
- $templates = ctools_export_crud_load_all('heartbeat_messages');
- $options = _heartbeat_perms_options(TRUE);
-
- $form['heartbeat_activity_settings'] = array(
- '#type' => 'fieldset',
- '#title' => $title,
- '#weight' => 4,
- '#tree' => TRUE,
- '#collapsible' => TRUE,
- '#description' => t('This setting lets you configure the visibility of activity messages.'),
- '#theme' => 'heartbeat_message_user_select_form',
- );
-
- foreach ($templates as $template) {
-
- $form['heartbeat_activity_settings'][$template->message_id]['title'] = array(
- '#value' => !empty($template->description) ? $template->description : str_replace('_', ' ', $template->message_id),
- );
- $form['heartbeat_activity_settings'][$template->message_id]['access'] = array(
- '#type' => 'select',
- '#options' => $options,
- '#default_value' => isset($settings[$template->message_id]['access']) ? $settings[$template->message_id]['access'] : HEARTBEAT_PUBLIC_TO_ALL,
- );
-
- }
-
- return $form;
- }
-
- /**
- * Returns HTML for a query pager for heartbeat activity.
- *
- * @param $variables
- * An associative array containing:
- * - tags: An array of labels for the controls in the pager.
- * - element: An optional integer to distinguish between multiple pagers on
- * one page.
- * - parameters: An associative array of query string parameters to append to
- * the pager links.
- * - quantity: The number of pages in the list.
- *
- * @ingroup themeable
- */
- function theme_activity_pager($variables) {
- if ($variables['stream']->hasMoreMessages()) {
- $last_message = end($variables['stream']->messages);
- $link = heartbeat_stream_more_link($variables['stream'], $last_message->timestamp);
- return $link;
- }
- return '';
- }
-
- /**
- * Helper function for a more link on streams (older messages)
- * Should only be called when hasMoreMessages resulted to TRUE
- */
- function heartbeat_stream_more_link(HeartbeatStream $heartbeatStream, $offset_time, $absolute = FALSE) {
-
- $attributes = array(
- 'html' => FALSE,
- 'attributes' => array(
- 'class' => array('heartbeat-older-messages')
- )
- );
- $attributes['absolute'] = $absolute;
-
- $content = '';
- $content .= '<div class="heartbeat-more-messages-wrapper">';
-
- // Override the viewer if possible.
- $uid = $heartbeatStream->getViewedId();
- $is_page = (int) $heartbeatStream->isPage();
-
- // Ajax pager.
- if ($heartbeatStream->isAjax()) {
-
- $attributes['attributes']['onclick'] = 'javascript:Drupal.heartbeat.getOlderMessages(this, {ajax: true, stream_name: "' . $heartbeatStream->config->name . '" ,stream_class: "' . $heartbeatStream->config->class . '" ,offset_time: ' . $offset_time . ',page:' . $is_page . ', uid: '. $uid . ' }); return false;';
- if (method_exists($heartbeatStream, 'getGroup')) {
- $attributes['attributes']['class'][] = 'heartbeat-group-' . $heartbeatStream->getGroup()->nid;
- }
-
- $content .= l(t('Older messages'), 'heartbeat/js/older', $attributes);
- $content .= '<span class="heartbeat-messages-throbber"> </span>';
-
- }
- // Pager but no ajax.
- elseif ($is_page && !empty($heartbeatStream->config->stream_path)) {
-
- $attributes['query'] = array(
- 'ajax' => FALSE,
- 'stream_name' => $heartbeatStream->config->name,
- 'stream_class' => $heartbeatStream->config->class,
- 'offset_time' => $offset_time,
- 'page' => $is_page,
- 'uid' => $uid
- );
- $content .= l(t('Older messages'), $heartbeatStream->config->stream_path, $attributes);
- $content .= '<span class="heartbeat-messages-throbber"> </span>';
-
- }
-
- // Link to the pages.
- if (!$heartbeatStream->isPage() && !empty($heartbeatStream->config->stream_path)
- && (!$heartbeatStream->isAjax() || $heartbeatStream->config->block_show_pager == 3)) {
- $path = $heartbeatStream->config->stream_path;
- if (isset($attributes['attributes']['onclick'])) {
- unset($attributes['attributes']['onclick']);
- }
- $fulllink = '<div class="more fullarchive heartbeat-full">' . l(t('Full list'), $path, $attributes) . '</div>';
- $content .= $fulllink;
- }
-
- $content .= '</div>';
-
- return $content;
-
- }
-
- /**
- * helper functions.
- */
-
- /**
- * Helper function to load the users from static cache.
- * There should be something in core to handle this.
- */
- function _heartbeat_user_load($uid) {
- static $users = array();
- if (!isset($users[$uid])) {
- $users[$uid] = user_load($uid);
- }
- return $users[$uid];
- }
-
- /**
- * Helper function to prepare a custom CTools Modal window.
- */
- function heartbeat_ctools_modal_prepare() {
-
- static $ran = FALSE;
-
- if (!$ran) {
-
- ctools_include('modal');
- ctools_include('ajax');
-
- // Add CTools' javascript to the page.
- ctools_modal_add_js();
-
- // Add the effects library.
- drupal_add_library('system', 'effects.highlight');
- drupal_add_library('system', 'effects.blind');
-
- // Create our own javascript that will be used to theme a modal.
- $style = array(
- 'ctools-heartbeat-style' => array(
- 'modalSize' => array(
- 'type' => 'fixed',
- 'width' => 500,
- 'height' => 300,
- 'addWidth' => 20,
- 'addHeight' => 15,
- ),
- 'modalOptions' => array(
- 'opacity' => .5,
- 'background-color' => '#111',
- ),
- 'animation' => 'fadeIn',
- 'modalTheme' => 'CToolsHeartbeatModal',
- 'throbber' => theme('image', array('path' => drupal_get_path('module', 'heartbeat') . '/images/ajax-loader.gif', 'alt' => t('Loading...'), 'title' => t('Loading'))),
- ),
- );
- drupal_add_js($style, 'setting');
-
- $ran = TRUE;
-
- }
-
- }
-
- /**
- * Helper function to print JSON data.
- */
- function heartbeat_print_json($data) {
- drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8');
- print drupal_json_encode($data);
- }
-
- /**
- * Decode heartbeat message variables
- */
- function heartbeat_decode_message_variables($string, $object = FALSE) {
-
- if (!is_string($string)) {
- return array();
- }
-
- // Variable string need to be cleared from spaces to decode properly
- $array = explode("-|-", $string);
- $variables = array();
- if (!empty($array)) {
- foreach ($array as $varvalue) {
- $parts = explode("=|=", $varvalue);
- if (isset($parts[0]) && !empty($parts[0])) {
- if (preg_match("/\*\*\*/", $parts[1])) {
- $parts[1] = explode("***", $parts[1]);
- }
- $variables[$parts[0]] = !is_array($parts[1]) ? (string)$parts[1] : $parts[1];
- }
- }
- }
-
- return $object ? (object) $variables : (array) $variables;
- }
-
- /**
- * Encode heartbeat message variables
- */
- function heartbeat_encode_message_variables($array) {
- $string = '';
- foreach ($array as $key => $value) {
- if (is_array($value)) {
- $value = implode('***', $value);
- }
- $string .= $key .'=|='. $value .'-|-';
- }
- //$string = serialize((object)$array);
- return $string;
- }
-
- /*
- * Helper function to retrieve the allowed html tags.
- */
- function heartbeat_allowed_html_tags() {
- $tags = variable_get('heartbeat_allowed_html_tags', 'a em strong blockquote ul ol li p div');
- return explode(" ", $tags);
- }
-
- /**
- * Helper function to map a array to dropdown
- * with a field and value for the options
- *
- * @param array $options
- * @param string target $field
- * @param sring target $value
- * @return array mapped for options dropdown
- */
- function _heartbeat_map_assoc($options, $field, $value) {
- $mapped = array();
- foreach ($options as $heartbeat_activity) {
- $mapped[$heartbeat_activity->{$field}] = $heartbeat_activity->{$value};
- }
- return $mapped;
- }
-
- /**
- * Returns the permission to log a Message based on the access
- * of the Template or the User setting.
- */
- function _heartbeat_activity_get_access($uid, $template) {
-
- $templates = heartbeat_user_templates_load($uid);
-
- // If the user has configured access to this type, use it.
- if (isset($templates[$template->message_id])) {
- $access = $templates[$template->message_id]->status;
- }
- else {
- // If the user configured general access.
- if (isset($templates['0'])) {
- $access = $templates['0']->status;
- }
- // Use the general permission for this template.
- else {
- $access = $template->perms;
- }
- }
-
- return $access;
- }
-
- /**
- * Helper function to check access on an Access type activity stream
- */
- function _heartbeat_message_has_access($heartbeatActivity) {
- if (user_access('view Single activity stream') && $heartbeatActivity instanceof HeartbeatActivity) {
- return $heartbeatActivity->hasAccess($GLOBALS['user']);
- }
- return FALSE;
- }
-
- /**
- * Helper function to get the options for perm types
- * @param boolean $profile indicator for personal or profile labels
- * @return array of perm types
- */
- function _heartbeat_perms_options($profile = FALSE, $max_perm = HEARTBEAT_PUBLIC_TO_ALL) {
-
- $permissions = array();
-
- if ($profile) {
- $perms = array(
- HEARTBEAT_NONE => ('Never'),
- HEARTBEAT_PRIVATE => t('Only me'),
- HEARTBEAT_PUBLIC_TO_CONNECTED => t('Only my friends'),
- HEARTBEAT_PUBLIC_TO_ALL => t('Everyone'),
- );
- }
- else {
- $perms = array(
- HEARTBEAT_PRIVATE => t('Only the user himself is allowed to see this message'),
- HEARTBEAT_PUBLIC_TO_ADDRESSEE => t('Only the user himself and the addressee are allowed to see this message'),
- HEARTBEAT_PUBLIC_TO_CONNECTED => t('Only user and relations are allowed to see this message'),
- HEARTBEAT_PUBLIC_TO_ALL => t('Everyone can see this message'),
- );
- }
-
- foreach ($perms as $access => $desc) {
- if ($access <= $max_perm) {
- $permissions[$access] = $desc;
- }
- }
-
- return $permissions;
-
- }
-
- /**
- * Heartbeat typical time ago
- * @return String with the time.
- */
- function _theme_time_ago($time) {
- return t('@time ago', array('@time' => format_interval(($_SERVER['REQUEST_TIME'] - $time), 1))) ;
- }
-
- /**
- * Helper function to check if a user has access to delete a message
- */
- function _heartbeat_message_delete_access($heartbeatActivity) {
- if (user_access('admin heartbeat delete all')) {
- return TRUE;
- }
-
- return $heartbeatActivity->uid == $GLOBALS['user']->uid && user_access('admin heartbeat delete own');
- }
-
- /**
- * Heartbeat invalid crud data exception.
- */
- class InvalidHeartbeatCrudOperationException extends Exception {
- }
-