Index: send.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/send/send.inc,v
retrieving revision 1.9.2.6
diff -u -p -r1.9.2.6 send.inc
--- send.inc	3 Mar 2008 03:34:17 -0000	1.9.2.6
+++ send.inc	17 May 2008 02:27:39 -0000
@@ -12,6 +12,14 @@ function _send_settings_form($module, $n
     '#default_value' => _send_value('fulltext', $module, $nodetype, $node),
     '#description'   => t("Send the full body of the node via email.  If this setting is not enabled, messages will only contain a teaser view."),
   );
+  $form["{$module}{$type}_max_recipients"] = array (
+    '#type'          => 'textfield',
+    '#title'         => t('Maximum number of recipients'),
+    '#default_value' => _send_value('max_recipients', $module, $nodetype, $node),
+    '#size'          => 3,
+    '#maxsize'       => 3,
+    '#validate'      => array('send_max_recipients_validate' => array())
+  );
   $form["{$module}{$type}_linktext"] = array(
     '#type'          => 'textfield',
     '#title'         => t("Link text"),
@@ -49,6 +57,15 @@ function _send_settings_form($module, $n
 }
 
 /**
+ * Validation callback for the 'Maximum number of recipients' field.
+ */
+function send_max_recipients_validate($form) {
+  if (!is_numeric($form['#value']) || $form['#value'] < 1) {
+    form_error($form, t('The "%field" setting must be a number greater than 0.', array('%field' => t('Maximum number of recipients'))));
+  }
+}
+
+/**
  * module-specific settings
  */
 function _send_module_form($module='default') {
@@ -284,25 +301,38 @@ function _send_form($module, $nids=array
     '#default_value' => 0,
   );
   $form['to'] = array();
-  $form['to']['recipient_mail'] = array(
-    '#type'          => 'textfield',
-    '#title'         => t('Email'),
-    '#required'      => true,
-    '#size'          => 30,
-    '#maxsize'       => 100,
-  );
-  $form['to']['recipient_first_name'] = array(
-    '#type'          => 'textfield',
-    '#title'         => t('First Name'),
-    '#size'          => 30,
-    '#maxsize'       => 100,
-  );
-  $form['to']['recipient_last_name'] = array(
-    '#type'          => 'textfield',
-    '#title'         => t('Last Name'),
-    '#size'          => 30,
-    '#maxsize'       => 100,
-  );
+  $max_recipients = _send_value('max_recipients', $module, $type, $node);
+  if ($max_recipients > 1) {
+    $form['to']['recipient_multi'] = array(
+      '#type'          => 'textarea',
+      '#title'         => t('Email Addresses'),
+      '#required'      => true,
+      '#cols'          => 70,
+      '#rows'          => min($max_recipients + 1, 6),
+      '#description'   => t('Enter up to @max e-mail addresses, each on a separate line.', array('@max' => $max_recipients)) . '<br />' . t('You can optionally specify names in front of each address.'),
+    );
+  }
+  else {
+    $form['to']['recipient_mail'] = array(
+      '#type'          => 'textfield',
+      '#title'         => t('Email'),
+      '#required'      => true,
+      '#size'          => 30,
+      '#maxsize'       => 100,
+    );
+    $form['to']['recipient_first_name'] = array(
+      '#type'          => 'textfield',
+      '#title'         => t('First Name'),
+      '#size'          => 30,
+      '#maxsize'       => 100,
+    );
+    $form['to']['recipient_last_name'] = array(
+      '#type'          => 'textfield',
+      '#title'         => t('Last Name'),
+      '#size'          => 30,
+      '#maxsize'       => 100,
+    );
+  }
   
   $subject = _send_value('subject', $module, $type, $node);
   $form['subject'] = array();
@@ -354,9 +384,10 @@ function _send_form($module, $nids=array
 
   // These values will be computed during the validate phase
   $form['values'] = array(
-    'body'   => array('#type' => 'value', '#value' => ''),
-    'sender' => array('#type' => 'value', '#value' => ''),
-    'sid'    => array('#type' => 'value', '#value' => ''),
+    'body'          => array('#type' => 'value', '#value' => ''),
+    'sender'        => array('#type' => 'value', '#value' => ''),
+    'sid'           => array('#type' => 'value', '#value' => ''),
+    'recipients'    => array('#type' => 'value', '#value' => ''),
   );
   
   $form['buttons'] = array();
@@ -366,7 +397,7 @@ function _send_form($module, $nids=array
   return $form;
 }
 
-function _send_form_prepare($values, $form) {
+function _send_form_prepare(&$values, $form) {
   $module  = $values['module'];
   $mail    = $values['sender_mail'];
   $first_name = $values['sender_first_name'];
@@ -382,24 +413,98 @@ function _send_form_prepare($values, $fo
   if (!$body = theme("{$module}_body", $values)) {
     $body = theme('send_body', $values);
   }
-  form_set_value($form['values']['body'], $body);
-  
+  form_set_value($form['values']['body'], $body); // Stored for _submit
+
+  $recipients = array();
+
+  if (isset($values['recipient_mail'])) {
+    // Recipients are from a single textfield.
+    $recipients[] = array(
+      'mail' => $values['recipient_mail'],
+      'first_name' => $values['recipient_first_name'],
+      'last_name' => $values['recipient_last_name'],
+    );
+  }
+  elseif (isset($values['recipient_multi'])) {
+    // Recipients are from a comma/line-delimited textarea.
+    $recipients = array();
+    $candidates = explode("\n", $values['recipient_multi']);
+    foreach ($candidates as $candidate) {
+      $recipient = array();
+      $candidate = trim($candidate);
+      if (!empty($candidate)) {
+        $parts = preg_split('/\s+/', $candidate);
+        // The email address is always the last part of a candidate recipient.
+        $recipient['mail'] = trim(array_pop($parts), '<>,');
+        // If there are still any other parts, save those as the name fields.
+        foreach ($parts as $part) {
+          if (strpos($part, ',') || !empty($recipient['first_name'])) {
+            $part = trim($part, ',');
+            if (empty($recipient['last_name'])) {
+              $recipient['last_name'] = $part;
+            }
+            else {
+              $recipient['last_name'] .= ' ' . $part;
+            }
+          }
+          else {
+            $recipient['first_name'] = $part;
+          }
+        }
+        // Save this recipient in our array.
+        $recipients[] = $recipient;
+      }
+    }
+  }
+  if (!empty($recipients)) {
+    $values['recipients'] = $recipients; // Returned to validation
+    form_set_value($form['values']['recipients'], $recipients); // Stored for _submit
+  }
 }
 
 function _send_form_validate($form_id, $values, $form) {
-  $ret = true;
   _send_form_prepare($values, $form);
 
   if (!valid_email_address($values['sender_mail'])) {
-    form_set_error('sender_mail',t('Invalid from address'));
-    $ret = false;
+    form_set_error('sender_mail', t('Invalid from address'));
   }
-    
-  if(isset($values['recipient_mail']) && !valid_email_address($values['recipient_mail'])) {
-    form_set_error('recipient_mail',t('Invalid recipient address'));
-    $ret = false;
+
+  if (isset($form['to']['recipient_mail'])) {
+    // Single-recipient form, all we have to validate is the one address.
+    $recipient = reset($values['recipients']);
+    if (!valid_email_address($recipient['mail'])) {
+      form_set_error('recipient_mail', t('Invalid recipient address: %invalid', array('%invalid' => $recipient['mail'])));
+    }
+  }
+  else {
+    // Multi-recipient form, so there are multiple validation errors
+    // we could find. You can't call form_set_error() on the same form
+    // element multiple times, since all you see is the first error
+    // message. So, we'll collect any validation error messages in an
+    // array, only call form_set_error() once, and any remaining messages
+    // will be displayed via drupal_set_message().
+    $errors = array();
+
+    $module = $values['module'];
+    $node = count($values['nids']) ? node_load($values['nids'][0]) : NULL;
+    $type = $node->type;
+    $max = _send_value('max_recipients', $module, $type, $node);
+    if (count($values['recipients']) > $max) {
+      $errors[] = t('Too many recipient addresses. The maximum number of recipients is: @max.', array('@max' => $max));
+    }
+    foreach ($values['recipients'] as $recipient) {
+      if (!valid_email_address($recipient['mail'])) {
+        $errors[] = t('Invalid recipient address: %invalid', array('%invalid' => $recipient['mail']));
+      }
+    }
+    if (!empty($errors)) {
+      form_set_error('recipient_multi', array_shift($errors));
+      // Any remaining errors have to be displayed with drupal_set_message().
+      foreach ($errors as $error) {
+        drupal_set_message($error, 'error');
+      }
+    }
   }
-  return $ret;
 }
 
 function _send_form_submit($form_id, $values) {
@@ -439,43 +544,13 @@ function _send_form_submit($form_id, $va
   if(!$deliver = module_invoke($module, 'send', 'deliver', $module)) {
     $deliver = module_invoke('send', 'send', 'deliver','send');
   }
-  
-  $recipients = array();
-  // recipients are from a space/line-delimited textarea
-  if (isset($values['recipients'])) {
-    if (!is_array($recipients = $values['recipients'])) {
-      $recipients = array();
-      foreach (explode(',', preg_replace(array("/\s/ms","/,+/"), ',',$values['recipients'])) as $r) {
-        if (valid_email_address($r)) {
-          $recipients[] = array('mail' => $r);
-        }
-        else {
-          $recipients[] = $r;
-        }
-      }
-    }
-  }
-  
-  // recipients expanded into separate form fields
-  // e.g. recipient1_first_name, recipient2_mail,  and so-on
-  if(!count($recipients)) {
-    foreach ($values as $key => $value) {
-      if ($key != ($name = preg_replace('/^recipient(\d*)_/', '\1 ', $key))) {
-        list($i, $name) = explode(' ', $name);
-        if (!$i) $i = 1;
-        $i--;
-        if (!isset($recipients[$i])) $recipients[$i] = array();
-        $recipients[$i][$name] = $value;
-      }
-    }
-  }
 
   // recipient type - for now, 'node' or 'user'
   ($rtype = module_invoke($module, 'send', 'recipient type', $module))
     || ($rtype = module_invoke('send', 'send', 'recipient type', $module));
   
   $ret = true;
-  foreach ($recipients as $r) {
+  foreach ($values['recipients'] as $r) {
     $rid = 0;
 
     switch ($rtype) {
Index: send.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/send/send.module,v
retrieving revision 1.28.2.6
diff -u -p -r1.28.2.6 send.module
--- send.module	3 Mar 2008 03:34:17 -0000	1.28.2.6
+++ send.module	17 May 2008 02:27:39 -0000
@@ -255,6 +255,10 @@ function send_send($op, $module = 'send'
 
     case 'recipient type':       // node or user 
       return 'user';
+
+    case 'max_recipients':       // default maximum number of recipients
+      return 1;
+
   }
   return;
 }
