You are here

class HeartbeatActivity in Heartbeat 6.4

Same name and namespace in other branches
  1. 6.3 includes/heartbeatactivity.inc \HeartbeatActivity
  2. 7 includes/heartbeatactivity.inc \HeartbeatActivity

Class defines an activity message object

Hierarchy

Expanded class hierarchy of HeartbeatActivity

1 string reference to 'HeartbeatActivity'
heartbeat.module in ./heartbeat.module

File

includes/heartbeatactivity.inc, line 12
HeartbeatActivity object Defines one heartbeat activity object.

View source
class HeartbeatActivity {

  // DB fields
  public $uaid = 0;
  public $tuaid = 0;
  public $message_id = '';
  public $nid_info = '';
  public $nid_target_info = '';
  public $uid = 0;
  public $uid_access = TRUE;
  public $uid_target = 0;
  public $nid = 0;
  public $nid_access = TRUE;
  public $nid_target = 0;
  public $nid_target_access = TRUE;
  public $timestamp = 0;
  public $language = 'en';
  public $message = '';
  public $message_concat = '';
  public $access = HEARTBEAT_PUBLIC_TO_ALL;
  public $variables = array();
  public $additions = NULL;
  public $classes = '';

  // User object of the uid, being the actor of activity.
  public $actor = NULL;

  // Array of associated user activity ID's.
  public $uaids = array();

  // Template composite
  public $template = '';

  // Global properties on message base.
  public $display_time = TRUE;
  public $count = 0;

  // count for same instance
  public $target_count = 0;

  // count for same instance that is merged by target
  public $time_info_grouped = 0;
  public $delete_access = FALSE;
  public $actor_access = FALSE;

  // Template variables
  public $name = 'heartbeatactivity';
  public $type = 'heartbeatactivity';
  public $build_mode = 'none';
  public $content = array();

  /**
   * constructor
   * @param $data Array or Object with fields that can match this object
   *   Data for the message, some are converted.
   *   It's possible to give a sql-result set as data which will
   *   adapt to a heartbeatActivity object.
   * @param $template HeartbeatMessageTemplate
   *   holds the template data.
   */
  function __construct($data, HeartbeatMessageTemplate $template) {
    $this->template = $template;
    $this->additions = new stdClass();
    $this->message_id = $this->template->message_id;
    if (is_object($data)) {
      $data = (array) $data;
    }
    if (isset($data['uaid'])) {
      $this->uaid = $data['uaid'];
    }
    if (isset($data['count'])) {
      $this->count = $data['count'];
    }

    // Only load the user if it's needed.
    if (empty($data['mail'])) {
      $this->actor = heartbeat_user_load($data['uid']);
    }
    else {
      $account = new stdClass();
      $message_actor_data = unserialize($data['data']);
      unset($data['data']);
      $account->data = $message_actor_data;
      $account->heartbeat_activity_settings = isset($message_actor_data['heartbeat_activity_settings']) ? $message_actor_data['heartbeat_activity_settings'] : array();
      foreach (user_fields() as $field) {
        if (isset($data[$field])) {
          $account->{$field} = $data[$field];
        }
      }
      $this->actor = $account;
    }
    $this->uid = $data['uid'];
    $this->uid_target = $data['uid_target'];
    $this->nid = $data['nid'];
    $this->nid_info = !empty($data['nid_info']) ? unserialize($data['nid_info']) : array();
    $this->nid_target = isset($data['nid_target']) ? (int) $data['nid_target'] : 0;
    $this->nid_target_info = !empty($data['nid_target_info']) ? unserialize($data['nid_target_info']) : array();
    $this->timestamp = !empty($data['timestamp']) ? $data['timestamp'] : $_SERVER['REQUEST_TIME'];

    // For performance reasons, one activity has knowlegde of the comment count.
    $this->additions->comment_count = isset($data['uaid_comments']) ? $data['uaid_comments'] : 0;
    $this->access = (int) $data['access'];
    if (isset($data['message'])) {
      $this->message = $data['message'];
    }
    else {
      $this->message = $this->template->message;
    }
    if (!empty($data['message_concat'])) {
      $this->message_concat = $data['message_concat'];
    }
    else {
      $this->message_concat = $this->template->message_concat;
    }
    $this
      ->set_variables($data['variables']);
    if (isset($data['extra']['duplicate'])) {
      $this->variables['duplicate'] = $data['extra']['duplicate'];
    }
  }

