Index: send.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/send/send.inc,v retrieving revision 1.9.2.4 diff -u -r1.9.2.4 send.inc --- send.inc 12 Feb 2007 06:05:12 -0000 1.9.2.4 +++ send.inc 10 Oct 2007 06:12:58 -0000 @@ -11,6 +11,14 @@ '#title' => t('Allow visitors to send full item text'), '#default_value' => _send_value('fulltext', $module, $nodetype, $node), ); + $form["{$module}{$type}_multipleaddresses"] = array ( + '#type' => 'textfield', + '#title' => t('Maximum number of \'to\' addresses'), + '#default_value' => _send_value('multipleaddresses', $module, $nodetype, $node), + '#size' => 30, + '#maxsize' => 100, + '#description' => t('Leave blank to allow only a single \'to\' address'), + ); $form["{$module}{$type}_linktext"] = array( '#type' => 'textfield', '#title' => t("Link text"), @@ -277,25 +285,37 @@ '#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, - ); + if (_send_value('multipleaddresses', $module, $type, $node) > 1) { + $form['to']['recipient_multi'] = array( + '#type' => 'textarea', + '#title' => t('Email Addresses'), + '#required' => true, + '#cols' => 70, + '#rows' => 10, + '#description' => t('You can enter multiple e-mail addresses separated by commas or one per line. If you use the format Firstname Lastname <email@example.com> your e-mails will be addressed correctly.'), + ); + } + 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(); @@ -347,9 +367,10 @@ // 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(); @@ -359,7 +380,7 @@ 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']; @@ -375,8 +396,73 @@ 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(); + + // recipients are from a single textfield + if(isset($values['recipient_mail'])) { + $recipients[] = array('mail' => $values['recipient_mail']); + } + + // Recipients are from a comma/line-delimited textarea + if (isset($values['recipient_multi'])) { + $recipients = array(); + // Split at anything that looks even remotely like an e-mail address + // (basically an '@' with at least one letter either side), capturing the + // e-mail address 'delimiter'. Using an e-mail address as a delimiter + // means that people can mix and match commas, newlines or even nothing + // as separators. We don't validate now, that is done in _send_form_validate(). + $candidates = preg_split('/([A-Z0-9._%-]+@[A-Z0-9.-]+)/i', $values['recipient_multi'], -1, PREG_SPLIT_DELIM_CAPTURE); + $count = count($candidates); + // Even numbers are names, odd numbers are e-mail addresses + for ($i = 0; $i <= $count; $i = $i+2) { + $recipient = array(); + $mail = $candidates[$i+1]; + // Trim any delimiter like characters and remove any newlines + $name = str_replace(array("\r\n", "\n", "\r"), '', trim($candidates[$i], " ,;<>")); + + // Pull out some sensible first/last names + if (strpos($name, ',') === false) { + // First then last format: Joe Alex Blow + // Split at the last space, so middle names are grouped with the first name not the last + $pos = strrpos($name, ' ')+1; + $names = array(); + $names[] = substr($name, 0, $pos); + $names[] = substr($name, $pos); + } + else { + // Last then first format: Blow, Joe Alex + // Here we assume the last name is always before the comma, so explode works nicely + $names = explode(',', $name, 2); + $names = array_reverse($names); + } + + // Store the result + if (!empty($mail)) { + $recipient['mail'] = $mail; + $recipient['first_name'] = trim($names[0], " ,;<>"); + $recipient['last_name'] = trim($names[1], " ,;<>"); + $recipients[] = $recipient; + } + } + } + + // 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; + } + } + } + $values['recipients'] = $recipients; // Returned to validation + form_set_value($form['values']['recipients'], $recipients); // Stored for _submit } function _send_form_validate($form_id, $values, $form) { @@ -387,11 +473,29 @@ form_set_error('sender_mail',t('Invalid from address')); $ret = false; } - - if(isset($values['recipient_mail']) && !valid_email_address($values['recipient_mail'])) { - form_set_error('recipient_mail',t('Invalid recipient address')); - $ret = false; + + foreach ($values['recipients'] as $recipient) { + if (!valid_email_address($recipient['mail'])) { + if ($form['to']['recipient_mail']) { + form_set_error('recipient_mail',t('Invalid recipient address:') . check_plain($recipient['mail'])); + } + else { + form_set_error('recipient_multi',t('Invalid recipient address:') . check_plain($recipient['mail'])); + } + // TODO: Correctly mark field when recipients expanded into separate form fields (recipient1_first_name etc). + $ret = false; + } } + + // Check that the number of addresses is within the configured limit + $module = $values['module']; + $node = count($values['nids']) ? node_load($values['nids'][0]) : null; + $type = $node->type; + $max = _send_value('multipleaddresses', $module, $type, $node); + if (count($values['recipients']) > $max) { + form_set_error('recipient_multi',t('Too many recipient addresses - the maximum number of addresses is @max.', array('@max' => $max))); + } + return $ret; } @@ -432,43 +536,13 @@ 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.4 diff -u -r1.28.2.4 send.module --- send.module 12 Feb 2007 06:05:12 -0000 1.28.2.4 +++ send.module 10 Oct 2007 06:12:58 -0000 @@ -217,7 +217,10 @@ case 'querystring': // callback that will return name=>value array for return links return; - + + case 'multiple_addresses': // callback that returns if multiple 'to' addresses are allowed + return; + case 'deliver': // callback to send the message return '_send_deliver';