You are here

notifications_custom.module in Notifications 6

Same filename and directory in other branches
  1. 6.4 notifications_custom/notifications_custom.module

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.module
View 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;
}

Functions

Namesort descending Description
notifications_custom_account_update Update custom subscriptions for user account
notifications_custom_build_subscription Get subscription object from custom subscription type
notifications_custom_delete Delete custom subscription and optionally all instances of it
notifications_custom_form_alter Implementation of hook_form_alter()
notifications_custom_get_subscription Get user subscription for a custom one
notifications_custom_help Implementation of hook_help()
notifications_custom_list Retrieve list of custom notifications
notifications_custom_load Load custom subscription type
notifications_custom_menu Implementation of hook_menu().
notifications_custom_notifications Implementatin of hook_notifications()
notifications_custom_rebuild Rebuild list of custom subscriptions from modules and the database
notifications_custom_subscription_title Menu title callback
notifications_custom_theme Implementation of hook_theme()
notifications_custom_user Implementation of hook_user().
notifications_custom_user_form Build user account form
notifications_custom_user_multiple_subscribe User operations callback
notifications_custom_user_operations Implementation of hook_user_operations()
notifications_custom_user_overview_submit Form submission with custom notifications
notifications_custom_user_save Save user subscription
theme_notifications_custom_fields Theme function for fields in form