--- subscriptions.module.old	Fri May 13 18:09:39 2005
+++ subscriptions.module	Fri May 13 18:12:44 2005
@@ -17,9 +17,20 @@
 
         <p>Note that because this module causes the comment insert to pause while all
         subscribers are notified, it may not be practical for large sites.</p>');
+    
     case 'admin/modules#description':
       // appears on the admin module selection page
       return t('Allows users to subscribe to nodes and taxonomy terms.');
+    
+    case strstr($section, 'admin/subscriptions/exceptions'):
+      return t('<p>You can select status for each user to override the default category selection.<br />For exemple, selecting "refuse" would make user not receive any subscription for this category, even if he belongs to a role which is subscribed to this category.</p>');
+    
+    case 'admin/subscriptions':
+      return t('<p>For categories you can manage exceptions to add or quit a user from subscriptions added through roles.</p>');  
+    
+    case 'admin/subscriptions/role':
+      return t('<p>Here you can control categories subscriptions for roles.</p>');  
+    
   }
 }
 
@@ -28,8 +39,10 @@
  */
 function subscriptions_perm() {
   return array('maintain subscriptions');
+  return array('administer subscriptions');
 }
 
+
 // this section will be commented out until the mailqueue module is completed
 /*
 function subscriptions_settings() {
@@ -119,7 +132,7 @@
   return $subscriptions[$account->uid];
 }
 
-/*
+/**
  * Returns a summary of all subscriptions
  */
 function subscriptions_get_summary() {
@@ -161,7 +174,7 @@
   return $subssumm;
 }
 
-/*
+/**
  * Formats the mail and sends it.
  */
 function subscriptions_sendmail($name, $to, $subject, $body, $headers) {
@@ -174,7 +187,7 @@
   }
 }
 
-/*
+/**
  * Get e-mail vars
  */
 function subscriptions_mailvars($sid, $ssid, $uid, $stype, $strsent) {
@@ -200,7 +213,9 @@
   if ($stype == 'taxa' && !is_null($sid)) {
     $result = db_query('SELECT name FROM {term_data} WHERE tid = %d', $sid);
     $subj = db_result($result);
-    $result = db_query('SELECT u.mail, u.name, u.uid, u.language FROM {users} u INNER JOIN {subscriptions} s ON u.uid = s.uid WHERE s.sid = %d AND stype = \'taxa\'', $sid);
+    //$result = db_query('SELECT u.mail, u.name, u.uid, u.language FROM {users} u INNER JOIN {subscriptions} s ON u.uid = s.uid WHERE s.sid = %d AND stype = \'taxa\'', $sid);
+    // Select all users subscribed through role subscriptions but we excluded the one who refuse to receive mail (status = -1).
+    $result = db_query('SELECT DISTINCT u.mail, u.name, u.uid, u.language FROM {subscriptions_role} sr INNER JOIN {users_roles} r ON r.rid = sr.rid AND sr.sid = %d AND sr.stype = \'taxa\' INNER JOIN {users} u  ON r.uid = u.uid LEFT OUTER JOIN {subscriptions} s ON u.uid = s.uid AND s.sid = %d AND s.stype = \'taxa\' WHERE IFNULL(s.status, 0) != -1 and u.uid != 0', $sid, $sid);
     $strtype = 'category';
     $nid = $ssid;
     $cid = NULL;
@@ -215,6 +230,31 @@
     $cid = NULL;
   } 
   // loop through subscribers and call mail function
+  $strstent .= _subscriptions_mailvars($result, $subj, $uid, $sid, $strtype, $nid, $cid, $strstent);
+
+  // Loop through subscribers who who subscribe individually (status = 1)
+  // We have to check if a mail hasn't been sent to them previously (if they belong to a subscribed role).
+  if ($stype == 'taxa' && !is_null($sid)) {
+    // We don't need to find again subject, it remain unchanged.
+    //$result = db_query('SELECT name FROM {term_data} WHERE tid = %d', $sid);
+    //$subj = db_result($result);
+    $result = db_query('SELECT DISTINCT u.mail, u.name, u.uid, u.language FROM {users} u INNER JOIN {subscriptions} s ON u.uid = s.uid WHERE s.status = 1 AND s.sid = %d AND s.stype = \'taxa\' AND u.uid != 0', $sid );
+    //$strtype = 'category';
+    //$nid = $ssid;
+    //$cid = NULL;
+    
+    // loop through subscribers and call mail function
+    $strstent .= _subscriptions_mailvars($result, $subj, $uid, $sid, $strtype, $nid, $cid, $strstent);
+  }
+
+  return $strsent;
+}
+
+/**
+ * loop through subscribers and call mail function
+ */
+
+function _subscriptions_mailvars($result, $subj, $uid, $sid, $strtype, $nid, $cid, $strstent) {
   while ($subscriptions = db_fetch_object($result)) {
     if ($subscriptions->uid != $uid && !is_null($sid) && strpos($strsent , '!'. $subscriptions->uid .'!') === false) {
       // add this user to "previously notified" string
@@ -247,9 +287,9 @@
       }
     }
   }
