function smtp_drupal_mail_wrapper in SMTP Authentication Support 6
Sends out the e-mail.
Parameters
message: An array with at least the following elements: id, to, subject, body and headers.
See also
1 call to smtp_drupal_mail_wrapper()
- smtp.module in ./
smtp.module - Enables Drupal to send e-mail directly to an SMTP server.
File
- ./
smtp.module, line 327 - Enables Drupal to send e-mail directly to an SMTP server.
Code
function smtp_drupal_mail_wrapper($message) {
$id = $message['id'];
$to = $message['to'];
$from = $message['from'];
$language = $message['language'];
$subject = $message['subject'];
$body = $message['body'];
$headers = $message['headers'];
if (!smtp_load_library()) {
watchdog('smtp', 'Could not locate PHPMailer library.', array(), WATCHDOG_ERROR);
return FALSE;
}
// Create a new PHPMailer object.
$mail = new PHPMailer();
// Set the language PHPMailer is to use.
if (!$language) {
global $language;
if ($language) {
$mail
->SetLanguage($language->language, drupal_get_path('module', 'smtp') . '/phpmailer/language/');
}
}
else {
$mail
->SetLanguage($language->language, drupal_get_path('module', 'smtp') . '/phpmailer/language/');
}
// Turn in debugging, if requested.
if (variable_get('smtp_debugging', 0) == 1 && user_access('administer smtp module')) {
$mail->SMTPDebug = TRUE;
}
// Set the from name and e-mail address.
$from_name = variable_get('smtp_fromname', '');
if ($from_name == '') {
// If value is not defined in settings, use site_name.
$from_name = variable_get('site_name', '');
}
//Hack to fix reply-to issue.
$properfrom = variable_get('site_mail', '');
if (!empty($properfrom)) {
$headers['From'] = $properfrom;
}
if (!isset($headers['Reply-To']) || empty($headers['Reply-To'])) {
if (strpos($from, '<')) {
$reply = preg_replace('/>.*/', '', preg_replace('/.*</', '', $from));
}
else {
$reply = $from;
}
$headers['Reply-To'] = $reply;
}
// Blank value will let the e-mail address appear.
if ($from == NULL || $from == '') {
// If from e-mail address is blank, use smtp_from config option.
if (($from = variable_get('smtp_from', '')) == '') {
// If smtp_from config option is blank, use site_mail.
if (($from = variable_get('site_mail', '')) == '') {
drupal_set_message(t('There is no submitted from address.'), 'error');
watchdog('smtp', 'There is no submitted from address.', array(), WATCHDOG_ERROR);
return FALSE;
}
}
}
/*
if ($from == NULL || $from == '') {
if (variable_get('smtp_from', '') != '') {
$from = variable_get('smtp_from', '');
}
else {
// If smtp_from config option is blank, use site_mail.
$from = variable_get('site_mail', '');
}
}
*/
if (preg_match('/^"?.*"?\\s*<.*>$/', $from)) {
// . == Matches any single character except line break characters \r and \n.
// * == Repeats the previous item zero or more times.
$from_name = preg_replace('/("([^"]*)")|(([^("\\s)]*))\\s*\\<.*\\>$/', '$2$4', $from);
// It gives: Name
$from = preg_replace("/(.*)\\<(.*)\\>/i", '$2', $from);
// It gives: name@domain.tld
}
elseif (!valid_email_address($from)) {
drupal_set_message(t('The submitted from address (@from) is not valid.', array(
'@from' => $from,
)), 'error');
watchdog('smtp', 'The submitted from address (@from) is not valid.', array(
'@from' => $from,
), WATCHDOG_ERROR);
return FALSE;
}
// Defines the From value to what we expect.
$mail->From = $from;
$mail->FromName = $from_name;
$mail->Sender = $from;
// Create the list of 'To:' recipients.
$torecipients = explode(',', $to);
foreach ($torecipients as $torecipient) {
if (strpos($torecipient, '<') !== FALSE) {
$toparts = explode(' <', $torecipient);
$toname = $toparts[0];
$toaddr = rtrim($toparts[1], '>');
}
else {
$toname = '';
$toaddr = $torecipient;
}
$mail
->AddAddress($toaddr, $toname);
}
// Parse the headers of the message and set the PHPMailer object's settings
// accordingly.
foreach ($headers as $key => $value) {
//watchdog('error', 'Key: ' . $key . ' Value: ' . $value);
switch (drupal_strtolower($key)) {
case 'from':
if ($from == NULL or $from == '') {
// If a from value was already given, then set based on header.
// Should be the most common situation since drupal_mail moves the
// from to headers.
$from = $value;
$mail->From = $value;
// then from can be out of sync with from_name !
$mail->FromName = '';
$mail->Sender = $value;
}
break;
case 'content-type':
// Parse several values on the Content-type header, storing them in an array like
// key=value -> $vars['key']='value'
$vars = preg_split('/;[\\s]*/', $value);
foreach ($vars as $i => $var) {
if ($cut = strpos($var, '=')) {
$new_var = drupal_strtolower(drupal_substr($var, $cut + 1));
$new_key = drupal_substr($var, 0, $cut);
unset($vars[$i]);
$vars[$new_key] = $new_var;
}
}
// Set the charset based on the provided value, otherwise set it to UTF-8 (which is Drupals internal default).
$mail->CharSet = isset($vars['charset']) ? $vars['charset'] : 'UTF-8';
switch ($vars[0]) {
case 'text/plain':
// The message includes only a plain text part.
$mail
->IsHTML(FALSE);
$content_type = 'text/plain';
break;
case 'text/html':
// The message includes only an HTML part.
$mail
->IsHTML(TRUE);
$content_type = 'text/html';
break;
case 'multipart/related':
// Get the boundary ID from the Content-Type header.
$boundary = _smtp_get_substring($value, 'boundary', '"', '"');
// The message includes an HTML part w/inline attachments.
$mail->ContentType = $content_type = 'multipart/related; boundary="' . $boundary . '"';
break;
case 'multipart/alternative':
// The message includes both a plain text and an HTML part.
$mail->ContentType = $content_type = 'multipart/alternative';
// Get the boundary ID from the Content-Type header.
$boundary = _smtp_get_substring($value, 'boundary', '"', '"');
break;
case 'multipart/mixed':
// The message includes one or more attachments.
$mail->ContentType = $content_type = 'multipart/mixed';
// Get the boundary ID from the Content-Type header.
$boundary = _smtp_get_substring($value, 'boundary', '"', '"');
break;
default:
// Everything else is unsuppored by PHPMailer.
drupal_set_message(t('The Content-Type of your message is not supported by PHPMailer and will be sent as text/plain instead.'), 'error');
watchdog('smtp', 'The Content-Type of your message is not supported by PHPMailer and will be sent as text/plain instead.', array(), WATCHDOG_ERROR);
// Force the Content-Type to be text/plain.
$mail
->IsHTML(FALSE);
$content_type = 'text/plain';
}
break;
case 'reply-to':
// Only add a "reply-to" if it's not the same as "return-path".
if ($value != $headers['Return-Path']) {
if (strpos($value, '<') !== FALSE) {
$replyToParts = explode('<', $value);
$replyToName = trim($replyToParts[0]);
$replyToName = trim($replyToName, '"');
$replyToAddr = rtrim($replyToParts[1], '>');
$mail
->AddReplyTo($replyToAddr, $replyToName);
}
else {
$mail
->AddReplyTo($value);
}
}
break;
case 'content-transfer-encoding':
$mail->Encoding = $value;
break;
case 'return-path':
case 'mime-version':
case 'x-mailer':
// Let PHPMailer specify these.
break;
case 'errors-to':
$mail
->AddCustomHeader('Errors-To: ' . $value);
break;
case 'cc':
$ccrecipients = explode(',', $value);
foreach ($ccrecipients as $ccrecipient) {
if (strpos($ccrecipient, '<') !== FALSE) {
$ccparts = explode(' <', $ccrecipient);
$ccname = $ccparts[0];
$ccaddr = rtrim($ccparts[1], '>');
}
else {
$ccname = '';
$ccaddr = $ccrecipient;
}
$mail
->AddCC($ccaddr, $ccname);
}
break;
case 'bcc':
$bccrecipients = explode(',', $value);
foreach ($bccrecipients as $bccrecipient) {
if (strpos($bccrecipient, '<') !== FALSE) {
$bccparts = explode(' <', $bccrecipient);
$bccname = $bccparts[0];
$bccaddr = rtrim($bccparts[1], '>');
}
else {
$bccname = '';
$bccaddr = $bccrecipient;
}
$mail
->AddBCC($bccaddr, $bccname);
}
break;
default:
// The header key is not special - add it as is.
$mail
->AddCustomHeader($key . ': ' . $value);
}
}
/**
* TODO
* Need to figure out the following.
// Add one last header item, but not if it has already been added.
$errors_to = FALSE;
foreach ($mail->CustomHeader as $custom_header) {
if ($custom_header[0] = '') {
$errors_to = TRUE;
}
}
if ($errors_to) {
$mail->AddCustomHeader('Errors-To: '. $from);
}
*/
// Add the message's subject.
$mail->Subject = $subject;
// Processes the message's body.
switch ($content_type) {
case 'multipart/related':
$mail->Body = $body;
/**
* TODO
* Firgure out if there is anything more to handling this type.
*/
break;
case 'multipart/alternative':
// Split the body based on the boundary ID.
$body_parts = _smtp_boundary_split($body, $boundary);
foreach ($body_parts as $body_part) {
// If plain/text within the body part, add it to $mail->AltBody.
if (strpos($body_part, 'text/plain')) {
// Clean up the text.
$body_part = trim(_smtp_remove_headers(trim($body_part)));
// Include it as part of the mail object.
$mail->AltBody = $body_part;
}
elseif (strpos($body_part, 'text/html')) {
// Clean up the text.
$body_part = trim(_smtp_remove_headers(trim($body_part)));
// Include it as part of the mail object.
$mail->Body = $body_part;
}
}
break;
case 'multipart/mixed':
// Split the body based on the boundary ID.
$body_parts = _smtp_boundary_split($body, $boundary);
// Determine if there is an HTML part for when adding the plain text part.
$text_plain = FALSE;
$text_html = FALSE;
foreach ($body_parts as $body_part) {
if (strpos($body_part, 'text/plain')) {
$text_plain = TRUE;
}
if (strpos($body_part, 'text/html')) {
$text_html = TRUE;
}
}
foreach ($body_parts as $body_part) {
// If test/plain within the body part, add it to either
// $mail->AltBody or $mail->Body, depending on whether there is
// also a text/html part ot not.
if (strpos($body_part, 'multipart/alternative')) {
// Get boundary ID from the Content-Type header.
$boundary2 = _smtp_get_substring($body_part, 'boundary', '"', '"');
// Clean up the text.
$body_part = trim(_smtp_remove_headers(trim($body_part)));
// Split the body based on the boundary ID.
$body_parts2 = _smtp_boundary_split($body_part, $boundary2);
foreach ($body_parts2 as $body_part2) {
// If plain/text within the body part, add it to $mail->AltBody.
if (strpos($body_part2, 'text/plain')) {
// Clean up the text.
$body_part2 = trim(_smtp_remove_headers(trim($body_part2)));
// Include it as part of the mail object.
$mail->AltBody = $body_part2;
$mail->ContentType = 'multipart/mixed';
}
elseif (strpos($body_part2, 'text/html')) {
// Clean up the text.
$body_part2 = trim(_smtp_remove_headers(trim($body_part2)));
// Include it as part of the mail object.
$mail->Body = $body_part2;
$mail->ContentType = 'multipart/mixed';
}
}
}
elseif (strpos($body_part, 'text/plain')) {
// Clean up the text.
$body_part = trim(_smtp_remove_headers(trim($body_part)));
if ($text_html) {
$mail->AltBody = $body_part;
$mail
->IsHTML(TRUE);
$mail->ContentType = 'multipart/mixed';
}
else {
$mail->Body = $body_part;
$mail
->IsHTML(FALSE);
$mail->ContentType = 'multipart/mixed';
}
}
elseif (strpos($body_part, 'text/html')) {
// Clean up the text.
$body_part = trim(_smtp_remove_headers(trim($body_part)));
// Include it as part of the mail object.
$mail->Body = $body_part;
$mail
->IsHTML(TRUE);
$mail->ContentType = 'multipart/mixed';
}
elseif (strpos($body_part, 'Content-Disposition: attachment;')) {
$file_path = _smtp_get_substring($body_part, 'filename=', '"', '"');
$file_name = _smtp_get_substring($body_part, ' name=', '"', '"');
$file_encoding = _smtp_get_substring($body_part, 'Content-Transfer-Encoding', ' ', "\n");
$file_type = _smtp_get_substring($body_part, 'Content-Type', ' ', ';');
if (file_exists($file_path)) {
if (!$mail
->AddAttachment($file_path, $file_name, $file_encoding, $filetype)) {
drupal_set_message(t('Attahment could not be found or accessed.'));
}
}
else {
// Clean up the text.
$body_part = trim(_smtp_remove_headers(trim($body_part)));
if (drupal_strtolower($file_encoding) == 'base64') {
$attachment = base64_decode($body_part);
}
elseif (drupal_strtolower($file_encoding) == 'quoted-printable') {
$attachment = quoted_printable_decode($body_part);
}
else {
$attachment = $body_part;
}
$attachment_new_filename = tempnam(realpath(file_directory_temp()), 'smtp');
$file_path = file_save_data($attachment, $attachment_new_filename, FILE_EXISTS_RENAME);
if (!$mail
->AddAttachment($file_path, $file_name)) {
// , $file_encoding, $filetype);
drupal_set_message(t('Attachment could not be found or accessed.'));
}
}
}
}
break;
default:
$mail->Body = $body;
break;
}
// Set the authentication settings.
$username = variable_get('smtp_username', '');
$password = variable_get('smtp_password', '');
// If username and password are given, use SMTP authentication.
if ($username != '' && $password != '') {
$mail->SMTPAuth = TRUE;
$mail->Username = $username;
$mail->Password = $password;
}
// Set the protocol prefix for the smtp host.
switch (variable_get('smtp_protocol', 'standard')) {
case 'ssl':
$mail->SMTPSecure = 'ssl';
break;
case 'tls':
$mail->SMTPSecure = 'tls';
break;
default:
$mail->SMTPSecure = '';
}
// Set other connection settings.
$mail->Host = variable_get('smtp_host', '') . ';' . variable_get('smtp_hostbackup', '');
$mail->Port = variable_get('smtp_port', '25');
$mail->Mailer = 'smtp';
// Try to queue e-mail.
if (function_exists('job_queue_add')) {
watchdog('smtp', 'Queueing mail to: @to', array(
'@to' => $to,
));
job_queue_add('smtp_mail_send', t('Queued email'), array(
$mail,
), drupal_get_path('module', 'smtp') . '/phpmailer/class.phpmailer.php');
}
else {
watchdog('smtp', 'Sending mail to: @to', array(
'@to' => $to,
));
if (!$mail
->Send()) {
watchdog('smtp', 'Error sending e-mail from @from to @to : !error_message', array(
'@from' => $from,
'@to' => $to,
'!error_message' => $mail->ErrorInfo,
), WATCHDOG_ERROR);
return FALSE;
}
$mail
->SmtpClose();
}
return TRUE;
}