Index: ad.module
===================================================================
--- ad.module	(revision 336)
+++ ad.module	(working copy)
@@ -9,6 +9,7 @@
  *   Jeremy Andrews <jeremy@tag1consulting.com>.
  */
 
+require_once("token_ad.inc");
 
 /**
  * Implementation of hook_theme().
@@ -1345,38 +1346,38 @@
       switch ($arg1) {
         case 'expired':
           return array(
-            'subject' => t('[%sitename ad] %event notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" that was being displayed on the %sitename website has expired.\n\n  Your advertisement was viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] %event notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" that was being displayed on the %site-name website has expired.\n\n  Your advertisement was viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
         case '-expired':
           return array(
-            'subject' => t('[%sitename ad] expiration notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" that is being displayed on the %sitename website will expire on %autoexpire_large.\n\n  Your advertisement has been viewed %today_views times and clicked %today_clicks times today.  It was viewed %yesterday_views times and clicked %yesterday_clicks times yesterday.  It has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] expiration notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" that is being displayed on the %site-name website will expire on %autoexpire_large.\n\n  Your advertisement has been viewed %today_views times and clicked %today_clicks times today.  It was viewed %yesterday_views times and clicked %yesterday_clicks times yesterday.  It has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
         case 'active':
           return array(
-            'subject' => t('[%sitename ad] %event notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" is now actively being displayed on the %sitename website.\n\n  Your advertisement has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] %event notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" is now actively being displayed on the %site-name website.\n\n  Your advertisement has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
         case '-active':
           return array(
-            'subject' => t('[%sitename ad] activation notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" will be actively displayed on the %sitename website on %autoactivate_large.\n\n  You can view statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] activation notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" will be actively displayed on the %site-name website on %autoactivate_large.\n\n  You can view statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
         case 'click':
           return array(
-            'subject' => t('[%sitename ad] %event notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" on the %sitename website has been clicked.\n\n  Your advertisement has been viewed %today_views times and clicked %today_clicks times today.  It was viewed %yesterday_views times and clicked %yesterday_clicks times yesterday.  It has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You will receive this %frequency  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] %event notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been clicked.\n\n  Your advertisement has been viewed %today_views times and clicked %today_clicks times today.  It was viewed %yesterday_views times and clicked %yesterday_clicks times yesterday.  It has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You will receive this %frequency  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
         case 'approved':
           return array(
-            'subject' => t('[%sitename ad] %event notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" on the %sitename website has been approved.\n\n  You can view statistics about this advertisement at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] %event notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been approved.\n\n  You can view statistics about this advertisement at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
         case 'denied':
           return array(
-            'subject' => t('[%sitename ad] %event notification'),
-            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" on the %sitename website has been denied and will not be displayed.\n\n  You can view statistics about this advertisement at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
+            'subject' => t('[%site-name ad] %event notification'),
+            'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been denied and will not be displayed.\n\n  You can view statistics about this advertisement at the following url:\n    %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"),
           );
       }
       break;
Index: notify/ad_notify.info
===================================================================
--- notify/ad_notify.info	(revision 325)
+++ notify/ad_notify.info	(working copy)
@@ -2,5 +2,6 @@
 name = Notify
 package = Ad
 dependencies[] = ad_owners
+dependencies[] = token
 description = Receive email notifications regarding ads.
 core = 6.x
Index: notify/ad_notify.install
===================================================================
--- notify/ad_notify.install	(revision 325)
+++ notify/ad_notify.install	(working copy)
@@ -97,6 +97,12 @@
         'type' => 'text',
         'not null' => FALSE,
       ),
+      'roles' => array(
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+        'default' => '',
+      ),
     ),
     'primary key' => array('notid'),
     'unique keys' => array(
@@ -122,7 +128,16 @@
   drupal_install_schema('ad_notify');
 }
 
+function ad_notify_update_6001() {
+  $return = array();
+  db_add_field($return, 'ad_notify', 'roles', array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => ''));
 
+  $return[] = update_sql('UPDATE {ad_notify} SET subject = REPLACE(subject, "%sitename", "%site-name")');
+  $return[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%siteurl", "%site-url")');
+
+  return $return;
+}
+
 /**
  * Allow complete uninstallation of the ad_notify module.
  */
Index: notify/ad_notify.module
===================================================================
--- notify/ad_notify.module	(revision 336)
+++ notify/ad_notify.module	(working copy)
@@ -78,15 +78,7 @@
   return $items;
 }
 
