notifications_custom.module in Notifications 6
Same filename and directory in other branches
Custom notifications module
Create custom predefined notifications and
- Bulk operations to assign them to users
- Force for new users or display on the registration form
File
notifications_custom/notifications_custom.moduleView source
<?php
/**
* @file
* Custom notifications module
*
* Create custom predefined notifications and
* - Bulk operations to assign them to users
* - Force for new users or display on the registration form
*/
/**
* Implementation of hook_help()
*/
function notifications_custom_help($path, $arg) {
switch ($path) {
case 'admin/messaging/customsubs':
$output = '<p>' . t('You can create custom subscription types and make them available in the registration form or enforce them for new users. Once you have created one or more subscription types they can be assigned to one or more users on the <a href="@user-admin">User administration page</a>.', array(
'@user-admin' => url('admin/user/user/'),
)) . '</p>';
return $output;
}
}
/**
* Implementation of hook_menu().
*/
function notifications_custom_menu() {
$items['admin/messaging/customsubs'] = array(
'title' => 'Custom subscriptions',
'description' => 'Create and manage custom subscriptions.',
'page callback' => 'notifications_custom_admin_page',
'access arguments' => array(
'administer notifications',
),
'file' => 'notifications_custom.admin.inc',
);
$items['admin/messaging/customsubs/overview'] = array(
'title' => 'Custom subscriptions',
//'description' => 'Create and manage custom subscriptions.',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/messaging/customsubs/csid/%notifications_custom'] = array(
'title' => 'Custom',
'description' => 'Create and manage custom subscriptions.',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'notifications_custom_form',
4,
),
'title callback' => 'notifications_custom_subscription_title',
'title arguments' => array(
4,
),
'access arguments' => array(
'administer notifications',
),
'file' => 'notifications_custom.admin.inc',
);
$items['admin/messaging/customsubs/csid/%notifications_custom/edit'] = array(
'title' => 'Edit',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/messaging/customsubs/csid/%notifications_custom/fields'] = array(
'title' => 'Fields',
'description' => 'Create and manage custom subscriptions.',
'type' => MENU_LOCAL_TASK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'notifications_custom_fields_form',
4,
),
'access arguments' => array(
'administer notifications',
),
'file' => 'notifications_custom.admin.inc',
);
$items['admin/messaging/customsubs/csid/%notifications_custom/delete'] = array(
'title' => 'Delete',
'description' => 'Delete subscription type and user subscriptions.',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'notifications_custom_delete_confirm',
4,
),
'access arguments' => array(
'administer notifications',
),
'file' => 'notifications_custom.admin.inc',
'weight' => 100,
);
return $items;
}
/**
* Menu title callback
*/
function notifications_custom_subscription_title($subscription) {
return check_plain($subscription->name);
}
/**
* Implementation of hook_user().
*/
function notifications_custom_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'register':
return notifications_custom_user_form($edit, $account, $category, TRUE);
case 'form':
return notifications_custom_user_form($edit, $account, $category);
case 'update':
return notifications_custom_user_save($edit, $account, $category);
case 'insert':
return notifications_custom_user_save($edit, $account, $category, TRUE);
}
}
/**
* Implementatin of hook_notifications()
*/
function notifications_custom_notifications($op) {
switch ($op) {
case 'subscription types':
if ($custom = notifications_custom_list()) {
foreach ($custom as $subs) {
$types[$subs->type] = array(
'event_type' => $subs->event_type,
'title' => check_plain($subs->name),
'custom' => TRUE,
'fields' => array(),
);
foreach ($subs->fields as $field) {
$types[$subs->type]['fields'][] = $field['type'];
}
}
return $types;
}
break;
}
}
/**
* Build user account form
*/
function notifications_custom_user_form($edit, $account, $category, $register = FALSE, $hidden = TRUE) {
$form = $params = array();
if ($register) {
$params['register'] = 1;
}
if ($custom = notifications_custom_list($params)) {
$form['notifications_custom'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#title' => t('Subscriptions'),
);
foreach ($custom as $subs) {
if ($subs->visibility || user_access('administer users')) {
$form['notifications_custom'][$subs->type] = array(
'#type' => 'checkbox',
'#title' => $subs->title,
'#default_value' => $register ? $subs->default_value : (bool) notifications_custom_get_subscription($subs->type, $account->uid),
'#description' => $subs->explanation,
);
}
elseif ($hidden) {
// Hidden option
$form['notifications_custom'][$subs->type] = array(
'#type' => 'value',
'#value' => $subs->default_value,
);
}
}
}
return $form;
}
/**
* Save user subscription
*/
function notifications_custom_user_save(&$edit, $account, $category, $register = FALSE) {
$enabled = array();
if (!empty($edit['notifications_custom'])) {
$enabled = $edit['notifications_custom'];
}
// If registering, add hidden forced subscription (register = 0, default_value = 1)
if ($register && ($custom = notifications_custom_list(array(
'register' => 0,
'default_value' => 1,
)))) {
$enabled = array_merge($enabled, $custom);
}
notifications_custom_account_update($account, $enabled);
$edit['notifications_custom'] = NULL;
}
/**
* Implementation of hook_form_alter()
*/
function notifications_custom_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'notifications_user_overview' && ($custom = notifications_custom_list(array(
'visibility' => 1,
)))) {
$form['custom'] = array(
'#type' => 'item',
'#title' => t('edit subscriptions'),
'#weight' => 25,
);
$form['custom']['notifications_custom']['#tree'] = TRUE;
foreach ($custom as $subs) {
$form['custom']['notifications_custom'][$subs->type] = array(
'#type' => 'checkbox',
'#title' => $subs->title,
'#default_value' => (bool) notifications_custom_get_subscription($subs->type, $form['account']['#value']->uid),
'#description' => $subs->explanation,
);
}
$form['custom']['button'] = array(
'#type' => 'submit',
'#value' => t('Update'),
);
$form['#submit'][] = 'notifications_custom_user_overview_submit';
}
}
/**
* Form submission with custom notifications
*/
function notifications_custom_user_overview_submit($form, $form_state) {
if (notifications_custom_account_update($form_state['values']['account'], $form_state['values']['notifications_custom'])) {
drupal_set_message(t('Your subscriptions have been updated'));
}
}
/**
* Update custom subscriptions for user account
*
* @param $account
* User account
* @param $update
* Array of type => status
*
* @return int
* The number of updated subscriptions
*/
function notifications_custom_account_update($account, $update) {
$changed = 0;
foreach ($update as $type => $value) {
$user_subs = notifications_custom_get_subscription($type, $account->uid);
if ($value && !$user_subs) {
// Add new subscription
$subscription = notifications_custom_build_subscription($type);
$subscription->uid = $account->uid;
notifications_save_subscription($subscription);
$changed++;
}
elseif (!$value && $user_subs) {
// Disable existing subscription
notifications_delete_subscription($user_subs->sid);
$changed++;
}
}
return $changed;
}
/**
* Retrieve list of custom notifications
*
* @params
* Optional query conditions. It only works with integer values
*/
function notifications_custom_list($params = array()) {
if ($params) {
foreach ($params as $field => $value) {
$where[] = "{$field} = %d";
}
}
$sql = "SELECT * FROM {notifications_custom}";
if ($where) {
$sql .= ' WHERE (' . implode(') AND (', $where) . ')';
}
$sql .= " ORDER BY weight";
$result = db_query($sql, $params);
$custom = array();
while ($subs = db_fetch_object($result)) {
$subs->fields = empty($subs->fields) ? array() : unserialize($subs->fields);
$custom[$subs->type] = $subs;
}
return $custom;
}
/**
* Rebuild list of custom subscriptions from modules and the database
*/
function notifications_custom_rebuild() {
$custom = array();
$result = db_query("SELECT * FROM {notifications_custom}");
while ($subs = db_fetch_object($result)) {
$custom[$subs->type] = $subs;
}
// Get custom subscriptions defined by modules and merge with the ones in db
$modules = notifications_module_information('custom subscriptions');
foreach ($modules as $type => $subs) {
if (empty($custom[$type])) {
$subs = (object) $subs;
$subs->type = $type;
drupal_write_record('notifications_custom', $subs);
$custom[$type] = $subs;
}
}
}
/**
* Delete custom subscription and optionally all instances of it
*
* @param $type
* Custom subscription type to delete
* @param $instances
* Delete also subscription instances
*/
function notifications_custom_delete($type, $instances = FALSE) {
if ($instances) {
notifications_delete_subscriptions(array(
'type' => $type,
));
}
db_query("DELETE FROM {notifications_custom} WHERE type = '%s'", $type);
}
/**
* Load custom subscription type
*
* @param $key
* It may be csid (integer) or type (string)
*/
function notifications_custom_load($key) {
static $cache;
if (!isset($cache[$key])) {
if (is_numeric($key)) {
$where = 'csid = %d';
}
else {
$where = "type = '%s'";
}
$subs = db_fetch_object(db_query('SELECT * FROM {notifications_custom} WHERE ' . $where, $key));
if ($subs) {
$subs->fields = empty($subs->fields) ? array() : unserialize($subs->fields);
// Cache by type and id
$cache[$subs->csid] = $subs;
$cache[$subs->type] = $subs;
}
else {
$cache[$key] = FALSE;
}
}
return $cache[$key];
}
/**
* Get subscription object from custom subscription type
*
* @param $type
* Custom subscription type
*/
function notifications_custom_build_subscription($type) {
if ($subs = notifications_custom_load($type)) {
$subs->type = $type;
$fields = $subs->fields;
$subs->fields = array();
foreach ($fields as $field) {
$subs->fields[$field['type']] = $field['value'];
}
return $subs;
}
}
/**
* Get user subscription for a custom one
*
* @param $type
* Custom subscription type
* @param $uid
* User id
*/
function notifications_custom_get_subscription($type, $uid) {
$subs = notifications_get_subscriptions(array(
'uid' => $uid,
'type' => $type,
));
return $subs ? array_shift($subs) : NULL;
}
/**
* Implementation of hook_user_operations()
*/
function notifications_custom_user_operations($form_state = array()) {
$operations = array();
if (user_access('administer notifications') && ($custom_list = notifications_custom_list())) {
foreach ($custom_list as $subs) {
$subs_options['custom_subscribe-' . $subs->type] = $subs->name;
}
$operations = array(
t('Add subscription for selected users') => array(
'label' => $subs_options,
),
);
// If the form has been posted, we need to insert the proper data for adding subscriptions
if (!empty($form_state['submitted'])) {
$operation_subs = explode('-', $form_state['values']['operation']);
$operation = $operation_subs[0];
if ($operation == 'custom_subscribe') {
$type = $operation_subs[1];
$operations[$form_state['values']['operation']] = array(
'callback' => 'notifications_custom_user_multiple_subscribe',
'callback arguments' => array(
$type,
),
);
}
}
}
return $operations;
}
/**
* User operations callback
*/
function notifications_custom_user_multiple_subscribe($accounts, $type) {
$custom = notifications_custom_build_subscription($type);
$count = 0;
foreach ($accounts as $uid) {
// Skip subscribing the user if they already are subscribed.
if (!notifications_custom_get_subscription($type, $uid)) {
$subscription = clone $custom;
$subscription->uid = $uid;
notifications_save_subscription($subscription);
$count++;
}
}
drupal_set_message(format_plural($count, 'A user has been subscribed.', '@count users have been subscribed.'));
}
/**
* Implementation of hook_theme()
*/
function notifications_custom_theme() {
return array(
'notifications_custom_fields' => array(
'arguments' => array(
'element' => NULL,
),
),
);
}
/**
* Theme function for fields in form
*/
function theme_notifications_custom_fields($elements) {
$header = array(
t('Delete'),
t('Field type'),
t('Value'),
);
$rows = array();
foreach (element_children($elements['name']) as $key) {
$rows[] = array(
drupal_render($elements['delete'][$key]),
drupal_render($elements['name'][$key]),
drupal_render($elements['value'][$key]),
);
}
$output = theme('table', $header, $rows);
$output .= drupal_render($elements);
return $output;
}