You are here

hrules.module in Heartbeat 6.4

Heartbeat rules implementation module

@author Stalski (Jochen Stals) - Menhir - www.menhir.be

@notes

RULES

The rules module can trigger an event based action that is delegated to the heartbeat logger. This is nice because you can use tokens to replace heartbeat message variables. This way you can customize your message and keep its parts very variable. To fully be creative with heartbeat as non-developer, you have to digg in the rules ui (and code). Lots of documentation can be found on http://drupal.org/node/298480 for an introduction and tutorial, but http://drupal.org/node/298486 is a lot of handy info for developers.

DEMOSITE

See also the demosite at heartbeat.menhireffect.be where lots of code examples are exposed as well as downloadable rules, tokens and examples of hook implementations.

File

modules/heartbeat_rules/hrules.module
View source
<?php

//

/**
 * @file
 *   Heartbeat rules implementation module
 *
 * @author
 *   Stalski (Jochen Stals) - Menhir - www.menhir.be
 *
 * @notes
 *
 *   RULES
 *
 *   The rules module can trigger an event based action that is
 *   delegated to the heartbeat logger. This is nice because you
 *   can use tokens to replace heartbeat message variables. This
 *   way you can customize your message and keep its parts very
 *   variable.
 *   To fully be creative with heartbeat as non-developer, you have to
 *   digg in the rules ui (and code). Lots of documentation can be
 *   found on http://drupal.org/node/298480 for an introduction and
 *   tutorial, but http://drupal.org/node/298486 is a lot of handy
 *   info for developers.
 *
 *   DEMOSITE
 *
 *   See also the demosite at heartbeat.menhireffect.be where lots
 *   of code examples are exposed as well as downloadable rules, tokens
 *   and examples of hook implementations.
 *
 */

/**
 * Implementation of hook_menu().
 */
function hrules_menu() {
  $items = array();
  $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',
    ),
  );
  return $items;
}

/**
 * Implementation of hook_token_list().
 */
function hrules_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_message']['heartbeat-message-uaid'] = t("Activity message ID");
    $tokens['heartbeat_message']['heartbeat-message-type'] = t("Machine name of the activity message template");
    $tokens['heartbeat_message']['heartbeat-message-uid'] = t("Message owner's user id");
    $tokens['heartbeat_message']['heartbeat-message-nid'] = t("Attached node's ID");
    $tokens['heartbeat_message']['heartbeat-message-language'] = t("Activity message language");
    $tokens['heartbeat_message']['heartbeat-message-nid-target'] = t("Target node ID");
    $tokens['heartbeat_message']['heartbeat-message-uid-target'] = t("Target user ID");
    $tokens['heartbeat_message']['heartbeat-message'] = t("The logged heartbeat message");
    $tokens['heartbeat_message']['heartbeat-message-raw'] = t("The logged heartbeat message in raw format");
    $tokens['heartbeat_message']['heartbeat-message-url'] = t("Absolute url to the parent activity message");
    $tokens['heartbeat_message']['heartbeat-message-link'] = t("Link to the parent activity message, the title is the moment it occurred");
    $tokens['heartbeat_message']['heartbeat-actor-picture'] = t("Avatar of the actor with a link to it leading to the user account page.");
  }
  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 (module_exists('image')) {
      $tokens['image']['node-image-thumbnail-link'] = t("An image thumbnail with a link to it");
      $tokens['image']['node-image-preview-link'] = t("An image preview 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>");
    $tokens['user']['heartbeat-user-picture'] = t("Avatar of the actor with a link to it leading to the user account page.");
  }
  return $tokens;
}

/**
 * Implementation of hook_token_values().
 */
function hrules_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-uaid'] = $object->uaid;
      $values['heartbeat-message-type'] = $object->message_id;
      $values['heartbeat-message-uid'] = $object->uid;
      $values['heartbeat-message-nid'] = $object->nid;
      $values['heartbeat-message-language'] = $object->language;
      $values['heartbeat-message-nid-target'] = $object->nid_target;
      $values['heartbeat-message-uid-target'] = $object->uid_target;
      $values['heartbeat-message'] = $object->message;
      $values['heartbeat-message-raw'] = check_plain($object->message);
      $values['heartbeat-message-url'] = url('heartbeat/message/' . $object->uaid, array(
        'absolute' => TRUE,
      ));
      $values['heartbeat-message-link'] = l(_theme_time_ago($object->timestamp), 'heartbeat/message/' . $object->uaid, array(
        'html' => TRUE,
      ));
      $values['heartbeat-actor-picture'] = l(theme('user_picture', $object->actor), 'user/' . $object->actor->uid, array(
        'html' => TRUE,
      ));
      break;
    case 'node':
      $values['title-link'] = l($object->title, 'node/' . $object->nid);
      $account = heartbeat_user_load($object->uid);
      $values['author-name-url'] = l($account->name, 'user/' . $account->uid, array(
        'attributes' => array(
          'class' => 'user',
        ),
      ));
      if (module_exists('image') && isset($object->images)) {
        $thumbnail = theme('image', $object->images['thumbnail'], $object->title, $object->title);
        $values['node-image-thumbnail-link'] = l($thumbnail, 'node/' . $object->nid, array(
          'html' => TRUE,
        ));
        $preview = theme('image', $object->images['preview'], $object->title, $object->title);
        $values['node-image-preview-link'] = l($preview, 'node/' . $object->nid, array(
          'html' => TRUE,
        ));
      }
      break;
    case 'user':
      if ($object->uid) {
        $name = check_plain($object->name);
        $values['user-name-url'] = l($name, 'user/' . $object->uid, array(
          'alias' => 'TRUE',
          'attributes' => array(
            'class' => 'user',
          ),
        ));
        $values['user-profile-url'] = l($name, 'profile/' . $object->name, array(
          'attributes' => array(
            'class' => 'user',
          ),
        ));
        $values['heartbeat-user-picture'] = l(theme('user_picture', $object), 'user/' . $object->uid, array(
          'html' => TRUE,
        ));
      }
      else {
        $anon = variable_get('anonymous', 'Anonymous');
        $values['user-name-url'] = $anon;
        $values['user-profile-url'] = $anon;
        $values['heartbeat-user-picture'] = '<span class="user-picture">' . $anon . '</span>';
      }
      break;
    case 'global':
      break;
  }
  return $values;
}

