$items = array();
// Menu page callbacks for each heartbeat stream.
- $streams = heartbeat_stream_config_load_all();
+ $streams = heartbeat_stream_config_load_all(TRUE);
foreach ($streams as $class => $stream) {
if ($stream->page_disabled == TRUE) {
continue;
'description' => $stream->name . ' page',
'page callback' => 'heartbeat_messages_page',
'page arguments' => array(1),
- 'access callback' => '_heartbeat_stream_has_access',
+ 'access callback' => 'heartbeat_stream_has_access',
'access arguments' => array(1),
'file' => 'heartbeat.pages.inc',
);
'title' => $stream->title,
'page callback' => 'heartbeat_messages_page',
'page arguments' => array($stream->class, '0', 1),
- 'access callback' => '_heartbeat_stream_has_access',
+ 'access callback' => 'heartbeat_stream_has_access',
'access arguments' => array($stream->class),
'type' => MENU_LOCAL_TASK,
'file' => 'heartbeat.pages.inc',
/**
* 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
/**
- * Theme functions and their helpers.
+ * Theme functions and helpers.
*/
/**
global $user, $language;
$content = '';
- $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><em>' . t('No activity yet.') . '</em></p>';
+ if (!isset($heartbeatStream->config) || empty($heartbeatStream->config->class)) {
+
+ $content .= drupal_render($variables['content']);
+
}
else {
- $content .= drupal_render($variables['content']);
+
+ $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><em>' . t('No activity yet.') . '</em></p>';
+
+ }
+ else {
+
+ $content .= drupal_render($variables['content']);
+
+ }
+
+ $content .= '</div></div>';
+
}
- $content .= '</div></div>';
return $content;
}
/**\r
* Page callback function to load an activity stream page\r
*\r
- * @param array $access_type\r
- * @return string Themed list of messages\r
+ * @param String $stream_name\r
+ * Stream class name.\r
+ * @param Integer $offset_time\r
+ * The Offset timestamp to fetch activity.\r
+ * @param stdClass $account\r
+ * Optional user account object. If none given, global user will be used\r
+ * as "viewer" of the stream.\r
*/\r
-function heartbeat_messages_page($access_type, $offset_time = 0, $account = NULL) {\r
+function heartbeat_messages_page($stream_name, $offset_time = 0, $account = NULL) {\r
\r
// Messages have to loaded by ajax if the url contains an offset\r
// variable AND a post variable ajax is defined.\r
\r
// For block updates by ajax displayed on the user\r
// profile page, we want to show the account requested.\r
- if (!$page && is_numeric($account) && $account > 0 && variable_get('heartbeat_show_user_profile_messages_' . $access_type, 0)) {\r
+ if (!$page && is_numeric($account) && $account > 0 && variable_get('heartbeat_show_user_profile_messages_' . $stream_name, 0)) {\r
$account = user_load($account);\r
}\r
// For blocks calling this page in general.\r
$account = user_load(arg(1));\r
}\r
\r
- if ($heartbeatStream = heartbeat_stream($access_type, $page, $account)) {\r
+ if ($heartbeatStream = heartbeat_stream($stream_name, $page, $account)) {\r
\r
// Changes at runtime.\r
$heartbeatStream->setOffsetTime($offset_time);\r
$build = heartbeat_stream_view($heartbeatStream);\r
}\r
else {\r
- $build = t('You are not allowed to see this activity stream.');\r
+ $build = t('You don\'t have access to this stream.');\r
}\r
\r
// Ajax calls may directly render the content. No extra wrapping needed.\r
}
/**
- * Implmentation of the Ctools load function.
+ * Implements Ctools load function.
*/
function _heartbeat_stream_config_load($name) {
}
/**
+ * Helper function to reset cached streams and attached menu entries.
+ */
+function heartbeat_stream_config_reset($streamConfig = NULL) {
+
+ // Clear the heartbeat stream cache.
+ cache_clear_all('heartbeat_streams', 'cache');
+ drupal_static_reset('heartbeat_streams');
+
+ // This is the only way we can let the menu system know that the
+ // menu needs to be rebuild. Just calling menu_rebuild here is too
+ // soon and would result in not clearing the menu later on.
+ variable_set('menu_rebuild_needed', TRUE);
+
+}
+
+/**
* Helper function to unpack the settings into the root of the object.
*/
function _heartbeat_stream_config_unpack(HeartbeatStreamConfig & $streamConfig) {
}
/**
- * Helper function to check access on activity stream
+ * Helper function to check access on activity stream by name.
+ *
+ * @param String $stream
+ * The ClassName of the stream.
*/
-function _heartbeat_stream_has_access($stream) {
-
- if (is_string($stream)) {
- ctools_include('export');
- $streamConfig = ctools_export_crud_load('heartbeat_streams', $stream);
- }
- else {
- $streamConfig = $stream;
- }
+function heartbeat_stream_has_access($stream) {
+ $streamConfig = heartbeat_stream_config_load($stream);
+ return _heartbeat_stream_has_access($streamConfig);
+}
+/**
+ * Helper function to check access on activity stream.
+ *
+ * @param HeartbeatStreamConfig $streamConfig
+ * A Heartbeat stream configuration object.
+ */
+function _heartbeat_stream_has_access(HeartbeatStreamConfig $streamConfig) {
return user_access('view heartbeat messages') && user_access('view ' . $streamConfig->name . ' stream');
-
}
/**
*/
function heartbeat_example_node_insert($node) {
heartbeat_api_log('heartbeat_add_node', $node->uid, 0, $node->nid, 0, array(
- '@node_title' => l($node->title, 'node/'. $node->nid),
- '@username'=> l(user_load($node->uid)->name, 'user/'. $node->uid),
- '@node_type' => $node->type,
- '@types' => $node->type .'s'
+ '!node_title' => l($node->title, 'node/'. $node->nid),
+ '!username'=> l(user_load($node->uid)->name, 'user/'. $node->uid),
+ '!node_type' => $node->type,
+ '!types' => $node->type .'s'
), HEARTBEAT_PUBLIC_TO_ALL, $node->created);
}
*/
function heartbeat_example_node_update($node) {
heartbeat_api_log('heartbeat_edit_node', $node->uid, 0, $node->nid, 0, array(
- '@node_title' => l($node->title, 'node/'. $node->nid),
- '@username'=> l(user_load($node->uid)->name, 'user/'. $node->uid),
- '@node_type' => $node->type,
- '@types' => $node->type .'s'
+ '!node_title' => l($node->title, 'node/'. $node->nid),
+ '!username'=> l(user_load($node->uid)->name, 'user/'. $node->uid),
+ '!node_type' => $node->type,
+ '!types' => $node->type .'s'
), HEARTBEAT_PUBLIC_TO_ALL);
}
\ No newline at end of file
// '#theme' => 'heartbeat_template_form'
+ // The template object is filled by ctools export. This means that
+ // we don't have an complete object like Heartbeat expects it.
+ // E.g. concat_arg[roles] which are stored and filtered by setRoles().
$template = $form_state['item'];
$form['general-tab'] = array('#type' => 'vertical_tabs');
'#collapsed' => TRUE,
'#group' => 'general-tab',
);
- $form['permissions']['disabled'] = array(
- '#type' => 'checkbox',
- '#title' => t('Disable the message'),
- '#description' => t('Defines whether this message template is disabled from logging and viewing.'),
- '#default_value' => empty($template->disabled) ? 0 : $template->disabled,
- );
$form['permissions']['perms'] = array(
'#type' => 'select',
'#title' => t('Message display access'),
'#options' => _heartbeat_perms_options(),
'#default_value' => !isset($template->perms) ? HEARTBEAT_PUBLIC_TO_ALL : $template->perms,
);
+
+ if (!empty($template->concat_args['roles'])) {
+ $template->setRoles($template->concat_args['roles']);
+ }
+
$form['permissions']['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Limit this message with roles'),
function heartbeat_ui_ctools_export_ui_form_submit(&$form, &$form_state) {
- // Reformat the variables and attachments section.
+ // Reformat the variables, attachments and concat args to fit the storage.
$form_state['values']['variables'] = HeartbeatMessageTemplate::getVariablesFromMessage($form_state['values']['message'], $form_state['values']['message_concat']);
$form_state['values']['attachments'] = empty($form_state['values']['attachments']) ? array() : $form_state['values']['attachments'];
+ $form_state['values']['concat_args']['roles'] = $form_state['values']['roles'];
}
}
}
- cache_clear_all('heartbeat_streams', 'cache');
- drupal_static_reset('heartbeat_streams');
-
- // Rebuild the menu.
- menu_rebuild();
+ heartbeat_stream_config_reset();
drupal_set_message(t('Heartbeat streams cache has been cleared and menu is rebuild.'));
--- /dev/null
+<?php
+
+/**
+ * @file
+ * Ctools export UI for a heartbeat stream.
+ * @author stalski
+ *
+ */
+class ctools_export_ui_heartbeat_stream extends ctools_export_ui {
+
+ /**
+ * Page callback to delete an exportable item.
+ */
+ function delete_page($js, $input, $item) {
+
+ $form_state = array(
+ 'plugin' => $this->plugin,
+ 'object' => &$this,
+ 'ajax' => $js,
+ 'item' => $item,
+ 'op' => $item->export_type & EXPORT_IN_CODE ? 'revert' : 'delete',
+ 'rerender' => TRUE,
+ 'no_redirect' => TRUE,
+ );
+
+ $output = drupal_build_form('ctools_export_ui_delete_confirm_form', $form_state);
+
+ if (!empty($form_state['executed'])) {
+ ctools_export_crud_delete($this->plugin['schema'], $item);
+ $export_key = $this->plugin['export']['key'];
+ $message = str_replace('%title', check_plain($item->{$export_key}), $this->plugin['strings']['confirmation'][$form_state['op']]['success']);
+ drupal_set_message($message);
+
+ heartbeat_stream_config_reset($item);
+
+ drupal_goto(ctools_export_ui_plugin_base_path($this->plugin));
+ }
+
+ return $output;
+ }
+
+}
\ No newline at end of file
'schema' => 'heartbeat_streams',
'access' => 'admin heartbeat streams',
+
'menu' => array(
'menu prefix' => 'admin/structure/heartbeat', // default
'menu item' => 'streams', // default
'menu title' => 'Heartbeat streams',
'menu description' => 'Administer heartbeat streams.',
),
+
'title singular' => t('Heartbeat stream'),
'title singular proper' => t('Heartbeat stream'),
'title plural' => t('Heartbeat streams'),
'title plural proper' => t('Heartbeat streams'),
+
'form' => array(
'settings' => 'heartbeat_streams_ui_ctools_export_ui_form',
'validate' => 'heartbeat_streams_ui_ctools_export_ui_form_validate',
'submit' => 'heartbeat_streams_ui_ctools_export_ui_form_submit',
),
+ // A handler to override some methods for advanced UI.
+ 'handler' => array(
+ 'class' => 'ctools_export_ui_heartbeat_stream',
+ 'parent' => 'ctools_export_ui',
+ ),
+
);
),
'handler' => array(
- 'class' => 'ctools_export_ui_heartbeat_template',
- 'parent' => 'ctools_export_ui',
- ),
+ 'class' => 'ctools_export_ui_heartbeat_template',
+ 'parent' => 'ctools_export_ui',
+ ),
);