  /**
   * Method gets a heartbeat_activity variable
   *
   * @desc The magic getter method fetches a variable
   *       in members. If not found there, it will always
   *       check the content holder as well
   */
  public function __get($variable) {
    return $this->variables[$variable];
  }

  /**
   * Method sets a heartbeat_activity property
   *
   * @desc The magic setter method sets a variable to member
   *  If not found, just stash in the content array
   */
  public function __set($variable, $value) {
    $this->variables[$variable] = $value;
  }

  /*
   * Rebuild the message with given candidate variables
   */
  public function rebuild_message($concat = FALSE) {
    if (count($this->variables) > 0) {
      $variables = array();
      foreach ($this->variables as $key => $value) {
        $key[0] = '!';
        $variables[$key] = $value;
      }
    }
    if ($concat) {
      return t($this->template->message_concat, $variables);
    }
    return t($this->template->message, $variables);
  }

  /**
   * Create the link for a delete button.
   */
  public function delete_button($args = array()) {
    $attributes = array(
      'query' => drupal_get_destination(),
      'alias' => TRUE,
    );
    if (count($this->uaids) > 1) {
      $attributes['attributes'] = array(
        'onclick' => 'javascript:Drupal.heartbeat.splitGroupedMessage(' . $this->uaid . ', new Array(' . implode(",", $this->uaids) . ')); return false;',
      );
    }
    $attributes += $args;
    return '<span class="hover-delete">' . l(t('Delete'), 'heartbeat/delete/' . $this->uaid, $attributes) . '</span>';
  }

  /*
   * Rebuild the message with given candidate variables
   */
  public function create_grouped_message($candidates, $max_items_to_group = 5) {
    global $base_url;
    $message_template = $this
      ->rebuild_message(TRUE);
    $message_extension = '';
    $message_template = str_replace("%times%", $this->target_count, $message_template);
    $message_template = str_replace("%count%", $this->target_count, $message_template);

    // Prepare the merged factors from the stored messages
    $merged_string = '';
    $remains = array();
    $target = $this->template->concat_args['group_target'];
    $beat = 'beat-item-' . $this->uaid;
    $unique = $candidates['variables'];
    $count = $candidates['count'];

    //count($candidates['variables']);

    // Limit the number of displayed (grouped) messages by message
    // or left as default global configuration
    if (!empty($this->template->concat_args['group_num_max'])) {
      $max_items_to_group = $this->template->concat_args['group_num_max'];
    }

    // Reduce the variables for substitution to the maximum
    // Add the remains by keeping the others plus the last one,
    // in case the total exceeds the max group setting.
    if ($count > $max_items_to_group) {
      $count = $max_items_to_group;
      $unique = array_slice($unique, 0, $count);
      $remains = array_slice($candidates['variables'], $count);
    }

    // Replacement of placeholder with group targets
    // If there is a match for %variable%
    // Try to replace the variable with the group_target variables
    if (preg_match_all("|\\%(.*)\\%(.*)|U", $message_template, $matches)) {
      if ($this->template->concat_args['show_remaining_items']) {
        $hidden_remains = theme('heartbeat_activity_remaining', $beat, $target, $remains);
      }

      // TODO Make a decision on how to handle the target on merged groups
      // This code in comment is/was a attempt to have more grouping words
      // The difficult and almost impossible part is the fact that you always
      // have to target something to group on (for the same node or same user)

      //foreach ($matches[1] as $target) {
      $placeholder = $matches[1][0];
      $i = 1;
      foreach ($unique as $stored_variables) {

        // limit them to the value given by the group variable setting
        if (isset($stored_variables["@" . $target])) {
          if ($i == 1) {
            $merged_string .= ' ' . $stored_variables["@" . $target];
          }
          elseif ($i < $count && $count > 2) {
            if (isset($this->template->concat_args['merge_separator_t']) && strlen(strip_tags($this->template->concat_args['merge_separator_t'])) > 0) {
              $merged_string .= ' ' . t($this->template->concat_args['merge_separator']);
            }
            else {
              $merged_string .= ' ' . $this->template->concat_args['merge_separator'];
            }
            $merged_string .= ' ' . $stored_variables["@" . $target];
          }
          elseif ($i == $count || $count == 2) {
            if (isset($this->template->concat_args['merge_end_separator_t']) && strlen(strip_tags($this->template->concat_args['merge_end_separator_t'])) > 0) {
              $merged_string .= ' ' . t($this->template->concat_args['merge_end_separator']);
            }
            else {
              $merged_string .= ' ' . $this->template->concat_args['merge_end_separator'];
            }
            if (count($remains) >= 1 && $hidden_remains != '') {

              // Add the last item.
              $merged_string .= ' ' . $stored_variables["@" . $target];
              if ($this->template->concat_args['show_remaining_items']) {

                // Add the remains.
                $message_extension .= $hidden_remains;

                // Add the link to the remaining items.
                $merged_string .= theme('hearbeat_activity_remain_link', $beat, count($remains));
              }
            }
            else {
              $merged_string .= ' ' . $stored_variables["@" . $target];
            }
          }
        }
        $i++;
      }
      $message_template = str_replace("%" . $placeholder . "%", $merged_string, $message_template);
      if (isset($message_extension)) {
        $message_template .= $message_extension;
      }

      //}
    }
    $this->message = $message_template;
  }

