Commit 7cd94c97 authored by Derek Wright's avatar Derek Wright
Browse files

[#397458] by dww: Massive edit of the code for consistent terminology.

- We use "notification" not "subscription" everywhere.
- The two new tables are now {project_issue_notification_global}
  and {project_issue_notification_project}. Both are per-user, the key
  difference is global settings vs. per-project settings.
- Renamed the constants for notification levels: we always want the
  constant to be "OWN", and just let the meaning of "OWN" change
  depending on whether or not flag.module is enabled and configured.
- Use "follow" terminology when appropriate for the flag.module case.
- Fixed PHPDoc to better conform to standards.
- Clean up the 'project_issue_follow_flag' setting on uninstall.
- Renamed includes/subscribe.inc to includes/notification.inc.
parent 8858cbc4
Loading
Loading
Loading
Loading
+5 −5
Changes for includes/admin.settings.inc: 5 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -32,12 +32,12 @@ function project_issue_settings_form(&$form_state) {
    foreach ($flags as $flag) {
      $flag_options[$flag->name] = $flag->title;
    }
    $form['project_issue_subscription_flag'] = array(
      '#title' => t('Issue subscription flag'),
    $form['project_issue_follow_flag'] = array(
      '#title' => t('Flag for following issues'),
      '#type' => 'select',
      '#options' => $flag_options,
      '#default_value' => variable_get('project_issue_subscription_flag', NULL),
      '#description' => t('Allows users to receive e-mail notifications about issues they flagged. If none is selected, users may only subscribe by commenting on an issue.'),
      '#default_value' => variable_get('project_issue_follow_flag', NULL),
      '#description' => t("Allows users to follow issues for both 'My issues' views and for e-mail notifications. If none is selected, users may only follow issues by commenting on them."),
    );
  }

@@ -45,7 +45,7 @@ function project_issue_settings_form(&$form_state) {
    '#type' => 'textfield',
    '#title' => t('Reply-to address on e-mail notifications'),
    '#default_value' => variable_get('project_issue_reply_to', variable_get('site_mail', ini_get('sendmail_from'))),
    '#description' => t('All issue e-mails sent via subscriptions will appear from this e-mail address. You can use %project as a placeholder which will be replaced with the %short_project_name setting for the issue\'s current project.', array('%project' => '%project', '%short_project_name' => t('Short project name'))),
    '#description' => t('All issue notification e-mails will appear from this e-mail address. You can use %project as a placeholder which will be replaced with the %short_project_name setting for the issue\'s current project.', array('%project' => '%project', '%short_project_name' => t('Short project name'))),
  );

  // Determine the auto followup username from the auto followup setting.
+19 −19
Changes for includes/mail.inc: 19 added lines, 19 removed lines.
Original line number Diff line number Diff line
@@ -250,13 +250,13 @@ function project_issue_mail_notify($nid) {
  }

  // Check whether Flag module integration is enabled for e-mail notifications.
  $flag_integration = (module_exists('flag') && variable_get('project_issue_subscription_flag', 0));
  $flag_integration = (module_exists('flag') && variable_get('project_issue_follow_flag', 0));

  // If flag integration is present, the list of users for 'own' issues will
  // be those that flagged the issue.
  if ($flag_integration) {
    // Retrieve all users who flagged the issue.
    $flag_contents = flag_get_content_flags('node', $node->nid, variable_get('project_issue_subscription_flag', 0));
    $flag_contents = flag_get_content_flags('node', $node->nid, variable_get('project_issue_follow_flag', 0));
    $own_issues_uids = array_keys($flag_contents);
  }
  // Without flag integration, 'own issues' are all users that posted to the
@@ -269,45 +269,45 @@ function project_issue_mail_notify($nid) {
  // Initialize the recipient list.  After compilation, the list will include
  // users that are:
  //  - globally subscribed to all issues
  //  - globally subscribed to own issues (without Flag integration)
  //  - globally subscribed to flagged issues
  //  - globally subscribed to "own" issues
  //  - subscribed to all issues of the project
  //  - subscribed to own issues of the project (without Flag integration)
  //  - subscribed to flagged issues of the project
  //  - subscribed to "own" issues of the project
  // Note that "own" changes meaning depending on if flag.module is enabled
  // and configured for following issues.
  $recipients = array();

  $args = array();

  // Build up filters for different issue subscription levels.
  // Build up filters for different issue notification levels.
  $filter_array = array();
  // 'All' level.
  $filter_array[] = "(pi.level = " . PROJECT_ISSUE_SUBSCRIPTIONS_ALL . ")";
  $filter_array[] = "(pi.level = " . PROJECT_ISSUE_NOTIFICATION_ALL . ")";
  // 'Own' level using the list of users attached to the issue.
  if (!empty($own_issues_uids)) {
    $placeholders = implode(',', array_fill(0, count($own_issues_uids), '%d'));
    $filter_array[] = "(pi.level = " . PROJECT_ISSUE_SUBSCRIPTIONS_FLAGGED . " AND u.uid IN ($placeholders))";
    $filter_array[] = "(pi.level = " . PROJECT_ISSUE_NOTIFICATION_OWN . " AND u.uid IN ($placeholders))";
    $args = array_merge($args, $own_issues_uids);
  }
  $filter = implode(" OR ", $filter_array);

  // Pull subscribers at the user level.
  $user_levels_query = "SELECT pi.uid, u.name, u.mail
    FROM {project_issue_subscriptions_user} pi
  // Pull users that want global notifications.
  $global_notification_query = "SELECT pi.uid, u.name, u.mail
    FROM {project_issue_notification_global} pi
    INNER JOIN {users} u ON pi.uid = u.uid
    WHERE u.status = 1 AND (" . $filter . ")";
  $result = db_query($user_levels_query, $args);
  $result = db_query($global_notification_query, $args);
  while ($account = db_fetch_object($result)) {
    $recipients[$account->uid] = $account;
  }

  // Pull subscribers at the project level.
  $project_levels_query = "SELECT pi.uid, u.name, u.mail
    FROM {project_issue_subscriptions_project} pi
  // Pull users that want notifications at the project level.
  $project_notification_query = "SELECT pi.uid, u.name, u.mail
    FROM {project_issue_notification_project} pi
    INNER JOIN {users} u ON pi.uid = u.uid
    WHERE u.status = 1 AND pi.nid = %d AND (" . $filter . ")";
  $project_levels_args = $args;
  array_unshift($project_levels_args, $node->project_issue['pid']);
  $result = db_query($project_levels_query, $project_levels_args);
  $project_notification_args = $args;
  array_unshift($project_notification_args, $node->project_issue['pid']);
  $result = db_query($project_notification_query, $project_notification_args);
  while ($account = db_fetch_object($result)) {
    $recipients[$account->uid] = $account;
  }
+51 −47
Changes for includes/notification.inc: 51 added lines, 47 removed lines.
Original line number Diff line number Diff line
@@ -4,31 +4,32 @@
 * @file
 * UI functionality for project issue e-mail notifications.
 *
 * Note: Internal function and variable names use "subscriptions" instead of
 * "notifications" for historical reasons.
 *
 * @see mail.inc
 */

/**
 * Returns project issue subscription levels.
 * Returns project issue notification levels.
 */
function _project_issue_subscriptions_levels() {
  return array(
    PROJECT_ISSUE_SUBSCRIPTIONS_NONE => t('None'),
    PROJECT_ISSUE_SUBSCRIPTIONS_FLAGGED => t('Subscribed issues'),
    PROJECT_ISSUE_SUBSCRIPTIONS_ALL => t('All issues'),
function _project_issue_notification_levels() {
  $levels = array(
    PROJECT_ISSUE_NOTIFICATION_NONE => t('None'),
    PROJECT_ISSUE_NOTIFICATION_OWN => t('Own issues'),
    PROJECT_ISSUE_NOTIFICATION_ALL => t('All issues'),
  );
  if (module_exists('flag') && variable_get('project_issue_follow_flag', 0)) {
    $levels[PROJECT_ISSUE_NOTIFICATION_OWN] = t('Issues you follow');
  }
  return $levels;
}

/**
 * Form constructor for global user project issue subscriptions.
 * Form constructor for global project issue notification settings for a user.
 */
function project_issue_subscriptions_user_form(&$form_state, $account) {
  // Global subscription level.
  project_issue_subscriptions_user_settings_load($account);
function project_issue_notification_user_form(&$form_state, $account) {
  // Global notification level.
  project_issue_notification_user_settings_load($account);

  $options = _project_issue_subscriptions_levels();
  $options = _project_issue_notification_levels();

  $form['account'] = array(
    '#type' => 'value',
@@ -36,45 +37,46 @@ function project_issue_subscriptions_user_form(&$form_state, $account) {
  );
  $form['#tree'] = TRUE;

  $form['project_issue_subscriptions'] = array(
  $form['project_issue_notification'] = array(
    '#type' => 'fieldset',
    '#title' => t('Issue notifications'),
    '#collapsible' => TRUE,
  );

  $form['project_issue_subscriptions']['level'] = array(
  $form['project_issue_notification']['level'] = array(
    '#type' => 'radios',
    '#title' => t('Global issue notification level'),
    '#title' => t('E-mail notification for all projects'),
    '#options' => $options,
    '#default_value' => $account->project_issue_subscriptions['level'],
    '#default_value' => $account->project_issue_notification['level'],
    // TODO: this could probably use some description text.
  );

  // Per-project subscription level (only enabled).
  // We only allow to change (and remove) per-project subscriptions on this
  // Per-project notification level (only enabled).
  // We only allow to change (and remove) per-project notifications on this
  // form. Users are able to subscribe to further projects by visiting the
  // individual project pages. In terms of UX, that's preferred anyway, since
  // a user normally wants to know and be sure what exactly she subscribes to.
  $form['project_issue_subscriptions']['projects'] = array(
    '#theme' => 'project_issue_subscriptions_projects_table',
  $form['project_issue_notification']['projects'] = array(
    '#theme' => 'project_issue_notification_projects_table',
    '#header' => array(t('Project'), t('Notification level')),
  );
  $result = db_query(db_rewrite_sql("SELECT pisp.nid, n.title, pisp.level
    FROM {project_issue_subscriptions_project} pisp
    FROM {project_issue_notification_project} pisp
    INNER JOIN {node} n ON n.nid = pisp.nid
    WHERE n.status = 1 AND pisp.uid = %d ORDER BY n.title
    ", 'n'), $account->uid);
  while ($project = db_fetch_object($result)) {
    $form['project_issue_subscriptions']['projects'][$project->nid]['title'] = array(
    $form['project_issue_notification']['projects'][$project->nid]['title'] = array(
      '#value' => l($project->title, "node/$project->nid"),
    );
    $form['project_issue_subscriptions']['projects'][$project->nid]['level'] = array(
    $form['project_issue_notification']['projects'][$project->nid]['level'] = array(
      '#type' => 'select',
      '#options' => $options,
      '#default_value' => $project->level,
      // Adjust #parents to get a simple $project->nid => $level mapping in the
      // submit handler. Without adjustment, the value would be
      // array('level' => $level).
      '#parents' => array('project_issue_subscriptions', 'projects', $project->nid),
      '#parents' => array('project_issue_notification', 'projects', $project->nid),
    );
  }

@@ -87,18 +89,18 @@ function project_issue_subscriptions_user_form(&$form_state, $account) {
}

/**
 * Form submission handler for project_issue_user_subscribe_form().
 * Form submission handler for project_issue_notification_user_form().
 */
function project_issue_subscriptions_user_form_submit($form, &$form_state) {
  // Update the global issue subscription settings.
function project_issue_notification_user_form_submit($form, &$form_state) {
  // Update the global issue notification settings.
  $account = $form_state['values']['account'];
  $account->project_issue_subscriptions = $form_state['values']['project_issue_subscriptions'];
  project_issue_subscriptions_user_settings_save($account);
  $account->project_issue_notification = $form_state['values']['project_issue_notification'];
  project_issue_notification_user_settings_save($account);

  // Insert the new per-project settings.
  if (!empty($form_state['values']['project_issue_subscriptions']['projects'])) {
    foreach ($form_state['values']['project_issue_subscriptions']['projects'] as $nid => $level) {
      project_issue_subscriptions_project_setting_save($account->uid, $nid, $level);
  if (!empty($form_state['values']['project_issue_notification']['projects'])) {
    foreach ($form_state['values']['project_issue_notification']['projects'] as $nid => $level) {
      project_issue_notification_project_setting_save($account->uid, $nid, $level);
    }
  }

@@ -106,9 +108,11 @@ function project_issue_subscriptions_user_form_submit($form, &$form_state) {
}

/**
 * Returns HTML for per-project subscription levels table in project_issue_user_subscribe_form().
 * Returns HTML for the table of per-project notification settings.
 *
 * @see project_issue_user_notification_form()
 */
function theme_project_issue_subscriptions_projects_table($element) {
function theme_project_issue_notification_projects_table($element) {
  $output = '';
  $rows = array();
  foreach (element_children($element) as $nid) {
@@ -126,15 +130,15 @@ function theme_project_issue_subscriptions_projects_table($element) {
}

/**
 * Form constructor for per-project issue subscription.
 * Form constructor for per-project issue notification settings.
 */
function project_issue_subscriptions_project_form($form_state, $project_nid) {
function project_issue_notification_project_form($form_state, $project_nid) {
  global $user;

  // Ensure the account has a valid e-mail address; may not be the case for
  // accounts created by external authentication providers.
  if (!valid_email_address($user->mail)) {
    drupal_set_message(t('You need to provide a valid e-mail address to subscribe to issue e-mails. Please edit your user information.'), 'error');
    drupal_set_message(t('You need to provide a valid e-mail address to receive issue notification e-mails. Please edit your user information.'), 'error');
    drupal_goto('user/' . $user->uid . '/edit');
  }

@@ -146,7 +150,7 @@ function project_issue_subscriptions_project_form($form_state, $project_nid) {
  }

  project_project_set_breadcrumb($project, TRUE);
  drupal_set_title(t('Subscribe to @project issues', array('@project' => $project->title)));
  drupal_set_title(t('Receive e-mail notifications for @project issues', array('@project' => $project->title)));

  $form['help'] = array(
    '#prefix' => '<p>',
@@ -166,27 +170,27 @@ function project_issue_subscriptions_project_form($form_state, $project_nid) {
    '#value' => $user->uid,
  );

  $level = project_issue_subscriptions_project_setting_load($user->uid, $project->nid);
  $level = project_issue_notification_project_setting_load($user->uid, $project->nid);
  $form['level'] = array(
    '#type' => 'radios',
    '#title' => t('Notification level'),
    '#options' => _project_issue_subscriptions_levels(),
    '#options' => _project_issue_notification_levels(),
    '#default_value' => $level,
    '#description' => t('Receive an e-mail notification when an issue for this project is updated.'),
  );

  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Subscribe'),
    '#value' => t('Save'),
  );
  return $form;
}

/**
 * Form submission handler for project_issue_user_subscribe_form().
 * Form submission handler for project_issue_project_notification_form().
 */
function project_issue_subscriptions_project_form_submit($form, &$form_state) {
  project_issue_subscriptions_project_setting_save($form_state['values']['uid'], $form_state['values']['nid'], $form_state['values']['level']);
function project_issue_notification_project_form_submit($form, &$form_state) {
  project_issue_notification_project_setting_save($form_state['values']['uid'], $form_state['values']['nid'], $form_state['values']['level']);

  drupal_set_message(t('Your subscription setting has been updated.'));
  drupal_set_message(t('Your notification settings have been updated.'));
}
+1 −1
Changes for includes/project_node.inc: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -65,6 +65,6 @@ function project_issue_project_delete($node) {
    node_delete($issue->nid);
  }
  db_query('DELETE FROM {project_issue_projects} WHERE nid = %d', $node->nid);
  db_query('DELETE FROM {project_issue_subscriptions_project} WHERE nid = %d', $node->nid);
  db_query('DELETE FROM {project_issue_notification_project} WHERE nid = %d', $node->nid);
}
+27 −26
Changes for project_issue.install: 27 added lines, 26 removed lines.
Original line number Diff line number Diff line
@@ -282,18 +282,18 @@ function project_issue_schema() {
    'primary key' => array('priority'),
  );

  $schema['project_issue_subscriptions_user'] = array(
    'description' => 'Stores global issue subscriptions per user.',
  $schema['project_issue_notification_global'] = array(
    'description' => 'Stores global issue notification settings per user.',
    'fields' => array(
      'uid' => array(
        'description' => 'The {users}.uid for this subscriber.',
        'description' => 'The {users}.uid for the user.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'level' => array(
        'description' => 'The global subscription setting level. 0 = None, 1 = Flagged, 2 = All.',
        'description' => 'The global notification setting level. 0 = None, 1 = Flagged/Own, 2 = All.',
        'type' => 'int',
        'size' => 'tiny',
        'unsigned' => TRUE,
@@ -307,25 +307,25 @@ function project_issue_schema() {
    ),
  );

  $schema['project_issue_subscriptions_project'] = array(
    'description' => 'Table keeping track of per-user project_issue subscriptions.',
  $schema['project_issue_notification_project'] = array(
    'description' => 'Table keeping track of per-project issue notification settings for each user.',
    'fields' => array(
      'nid' => array(
        'description' => '{project_projects}.nid of the project to which the user is subscribed.',
        'description' => '{project_projects}.nid of the project which the user wants issue notification emails for.',
        'type' => 'int',
        'unsigned' => 1,
        'not null' => TRUE,
        'default' => 0,
      ),
      'uid' => array(
        'description' => 'The {users}.uid for this subscriber.',
        'description' => 'The {users}.uid for this user.',
        'type' => 'int',
        'unsigned' => 1,
        'not null' => TRUE,
        'default' => 0,
      ),
      'level' => array(
        'description' => 'The type of subscription for the project. Possible values are: 0 = not subscribed, 1 = subscribed to own issues or 2 = subscribed to all issues.',
        'description' => 'The notification level for the project. Possible values are: 1 = notify for own/flagged issues; 2 = notify for all issues.',
        'type' => 'int',
        'size' => 'tiny',
        'unsigned' => 1,
@@ -477,6 +477,7 @@ function project_issue_uninstall() {
    'project_issue_invalid_releases',
    'project_issue_followup_user',
    'project_issue_hook_cron',
    'project_issue_follow_flag',
  );
  foreach ($variables as $variable) {
    variable_del($variable);
@@ -702,8 +703,10 @@ function project_issue_update_6008(&$sandbox) {
}

/**
 * Move subscriptions into the project_issue namespace, and split into
 * user-level and project-level.
 * Fix tables for issue notification emails.
 *
 * Move them into the project_issue namespace, split into global and
 * project-level tables, and standardize on "notification" as the terminology.
 */
function project_issue_update_6009() {
  $ret = array();
@@ -711,22 +714,22 @@ function project_issue_update_6009() {
  // Delete obsolete 'project_issue_global_subscribe_page' variable.
  variable_del('project_issue_global_subscribe_page');

  // Rename {project_subscriptions} to {project_issue_subscriptions_project}.
  db_rename_table($ret, 'project_subscriptions', 'project_issue_subscriptions_project');
  // Rename {project_subscriptions} to {project_issue_notification_project}.
  db_rename_table($ret, 'project_subscriptions', 'project_issue_notification_project');

  // Create new global issue subscription setting table.
  db_create_table($ret, 'project_issue_subscriptions_user', array(
    'description' => 'Stores global issue subscriptions per user.',
  // Create new global issue notification settings table.
  db_create_table($ret, 'project_issue_notification_global', array(
    'description' => 'Stores global issue notification settings per user.',
    'fields' => array(
      'uid' => array(
        'description' => 'The {users}.uid for this subscriber.',
        'description' => 'The {users}.uid for the user.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'level' => array(
        'description' => 'The global subscription setting level. 0 = None, 1 = Flagged, 2 = All.',
        'description' => 'The global notification setting level. 0 = None, 1 = Flagged/Own, 2 = All.',
        'type' => 'int',
        'size' => 'tiny',
        'unsigned' => TRUE,
@@ -744,7 +747,7 @@ function project_issue_update_6009() {
}

/**
 * Add primary key to {project_issue_subscriptions_project}.
 * Add primary key to {project_issue_notification_project}.
 *
 * WARNING: This update can take a *very* long time (potentially hours) if
 * there are a high number of rows in the table. The test table had 2.34
@@ -752,29 +755,27 @@ function project_issue_update_6009() {
 */
function project_issue_update_6010() {
  $ret = array();
  db_add_primary_key($ret, 'project_issue_subscriptions_project', array('uid', 'nid'));
  db_add_primary_key($ret, 'project_issue_notification_project', array('uid', 'nid'));
  return $ret;
}

/**
 * Add nid_level key to {project_issue_subscriptions_project}.
 * Add nid_level key to {project_issue_notification_project}.
 *
 * WARNING: This update can take a *very* long time (potentially hours) if
 * there are a high number of rows in the table.
 */
function project_issue_update_6011() {
  $ret = array();
  db_add_index($ret, 'project_issue_subscriptions_project', 'nid_level', array('nid', 'level'));
  db_add_index($ret, 'project_issue_notification_project', 'nid_level', array('nid', 'level'));
  return $ret;
}

/**
 * Drop unneccessary indexes from {project_issue_subscriptions_project}.
 * Drop unneccessary indexes from {project_issue_notification_project}.
 */
function project_issue_update_6012() {
  $ret = array();
  db_drop_index($ret, 'project_issue_subscriptions_project', 'uid');
  db_drop_index($ret, 'project_issue_subscriptions_project', 'project_subscriptions_nid_uid_level');
  db_drop_index($ret, 'project_issue_notification_project', 'project_subscriptions_nid_uid_level');
  return $ret;
}
Loading