-  return $strsent;
 }
 
+
 /*
  * Subscribes users to nodes in which they post, if not already subscribed
  */
@@ -329,8 +369,18 @@
       'access' => user_access('maintain subscriptions'),
       'callback' => 'subscriptions_page');
     $items[] = array('path' => 'admin/subscriptions', 'title' => t('subscriptions'),
-      'access' => user_access('administer users'),
-      'callback' => 'subscriptions_page');
+      'access' => user_access('administer subscriptions'),
+      'callback' => 'subscriptions_admin');  
+    $items[] = array('path' => 'admin/subscriptions/list', 'title' => t('list'),   
+      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+    $items[] = array('path' => 'admin/subscriptions/role', 'title' => t('subscribe role'),
+      'callback' => 'subscriptions_role', 
+      'access' => user_access('administer subscriptions'),
+      'type' => MENU_LOCAL_TASK);  
+    $items[] = array('path' => 'admin/subscriptions/exceptions', 'title' => t('subscriptions exceptions'),
+      'access' => user_access('administer subscriptions'),
+      'callback' => 'subscriptions_exceptions',
+      'type' => MENU_CALLBACK); 
   }
   return $items;
 }
@@ -369,9 +419,24 @@
 }
 
 function subscriptions_get_taxa_count() {
-  $result = db_query('SELECT sid, count(*) as tcount FROM {subscriptions} WHERE stype=\'taxa\' GROUP BY sid');
-  while ($taxasub = db_fetch_object($result)) {
-    $tsubscriptions[$taxasub->sid] = $taxasub->tcount;
+
+  //Count of users subscribed through their own role.
+  $result = db_queryd('SELECT DISTINCT sr.sid, u.uid FROM subscriptions_role sr INNER JOIN users_roles r ON r.rid = sr.rid  AND sr.stype = \'taxa\' INNER JOIN users u  ON r.uid = u.uid LEFT OUTER JOIN subscriptions s ON u.uid = s.uid AND s.stype = \'taxa\' WHERE IFNULL(s.status, 0) != -1 and u.uid != 0 ORDER BY sr.sid, u.uid');
+  while ($taxa_user_count = db_fetch_object($result)) {
+    $sub_user_count[$taxa_user_count->sid] = $sub_user_count[$taxa_user_count->sid] ? $sub_user_count[$taxa_user_count->sid].$taxa_user_count->uid.'!' : '!'.$taxa_user_count->uid.'!';
+  }
+
+  //Add users subscribed individually if they don't already have a subscribed role.
+  $result = db_queryd('SELECT DISTINCT s.sid, u.uid FROM {users} u INNER JOIN {subscriptions} s ON u.uid = s.uid WHERE s.status = 1 AND s.stype = \'taxa\' AND u.uid != 0 ORDER BY s.sid, u.uid');
+  while ($taxa_user_count = db_fetch_object($result)) {
+    if (!strpos($sub_user_count[$taxa_user_count->sid] , '!'. $subscriptions->uid .'!')) {
+      $sub_user_count[$taxa_user_count->sid] = $sub_user_count[$taxa_user_count->sid] ? $sub_user_count[$taxa_user_count->sid].$taxa_user_count->uid.'!' : '!'.$taxa_user_count->uid.'!';
+    }
+  }
+  
+  //Final count.
+  foreach($sub_user_count as $key => $value) {
+     $tsubscriptions[$key] = count(explode('!', $value)) - 2; //Eliminate first and last "!"
   }
   return $tsubscriptions ? $tsubscriptions : array();
 }
@@ -443,46 +508,6 @@
       print theme('page', $message);
       break;
 
-    // Base report for admin functions
-    case 'admin':
-      // get all subscriptions for all users
-      $subscriptions = subscriptions_get_summary();
-      // build node rows
-      foreach ($subscriptions['node'] as $nsub) {
-        $subrowsn[] = array(t('thread'), l($nsub->title, 'node/'. $nsub->nid), $nsub->ncount);
-      }
-      // build blog rows
-      foreach ($subscriptions['blog'] as $bsub) {
-        $subrowsb[] = array(t('blog'), l($bsub->name, 'blog/'. $bsub->uid), $bsub->ncount);
-      }
-      // traverse the taxonomy tree
-      $taxa = subscriptions_get_taxa_count();
-      // omit undesired vocabularies from listing
-      $vocabularies = taxonomy_get_vocabularies();
-      $omits = variable_get('subscriptions_omitted_taxa', array());
-      foreach ($omits as $omit) {
-        unset($vocabularies[$omit]);
-      }
-      foreach ($vocabularies as $vocab) {
-        $tree = taxonomy_get_tree($vocab->vid);
-        foreach ($tree as $term) {
-          $subrowst[] = array(t('category'), $vocab->name .': '. l($term->name, 'taxonomy/term/'. $term->tid), is_null($taxa[$term->tid]) ? '0' : $taxa[$term->tid]);
-        }
-      }
-      // concatentate the arrays
-      $headers = array(t('type'), t('title'), t('subscribers'));
-      $subrows = array_merge($subrowsn, $subrowsb, $subrowst);
-      // assemble output
-      if (!$subrows) {
-        $message .= t('<p>No threads or categories are currently subscribed.</p>');
-      }
-      else {
-        $message .= theme('table', $headers, $subrows, array('id' => 'subscriptions'));
-      }
-      drupal_set_title(t('Subscriptions Summary'));
-      print theme('page', $message);
-      break;
-
     // determines the user's subscription status and displays the right option to change it
     default:
       // get all subscriptions and write to table rows
@@ -524,4 +549,185 @@
   }
 }
 
