smtp_drupal_mail_wrapper

  1. smtp
    1. 6
Versions
6 smtp_drupal_mail_wrapper($message)

Sends out the e-mail.

Parameters

message An array with at least the following elements: id, to, subject, body and headers.

See also

drupal_mail_send()

Code

./smtp.module, line 327

<?php
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) {
    $mail->SMTPDebug = TRUE;
  }


  // Set the from name and e-mail address.
  if (variable_get('smtp_fromname', '') != '') {
    $from_name = variable_get('smtp_fromname', '');
  }
  else {
    // 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_email.
      if (($from = variable_get('site_email', '')) == '') {
        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_email.
   $from = variable_get('site_email', '');
   }
   }
   */
  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)]*)"?.*$/', '$1', $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 = explode('; ', $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, if there is one.
        $charset = $vars['charset'];
        if ($charset) {
          $mail->CharSet = $charset;
        }
        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;
        }
        // If plain/html within the body part, add it to $mail->Body.
        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')) {
          // Clean up the text.
          $body_part = trim(_smtp_remove_headers(trim($body_part)));
          // Get boundary ID from the Content-Type header.
          $boundary2 = _smtp_get_substring($body_part, 'boundary', '"', '"');
          // 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';
            }
            // If plain/html within the body part, add it to $mail->Body.
            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';
            }
          }
        }
        // If text/plain within the body part, add it to $mail->Body.
        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';
          }
        }
        // If text/html within the body part, add it to $mail->Body.
        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';
        }
        // Add the attachment.
        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';


  // Let the people know what is going on.
  watchdog('smtp', 'Sending mail to: @to', array('@to' => $to));

  // Try to send e-mail. If it fails, set watchdog entry.
  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;
}
?>