From 45df705b3d927c55e7851d073b69dd2138f776e3 Mon Sep 17 00:00:00 2001
From: Moshe Weitzman <weitzman@tejasa.com>
Date: Mon, 7 Mar 2011 13:37:54 -0500
Subject: [PATCH] Mobile phone friendly emails. Can be turned on at user/n/edit

---
 includes/mail.inc     |   77 ++++++++++++++++++++++++++++--------------------
 project_issue.install |   53 +++++++++++++++++++++++++++++++++-
 project_issue.module  |   56 +++++++++++++++++++++++++++++++++++
 3 files changed, 153 insertions(+), 33 deletions(-)

diff --git a/includes/mail.inc b/includes/mail.inc
index 0e510fc..522f61e 100644
--- a/includes/mail.inc
+++ b/includes/mail.inc
@@ -289,6 +289,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.
   while ($recipient = db_fetch_object($result)) {
     // To save work, only go through a user_load if we need it.
     if ($check_file_perms || $check_node_access) {
@@ -297,6 +298,8 @@ function project_issue_mail_notify($nid) {
     }
     else {
       $language = language_default();
+      // Populate length preference
+      project_issue_user('load', $recipient, $recipient);
     }
 
     $can_access = $check_node_access ? node_access('view', $node, $account) : TRUE;
@@ -305,6 +308,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);
     }
   }
@@ -362,19 +366,31 @@ function _project_issue_mail($key, &$message, $params) {
         $message['headers']['Message-Id'] = "<type=project&nid=$node->nid&cid=$cid&host=@$domain>";
         $message['headers']['In-Reply-To'] = "<type=project&nid=$node->nid&host=@$domain>";
         $message['headers']['References'] = "<type=project&nid=$node->nid&host=@$domain> <type=project&nid=$node->nid&cid=$previous_cid&host=@$domain> <type=project&nid=$node->nid&revcount=1&host=@$domain>";
-      } else {
+      }
+      else {
         // Only original issue in this email.
         $message['headers']['Message-Id'] = "<type=project&nid=$node->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']);
+
+      if ($params['recipient']->project_issue_mail_length == PROJECT_ISSUE_MAIL_LENGTH_VERBOSE) {
+        $message['subject'] = t('[!short_name] [!category] !title', array('!short_name' => $project->project['uri'], '!category' => $node->project_issue['category'], '!title' => $node->title));
+        $message['body']['links'] = $links;
+        $message['body']['body'] = $body;
+      }
+      else {
+        // Omit short_name and category in brief mode.
+        $message['subject'] = $node->title;
+        // Show links last since recipient is less likely to follow-up using mobile device.
+        $message['body']['body'] = $body;
+        $message['body']['links'] = $links;
+      }
 
       break;
 
@@ -416,23 +432,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 preferred mail length.
  * @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_length = isset($recipient->project_issue_mail_length) ? $recipient->project_issue_mail_length : PROJECT_ISSUE_MAIL_LENGTH_VERBOSE;
 
   // 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_length])) {
+    return $cache[$display_files][$mail_length];
   }
 
   // Get most recent update.
@@ -483,31 +496,31 @@ 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_length == PROJECT_ISSUE_MAIL_LENGTH_VERBOSE) {
+    $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;
+    $output = "$summary\n$body";
   }
   else {
-    $output_without_files = $output;
+    $output = "$body\n$summary";
   }
 
+  // Set cached output.
+  $cache[$display_files][$mail_length] = $output;
+
   return $output;
 }
 
diff --git a/project_issue.install b/project_issue.install
index 1c24aff..9131474 100644
--- a/project_issue.install
+++ b/project_issue.install
@@ -293,7 +293,7 @@ function project_issue_schema() {
         'default' => 0,
       ),
       'uid' => array(
-        'description' => 'The {users}.uid for this subscriber.',
+        'description' => 'Foreign key: The {users}.uid for this subscriber.',
         'type' => 'int',
         'unsigned' => 1,
         'not null' => TRUE,
@@ -381,6 +381,27 @@ function project_issue_schema() {
     ),
     'primary key' => array('nid', 'uid'),
   );
