class heartbeatParser in Heartbeat 6.3
Same name and namespace in other branches
- 6.4 includes/heartbeatparser.inc \heartbeatParser
- 7 includes/heartbeatparser.inc \heartbeatParser
Hierarchy
- class \heartbeatParser
Expanded class hierarchy of heartbeatParser
File
- includes/
heartbeatparser.inc, line 3
View source
class heartbeatParser {
private $_info = null;
private $_candidates = array();
private $_messages = array();
private $_sets = array();
private $_timespan_gap = 0;
private $_allowed_tags = array(
'a',
'span',
'em',
'strong',
'ul',
'li',
'p',
'img',
);
private function __construct() {
}
/**
* Set the first time , start time of the gap
*/
public function set_timespan_gap($gap) {
$this->_timespan_gap = $gap;
}
/**
* build sets of messages
*/
public function build_sets($messages_raw) {
$renewal_time = $_SERVER['REQUEST_TIME'] - $this->_timespan_gap;
$raw_messages = array();
foreach ($messages_raw as $key => $message) {
// if the time with the gap exceeds the starttime
if ($renewal_time >= $message->timestamp) {
// reset the start time of the set
$renewal_time = $message->timestamp - $this->_timespan_gap;
}
$this->_sets[$renewal_time][$key] = new HeartbeatActivity($message);
}
}
/**
* Sets information on heartbeat messages in total
*/
public function set_info(HeartbeatInfo $info) {
$this->_info = $info;
}
public function get_info() {
return $this->_info;
}
/**
* Merges sets of messages to fully formatted messages
* regenerated at runtime to group settings
*/
public function merge_sets() {
$set_count = 0;
foreach ($this->_sets as $message_set) {
$this
->prepare_candidates($message_set, $set_count);
$set_count++;
}
$this
->remove_variables_duplicates();
$this
->rebuild_in_groups();
return $count;
}
/**
* Gets the messages as they exist for the time asked
*/
public function get_messages($limit = 25) {
if ($limit > 0) {
return array_slice($this->_messages, 0, $limit);
}
return $this->_messages;
}
/**
* Function to remove duplicate messages
* meaning remove exactly the same already build messages,
* incrementing the count of the messages
* User-user relation always have duplicates that need to be removed.
* This is handled here as well. Take care: the counter cannot increment!
* @TODO Refactor this crappy shit
*/
private function remove_message_duplicates($message_set) {
global $user;
$ow_relations = array();
foreach ($message_set as $key => $message) {
if ($message->concat_args['group_by'] == 'user-user') {
if (!isset($ow_relations[$message->uid_target])) {
$ow_relations[$message->uid_target] = array();
}
// Find bad duplicates in two way relations (5-2 and 2-5)
if (!in_array($message->uid, $ow_relations[$message->uid_target])) {
$ow_relations[$message->uid][] = $message->uid_target;
}
}
}
foreach ($message_set as $key => $message) {
if ($message->concat_args['group_by'] == 'user-user') {
// If i am not the actor, but one of my relations is
// and i am the target for the relation, then
// it is a duplicate message
/*if($this->_info->access == HEARTBEAT_PUBLIC_TO_CONNECTED) {
if($message->uid_target == $user->uid && in_array($message->uid, $user->heartbeat_relations)) {
unset($message_set[$key]);
}
}
if($this->_info->access == HEARTBEAT_PUBLIC_TO_ALL) {
if(!in_array($message->uid, $ow_relations[$message->uid_target])) {
unset($message_set[$key]);
}
}*/
if (!in_array($message->uid, $ow_relations[$message->uid_target])) {
unset($message_set[$key]);
}
}
}
// hash holding all unique values
// if this would be static ...you could do it for all timespan-sets
$holder = array();
foreach ($message_set as $key => $message) {
// if an exact identical message occurs contextual wise,
// then skip it with an incrementation of the frequency
// of the message
$id = $message->message_id . '-' . $message->uid . '-' . $message->uid_target . '-' . $message->nid_target;
if (in_array($id, $holder)) {
$message_set[array_search($id, $holder)]->count++;
unset($message_set[$key]);
}
else {
$holder[$key] = $id;
//$message->message;
}
}
return $message_set;
}
/**
* Prepare message candidates
* This is an important method that handles several things
* - Build an id for each time-gap limiting groupable messages
* - Hold the candidates for each id (and count of messages)
* - Logic to handle the group_by node or user setting
*/
private function prepare_candidates($message_set, $set_count = 0) {
static $singles = 0;
// Remove duplicate messages in the same set,
// incrementing the counter on the grouped message
$message_set = $this
->remove_message_duplicates($message_set);
foreach ($message_set as $key => $message) {
$type = $message->concat_args['type'];
// Variable to hold the unique grouping gap id.
// Extending the gap id will result in summaries
// and groups of identical and related messages.
$gap_id = 'BEAT_' . $set_count . '_' . $message->message_id;
// Summaries have to be evaluated for merging
if ($type == 'summary' && $this
->extend_gap_id($gap_id, $message, $type, $set_count)) {
// Add a candidates if this one does not exist yet
if (!isset($this->_candidates[$gap_id])) {
$this->_candidates[$gap_id] = array(
'count' => 0,
'group_target' => $message->concat_args['group_target'],
'variables' => array(),
);
// Add the message
$this->_messages[$gap_id] = $message;
}
// Add the counters and variables needed for merging in groups
$this->_messages[$gap_id]->target_count++;
// Message occurrency, first time is 1
$this->_candidates[$gap_id]['variables'][] = $message->variables_array;
$this->_candidates[$gap_id]['count']++;
// variable count, NOT the same as target_count
}
elseif ($type == 'count') {
//$gap_id = $gap_id . '_'.$message->uid;
$gap_id = $gap_id . '_count';
$this->_messages[$gap_id] = $message;
$this->_messages[$gap_id]->target_count++;
}
else {
// Autoincrement the singles to make the gap_id unique
$gap_id .= '_single_' . $singles;
$this->_messages[$gap_id] = $message;
$singles++;
}
}
}
/**
* Remove broken messages
* @Todo build this function
*/
public function remove_broken_messages($messages = array()) {
if ($messages == array()) {
$messages = $this->_messages;
}
return $messages;
}
/**
* Function to remove duplicate messages valuating the
* variables and count properties
*/
private function remove_variables_duplicates() {
$uniques = array();
foreach ($this->_candidates as $single_id => $info) {
$uniques[$single_id] = array();
// Loop through variables to check if there are identical
foreach ($info['variables'] as $rid => $value) {
if (!in_array($value, $uniques[$single_id])) {
$uniques[$single_id][] = $value;
}
else {
unset($this->_candidates[$single_id]['variables'][$rid]);
}
}
}
// Re-evaluate the counts
foreach ($this->_candidates as $single_id => $info) {
$this->_candidates[$single_id]['count'] = count($this->_candidates[$single_id]['variables']);
}
return $uniques;
}
/**
* Private helper function to build the gap_id
*/
private function extend_gap_id(&$gap_id, $message, $type, $set_count) {
// Extend the gap id with the node_type if available
if (!empty($message->variables_array['@node_type'])) {
$gap_id .= '_' . $message->variables_array['@node_type'];
}
// group by node will result in a summary of users
// performing the activity
if ($message->concat_args['group_by'] == 'node') {
$gap_id .= '_' . $message->concat_args['group_target'] . '_node_' . $message->nid_target;
}
else {
if ($message->concat_args['group_by'] == 'user') {
$gap_id .= '_' . $message->concat_args['group_target'] . '_user_' . $message->uid;
}
else {
if ($message->concat_args['group_by'] == 'user-user') {
$gap_id .= '_user_relation';
$gap_id .= '_' . $message->uid;
}
else {
// Handle the fall-backs as unique messages
$gap_id .= '_' . $message->uid . '_' . $message->uid_target;
}
}
}
return TRUE;
}
/**
* Function to rebuild the messages in groups
* all sets are handled already
*/
private function rebuild_in_groups() {
// Check the candidates and make the rebuild array
foreach ($this->_candidates as $single_id => $info) {
$this->_messages[$single_id]->message = filter_xss($this->_messages[$single_id]->message, $this->_allowed_tags);
$this->_messages[$single_id]->message_concat = filter_xss($this->_messages[$single_id]->message_concat, $this->_allowed_tags);
$message = $this->_messages[$single_id];
// if a candidate exists for this message and
// it has more than one count
// Take care!! not message->count because this could be set with the sql as well
// The purpose would be to fill %times% or its alias %count%
if ($this->_candidates[$single_id]['count'] > 1) {
$message_template = $this->_messages[$single_id]->message_concat;
$message_template = str_replace("%times%", $message->target_count, $message_template);
$message_template = str_replace("%count%", $message->target_count, $message_template);
// Prepare the merged factors from the stored messages
$merged_string = '';
$unique = $info['variables'];
$count = $info['count'];
//count($info['variables']);
/**
* TODO Make a message property to handle max_messages_count
**/
if ($count > variable_get('heartbeat_activity_grouping_how_many', 6)) {
$count = variable_get('heartbeat_activity_grouping_how_many', 6);
$unique = array_slice($unique, 0, $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)) {
/**
* TODO Make a decision on how to handle the target on merge 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];
$target = $message->concat_args['group_target'];
//dsm($target.$placeholder);
$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];
}
else {
if ($i < $count && $count > 2) {
$merged_string .= ' ' . $message->concat_args['merge_separator'];
$merged_string .= ' ' . $stored_variables["@" . $target];
}
else {
if ($i == $count || $count == 2) {
$merged_string .= ' ' . $message->concat_args['merge_end_separator'];
$merged_string .= ' ' . $stored_variables["@" . $target];
}
}
}
}
$i++;
}
$message_template = str_replace("%" . $placeholder . "%", $merged_string, $message_template);
//}
}
$this->_messages[$single_id]->message = $message_template;
}
}
}
/**
* Creates an instance of heartbeat as singleton
*/
public static function instantiate($type = 'cached') {
static $instances;
if (!$instances) {
$instances = array();
}
if (!isset($instances[$type])) {
$instances[$type] = new HeartbeatParser();
}
return $instances[$type];
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
heartbeatParser:: |
private | property | ||
heartbeatParser:: |
private | property | ||
heartbeatParser:: |
private | property | ||
heartbeatParser:: |
private | property | ||
heartbeatParser:: |
private | property | ||
heartbeatParser:: |
private | property | ||
heartbeatParser:: |
public | function | build sets of messages | |
heartbeatParser:: |
private | function | * Private helper function to build the gap_id | |
heartbeatParser:: |
public | function | ||
heartbeatParser:: |
public | function | Gets the messages as they exist for the time asked | |
heartbeatParser:: |
public static | function | Creates an instance of heartbeat as singleton | |
heartbeatParser:: |
public | function | Merges sets of messages to fully formatted messages regenerated at runtime to group settings | |
heartbeatParser:: |
private | function | Prepare message candidates This is an important method that handles several things | |
heartbeatParser:: |
private | function | * Function to rebuild the messages in groups * all sets are handled already | |
heartbeatParser:: |
public | function | Remove broken messages @Todo build this function | |
heartbeatParser:: |
private | function | Function to remove duplicate messages meaning remove exactly the same already build messages, incrementing the count of the messages User-user relation always have duplicates that need to be removed. This is handled here as well. Take care: the… | |
heartbeatParser:: |
private | function | * Function to remove duplicate messages valuating the * variables and count properties | |
heartbeatParser:: |
public | function | Sets information on heartbeat messages in total | |
heartbeatParser:: |
public | function | Set the first time , start time of the gap | |
heartbeatParser:: |
private | function |