  /**
   * Public function to save activity to database
   * @param array raw argument to enforce as is (pre-renderd)
   */
  public function save($raw_args = array()) {
    $locale = module_exists('locale');
    if (!empty($this->nid)) {
      $node = node_load($this->nid);

      // Add extra node access information for nid.
      if (empty($this->nid_info)) {

        // Add extra node access information for nid.
        $this->nid_info = array(
          'uid' => $node->uid,
          'type' => $node->type,
          'format' => $node->format,
        );
      }
    }
    if (!empty($this->nid_target)) {
      $node_target = node_load($this->nid_target);

      // Add extra node access information for nid_target.
      $this->nid_target_info = array(
        'uid' => $node_target->uid,
        'type' => $node_target->type,
        'format' => $node_target->format,
      );
    }

    // if a user selected a language, then we follow i19n.
    if (isset($node) && !empty($node->language)) {
      return $this
        ->_save($raw_args, $node->language);
    }
    if ($locale) {
      return $this
        ->save_locale($raw_args);
    }
    else {
      return $this
        ->_save($raw_args);
    }
  }

  /**
   * Sets the variables array
   * Data variables are stored in an array to use them to build real variables.
   * this means that when activity message objects get merged, the variables
   * will be filled with variables components from all instances.
   */
  private function set_variables($variables = NULL) {
    if (!empty($variables)) {
      if (is_string($variables)) {
        $this->variables = heartbeat_decode_message_variables($variables);
      }
      elseif (is_array($variables)) {
        $this->variables = $variables;
      }
    }
  }

  /**
   * Save activity log with multilingual content
   * and multilingual parts to pre-translate
   *
   * @param array $raw_args
   */
  private function save_locale($raw_args = array()) {
    $logged = FALSE;
    $args = $this
      ->rebuild_arguments($raw_args, TRUE);
    $locale = $args['locale'];
    unset($args['locale']);

    // Save activity by logging a row for each active language
    // Translations only when locale exists
    $languages = locale_language_list();
    $tuaid = NULL;
    foreach ($languages as $language => $human_language) {

      // preprocess multilingual message "parts"
      // for all flagged token replacements
      foreach ($this->variables as $key => $value) {
        if (isset($locale[$key])) {
          $amp_token = str_replace("#", "!", $key);
          $args[$amp_token] = locale($locale[$key], $language);
        }
      }
      $uaid = $this
        ->log_message($args, $language);

      // Each language has the first uaid (user activity id) as
      // tuaid (translated user activity id)
      if ($uaid && !isset($tuaid)) {
        $tuaid = $uaid;
      }
      db_query("INSERT INTO {heartbeat_translations} SET tuaid=%d, uaid=%d", $tuaid, $uaid);
    }
    $this->uaid = $tuaid;
    return $tuaid;
  }

  /**
   * Save activity log
   *
   * @param array $raw_args
   */
  private function _save($raw_args = array(), $lang = '') {

    // Rebuild arguments with tokens
    $args = $this
      ->rebuild_arguments($raw_args);
    $this->uaid = $this
      ->log_message($args, $lang);
    return $this->uaid;
  }

