You are here

phpmailer.module in PHPMailer 8.3

Integrates the PHPMailer library for SMTP e-mail delivery.

File

phpmailer.module
View source
<?php

/**
 * @file
 * Integrates the PHPMailer library for SMTP e-mail delivery.
 */
use Drupal\Core\Url;
use Drupal\Component\Utility\Unicode;

/**
 * Implementation of hook_form_FORM_ID_alter().
 *
 * This is for the mimemail_admin_settings form.
 * 
 * @todo This whole function needs to be figured out.
 */
function phpmailer_form_mimemail_admin_settings_alter(&$form, &$form_state) {

  // Hide the Mime Mail global enabler setting if phpmailer is used to deliver
  // e-mails (they can't be both active).
  if (phpmailer_active()) {
    $mimemail_alter =& $form['mimemail']['mimemail_alter'];
    $mimemail_alter['#disabled'] = TRUE;
    $mimemail_alter['#default_value'] = 0;
    $phpmailer_settings = \Drupal::l(t('PHPMailer settings page'), Url::fromRoute('phpmailer.settings'));
    $mimemail_alter['#description'] = t('PHPMailer has been set to deliver all site messages. To let Mime Mail apply styles and formatting to system e-mails but still use PHPMailer for mail transport, uncheck <em>Use PHPMailer to send e-mails</em> first on the @url. Then activate this setting and choose PHPMailer from the list of e-mail engines below.', [
      '@url' => $phpmailer_settings,
    ]);
  }

  // @todo Move to MimeMail project.

  /**
   * @todo This needs to be figured out.
   */
  $phpmailer_preview = \Drupal::l(t('preview of a styled e-mail'), Url::fromRoute('phpmailer/preview'));
  $form['preview'] = [
    '#type' => 'item',
    '#title' => t('Preview'),
    '#value' => t('See a @url using the current message template (<code>mimemail-message.tpl.php</code>).', [
      '@url' => $phpmailer_preview,
    ]),
  ];
  $form['buttons']['#weight'] = 10;
}

/**
 * Implementation of hook_mailengine().
 *
 * This is for the Mime Mail module.
 */
function phpmailer_mailengine($op, $message = []) {
  if (!class_exists('PHPMailer')) {
    return;
  }
  switch ($op) {
    case 'list':
      return [
        'name' => t('PHPMailer'),
        'description' => t('Mailing engine using the PHPMailer library.'),
      ];
    case 'settings':
      $phpmailer_settings = \Drupal::l(t('PHPMailer settings page'), Url::fromRoute('phpmailer.settings'));
      $form['info']['#markup'] = t('To configure your mail server settings, visit the @url.', [
        '@url' => $phpmailer_settings,
      ]);
      return $form;
    case 'multiple':
    case 'single':
    case 'send':
      module_load_include('inc', 'phpmailer', 'includes/phpmailer.mimemail');

      // Mimemail API does not load mimemail.inc for other mailengines; we rely
      // on mimemail_rfc_headers(), so ensure that it is loaded.
      module_load_include('inc', 'mimemail');
      return mimemail_phpmailer_send($message);
  }
}

/**
 * Implementation of hook_mail().
 */
function phpmailer_mail($key, &$message, $params) {
  switch ($key) {
    case 'test':
      $message['subject'] = (string) t('PHPMailer test email');
      $message['body'][] = (string) t('Your site is properly configured to send emails using the <strong>PHPMailer</strong> library.');
      break;
  }
}

/**
 * Determine if PHPMailer is used to deliver e-mails.
 */
function phpmailer_active() {

  // We need to rely on our 'smtp_on' variable, since PHPMailer may not be
  // configured as the default mail system.
  return (bool) \Drupal::config('phpmailer.settings')
    ->get('smtp_on');
}

/**
 * Extract address and optional display name of an e-mail address.
 *
 * @param $string
 *   A string containing one or more valid e-mail address(es) separated with
 *   commas.
 *
 * @return
 *   An array containing all found e-mail addresses split into mail and name.
 *
 * @see http://tools.ietf.org/html/rfc5322#section-3.4
 */
function phpmailer_parse_address($string) {
  $parsed = [];

  // The display name may contain commas (3.4). Extract all quoted strings
  // (3.2.4) to a stack and replace them with a placeholder to prevent
  // splitting at wrong places.
  $string = preg_replace_callback('(".*?(?<!\\\\)")', '_phpmailer_stack', $string);

  // Build a regex that matches a name-addr (3.4).
  // @see valid_email_address()
  $user = '[a-zA-Z0-9_\\-\\.\\+\\^!#\\$%&*+\\/\\=\\?\\`\\|\\{\\}~\']+';
  $domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.?)+';
  $ipv4 = '[0-9]{1,3}(?:\\.[0-9]{1,3}){3}';
  $ipv6 = '[0-9a-fA-F]{1,4}(?:\\:[0-9a-fA-F]{1,4}){7}';
  $address = "{$user}@(?:{$domain}|(?:\\[(?:{$ipv4}|{$ipv6})\\]))";
  $adr_rx = "/^(?P<name>.*)\\s<(?P<address>{$address})>\$/";

  // Split string into multiple parts and process each.
  foreach (explode(',', $string) as $email) {

    // Re-inject stripped placeholders.
    $email = preg_replace_callback('(\\x01)', '_phpmailer_stack', trim($email));

    // Check if it's a name-addr or a plain address (3.4).
    if (preg_match($adr_rx, $email, $matches)) {

      // PHPMailer expects an unencoded display name.
      $parsed[] = [
        'mail' => $matches['address'],
        'name' => Unicode::mimeHeaderDecode(stripslashes($matches['name'])),
      ];
    }
    else {
      $parsed[] = [
        'mail' => trim($email, '<>'),
        'name' => '',
      ];
    }
  }
  return $parsed;
}

/**
 * Implements a FIFO stack to store extracted quoted strings.
 */
function _phpmailer_stack($matches = NULL) {
  $string = $matches[0];
  static $stack = [];
  if ($string == "\1") {

    // Unescape quoted characters (3.2.4) to prevent double escaping.
    return str_replace([
      '\\"',
      '\\\\',
    ], [
      '"',
      '\\',
    ], array_shift($stack));
  }

  // Remove surrounding quotes and push on stack.
  array_push($stack, substr($string, 1, -1));

  // Return placeholder substitution. 0x01 may never appear outside a quoted
  // string (3.2.3).
  return "\1";
}

Functions

Namesort descending Description
phpmailer_active Determine if PHPMailer is used to deliver e-mails.
phpmailer_form_mimemail_admin_settings_alter Implementation of hook_form_FORM_ID_alter().
phpmailer_mail Implementation of hook_mail().
phpmailer_mailengine Implementation of hook_mailengine().
phpmailer_parse_address Extract address and optional display name of an e-mail address.
_phpmailer_stack Implements a FIFO stack to store extracted quoted strings.