+
+/**
+ * Let admin view/manage users subscriptions.
+ */
+ 
+function subscriptions_admin() {
+  global $user;
+  $subscribed = false;
+  $uid = $user->uid;
+  if (!arg(2)) {
+    $sid = arg(1);
+    $nid = $sid;
+    $op = arg(0);
+  }
+  else {
+    $op = arg(1);
+    $stype = arg(2);
+    $sid = arg(3);
+    $nid = arg(4);
+    if ($stype == 'node') {
+      $nid = $sid;
+    }
+  }
+
+  // get all subscriptions for all users
+  $subscriptions = subscriptions_get_summary();
+  // build node rows
+  foreach ($subscriptions['node'] as $nsub) {
+    $subrowsn[] = array(t('thread'), l($nsub->title, 'node/'. $nsub->nid), $nsub->ncount, t('n/a'));
+  }
+  // build blog rows
+  foreach ($subscriptions['blog'] as $bsub) {
+    $subrowsb[] = array(t('blog'), l($bsub->name, 'blog/'. $bsub->uid), $bsub->ncount, t('n/a'));
+  }
+  // traverse the taxonomy tree
+  $taxa = subscriptions_get_taxa_count();
+  // omit undesired vocabularies from listing
+  $vocabularies = taxonomy_get_vocabularies();
+  $omits = variable_get('subscriptions_omitted_taxa', array());
+  foreach ($omits as $omit) {
+    unset($vocabularies[$omit]);
+  }
+  foreach ($vocabularies as $vocab) {
+    $tree = taxonomy_get_tree($vocab->vid);
+    foreach ($tree as $term) {
+      $subrowst[] = array(t('category'), $vocab->name .': '. l($term->name, 'taxonomy/term/'. $term->tid), is_null($taxa[$term->tid]) ? '0' : $taxa[$term->tid], l(t('manage'),'admin/subscriptions/exceptions/'. $term->tid));
+    }
+  }
+  // concatentate the arrays
+  $headers = array(t('type'), t('title'), t('subscribers'), t('exceptions'));
+  $subrows = array_merge($subrowsn, $subrowsb, $subrowst);
+  // assemble output
+  if (!$subrows) {
+    $message .= t('<p>No threads or categories are currently subscribed.</p>');
+  }
+  else {
+    $message .= theme('table', $headers, $subrows, array('id' => 'subscriptions'));
+  }
+  drupal_set_title(t('Subscriptions Summary'));
+  print theme('page', $message);
+}
+
+
+/**
+ * Allow to subscribe role to categories.
+ */
+
+function subscriptions_role() {
+  $edit = $_POST['edit'];
+  if ($edit) {
+    // Save role:
+    $result = db_query('SELECT * FROM {role}');
+    while ($role = db_fetch_object($result)) {
+      db_query('DELETE FROM {subscriptions_role} WHERE rid = %d', $role->rid);
+      foreach ($edit[$role->rid] as $key => $value) {
+        if (!$value) {
+          unset($edit[$role->rid][$key]);
+        }
+      }
+      if (count($edit[$role->rid])) {
+        foreach (array_keys($edit[$role->rid]) as $key) {
+          db_query("INSERT INTO {subscriptions_role} (sid, rid, stype) VALUES (%d, %d, '%s')", $key, $role->rid, 'taxa');
+        }
+      }
+    }
+
+    drupal_set_message(t('The changes have been saved.'));
+
+    drupal_goto('admin/subscriptions');
+  }
+  
+  // Compile role array:
+  $result = db_query('SELECT s.rid, s.sid FROM {subscriptions_role} s WHERE s.stype = "taxa" ORDER BY s.rid, s.sid');
+  while ($role = db_fetch_object($result)) {
+    $role_subscription[$role->rid] = $role_subscription[$role->rid] ? $role_subscription[$role->rid].','.$role->sid : $role->sid;
+  }
+  //Get roles.
+  $role_names = user_roles(1);
+
+  // traverse the taxonomy tree
+  //$taxa = subscriptions_get_taxa_count();
+  // omit undesired vocabularies from listing
+  $vocabularies = taxonomy_get_vocabularies();
+  $omits = variable_get('subscriptions_omitted_taxa', array());
+  foreach ($omits as $omit) {
+    unset($vocabularies[$omit]);
+  }
+  foreach ($vocabularies as $vocab) {
+    $tree = taxonomy_get_tree($vocab->vid);
+    foreach ($tree as $term) {
+      $row = array(t('category'), $vocab->name .': '. l($term->name, 'taxonomy/term/'. $term->tid)); //, is_null($taxa[$term->tid]) ? '0' : $taxa[$term->tid], l(t('subscribe'),'admin/subscriptions/add/'. $term->tid)
+      foreach ($role_names as $rid => $name) {
+        $row = array_merge($row, array(form_checkbox('', "$rid][".$term->tid, 1, strstr($role_subscription[$rid], $term->tid))));
+      }
+      $rows[] = $row;
+      unset($row);
+    } 
+  }
+ 
+  // concatentate the arrays
+  $headers = array_merge(array(t('type'), t('title')), array_values($role_names));
+  if (!$rows) {
+    $message .= t('<p>No categories defined.</p>');
+  }
+  else {
+    $message = theme('table', $headers, $rows);
+    $message .= form_submit(t('Save roles'));
+  }
+  drupal_set_title(t('Subscriptions Summary'));
+  print theme('page', form($message));
+  
+}
+
+/**
+ * Let admin (or user with the right to see his subscriptions)
+ * modify a subscription :
+ * - default : if one of the user roles get a subscription, user will receive 
+ *             notification
+ * - subscribe : the user will always receive subscription even if he got no 
+ *               role subscribed to the category.
+ * - refuse : the user refuse to receive subscription for this category.
+ * 
+ */
+
+function subscriptions_exceptions() {
+  $op = arg(3);
+  $edit = $_POST['edit'];
+  if ($edit) {
+    $sid = $edit['sid'];
+    unset($edit['sid']);
+    // Save users status:
+    db_query('DELETE FROM {subscriptions} WHERE stype="taxa"');
+    foreach ($edit as $key => $value) {
+      if (!$value) {
+        unset($edit[$key]);
+      }
+      else {
+        db_query("INSERT INTO {subscriptions} (sid, uid, stype, status) VALUES (%d, %d, '%s', %d)", $sid, $key, 'taxa', $value);
+      }
+    }
+
+    drupal_set_message(t('The changes have been saved.'));
+    drupal_goto('admin/subscriptions');
+  }
+  
+  
+  $result = db_queryd("SELECT u.uid, u.name, IFNULL(s.status, 0) AS status FROM {users} u LEFT OUTER JOIN {subscriptions} s ON u.uid = s.uid AND s.sid = %d AND s.stype = 'taxa' WHERE u.uid != 0", $op);
+  while ($user = db_fetch_object($result)) {
+    $rows[] = array(format_name($user), form_select(NULL, $user->uid, $user->status, array('-1'=>t('refuse'), '0'=>t('default'), '1'=>t('subscribe'))));
+  }   
+  
+  $term = taxonomy_get_term($op);
+  $title = $term->name;
+  drupal_set_title(t($title));
+  $headers = array(t('Username'), t('status'));
+  $output = theme('table', $headers, $rows);
+  $output .= form_hidden('sid', $op);
+  $output .= form_submit(t('Save status'));
+  print theme('page', form($output));
+  
+}
 ?>