  /**
   * Logs a heartbeat message
   * @param string language optional
   *
   */
  private function log_message($args, $lang = '') {
    if (empty($lang)) {
      global $language;
      $lang = $language->language;
    }
    $message = t($this->message, $args, $lang);
    $message_concat = t($this->message_concat, $args, $lang);

    // Checks if there should be logging what so ever
    if (empty($message)) {
      watchdog('heartbeat', 'Error in logging user activity: it is not possible to log empty message', array(), WATCHDOG_ERROR);
      return FALSE;
    }

    // Log relational message to user activity
    $logged = db_query("INSERT INTO {heartbeat_activity}\n      SET uid=%d, uid_target=%d, nid=%d, nid_target=%d, message_id='%s', language='%s',\n      access = %d, message ='%s',message_concat ='%s', timestamp=%d\n      , nid_info='%s', nid_target_info='%s', uaid_comments=%d, variables='%s'", $this->uid, $this->uid_target, $this->nid, $this->nid_target, $this->message_id, $lang, $this->access, $message, $message_concat, $this->timestamp, serialize($this->nid_info), serialize($this->nid_target_info), 0, heartbeat_encode_message_variables($this->variables));
    if (!$logged) {
      return 0;
    }
    $uaid = db_last_insert_id('heartbeat_activity', 'uaid');
    $this->uaids[] = $uaid;
    return $uaid;
  }

  /**
   * Rebuild the arguments for variables
   * to share within this object
   *
   * @param array $raw_input of arguments
   */
  private function rebuild_arguments($raw_input, $locale = FALSE) {
    $args = array();
    if ($locale) {

      // Variables that need to be pre-translated go here
      $args['locale'] = array();
    }
    $tags = heartbeat_allowed_tags();

    // Rebuild arguments with language tokens
    foreach ($this->variables as $key => $value) {
      $value = filter_xss($value, $tags);

      // Leave $key[0] == "!"  asis
      if ($key[0] != "@" && $key[0] != "#") {

        //continue; // bad argument
      }
      $oldkey = $key;

      // Reset the key of the arguments to ! to parse the next
      // tokenization asis.
      if ($key[0] == "@") {
        $key[0] = "!";
      }

      // # and @ token replacement prefixes are kept,
      // but set a flag for it in the raw_arguments
      if ($key[0] == "#") {

        // if it has to be translated ...
        if ($locale) {
          $args['locale'][$key] = $value;
        }

        // Now reset the key
        $key[0] = "!";
      }

      // if argument is prefilled, override
      if (isset($raw_input[$oldkey])) {
        $args[$key] = $raw_input[$oldkey];
        continue;
      }

      // Argument gets the value as in variables
      $args[$key] = $value;
    }
    return $args;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
HeartbeatActivity::$access public property
HeartbeatActivity::$actor public property
HeartbeatActivity::$actor_access public property
HeartbeatActivity::$additions public property
HeartbeatActivity::$build_mode public property
HeartbeatActivity::$classes public property
HeartbeatActivity::$content public property
HeartbeatActivity::$count public property
HeartbeatActivity::$delete_access public property
HeartbeatActivity::$display_time public property
HeartbeatActivity::$language public property
HeartbeatActivity::$message public property
HeartbeatActivity::$message_concat public property
HeartbeatActivity::$message_id public property
HeartbeatActivity::$name public property
HeartbeatActivity::$nid public property
HeartbeatActivity::$nid_access public property
HeartbeatActivity::$nid_info public property
HeartbeatActivity::$nid_target public property
HeartbeatActivity::$nid_target_access public property
HeartbeatActivity::$nid_target_info public property
HeartbeatActivity::$target_count public property
HeartbeatActivity::$template public property
HeartbeatActivity::$timestamp public property
HeartbeatActivity::$time_info_grouped public property
HeartbeatActivity::$tuaid public property
HeartbeatActivity::$type public property
HeartbeatActivity::$uaid public property
HeartbeatActivity::$uaids public property
HeartbeatActivity::$uid public property
HeartbeatActivity::$uid_access public property
HeartbeatActivity::$uid_target public property
HeartbeatActivity::$variables public property
HeartbeatActivity::create_grouped_message public function
HeartbeatActivity::delete_button public function Create the link for a delete button.
HeartbeatActivity::log_message private function Logs a heartbeat message
HeartbeatActivity::rebuild_arguments private function Rebuild the arguments for variables to share within this object
HeartbeatActivity::rebuild_message public function
HeartbeatActivity::save public function Public function to save activity to database
HeartbeatActivity::save_locale private function Save activity log with multilingual content and multilingual parts to pre-translate
HeartbeatActivity::set_variables private function Sets the variables array Data variables are stored in an array to use them to build real variables. this means that when activity message objects get merged, the variables will be filled with variables components from all instances.
HeartbeatActivity::_save private function Save activity log
HeartbeatActivity::__construct function constructor
HeartbeatActivity::__get public function Method gets a heartbeat_activity variable
HeartbeatActivity::__set public function Method sets a heartbeat_activity property