View source
<?php
function heartbeat_admin_settings() {
$form['heartbeat_enabled'] = array(
'#title' => t('Do you want to enable the heatbeat logging'),
'#type' => 'checkbox',
'#default_value' => variable_get('heartbeat_enabled', 1),
);
$form['heartbeat_show_message_times'] = array(
'#title' => t('Show the time of action in message displays'),
'#type' => 'checkbox',
'#default_value' => variable_get('heartbeat_show_message_times', 1),
);
$form['heartbeat_show_time_grouped_items'] = array(
'#title' => t('Show the time of action with messages are grouped together'),
'#type' => 'checkbox',
'#default_value' => variable_get('heartbeat_show_time_grouped_items', 1),
);
return system_settings_form($form);
}
function heartbeat_messages_overview() {
global $base_url;
if (module_exists('rules')) {
$intro = t('Go to !link to add your conditional actions to one of the existing events.', array(
'!link' => l('rules administration', 'admin/rules/trigger'),
));
}
$info = heartbeat_gather_messages();
if (!empty($info)) {
drupal_set_message(t('New messages were added to heartbeat.'));
}
$messages = heartbeat_messages('all', true, true);
if (count($messages) <= 0) {
return t('No messages yet');
}
$languages = module_exists('locale') ? locale_language_list() : array();
foreach ($messages as $message) {
if ($languages != array()) {
_heartbeat_messages_overview_language($languages, $message);
}
$rows[] = array(
strlen($message->description) <= 0 ? str_replace('_', ' ', $message->message_id) : $message->description,
$message->module,
$message->message_type,
l(t('edit'), $base_url . "/admin/build/heartbeat/edit/" . $message->hid, array(
'query' => 'destination=admin/build/heartbeat/list',
)) . ' - ' . l(t('delete'), $base_url . "/admin/build/heartbeat/delete/" . $message->hid, array(
'query' => 'destination=admin/build/heartbeat/list',
)),
);
}
$headers = array(
t('Description'),
t('Module'),
t('Message type'),
t('Operations'),
);
if (module_exists('locale')) {
$intro .= t('<p>The messages are passed to the t-function when parsed to view.</p>
<p>This means that once they are viewed, they are available for you to translate.
Altering these messages will clear the rules cache and the altered message
will need translation if you are dealing with a multilingual site.
The links show only the untranslated messages.</p>');
}
return $intro . theme('table', $headers, $rows);
}
function _heartbeat_messages_overview_language($languages, &$message) {
$fake_message = t($message->message);
$fake_message_concat = t($message->message_concat);
$report = array();
foreach ($languages as $lang => $human_language) {
if ($lang != 'en') {
if (locale($message->message, $lang) == locale($message->message, 'en')) {
$label = t('@human_language translation', array(
'@human_language' => strip_tags($human_language),
));
$options = array(
'query' => 'op=Search&string=' . str_replace(" ", "+", $message->message),
);
$report[] = l($label, 'admin/build/translate/search', $options);
}
if (t($message->message_concat, array(), $lang) == t($message->message_concat, array(), 'en')) {
$label = t('@human_language translation', array(
'@human_language' => strip_tags($human_language),
));
$options = array(
'query' => 'op=Search&string=' . str_replace(" ", "+", $message->message_concat),
);
$report[] = l($label, 'admin/build/translate/search', $options);
}
}
}
if ($report != array()) {
$message->description .= '<div><small>' . implode(', ', $report) . '</small></div>';
}
}
function heartbeat_messages_delete($hid) {
global $base_url;
$result = db_query("DELETE FROM {heartbeat_messages} WHERE hid = %d LIMIT 1", $hid);
if (isset($_REQUEST['destination'])) {
drupal_set_message(t('Message deleted'));
drupal_goto($base_url . '/' . urlencode($_REQUEST['destination']));
}
}
function heartbeat_messages_add(&$form_state, $edit = array()) {
return heartbeat_messages_edit($form_state, 0, $edit);
}
function heartbeat_messages_edit(&$form_state, $hid = 0, $edit = array()) {
drupal_add_js(drupal_get_path('module', 'heartbeat') . '/heartbeat.js');
$form = array();
if ($hid) {
$result = db_query("SELECT * FROM {heartbeat_messages} WHERE hid = %d LIMIT 1", $hid);
$message = db_fetch_object($result);
$concat_args = heartbeat_decode_message_variables($message->concat_args);
if (!empty($concat_args)) {
$message->concat_args = array();
foreach ($concat_args as $arg => $value) {
$message->concat_args[$arg] = $value;
}
}
}
else {
$message = new StdClass();
}
$form['message_id'] = array(
'#type' => 'textfield',
'#title' => t('Unique but descriptive message id'),
'#description' => t('Example "heartbeat_add_content" in the format heartbeat_do_something.'),
'#default_value' => empty($edit['message_id']) ? $message->message_id : $edit['message_id'],
'#disabled' => $hid ? TRUE : FALSE,
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description of the message'),
'#description' => t('(most of the time you already have an event in mind)'),
'#cols' => 60,
'#rows' => 1,
'#default_value' => empty($edit['description']) ? $message->description : $edit['description'],
);
$form['perms'] = array(
'#type' => 'select',
'#title' => t('Message display access'),
'#description' => t('Defines to whom the message is ment for and who is entitled to see the message.'),
'#options' => array(
0 => t('Only me'),
1 => t('Everyone can see this message'),
2 => t('People I am connected to'),
),
'#default_value' => empty($edit['perms']) ? $message->perms : $edit['perms'],
);
$module_list = module_list();
asort($module_list);
$form['module'] = array(
'#type' => 'select',
'#title' => t('Module to filter in views'),
'#options' => $module_list,
'#default_value' => empty($edit['module']) ? $message->module : $edit['module'],
);
$form['message_type'] = array(
'#type' => 'select',
'#title' => t('Type of the message and can be used as a filter in views'),
'#options' => heartbeat_get_message_types(),
'#default_value' => empty($edit['message_type']) ? $message->message_type : $edit['message_type'],
'#ahah' => array(
'path' => 'heartbeat/message_types/js',
'wrapper' => 'heartbeat-type-messages',
'event' => 'change',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['examples'] = array(
'#type' => 'fieldset',
'#title' => t('Examples of message variables'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['examples']['tokens']['#type'] = 'markup';
$form['examples']['tokens']['#value'] = '<p>' . t('Here are a few examples of usage of variables in heartbeat messages:') . '</p><div>';
$form['examples']['tokens']['#value'] .= '<small>' . t('!username has updated !node_title') . ' (for a single message)</small><br />';
$form['examples']['tokens']['#value'] .= '<small>' . t('!username has added %node_title%') . ' (for grouped messages with variable summary)</small><br />';
if (module_exists('friendlist_api')) {
$form['examples']['tokens']['#value'] .= '<small>' . t('!user1 is now !relation_type with !user2') . ' (use %user2% if user1 becomes friends with lots of users in last timespan)</small><br />';
}
$form['examples']['tokens']['#value'] .= '</div><p>' . t('Always append your variables with ! or embed the word in %\'s to group several instances of one part of a message.') . '</p>';
$form['message'] = array(
'#type' => 'textarea',
'#title' => t('Single message'),
'#cols' => 60,
'#rows' => 1,
'#required' => TRUE,
'#default_value' => empty($edit['message']) ? $message->message : $edit['message'],
'#description' => t('"!" is available to interpret a words as variables.'),
);
$desc = t('Type of message when it comes to grouping messages together.<br />
<strong>Single</strong> is when you want to repeat messages without merging them together. These messages
are standalone and they dont take notice on previous and upcoming messages.<br />
<strong>Count</strong> means you want to merge the messages together so you know the occurrency.
Only one message in its single format will be displayed.<br />
A <strong>summary</strong> is when you want to group the same instance of several messages together.
For this you will summarize a part of the message and use it as substitional variables (with separators) to
form the merged messages. The occurrency of the message instance is also known as the count.<br />');
$form['type'] = array(
'#id' => 'heartbeat_message_type',
'#type' => 'select',
'#title' => t('Type of message'),
'#description' => $desc,
'#options' => drupal_map_assoc(variable_get('heartbeat_types', array(
'single',
'summary',
'count',
))),
'#required' => TRUE,
'#default_value' => empty($edit['type']) ? $message->concat_args['type'] : $edit['type'],
'#attributes' => array(
'onchange' => 'javascript:heartbeat_message_type_onchange(this); return false;',
),
);
$form['type_summary'] = array(
'#type' => 'markup',
'#prefix' => '<div id="type-summary-wrapper">',
'#suffix' => '</div>',
);
$form['type_summary']['message_concat'] = array(
'#type' => 'textarea',
'#title' => t('Message to group instances'),
'#description' => t('You can use "%" to indicate that a variable word needs to be replaced with multiple instances of another variable (target variable). This is used when messages are merged together.<br />! is still available'),
'#cols' => 60,
'#rows' => 2,
'#default_value' => empty($edit['message_concat']) ? $message->message_concat : $edit['message_concat'],
);
$form['type_summary']['group_by'] = array(
'#type' => 'select',
'#options' => array(
'none' => t('No grouping'),
'user' => 'user',
'node' => 'node',
'user-user' => 'user-user',
),
'#title' => t('Group by'),
'#description' => t('<strong>Required for types summary. </strong>Messages with parts that merge together are grouped by user or node.
E.g. Group by node if you want to summarize users and vice versa.<br />In some cases where the activity uses a relation
between two users, then set the group by to "user-user". A good example is a friend-relation.'),
'#required' => FALSE,
'#default_value' => empty($edit['group_by']) ? $message->concat_args['group_by'] : $edit['group_by'],
);
$desc = t('<blockquote>
Grouped message: !username added %images%.
Single message: !username added an !image and a nice one.
Then you will group by user and build a summary of images. The grouping variable here is "image".
</blockquote>');
$form['type_summary']['group_target'] = array(
'#type' => 'textfield',
'#title' => t('Group or merge variable'),
'#description' => t('If you used a word between %-signs, you have to fill in the message variable you used that needs to be replaced with a summary.') . '<br /> e.g.:' . $desc,
'#required' => FALSE,
'#default_value' => empty($edit['group_target']) ? $message->concat_args['group_target'] : $edit['group_target'],
);
$form['type_summary']['merge_separator'] = array(
'#type' => 'textfield',
'#title' => t('Fill in the target separator'),
'#description' => t('Separators between the targets, like a colon. E.g. "title1<strong>,</strong> title2 and title3"'),
'#required' => FALSE,
'#default_value' => empty($edit['merge_separator']) ? $message->concat_args['merge_separator'] : $edit['merge_separator'],
);
$form['type_summary']['merge_end_separator'] = array(
'#type' => 'textfield',
'#title' => t('Fill in the target end separator.'),
'#description' => t('Separators finishing listed targets. E.g. "title1, title2 <strong>and</strong> title3"'),
'#required' => FALSE,
'#default_value' => empty($edit['merge_end_separator']) ? $message->concat_args['merge_end_separator'] : $edit['merge_end_separator'],
);
$form['hid'] = array(
'#type' => 'hidden',
'#default_value' => empty($edit['hid']) ? $message->hid : $edit['hid'],
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
'#weight' => 50,
);
if (isset($edit['hid'])) {
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
}
$form['data'] = array(
'#tree' => TRUE,
);
return $form;
}
function heartbeat_messages_add_submit($form, &$form_state) {
if ($form_state['clicked_button']['#value'] != t('Save')) {
return;
}
if (!empty($form_state['values']['message'])) {
$variables = array(
'type' => $form_state['values']['type'],
'group_by' => $form_state['values']['group_by'],
'group_target' => $form_state['values']['group_target'],
'merge_separator' => $form_state['values']['merge_separator'],
'merge_end_separator' => $form_state['values']['merge_end_separator'],
'perms' => $form_state['values']['perms'],
);
if (!empty($form_state['values']['data'])) {
$variables = array_merge($variables, $form_state['values']['data']);
}
$concat_args = heartbeat_encode_message_variables($variables);
$result = db_query("INSERT INTO {heartbeat_messages} SET message_id ='%s', custom = %d, message ='%s', message_concat ='%s',\n message_type = '%s', perms = %d, description = '%s', module = '%s', concat_args = '%s' ", $form_state['values']['message_id'], (int) $form_state['values']['custom'], $form_state['values']['message'], $form_state['values']['message_concat'], $form_state['values']['message_type'], $form_state['values']['perms'], $form_state['values']['description'], $form_state['values']['module'], $concat_args);
drupal_set_message(t('New message was added and can be used in actions of a rule'));
}
return;
}
function heartbeat_messages_edit_submit($form, &$form_state) {
if ($form_state['clicked_button']['#value'] == t('Save')) {
$variables = array(
'type' => $form_state['values']['type'],
'group_by' => $form_state['values']['group_by'],
'group_target' => $form_state['values']['group_target'],
'merge_separator' => $form_state['values']['merge_separator'],
'merge_end_separator' => $form_state['values']['merge_end_separator'],
'perms' => $form_state['values']['perms'],
);
if (!empty($form_state['values']['data'])) {
$variables = array_merge($variables, $form_state['values']['data']);
}
$concat_args = heartbeat_encode_message_variables($variables);
if (db_query("UPDATE {heartbeat_messages} SET message ='%s', message_concat ='%s',\n description = '%s', module = '%s' , concat_args = '%s', perms = %d\n WHERE hid = %d", $form_state['values']['message'], $form_state['values']['message_concat'], $form_state['values']['description'], $form_state['values']['module'], $concat_args, $form_state['values']['perms'], $form_state['values']['hid'])) {
drupal_set_message(t('Settings saved'));
}
}
return;
}
function heartbeat_activity_rules_action_message_id_js() {
module_load_include('inc', 'rules', 'rules.input_evaluators');
module_load_include('inc', 'rules_admin', 'rules_admin');
$form_state = array(
'submitted' => FALSE,
);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$hm_form = $form['settings']['variables_param'];
unset($hm_form['#prefix'], $hm_form['#suffix']);
$output = drupal_render($hm_form);
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => $output,
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
function heartbeat_messages_export($form_state = array()) {
$form = array();
$messages = heartbeat_messages('all', true, true);
if (count($messages) == 0) {
return t('There are not heartbeat messages to export.');
}
if (!isset($form_state['export'])) {
$form['messages'] = array(
'#tree' => TRUE,
);
foreach ($messages as $message) {
$form['messages']['m_' . $message->hid] = array(
'#type' => 'checkbox',
'#title' => $message->description,
'#default_value' => 1,
'#description' => $message->message,
);
}
$form['button'] = array(
'#type' => 'submit',
'#weight' => 10,
'#value' => t('Export'),
);
}
else {
$form['result'] = array(
'#type' => 'textarea',
'#title' => 'Exported heartbeat messages',
'#description' => 'Copy this data and paste them in <strong>hook_heartbeat_message_info</strong>.',
'#rows' => 15,
'#attributes' => array(
'readonly' => 'readonly',
),
'#default_value' => var_export(heartbeat_messages_export_messages($form_state['export']), 1),
);
}
return $form;
}
function heartbeat_messages_export_submit($form, &$form_state) {
$count = 0;
foreach ($form_state['values']['messages'] as $key => $value) {
$count += $value;
}
if ($count) {
$form_state['export'] = $form_state['values']['messages'];
$form_state['rebuild'] = TRUE;
}
}
function heartbeat_messages_export_messages($selected_messages) {
$messages = heartbeat_messages('all', true, false);
if (count($messages) == 0) {
return t('There are not heartbeat messages to export.');
}
$info = array();
foreach ($messages as $message) {
$message = (object) $message;
if (!$selected_messages['m_' . $message->hid]) {
continue;
}
$concat_args = heartbeat_decode_message_variables($message->concat_args);
$variables = heartbeat_decode_message_variables($message->variables);
$info[$message->hid] = array(
'message' => $message->message,
'message_concat' => $message->message_concat,
'message_id' => $message->message_id,
'message_type' => $message->message_type,
'concat_args' => $concat_args,
'module' => $message->module,
'description' => $message->description,
'variables' => $variables,
);
}
return $info;
}
function heartbeat_message_type_js() {
$form_state = array(
'submitted' => FALSE,
);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$hm_form = $form['messages'];
unset($hm_form['#prefix'], $hm_form['#suffix']);
$output = drupal_render($hm_form);
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => $output,
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
function heartbeat_delete_logs_confirm() {
return confirm_form(array(), t('Are you sure you want to delete all activity logs?'), 'admin/settings/heartbeat/delete/confirm', t('This action can not be undone.'), t('Delete'), t('Cancel'));
}
function heartbeat_delete_logs_confirm_submit($form, &$form_state) {
db_query("DELETE FROM {heartbeat_activity}");
$form_state['redirect'] = 'admin/settings/heartbeat/settings';
drupal_set_message('All messages have been deleted');
}
function heartbeat_logs_admin_settings() {
$form['hb_fields'] = array(
'#type' => 'fieldset',
'#weight' => -5,
'#title' => t('Heartbeat log settings'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$value = variable_get('heartbeat_activity_no_duplicate_seconds', 172800);
$form['hb_fields']['heartbeat_activity_no_duplicate_seconds'] = array(
'#title' => t('Total timespan to show in heartbeat views'),
'#type' => 'textfield',
'#size' => 40,
'#default_value' => $value,
'#description' => t('Currently set ') . _heartbeat_activity_get_time($value) . '.<br />' . t('You can set this to your needs. For example 36000 is 10h, 172800 is 24h'),
'#prefix' => '<div id="heartbeat-tabs">',
'#suffix' => '</div>',
'#ahah' => array(
'path' => 'heartbeat/ahah/heartbeat_activity_no_duplicate_seconds',
'wrapper' => 'heartbeat-tabs',
'event' => 'change',
'method' => 'replace',
'effect' => 'fade',
),
);
$value = variable_get('heartbeat_activity_grouping_seconds', 7200);
$form['hb_fields']['heartbeat_activity_grouping_seconds'] = array(
'#title' => t('Maximum gap (in seconds)'),
'#type' => 'textfield',
'#size' => 40,
'#default_value' => $value,
'#description' => t('Currently set ') . _heartbeat_activity_get_time($value) . '.<br />' . t('Maximum gap for the same activity to be grouped together and before an identical activity can be logged again'),
'#prefix' => '<div id="heartbeat-tabs-2">',
'#suffix' => '</div>',
'#ahah' => array(
'path' => 'heartbeat/ahah/heartbeat_activity_grouping_seconds',
'wrapper' => 'heartbeat-tabs-2',
'event' => 'change',
'method' => 'replace',
'effect' => 'fade',
),
);
$form['hb_fields']['heartbeat_activity_grouping_how_many'] = array(
'#title' => 'Maximum number of messages to group',
'#type' => 'textfield',
'#size' => 20,
'#default_value' => variable_get('heartbeat_activity_grouping_how_many', 5),
'#description' => 'Maximum number of items that can be grouped. This can be overruled for each heartbeat message specific.',
);
$form['hb_fields']['heartbeat_block_items_max'] = array(
'#title' => 'Maximum rows that are fetched from database',
'#type' => 'textfield',
'#size' => 20,
'#default_value' => variable_get('heartbeat_block_items_max', 100),
'#description' => 'This is for performance reasons. Limiting the messages is calculated after grouping',
);
$form['hb_fields']['heartbeat_block_public_items_max'] = array(
'#title' => 'Maximum items in the public heartbeat',
'#type' => 'textfield',
'#size' => 20,
'#default_value' => variable_get('heartbeat_block_public_items_max', 25),
);
$form['hb_fields']['heartbeat_block_private_items_max'] = array(
'#title' => 'Maximum items in the private heartbeat',
'#type' => 'textfield',
'#size' => 20,
'#default_value' => variable_get('heartbeat_block_private_items_max', 25),
);
$form = system_settings_form($form);
$form['#submit'][] = 'heartbeat_activity_admin_settings_submit';
return $form;
}
function heartbeat_admin_settings_submit($form, &$form_state) {
}
function heartbeat_activity_ahah($element) {
$form_state = array(
'storage' => NULL,
'submitted' => FALSE,
);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$javascript = drupal_add_js(NULL, NULL, 'header');
$_SESSION['messages'] = array();
if (isset($form['hb_fields'][$element])) {
$ahah_form = $form['hb_fields'][$element];
$ahah_form['#description'] = '<div class="status">' . t('Currently set ') . _heartbeat_activity_get_time($form_state['values'][$element]) . '</div>';
unset($ahah_form['#prefix'], $ahah_form['#suffix']);
drupal_json(array(
'status' => TRUE,
'data' => theme('status_messages') . drupal_render($ahah_form),
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
else {
drupal_json(array(
'status' => FALSE,
'data' => t('Element not found: @element', array(
'@element' => $element,
)),
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
}
function _heartbeat_activity_get_time($time) {
global $language;
return format_interval($time, 6, $language->language);
}