/**
 * Callback function to add variables to the
 *  user activity actions forms
 */
function heartbeat_activity_rules_action_message_id_js() {
  $message = heartbeat_message_load($_GET['message_id'], 'message_id');
  if (isset($message)) {
    $default_values = heartbeat_rule_action_get_variables($message, heartbeat_encode_message_variables($message->variables));
  }

  // Updating the drupal settings to be able to do one ahah request after another
  $javascript = drupal_add_js(NULL, NULL, 'header');

  // Final rendering callback.
  return drupal_json(array(
    'status' => TRUE,
    'data' => isset($default_values) ? $default_values : '',
    'message' => isset($message->message) ? $message->message : '',
    'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
  ));
}

/**
 * Helper function to fetch the defined variables for this message
 */
function heartbeat_rule_action_get_variables($message, $values = array()) {
  $defined_variables = heartbeat_match_variables($message->message, $message->message_concat);

  // If words are found as match to a heartbeat message variable,
  // variables are needed in the message
  if (count($defined_variables['words']) > 0) {

    // Add the textarea where all the magic variables go into
    return heartbeat_variables_compare($defined_variables['words'], $values);
  }
  return '';
}

/**
 * Function looks for variables in an array of given strings
 * @return array of words and variables found (separately stored)
 * @remark
 *   %targetnames% do not have to be tokenized
 */
function heartbeat_match_variables() {
  $args = func_get_args();
  $string = '';
  $string .= implode(' ', array_values($args));
  preg_match_all("/\\!([a-zA-Z0-9_]+)/", $string, $matches);
  $words = $matches[1];
  $variables = $matches[0];
  $found = array(
    'words' => $words,
    'variables' => $variables,
  );
  return $found;
}

/**
 * compares variables that need to be included
 *   with variables that are already there and
 *   check their values to fit as default value
 *   in a textarea
 *
 * @param array $settings
 * @param array $form_settings
 * @param string $variables
 * @return string fit for textarea
 */
function heartbeat_variables_compare($variables = array(), $defaults = array(), $flipped = TRUE) {
  $default_values = '';

  // normal settings from rules action, rules cache
  $vars = array();
  if (isset($defaults)) {
    $vars = heartbeat_decode_message_variables($defaults, FALSE);
  }
  if ($flipped) {
    $variables = array_flip($variables);
  }

  // See if there is already a token assignment on a variable
  foreach ($variables as $variable_word => $key) {

    // Standardize possible variable formats
    $variable_normal = !eregi("@", $variable_word) ? "@" . $variable_word : $variable_word;
    $variable_part = !eregi("#", $variable_word) ? "#" . $variable_word : $variable_word;
    if (!empty($vars[$variable_normal])) {
      $default_values .= $variable_normal . "=" . $vars[$variable_normal] . "\r\n";
    }
    elseif (!empty($vars[$variable_part])) {
      $default_values .= $variable_part . "=" . $vars[$variable_part] . "\r\n";
    }
    elseif (!empty($vars[$variable_word])) {
      $default_values .= $variable_normal . "=" . $vars[$variable_word] . "\r\n";
    }
    else {
      $default_values .= $variable_normal . "=\r\n";
    }
  }
  return $default_values;
}

Functions

Namesort descending Description
heartbeat_activity_rules_action_message_id_js Callback function to add variables to the user activity actions forms
heartbeat_match_variables Function looks for variables in an array of given strings
heartbeat_rule_action_get_variables Helper function to fetch the defined variables for this message
heartbeat_variables_compare compares variables that need to be included with variables that are already there and check their values to fit as default value in a textarea
hrules_menu Implementation of hook_menu().
hrules_token_list Implementation of hook_token_list().
hrules_token_values Implementation of hook_token_values().