+
+  $schema['project_issue_users'] = array(
+    'description' => 'User preferences for issues.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Foreign key: The {users}.uid for this subscriber.',
+        'type' => 'int',
+        'unsigned' => 1,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'mail_length' => array(
+        'description' => 'User preference for brief or verbose emails.',
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => 1,
+        'not null' => FALSE,
+      ),
+    ),
+    'primary key' => array('uid'),
+  );
   return $schema;
 }
 
@@ -626,3 +647,33 @@ function project_issue_update_6006() {
 
   return $ret;
 }
+
+/**
+ * Add the {project_issue_users} table.
+ */
+function project_issue_update_6007() {
+  $ret = array();
+
+  $table = array(
+    'description' => 'User preferences for issues.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'The {users}.uid for this user.',
+        'type' => 'int',
+        'unsigned' => 1,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'mail_length' => array(
+        'description' => 'User preference for brief or verbose emails.',
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => 1,
+        'not null' => FALSE,
+      ),
+    ),
+    'primary key' => array('uid'),
+  );
+  db_create_table($ret, 'project_issue_users', $table);
+  return $ret;
+}
diff --git a/project_issue.module b/project_issue.module
index a704d52..ef157aa 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);
+/// Long email notification emails containing all follow-ups
+define('PROJECT_ISSUE_MAIL_LENGTH_VERBOSE', 0);
+// Brief email notification emails.
+define('PROJECT_ISSUE_MAIL_LENGTH_BRIEF', 1);
+
 
 /**
  * Implementation of hook_init().
@@ -480,6 +485,57 @@ function project_issue_node_info() {
   );
 }
 
+/**
+ * Implementation of hook_user().
+ *
+ * Allows the user the option of enabling/disabling brief email notifications.
+ */
+function project_issue_user($type, &$edit, &$account, $category = NULL) {
+  if ($type == 'form' && $category == 'account') {
+    $form['project_issue'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Issue settings'),
+      '#weight' => 5,
+      '#collapsible' => TRUE,
+    );
+    $form['project_issue']['project_issue_mail_length'] = array(
+      '#type' => 'radios',
+      '#title' => t('Email notification format'),
+      '#options' => array(
+        PROJECT_ISSUE_MAIL_LENGTH_VERBOSE => t('Complete. Full issue history included in every email.'),
+        PROJECT_ISSUE_MAIL_LENGTH_BRIEF => t('Brief. Preferred when reading email on a mobile device'),
+      ),
+      '#default_value' => !empty($edit['project_issue_mail_length']) ? $edit['project_issue_mail_length'] : PROJECT_ISSUE_MAIL_LENGTH_VERBOSE,
+    );
+    return $form;
+  }
+  elseif ($type == 'load') {
+    if ($account->uid) {
+      $row = db_fetch_object(db_query('SELECT mail_length FROM {project_issue_users} WHERE uid = %d', $account->uid));
+      $account->project_issue_mail_length = isset($row->mail_length) ? $row->mail_length : NULL;
+    }
+    else {
+      $account->project_issue_mail_length = PROJECT_ISSUE_MAIL_LENGTH_VERBOSE;
+    }
+  }
+  elseif ($type == 'insert') {
+    if (isset($edit['project_issue_mail_length'])) {
+      db_query('INSERT INTO {project_issue_users} (uid, mail_length) VALUES (%d, %d)', $account->uid, $edit['project_issue_mail_length']);
+      $edit['project_issue_mail_length'] = NULL;
+    }
+  }
+  elseif ($type == 'update') {
+    db_query('UPDATE {project_issue_users} SET mail_length = %d WHERE uid = %d', $edit['project_issue_mail_length'], $account->uid);
+    if (!db_affected_rows()) {
+      db_query('INSERT INTO {project_issue_users} (uid, mail_length) VALUES (%d, %d)', $account->uid, $edit['project_issue_mail_length']);
+    }
+    $edit['project_issue_mail_length'] = NULL;
+  }
+  elseif ($type == 'delete') {
+    db_query('DELETE FROM {project_issue_users} WHERE uid = %d', $account->uid);
+  }
+}
+
 function project_issue_perm() {
   $perms = array(
     'create project issues',
-- 
1.7.3.5

