Index: notify.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/notify/notify.install,v
retrieving revision 1.4.2.3
diff -u -p -r1.4.2.3 notify.install
--- notify.install	19 Aug 2007 22:42:14 -0000	1.4.2.3
+++ notify.install	9 Dec 2007 14:48:49 -0000
@@ -15,6 +15,7 @@ function notify_install() {
         comment TINYINT(2) NOT NULL DEFAULT '0',
         attempts TINYINT(4) NOT NULL DEFAULT '0',
         teasers TINYINT(4) NOT NULL DEFAULT '0',
+        last_notification int not null default '0',
         PRIMARY KEY (uid)
       ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
       break;
@@ -27,6 +28,7 @@ function notify_install() {
         comment integer NOT NULL DEFAULT '0',
         attempts integer NOT NULL DEFAULT '0',
         teasers integer NOT NULL DEFAULT '0',
+        last_notification int not null default '0',
         PRIMARY KEY (uid)
       );");
       break;
@@ -78,3 +80,20 @@ function notify_update_2() {
   drupal_set_message(t('The settings page for the notify.module is now to be found in Administer > Site configuration > Notification settings.'));
   return $ret;
 }
+
+
+/**
+ * Add new column last_notification and set it to the value of former variable notify_send_last
+ * 
+ */
+function notify_update_3() {
+  $result[] = update_sql("ALTER TABLE {notify} ADD COLUMN last_notification int  NOT NULL DEFAULT 0");
+  
+  $last_notify_time = (int)variable_get('notify_send_last',time());
+  
+  $result[] = update_sql("update {notify} set last_notification = $last_notify_time");
+  variable_del('notify_send_last');  // Now we'll use the notify_time in table
+  cache_clear_all();
+  drupal_set_message(t('Notify database table updated'));
+  return $result;
+}
Index: notify.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/notify/notify.module,v
retrieving revision 2.67.2.3
diff -u -p -r2.67.2.3 notify.module
--- notify.module	15 Jul 2007 03:54:19 -0000	2.67.2.3
+++ notify.module	9 Dec 2007 14:48:50 -0000
@@ -55,6 +55,15 @@ function notify_admin_settings() {
     '#default_value' => variable_get('notify_attempts', 5),
     '#options' => array(t('Disabled'), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20),
   );
+  
+  $form['notify_emails_per_cron'] = array(
+    '#type' => 'select',
+    '#title' => t('Maximim number of emails to send on each cron run'),
+    '#default_value' => variable_get('notify_emails_per_cron', 5000),
+    '#options' => array('5000' => 5000, 50 => 50, 100 => 100, 200 => 200, 
+        300 => 300, 400 => 400, 500 => 500),
+    '#description' => t('Many hosting companies place a limit on the number of outgoing emails. Select a number that makes sense for your cron setup and your hosting company\'s limit'),
+  );
 
   return system_settings_form($form);
 }
@@ -63,10 +72,10 @@ function notify_admin_settings() {
  * Implementation of hook_cron().
  */
 function notify_cron() {
-  if (time() - variable_get('notify_send_last', 0) > variable_get('notify_send', 86400)) {
+    if (_notify_check_upgrade_required())  {
+      return;
+    }
     _notify_send();
-    variable_set('notify_send_last', time());
-  }
 }
 
 /**
@@ -321,19 +330,22 @@ function _notify_content($node, $notify)
  * TODO: Needs some cleanup and themability.
  */
 function _notify_send() {
-  $period = variable_get('notify_send_last', time() - variable_get('notify_send', 86400));
   $separator = '------------------------------------------------------------------------------';
   $mini_separator = '---';
 
   $num_sent = 0;
   $num_failed = 0;
+  $max_to_send = variable_get('notify_emails_per_cron',5000);
 
   _notify_switch_user(); // Store current user
 
-  // Fetch users with notify enabled
-  $uresult = db_query('SELECT u.uid, u.name, u.mail, n.status, n.node, n.teasers, n.comment FROM {notify} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND u.status = 1 AND n.attempts <= %d', variable_get('notify_attempts', 5));
+  // Fetch users with notify enabled who are ready for a new notification
+  $uresult = db_query('SELECT u.uid, u.name, u.mail, n.status, n.node, n.teasers, n.comment, n.last_notification FROM {notify} n INNER JOIN {users} u ON n.uid = u.uid 
+    WHERE n.status = 1 AND u.status = 1 AND (unix_timestamp() - last_notification > %d) and n.attempts <= %d', 
+    variable_get('notify_send',86400), variable_get('notify_attempts', 5));
 
   while ($user = db_fetch_object($uresult)) {
+    $period = $user->last_notification;
     // Switch current user to this account to use node_access functions, etc.
     _notify_switch_user($user->uid);
 
@@ -449,11 +461,19 @@ function _notify_send() {
       else {
         $num_sent++;
         watchdog('user', t('Notify: User %name (%mail) notified successfully.', array('%name' => $user->name, '%mail' => $user->mail)));
-      }
+       }
+    }
+    // Update regardless of whether send failed, or the failing users will be at the front all the time
+    db_query('update {notify} set last_notification = unix_timestamp() where uid=%d',$user->uid);
+    if ($num_sent + $num_failed >= $max_to_send) { 
+      break;
     }
   }
   // Restore user.
   _notify_switch_user();
+  if ($num_sent || $num_failed) {
+    watchdog('notify',t("Sent %num_emails notifications in this cron run (%num_failed failed)",array('%num_emails' => $num_sent, '%num_failed'=>$num_failed)));
+  }
   return array($num_sent, $num_failed);
 }
 
@@ -533,3 +553,19 @@ function _notify_switch_user($uid = NULL
     $orig_user[] = $user;
   }
 }
+
+/**
+ * Check to see whether update_2 to update_3 has been run. If it has not, everybody
+ * will be notified on each cron run (or at least the first notify_emails_per_cron members)
+ *
+ * @return 
+ *  true if an upgrade is required (currently v2 to v3)
+ *  false if not
+ */
+function _notify_check_upgrade_required() {
+  if (variable_get('notify_send_last',-1000) != -1000) {  // If the old var still exists
+    watchdog('notify',t("Notify is disabled. You must run the update.php script to re-enable it"));
+    return true;
+  }
+  return false;
+}
