Index: includes/alerting/email.inc.php
===================================================================
--- includes/alerting/email.inc.php	(revision 0)
+++ includes/alerting/email.inc.php	(working copy)
@@ -0,0 +1,107 @@
+<?php
+// this is legacy code, but i'll leave it here to not break existing
+// installations
+if ($config['alerts']['email']['default_only'])
+{
+  $email = $config['alerts']['email']['default'];
+} else {
+  if (get_dev_attrib($device,'override_sysContact_bool'))
+  {
+    $email = get_dev_attrib($device,'override_sysContact_string');
+  }
+  elseif ($device['sysContact'])
+  {
+    $email = $device['sysContact'];
+  } else {
+    $email = $config['alerts']['email']['default'];
+  }
+}
+
+// lookup additional email addresses that need a notification
+$sql = "SELECT contact_descr, contact_endpoint FROM `alert_contacts`";
+$sql .= " WHERE `contact_disabled` = 0 AND `contact_method` = 'email'";
+$sql .= " AND contact_id IN";
+$sql .= " (SELECT contact_id FROM `alert_contacts_assoc` WHERE `alert_checker_id` = ?);";
+
+foreach (dbFetchRows($sql, array($alert_id)) as $entry)
+{
+  $email .= "," . $entry['contact_descr'] . " <" . $entry['contact_endpoint'] . ">";
+}
+
+$emails = parse_email($email);
+
+// Find local hostname (could also use gethostname() on 5.3+)
+$localhost = php_uname('n');
+
+if ($emails)
+{
+  // Mail backend params
+  $backend = strtolower(trim($config['email_backend']));
+  switch ($backend)
+  {
+    case 'sendmail':
+      $params['sendmail_path'] = $config['email_sendmail_path'];
+      break;
+    case 'smtp':
+      $params['host']      = $config['email_smtp_host'];
+      $params['port']      = $config['email_smtp_port'];
+      if ($config['email_smtp_secure'] == 'ssl')
+      {
+        $params['host']    = 'ssl://'.$config['email_smtp_host'];
+        if ($config['email_smtp_port'] == 25)
+        {
+          $params['port']  = 465; // Default port for SSL
+        }
+      }
+      $params['timeout']   = $config['email_smtp_timeout'];
+      $params['auth']      = $config['email_smtp_auth'];
+      $params['username']  = $config['email_smtp_username'];
+      $params['password']  = $config['email_smtp_password'];
+      $params['localhost'] = $localhost;
+      if ($debug) { $params['debug'] = TRUE; }
+      break;
+    case 'mail':
+    default:
+      $backend = 'mail'; // Default mailer backend
+  }
+
+  // Mail headers
+  $headers = array();
+  if (empty($config['email_from']))
+  {
+    $headers['From']   = '"Observium" <observium@'.$localhost.'>'; // Default "From:"
+  } else {
+    foreach (parse_email($config['email_from']) as $from => $from_name)
+    {
+      $headers['From'] = (empty($from_name)) ? $from : '"'.$from_name.'" <'.$from.'>'; // From:
+    }
+  }
+  $rcpts_full = '';
+  $rcpts = '';
+  foreach ($emails as $to => $to_name)
+  {
+    $rcpts_full .= (empty($to_name)) ? $to.', ' : '"'.trim($to_name).'" <'.$to.'>, ';
+    $rcpts .= $to.', ';
+  }
+  $rcpts_full = substr($rcpts_full, 0, -2); // To:
+  $rcpts = substr($rcpts, 0, -2);
+  $headers['Subject']      = $title; // Subject:
+  $headers['X-Priority']   = 3; // Mail priority
+  $headers['X-Mailer']     = 'Observium ' . $config['version']; // X-Mailer:
+  $headers['Content-type'] = 'text/html';
+  $headers['Message-ID']   = '<' . md5(uniqid(time())) . '@' . $params['localhost'] . '>';
+  $headers['Date']         = date('r', time());
+
+  // Mail body
+  // $message_header = $config['page_title_prefix']."\n\n"; // Seems useless now.
+  $message_footer = "\n\nE-mail sent to: ".$rcpts."\n";
+  $message_footer .= "E-mail sent at: " . date($config['timestamp_format']) . "\n";
+  $body = $message . $message_footer;
+
+  // Create mailer instance
+  $mail =& Mail::factory($backend, $params);
+  // Sending email
+  $status = $mail->send($rcpts_full, $headers, $body);
+  if (PEAR::isError($status)) { echo 'Mailer Error: ' . $status->getMessage() . PHP_EOL; }
+}
+?>
Index: includes/alerts.inc.php
===================================================================
--- includes/alerts.inc.php	(revision 5371)
+++ includes/alerts.inc.php	(working copy)
@@ -809,7 +809,7 @@
 </body>
 </html>';
 
-      alert_notify($device, "RECOVER: [".$device['hostname']."] [".$alert['entity_type']."] [".$entity['entity_name']."] ".$alert['alert_message'],  $message);
+      alert_notify($device, "RECOVER: [".$device['hostname']."] [".$alert['entity_type']."] [".$entity['entity_name']."] ".$alert['alert_message'], $message, $entry['alert_test_id']);
 
       $update_array['last_recovered'] = time();
       $update_array['has_alerted'] = 0;
@@ -916,7 +916,7 @@
 </body>
 </html>';
 
-        alert_notify($device, "ALERT: [".$device['hostname']."] [".$alert['entity_type']."] [".$entity['entity_name']."] ".$alert['alert_message'],  $message);
+        alert_notify($device, "ALERT: [".$device['hostname']."] [".$alert['entity_type']."] [".$entity['entity_name']."] ".$alert['alert_message'], $message, $entry['alert_test_id']);
 
         $update_array['last_alerted'] = time();
         $update_array['has_alerted'] = 1;
