diff --git a/includes/mail.inc b/includes/mail.inc index 5e539a2..f4de198 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(); } + // Also load in this recipient's project_issue e-mail preferences. + 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,42 @@ 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, + ); + if (!empty($preferences['mail_subject_project']) && !empty($preferences['mail_subject_category'])) { + $subject = t('[!short_name] [!category] !title', $subject_tokens); + } + elseif(!empty($preferences['mail_subject_project']) && empty($preferences['mail_subject_category'])) { + $subject = t('[!short_name] !title', $subject_tokens); + } + elseif(empty($preferences['mail_subject_project']) && !empty($preferences['mail_subject_category'])) { + $subject = t('[!category] !title', $subject_tokens); + } + else { + $subject = t('!title', $subjet_tokens); + } + $message['subject'] = $subject; + $message['body']['links'] = $links; + $message['body']['body'] = $body; break; case 'project_issue_critical_summary': @@ -476,23 +502,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 = isset($recipient->project_issue_notification['mail_body']) ? $recipient->project_issue_notification['mail_body'] : PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY; // 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 +566,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 8d45ff5..dcedcc1 100644 --- a/includes/notification.inc +++ b/includes/notification.inc @@ -106,6 +106,38 @@ function project_issue_notification_user_form(&$form_state, $account) { 'operations' => array(), ); + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Configure e-mail contents'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + + $options = array( + 'mail_subject_project' => t('Project name'), + 'mail_subject_category' => t('Issue category'), + ); + + $issue_preferences = array_filter($account->project_issue_notification); + $defaults = array_keys(array_intersect_key($options, $issue_preferences)); + + $form['advanced']['project_issue_mail_subject'] = array( + '#type' => 'checkboxes', + '#title' => t('Subject includes'), + '#options' => $options, + '#default_value' => $defaults, + ); + + $form['advanced']['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'), @@ -142,8 +174,13 @@ function project_issue_notification_user_form_submit($form, &$form_state) { // Update the global issue notification settings. $account = $form_state['values']['account']; - // First, save the default setting for this user. - $account->project_issue_notification = $form_state['values']['projects']['default']; + // First, save the global settings for this user. + $account->project_issue_notification = array( + 'level' => $form_state['values']['projects']['default'], + 'mail_body' => $form_state['values']['advanced']['project_issue_mail_body'], + 'mail_subject_project' => !empty($form_state['values']['advanced']['project_issue_mail_subject']['mail_subject_project']), + 'mail_subject_category' => !empty($form_state['values']['advanced']['project_issue_mail_subject']['mail_subject_category']), + ); project_issue_notification_user_settings_save($account); unset($form_state['values']['projects']['default']); diff --git a/project_issue.install b/project_issue.install index 71cd00a..2ff28a0 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' => 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' => 1, + 'not null' => TRUE, + 'default' => 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' => 1, + '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' => 1, + '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 the {project_issue_notification_global} table for other preferences. + */ +function project_issue_update_6018() { + $ret = array(); + + $spec = array( + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => 1, + 'not null' => TRUE, + ); + $spec['description'] = 'User preference for the body of notification e-mails (e.g. full history vs. only new content).'; + $spec['default'] = 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..b31fa57 100644 --- a/project_issue.module +++ b/project_issue.module @@ -9,6 +9,11 @@ define('PROJECT_ISSUE_AUTO_CLOSE_DAYS', 14); define('PROJECT_ISSUE_STATE_FIXED', 2); /// Project issue state = closed. define('PROJECT_ISSUE_STATE_CLOSED', 7); +// Email notification e-mail contains the full issue history. +define('PROJECT_ISSUE_MAIL_BODY_FULL_HISTORY', 0); +// Email notification e-mail only contains new content. +define('PROJECT_ISSUE_MAIL_BODY_NEW_CONTENT', 1); + /** * Project issue notification level: No notification emails. @@ -934,11 +939,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 +967,36 @@ function project_issue_notification_user_settings_load($account) { * - PROJECT_ISSUE_NOTIFICATION_NONE * - PROJECT_ISSUE_NOTIFICATION_OWN * - PROJECT_ISSUE_NOTIFICATION_ALL + * - mail_body: An integer for 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 if the user wants the + * issue category (bug, feature, etc) in the subject of issue + * notification e-emails. + * - mail_subject_project: A boolean indicating if the user wants the + * project name in the subject of issue notification e-emails. * * @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( + $mail_body = $account->project_issue_notification['mail_body']; + $mail_subject_category = $account->project_issue_notification['mail_subject_category']; + $mail_subject_project = $account->project_issue_notification['mail_subject_project']; + 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( $level, + $mail_body, + $mail_subject_category, + $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, + $mail_body, + $mail_subject_category, + $mail_subject_project, )); } }