diff --git a/includes/mail.inc b/includes/mail.inc index 5e539a2..9a7cbfd 100644 --- a/includes/mail.inc +++ b/includes/mail.inc @@ -349,6 +349,7 @@ function project_issue_mail_notify($nid) { // some punctuation) are used. See example in Appendix A.1.2. $from = '"' . mime_header_encode($sender->name) . "\" <$sender->mail>"; + // Send notification to each connected user. foreach ($recipients as $recipient) { // To save work, only go through a user_load if we need it. if ($check_file_perms || $check_node_access) { @@ -358,6 +359,8 @@ function project_issue_mail_notify($nid) { else { $language = language_default(); } + // Load the recipient's content preferences for issue notification e-mails. + project_issue_notification_user_settings_load($recipient); $can_access = $check_node_access ? node_access('view', $node, $account) : TRUE; @@ -365,6 +368,7 @@ function project_issue_mail_notify($nid) { $display_files = $check_file_perms ? user_access('view uploaded files', $account) : TRUE; $params['display_files'] = $display_files; + $params['recipient'] = $recipient; drupal_mail('project_issue', 'project_issue_update_notification', $recipient->mail, $language, $params, $from); } } @@ -422,20 +426,41 @@ function _project_issue_mail($key, &$message, $params) { $message['headers']['Message-Id'] = "nid&cid=$cid&host=@$domain>"; $message['headers']['In-Reply-To'] = "nid&host=@$domain>"; $message['headers']['References'] = "nid&host=@$domain> nid&cid=$previous_cid&host=@$domain> nid&revcount=1&host=@$domain>"; - } else { + } + else { // Only original issue in this email. $message['headers']['Message-Id'] = "nid&host=@$domain>"; } project_issue_mail_output($node->title, 0); - $message['subject'] = t('[!short_name] [!category] !title', array('!short_name' => $project->project['uri'], '!category' => $node->project_issue['category'], '!title' => $node->title)); // Create link to related node $links = t('Issue status update for !link', array('!link' => "\n". url("node/$node->nid", array('absolute' => TRUE)))) ."\n"; $links .= t('Post a follow up: !link', array('!link' => "\n". url("comment/reply/$node->nid", array('fragment' => 'comment-form', 'absolute' => TRUE)))) ."\n"; - $message['body'][] = $links; - $message['body'][] = project_issue_mail_generate_followup_mail_body($node, $history, $params['display_files']); + $body = project_issue_mail_generate_followup_mail_body($node, $history, $params['display_files'], $params['recipient']); + + $preferences = $params['recipient']->project_issue_notification; + + // Construct the appropriate subject based on the user's preferences. + $subject_tokens = array( + '!short_name' => $project->project['uri'], + '!category' => $node->project_issue['category'], + '!title' => $node->title, + ); + $subject = array(); + if (!empty($preferences['mail_subject_project'])) { + $subject[] = '[!short_name]'; + } + if (!empty($preferences['mail_subject_category'])) { + $subject[] = '[!category]'; + } + $subject[] = '!title'; + + $subject = strtr(implode(' ', $subject), $subject_tokens); + $message['subject'] = $subject; + $message['body']['links'] = $links; + $message['body']['body'] = $body; break; case 'project_issue_critical_summary': @@ -476,23 +501,20 @@ function _project_issue_mail($key, &$message, $params) { * An array containing the history of issue followups. * @param $display_files * Boolean indicating if file attachments should be displayed. + * @param $recipient + * User object indicating recipient's notification preferences. * @return * A string of the email body. */ -function project_issue_mail_generate_followup_mail_body($node, $history, $display_files) { +function project_issue_mail_generate_followup_mail_body($node, $history, $display_files, $recipient = NULL) { global $user; - static $output_with_files = NULL, $output_without_files = NULL; + static $cache = array(); + + $mail_body = $recipient->project_issue_notification['mail_body']; // Return cached output if available. - if ($display_files) { - if (isset($output_with_files)) { - return $output_with_files; - } - } - else { - if (isset($output_without_files)) { - return $output_without_files; - } + if (isset($cache[$display_files][$mail_body])) { + return $cache[$display_files][$mail_body]; } // Get most recent update. @@ -543,30 +565,26 @@ function project_issue_mail_generate_followup_mail_body($node, $history, $displa project_issue_mail_output($content, 1, $entry->format); $body = "$content\n$entry->name\n"; - $hr = str_repeat('-', 72); - - if (count($history)) { + // Append complete follow-up history if recient prefers that. + if ($mail_body == PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY) { + $hr = str_repeat('-', 72); - $body .= "\n\n"; - $body .= t('Original issue:') ."\n"; - $body .= project_issue_mail_format_entry(array_shift($history), $display_files, TRUE); if (count($history)) { - $body .= "\n". t('Previous comments (!count):', array('!count' => count($history))) ."\n"; - foreach ($history as $entry) { - $body .= project_issue_mail_format_entry($entry, $display_files); + $body .= "\n\n"; + $body .= t('Original issue:') ."\n"; + $body .= project_issue_mail_format_entry(array_shift($history), $display_files, TRUE); + if (count($history)) { + $body .= "\n". t('Previous comments (!count):', array('!count' => count($history))) ."\n"; + foreach ($history as $entry) { + $body .= project_issue_mail_format_entry($entry, $display_files); + } } } } - $output = "$summary\n$body"; // Set cached output. - if ($display_files) { - $output_with_files = $output; - } - else { - $output_without_files = $output; - } + $cache[$display_files][$mail_body] = $output; return $output; } diff --git a/includes/notification.inc b/includes/notification.inc index dfc5005..7010292 100644 --- a/includes/notification.inc +++ b/includes/notification.inc @@ -108,6 +108,35 @@ function project_issue_notification_user_form(&$form_state, $account) { 'operations' => array(), ); + $form['content'] = array( + '#type' => 'fieldset', + '#title' => t('E-mail content'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $options = array( + 'mail_subject_project' => t('Project name'), + 'mail_subject_category' => t('Issue category'), + ); + $defaults = array_keys(array_filter(array_intersect_key($account->project_issue_notification, $options))); + $form['content']['project_issue_mail_subject'] = array( + '#type' => 'checkboxes', + '#title' => t('Subject includes'), + '#options' => $options, + '#default_value' => $defaults, + ); + + $form['content']['project_issue_mail_body'] = array( + '#type' => 'radios', + '#title' => t('Body includes'), + '#options' => array( + PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY => t('Full issue history'), + PROJECT_ISSUE_MAIL_BODY_NEW_CONTENT => t('Only new content'), + ), + '#default_value' => $account->project_issue_notification['mail_body'], + ); + $form['actions']['submit'] = array( '#type' => 'submit', '#value' => t('Save'), @@ -145,7 +174,12 @@ function project_issue_notification_user_form_submit($form, &$form_state) { $account = $form_state['values']['account']; // First, save the default setting for this user. - $account->project_issue_notification = $form_state['values']['project_issue_notification']['projects']['default']; + $account->project_issue_notification = array( + 'level' => (int) $form_state['values']['project_issue_notification']['projects']['default'], + 'mail_body' => (int) $form_state['values']['content']['project_issue_mail_body'], + 'mail_subject_project' => (int) !empty($form_state['values']['content']['project_issue_mail_subject']['mail_subject_project']), + 'mail_subject_category' => (int) !empty($form_state['values']['content']['project_issue_mail_subject']['mail_subject_category']), + ); project_issue_notification_user_settings_save($account); unset($form_state['values']['project_issue_notification']['projects']['default']); diff --git a/project_issue.install b/project_issue.install index 71cd00a..2ed0bae 100644 --- a/project_issue.install +++ b/project_issue.install @@ -298,7 +298,31 @@ function project_issue_schema() { 'size' => 'tiny', 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => 0, + 'default' => 0, // PROJECT_ISSUE_NOTIFICATION_NONE + ), + 'mail_body' => array( + 'description' => 'User preference for the body of notification e-mails (e.g. full history vs. only new content).', + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, // PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY + ), + 'mail_subject_project' => array( + 'description' => 'Defines if the subject of notification e-mails includes the project name.', + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 1, + ), + 'mail_subject_category' => array( + 'description' => 'Defines if the subject of notification e-mails includes the issue category (bug, feature, etc).', + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 1, ), ), 'primary key' => array('uid'), @@ -318,7 +342,7 @@ function project_issue_schema() { 'default' => 0, ), 'uid' => array( - 'description' => 'The {users}.uid for this user.', + 'description' => 'Foreign key: The {users}.uid for this subscriber.', 'type' => 'int', 'unsigned' => 1, 'not null' => TRUE, @@ -407,6 +431,7 @@ function project_issue_schema() { ), 'primary key' => array('nid', 'uid'), ); + return $schema; } @@ -1115,6 +1140,31 @@ function project_issue_update_6017() { ); } } +} + +/** + * Alter {project_issue_notification_global} for issue e-mail notification content preferences. + */ +function project_issue_update_6018() { + $ret = array(); + + $spec = array( + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'not null' => TRUE, + ); + $spec['description'] = 'User preference for the body of notification e-mails (e.g. full history vs. only new content).'; + $spec['default'] = 0; // PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY + db_add_field($ret, 'project_issue_notification_global', 'mail_body', $spec); + + $spec['description'] = 'Defines if the subject of notification e-mails includes the project name.'; + $spec['default'] = 1; + db_add_field($ret, 'project_issue_notification_global', 'mail_subject_project', $spec); + + $spec['description'] = 'Defines if the subject of notification e-mails includes the issue category (bug, feature, etc).'; + $spec['default'] = 1; + db_add_field($ret, 'project_issue_notification_global', 'mail_subject_category', $spec); return $ret; } diff --git a/project_issue.module b/project_issue.module index b7b1cdb..a2f1c3b 100644 --- a/project_issue.module +++ b/project_issue.module @@ -26,6 +26,16 @@ define('PROJECT_ISSUE_NOTIFICATION_OWN', 1); define('PROJECT_ISSUE_NOTIFICATION_ALL', 2); /** + * Project issue notification e-mail contains the full issue history. + */ +define('PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY', 0); + +/** + * Project issue notification e-mail only contains new content. + */ +define('PROJECT_ISSUE_MAIL_BODY_NEW_CONTENT', 1); + +/** * Implementation of hook_init(). */ function project_issue_init() { @@ -934,11 +944,14 @@ function project_issue_notification_user_settings_load($account) { // Setup defaults. $defaults = array( 'level' => PROJECT_ISSUE_NOTIFICATION_NONE, + 'mail_body' => PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY, + 'mail_subject_project' => TRUE, + 'mail_subject_category' => TRUE, ); // For existing accounts, load account settings. if (!empty($account->uid)) { - $settings = db_fetch_array(db_query("SELECT * FROM {project_issue_notification_global} WHERE uid = %d", array($account->uid))); + $settings = db_fetch_array(db_query("SELECT level, mail_body, mail_subject_project, mail_subject_category FROM {project_issue_notification_global} WHERE uid = %d", array($account->uid))); $settings = ($settings ? $settings : array()); $account->project_issue_notification = array_merge($defaults, $settings); } @@ -959,19 +972,31 @@ function project_issue_notification_user_settings_load($account) { * - PROJECT_ISSUE_NOTIFICATION_NONE * - PROJECT_ISSUE_NOTIFICATION_OWN * - PROJECT_ISSUE_NOTIFICATION_ALL + * - mail_body: An integer denoting the user's preference for e-mail bodies: + * - PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY + * - PROJECT_ISSUE_MAIL_BODY_NEW_CONTENT + * - mail_subject_category: A Boolean indicating whether the user wants the + * issue category (bug, feature, etc) in the subject of e-mails. + * - mail_subject_project: A Boolean indicating whether the user wants the + * project name in the subject of e-mails. * * @see project_issue_notification_user_settings_load() */ function project_issue_notification_user_settings_save($account) { - $level = $account->project_issue_notification['level']; - db_query("UPDATE {project_issue_notification_global} SET level = %d WHERE uid = %d", array( - $level, + db_query("UPDATE {project_issue_notification_global} SET level = %d, mail_body = %d, mail_subject_category = %d, mail_subject_project = %d WHERE uid = %d", array( + $account->project_issue_notification['level'], + $account->project_issue_notification['mail_body'], + $account->project_issue_notification['mail_subject_category'], + $account->project_issue_notification['mail_subject_project'], $account->uid, )); if (!db_affected_rows()) { - db_query("INSERT INTO {project_issue_notification_global} (uid, level) VALUES (%d, %d)", array( + db_query("INSERT INTO {project_issue_notification_global} (uid, level, mail_body, mail_subject_category, mail_subject_project) VALUES (%d, %d, %d, %d, %d)", array( $account->uid, - $level, + $account->project_issue_notification['level'], + $account->project_issue_notification['mail_body'], + $account->project_issue_notification['mail_subject_category'], + $account->project_issue_notification['mail_subject_project'], )); } }