# HG changeset patch # User Rich Siomporas # Date 1243394585 14400 # Node ID 511cfad8189d0588300b44bb6acd3ff1fe4609be # Parent c3aa9a9d51ff59f80c88f35c31f7583e8f9c62e8 Added _mass_contact_mail() duplicate function of drupal_mail() function to fix issue with drupal_wrap_mail() f'ing mixed messages up. Cleaned up a logic bug with building the mixed mail messages to add a close marker to the HTML message if present. Tested across every permutation of possible ways to send mail, it worked! --- a/mass_contact.module +++ b/mass_contact.module @@ -314,16 +314,127 @@ function mass_contact_mail($key, &$messa } } $message['subject'] = $params['subject']; $message['body'] = $params['body']; } // End of mass_contact_mail(). + + + + +/* + * Duplication of drupal_mail() function from /includes/mail.inc, from + * Version 1.8.2.6 (checked in on 2009/04/27 at 11:07:43 by goba); + * duplicated because the drupal_mail() function calls drupal_wrap_mail(), + * which causes destruction of multpart/mixed e-mails generated by this + * module. The function call is removed from this version, but otherwise + * it should operate just as well. + * + * @param $module + * A module name to invoke hook_mail() on. The {$module}_mail() hook will be + * called to complete the $message structure which will already contain common + * defaults. + * @param $key + * A key to identify the e-mail sent. The final e-mail id for e-mail altering + * will be {$module}_{$key}. + * @param $to + * The e-mail address or addresses where the message will be sent to. The + * formatting of this string must comply with RFC 2822. Some examples are: + * user@example.com + * user@example.com, anotheruser@example.com + * User + * User , Another User + * @param $language + * Language object to use to compose the e-mail. + * @param $params + * Optional parameters to build the e-mail. + * @param $from + * Sets From, Reply-To, Return-Path and Error-To to this value, if given. + * @param $send + * Send the message directly, without calling drupal_mail_send() manually. + * @return + * The $message array structure containing all details of the + * message. If already sent ($send = TRUE), then the 'result' element + * will contain the success indicator of the e-mail, failure being already + * written to the watchdog. (Success means nothing more than the message being + * accepted at php-level, which still doesn't guarantee it to be delivered.) + */ +function _mass_contact_mail($module, $key, $to, $language, $params = array(), $from = NULL, $send = TRUE) { + $default_from = variable_get('site_mail', ini_get('sendmail_from')); + + // Bundle up the variables into a structured array for altering. + $message = array( + 'id' => $module .'_'. $key, + 'to' => $to, + 'from' => isset($from) ? $from : $default_from, + 'language' => $language, + 'params' => $params, + 'subject' => '', + 'body' => array() + ); + + // Build the default headers + $headers = array( + 'MIME-Version' => '1.0', + 'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes', + 'Content-Transfer-Encoding' => '8Bit', + 'X-Mailer' => 'Drupal' + ); + if ($default_from) { + // To prevent e-mail from looking like spam, the addresses in the Sender and + // Return-Path headers should have a domain authorized to use the originating + // SMTP server. Errors-To is redundant, but shouldn't hurt. + $headers['From'] = $headers['Sender'] = $headers['Return-Path'] = $headers['Errors-To'] = $default_from; + } + if ($from) { + $headers['From'] = $from; + } + $message['headers'] = $headers; + + // Build the e-mail (get subject and body, allow additional headers) by + // invoking hook_mail() on this module. We cannot use module_invoke() as + // we need to have $message by reference in hook_mail(). + if (function_exists($function = $module .'_mail')) { + $function($key, $message, $params); + } + + // Invoke hook_mail_alter() to allow all modules to alter the resulting e-mail. + drupal_alter('mail', $message); + + // Removed destruction of multipart/mixed e-mails by the (now missing) call below + + + // Optionally send e-mail. + if ($send) { + $message['result'] = drupal_mail_send($message); + + // Log errors + if (!$message['result']) { + watchdog('mail', 'Error sending e-mail (from %from to %to).', array('%from' => $message['from'], '%to' => $message['to']), WATCHDOG_ERROR); + drupal_set_message(t('Unable to send e-mail. Please contact the site administrator if the problem persists.'), 'error'); + } + } + + return $message; +} + + + + + + + + + + + + /* ************************************************************** * * Functions for listing, adding/editing and deleting categories. * * *************************************************************/ @@ -1269,16 +1380,18 @@ function mass_contact_mail_page_submit($ 'filepath' => $_FILES['files']['tmp_name']['attachment'], 'filename' => $_FILES['files']['name']['attachment'], 'filemime' => $_FILES['files']['type']['attachment'], ) ); } else { */ + if ($form_state['values']['html']) + $message .= "\n--". $boundary_html ."--\n"; $message_attachment = "\n--". $boundary_attachment ."\n"; $message_attachment .= 'Content-Type: '. $_FILES['files']['type']['attachment'] .'; name="'. basename($_FILES['files']['name']['attachment']) .'"'."\n"; $message_attachment .= "Content-Transfer-Encoding: base64\n"; $message_attachment .= 'Content-Disposition: attachment; filename="'. basename($_FILES['files']['name']['attachment']) .'"'."\n\n"; $message_attachment .= chunk_split(base64_encode(file_get_contents($_FILES['files']['tmp_name']['attachment']))); $message_attachment .= "\n--". $boundary_attachment ."--\n"; $message .= $message_attachment; @@ -1428,17 +1541,17 @@ function mass_contact_mail_page_submit($ $success = mimemail($from_email, $to, $params['subject'], $body, NULL, $params['headers'], NULL, $message_attachment); } else { $success = mimemail($from_email, $to, $params['subject'], $body, TRUE, $params['headers'], $body, $message_attachment); } } else { */ - $success = drupal_mail('mass_contact', 'mail_page', $to, language_default(), $params, $from_email); + $success = _mass_contact_mail('mass_contact', 'mail_page', $to, language_default(), $params, $from_email); // } if ($success['result']) { drupal_set_message(t('[Success] Send #!ccc: -e-mails', array('!ccc' => $ccc, '-e-mails' => $recipient_send))); } else { ++$send_error; } @@ -1470,22 +1583,22 @@ function mass_contact_mail_page_submit($ $success = mimemail($from_email, $to, $params['subject'], $body, NULL, $params['headers'], NULL, $message_attachment); } else { $success = mimemail($from_email, $to, $params['subject'], $body, TRUE, $params['headers'], $body, $message_attachment); } } else { */ - $success = drupal_mail('mass_contact', 'mail_page', $to, language_default(), $params, $from_email); + $success = _mass_contact_mail('mass_contact', 'mail_page', $to, language_default(), $params, $from_email); // } // Send a copy to self, if requested. if ($form_state['values']['copy'] && !$bcc) { - drupal_mail('mass_contact', 'user-copy', $from_email, language_default(), $params, $from_email); + _mass_contact_mail('mass_contact', 'user-copy', $from_email, language_default(), $params, $from_email); } if ($success['result']) { drupal_set_message(t('[Success] Send Remainder: -e-mails', array('-e-mails' => $recipient_send))); } else { ++$send_error; } @@ -1518,22 +1631,22 @@ function mass_contact_mail_page_submit($ $success = mimemail($from_email, $to, $params['subject'], $body, NULL, $params['headers'], NULL, $message_attachment); } else { $success = mimemail($from_email, $to, $params['subject'], $body, TRUE, $params['headers'], $body, $message_attachment); } } else { */ - $success = drupal_mail('mass_contact', 'mail_page', $to, language_default(), $params, $from_email); + $success = _mass_contact_mail('mass_contact', 'mail_page', $to, language_default(), $params, $from_email); // } // Send a copy to self, if requested. if ($form_state['values']['copy'] && !$bcc) { - drupal_mail('mass_contact', 'user-copy', $from_email, language_default(), $params, $from_email); + _mass_contact_mail('mass_contact', 'user-copy', $from_email, language_default(), $params, $from_email); } if ($success['result']) { drupal_set_message(t('[Success] Send Once: -e-mails', array('-e-mails' => $recipientout))); } else { ++$send_error; }