subscriptions.module in Subscriptions 6
Same filename and directory in other branches
Subscriptions module.
File
subscriptions.moduleView source
<?php
/**
* @mainpage Subscriptions module
*
* This module enables users to subscribe to be notified of changes to nodes or
* taxonomies, such as new comments in specific forums, or additions to some
* category of blog. Once enabled, all nodes will have an additional link that
* allows the user to change their subscriptions. Users get a tab on their user
* page to manage their own subscriptions. Users can also set an auto-subscribe
* function which notifies the user if anyone comments on posts they have made.
* Admins can turn this on by default.
*/
/**
* @file
* Subscriptions module.
*/
/**
* Implementation of hook_init().
*
* @ingroup hooks
* @ingroup init
*/
function subscriptions_init() {
define('SUBSCRIPTIONS_UNAVAILABLE', '<span class="error" title="' . t('(unavailable to regular users)') . '">¤</span>');
if (subscriptions_arg(0) == 'subscriptions' || subscriptions_arg(2) == 'subscriptions') {
include_once drupal_get_path('module', 'subscriptions') . '/subscriptions.admin.inc';
// TODO: do we need this?
}
if (subscriptions_arg(0) == 's' && subscriptions_arg(1) == 'del') {
$router_item = menu_get_item('subscriptions/rem/' . substr($_GET['q'], 6));
if (isset($router_item) && $router_item['access']) {
menu_set_item($_GET['q'], $router_item);
}
}
}
/**
* Implementation of hook_menu().
*
* @ingroup hooks
* @ingroup menu
*/
function subscriptions_menu() {
global $user;
// we need the user to to build some urls
$items['admin/settings/subscriptions'] = array(
'title' => 'Subscriptions',
'description' => 'Enables site settings for user subscriptions.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'subscriptions_settings_form',
),
'access arguments' => array(
'administer site configuration',
),
);
$items['admin/settings/subscriptions/settings'] = array(
'title' => 'Site settings',
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/settings/subscriptions/userdefaults'] = array(
'title' => 'User defaults',
'weight' => -5,
'page callback' => 'subscriptions_page_user_overview',
'page arguments' => array(
NULL,
),
'type' => MENU_LOCAL_TASK,
'access arguments' => array(
'administer site configuration',
),
);
$items['admin/settings/subscriptions/userdefaults/settings'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => 'Overview',
'weight' => -10,
);
$items['admin/settings/subscriptions/userdefaults/bulk'] = array(
'title' => 'Bulk operation',
'weight' => -8,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'subscriptions_page_user_bulk',
),
'type' => MENU_LOCAL_TASK,
'access callback' => '_subscriptions_bulk_access',
);
$items['admin/settings/subscriptions/intervals'] = array(
'title' => 'Interval',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'subscriptions_intervals',
),
'type' => MENU_LOCAL_TASK,
'access arguments' => array(
'administer site configuration',
),
);
$items['user/%user/subscriptions'] = array(
'title' => 'Subscriptions',
'page callback' => 'subscriptions_page_user_overview',
'page arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
'access callback' => '_subscriptions_access',
'access arguments' => array(
1,
),
);
$hide_overview_page = variable_get('subscriptions_hide_overview_page', 0);
if (!$hide_overview_page) {
$items['user/%user/subscriptions/overview'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => 'Overview',
'weight' => -10,
);
}
else {
$minimum_weight = 0;
foreach (subscriptions_types() as $stype => $data) {
if (isset($data['weight']) && $data['weight'] < $minimum_weight) {
$minimum_weight = $data['weight'];
}
}
}
foreach (subscriptions_types() as $stype => $data) {
$weight = isset($data['weight']) ? $data['weight'] : 0;
$items['subscriptions/add/' . $stype] = array(
'title' => 'Add subscription',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'subscriptions_add_form',
$stype,
),
'access arguments' => array(
$data['access'],
),
);
$items['subscriptions/del/' . $stype] = array(
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'subscriptions_del_form',
$stype,
),
'access arguments' => array(
$data['access'],
),
);
if (empty($data['page'])) {
continue;
// no page
}
$items['user/%user/subscriptions/' . $stype] = array(
'title' => 'N/A',
// for l.d.o, overwritten below
'type' => MENU_LOCAL_TASK,
'file' => 'subscriptions.admin.inc',
'page callback' => 'subscriptions_page',
'page arguments' => array(
1,
$stype,
),
'access callback' => '_subscriptions_access',
'access arguments' => array(
1,
$data['access'],
),
'weight' => $weight,
);
$items['user/%user/subscriptions/' . $stype]['title'] = $data['title'];
if ($hide_overview_page && $minimum_weight == $weight) {
// Install the first subscription type page as the default task.
$items['user/%user/subscriptions/' . $stype]['type'] = MENU_DEFAULT_LOCAL_TASK;
$default_item = $items['user/%user/subscriptions/' . $stype];
$items['user/%user/subscriptions'] = array_merge($items['user/%user/subscriptions'], array(
'file' => $default_item['file'],
'page callback' => $default_item['page callback'],
'page arguments' => $default_item['page arguments'],
'access callback' => $default_item['access callback'],
'access arguments' => $default_item['access arguments'],
));
$hide_overview_page = FALSE;
}
if ($stype == 'node') {
continue;
// not in site settings
}
$items['admin/settings/subscriptions/userdefaults/' . $stype] = array(
'title' => 'N/A',
// for l.d.o, overwritten below
'type' => MENU_LOCAL_TASK,
'file' => 'subscriptions.admin.inc',
'page callback' => 'subscriptions_page',
'page arguments' => array(
NULL,
$stype,
),
'access arguments' => array(
'administer site configuration',
),
'weight' => $weight,
);
$items['admin/settings/subscriptions/userdefaults/' . $stype]['title'] = $data['title'];
}
// Unsubscribe links
$items['subscriptions/rem/%'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'subscriptions_delete_form',
2,
3,
4,
5,
6,
),
'type' => MENU_CALLBACK,
'access callback' => '_subscriptions_rem_access',
'access arguments' => array(
2,
3,
4,
5,
6,
7,
),
);
return $items;
}
function _subscriptions_rem_access($a2, $a3, $a4, $a5, $a6, $md) {
return $md == md5(drupal_get_private_key() . $a2 . $a3 . $a4 . $a5 . $a6);
}
function _subscriptions_access($account, $access = NULL) {
global $user;
if ($account && $account->uid) {
if (isset($access)) {
$has_access = user_access($access, $account);
}
else {
foreach (subscriptions_types() as $stype => $data) {
if (user_access($data['access'], $account)) {
$has_access = TRUE;
}
}
}
return !empty($has_access) && ($account->uid == $user->uid || user_access('administer user subscriptions'));
}
return FALSE;
}
/*
* Access callback for bulk subscribe operations.
*/
function _subscriptions_bulk_access() {
return user_access('bulk-administer user subscriptions') && !empty($_SESSION['subscriptions']['bulk_op']);
}
/**
* Implementation of hook_perm().
*
* @ingroup hooks
*/
function subscriptions_perm() {
return array_merge(array(
'administer user subscriptions',
'bulk-administer user subscriptions',
'subscribe to all content types',
'suspend own subscriptions',
), subscriptions_types('access'));
t('administer user subscriptions');
t('bulk-administer user subscriptions');
t('subscribe to all content types');
t('suspend own subscriptions');
}
/**
* Implementation of hook_user().
*
* @ingroup hooks
*/
function subscriptions_user($type, $edit, &$account, $category = NULL) {
static $new_uid = 0;
switch ($type) {
case 'insert':
db_query("INSERT INTO {subscriptions_user} (uid) VALUES(%d)", $account->uid);
// $account->roles isn't set yet, but we'll be called again with 'load'
$new_uid = $account->uid;
break;
case 'load':
if ($new_uid && $account->uid == $new_uid) {
foreach (array_keys($account->roles) as $rid) {
$rids[] = -$rid;
}
db_query("INSERT INTO {subscriptions} (module, field, value, recipient_uid, send_interval, author_uid, send_updates, send_comments)\n SELECT module, field, value, %d, send_interval, author_uid, send_updates, send_comments FROM {subscriptions}\n WHERE recipient_uid IN (%s)", $account->uid, implode(',', $rids));
$new_uid = 0;
}
break;
case 'delete':
db_query("DELETE FROM {subscriptions_user} WHERE uid = %d", $account->uid);
db_query("DELETE FROM {subscriptions} WHERE recipient_uid = %d", $account->uid);
db_query("DELETE FROM {subscriptions_last_sent} WHERE uid = %d", $account->uid);
break;
}
}
/**
* Helper function to do access checking and create a subscription.
*
* @param string $access_key
* The key for checking access to the subscription item.
* @param string $module
* Module that implements the subscription.
* @param string $field
* Field that's being checked for the subscription.
* @param mixed $value
* Value that must be in the field in order to trigger the subscription.
* @param int $author_uid
* Optional ID of the author if the subscription is restricted to nodes by
* on specific author.
* @param object|null $recipient
* Optional user object of the recipient.
* @param int $send_interval
* Optional send interval, must be >0.
* @param int $send_updates
* Optional flag (0 or 1) to indicate whether to trigger on node updates.
* @param int $send_comments
* Optional flag (0 or 1) to indicate whether to trigger on comment additions
* or changes.
*/
function subscriptions_write($access_key, $module, $field, $value, $author_uid = -1, $recipient = NULL, $send_interval = 1, $send_updates = 0, $send_comments = 0) {
global $user;
// Access checking
$recipient_uid = isset($recipient) ? $recipient : $user->uid;
$access = subscriptions_types('access', $access_key);
if ($recipient_uid && $access && ($recipient_uid == $user->uid && user_access($access) || user_access('administer user subscriptions')) || $recipient_uid == 0 && user_access('administer site configuration')) {
subscriptions_write_subscription($module, $field, $value, $author_uid, $recipient_uid, $send_interval, $send_updates, $send_comments);
}
}
/**
* Queue events for notifications.
*
* @param $event
* Event array.
*/
function subscriptions_queue($event) {
global $user;
if (isset($event['node']->nid) && strpos(' ' . variable_get('subscriptions_blocked_nodes', '') . ' ', ' ' . $event['node']->nid . ' ')) {
return;
}
$event += array(
'uid' => $user->uid,
'load_args' => '',
);
foreach (module_implements('subscriptions_queue_alter') as $module) {
$function = $module . '_subscriptions_queue_alter';
$function($event);
if (empty($event)) {
return;
// $event was cleared, forget it
}
}
if (is_array($event['load_args'])) {
$event['load_args'] = serialize($event['load_args']);
}
if (!empty($event['noqueue_uids'])) {
// Allow hook_subscriptions_queue_alter() modules to set uids that won't get any notifications queued:
$noqueue_uids_where = "s.recipient_uid NOT IN (" . implode(', ', array_fill(0, count($event['noqueue_uids']), '%d')) . ")";
}
foreach (module_implements('subscriptions') as $subs_module) {
$subs_module_query = module_invoke($subs_module, 'subscriptions', 'queue', $event);
// Allow other modules to alter the data.
drupal_alter('subscriptions_queue_guery', $subs_module_query);
if (!isset($subs_module_query)) {
continue;
}
foreach ($subs_module_query as $module => $module_query) {
foreach ($module_query as $field => $query) {
$join = empty($query['join']) ? '' : $query['join'];
$where = empty($query['where']) ? array() : array(
$query['where'],
);
$args = array(
$event['load_function'],
$event['load_args'],
$event['is_new'],
$module,
$field,
);
$groupby = empty($query['groupby']) ? '' : $query['groupby'];
// author-specific subscriptions trigger on comments, when the node author is subscribed to:
$args[] = $module == 'node' && $event['type'] == 'comment' && isset($event['node']->uid) ? $event['node']->uid : $event['uid'];
if (!empty($query['value'])) {
$where[] = "s.value = '%s'";
$args[] = $query['value'];
}
if (!empty($query['args'])) {
$args = array_merge($args, $query['args']);
}
if ($user->uid && !_subscriptions_get_setting('send_self', $user)) {
$where[] = "s.recipient_uid != %d";
$args[] = $user->uid;
}
if (!empty($event['noqueue_uids'])) {
$where[] = $noqueue_uids_where;
$args = array_merge($args, $event['noqueue_uids']);
}
$conditions = implode(' AND ', $where);
$sql = "\n INSERT INTO {subscriptions_queue} (uid, name, language, module, field, value, author_uid, send_interval, digest, last_sent, load_function, load_args, is_new, suspended)\n SELECT u.uid, u.name, u.language, s.module, s.field, s.value, s.author_uid, s.send_interval, su.digest, COALESCE(sls.last_sent, 0) last_sent, '%s', '%s', '%d', su.suspended\n FROM {subscriptions} s\n INNER JOIN {subscriptions_user} su ON s.recipient_uid = su.uid\n INNER JOIN {users} u ON su.uid = u.uid\n {$join}\n LEFT JOIN {subscriptions_last_sent} sls ON su.uid = sls.uid AND s.send_interval = sls.send_interval\n WHERE\n s.module = '%s' AND\n s.field = '%s' AND\n s.author_uid IN (%d, -1) AND {$conditions}\n {$groupby}";
$result = db_query($sql, $args);
$affected_rows = db_affected_rows();
/* for debugging:
$sql = db_prefix_tables($sql);
_db_query_callback($args, TRUE);
$sql = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $sql);
drupal_set_message("$sql<br />". $affected_rows .' row(s) inserted.');
/**/
}
}
}
}
/**
* Get subscription sid for the given parameters.
*/
function subscriptions_get_subscription($uid, $module, $field, $value, $author_uid = -1) {
static $subscriptions;
if (!isset($subscriptions[$uid][$module][$field][$value][$author_uid])) {
$sql = "SELECT sid FROM {subscriptions} WHERE module = '%s' AND field = '%s' AND value = '%s' AND author_uid = %d AND recipient_uid = %d";
$subscriptions[$uid][$module][$field][$value][$author_uid] = db_result(db_query($sql, $module, $field, $value, $author_uid, $uid));
}
return $subscriptions[$uid][$module][$field][$value][$author_uid];
}
/**
* Get all subscription fields for the given parameters.
*/
function subscriptions_get_full_subscription($uid, $module, $field, $value, $author_uid = -1) {
$sql = "SELECT * FROM {subscriptions} WHERE module = '%s' AND field = '%s' AND value = '%s' AND author_uid = %d AND recipient_uid = %d";
return db_fetch_object(db_query($sql, $module, $field, $value, $author_uid, $uid));
}
/**
* Create a subscription.
*/
function subscriptions_write_subscription($module, $field, $value, $author_uid, $recipient_uid, $send_interval = 1, $send_updates = 0, $send_comments = 0) {
db_query("UPDATE {subscriptions} SET send_interval = %d, send_updates = %d, send_comments = %d WHERE module = '%s' AND field ='%s' AND value='%s' AND recipient_uid = %d AND author_uid = %d", $send_interval, $send_updates, $send_comments, $module, $field, $value, $recipient_uid, $author_uid);
if (!db_affected_rows()) {
@db_query("INSERT INTO {subscriptions} (module, field, value, author_uid, recipient_uid, send_interval, send_updates, send_comments) VALUES ('%s', '%s', '%s', %d, %d, %d, %d, %d)", $module, $field, $value, $author_uid, $recipient_uid, $send_interval, $send_updates, $send_comments);
}
}
/**
* Provide the form definition for deleting subscriptions via
* s/del/... (aka subscriptions/rem/...) link.
*
* Callback of _subscriptions_menu().
*
* @param $form_state
* FAPI form state.
* @param $module
* Module that controls the subscription.
* @param $field
* Field that controls the subscription (subscription type).
* @param $value
* Subscription parameter (depends on type).
* @param $author_uid
* User ID for author-specific subscriptions or -1/NULL for all authors.
* @param $recipient_uid
* User ID of the subscriber.
*
* @ingroup forms
* @see _subscriptions_menu()
*/
function subscriptions_delete_form(&$form_state, $module, $field, $value, $author_uid, $recipient_uid) {
$form['data'] = array(
'#type' => 'value',
'#value' => array(
$module,
$field,
$value,
$author_uid,
$recipient_uid,
),
);
// We might be called from subscriptions_del_form() and don't want to submit to subscriptions_del_form_submit():
$form['#submit'][] = 'subscriptions_delete_form_submit';
return confirm_form($form, t('Are you sure you want to unsubscribe?'), '<front>', NULL, t('Unsubscribe'));
}
/**
* Delete Subscription form submit handler.
*/
function subscriptions_delete_form_submit($form, &$form_state) {
db_query("DELETE FROM {subscriptions} WHERE module = '%s' AND field = '%s' AND value = '%s' AND author_uid = %d AND recipient_uid = %d", $form_state['values']['data']);
drupal_set_message(t('Your subscription was deactivated.'));
$form_state['redirect'] = '<front>';
}
/**
* Subscribe users to content they post, if not already subscribed
* (context: on_post, on_update, on_comment).
*/
function subscriptions_autosubscribe($module, $field, $value, $context) {
global $user;
// if user has auto subscribe enabled and he's not already subscribed
if ($user->uid && _subscriptions_get_setting('autosub_' . $context, $user) && !subscriptions_get_subscription($user->uid, $module, $field, $value)) {
subscriptions_write_subscription($module, $field, $value, -1, $user->uid, _subscriptions_get_setting('send_interval', $user), 1, 1);
}
}
/**
* Get subscriptions.
*
* @param $params
* Array of parameters for the query.
* @return
* Array of subscriptions indexed by uid, module, field, value, author_uid.
*/
function subscriptions_get($params) {
// Build query
foreach ($params as $field => $value) {
if (is_numeric($value)) {
$conditions[] = $field . ' = %d';
}
else {
$conditions[] = "{$field} = '%s'";
}
$args[] = $value;
}
$sql = "SELECT * FROM {subscriptions} WHERE " . implode(' AND ', $conditions);
$result = db_query($sql, $args);
$subscriptions = array();
while ($s = db_fetch_object($result)) {
$subscriptions[$s->recipient_uid][$s->module][$s->field][$s->value][$s->author_uid] = 1;
}
return $subscriptions;
}
/**
* Hook subscription_types(). Get info about subscription types.
*
* @return
* Information for a given field and type
* or information for a given field for all types
*
* @ingroup hooks
*/
function subscriptions_types($field = NULL, $type = NULL) {
static $types, $list;
if (!isset($types)) {
$types = module_invoke_all('subscriptions', 'types');
// Allow other modules to alter the data.
drupal_alter('subscriptions_types', $types);
foreach ($types as $stype => $data) {
if (!_subscriptions_validate_hook_result($stype, $data)) {
continue;
}
foreach ($data as $name => $value) {
$list[$name][$stype] = $value;
}
}
}
if ($type) {
return isset($types[$type][$field]) ? $types[$type][$field] : NULL;
}
else {
if ($field) {
return isset($list[$field]) ? $list[$field] : array();
}
else {
return $types;
}
}
}
/**
* Check return values of hook_subscriptions().
*/
function _subscriptions_validate_hook_result($stype, $data) {
if (isset($stype)) {
if (!is_numeric($stype) && is_array($data) && isset($data['title']) && isset($data['access']) && isset($data['page']) && isset($data['fields']) && is_array($data['fields'])) {
return TRUE;
}
}
static $already_reported = FALSE;
if (!$already_reported) {
$already_reported = TRUE;
foreach (module_implements('subscriptions') as $module) {
$hook = $module . '_subscriptions';
$types = $hook('types');
foreach ($types as $stype => $data) {
if (!_subscriptions_validate_hook_result($stype, $data)) {
$modules[$module] = $module;
}
}
}
drupal_set_message(t('The following modules return invalid data from %hook: !modules Either they are buggy !Subscriptions add-ons, or they are unrelated to !Subscriptions and should not define %hook!', array(
'%hook' => 'hook_subscriptions()',
'!modules' => '<ul><li>' . implode($modules, '</li><li>') . '</li></ul>',
'!Subscriptions' => 'Subscriptions',
)), 'error', FALSE);
}
return FALSE;
}
/**
* Implementation of hook_theme().
*/
function subscriptions_theme() {
return array(
'subscriptions_form_table' => array(
'file' => 'subscriptions.admin.inc',
'arguments' => array(
'element' => NULL,
),
),
);
}
/**
* Returns TRUE if the given $nid is blocked.
*/
function subscriptions_node_is_blocked($nid) {
return strpos(' ' . variable_get('subscriptions_blocked_nodes', '') . ' ', ' ' . $nid . ' ');
}
/**
* Helper function for uasort()ing arrays with elements that have a 'weight'
*/
function _subscriptions_cmp_by_weight($a, $b) {
$a = isset($a['weight']) ? $a['weight'] : 0;
$b = isset($b['weight']) ? $b['weight'] : 0;
return $a < $b ? -1 : ($a == $b ? 0 : +1);
}
/**
* Helper function to retrieve
* send_self/autosub_on_post/autosub_on_update/autosub_on_comment/ | 1, 0,
* digest/send_interval/send_updates/send_comments/ | -1 = use default
* send_interval_visible/send_updates_visible/send_comments_visible/ | 1, 0, -1 = only preference, -2 = always use site default
* uses_defaults values;
* $account can be NULL/0 (for site default), a user object, or a uid.
*/
function _subscriptions_get_setting($name, $account) {
global $user;
if (!isset($account) || is_object($account) && empty($account->uid) || is_numeric($account) && $account <= 0) {
$uid = -DRUPAL_AUTHENTICATED_RID;
unset($account);
}
elseif (is_numeric($account)) {
if ($account == $user->uid) {
$account = $user;
$uid = $user->uid;
}
else {
$uid = $account;
unset($account);
}
}
if (isset($account)) {
$uid = $account->uid;
}
static $defaults = array();
if (!isset($defaults[$uid][$name])) {
$result = db_query("SELECT uid, digest, send_interval, send_updates, send_comments, send_interval_visible, send_updates_visible, send_comments_visible, autosub_on_post, autosub_on_update, autosub_on_comment, send_self FROM {subscriptions_user} WHERE uid in (%d, %d) ORDER BY uid", -DRUPAL_AUTHENTICATED_RID, $uid);
while ($s = db_fetch_array($result)) {
$defaults[$s['uid']] = $s;
}
if (empty($defaults[$uid])) {
// Note: This should not happen -- subscriptions_user() takes care of inserting/removing records as users are created/deleted.
// If it does happen, then users were created without calling the proper hooks, or they may have been created on another multi-site (#351753).
// Let's add the missing records, as if the user were being created just now, with the expected hook_user() invocations:
$account = user_load($uid);
subscriptions_user('insert', NULL, $account);
subscriptions_user('load', NULL, $account);
return _subscriptions_get_setting($name, $account);
}
$defaults[$uid]['uses_defaults'] = FALSE;
foreach ($defaults[$uid] as $key => $value) {
if ($value < 0) {
// not set, use site dft
$defaults[$uid][$key] = $defaults[-DRUPAL_AUTHENTICATED_RID][$key];
$defaults[$uid]['uses_defaults'] = TRUE;
}
}
foreach (array(
'interval',
'updates',
'comments',
) as $parm) {
// Site overrides user values.
if ($defaults[-DRUPAL_AUTHENTICATED_RID]['send_' . $parm . '_visible'] == -2) {
$defaults[$uid]['send_' . $parm] = $defaults[-DRUPAL_AUTHENTICATED_RID]['send_' . $parm];
}
}
}
return $defaults[$uid][$name];
}
/**
* Load (and cache) a user.
*/
function subscriptions_user_load($uid) {
static $users = array();
if (!isset($users[$uid])) {
$users[$uid] = user_load($uid);
}
return $users[$uid];
}
/**
* Returns whether notifications are suspended for the given user,
* and optionally alerts the user if delivery is suspended.
*/
function subscriptions_suspended($uid, $alert = FALSE) {
$result = db_result(db_query("SELECT suspended FROM {subscriptions_user} WHERE uid = %d", $uid));
if ($result && $alert && empty($_POST)) {
include_once drupal_get_path('module', 'subscriptions') . '/subscriptions.admin.inc';
_subscriptions_suspended_alert($uid, $result);
}
return $result;
}
/**
* Implementation of hook_form_alter() for the user/uid/edit form.
*
* Display a message if subscriptions notifications are suspended.
*
* @ingroup hooks
*/
function subscriptions_form_user_profile_form_alter(&$form, &$form_state) {
subscriptions_suspended(subscriptions_arg(1, 'uid'), TRUE);
}
/**
* Implementation of hook_user_operations().
*/
function subscriptions_user_operations($form_state = NULL) {
if (user_access('bulk-administer user subscriptions')) {
return array(
array(
'label' => t('Subscribe the selected users to...'),
'callback' => '_subscriptions_bulk_operation',
'callback arguments' => array(
'sub',
),
),
array(
'label' => t('Unsubscribe the selected users from...'),
'callback' => '_subscriptions_bulk_operation',
'callback arguments' => array(
'unsub',
),
),
);
}
}
/**
* Callback for bulk subscriptions.
*/
function _subscriptions_bulk_operation($uids, $bulk_op) {
$_SESSION['subscriptions']['bulk_op'] = $bulk_op;
$_SESSION['subscriptions']['uids'] = serialize($uids);
$_SESSION['subscriptions']['back_url'] = $_GET['q'];
drupal_goto('admin/settings/subscriptions/userdefaults/bulk');
}
/**
* Return arg($index) in the proper way.
*/
function subscriptions_arg($index, $member_name = FALSE) {
if (strpos($_GET['q'], 's/del') === 0) {
return arg($index);
}
$mgi = menu_get_item();
$arg = NULL;
if (isset($mgi['map'][$index])) {
$arg = $mgi['map'][$index];
if ($member_name) {
if (is_object($arg) && isset($arg->{$member_name})) {
$arg = $arg->{$member_name};
}
else {
$arg = NULL;
}
}
}
return $arg;
}
/**
* Implements hook_coder_ignore().
*/
function subscriptions_coder_ignore() {
return array(
'path' => drupal_get_path('module', 'subscriptions'),
'line prefix' => drupal_get_path('module', 'subscriptions') . '/',
);
}
Functions
Name | Description |
---|---|
subscriptions_arg | Return arg($index) in the proper way. |
subscriptions_autosubscribe | Subscribe users to content they post, if not already subscribed (context: on_post, on_update, on_comment). |
subscriptions_coder_ignore | Implements hook_coder_ignore(). |
subscriptions_delete_form | Provide the form definition for deleting subscriptions via s/del/... (aka subscriptions/rem/...) link. |
subscriptions_delete_form_submit | Delete Subscription form submit handler. |
subscriptions_form_user_profile_form_alter | Implementation of hook_form_alter() for the user/uid/edit form. |
subscriptions_get | Get subscriptions. |
subscriptions_get_full_subscription | Get all subscription fields for the given parameters. |
subscriptions_get_subscription | Get subscription sid for the given parameters. |
subscriptions_init | Implementation of hook_init(). |
subscriptions_menu | Implementation of hook_menu(). |
subscriptions_node_is_blocked | Returns TRUE if the given $nid is blocked. |
subscriptions_perm | Implementation of hook_perm(). |
subscriptions_queue | Queue events for notifications. |
subscriptions_suspended | Returns whether notifications are suspended for the given user, and optionally alerts the user if delivery is suspended. |
subscriptions_theme | Implementation of hook_theme(). |
subscriptions_types | Hook subscription_types(). Get info about subscription types. |
subscriptions_user | Implementation of hook_user(). |
subscriptions_user_load | Load (and cache) a user. |
subscriptions_user_operations | Implementation of hook_user_operations(). |
subscriptions_write | Helper function to do access checking and create a subscription. |
subscriptions_write_subscription | Create a subscription. |
_subscriptions_access | |
_subscriptions_bulk_access | |
_subscriptions_bulk_operation | Callback for bulk subscriptions. |
_subscriptions_cmp_by_weight | Helper function for uasort()ing arrays with elements that have a 'weight' |
_subscriptions_get_setting | Helper function to retrieve send_self/autosub_on_post/autosub_on_update/autosub_on_comment/ | 1, 0, digest/send_interval/send_updates/send_comments/ | -1 = use… |
_subscriptions_rem_access | |
_subscriptions_validate_hook_result | Check return values of hook_subscriptions(). |