From d0ef60dca3004d5dadf2950d6cf6c3fb20324618 Mon Sep 17 00:00:00 2001
From: scottrigby <scott@basekamp.com>
Date: Sat, 10 Dec 2011 21:38:46 -0500
Subject: [PATCH] Issue #1159632 by john.oltman, scottrigby: update to readme,
 info file declaration, add intervals, fix body markup, fix
 session function, fix queries, and make menu item placement
 more standard

---
 README.txt    |   13 ++-
 notify.info   |    3 +
 notify.module |  231 ++++++++++++++++++++++++++++++++++----------------------
 3 files changed, 152 insertions(+), 95 deletions(-)

diff --git a/README.txt b/README.txt
index 75ba2ff..97e717c 100644
--- a/README.txt
+++ b/README.txt
@@ -22,13 +22,15 @@ INSTALLATION
 1. Extract the notify module directory, including all its subdirectories, into
    your sites/all/modules directory.
 
-2. Enable the notify module on the Administer >> Site building >> Modules page.
+2. Enable the notify module on the Modules list page.
    The database tables will be created automagically for you at this point.
 
-3. Modify permissions on the Administer >> Users >> Permissions page.
+3. Modify permissions on the People >> Permissions page.
+
+4. Find the module in the Modules list page and click the Configuration link
+   to edit the settings to your liking.  You can also navigate directly to
+   admin/config/notify.
 
-4. Go to Administer >> Content >> Notification settings and modify the settings
-   to your liking.
    Note: e-mail updates can only happen as frequently as the cron is setup to.
    Check your cron settings.
 
@@ -49,6 +51,9 @@ Rob Barreca <rob@electronicinsight.com> was a previous maintainer.
 
 Matt Chapman <matt@ninjitsuweb.com> is the current maintainer.
 
