? comment_notify.lib.inc
? comment_notify_d7_4.patch
Index: comment_notify.info
===================================================================
RCS file: /cvs/drupal/contributions/modules/comment_notify/comment_notify.info,v
retrieving revision 1.3
diff -u -p -r1.3 comment_notify.info
--- comment_notify.info	6 Aug 2008 23:27:08 -0000	1.3
+++ comment_notify.info	18 Nov 2009 00:06:59 -0000
@@ -2,4 +2,6 @@
 name = Comment Notify
 description = "Comment follow-up e-mail notification for anonymous as well as registered users."
 dependencies[] = comment
-core = 6.x
+core = 7.x
+files[] = comment_notify.install
+files[] = comment_notify.module
Index: comment_notify.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/comment_notify/comment_notify.install,v
retrieving revision 1.16
diff -u -p -r1.16 comment_notify.install
--- comment_notify.install	8 Apr 2009 01:52:02 -0000	1.16
+++ comment_notify.install	18 Nov 2009 00:06:59 -0000
@@ -11,17 +11,26 @@
 function comment_notify_install() {
   // Create the table.
   drupal_install_schema('comment_notify');
-
-  // Insert a record for each existing comment.
-  if ( $GLOBALS['db_type']=='pgsql') {
-    db_query("INSERT INTO {comment_notify} (cid, notify, notify_hash) SELECT c.cid, 0, md5(c.mail || coalesce(u.mail, u.init) || c.uid || c.name || c.nid) FROM {comments} c LEFT OUTER JOIN {users} u on c.uid = u.uid");
+  
+  $comments_select = db_select('comment', 'c');
+  $comments_select->join('users', 'u', 'c.uid = u.uid');
+  $comments_select->addField('c', 'cid');
+  $comments_select->addExpression('0', 'notify');
+  if (db_driver() == 'pgsql') {
+    $comments_select->addExpression('md5(c.mail || coalesce(u.mail, u.init) || c.uid || c.name || c.nid)', 'notify_hash');
   }
   else {
-    db_query("INSERT INTO {comment_notify} (cid, notify, notify_hash) SELECT c.cid, 0, md5(concat(c.mail, ifnull(u.mail, u.init), c.uid, c.name, c.nid)) FROM {comments} c LEFT OUTER JOIN {users} u on c.uid = u.uid");
+  	$comments_select->addExpression('md5(concat(c.mail, ifnull(u.mail, u.init), c.uid, c.name, c.nid))', 'notify_hash');
   }
-
+  $comments_select->addField('c', 'cid');
+  
   // Set module weight low so that other modules act on the comment first.
-  db_query("UPDATE {system} SET weight = 10 WHERE name = 'comment_notify'");
+  db_insert('comment_notify')->from($comments_select)->execute();
+  db_update('system')->
+  	fields(array(
+  	'weight' => 10
+  	))
+  	->condition('name', 'comment_notify');
 }
 
 /**
@@ -30,7 +39,8 @@ function comment_notify_install() {
 function comment_notify_uninstall() {
   drupal_uninstall_schema('comment_notify');
   variable_del('node_notify_default_mailtext');
-  db_query("DELETE FROM {variable} WHERE name LIKE 'comment_notify_%'");
+  db_delete('variable')
+  	->where('name', "comment_notify_%", 'LIKE');
 }
 
 /**
@@ -95,208 +105,4 @@ function comment_notify_schema() {
   );
 
   return $schema;
-}
-
-/**
- * Sync up the two tables after as part of http://drupal.org/node/297791
- */
-function comment_notify_update_6000() {
-  $return[] = update_sql("DELETE FROM {comment_notify} WHERE cid NOT IN (SELECT cid FROM {comments})");
-  return $return;
-}
-
-/**
- * Permissions got renamed, update them.
- */
-function comment_notify_update_6001() {
-  $ret = array();
-  $result = db_query("SELECT pid, perm FROM {permission}");
-  while ($row = db_fetch_object($result)) {
-    $permissions = explode(', ', $row->perm);
-    if (in_array('Subscribe to comments', $permissions) && !in_array('subscribe to comments', $permissions)) {
-      $permissions[] = 'subscribe to comments';
-    }
-    if (in_array('Administer comment notify', $permissions) && !in_array('administer comment notify', $permissions)) {
-      $permissions[] = 'administer comment notify';
-    }
-
-    $permissions = implode(', ', $permissions);
-    $ret[] = update_sql("UPDATE {permission} SET perm = '%s' WHERE pid = %d", $permissions, $row->pid);
-  }
-  return $ret;
-}
-
-/**
- * Drop the notify column from the {comments} table.  This column will only exist
- * if the 5.x-1.x version of comment_notify was installed at some point.  Since
- * the 5.x-2.x version of the module {comment_notify}.notify has been used instead.
- */
-function comment_notify_update_6002() {
-  $ret = array();
-  if (db_column_exists('comments', 'notify')) {
-    db_drop_field($ret, 'comments', 'notify');
-  }
-  return $ret;
-}
-
-/**
- * Create a new table to store user preferences and move the $user->data there.
- */
-function comment_notify_update_6003() {
-  $ret = array();
-  // This determines how many users will be processed in each batch run.
-  $num_users_per_batch = 100;
-
-  // Multi-part update.
-  if (!isset($_SESSION['comment_notify_update_6003'])) {
-    // We need to start at uid 1, so initialize our variable
-    // to the value below that.
-    $_SESSION['comment_notify_update_6003'] = 1;
-    $_SESSION['comment_notify_update_6003_max'] = db_result(db_query("SELECT MAX(uid) FROM {users}"));
-
-    // Create the table.
-    $schema['comment_notify_user_settings'] = array(
-      'fields' => array(
-          'uid' => array(
-            'type' => 'serial',
-            'unsigned' => TRUE,
-            'description' => 'The user id from {users}.cid',
-            'not null' => TRUE,
-            'disp-width' => '11'),
-          'node_notify' => array(
-            'type' => 'int',
-            'size' => 'tiny',
-            'not null' => TRUE,
-            'default' => 0,
-            'disp-width' => '11'),
-          'comment_notify' => array(
-            'type' => 'int',
-            'size' => 'tiny',
-            'not null' => TRUE,
-            'default' => 0,
-            'disp-width' => '11'),
-      ),
-      'primary key' => array('uid'),
-    );
-
-    db_create_table($ret, 'comment_notify_user_settings', $schema['comment_notify_user_settings']);
-  }
-  // Do the next batch of the deed.
-
-  // Find the next N records to update, or do the final batch.
-  $next = min($_SESSION['comment_notify_update_6003'] + $num_users_per_batch, $_SESSION['comment_notify_update_6003_max']);
-
-  // Check to make sure that the {comment_notify_user_settings} table exists.
-  // If for some reason it was not created above, we might lose data when
-  // we delete the comment_notify data that is currently in {users}.data.
-  // If the table doesn't exist, then alert the user and don't allow any
-  // more batches to be processed.
-  if (!db_table_exists('comment_notify_user_settings')) {
-    unset($_SESSION['comment_notify_update_6003']);
-    unset($_SESSION['comment_notify_update_6003_max']);
-
-    // Alert the user that there was an error.
-    $ret[] = array('success' => FALSE, 'query' => t('For some reason the {comment_notify_user_settings} table was not properly created, and so per-user comment_notify settings could not be copied from {users}.data.  You will need to run this update again.'));
-    return $ret;
-  }
-
-  // Transfer the data in our specified range of uid values.
-  $uid = $_SESSION['comment_notify_update_6003'];
-  while ($uid <= $next) {
-    // Get the value of {users}.data.
-    $data = db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $uid));
-    $settings = array('uid' => $uid);
-    if (!empty($data)) {
-      $data = unserialize($data);
-      if (isset($data['node_notify_mailalert'])) {
-        $settings['node_notify'] = $data['node_notify_mailalert'];
-        unset($data['node_notify_mailalert']);
-      }
-      if (isset($data['comment_notify_mailalert'])) {
-        $settings['comment_notify'] = $data['comment_notify_mailalert'];
-        unset($data['comment_notify_mailalert']);
-      }
-      $fields_sql = '';
-      $values_sql = '';
-      foreach ($settings as $field => $value) {
-        $fields_sql .= "$field, ";
-        $values_sql .= '%d, ';
-      }
-      // Trim off any trailing commas and spaces.
-      $fields_sql = rtrim($fields_sql, ', ');
-      $values_sql = rtrim($values_sql, ', ');
-
-      // Add this user and settings to {comment_notify_user_settings} only if
-      // at least one setting was found in {users}.data for this user.
-      if (count($settings) > 1) {
-        db_query("INSERT INTO {comment_notify_user_settings} ($fields_sql) VALUES ($values_sql)", $settings);
-
-        // Remove this comment_notify data from {users}.data.
-        db_query("UPDATE {users} SET data = '%s' WHERE uid = %d", serialize($data), $uid);
-      }
-    }
-    $uid++;
-  }
-
-  // Remember where we left off.
-  $_SESSION['comment_notify_update_6003'] = $next;
-
-  if ($_SESSION['comment_notify_update_6003'] == $_SESSION['comment_notify_update_6003_max']) {
-    // We're done, clear these out.
-    unset($_SESSION['comment_notify_update_6003']);
-    unset($_SESSION['comment_notify_update_6003_max']);
-
-    // Provide an explaination of what we did.
-    $ret[] = array('success' => TRUE, 'query' => t('Moved comment_notify user settings data from the {users} table into the {comment_notify_user_settings} table.'));
-  }
-  elseif ($uid == $next) {
-    unset($_SESSION['comment_notify_update_6003']);
-    unset($_SESSION['comment_notify_update_6003_max']);
-    $ret[] = array('success' => FALSE, 'query' => t('Something is maybe not right.'));
-  }
-  else {
-    // Report how much is left to complete.
-    $ret['#finished'] = $_SESSION['comment_notify_update_6003'] / $_SESSION['comment_notify_update_6003_max'];
-  }
-
-  return $ret;
-}
-
-/**
- * Add a "notified" column to {comment_notify} to keep track of whether
- * notifications have already been sent out for a given comment.  This
- * prevents new notifications from being sent when a comment is edited.
- */
-function comment_notify_update_6004() {
-  $ret = array();
-
-  db_add_field($ret, 'comment_notify', 'notified', array('type' => 'int', 'size' => 'small', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
-
-  // Set the value in the notified column to 1 for all existing records.
-  $ret[] = update_sql('UPDATE {comment_notify} SET notified = 1');
-
-  return $ret;
-}
-
-/**
- * Having our foreign keys auto_increment could lead to unexpected results.
- */
-function comment_notify_update_6005() {
-  $ret = array();
-
-  db_change_field($ret, 'comment_notify', 'cid', 'cid',
-    array('type' => 'int',
-      'unsigned' => TRUE,
-      'description' => 'The comment id from {comments}.cid',
-      'not null' => TRUE,
-      'disp-width' => '11'));
-
-  db_change_field($ret, 'comment_notify_user_settings', 'uid', 'uid',
-    array('type' => 'int',
-      'unsigned' => TRUE,
-      'description' => 'The user id from {users}.cid',
-      'not null' => TRUE,
-      'disp-width' => '11'));
-
-  return $ret;
 }
\ No newline at end of file
Index: comment_notify.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/comment_notify/comment_notify.module,v
retrieving revision 1.73
diff -u -p -r1.73 comment_notify.module
--- comment_notify.module	17 Nov 2009 15:20:10 -0000	1.73
+++ comment_notify.module	18 Nov 2009 00:07:00 -0000
@@ -1,5 +1,8 @@
 <?php
-// $Id: comment_notify.module,v 1.73 2009/11/17 15:20:10 greggles Exp $
+// $Id: comment_notify.module,v 1.72 2009/11/07 18:39:55 greggles Exp $
+
+// Contains functions which utilize the database and other internal helpers.
+include_once 'comment_notify.lib.inc';
 
 /**
  * @file
@@ -7,50 +10,53 @@
  * This module provides comment follow-up e-mail notification for anonymous and registered users.
  */
 
+define('COMMENT_NOTIFY_DISABLED', 0);
+define('COMMENT_NOTIFY_NODE', 1);
+define('COMMENT_NOTIFY_COMMENT', 2);
+
+
 define('AUTHOR_MAILTEXT',
-'Hi !name,
+'Hi [user:name],
 
-You have received a comment on: "!node_title"
+You have received a comment on: "[node:title]"
 
 You can view the comment at the following url
-!comment_url
+[comment:url]
 
 You will receive emails like this for all replies to your posts. You can disable this by logging in and going to your account settings.
 
-Webmaster of !site
-!mission
-!uri');
+Webmaster of [site:name]
+[site:mission]
+[site:url]');
 
 define('DEFAULT_MAILTEXT',
-'Hi !name,
+'Hi [user:name],
 
-!commname has commented on: "!node_title"
+[comment:name] has commented on: "[node:title]"
 
 The post is about
 ----
-!node_teaser
+[node:summary]
 ----
 
 You can view the comment at the following url
-!comment_url
+[comment:url]
 
 You can stop receiving emails when someone replies to this post,
-by going to !link1
+by going to [comment:unsubscribe_url]
 
 If you have auto-following enabled in your account, you will receive emails like this for all replies to a blog post you commented on. You can disable this by logging in and going to your account settings or unchecking the flag at the time you post the comment.
 
 You can set up auto-following feature for all future posts
-by creating your own user with a few clicks here !uri/user/register
+by creating your own user with a few clicks here [site:url]/user/register
 
 Thanks for your feedback,
 
-Webmaster of !site
-!mission
-!uri');
+Webmaster of [site:name]
+[site:mission]
+[site:url]');
+
 
-define('COMMENT_NOTIFY_DISABLED', 0);
-define('COMMENT_NOTIFY_NODE', 1);
-define('COMMENT_NOTIFY_COMMENT', 2);
 
 /**
  * Provide an array of available options for notification on a comment.
@@ -72,93 +78,99 @@ function _comment_notify_options() {
   return $available_options;
 }
 
-/**
- * Insert our checkbox, add a submit button, and populate fields.
- */
-function comment_notify_form_alter(&$form, &$form_state, $form_id) {
+
+function comment_notify_form_comment_form_alter(&$form, &$form_state, $form_id) {
   global $user;
+  if (!(user_access('subscribe to comments') || user_access('administer comments'))) {
+    return;
+  }
 
-  // Only alter the form if it's a comment form and the user has the permission to subscribe.
-  if ($form_id == 'comment_form' && (user_access('subscribe to comments') || user_access('administer comments'))) {
-    // Only add the checkbox if this is an enabled content type
-    $node = node_load($form['nid']['#value'] ? $form['nid']['#value'] : $form['nid']['#default_value']);
-    $enabled_types = variable_get('comment_notify_node_types', drupal_map_assoc(array($node->type)));
-    if (empty($enabled_types[$node->type])) {
-      return;
-    }
+  // Only add the checkbox if this is an enabled content type
+  $node = node_load($form['nid']['#value'] ? $form['nid']['#value'] : $form['nid']['#default_value']);
+  $enabled_types = variable_get('comment_notify_node_types', drupal_map_assoc(array($node->type)));
+  if (empty($enabled_types[$node->type])) {
+    return;
+  }
 
-    $available_options = _comment_notify_options();
+  $available_options = _comment_notify_options();
 
-    drupal_add_css(drupal_get_path('module', 'comment_notify') .'/comment_notify.css');
-    drupal_add_js(drupal_get_path('module', 'comment_notify') .'/comment_notify.js');
+  drupal_add_css(drupal_get_path('module', 'comment_notify') .'/comment_notify.css');
+  drupal_add_js(drupal_get_path('module', 'comment_notify') .'/comment_notify.js');
 
-    // Add the checkbox for anonymous users and set the default based on admin settings.
-    if ($user->uid == 0) {
-      // If anonymous user's can't enter their e-mail don't tempt them with the checkbox.
-      if (empty($form['mail'])) {
-        return;
-      }
-      $preference = variable_get('comment_notify_default_anon_mailalert', COMMENT_NOTIFY_DISABLED);
-    }
-    else {
-      $user_preference = db_result(db_query("SELECT comment_notify FROM {comment_notify_user_settings} WHERE uid = %d", $user->uid));
-      $preference = strlen($user_preference) ? $user_preference : variable_get('comment_notify_default_registered_mailalert', COMMENT_NOTIFY_DISABLED);
+  // Add the checkbox for anonymous users and set the default based on admin settings.
+  if ($user->uid == 0) {
+    // If anonymous user's can't enter their e-mail don't tempt them with the checkbox.
+    if (empty($form['mail'])) {
+      return;
     }
+    $preference = variable_get('comment_notify_default_anon_mailalert', COMMENT_NOTIFY_DISABLED);
+  }
+  else {
+    $preference = comment_notify_get_user_comment_notify_preference($user->uid);
+  }
 
-    // If you want to hide this on your site see http://drupal.org/node/322482
-    $form['notify_settings'] = array(
+  // If you want to hide this on your site see http://drupal.org/node/322482
+  $form['notify_settings'] = array(
       '#prefix' => '<div class="clear-block">',
       '#suffix' => '</div>',
-    );
+  );
 
-    $form['notify_settings']['notify'] = array(
+  $form['notify_settings']['notify'] = array(
       '#type' => 'checkbox',
       '#title' => t('Notify me when new comments are posted'),
       '#default_value' => $preference,
-    );
+  );
 
-    if (count($available_options) > 1) {
-      $form['notify_settings']['notify_type'] = array(
+  if (count($available_options) > 1) {
+    $form['notify_settings']['notify_type'] = array(
         '#type' => 'radios',
         '#options' => $available_options,
         '#default_value' => $preference,
-      );
-    }
-    else {
-      $form['notify_settings']['notify_type'] = array(
+    );
+  }
+  else {
+    $form['notify_settings']['notify_type'] = array(
         '#type' => 'hidden',
         '#value' => key($available_options),
-      );
-    }
-    $form['notify_settings']['notify_type']['#default_value'] = $preference;
+    );
+  }
+  $form['notify_settings']['notify_type']['#default_value'] = $preference;
 
-    // If this is an existing comment we set the default value based on their selection last time.
-    if ($form['cid']['#value'] != '') {
-      $notify = db_result(db_query("SELECT notify FROM {comment_notify} WHERE cid = %d", $form['cid']['#value']));
-      $form['notify_settings']['notify']['#default_value'] = $notify;
-      if (count($available_options) > 1) {
-        $form['notify_settings']['notify_type']['#default_value'] = $notify;
-      }
-      else {
-        $form['notify_settings']['notify_type']['#default_value'] = key($available_options);
-      }
+  // If this is an existing comment we set the default value based on their selection last time.
+  if ($form['cid']['#value'] != '') {
+    $notify = comment_notify_get_notification_type($form['cid']['#value']);
+    $form['notify_settings']['notify']['#default_value'] = $notify;
+    if (count($available_options) > 1) {
+      $form['notify_settings']['notify_type']['#default_value'] = $notify;
+    }
+    else {
+      $form['notify_settings']['notify_type']['#default_value'] = key($available_options);
     }
   }
 }
 
 /**
- * Implementation of hook_perm().
+ * Implement of hook_permission().
  */
-function comment_notify_perm() {
-  return array('administer comment notify', 'subscribe to comments');
+function comment_notify_permission() {
+  return array(
+    'administer comment notify' => array(
+      'title' => 'Administer Comment Notify',
+      'description' => 'Change global comment notification settings.',
+  ),
+    'subscribe to comments' => array(
+      'title' => 'Subscribe to comment notifications',
+      'description' => 'Subscribe to recieve notifications when new comments are posted.',
+  ),
+  );
 }
 
 /**
- * Implementation of hook_menu().
+ * Implement of hook_menu().
  */
 function comment_notify_menu() {
 
-  $items['admin/settings/comment_notify'] = array(
+  $items['admin/config/people/comment_notify'] = array(
     'title' => 'Comment notify',
     'description' => 'Configure settings for e-mails about new comments.',
     'page callback' => 'drupal_get_form',
@@ -166,7 +178,7 @@ function comment_notify_menu() {
     'access arguments' => array('administer comment notify'),
     'type' => MENU_NORMAL_ITEM,
   );
-  $items['admin/settings/comment_notify/settings'] = array(
+  $items['admin/config/people/comment_notify/settings'] = array(
     'title' => 'Settings',
     'description' => 'Configure settings for e-mails about new comments.',
     'page callback' => 'drupal_get_form',
@@ -175,7 +187,7 @@ function comment_notify_menu() {
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
 
-  $items['admin/settings/comment_notify/unsubscribe'] = array(
+  $items['admin/config/people/comment_notify/unsubscribe'] = array(
     'title' => 'Unsubscribe',
     'description' => 'Unsubscribe an email from all notifications.',
     'weight' => 2,
@@ -199,157 +211,169 @@ function comment_notify_menu() {
  * Page callback to allow users to unsubscribe simply by visiting the page.
  */
 function comment_notify_disable_page($hash) {
-  db_query("UPDATE {comment_notify} SET notify = 0 WHERE notify_hash = '%s'", $hash);
-
-  drupal_set_message(t('Your comment follow-up notification for this post was disabled. Thanks.'));
+  if (comment_notify_unsubscribe_by_hash($hash)) {
+    drupal_set_message(t('Your comment follow-up notification for this post was disabled. Thanks.'));
+  } else {
+    drupal_set_message(t('Sorry, there was a problem unsubscribing from notifications.'));
+  }
   return ' ';
 }
 
-/**
- * Implementation of hook_comment().
- */
-function comment_notify_comment($comment, $op) {
+
+function comment_notify_comment_validate($comment) {
   global $user;
+  // We assume that if they are non-anonymous then they have a valid mail.
+  // For anonymous users, though, we verify that they entered a mail and let comment.module validate it is real.
+  if (!$user->uid && $comment->notify && empty($comment->mail)) {
+    form_set_error('mail', t('If you want to subscribe to comments you must supply a valid e-mail address.'));
+  }
+}
 
-  // In theory, the update or insert operations are duplicates with publish which
-  // would lead to duplicate messages.  _comment_notify_mailalert() protects against that.
-  switch ($op) {
-    case 'validate':
-       // We assume that if they are non-anonymous then they have a valid mail.
-       // For anonymous users, though, we verify that they entered a mail and let comment.module validate it is real.
-      if (!$user->uid && $comment['notify'] && empty($comment['mail'])) {
-        form_set_error('mail', t('If you want to subscribe to comments you must supply a valid e-mail address.'));
-      }
-      break;
-    case 'publish':
-      // And send notifications - the real purpose of the module.
-      _comment_notify_mailalert($comment);
-      break;
-    case 'update':
-      // In case they have changed their status, save it in the database.
-      $sql = 'UPDATE {comment_notify} SET notify = %d WHERE cid = %d';
-      if ($comment['notify']) {
-        db_query($sql, $comment['notify_type'], $comment['cid']);
-      }
-      else {
-        db_query($sql, 0, $comment['cid']);
-      }
-      // And send notifications - the real purpose of the module.
-      if ($comment['status'] == COMMENT_PUBLISHED) {
-        _comment_notify_mailalert($comment);
-      }
-      break;
-    case 'insert':
-      // For new comments, we first build up a string to be used as the identifier for the alert
-      $mail = empty($comment['mail']) ? $user->mail : $comment['mail'];
-      $notify_hash = drupal_get_token($mail . $comment['cid']);
-
-      if ($comment['notify']) {
-        $notify = $comment['notify_type'];
-        // If they don't have a preference, save one.
-        $current = db_result(db_query("SELECT count(1) from {comment_notify_user_settings} WHERE uid = %d", $user->uid));
-        if ($current == 0 && $user->uid) {
-          db_query("INSERT INTO {comment_notify_user_settings} (uid, comment_notify) VALUES (%d, %d)", $user->uid, $comment['notify_type']);
-        }
-      }
-      else {
-        $notify = $comment['notify'];
-      }
-      // And then save the data.
-      db_query("INSERT INTO {comment_notify} (cid, notify, notify_hash) values (%d, %d, '%s')", $comment['cid'], $notify, $notify_hash);
+function comment_notify_comment_publish($comment) {
+  // And send notifications - the real purpose of the module.
+  _comment_notify_mailalert($comment);
+}
 
-      // And send notifications - the real purpose of the module.
-      if ($comment['status'] == COMMENT_PUBLISHED) {
-        _comment_notify_mailalert($comment);
-      }
-      break;
-    case 'delete':
-      db_query("DELETE FROM {comment_notify} WHERE cid = %d", $comment->cid);
-      break;
+function comment_notify_comment_update($comment) {
+  // In case they have changed their status, save it in the database.
+  comment_notify_update_notification($comment->cid, $comment->notify_type);
+  // And send notifications - the real purpose of the module.
+  if ($comment->status == COMMENT_PUBLISHED) {
+    _comment_notify_mailalert($comment);
   }
+
 }
 
+function comment_notify_comment_insert($comment) {
+  global $user;
+  // For new comments, we first build up a string to be used as the identifier for the alert
+  // JS: This is terribly broken.  What if the user changes their email??!?
+  $mail = empty($comment->mail) ? $user->mail : $comment->mail;
+  $notify_hash = drupal_get_token($mail . $comment->cid);
+
+  if ($comment->notify) {
+    $notify = $comment->notify_type;
+    // If they don't have a preference, save one.
+    $current = comment_notify_get_user_comment_notify_preference($user->uid);
+    if ($current == 0 && $user->uid) {
+      comment_notify_set_user_notification_setting($user->uid, NULL, $comment->notify_type);
+    }
+  }
+  else {
+    $notify = 0;
+  }
+  // And then save the data.
+  comment_notify_add_notification($comment->cid, $notify, $notify_hash);
+
+  // And send notifications - the real purpose of the module.
+  if ($comment->status == COMMENT_PUBLISHED) {
+    _comment_notify_mailalert($comment);
+  }
+}
+
+function comment_notify_comment_delete($comment) {
+  comment_notify_remove_all_notifications($comment->cid);
+}
+
+
 /**
- * Implementation of hook_user().
+ * Implement hook_form_alter().
  */
-function comment_notify_user($type, &$edit, &$user, $category = NULL) {
-  switch ($type) {
-    case 'form':
-      if ($category == 'account' && user_access('subscribe to comments', $user)) {
-        $form = array();
-        $form['comment_notify_settings'] = array(
+function comment_notify_form_alter(&$form, &$form_state, $form_id) {
+  if (!($form_id == 'user_register_form' || $form_id == 'user_profile_form')) {
+    return;
+  }
+  elseif ($form['#user_category'] != 'account'){
+    return;
+  }
+
+  $user = $form['#user'];
+  if ($user->comment_notify_settings) {
+    $node_notify = $user->comment_notify_settings->node_notify;
+    $comment_notify = $user->comment_notify_settings->comment_notify;
+  }
+
+
+  $form['comment_notify_settings'] = array(
           '#type' => 'fieldset',
           '#title' => t('Comment follow-up notification settings'),
-          '#weight' => 4,
-          '#collapsible' => TRUE
-        );
-
-        // Only show the node followup UI if the user has permission to create nodes.
-        $nodes = FALSE;
-        foreach (node_get_types() as $type) {
-          if (user_access('create '. $type->type .' content')) {
-            $nodes = TRUE;
-            break;
-          }
-        }
-        if (user_access('administer nodes') || $nodes) {
-          $form['comment_notify_settings']['node_notify_mailalert'] = array(
+          '#weight' => 4,          '#collapsible' => TRUE
+  );
+
+
+  // Only show the node followup UI if the user has permission to create nodes.
+  $nodes = FALSE;
+  foreach (node_type_get_names() as $type) {
+    if (user_access('create '. $type .' content')) {
+      $nodes = TRUE;
+      break;
+    }
+  }
+
+  if (user_access('administer nodes') || $nodes) {
+    $form['comment_notify_settings']['node_notify'] = array(
             '#type' => 'checkbox',
             '#title' => t('Receive node follow-up notification e-mails'),
-            '#default_value' => isset($edit['node_notify_mailalert']) ? $edit['node_notify_mailalert'] : variable_get('node_notify_default_mailalert', FALSE),
+            '#default_value' => isset($node_notify) ? $node_notify : comment_notify_variable_registry_get('node_notify_default_mailalert'),
             '#description' => t('Check this box to receive an e-mail notification for follow-ups on your nodes (pages, forum topics, etc). You can not disable notifications for individual threads.')
-          );
-        }
-        else {
-          $form['comment_notify_settings']['node_notify_mailalert'] = array(
+    );
+  }
+  else {
+    $form['comment_notify_settings']['node_notify'] = array(
             '#type' => 'hidden',
             '#value' => COMMENT_NOTIFY_DISABLED,
-          );
-        }
+    );
+  }
 
-        $available_options[COMMENT_NOTIFY_DISABLED] = t('No notifications');
-        $available_options += _comment_notify_options();
-        $form['comment_notify_settings']['comment_notify_mailalert'] = array(
+  $available_options[COMMENT_NOTIFY_DISABLED] = t('No notifications');
+  $available_options += _comment_notify_options();
+  $form['comment_notify_settings']['comment_notify'] = array(
           '#type' => 'select',
           '#title' => t('Receive comment follow-up notification e-mails'),
-          '#default_value' => isset($edit['comment_notify_mailalert']) ? $edit['comment_notify_mailalert'] : variable_get('comment_notify_default_registered_mailalert', COMMENT_NOTIFY_DISABLED),
+          '#default_value' => isset($comment_notify) ? array($comment_notify) : array(comment_notify_variable_registry_get('comment_notify_default_registered_mailalert')),
           '#options' => $available_options,
           '#description' => t("Check this box to receive e-mail notification for follow-up comments to comments you posted. You can later disable this on a post-by-post basis... so if you leave this to YES, you can still disable follow-up notifications for comments you don't want follow-up mails anymore - i.e. for very popular posts.")
-        );
-        return $form;
-      }
-      break;
+  );
+  return $form;
+  // Construct the user form
+}
 
-    case 'submit':
-      // Save the values of node_notify_mailalert and comment_notify_mailalert
-      // to {comment_notify_user_settings}.
-      db_query('UPDATE {comment_notify_user_settings} SET node_notify = %d, comment_notify = %d WHERE uid = %d', $edit['node_notify_mailalert'], $edit['comment_notify_mailalert'], $user->uid);
-      if (!db_affected_rows()) {
-        db_query('INSERT INTO {comment_notify_user_settings} (uid, node_notify, comment_notify) VALUES (%d, %d, %d)', $user->uid, $edit['node_notify_mailalert'], $edit['comment_notify_mailalert']);
-      }
+function comment_notify_user_update(&$edit, $account, $category) {
+  if ($category != 'account') {
+    return;
+  }
+  if (isset($edit['node_notify']) && isset($edit['comment_notify'])) {
+    // Save the values of node_notify_mailalert and comment_notify_mailalert
+    // to {comment_notify_user_settings}.
+    comment_notify_set_user_notification_setting($account->uid, $edit['node_notify'], $edit['comment_notify']);
+  }
+  // Unset them from $user so they don't also get saved into {users}.data.
+  unset($edit['node_notify']);
+  unset($edit['comment_notify']);
 
-      // Unset them from $user so they don't also get saved into {users}.data.
-      unset($edit['node_notify_mailalert']);
-      unset($edit['comment_notify_mailalert']);
-      break;
+}
 
-    case 'load':
-      $user_settings = db_fetch_array(db_query('SELECT node_notify AS node_notify_mailalert, comment_notify AS comment_notify_mailalert FROM {comment_notify_user_settings} WHERE uid = %d', $user->uid));
-      if (!empty($user_settings)) {
-        foreach ($user_settings as $property => $value) {
-          $user->$property = $value;
-        }
-      }
-      break;
+function comment_notify_user_load(&$users) {
+  // Why would we want to load this on every user load?
+  foreach ($users as &$user) {
+    $user->comment_notify_settings = comment_notify_get_user_notification_setting($user->uid);
+  }
 
-    case 'delete':
-      db_query('DELETE FROM {comment_notify_user_settings} WHERE uid = %d', $user->uid);
-      break;
+  return;
 
-      break;
+  // @todo: Fix this naming weirdness.
+  foreach ($users as $user) {
+    $result = db_select('comment_notify_user_settings', 'cnus')
+    ->fields('cnus', array('node_notify' => 'node_notify_mailalert', 'comment_notify' => 'comment_notify_mailalert'))
+    ->condition('uid', $user->uid)
+    ->execute();
   }
 }
 
+function comment_notify_user_cancel(&$edit, $account, $method) {
+  comment_notify_delete_user_notification_setting($account->uid);
+}
+
 /**
  * Private function to send the notifications.
  *
@@ -368,7 +392,7 @@ function _comment_notify_mailalert($comm
   // Check to see if a notification has already been sent for this
   // comment so that edits to a comment don't trigger an additional
   // notification.
-  if (db_result(db_query('SELECT cid from {comment_notify} WHERE cid = %d AND notified = %d', $cid, 1))) {
+  if (comment_notify_is_notification_already_sent($cid)) {
     return;
   }
 
@@ -381,11 +405,6 @@ function _comment_notify_mailalert($comm
 
   $node = node_load($nid);
 
-  // Render up the node and comment.
-  $node_teaser = node_view($node, TRUE, TRUE, FALSE);
-  $node_body = node_view($node, FALSE, TRUE, FALSE);
-  $comment_text = check_markup($comment->comment, $comment->format);
-
   // No mails if this is not an enabled content type.
   $enabled_types = variable_get('comment_notify_node_types', array($node->type => TRUE));
   if (empty($enabled_types[$node->type])) {
@@ -403,48 +422,30 @@ function _comment_notify_mailalert($comm
 
   // Send to a subscribed author if they are not the current commenter
   $author = user_load(array('uid' => $node->uid));
-  if (!empty($author->node_notify_mailalert) && $author->node_notify_mailalert == 1 && $user->uid != $author->uid && node_access('view', $node, $author)) {
 
+  if (!empty($author->comment_notify_settings->node_notify) && $author->node_notify_mailalert == 1 && $user->uid != $author->uid && node_access('view', $node, $author)) {
     // Get the author's language.
     $language = user_preferred_language($author);
-    $message['subject'] = t('!site :: new comment for your post.', array('!site' => variable_get('site_name', 'drupal')));
-    $message['body'] = t(
-      variable_get('node_notify_default_mailtext', AUTHOR_MAILTEXT),
-      array(
-        '!cid' => $cid,
-        '!commname' => $comment->name,
-        '!commtext' => drupal_html_to_text($comment_text),
-        '!commsubj' => $comment->subject,
-        '!comment_url' => url('node/'. $nid, array('absolute' => TRUE, 'fragment' => 'comment-'. $cid)),
-        '!node_title' =>  $node->title,
-        '!node_teaser' => drupal_html_to_text($node_teaser),
-        '!mission' => variable_get('site_mission', ''),
-        '!nid' =>  $nid,
-        '!node_body' =>  drupal_html_to_text($node_body),
-        '!name' => $author->name,
-        '!site' => variable_get('site_name', 'drupal'),
-        '!uri' => $base_url,
-        '!uri_brief' => preg_replace('!^https?://!', '', $base_url),
-        '!date' => format_date(time()),
-        '!login_uri' => url('user', array('absolute' => TRUE)),
-        '!edit_uri' => url('user/'. $author->uid .'/edit', array('absolute' => TRUE))
-      )
+    $raw_values = array (
+      'subject' => comment_notify_variable_registry_get('author_subject'),
+      'body'  => comment_notify_variable_registry_get('node_notify_default_mailtext'), //JS @todo:change this.
     );
+    foreach ($raw_values as $k => $v) {
+      $message[$k] = comment_notify_tokenize(t($v), $comment, $node, $user);
+    }
+
     drupal_mail('comment_notify', 'comment_notify_mail', $author->mail, $language, $message);
     $sent_to[] = $author->mail;
   }
 
   // For "reply to my comments" notifications, figure out what thread this is.
-  $thread = db_result(db_query("SELECT thread FROM {comments} WHERE cid = %d", $cid));
+  $thread = comment_notify_get_thread($cid);
 
-  //Get the list of commenters to notify
-  $result = db_query(db_rewrite_sql("SELECT c.cid, c.nid, c.uid, c.name, c.mail AS cmail, u.mail AS umail, u.init AS uinit, c.uid, c.name, cn.notify, cn.notify_hash, c.thread
-    FROM {comments} c INNER JOIN {comment_notify} cn on c.cid = cn.cid LEFT OUTER JOIN {users} u ON c.uid = u.uid
-    WHERE c.nid = %d AND cn.notify > 0 AND c.status = 0 AND (u.status = 1 OR u.uid = 0)", 'c', 'cid'), $nid
-  );
   // TODO? the original big query had stuff making sure the mail was populated and contained .+@.+ Perhaps check for that here and set notify = 0 if that is the case for this cid
+  // Get the list of commenters to notify.
+  $watchers = comment_notify_get_watchers($nid);
 
-  while ($alert = db_fetch_object($result)) {
+  foreach ($watchers as $alert) {
     $umail = empty($alert->umail) ? $alert->uinit : $alert->umail;
     $mail = empty($alert->cmail) ? $umail : $alert->cmail;
 
@@ -452,7 +453,9 @@ function _comment_notify_mailalert($comm
     if ($alert->notify == COMMENT_NOTIFY_COMMENT && strcmp($relevant_thread . '/', $alert->thread) != 0) {
       continue;
     }
+
     if ($mail != $comment_mail && !in_array($mail, $sent_to) && $alert->uid != $comment->uid) {
+
       $message = array();
       if (!empty($alert->uid)) {
         $recipient_user = user_load(array('uid' => $alert->uid));
@@ -467,30 +470,19 @@ function _comment_notify_mailalert($comm
         continue;
       }
 
-      $message['subject'] = t('!site :: new comment for your post.', array('!site' => variable_get('site_name', 'drupal')));
-      $message['body'] = t(
-        variable_get('comment_notify_default_mailtext', DEFAULT_MAILTEXT),
-        array(
-          '!cid' => $cid,
-          '!commname' => $comment->name,
-          '!commtext' => drupal_html_to_text($comment_text),
-          '!commsubj' => $comment->subject,
-          '!comment_url' => url('node/'. $nid, array('absolute' => TRUE, 'fragment' => 'comment-'. $cid)),
-          '!node_title' =>  $node->title,
-          '!node_teaser' => drupal_html_to_text($node_teaser),
-          '!mission' => variable_get('site_mission', ''),
-          '!nid' =>  $nid,
-          '!node_body' =>  drupal_html_to_text($node_body),
-          '!name' => $alert->name,
-          '!site' => variable_get('site_name', 'drupal'),
-          '!uri' => $base_url,
-          '!uri_brief' => preg_replace('!^https?://!', '', $base_url),
-          '!date' => format_date(time()),
-          '!login_uri' => url('user', array('absolute' => TRUE)),
-          '!edit_uri' => url('user/'. $alert->uid .'/edit', array('absolute' => TRUE)),
-          '!link1' => url('comment_notify/disable/'. $alert->notify_hash, array('absolute' => TRUE))
-        )
+      $raw_values = array (
+        'subject' => comment_notify_variable_registry_get('watcher_subject'),
+        'body'  => comment_notify_variable_registry_get('comment_notify_default_mailtext'), //JS @todo:change this var name.
       );
+
+      foreach ($raw_values as $k => $v) {
+        $message[$k] = comment_notify_tokenize(t($v), $comment, $node, $user);
+      }
+
+      //      array(
+      //          '!link1' => url('comment_notify/disable/'. $alert->notify_hash, array('absolute' => TRUE))
+      //      )
+
       drupal_mail('comment_notify', 'comment_notify_mail', $mail, $language, $message);
       $sent_to[] = $mail;
 
@@ -506,11 +498,11 @@ function _comment_notify_mailalert($comm
       watchdog(
         'comment_notify',
         'Notified: !user_mail',
-        array('!user_mail' => $user_mail),
-        WATCHDOG_NOTICE,
-        l(t('source comment'), 'node/'. $nid, array(
+      array('!user_mail' => $user_mail),
+      WATCHDOG_NOTICE,
+      l(t('source comment'), 'node/'. $nid, array(
           'fragment' => 'comment-'. $alert->cid,
-        ))
+      ))
       );
 
       // revert to previous (site default) locale
@@ -519,11 +511,12 @@ function _comment_notify_mailalert($comm
   }
   // Record that a notification was sent for this comment so that
   // notifications aren't sent again if the comment is later edited.
-  db_query('UPDATE {comment_notify} SET notified = 1 WHERE cid = %d', $cid);
+
+  comment_notify_mark_comment_as_notified($cid);
 }
 
 /**
- * Implementation of hook_mail().
+ * Implement of hook_mail().
  */
 function comment_notify_mail($key, &$message, $params) {
   $message['subject'] = $params['subject'];
@@ -533,7 +526,7 @@ function comment_notify_mail($key, &$mes
 /**
  * Callback for an administrative form to unsubscribe users by e-mail address.
  */
-function comment_notify_unsubscribe() {
+function comment_notify_unsubscribe($form, &$form_state) {
   $form['comment_notify_unsubscribe'] = array();
   $form['comment_notify_unsubscribe']['email_to_unsubscribe'] = array(
     '#type' => 'textfield',
@@ -551,16 +544,7 @@ function comment_notify_unsubscribe() {
  */
 function comment_notify_unsubscribe_submit($form, &$form_state) {
   $email = trim($form_state['values']['email_to_unsubscribe']);
-  // If they have a uid, use that, otherwise update comments directly
-  $result = db_result(db_query_range("SELECT uid FROM {users} WHERE mail = '%s'", $email, 0, 1));
-  if ($result > 0) {
-    $comments = db_result(db_query("SELECT COUNT(1) FROM {comments} c INNER JOIN {comment_notify} cn ON c.cid = cn.cid WHERE c.uid = %d AND cn.notify > 0", $result));
-    db_query("UPDATE {comment_notify} SET notify = 0 WHERE cid IN (SELECT cid FROM  {comments} WHERE uid = %d)", $result);
-  }
-  else {
-    $comments = db_result(db_query("SELECT COUNT(1) FROM {comments} c INNER JOIN {comment_notify} cn ON c.cid = cn.cid WHERE c.mail = '%s' AND cn.notify > 0", $email));
-    db_query("UPDATE {comment_notify} SET notify = 0 WHERE cid IN (SELECT cid FROM {comments} WHERE mail = '%s')", $email);
-  }
+  $comments = comment_notify_unsubscribe_by_email($email);
   // Update the admin about the state of this comment notification subscription.
   if ($comments == 0) {
     drupal_set_message(t("There were no active comment notifications for that email."));
@@ -577,16 +561,16 @@ function comment_notify_unsubscribe_subm
 function comment_notify_settings() {
   $form['comment_notify_settings'] = array();
 
-  // Only perform comment_notify for certain node types (default, all)
-  $enabled_types = variable_get('comment_notify_node_types', FALSE);
+  // Only perform comment_notify for certain node types.
+  $enabled_types = comment_notify_variable_registry_get('node_types');
   $anonymous_problems = '';
-  foreach (node_get_types('names') as $type => $name) {
+  foreach (node_type_get_names() as $type => $name) {
     $checkboxes[$type] = check_plain($name);
     $default[] = $type;
 
     // If they don't have the ability to leave contact info, then we make a report
     if (isset($enabled_types[$type]) && $enabled_types[$type] && variable_get('comment_anonymous_'. $type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
-      $account = user_load(array('uid' => 0));
+      $account = drupal_anonymous_user();
       if (user_access('subscribe to comments', $account)) {
         $anonymous_problems[] = l(t('@content-type', array('@content-type' => $name)), 'admin/content/node-type/'. $type);
       }
@@ -600,7 +584,7 @@ function comment_notify_settings() {
   $form['comment_notify_settings']['comment_notify_node_types'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Content types to enable for comment notification'),
-    '#default_value' => variable_get('comment_notify_node_types', $default),
+    '#default_value' => $enabled_types,
     '#options' => $checkboxes,
     '#description' => t('Comments on content types enabled here will have the option of comment notification.'),
   );
@@ -609,12 +593,12 @@ function comment_notify_settings() {
     '#type' => 'checkboxes',
     '#title' => t('Available subscription modes'),
     '#return_value' => 1,
-    '#default_value' => variable_get('comment_notify_available_alerts', array(COMMENT_NOTIFY_NODE, COMMENT_NOTIFY_COMMENT)),
+    '#default_value' => comment_notify_variable_registry_get('available_alerts'),
     '#description' => t('Choose which notification subscription styles are available for users'),
     '#options' => array(
-      COMMENT_NOTIFY_NODE     => t('All comments'),
-      COMMENT_NOTIFY_COMMENT  => t('Replies to my comment')
-    )
+  COMMENT_NOTIFY_NODE     => t('All comments'),
+  COMMENT_NOTIFY_COMMENT  => t('Replies to my comment')
+  )
   );
 
   $available_options[COMMENT_NOTIFY_DISABLED] = t('No notifications');
@@ -623,7 +607,7 @@ function comment_notify_settings() {
     '#type' => 'select',
     '#title' => t('Default state for the notification selection box for anonymous users'),
     '#return_value' => 1,
-    '#default_value' => variable_get('comment_notify_default_anon_mailalert', COMMENT_NOTIFY_NODE),
+    '#default_value' => comment_notify_variable_registry_get('default_anon_mailalert'),
     '#options' => $available_options,
   );
 
@@ -631,77 +615,35 @@ function comment_notify_settings() {
     '#type' => 'select',
     '#title' => t('Default state for the notification selection box for registered users'),
     '#return_value' => 1,
-    '#default_value' => variable_get('comment_notify_default_registered_mailalert', COMMENT_NOTIFY_NODE),
+    '#default_value' => comment_notify_variable_registry_get('default_registered_mailalert'),
     '#description' => t('This flag presets the flag for the follow-up notification on the form that anon users will see when posting a comment'),
     '#options' => $available_options,
   );
 
-  $form['comment_notify_settings']['node_notify_default_mailalert'] = array(
+  $form['comment_notify_settings']['comment_notify_node_notify_default_mailalert'] = array(
     '#type' => 'checkbox',
     '#title' => t('Subscribe users to their node follow-up notification emails by default'),
-    '#default_value' => variable_get('node_notify_default_mailalert', FALSE),
+    '#default_value' => comment_notify_variable_registry_get('node_notify_default_mailalert'),
     '#description' => t('If this is checked, new users will receive e-mail notifications for follow-ups on their nodes by default until they individually disable the feature.'),
   );
 
+  $token_help = "Need a theme_token_info :(";
 
-  $form['comment_notify_settings']['comment_notify_default_mailtext'] = array(
+  $form['comment_notify_settings']['comment_notify_comment_notify_default_mailtext'] = array(
     '#type' => 'textarea',
     '#title' => t('Default mail text for sending out notifications to commenters'),
-    '#description' => t(
-      'You can use the following variables to be replaced:
-      <ul>
-      <li>!cid = the comment id for the comment
-      <li>!commname = the username who posted the comment
-      <li>!commtext = the text of the posted comment
-      <li>!commsubj = the subject of the posted comment
-      <li>!comment_url = the full url of the post and comment - note: if you have paging enabled, this does not work correct - set your max comments per page so that all fit on one page or reverse order them
-      <li>!nid = the node id the comment was posted on
-      <li>!node_title = the title of the node that was commented on
-      <li>!node_teaser = the teaser of the node that was commented on
-      <li>!node_body = the body of the node that was commented on
-      <li>!mission = site_mission text
-      <li>!name = username receiving the alert
-      <li>!site = your site
-      <li>!uri = base_url of site
-      <li>!uri_brief = base_url of site w/o http
-      <li>!date = the current time
-      <li>!login_uri  uri to login the user
-      <li>!edit_uri = uri to edit user profile
-      <li>!link1 the QUICKLINK to disable future follow-up notifications for the user
-      </ul>'
-    ),
-    '#default_value' => variable_get('comment_notify_default_mailtext', t(DEFAULT_MAILTEXT)),
+    '#suffix' => $token_help,
+    '#default_value' => comment_notify_variable_registry_get('comment_notify_default_mailtext'),
     '#return_value' => 1,
     '#cols' => 80,
     '#rows' => 15
   );
 
-  $form['comment_notify_settings']['node_notify_default_mailtext'] = array(
+  $form['comment_notify_settings']['comment_notify_node_notify_default_mailtext'] = array(
     '#type' => 'textarea',
     '#title' => t('Default mail text for sending out the notifications to node authors'),
-    '#description' => t(
-      'You can use the following variables to be replaced:
-      <ul>
-      <li>!cid = the comment id for the comment
-      <li>!commname = the username who posted the comment
-      <li>!commtext = the text of the posted comment
-      <li>!commsubj = the subject of the posted comment
-      <li>!comment_url = the full url of the post and comment - note: if you have paging enabled, this does not work correct - set your max comments per page so that all fit on one page or reverse order them
-      <li>!nid = the node id the comment was posted on
-      <li>!node_title = the title of the node that was commented on
-      <li>!node_teaser = the teaser of the node that was commented on
-      <li>!node_body = the body of the node that was commented on
-      <li>!mission = site_mission text
-      <li>!name = username receiving the alert
-      <li>!site = your site
-      <li>!uri = base_url of site
-      <li>!uri_brief = base_url of site w/o http
-      <li>!date = the current time
-      <li>!login_uri  uri to login the user
-      <li>!edit_uri = uri to edit user profile
-      </ul>'
-    ),
-    '#default_value' => variable_get('node_notify_default_mailtext', t(AUTHOR_MAILTEXT)),
+    '#suffix' => $token_help,
+    '#default_value' => comment_notify_variable_registry_get('node_notify_default_mailtext'),
      '#return_value' => 1,
      '#cols' => 80,
      '#rows' => 15
@@ -721,3 +663,21 @@ function comment_notify_settings_validat
     form_set_error('comment_notify_available_alerts', 'You must enable at least one subscription mode.');
   }
 }
+
+
+function comment_notify_tokens($type, $tokens, array $data = array(), array $options = array()) {
+
+  // Add the tokens for unsubscribe links
+  if ($type != "comment" ||!isset($data['comment'])) {
+    return;
+  }
+  $cid = $data['comment']->cid;
+  $hash = comment_notify_get_notify_hash($cid);
+  if (!$hash) {
+    return;
+  }
+  $replacements = array();
+  $replacements['comment:unsubscribe_url'] = url('comment_notify/disable/'. $hash, array('absolute' => TRUE));
+  return $replacements;
+
+}
Index: comment_notify.test
===================================================================
RCS file: /cvs/drupal/contributions/modules/comment_notify/comment_notify.test,v
retrieving revision 1.4
diff -u -p -r1.4 comment_notify.test
--- comment_notify.test	17 Nov 2009 18:38:14 -0000	1.4
+++ comment_notify.test	18 Nov 2009 00:07:00 -0000
@@ -20,9 +20,6 @@ class CommentNotifyTestCase extends Drup
     parent::setUp('comment_notify');
     // Create a content type where commenting is enabled.
     // Allow contact info for anons on that content type, and make preview optional.
-
-    // Do some default comment notify settings?.
-    // variable_set('some_variable', 'some value');
   }
 
   /**
@@ -42,21 +39,24 @@ class CommentNotifyTestCase extends Drup
     $this->node = $this->drupalCreateNode(array('type' => 'story', 'promote' => 1, 'comment' => 2));
 
     // Allow anonymous users to post comments and get notifications.
-    $this->setPermission('anonymous user', array('access comments' => TRUE, 'access content' => TRUE, 'post comments' => TRUE, 'post comments without approval' => TRUE, 'subscribe to comments' => TRUE));
+    $this->setPermission('anonymous', array('access comments' => TRUE, 'access content' => TRUE, 'post comments' => TRUE, 'post comments without approval' => TRUE, 'subscribe to comments' => TRUE));
     $this->drupalLogout();
 
     // Notify type 1 - All comments on the node.
     // First confirm that we properly require an e-mail address.
     $subscribe_1 = array('notify' => TRUE, 'notify_type' => 1);
     $this->postCommentNotifyComment($this->node, $this->randomName(), $this->randomName(), TRUE, TRUE, $subscribe_1);
-    $this->assertText(t('If you want to subscribe to comments you must supply a valid e-mail address.'), t('Anonymous user must leave E-mail if they want to get notifications.'));
+
+    // This is still a bad test to test for a static string showing on the page, but at least the definition of the string is centralized.
+    $expected_error = comment_notify_variable_registry_get('error_anonymous_email_missing');
+    $this->assertText(t($expected_error));
 
     // Try again with an e-mail address.
     $contact_1 = array('mail' => $this->randomName() .'@'. $this->randomName());
     $anonymous_comment_1 = $this->postCommentNotifyComment($this->node, $this->randomName(), $this->randomName(), TRUE, $subscribe_1, $contact_1);
 
     // Confirm that the notification is saved.
-    $result = db_result(db_query("SELECT notify FROM {comment_notify} WHERE cid = %d", $anonymous_comment_1['id']));
+    $result = comment_notify_get_notification_type($anonymous_comment_1['id']);
     $this->assertEqual($result, $subscribe_1['notify_type'], 'Notify selection option 1 is saved properly.');
 
     // Notify type 2 - replies to a comment.
@@ -65,7 +65,7 @@ class CommentNotifyTestCase extends Drup
     $anonymous_comment_2 = $this->postCommentNotifyComment($this->node, $this->randomName(), $this->randomName(), TRUE, $subscribe_2, $contact_2);
 
     // Confirm that the notification is saved.
-    $result = db_result(db_query("SELECT notify FROM {comment_notify} WHERE cid = %d", $anonymous_comment_2['id']));
+    $result = comment_notify_get_notification_type($anonymous_comment_2['id']);
     $this->assertEqual($result, $subscribe_2['notify_type'], 'Notify selection option 2 is saved properly.');
 
     // Confirm that the original subscriber with all comments on this node got their mail.
@@ -78,7 +78,7 @@ class CommentNotifyTestCase extends Drup
     $anonymous_comment_0 = $this->postCommentNotifyComment($this->node, $this->randomName(), $this->randomName(), TRUE, $subscribe_0, $contact_0);
 
     // Confirm that the notification is saved.
-    $result = db_result(db_query("SELECT notify FROM {comment_notify} WHERE cid = %d", $anonymous_comment_0['id']));
+    $result = comment_notify_get_notification_type($anonymous_comment_0['id']);
     $this->assertEqual($result, 2, 'Notify selection option 0 is saved properly.');
 
     // TODO yet more tests.
@@ -91,21 +91,13 @@ class CommentNotifyTestCase extends Drup
    * @param string $role User role to set permissions for.
    * @param array $permissions Key-value array of permissions to set.
    */
-  function setPermission($role, $permissions) {
+  function setPermission($role_name, $permissions) {
     // Get role id (rid) for specified role.
-    $rid = db_result(db_query("SELECT rid FROM {role} WHERE name = '%s'", array('%s' => $role)));
-    if ($rid === FALSE) {
-      $this->fail(t(' [permission] Role "' . $role . '" not found.'));
-    }
-
-    // Create edit array from permission.
-    $edit = array();
-    foreach ($permissions as $name => $value) {
-      $edit[$rid . '[' . $name . ']'] = $value;
+    $role = user_role_load($role_name);
+    if ($role) {
+      $this->fail('Unable to load role: ' . $role_name);
     }
-
-    $this->drupalPost('admin/user/permissions', $edit, t('Save permissions'));
-    $this->assertText(t('The changes have been saved.'), t(' [permission] Saved changes.'));
+    user_role_change_permissions($role->rid, $permissions);
   }
 
   /////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
