View source
<?php
define('NOTIFICATIONS_CONTENT_PAGER', 20);
require_once drupal_get_path('module', 'notifications') . '/notifications.node.inc';
function notifications_content_menu() {
$items['admin/messaging/notifications/content'] = array(
'title' => 'Content subscriptions',
'type' => MENU_LOCAL_TASK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'notifications_content_settings_form',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'notifications_content.pages.inc',
);
$items['user/%user/notifications/thread'] = array(
'type' => MENU_LOCAL_TASK,
'access callback' => FALSE,
'access arguments' => FALSE,
'title' => 'Thread',
'page callback' => 'notifications_content_page_thread',
'page arguments' => array(
1,
),
'weight' => 10,
'file' => 'notifications_content.pages.inc',
);
$items['user/%user/notifications/nodetype'] = array(
'type' => MENU_LOCAL_TASK,
'access callback' => FALSE,
'title' => 'Content type',
'page callback' => 'notifications_content_page_nodetype',
'page arguments' => array(
1,
),
'weight' => 10,
'file' => 'notifications_content.pages.inc',
);
$items['user/%user/notifications/author'] = array(
'type' => MENU_LOCAL_TASK,
'access callback' => FALSE,
'title' => t('Author'),
'page callback' => 'notifications_content_page_author',
'pàge arguments' => array(
1,
),
'weight' => 10,
'file' => 'notifications_content.pages.inc',
);
return $items;
}
function notifications_content_access($account, $perm) {
global $user;
return $account->uid && $account->uid == $user->uid && user_access($perm) || user_access('administer notifications') && user_access($perm, $account);
}
function notifications_content_perm() {
return array(
'subscribe to content',
'subscribe to content type',
'subscribe to author',
'skip notifications',
);
}
function notifications_content_help($path, $arg) {
if ($path == 'admin/messaging/notifications/content') {
$output .= '<p>' . t('To determine the available subscription types for each content type you can also use the !content-type-settings', array(
'!content-type-settings' => l(t('content types settings page'), 'admin/content/types'),
)) . '</p>';
return $output;
}
elseif (array(
$arg[0],
$arg[1],
$arg[2],
$arg[3],
) == array(
'admin',
'messaging',
'template',
'edit',
) && ($group = $arg[4])) {
switch ($group) {
case 'notifications-digest-node-nid':
case 'notifications-digest-node-type':
$help = '<p>' . t('This is the format for each digest group. A message may consist on one or many of these groups:') . '</p>';
$help .= '<small><pre>';
$help .= t('Group title') . "\n";
$help .= '- ' . t('Digest line.') . "\n";
$help .= '- ' . t('Digest line.') . "\n";
$help .= '- ...' . "\n";
$help .= t('Group footer') . "\n";
$help .= '</pre></small>';
return $help;
}
}
}
function notifications_content_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'comment_form':
$node = node_load($form['nid']['#value']);
if (notifications_content_type_enabled($node->type)) {
$form['notifications']['notifications_content_disable'] = array(
'#type' => 'checkbox',
'#title' => t('Do not send notifications for this comment.'),
'#default_value' => 0,
'#access' => user_access('skip notifications'),
);
}
break;
case 'node_type_form':
if (isset($form['identity']['type'])) {
if (!isset($form['notifications'])) {
$form['notifications'] = array();
}
$form['notifications'] += array(
'#type' => 'fieldset',
'#title' => t('Subscription settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['notifications']['notifications_content_type'] = array(
'#type' => 'checkboxes',
'#title' => t('Allowed subscription types'),
'#default_value' => notifications_content_type_enabled($form['#node_type']->type),
'#options' => _notifications_content_type_options(),
'#description' => t('Enable different subscription options for this content type.'),
'#weight' => -10,
);
if (!variable_get('notifications_content_per_type', 0)) {
$form['notifications']['notifications_content_type']['#disabled'] = TRUE;
$form['notifications']['notifications_content_type']['#description'] .= ' <strong>' . t('To enable these options check the <a href="@notifications-settings">Notifications content settings</a>', array(
'@notifications-settings' => url('admin/messaging/notifications/content'),
)) . '</strong>';
}
}
break;
default:
if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
$types = notifications_content_types(NULL);
if (notifications_content_type_enabled($node->type)) {
$noprevious = !isset($form['notifications']);
$form['notifications']['#type'] = 'fieldset';
$form['notifications']['#title'] = t('Notifications');
$form['notifications']['#collapsible'] = TRUE;
$form['notifications']['#weight'] = 1;
if ($noprevious) {
$form['notifications']['#collapsed'] = TRUE;
$form['notifications']['#access'] = user_access('skip notifications');
}
$form['notifications']['notifications_content_disable'] = array(
'#type' => 'checkbox',
'#title' => t('Do not send notifications for this update.'),
'#default_value' => 0,
'#access' => user_access('skip notifications'),
);
}
}
}
}
function notifications_content_theme() {
return array(
'notifications_content_type_settings' => array(
'arguments' => array(
'element' => NULL,
),
'file' => 'notifications_content.pages.inc',
),
);
}
function notifications_content_notifications($op, &$arg0, $arg1 = NULL, $arg2 = NULL) {
switch ($op) {
case 'names':
$subs =& $arg0;
if ($subs->event_type == 'node') {
$subs->type_name = t('Content');
if (!empty($subs->fields['type'])) {
$subs->names['type'] = t('Content type: @type', array(
'@type' => node_get_types('name', $subs->fields['type']),
));
}
if (!empty($subs->fields['author']) && ($author = user_load(array(
'uid' => $subs->fields['author'],
)))) {
$subs->names['author'] = t('Author: @name', array(
'@name' => $author->name,
));
}
if (!empty($subs->fields['nid']) && ($node = node_load($subs->fields['nid']))) {
$subs->names['thread'] = t('Thread: @title', array(
'@title' => $node->title,
));
}
}
break;
case 'subscription types':
$types['thread'] = array(
'event_type' => 'node',
'title' => t('Thread'),
'access' => 'subscribe to content',
'page callback' => 'notifications_content_page_thread',
'user page' => 'user/%user/notifications/thread',
'fields' => array(
'nid',
),
'description' => t('Subscribe to all changes and comments for a thread.'),
);
$types['nodetype'] = array(
'event_type' => 'node',
'title' => t('Content type'),
'access' => 'subscribe to content type',
'page callback' => 'notifications_content_page_nodetype',
'user page' => 'user/%user/notifications/nodetype',
'fields' => array(
'type',
),
'description' => t('Subscribe to all content of a given type.'),
);
$types['author'] = array(
'event_type' => 'node',
'title' => t('Author'),
'access' => 'subscribe to author',
'page callback' => 'notifications_content_page_author',
'user page' => 'user/%user/notifications/author',
'fields' => array(
'author',
),
'description' => t('Subscribe to all content submitted by a user.'),
);
$types['typeauthor'] = array(
'event_type' => 'node',
'title' => t('Content type and Author'),
'access' => 'subscribe to content type and author',
'fields' => array(
'author',
'type',
),
'description' => t('Subscribe to all content of a given type submitted by a user.'),
);
return $types;
case 'subscription fields':
$fields['nid'] = array(
'name' => t('Node'),
'field' => 'nid',
'type' => 'int',
'autocomplete path' => 'notifications/autocomplete/node/title',
'autocomplete callback' => 'notifications_node_nid2autocomplete',
'format callback' => 'notifications_node_nid2title',
'value callback' => 'notifications_node_title2nid',
);
$fields['author'] = array(
'name' => t('Author'),
'field' => 'author',
'type' => 'int',
'autocomplete path' => 'user/autocomplete',
'autocomplete callback' => 'notifications_content_author_name',
'format callback' => 'notifications_content_author_name',
'value callback' => 'notifications_content_author_uid',
);
$fields['type'] = array(
'name' => t('Node type'),
'field' => 'type',
'type' => 'string',
'options callback' => 'notifications_content_types',
);
return $fields;
case 'query':
if ($arg0 == 'event' && $arg1 == 'node' && ($node = $arg2->node) || $arg0 == 'user' && $arg1 == 'node' && ($node = $arg2)) {
$query[]['fields'] = array(
'nid' => $node->nid,
'type' => $node->type,
'author' => $node->uid,
);
return $query;
}
break;
case 'node options':
return _notifications_content_node_options($arg0, $arg1);
case 'user options':
return _notifications_content_user_options($arg0, $arg1);
case 'event load':
$event =& $arg0;
$load = array();
if ($event->type == 'node') {
if (!empty($event->params['nid'])) {
$event->objects['node'] = node_load($event->params['nid']);
}
if (!empty($event->params['cid'])) {
$event->objects['comment'] = notifications_content_comment_load($event->params['cid']);
}
}
break;
case 'event objects':
return array(
'node' => t('Node'),
);
case 'event types':
$types[] = array(
'type' => 'node',
'action' => 'insert',
'name' => t('New content of type [type-name] has been submitted'),
'line' => t('[type-name] [title] by [author-name]'),
'digest' => array(
'node',
'type',
),
'description' => t('Node creation'),
);
$types[] = array(
'type' => 'node',
'action' => 'update',
'name' => t('[type-name]: [title]'),
'line' => t('The [type-name] has been updated'),
'digest' => array(
'node',
'nid',
),
'description' => t('Node update'),
);
$types[] = array(
'type' => 'node',
'action' => 'comment',
'name' => t('[type-name]: [title]'),
'line' => t('New comment by [comment-author-name]: [comment-title]'),
'digest' => array(
'node',
'nid',
),
'description' => t('Node comment'),
);
return $types;
case 'access':
$type = $arg0;
$account =& $arg1;
$object =& $arg2;
$access = TRUE;
if ($type == 'event' && $object->type == 'node') {
if (!empty($object->objects['node'])) {
$access = notifications_content_node_allow($account, $object->objects['node']);
}
if ($access && !empty($object->objects['comment'])) {
$access = $access && notifications_content_comment_allow($account, $object->objects['comment']);
}
}
elseif ($type == 'subscription') {
$access = TRUE;
if (!empty($object->fields['nid'])) {
if ($node = node_load($object->fields['nid'])) {
$access = notifications_content_node_allow($account, $node);
}
else {
$access = FALSE;
}
}
if (!empty($object->fields['type'])) {
$access = $access && array_key_exists($object->fields['type'], notifications_content_types());
}
}
return array(
$access,
);
break;
}
}
function notifications_content_author_name($uid, $html = FALSE) {
if ($account = user_load($uid)) {
return $html ? theme('username', $account) : check_plain($account->name);
}
}
function notifications_content_author_uid($name, $field = NULL) {
if ($account = user_load(array(
'name' => $name,
))) {
return $account->uid;
}
elseif ($field) {
form_set_error($field, t('User name not found.'));
}
}
function notifications_content_messaging($op, $arg1 = NULL, $arg2 = NULL, $arg3 = NULL, $arg4 = NULL) {
switch ($op) {
case 'message groups':
$help = t('The <em>Header</em> and <em>Footer</em> will be taken from Notification events.');
$help_digest = $help . ' ' . t('The <em>Digest line</em> will be used when composing Short digests on which each event will be just a line.');
$info['notifications-event-node'] = array(
'module' => 'notifications_content',
'name' => t('Notifications for node events'),
'description' => t('Defaults for all notifications related to node events.'),
'help' => $help_digest,
'fallback' => 'notifications-event',
);
$info['notifications-event-node-insert'] = array(
'module' => 'notifications_content',
'name' => t('Notifications for node creation'),
'description' => t('Notifications produced when a new node is created.'),
'help' => $help_digest,
'fallback' => 'notifications-event-node',
);
$info['notifications-event-node-update'] = array(
'module' => 'notifications_content',
'name' => t('Notifications for node updates'),
'description' => t('Notifications produced when a node is updated.'),
'help' => $help_digest,
'fallback' => 'notifications-event-node',
);
$info['notifications-event-node-comment'] = array(
'module' => 'notifications_content',
'name' => t('Notifications for node comments'),
'description' => t('Notifications produced when a comment is posted to a node.'),
'help' => $help_digest,
'fallback' => 'notifications-event-node',
);
$info['notifications-digest-node-nid'] = array(
'module' => 'notifications-content',
'name' => t('Groups digests per node'),
'description' => t('Group of events digested for each node.'),
'fallback' => 'notifications-digest',
);
$info['notifications-digest-node-type'] = array(
'module' => 'notifications-content',
'name' => t('Groups digests per node type'),
'description' => t('Group of events digested for each node type.'),
'fallback' => 'notifications-digest',
);
return $info;
case 'message keys':
$type = $arg1;
switch ($type) {
case 'notifications-event-node':
case 'notifications-event-node-insert':
case 'notifications-event-node-update':
case 'notifications-event-node-comment':
return array(
'subject' => t('Subject'),
'main' => t('Content'),
'digest' => t('Digest line'),
);
case 'notifications-digest-node-nid':
case 'notifications-digest-node-type':
$parts['title'] = t('Group title');
$parts['footer'] = t('Group footer');
return $parts;
}
break;
case 'messages':
$type = $arg1;
switch ($type) {
case 'notifications-event-node':
case 'notifications-event-node-update':
return array(
'subject' => t('Update for [type-name]: [title]'),
'main' => array(
'[node-teaser]',
t('Read more [node-url]'),
),
'digest' => array(
'[title]',
'Read more [node-url]',
),
);
case 'notifications-event-node-insert':
return array(
'subject' => t('New [type-name]: [title]'),
'main' => array(
'[node-teaser]',
t('Read more [node-url]'),
),
'digest' => array(
'[title]',
'Read more [node-url]',
),
);
case 'notifications-event-node-comment':
return array(
'subject' => t('Comment for [type-name]: [title]'),
'main' => array(
t('Comment by [comment-author-name]: [comment-title]'),
'[comment-body]',
t('Read more [comment-url]'),
),
'digest' => array(
t('New Comment on [title] by [comment-author-name] titled [comment-title]'),
t('Read more [comment-url]'),
),
);
case 'notifications-digest-node-nid':
return array(
'title' => t('Updates for [type-name]: [title]'),
'footer' => t('Read more [node-url]'),
);
case 'notifications-digest-node-type':
return array(
'title' => t('New content of type [type-name] has been submitted'),
'footer' => '<none>',
);
}
break;
case 'tokens':
$type = explode('-', $arg1);
$tokens = array();
if ($type[0] == 'notifications' && $type[2] == 'node') {
if ($type[1] == 'event') {
$tokens[] = 'node';
if ($type[3] == 'comment') {
$tokens[] = 'comment';
}
}
elseif ($type[1] == 'digest') {
if ($type[3] == 'nid') {
$tokens[] = 'node';
}
elseif ($type[3] == 'type') {
$tokens[] = array(
'node',
'type-name',
);
}
}
}
return $tokens;
}
}
function _notifications_content_node_options($account, $node) {
$options = array();
if (notifications_content_type_enabled($node->type, 'thread')) {
$options[] = array(
'name' => t('This post'),
'type' => 'thread',
'fields' => array(
'nid' => $node->nid,
),
);
}
if (notifications_content_type_enabled($node->type, 'nodetype')) {
$options[] = array(
'name' => t('Posts of type @type', array(
'@type' => node_get_types('name', $node->type),
)),
'type' => 'nodetype',
'fields' => array(
'type' => $node->type,
),
);
}
if (notifications_content_type_enabled($node->type, 'author')) {
$options[] = array(
'name' => t('Posts by @name', array(
'@name' => $node->name,
)),
'type' => 'author',
'fields' => array(
'author' => $node->uid,
),
);
}
return $options;
}
function _notifications_content_user_options($account, $author) {
$options = array();
$options[] = array(
'name' => t('All posts by @name', array(
'@name' => $author->name,
)),
'type' => 'author',
'fields' => array(
'author' => $author->uid,
),
);
foreach (notifications_content_types('name', 'typeauthor') as $type => $name) {
$options[] = array(
'name' => t('@type posts by @name', array(
'@name' => $author->name,
'@type' => $name,
)),
'type' => 'typeauthor',
'fields' => array(
'author' => $author->uid,
'type' => $type,
),
);
}
return $options;
}
function _notifications_content_type_options() {
return _notifications_subscription_types('long', array(
'event_type' => 'node',
));
}
function notifications_content_nodeapi(&$node, $op, $arg = 0) {
global $user;
switch ($op) {
case 'load':
$node->old_status = $node->status;
break;
case 'update':
case 'insert':
if ($node->status && empty($node->notifications_content_disable) && notifications_content_type_enabled($node->type)) {
$event = array(
'module' => 'node',
'uid' => $node->uid,
'oid' => $node->nid,
'type' => 'node',
'action' => $op,
'node' => $node,
'params' => array(
'nid' => $node->nid,
),
);
if ($op == 'update') {
if (!isset($node->old_status)) {
$oldnode = node_load($node->nid);
$node->old_status = $oldnode->status;
}
if (!$node->old_status) {
$event['action'] = 'insert';
}
if (variable_get('notifications_send_immediate', 0)) {
node_load(0, NULL, TRUE);
}
}
notifications_event($event);
}
break;
case 'delete':
notifications_delete_subscriptions(array(
'event_type' => 'node',
), array(
'nid' => $node->nid,
), FALSE);
}
}
function notifications_content_comment($comment, $op) {
$comment = (object) $comment;
if (($op == 'update' || $op == 'publish') && empty($comment->notifications_content_disable) && empty($comment->status)) {
$node = node_load($comment->nid);
if (notifications_content_type_enabled($node->type)) {
$event = array(
'module' => 'node',
'uid' => $comment->uid,
'type' => 'node',
'action' => 'comment',
'node' => $node,
'comment' => $comment,
'params' => array(
'nid' => $comment->nid,
'cid' => $comment->cid,
),
);
}
notifications_event($event);
}
}
function notifications_content_node_type($op, $info) {
if ($op == 'delete') {
notifications_delete_subscriptions(array(
'event_type' => 'node',
), array(
'type' => $info->type,
));
}
}
function notifications_content_comment_load($cid) {
static $cache;
if (!isset($cache[$cid])) {
$comment = db_fetch_object(db_query('SELECT c.*, u.uid, u.name AS registered_name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d', $cid));
$comment = drupal_unpack($comment);
$comment->name = $comment->uid ? $comment->registered_name : $comment->name;
$cache[$cid] = $comment;
}
return $cache[$cid];
}
function notifications_content_types($field = 'name', $subs_type = 'nodetype') {
$types = array();
foreach (node_get_types() as $key => $data) {
if (notifications_content_type_enabled($key, $subs_type)) {
$types[$key] = $data;
}
}
if ($field) {
foreach (array_keys($types) as $type) {
$types[$type] = $types[$type]->{$field};
}
}
return $types;
}
function notifications_content_type_enabled($type = NULL, $option = NULL) {
$defaults = variable_get('notifications_content_type', array());
if ($type && variable_get('notifications_content_per_type', 0)) {
$settings = variable_get('notifications_content_type_' . $type, $defaults);
}
else {
$settings = $defaults;
}
if ($option) {
return in_array($option, $settings, TRUE);
}
else {
return $settings;
}
}
function notifications_content_token_list($type = 'all') {
$tokens = array();
if ($type == 'node' || $type == 'all') {
$tokens['node']['node-teaser'] = t('The node teaser.');
$tokens['node']['node-body'] = t('The node body.');
$tokens['node']['node-url'] = t('The node view url for read more links.');
$tokens['node']['node-teaser-raw'] = t('Unfiltered node teaser. WARNING - raw user input.');
$tokens['node']['node-body-raw'] = t('Unfiltered node body. WARNING - raw user input.');
}
if ($type == 'comment' || $type == 'all') {
$tokens['comment']['comment-url'] = t('The comment view url.');
$tokens['comment']['comment-reply-url'] = t('The comment reply url.');
}
return $tokens;
}
function notifications_content_token_values($type, $object = NULL, $options = array()) {
switch ($type) {
case 'node':
if ($node = $object) {
$values['node-teaser'] = $node->teaser ? check_markup($node->teaser, $node->format, FALSE) : '';
$values['node-body'] = $node->body ? check_markup($node->body, $node->format, FALSE) : '';
$values['node-url'] = url('node/' . $node->nid, array(
'absolute' => TRUE,
));
$values['node-teaser-raw'] = $node->teaser ? $node->teaser : '';
$values['node-body-raw'] = $node->body ? $node->body : '';
return $values;
}
break;
case 'comment':
if ($comment = (object) $object) {
$values['comment-url'] = url('node/' . $comment->nid, array(
'fragment' => 'comment-' . $comment->cid,
'absolute' => TRUE,
));
$values['comment-reply-url'] = url('comment/reply/' . $comment->nid . '/' . $comment->cid, array(
'absolute' => TRUE,
));
return $values;
}
break;
}
}
function notifications_content_node_allow($account, $node) {
static $access;
if (!$node) {
return FALSE;
}
if (!isset($access[$account->uid][$node->nid])) {
$access[$account->uid][$node->nid] = node_access('view', $node, $account);
}
return $access[$account->uid][$node->nid];
}
function notifications_content_comment_allow($account, $comment) {
static $access;
$comment = is_object($comment) ? $comment : db_fetch_object(db_query("SELECT * FROM {comments} WHERE cid = %d", $comment));
if (!isset($access[$account->uid][$comment->cid])) {
if (($account->uid == $comment->uid || $comment->status == COMMENT_PUBLISHED) && user_access('access comments', $account) || user_access('administer comments', $account)) {
$access[$account->uid][$comment->cid] = TRUE;
}
else {
$access[$account->uid][$comment->cid] = FALSE;
}
}
return $access[$account->uid][$comment->cid];
}