Skip to content
phpmailer.drupal.inc 6.06 KiB
Newer Older
Stefan Kudwien's avatar
Stefan Kudwien committed
<?php

/**
 * @file
 * Implements PHPMailer support on behalf of Drupal core.
 */

/**
Stefan Kudwien's avatar
Stefan Kudwien committed
 *
 * @param $message
 *   Message array structure.
 */
function phpmailer_send($message) {
  static $mail;

  if (!isset($mail)) {
    if (!phpmailer_load_library()) {
      return FALSE;
    }
Stefan Kudwien's avatar
Stefan Kudwien committed
    $mail = new DrupalPHPMailer();
  }

  try {
    // Parse 'From' e-mail address.
    $from = phpmailer_parse_address($message['from']);
    $from = reset($from);
    $mail->From = $from['mail'];
    if ($from['name'] != '') {
      $mail->FromName = $from['name'];
Stefan Kudwien's avatar
Stefan Kudwien committed
    }
    unset($message['headers']['From']);

    if (variable_get('phpmailer_debug_email', '') === '') {
      // Set recipients.
      foreach (phpmailer_parse_address($message['to']) as $address) {
        $mail->AddAddress($address['mail'], $address['name']);
      // Extract CCs and BCCs from headers.
      if (isset($message['headers']['Cc'])) {
        foreach (phpmailer_parse_address($message['headers']['Cc']) as $address) {
          $mail->AddCC($address['mail'], $address['name']);
        }
      }
      if (isset($message['headers']['Bcc'])) {
        foreach (phpmailer_parse_address($message['headers']['Bcc']) as $address) {
          $mail->AddBCC($address['mail'], $address['name']);
        }
    else {
      // Reroute to debug e-mail address.
      $mail->AddAddress(variable_get('phpmailer_debug_email', ''));
    unset($message['headers']['Cc'], $message['headers']['Bcc']);
    // Extract Reply-To from headers.
    if (isset($message['headers']['Reply-To'])) {
      foreach (phpmailer_parse_address($message['headers']['Reply-To']) as $address) {
        $mail->AddReplyTo($address['mail'], $address['name']);
Stefan Kudwien's avatar
Stefan Kudwien committed
      }
      unset($message['headers']['Reply-To']);
    }
    elseif (variable_get('smtp_always_replyto', FALSE)) {
      // If no Reply-To header has been explicitly set, use the From address to
      // be able to respond to e-mails sent via Google Mail.
      $mail->AddReplyTo($from['mail'], $from['name']);
    }

    // Extract Content-Type and charset.
    if (isset($message['headers']['Content-Type'])) {
      $content_type = explode(';', $message['headers']['Content-Type']);
      $mail->ContentType = trim(array_shift($content_type));
      foreach ($content_type as $param) {
        $param = explode('=', $param, 2);
        $key = trim($param[0]);
        if ($key == 'charset') {
          $mail->CharSet = trim($param[1]);
        }
        else {
          $mail->ContentType .= '; ' . $key . '=' . trim($param[1]);
        }
Stefan Kudwien's avatar
Stefan Kudwien committed
      }
      unset($message['headers']['Content-Type']);
    // Set additional properties.
    $properties = array(
      'X-Priority'                => 'Priority',
      'Content-Transfer-Encoding' => 'Encoding',
      'Sender'                    => 'Sender',
      'Message-ID'                => 'MessageID',
      // Custom property.
      // @see DrupalPHPMailer::CreateHeader()
      'Return-Path'               => 'ReturnPath',
    );
    foreach ($properties as $source => $property) {
      if (isset($message['headers'][$source])) {
        $mail->$property = $message['headers'][$source];
        unset($message['headers'][$source]);
      }
    // This one is always set by PHPMailer.
    unset($message['headers']['MIME-Version']);
    // Add remaining header lines.
    // Note: Any header lines MUST already be checked by the caller for unwanted
    // newline characters to avoid header injection.
    // @see PHPMailer::SecureHeader()
    foreach ($message['headers'] as $key => $value) {
      $mail->AddCustomHeader("$key:$value");
    }
    $mail->Subject = $message['subject'];
    $mail->Body = $message['body'];
    return $mail->Send();
  }
  catch (phpmailerException $e) {
    // Log the error including verbose debug information.
    // Since DBLog module is the most common case, we use HTML to format the
    // message for visual inspection. For sites running with Syslog or other
    // logging modules, we put the actual values on separate lines (\n), so the
    // surrounding HTML markup doesn't get too disturbing.

    // Message is a safe t() string from DrupalPHPMailer::SetLanguage().
    $output = $e->getMessage();
    // Attempt to delimit summary from full message.
    $output .= " \n";
    $arguments = array();
    // Append SMTP communication output.
    if ($mail->drupalDebugOutput) {
      // PHPMailer debug output contains HTML linebreaks. PRE is more readable.
      $mail->drupalDebugOutput = str_replace('<br />', '', $mail->drupalDebugOutput);
      $output .= '<p><strong>Server response:</strong></p>';
      $output .= "<pre>\n@smtp_output\n</pre>";
      $arguments += array(
        '@smtp_output' => $mail->drupalDebugOutput,
      );
    }
    // We need to log the message in order to be able to debug why the server
    // responded with an error. The mail body may contain passwords and other
    // sensitive information, which should not be logged. Since all kind of
    // mails are processed and Drupal provides no way to mark sensible data, it
    // is technically impossible prevent logging in all cases. This is a best
    // attempt to at least clean out passwords from User module mails, but known
    // to be insufficient.
    $message['body'] = preg_replace('@password: .+@', 'password: - REMOVED -', $message['body']);
    // Also remove $params; they've already been processed and may contain
    // sensible data, too.
    unset($message['params']);

    // Subject.
    $output .= "<p><strong>Subject:</strong> \n@subject\n</p>";
    $arguments += array(
      '@subject' => $message['subject'],
    );
    unset($message['subject']);
    // Body.
    $output .= '<p><strong>Body:</strong></p>';
    $output .= "<pre>\n@body\n</pre>";
    $arguments += array(
      '@body' => $message['body'],
    );
    unset($message['body']);
    // Rest of $message.
    $output .= '<p><strong>Message:</strong></p>';
    $output .= "<pre>\n@message\n</pre>";
    $arguments += array(
      '@message' => var_export($message, TRUE),
    );
    watchdog('phpmailer', $output, $arguments, WATCHDOG_ERROR);
    return FALSE;
  }