@@ -928,108 +928,40 @@
   }
 }
 
-function alert_notify($device,$title,$message)
+function alert_notify($device,$title,$message,$alert_id=FALSE)
 {
   /// NOTE. Need full rewrite to universal function with message queues and multi-protocol (email,jabber,twitter)
+
   global $config, $debug;
 
-  if (!$device['ignore'])
+  // do not send alerts when the device is in either:
+  // ignore mode, disable_notify
+  if (!$device['ignore'] and !get_dev_attrib($device,'disable_notify'))
   {
-    if (!get_dev_attrib($device,'disable_notify'))
+    // figure out which transport methods apply to an alert
+    $transports = array();
+    $sql = "SELECT DISTINCT `contact_method` FROM `alert_contacts`";
+    $sql .= " WHERE `contact_disabled` = 0 AND contact_id IN";
+    $sql .= " (SELECT contact_id FROM `alert_contacts_assoc` WHERE `alert_checker_id` = ?);";
+
+    foreach (dbFetchRows($sql, array($alert_id)) as $entry)
     {
-      if ($config['alerts']['email']['default_only'])
-      {
-        $email = $config['alerts']['email']['default'];
-      } else {
-        if (get_dev_attrib($device,'override_sysContact_bool'))
-        {
-          $email = get_dev_attrib($device,'override_sysContact_string');
-        }
-        elseif ($device['sysContact'])
-        {
-          $email = $device['sysContact'];
-        } else {
-          $email = $config['alerts']['email']['default'];
-        }
-      }
-      $emails = parse_email($email);
+      $transports[] = $entry['contact_method'];
+    }
 
-      // Find local hostname (could also use gethostname() on 5.3+)
-      $localhost = php_uname('n');
+    // if alert_contacts table is not in use, fall back to default
+    if(!$transports) $transports = array('email');
 
-      if ($emails)
-      {
-        // Mail backend params
-        $backend = strtolower(trim($config['email_backend']));
-        switch ($backend)
-        {
-          case 'sendmail':
-            $params['sendmail_path'] = $config['email_sendmail_path'];
-            break;
-          case 'smtp':
-            $params['host']      = $config['email_smtp_host'];
-            $params['port']      = $config['email_smtp_port'];
-            if ($config['email_smtp_secure'] == 'ssl')
-            {
-              $params['host']    = 'ssl://'.$config['email_smtp_host'];
-              if ($config['email_smtp_port'] == 25)
-              {
-                $params['port']  = 465; // Default port for SSL
-              }
-            }
-            $params['timeout']   = $config['email_smtp_timeout'];
-            $params['auth']      = $config['email_smtp_auth'];
-            $params['username']  = $config['email_smtp_username'];
-            $params['password']  = $config['email_smtp_password'];
-            $params['localhost'] = $localhost;
-            if ($debug) { $params['debug'] = TRUE; }
-            break;
-          case 'mail':
-          default:
-            $backend = 'mail'; // Default mailer backend
-        }
-
-        // Mail headers
-        $headers = array();
-        if (empty($config['email_from']))
-        {
-          $headers['From']   = '"Observium" <observium@'.$localhost.'>'; // Default "From:"
-        } else {
-          foreach (parse_email($config['email_from']) as $from => $from_name)
-          {
-            $headers['From'] = (empty($from_name)) ? $from : '"'.$from_name.'" <'.$from.'>'; // From:
-          }
-        }
-        $rcpts_full = '';
-        $rcpts = '';
-        foreach ($emails as $to => $to_name)
-        {
-          $rcpts_full .= (empty($to_name)) ? $to.', ' : '"'.trim($to_name).'" <'.$to.'>, ';
-          $rcpts .= $to.', ';
-        }
-        $rcpts_full = substr($rcpts_full, 0, -2); // To:
-        $rcpts = substr($rcpts, 0, -2);
-        $headers['Subject']      = $title; // Subject:
-        $headers['X-Priority']   = 3; // Mail priority
-        $headers['X-Mailer']     = 'Observium ' . $config['version']; // X-Mailer:
-        $headers['Content-type'] = 'text/html';
-        $headers['Message-ID']   = '<' . md5(uniqid(time())) . '@' . $params['localhost'] . '>';
-        $headers['Date']         = date('r', time());
-
-        // Mail body
-        // $message_header = $config['page_title_prefix']."\n\n"; // Seems useless now.
-        $message_footer = "\n\nE-mail sent to: ".$rcpts."\n";
-        $message_footer .= "E-mail sent at: " . date($config['timestamp_format']) . "\n";
-        $body = $message . $message_footer;
-
-        // Create mailer instance
-        $mail =& Mail::factory($backend, $params);
-        // Sending email
-        $status = $mail->send($rcpts_full, $headers, $body);
-        if (PEAR::isError($status)) { echo 'Mailer Error: ' . $status->getMessage() . PHP_EOL; }
+    foreach ($transports as $method)
+    {
+      switch ($method) {
+        case "email":
+          include_once('includes/alerting/email.inc.php');
+          // case "sms":
+          // case "jabber":
+          // case "etc..."
       }
     }
   }
 }
-
 // EOF
Index: test_mail.php
===================================================================
--- test_mail.php	(revision 5371)
+++ test_mail.php	(working copy)
@@ -50,7 +50,7 @@
   foreach (dbFetch($query) as $device)
   {
     echo("Sending test notification for " . $device['hostname'] . "...");
-    alert_notify($device, "TEST: [".$device['hostname']."]",  $message);
+    alert_notify($device, "TEST: [".$device['hostname']."]",  $message, FALSE);
     echo(" done." . PHP_EOL);
   }
 } else {