+Ishmael Sanchez (http://ishmaelsanchez.com) and
+John Oltman <john.oltman@sitebasin.com> co-developed the Drupal 7 port.
+
 ------------------------
 RELATED PROJECTS & ALTERNATIVES
 ------------------------
diff --git a/notify.info b/notify.info
index fb66523..58b049e 100644
--- a/notify.info
+++ b/notify.info
@@ -2,3 +2,6 @@ name = Notify
 description = "Enables notifications of new content and comments by e-mail."
 package = Mail
 core = 7.x
+files[] = notify.install
+files[] = notify.module
+configure = admin/config/notify
diff --git a/notify.module b/notify.module
index d40a086..2e2a13c 100644
--- a/notify.module
+++ b/notify.module
@@ -32,6 +32,11 @@ function notify_help($section) {
  */
 function notify_admin_settings($form, &$form_state) {
   $period = array(
+    60 => format_interval(60),
+    120 => format_interval(120),
+    180 => format_interval(180),
+    300 => format_interval(300),
+    600 => format_interval(600),
     900 => format_interval(900),
     1800 => format_interval(1800),
     3600 => format_interval(3600),
@@ -143,10 +148,11 @@ function notify_user_cancel($edit, $account, $method) {
 }
 
 /**
- * Implements hook_user_XXX().
+ * Implements hook_form_FORM_ID_alter()
  */
-function notify_user_XXX($edit, $account) {
-  return _notify_user_reg_fields();
+function notify_form_user_register_form_alter(&$form, &$form_state, $form_id) {
+  dpm($form);
+  $form += _notify_user_reg_fields();
 }
 
 /**
@@ -156,31 +162,25 @@ function notify_user_insert(&$edit, $account, $category) {
   if (isset($edit['notify_decision']) && $edit['notify_decision'] == 1) {
     // TODO Please review the conversion of this statement to the D7 database API syntax.
     /* db_query('INSERT INTO {notify} (uid, status, node, teasers, comment) VALUES (%d, %d, %d, %d, %d)', $user->uid, 1, 1, 0, 0) */
-    $id = db_insert('notify')
-  ->fields(array(
-      'uid' => $user->uid,
+    db_insert('notify')
+      ->fields(array(
+      'uid' => $account->uid,
       'status' => 1,
       'node' => 1,
       'teasers' => 0,
       'comment' => 0,
     ))
-  ->execute();
+      ->execute();
     $edit['notify_decision'] = NULL;
   }
 }
 
 /**
- * Implements hook_user().
- */
-function notify_user_OLD($type, &$edit, &$user, $category = NULL) { }
-
-
-/**
  * Returns form fields to be added to User Regsitration form
  */
 function _notify_user_reg_fields() {
   if (!user_access('access notify')) {
-    return;
+    return array();
   }
 
   // Get the variable for how often the notifications are sent out
@@ -229,7 +229,7 @@ function notify_permission() {
 function notify_menu() {
   $items = array();
 
-  $items['admin/config/notify'] = array(
+  $items['admin/config/people/notify'] = array(
     'title' => 'Notification settings',
     'description' => 'Adjust settings for new content notifications sent by e-mail.',
     'page callback' => 'drupal_get_form',
@@ -238,6 +238,19 @@ function notify_menu() {
     'access arguments' => array('administer notify'),
     'type' => MENU_NORMAL_ITEM,
   );
+  $items['admin/config/people/notify/settings'] = array(
+    'title' => 'Settings',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+  $items['admin/config/people/notify/users'] = array(
+    'title' => 'Users',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('notify_admin_users'),
+    'access callback' => 'user_access',
+    'access arguments' => array('administer notify'),
+    'type' => MENU_LOCAL_TASK,
+  );
   $items['user/%user/notify'] = array(
     'title' => 'Notification settings',
     'page callback' => 'drupal_get_form',
@@ -246,14 +259,6 @@ function notify_menu() {
     'access arguments' => array(1),
     'type' => MENU_LOCAL_TASK,
   );
-  $items['admin/user/user/notify'] = array(
-    'title' => 'Notifications',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('notify_admin_users'),
-    'access callback' => 'user_access',
-    'access arguments' => array('administer notify'),
-    'type' => MENU_LOCAL_TASK,
-  );
 
   return $items;
 }
@@ -304,8 +309,9 @@ function notify_user_settings_form($form, &$form_state, $arg) {
     return;
   }
 
-  $result = db_query('SELECT u.uid, u.name, u.mail, n.status, n.node, n.teasers, n.comment FROM {users} u LEFT JOIN {notify} n ON u.uid = n.uid WHERE u.uid = :u.uid AND u.status = :u.status', array(':u.uid' => $account->uid, ':u.status' => 1));
-  $notify = db_fetch_object($result);
+  $result = db_query('SELECT u.uid, u.name, u.mail, n.status, n.node, n.teasers, n.comment FROM {users} u LEFT JOIN {notify} n ON u.uid = n.uid WHERE u.uid = :uid AND u.status = :status', array(':uid' => $account->uid, ':status' => 1));
+  foreach ($result as $notify) {
+  }
   $form = array();
   if (!$notify->mail) {
     drupal_set_message(t('Your e-mail address must be specified on your <a href="@url">my account</a> page.', array('@url' => url('user/' . $account->uid . '/edit'))), 'error');
@@ -369,19 +375,19 @@ function notify_user_settings_form_submit($form, &$form_state) {
   // TODO Please review the conversion of this statement to the D7 database API syntax.
   /* db_query('DELETE FROM {notify} WHERE uid = %d', $form_state['values']['uid']) */
   db_delete('notify')
-  ->condition('uid', $form_state['values']['uid'])
-  ->execute();
+    ->condition('uid', $form_state['values']['uid'])
+    ->execute();
   // TODO Please review the conversion of this statement to the D7 database API syntax.
   /* db_query('INSERT INTO {notify} (uid, status, node, teasers, comment) VALUES (%d, %d, %d, %d, %d)', $form_state['values']['uid'], $form_state['values']['status'], $form_state['values']['node'], $form_state['values']['teasers'], $form_state['values']['comment']) */
   $id = db_insert('notify')
-  ->fields(array(
+    ->fields(array(
     'uid' => $form_state['values']['uid'],
     'status' => $form_state['values']['status'],
     'node' => $form_state['values']['node'],
     'teasers' => $form_state['values']['teasers'],
     'comment' => $form_state['values']['comment'],
   ))
-  ->execute();
+    ->execute();
   drupal_set_message(t('Notify settings saved.'));
 }
 
@@ -395,34 +401,43 @@ function notify_admin_users($form, &$form_state) {
 
   $form['users'] = array();
 
-  $result = db_query('SELECT u.uid, u.name, u.mail, n.* FROM {users} u LEFT JOIN {notify} n ON u.uid = n.uid WHERE n.status = :n.status AND u.status = :u.status ORDER BY u.name', array(':n.status' => 1, ':u.status' => 1));
-  while ($notify = db_fetch_object($result)) {
-    $form['users'][$notify->uid] = array();
-    $form['users'][$notify->uid]['name'] = array(
+  // Fetch users with notify enabled
+  $q = db_select('notify', 'n');
+  $q->join('users', 'u', 'n.uid = u.uid');
+  $q->fields('u', array('uid', 'name', 'mail', 'language'));
+  $q->fields('n', array('status', 'node', 'comment', 'attempts', 'teasers'));
+  $q->condition('n.status', 1);
+  $q->condition('u.status', 1);
+  $q->orderBy('u.name');
+  $uresult = $q->execute();
+
+  foreach ($uresult as $user) {
+    $form['users'][$user->uid] = array();
+    $form['users'][$user->uid]['name'] = array(
       '#type' => 'markup',
-      '#value' => theme('username', array('account' => $notify)),
+      '#value' => theme('username', array('account' => $user)),
     );
-    $form['users'][$notify->uid]['mail'] = array(
+    $form['users'][$user->uid]['mail'] = array(
       '#type' => 'markup',
-      '#value' => $notify->mail,
+      '#value' => $user->mail,
     );
-    $form['users'][$notify->uid]['node'] = array(
+    $form['users'][$user->uid]['node'] = array(
       '#type' => 'checkbox',
-      '#default_value' => $notify->node,
+      '#default_value' => $user->node,
     );
-    $form['users'][$notify->uid]['teasers'] = array(
+    $form['users'][$user->uid]['teasers'] = array(
       '#type' => 'select',
-      '#default_value' => $notify->teasers,
+      '#default_value' => $user->teasers,
       '#options' => array(t('Title only'), t('Title + Teaser'), t('Title + Body')),
     );
-    $form['users'][$notify->uid]['comment'] = array(
+    $form['users'][$user->uid]['comment'] = array(
       '#type' => 'checkbox',
-      '#default_value' => $notify->comment,
+      '#default_value' => $user->comment,
     );
-    $form['users'][$notify->uid]['attempts'] = array(
+    $form['users'][$user->uid]['attempts'] = array(
       '#type' => 'textfield',
       '#size' => 2,
-      '#default_value' => $notify->attempts ? intval($notify->attempts) : 0,
+      '#default_value' => $user->attempts ? intval($user->attempts) : 0,
     );
   }
 
@@ -517,15 +532,22 @@ function theme_notify_admin_users($variables) {
  */
 function _notify_content($node, $notify) {
   static $i = 0;
+  $txt = '';
 
   switch ($notify->teasers) {
     case 0:
-      return;
+      return $txt;
     case 1:
-      $txt = check_markup($node->teaser, $node->format, $langcode = '' /* TODO Set this variable. */, FALSE);
+      $content = node_view($node,'teaser');
+      if (isset($content['body'][0]['#markup'])) {
+        $txt = $content['body'][0]['#markup'];
+      }
       break;
     case 2:
-      $txt = check_markup($node->body, $node->format, $langcode = '' /* TODO Set this variable. */, FALSE);
+      $content = node_view($node,'full');
+      if (isset($content['body'][0]['#markup'])) {
+        $txt = $content['body'][0]['#markup'];
+      }
   }
 
   return drupal_html_to_text($txt);
@@ -548,41 +570,58 @@ function _notify_send($send_start = NULL) {
   _notify_switch_user(); // Store current user
 
   // Fetch all node type authorized by notify settings
-  //Note that queries use 'nn' alias to avoid conflicts when query is rewritten by access control modules
   $ntype = array();
   foreach (node_type_get_types() as $type => $name) {
     if (variable_get(NOTIFY_NODE_TYPE . $type, 0)) {
       $ntype[] = $type;
     }
-    if (count($ntype) >= 1) {
-      $nodetypes_query = "AND (nn.type = '" . implode("' OR nn.type = '", $ntype) . "') ";
-    }
-    else {
-      $nodetypes_query = '';
-    }
   }
 
   // build query to fetch desired nodes.
-  $q = 'SELECT nn.nid FROM {node} nn WHERE (nn.status = 1 OR nn.moderate = 1) ' . $nodetypes_query . ' AND ((nn.created > %d AND nn.created <= %d)';
-  //include updated nodes?
-  $q .= variable_get('notify_include_updates', 1) ? ' OR (nn.changed > %d AND nn.changed <= %d))' : ')';
-  $q .= ' ORDER BY nn.created ASC';
+  $q = db_select('node', 'n');
+  $q->fields('n', array('nid'));
+  $q->condition('status', 1);
+  if (count($ntype) >= 1) {
+    $q->condition('n.type', $ntype, 'IN');
+  }
+  if (variable_get('notify_include_updates', 1)) {
+    $q->condition(db_or()->condition(db_and()->condition('n.created', $period, '>')->condition('n.created', $send_start, '<='))
+                         ->condition(db_and()->condition('n.changed', $period, '>')->condition('n.changed', $send_start, '<=')));
+  } else {
+    $q->condition('n.created', $period, '>');
+    $q->condition('n.created', $send_start, '<=');
+  }
+  $q->orderBy('n.created', 'asc');
+  $result = $q->execute();
 
   //Run the query, and load the nodes
   _notify_switch_user(1); //Query as if user 1, we check for individual user access later.
-  // TODO Please convert this statement to the D7 database API syntax.
-  $nresult = db_query(db_rewrite_sql($q, 'nn'), $period, $send_start, $period, $send_start);
   $nodes = array();
-  while ($node = db_fetch_object($nresult)) {
+  foreach ($result as $node) {
     $nodes[$node->nid] = node_load($node->nid);
   }
 
   // Fetch new comments.
   $comments = array();
   if (module_exists('comment')) {
-    // TODO Please convert this statement to the D7 database API syntax.
-    $cresult = db_query(db_rewrite_sql('SELECT c.nid, c.cid, c.subject, c.name, c.status FROM {comments} c INNER JOIN {node} nn ON c.nid = nn.nid WHERE c.timestamp > %d AND c.timestamp <= %d ' . $nodetypes_query . ' ORDER BY c.nid, c.timestamp', 'c'), $period, $send_start);
-    while ($comment = db_fetch_object($cresult)) {
+    $q = db_select('comment', 'c');
+    $q->join('node', 'n', 'c.nid = n.nid');
+    $q->fields('c');
+    if (count($ntype) >= 1) {
+      $q->condition('n.type', $ntype, 'IN');
+    }
+    if (variable_get('notify_include_updates', 1)) {
+      $q->condition(db_or()->condition(db_and()->condition('c.created', $period, '>')->condition('c.created', $send_start, '<='))
+                           ->condition(db_and()->condition('c.changed', $period, '>')->condition('c.changed', $send_start, '<=')));
+    } else {
+      $q->condition('c.created', $period, '>');
+      $q->condition('c.created', $send_start, '<=');
+    }
+    $q->orderBy('c.nid', 'asc');
+    $q->orderBy('c.changed', 'asc');
+    $cresult = $q->execute();
+
+    foreach ($cresult as $comment) {
       $comments[$comment->nid][] = $comment;
     }
   }
@@ -590,9 +629,19 @@ function _notify_send($send_start = NULL) {
   if (count($nodes) || count($comments)) {
 
     // Fetch users with notify enabled
-    $uresult = db_query('SELECT u.uid, u.name, u.mail, u.language, n.status, n.node, n.teasers, n.comment FROM {notify} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = :n.status AND u.status = :u.status AND n.attempts <= :n.attempts', array(':n.status' => 1, ':u.status' => 1, ':n.attempts' => variable_get('notify_attempts', 5)));
+    $q = db_select('notify', 'n');
+    $q->join('users', 'u', 'n.uid = u.uid');
+    $q->fields('u', array('uid', 'name', 'mail', 'language'));
+    $q->fields('n', array('status', 'node', 'teasers', 'comment'));
+    $q->condition('n.status', 1);
+    $q->condition('u.status', 1);
+    $q->condition('n.attempts', variable_get('notify_attempts', 5), '<=');
+    if (count($ntype) >= 1) {
+      $q->condition('n.type', $ntype, 'IN');
+    }
+    $uresult = $q->execute();
 
-    while ($user = db_fetch_object($uresult)) {
+    foreach ($uresult as $user) {
       // Switch current user to this account to use node_access functions, etc.
       _notify_switch_user($user->uid);
 
@@ -611,10 +660,7 @@ function _notify_send($send_start = NULL) {
           }
 
           // @TODO: Add functionality to hook into moderation modules?
-          if ($node->moderate == 1) {
-            $status = t('Queued');
-          }
-          elseif ($node->status == 1) {
+          if ($node->status == 1) {
             $status = t('Published');
           }
           elseif ($node->status == 0) {
@@ -640,6 +686,7 @@ function _notify_send($send_start = NULL) {
 
       // Write new comments to e-mail if user has permissions and there are
       // comments to be sent.
+
       if ($user->comment && user_access('access comments') && count($comments)) {
         $total_comment_count = 0;
         foreach ($comments as $nid => $comment) {
@@ -668,13 +715,17 @@ function _notify_send($send_start = NULL) {
               $status = $c->status == COMMENT_PUBLISHED ? t('Published') : t('Unpublished');
               $status = " [$status]";
             }
-            $comment_body .= '   ' . ++$comment_count . '.' . t('!status !title by !author',
-                                                              array(
-              '!status' => $status,
-              '!title' => $c->subject,
-              '!author' => ($c->name ? $c->name : variable_get('anonymous', 'Anonymous')),
+            $comment_body .= '   ' . ++$comment_count . '.' . t('!status !title by !author', array(
+              '!status' => $status, '!title' => $c->subject, '!author' => ($c->name ? $c->name : variable_get('anonymous', 'Anonymous')),
             )) . "\n"
               . '     ' . url('node/' . $nid, array('fragment' => 'comment-' . $c->cid, 'absolute' => TRUE)) . "\n\n";
+
+            /* @TODO - some people may not want comment body in the email, so make it an option instead of always included */
+            $comment_loaded = comment_load($c->cid);
+            if (isset($comment_loaded->comment_body[$comment_loaded->language][0]['value'])) {
+              $format = $comment_loaded->comment_body[$comment_loaded->language][0]['format'];
+              $comment_body .= drupal_html_to_text(check_markup($comment_loaded->comment_body[$comment_loaded->language][0]['value'], $format, $comment_loaded->language, FALSE)) . "\n\n" ;
+            }
             $total_comment_count++;
           }
         }
@@ -695,14 +746,10 @@ function _notify_send($send_start = NULL) {
         $headers = array(); //'From' => "$from_name <$from>");
         if (!drupal_mail('notify', 'send', $user->mail, user_preferred_language($user), array('content' => $body))) {
           $num_failed++;
-          // TODO Please review the conversion of this statement to the D7 database API syntax.
-          /* db_query('UPDATE {notify} SET attempts = attempts + 1 WHERE uid = %d', $user->uid) */
           db_update('notify')
-  ->fields(array(
-            'attempts' => attempts + 1,
-          ))
-  ->condition('uid', $user->uid)
-  ->execute();
+          ->expression('attempts', 'attempts + 1')
+          ->condition('uid', $user->uid)
+          ->execute();
           watchdog('notify', 'User %name (%mail) could not be notified. Mail error.', array('%name' => $user->name, '%mail' => $user->mail), WATCHDOG_ERROR);
         }
         else {
@@ -718,18 +765,20 @@ function _notify_send($send_start = NULL) {
 }
 
 /**
- * @todo Please document this function.
- * @see http://drupal.org/node/1354
+ * Implementation of hook_mail().
  */
 function notify_mail($key, &$message, $params) {
   global $user;
 
+  $message['headers']['MIME-Version'] = '1.0';
+  $message['headers']['Content-Type'] = 'text/plain';
+
   $message['subject'] = t('!sitename new content notification for !username', array('!username' => $user->name, '!sitename' => variable_get('site_name', 'Drupal')));
-  $message['body'] = t('Greetings !user,', array('!user' => $user->name)) . "\n\n";
-  $message['body'] .= $params['content'];
-  $message['body'] .= "\n-- \n";
-  $message['body'] .= t('This is an automatic e-mail from !sitename.', array('!sitename' => variable_get('site_name', 'Drupal'))) . "\n";
-  $message['body'] .= t('To stop receiving these e-mails, change your notification preferences at !notify-url', array('!notify-url' => url("user/$user->uid/notify", array('absolute' => TRUE)))) . "\n";
+  $message['body'][] = t('Greetings !user,', array('!user' => $user->name)) . "\n\n";
+  $message['body'][] = $params['content'];
+  $message['body'][] = "\n-- \n";
+  $message['body'][] = t('This is an automatic e-mail from !sitename.', array('!sitename' => variable_get('site_name', 'Drupal'))) . "\n";
+  $message['body'][] = t('To stop receiving these e-mails, change your notification preferences at !notify-url', array('!notify-url' => url("user/$user->uid/notify", array('absolute' => TRUE)))) . "\n";
 }
 
 /**
@@ -751,14 +800,14 @@ function _notify_switch_user($uid = NULL) {
     // Should a user visit cron.php, or should this module be invoked via poormanscron and _notify_send() does not complete,
     // the visitor will end up logged in as the "switched to user" for subsequent requests unless we disable saving the session
     // until we are sure we're the invoking user again.
-    session_save_session(FALSE);
+    drupal_save_session(FALSE);
     $user = user_load($uid);
   }
   // Retrieve the initial user, can be called multiple times.
   elseif (count($orig_user)) {
     $user = array_shift($orig_user);
     array_unshift($orig_user, $user);
-    session_save_session(TRUE);
+    drupal_save_session(TRUE);
   }
   // Store the initial user.
   else {
-- 
1.7.6.1