-
 /**
- * Menu item title callback - list of global notifications
- */
-function ad_admin_notification_list() {
-  return '123';
-}
-
-/**
  * Menu item title callback - use the user name
  */
 function owner_notifications_title($account) {
@@ -95,20 +87,20 @@
 
 /**
  * Implementation of hook_cron().
- * For performance reasons, all notifications are actually sent via this cron 
- * hook.
+ * Send time based notifications and those, who has negative delay.
  */
 function ad_notify_cron() {
   // Walk through all configured notifications and determine if any need to be
   // emailed. 
-  $result = db_query('SELECT n.notid, o.aid, n.oid, n.event, n.queued, n.delay, n.sent, n.expire, n.address, n.subject, n.body FROM {ad_notify} n INNER JOIN {ad_owners} o ON n.oid = o.oid WHERE n.status = %d', AD_NOTIFY_ENABLED);
+  $result = db_query('SELECT n.notid, o.aid, n.oid, n.event, n.queued, n.delay, n.sent, n.expire, n.address, n.subject, n.body, n.roles FROM {ad_notify} n INNER JOIN {ad_owners} o ON n.oid = o.oid WHERE n.status = %d', AD_NOTIFY_ENABLED);
   while ($notification = db_fetch_object($result)) {
     $send = FALSE;
     // Handle special case 'regular' notification that is simply a time-based
     // status email.
     if ($notification->event == 'regular') {
       if ((time() - $notification->delay) >= $notification->sent) {
-        ad_notify_send_mail($notification, 1);
+        $send = TRUE;
+        $count = 1;
       }
     }
     // Handle event based notifications based on information stored in the 
@@ -118,138 +110,83 @@
         // Event was prefixed by a -, so time is negative.  We can't pull a
         // future event out of the statistics table, so we let the module that
         // defined this event tell us whether or not it's happened.
-        if ($notification->aid == 0) {
-          $result = db_query('SELECT nid FROM {node} WHERE type = "ad"');
-          while ($nid = db_result($result)) {
-            $event_count = module_invoke_all('adnotifyapi', $notification->event, $nid);
-            if (isset($event_count[$notification->event])) {
-              foreach (ad_get_owners($nid) as $oid => $owner) {
-                ad_notify_send_mail($notification, $event_count[$notification->event], $nid, $oid);
-              }
-            }
-          }
+        $event_count = module_invoke_all('adnotifyapi', $notification->event, $notification);
+        if (isset($event_count[$notification->event])) {
+          $send = TRUE;
         }
-        else {
-          $event_count = module_invoke_all('adnotifyapi', $notification->event, $notification->aid);
-          if (isset($event_count[$notification->event])) {
-            ad_notify_send_mail($notification, $event_count[$notification->event]);
-          }
-        }
       }
 
       else {
-        if ($notification->aid == 0) {
-          $count = db_result(db_query("SELECT COUNT(aid), aid AS count FROM {ad_statistics} WHERE date > %d AND action = '%s' GROUP BY aid", date('YmdH', $notification->sent), $notification->event));
-        }
-        else {
-          $count = db_result(db_query("SELECT COUNT(aid) AS count FROM {ad_statistics} WHERE aid = %d AND date > %d AND action = '%s'", $notification->aid, date('YmdH', $notification->sent), $notification->event));
-          if ($count) {
-            // See if the notification has been queued long enough to be sent.
-            if (!$notification->delay || ($notification->queued &&
-                (time() > ($notification->queued + $notification->delay)))) {
-              ad_notify_send_mail($notification, $count);
-            }
-            else if (!$notification->queued) {
-              // Queue up the notification to send it at a later time.
-              db_query('UPDATE {ad_notify} SET queued = %d WHERE notid = %d', time(), $notification->notid);
-            }
+        $count = db_result(db_query("SELECT COUNT(aid) AS count FROM {ad_statistics} WHERE aid = %d AND date > %d AND action = '%s'", $notification->aid, date('YmdH', $notification->sent), $notification->event));
+        if ($count) {
+          // See if the notification has been queued long enough to be sent.
+          if (!$notification->delay || ($notification->queued &&
+              (time() > ($notification->queued + $notification->delay)))) {
+            $send = TRUE;
           }
+          else if (!$notification->queued) {
+            // Queue up the notification to send it at a later time.
+            db_query('UPDATE {ad_notify} SET queued = %d WHERE notid = %d', time(), $notification->notid);
+          }
         }
       }
     }
+
+    if ($send) {
+      ad_notify_send_mail($notification, $count);
+      if ($notification->expire) {
+        // Update the sent timestamp and counter, and auto-expire the 
+        // notification so it is not sent again.
+        db_query('UPDATE {ad_notify} SET queued = 0, sent = %d, counter = counter + 1, status = %d WHERE notid = %d', time(), AD_NOTIFY_DISABLED, $notification->notid);
+      }
+      else {
+        // Simply update the sent timestamp and counter.
+        db_query('UPDATE {ad_notify} SET queued = 0, sent = %d, counter = counter + 1 WHERE notid = %d', time(), $notification->notid);
+      }
+    }
   }
 }
 
 /**
  * Send email notifications using PHP mail() function.
  */
-function ad_notify_send_mail($notification, $count = 0, $nid = NULL, $oid = NULL) {
-  if (!$oid) {
-    $oid = $notification->oid;
+function ad_notify_send_mail($notification, $count = 0) {
+  $owner = user_load($notification->uid);
+
+  $send = TRUE;
+  // Send notification only for user who has a permission
+  if ($notification->roles) {
+    $send = FALSE;
+    $notification->roles = unserialize($notification->roles);
+    foreach ($notification->roles as $rid) {
+      if (isset($owner->roles[$rid])) {
+        $send = TRUE;
+        break;
+      }
+    }
   }
-  if (!$nid) {
-    $nid = $notification->aid;
-  }
-  
-  $uid = db_result(db_query('SELECT uid FROM {ad_owners} WHERE oid = %d', $oid));
-  $node = node_load($nid);
-  $owner = user_load($uid);
-  $statistics = ad_statistics($nid);
-  $notifications = module_invoke_all('adnotifyapi', 'register');
-  $variables = array(
-    '%owner_name' => $owner->name,
-    '%owner_mail' => $owner->mail,
-    '%owner_uid' => $owner->uid,
-    '%sitename' => variable_get('site_name', 'drupal'),
-    '%status' => $node->adstatus,
-    '%type' => $node->adtype,
-    '%event' => $notification->event,
-    '%frequency' => t(strtolower($notifications[$notification->event]), array('@when' => format_interval($notification->delay))),
-    '%redirect' => url($node->redirect, array('absolute' => TRUE)),
-    '%aid' => $nid,
-    '%title' => $node->title,
-    '%url' => url("node/$node->nid", array('absolute' => TRUE)),
-    '%siteurl' => url('', array('absolute' => TRUE)),
-    '%comments' => $node->comment_count,
-    '%count' => $count,
-    '%created_small' => format_date($node->created, 'small'),
-    '%created_medium' => format_date($node->created, 'medium'),
-    '%created_large' => format_date($node->created, 'large'),
-    '%activated_small' => $node->activated ? format_date($node->activated, 'small') : t('never'),
-    '%activated_medium' => $node->activated ? format_date($node->activated, 'medium') : t('never'),
-    '%activated_large' => $node->activated ? format_date($node->activated, 'large') : t('never'),
-    '%expired_small' => $node->expired ? format_date($node->expired, 'small') : t('never'),
-    '%expired_medium' => $node->expired ? format_date($node->expired, 'medium') : t('never'),
-    '%expired_large' => $node->expired ? format_date($node->expired, 'large') : t('never'),
-    '%autoactivate_small' => $node->autoactivate ? format_date($node->autoactivate, 'small') : t('never'),
-    '%autoactivate_medium' => $node->autoactivate ? format_date($node->autoactivate, 'medium') : t('never'),
-    '%autoactivate_large' => $node->autoactivate ? format_date($node->autoactivate, 'large') : t('never'),
-    '%autoexpire_small' => $node->autoexpire ? format_date($node->autoexpire, 'small') : t('never'),
-    '%autoexpire_medium' => $node->autoexpire ? format_date($node->autoexpire, 'medium') : t('never'),
-    '%autoexpire_large' => $node->autoexpire ? format_date($node->autoexpire, 'large') : t('never'),
-    '%maxviews' => $node->maxviews,
-    '%maxclicks' => $node->maxclicks,
-    '%log_message' => $node->log,
-    '%global_views' => $statistics['global']['views'],
-    '%global_clicks' => $statistics['global']['clicks'],
-    '%last_year_views' => $statistics['last_year']['views'],
-    '%last_year_clicks' => $statistics['last_year']['clicks'],
-    '%this_year_views' => $statistics['this_year']['views'],
-    '%this_year_clicks' => $statistics['this_year']['clicks'],
-    '%last_month_views' => $statistics['last_month']['views'],
-    '%last_month_clicks' => $statistics['last_month']['clicks'],
-    '%this_month_views' => $statistics['this_month']['views'],
-    '%this_month_clicks' => $statistics['this_month']['clicks'],
-    '%this_week_views' => $statistics['this_week']['views'],
-    '%this_week_clicks' => $statistics['this_week']['clicks'],
-    '%yesterday_views' => $statistics['yesterday']['views'],
-    '%yesterday_clicks' => $statistics['yesterday']['clicks'],
-    '%today_views' => $statistics['today']['views'],
-    '%today_clicks' => $statistics['today']['clicks'],
-    '%last_hour_views' => $statistics['last_hour']['views'],
-    '%last_hour_clicks' => $statistics['last_hour']['clicks'],
-    '%this_hour_views' => $statistics['this_hour']['views'],
-    '%this_hour_clicks' => $statistics['this_hour']['clicks'],
-  );
-  // TODO: Add hook to allow other modules to define variables.
 
-  // TODO: Should the from_address be configurable?
-  drupal_mail(
-    'ad_notify_mail',                                   // mail key
-    $notification->address,                             // to address
-    strtr($notification->subject, $variables),          // subject
-    wordwrap(strtr($notification->body, $variables), 72),      // message
-    variable_get('site_mail', ini_get('sendmail_from')) // from address
-  );
-  if ($notification->expire) {
-    // Update the sent timestamp and counter, and auto-expire the 
-    // notification so it is not sent again.
-    db_query('UPDATE {ad_notify} SET queued = 0, sent = %d, counter = counter + 1, status = %d WHERE notid = %d', time(), AD_NOTIFY_DISABLED, $notification->notid);
+  if ($send) {
+    $node = node_load($notification->aid);
+    $node->notification = $notification;
+
+    $replacements = array(
+      'global' => NULL,
+      'ad' => $node,
+      'ad_owner' => $owner,
+    );
+    $notification->body = token_replace_multiple($notification->body, $replacements, '%', '');
+    $notification->subject = token_replace_multiple($notification->subject, $replacements, '%', '');
+
+    // TODO: Should the from_address be configurable?
+    drupal_mail(
+      'ad_notify_mail',                                                   // mail key
+      $notification->address ? $notification->address : $owner->mail,     // to address
+      $notification->subject,                                             // subject
+      wordwrap($notification->body, 72),                                  // message
+      variable_get('site_mail', ini_get('sendmail_from'))                 // from address
+    );
   }
-  else {
-    // Simply update the sent timestamp and counter.
-    db_query('UPDATE {ad_notify} SET queued = 0, sent = %d, counter = counter + 1 WHERE notid = %d', time(), $notification->notid);
-  }
 }
 
 /**
@@ -281,16 +218,46 @@
 }
 
 /**
+ * Implementation of hook_adowners().
+ */
+function ad_notify_adowners($op, $arg1 = NULL, $arg2 = NULL) {
+  switch ($op) {
+    case 'overview':
+      return l(t('notifications'), 'node/'. $arg1 .'/adowners/'. $arg2 .'/notifications');
+
+    case 'add':
+      if ($arg2['aid'] && $arg2['oid']) {
+        $owner = user_load($arg2['uid']);
+
+        $result = db_query('SELECT * FROM {ad_notify} WHERE aid = 0 AND oid = 0');
+        while ($template = db_fetch_object($result)) {
+          db_query("INSERT INTO {ad_notify} (aid, oid, event, delay, expire, locked, status, address, subject, body) VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s')", $arg2['aid'], $arg2['oid'], $template->event, $template->delay, $template->expire, $template->locked, AD_NOTIFY_ENABLED, $owner->mail, $template->subject, $template->body);
+        }
+      }
+      break;
+
+    case 'remove':
+      if ($arg1) {
+        $result = db_query('DELETE FROM {ad_notify} WHERE oid = %d', $arg1);
+      }
+      break;
+  }
+}
+
+/**
  * Notification overview form.
  */
 function ad_notify_overview_form($form_state, $nid = 0, $uid = NULL, $notid = 0) {
   global $user;
   if (is_null($uid)) {
     $uid = $user->uid;
+    $owner = $user;
   }
+  if ($uid && !$owner) {
+    $owner = user_load($uid);
+  }
 
   $oid = (int)db_result(db_query('SELECT oid FROM {ad_owners} WHERE aid = %d AND uid = %d', $nid, $uid));
-
   $notifications = module_invoke_all('adnotifyapi', 'register');
 
   $header = array(
@@ -300,26 +267,41 @@
     array('data' => t('Action'))
   );
 
-  $sql = "SELECT notid, event, delay, sent, address, status FROM {ad_notify} WHERE oid in (%d, 0)";
+  $sql = "SELECT notid, event, delay, sent, address, status, roles FROM {ad_notify} WHERE oid = %d";
   $sql .= tablesort_sql($header, 'oid DESC, ');
   $result = pager_query($sql, 25, 0, NULL, $oid);
 
   $rows = array();
   while ($notify = db_fetch_object($result)) {
-    $row = array();
-    $row[] = $notify->sent ? t('!time ago', array('!time' => format_interval(time() - $notify->sent))) : t('Never');
-    $row[] = t($notifications[$notify->event], array('@when' => format_interval($notify->delay)));
-    $row[] = $notify->status == AD_NOTIFY_ENABLED ? t('enabled') : t('disabled');
-    if ($oid) {
-      $row[] = l(t('edit'), 'node/'. $nid .'/adowners/'. $uid .'/notifications/' .$notify->notid. '/edit') .' '. l(t('delete'), 'node/'. $nid .'/adowners/'. $uid .'/notifications/'. $notify->notid .'/delete');
+    $list_notification = TRUE;
+    // Check if user has permission to see the notification.
+    if ($uid && $notify->roles) {
+      $list_notification = FALSE;
+      $notify->roles = unserialize($notify->roles);
+      foreach ($notify->roles as $rid) {
+        if (isset($owner->roles[$rid])) {
+          $list_notification = TRUE;
+          break;
+        }
+      }
     }
-    else if (user_access('administer advertisements')) {
-      $row[] = l(t('edit'), 'admin/content/ad/notifications/' .$notify->notid. '/edit') .' '. l(t('delete'), 'admin/content/ad/notifications/'. $notify->notid .'/delete');
+
+    if (!$uid || $list_notification) {
+      $row = array();
+      $row[] = $notify->sent ? t('!time ago', array('!time' => format_interval(time() - $notify->sent))) : t('Never');
+      $row[] = t($notifications[$notify->event], array('@when' => format_interval($notify->delay)));
+      $row[] = $notify->status == AD_NOTIFY_ENABLED ? t('enabled') : t('disabled');
+      if ($oid) {
+        $row[] = l(t('edit'), 'node/'. $nid .'/adowners/'. $uid .'/notifications/' .$notify->notid. '/edit') .' '. l(t('delete'), 'node/'. $nid .'/adowners/'. $uid .'/notifications/'. $notify->notid .'/delete');
+      }
+      else if (user_access('administer advertisements')) {
+        $row[] = l(t('edit'), 'admin/content/ad/notifications/' .$notify->notid. '/edit') .' '. l(t('delete'), 'admin/content/ad/notifications/'. $notify->notid .'/delete');
+      }
+      else {
+        $row[] = 'N/A';
+      }
+      $rows[] = $row;
     }
-    else {
-      $row[] = 'N/A';
-    }
-    $rows[] = $row;
   }
   $output = theme('table', $header, $rows);
   $output .= theme('pager', NULL, 25, 0);
@@ -389,8 +371,6 @@
   }
 
   if ($uid) {
-    $owner = user_load($uid);
-
     // TODO: Make it possible for admins to modify email address, and even to
     // enter multiple email addresses.  Wrap this in a special permission, as 
     // it involves trust to configure notifications to unverified addresses.
@@ -406,6 +386,15 @@
       '#value' => $owner->mail,
     );
   }
+  else {
+    $roles = user_roles(TRUE);
+    $form['create']['roles'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Notify roles'),
+      '#description' => t('Only listed roles will get this notification. Live blank to send always.'),
+      '#options' => $roles,
+    );
+  }
 
   if ($notid) {
     $form['create']['mail']['subject'] = array(
@@ -420,32 +409,17 @@
       '#title' => t('Body'),
       '#required' => TRUE,
       '#default_value' => $notification->body,
-      '#description' => t('Enter the body of your notification email.  The following variables can be used in your message and will be automatically replaced before the email is sent:') .'<ul>'
-          .'<li>'. t('%sitename: the name of this website.') 
-          .'<li>'. t('%owner_name: the username of the ad owner.') 
-          .'<li>'. t('%owner_mail: the email address of the ad owner.') 
-          .'<li>'. t('%owner_uid: the user ID of the ad owner.') 
-          .'<li>'. t('%event: the type of event that has triggered this notification.')
-          .'<li>'. t('%count: the number of times the event happened.') 
-          .'<li>'. t('%frequency: a complete sentence describing the frequency this notification will be sent.') 
-          .'<li>'. t('%type: the type of ad.') 
-          .'<li>'. t('%status: the status of the ad.') 
-          .'<li>'. t('%url: the url of the advertisement.') 
-          .'<li>'. t('%siteurl: the url of the website.') 
-          .'<li>'. t('%redirect: the redirection url of the advertisement.') 
-          .'<li>'. t('%title: the title of the advertisement.') 
-          .'<li>'. t('%aid: the ID of the advertisement.') 
-          .'<li>'. t('%comments: the number of comments attached to the advertisement.') 
-          .'<li>'. t('%created_small, %created_medium, %created_large: various formats of when the advertisement was created.') 
-          .'<li>'. t('%activated_small, %activated_medium, %activated_large: various formats of when the advertisement was activated.') 
-          .'<li>'. t('%expired_small, %expired_medium, %expired_large: various formats of when the advertisement was expired.') 
-          .'<li>'. t('%autoactivate_small, %autoactivate_medium, %autoactivate_large: various formats of when the advertisement was automatically activated.') 
-          .'<li>'. t('%autoexpire_small, %autoexpire_medium, %autoexpire_large: various formats of when the advertisement was automatically expired.') 
-          .'<li>'. t('%maxviews: the maximum number of times this advertisement is allowed to be viewed.') 
-          .'<li>'. t('%maxclicks: the maximum number of times this advertisement is allowed to be clicked.') 
-          .'<li>'. t('%global_views, %global_clicks, %last_year_views, %last_year_clicks, %this_year_views, %this_year_clicks, %last_month_views, %last_month_clicks, %this_month_views, %this_month_clicks, %this_week_views, %this_week_clicks, %yesterday_views, %yesterday_clicks, %today_views, %today_clicks, %last_hour_views, %last_hour_clicks, %this_hour_views, %this_hour_clicks: various advertisement statistics')
-          .'</ul>',
     );
+    $form['create']['mail']['tokens'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Replacement patterns'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+    $form['create']['mail']['tokens']['list'] = array(
+      '#value' => theme('token_help', 'ad', '%', ''),
+    );
+    $form['create']['roles']['#default_value'] = $notification->roles;
   }
 
   $form['create']['oid'] = array(
@@ -532,7 +506,7 @@
  */
 function ad_notify_overview_form_submit($form, &$form_state) {
   if (isset($form_state['values']['notid'])) {
-    db_query("UPDATE {ad_notify} SET aid = %d, oid = %d, event = '%s', delay = %d, expire = %d, locked = %d, status = %d, address = '%s', subject = '%s', body = '%s' WHERE notid = %d", $form_state['values']['aid'], $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, $form_state['values']['address'], $form_state['values']['subject'], $form_state['values']['body'], $form_state['values']['notid']);
+    db_query("UPDATE {ad_notify} SET aid = %d, oid = %d, event = '%s', delay = %d, expire = %d, locked = %d, status = %d, address = '%s', subject = '%s', body = '%s', roles = '%s' WHERE notid = %d", $form_state['values']['aid'], $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, $form_state['values']['address'], $form_state['values']['subject'], $form_state['values']['body'], serialize($form_state['values']['roles']), $form_state['values']['notid']);
     drupal_set_message('Notification updated.');
   }
   else {
@@ -545,7 +519,7 @@
         'body' => t("Hello %owner_name,\n\n  This is an automatically generated notification about your advertisement \"%title\" that is being displayed on the %sitename website.\n\n  Your advertisement has been viewed %today_views times and clicked %today_clicks times today.  It was viewed %yesterday_views times and clicked %yesterday_clicks times yesterday.  It has been viewed %global_views times and clicked %global_clicks times since it was activated on %activated_large.\n\n  You will receive this %frequency  You can view additional statistics about this advertisement or update this notification at the following url:\n    %url\n\nRegards,\n The %sitename Team\n\n-\n%siteurl"),
       );
     }
-    db_query("INSERT INTO {ad_notify} (aid, oid, event, delay, expire, locked, status, address, subject, body) VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s')", $form_state['values']['aid'], $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, $form_state['values']['address'], $mail['subject'], $mail['body']);
+    db_query("INSERT INTO {ad_notify} (aid, oid, event, delay, expire, locked, status, address, subject, body, roles) VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s')", $form_state['values']['aid'], $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, $form_state['values']['address'], $mail['subject'], $mail['body'], serialize($form_state['values']['roles']));
     drupal_set_message('Notification created.');
   }
 
@@ -564,7 +538,9 @@
  * Load a specified notification from the database, return as an object.
  */
 function ad_notification_load($notid) {
-  return db_fetch_object(db_query('SELECT * FROM {ad_notify} WHERE notid = %d', $notid));
+  $notification = db_fetch_object(db_query('SELECT * FROM {ad_notify} WHERE notid = %d', $notid));
+  $notification->roles = unserialize($notification->roles);
+  return $notification;
 }
 
 /**
@@ -657,20 +633,4 @@
   else {
     $form_state['redirect'] = 'admin/content/ad/notifications';
   }
-}
-
-/**
- * Implementation of hook_adowners().
- */
-function ad_notify_adowners($op, $arg1 = NULL, $arg2 = NULL) {
-  switch ($op) {
-    case 'overview':
-      return l(t('notifications'), 'node/'. $arg1 .'/adowners/'. $arg2 .'/notifications');
-
-    case 'delete':
-      if ($arg1) {
-        db_query('DELETE FROM {ad_notify} WHERE oid = %d', $arg1);
-      }
-      break;
-  }
-}
+}
\ No newline at end of file
Index: token_ad.inc
===================================================================
--- token_ad.inc	(revision 0)
+++ token_ad.inc	(revision 0)
@@ -0,0 +1,151 @@
+<?php
+// $Id: token_user.inc,v 1.3.4.2 2008/06/28 15:10:22 greggles Exp $
+
+/**
+ * @file
+ * Implementations of token module hooks for the Advertisement module.
+ *
+ * @ingroup token
+ */
+
+/**
+ * Implementation of hook_token_values().
+ */
+function ad_token_values($type, $object = NULL, $options = array()) {
+  $values = array();
+  switch ($type) {
+    case 'ad':
+      if (isset($object)) {
+        $node = $object;
+        $notifications = module_invoke_all('adnotifyapi', 'register');
+        module_load_include('pages.inc', 'ad');
+
+        $values['aid']           = $node->nid;
+        $values['title']         = $node->title;
+        $values['description']   = $node->body;
+        $values['log_message']   = $node->log;
+        $values['type']          = $node->adtype;
+        $values['status']        = $node->adstatus;
+        $values['url']           = url('node/'. $node->nid, array('absolute' => TRUE));
+        $values['redirect']      = url($node->redirect, array('absolute' => TRUE));
+        $values['comments']      = $node->comment_count;
+
+        if (isset($node->notification)) {
+          $values['event']       = $node->notification->event;
+          $values['frequency']   = t(strtolower($notifications[$node->notification->event]), array('@when' => format_interval($node->notification->delay)));
+        }
+
+        $values['created_small'] = format_date($node->created, 'small');
+        $values['created_medium'] = format_date($node->created, 'medium');
+        $values['created_large'] = format_date($node->created, 'large');
+        $values['activated_small'] = $node->activated ? format_date($node->activated, 'small') : t('never');
+        $values['activated_medium'] = $node->activated ? format_date($node->activated, 'medium') : t('never');
+        $values['activated_large'] = $node->activated ? format_date($node->activated, 'large') : t('never');
+        $values['expired_small'] = $node->expired ? format_date($node->expired, 'small') : t('never');
+        $values['expired_medium'] = $node->expired ? format_date($node->expired, 'medium') : t('never');
+        $values['expired_large'] = $node->expired ? format_date($node->expired, 'large') : t('never');
+        $values['autoactivate_small'] = $node->autoactivate ? format_date($node->autoactivate, 'small') : t('never');
+        $values['autoactivate_medium'] = $node->autoactivate ? format_date($node->autoactivate, 'medium') : t('never');
+        $values['autoactivate_large'] = $node->autoactivate ? format_date($node->autoactivate, 'large') : t('never');
+        $values['autoexpire_small'] = $node->autoexpire ? format_date($node->autoexpire, 'small') : t('never');
+        $values['autoexpire_medium'] = $node->autoexpire ? format_date($node->autoexpire, 'medium') : t('never');
+        $values['autoexpire_large'] = $node->autoexpire ? format_date($node->autoexpire, 'large') : t('never');
+
+        $statistics = ad_statistics($node->nid);
+        $values['maxviews'] = $node->maxviews;
+        $values['maxclicks'] = $node->maxclicks;
+        $values['global_views'] = $statistics['global']['views'];
+        $values['global_clicks'] = $statistics['global']['clicks'];
+        $values['last_year_views'] = $statistics['last_year']['views'];
+        $values['last_year_clicks'] = $statistics['last_year']['clicks'];
+        $values['this_year_views'] = $statistics['this_year']['views'];
+        $values['this_year_clicks'] = $statistics['this_year']['clicks'];
+        $values['last_month_views'] = $statistics['last_month']['views'];
+        $values['last_month_clicks'] = $statistics['last_month']['clicks'];
+        $values['this_month_views'] = $statistics['this_month']['views'];
+        $values['this_month_clicks'] = $statistics['this_month']['clicks'];
+        $values['this_week_views'] = $statistics['this_week']['views'];
+        $values['this_week_clicks'] = $statistics['this_week']['clicks'];
+        $values['yesterday_views'] = $statistics['yesterday']['views'];
+        $values['yesterday_clicks'] = $statistics['yesterday']['clicks'];
+        $values['today_views'] = $statistics['today']['views'];
+        $values['today_clicks'] = $statistics['today']['clicks'];
+        $values['last_hour_views'] = $statistics['last_hour']['views'];
+        $values['last_hour_clicks'] = $statistics['last_hour']['clicks'];
+        $values['this_hour_views'] = $statistics['this_hour']['views'];
+        $values['this_hour_clicks'] = $statistics['this_hour']['clicks'];
+      }
+      break;
+    case 'ad_owner':
+      if (isset($object)) {
+        $owner = $object;
+        $values['owner_name']    = $owner->name;
+        $values['owner_mail']    = $owner->mail;
+        $values['owner_uid']     = $owner->uid;
+      }
+      break;
+  }
+  return $values;
+}
+
+/**
+ * Implementation of hook_token_list().
+ */
+function ad_token_list($type = 'all') {
+  if ($type == 'ad' || $type == 'all') {
+    $tokens['ad']['aid']           = t('The ID of the advertisement.');
+    $tokens['ad']['type']          = t('The type of ad.');
+    $tokens['ad']['status']        = t('The status of the ad.');
+    $tokens['ad']['url']           = t('The url of the advertisement.');
+    $tokens['ad']['redirect']      = t('The redirection url of the advertisement.');
+    $tokens['ad']['event']         = t('The type of event that has triggered this notification.');
+    $tokens['ad']['frequency']     = t('A complete sentence describing the frequency this notification will be sent.');
+    $tokens['ad']['title']         = t('The title of the advertisement.');
+    $tokens['ad']['comments']      = t('The number of comments attached to the advertisement.');
+
+    $tokens['ad']['created_small']        = t('"Small" date format of when the advertisement was created.');
+    $tokens['ad']['created_medium']       = t('"Medium" date format of when the advertisement was created.');
+    $tokens['ad']['created_large']        = t('"Large" date format of when the advertisement was created.');
+    $tokens['ad']['activated_small']      = t('"Small" date format when the advertisement was activated.');
+    $tokens['ad']['activated_medium']     = t('"Medium" date format of when the advertisement was activated.');
+    $tokens['ad']['activated_large']      = t('"Large" date format of when the advertisement was activated.');
+    $tokens['ad']['expired_small']        = t('"Small" date format of when the advertisement was expired.');
+    $tokens['ad']['expired_medium']       = t('"Medium" date format of when the advertisement was expired.');
+    $tokens['ad']['expired_large']        = t('"Large" date format of when the advertisement was expired.');
+    $tokens['ad']['autoactivate_small']   = t('"Small" date format of when the advertisement was automatically activated.');
+    $tokens['ad']['autoactivate_medium']  = t('"Medium" date format of when the advertisement was automatically activated.');
+    $tokens['ad']['autoactivate_large']   = t('"Large" date format of when the advertisement was automatically activated.');
+    $tokens['ad']['autoexpire_small']     = t('"Small" date format of when the advertisement was automatically expired.');
+    $tokens['ad']['autoexpire_medium']    = t('"Medium" date format of when the advertisement was automatically expired.');
+    $tokens['ad']['autoexpire_large']     = t('"Large" date format of when the advertisement was automatically expired.');
+
+    $tokens['ad']['maxviews']          = t('The maximum number of times this advertisement is allowed to be viewed.');
+    $tokens['ad']['maxclicks']         = t('The maximum number of times this advertisement is allowed to be clicked.');
+    $tokens['ad']['global_views']      = t('Various advertisement statistics');
+    $tokens['ad']['global_clicks']     = t('Various advertisement statistics');
+    $tokens['ad']['last_year_views']   = t('Various advertisement statistics');
+    $tokens['ad']['last_year_clicks']  = t('Various advertisement statistics');
+    $tokens['ad']['this_year_views']   = t('Various advertisement statistics');
+    $tokens['ad']['this_year_clicks']  = t('Various advertisement statistics');
+    $tokens['ad']['last_month_views']  = t('Various advertisement statistics');
+    $tokens['ad']['last_month_clicks'] = t('Various advertisement statistics');
+    $tokens['ad']['this_month_views']  = t('Various advertisement statistics');
+    $tokens['ad']['this_month_clicks'] = t('Various advertisement statistics');
+    $tokens['ad']['this_week_views']   = t('Various advertisement statistics');
+    $tokens['ad']['this_week_clicks']  = t('Various advertisement statistics');
+    $tokens['ad']['yesterday_views']   = t('Various advertisement statistics');
+    $tokens['ad']['yesterday_clicks']  = t('Various advertisement statistics');
+    $tokens['ad']['today_views']       = t('Various advertisement statistics');
+    $tokens['ad']['today_clicks']      = t('Various advertisement statistics');
+    $tokens['ad']['last_hour_views']   = t('Various advertisement statistics');
+    $tokens['ad']['last_hour_clicks']  = t('Various advertisement statistics');
+    $tokens['ad']['this_hour_views']   = t('Various advertisement statistics');
+    $tokens['ad']['this_hour_clicks']  = t('Various advertisement statistics');
+  }
+  if ($type == 'ad' || $type == 'all') {
+    $tokens['Ad owner']['owner_name']  = t('The username of the ad owner.');
+    $tokens['Ad owner']['owner_mail']  = t('The email address of the ad owner.');
+    $tokens['Ad owner']['owner_uid']   = t('The user ID of the ad owner.');
+  }
+  return $tokens;
+}
\ No newline at end of file
