You are here

smtp.module in SMTP Authentication Support 7.2

Same filename and directory in other branches
  1. 8 smtp.module
  2. 5 smtp.module
  3. 6 smtp.module
  4. 7 smtp.module

Enables Drupal to send e-mail directly to an SMTP server.

This module uses a customized extract of the PHPMailer library (originally by Brent R. Matzelle, now maintained by Codeworx Tech.) relicensed from LGPL to GPL, included as a part of the module.

Overriding mail handling in Drupal to make SMTP the default transport layer, requires to change the mail_system variable's default value array('default-system' => 'DefaultMailSystem'). This module uses array('default-system' => 'SmtpMailSystem').

File

smtp.module
View source
<?php

/**
 * @file
 * Enables Drupal to send e-mail directly to an SMTP server.
 *
 * This module uses a customized extract of the PHPMailer
 * library (originally by Brent R. Matzelle, now maintained
 *  by Codeworx Tech.) relicensed from LGPL to GPL, included
 * as a part of the module.
 *
 * Overriding mail handling in Drupal to make SMTP the default
 * transport layer, requires to change the mail_system variable's
 * default value array('default-system' => 'DefaultMailSystem').
 * This module uses array('default-system' => 'SmtpMailSystem').
 */

/**
 * SMTP logging -- logging is disabled
 */
define('SMTP_LOGGING_NONE', 0);

/**
 * SMTP logging -- all messages are logged
 */
define('SMTP_LOGGING_ALL', 1);

/**
 * SMTP logging -- only errors are logged
 */
define('SMTP_LOGGING_ERRORS', 2);

/**
 * Implements hook_help().
 */
function smtp_help($path, $arg) {
  switch ($path) {
    case 'admin/help#smtp':
      return t('Allow for site emails to be sent through an SMTP server of your choice.');
  }
}

/**
 * Implements hook_menu().
 */
function smtp_menu() {
  $items['admin/config/system/smtp'] = array(
    'title' => 'SMTP Authentication Support',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_settings',
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Allow for site emails to be sent through an SMTP server of your choice.',
    'file' => 'smtp.admin.inc',
  );
  $items['admin/config/system/smtp/provider/add'] = array(
    'title' => 'SMTP Provider',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_provider_settings',
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Edition page for SMTP providers.',
    'file' => 'smtp.admin.inc',
  );
  $items['admin/config/system/smtp/provider/%/edit'] = array(
    'title' => 'SMTP Provider',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_provider_settings',
      5,
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Edition page for SMTP providers.',
    'file' => 'smtp.admin.inc',
  );
  $items['admin/config/system/smtp/provider/%/delete'] = array(
    'title' => 'Delete SMTP provider',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_provider_delete',
      5,
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Edition page for SMTP providers.',
    'file' => 'smtp.admin.inc',
  );
  $items['admin/config/system/smtp/criteria/add'] = array(
    'title' => 'Selection Criteria',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_criteria_settings',
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Edition page for selection criterias.',
    'file' => 'smtp.admin.inc',
  );
  $items['admin/config/system/smtp/criteria/%smtp_selection_criteria/edit'] = array(
    'title' => 'Selection Criteria',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_criteria_settings',
      5,
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Edition page for selection criterias.',
    'file' => 'smtp.admin.inc',
  );
  $items['admin/config/system/smtp/criteria/%smtp_selection_criteria/delete'] = array(
    'title' => 'Delete selection criteria',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'smtp_admin_criteria_delete',
      5,
    ),
    'access arguments' => array(
      'administer smtp module',
    ),
    'description' => 'Deletion page for selection criterias.',
    'file' => 'smtp.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function smtp_permission() {
  return array(
    'administer smtp module' => array(
      'title' => t('Administer SMTP Authentication Support module'),
      'description' => t('Perform administration tasks for SMTP Authentication Support module.'),
    ),
  );
}

/**
 * Implements hook_theme().
 */
function smtp_theme($existing, $type, $theme, $path) {
  return array(
    'smtp_table' => array(
      'render element' => 'element',
      'file' => 'smtp.theme.inc',
    ),
    'smtp_selection_criteria' => array(
      'render element' => 'element',
      'file' => 'smtp.theme.inc',
    ),
  );
}

/**
 * Implements hook_mail().
 */
function smtp_mail($key, &$message, $params) {
  if ($key == 'smtp-test') {
    $message['subject'] = $params['subject'];
    $message['body'] = $params['body'];
  }
}

/**
 * Implementation of hook_cron_queue_info().
 */
function smtp_cron_queue_info() {
  $queues['smtp_send_queue'] = array(
    'worker callback' => 'smtp_send_queue_runner',
    'time' => 60,
  );
  $queues['smtp_failure_queue'] = array(
    'worker callback' => 'smtp_failure_queue_runner',
    'time' => 30,
  );
  return $queues;
}

/**
 * smtp_send_queue queuer.
 */
function smtp_send_queue($mailerObj) {
  $queue = DrupalQueue::get('smtp_send_queue');
  $queue
    ->createItem($mailerObj);
}
function smtp_send_queue_runner($message) {
  $logging = variable_get('smtp_debugging', SMTP_LOGGING_ERRORS);

  // Legacy for mails queued before 7.x-v1.3
  // What was passed to the runner used to be a PHPMailer object, not a message array.
  if (!empty($message['mailer']) && is_object($message['mailer'])) {
    if (!$message['mailer']
      ->Send()) {
      if ($logging == SMTP_LOGGING_ALL || $logging == SMTP_LOGGING_ERRORS) {
        watchdog('smtp', 'Error sending e-mail from @from to @to, will retry on cron run : !error_message.', array(
          '@from' => $message['from'],
          '@to' => $message['to'],
          '!error_message' => $message['mailer']->ErrorInfo,
        ), WATCHDOG_ERROR);
      }
    }
    return;
  }

  // Let the people know what is going on.
  if ($logging == SMTP_LOGGING_ALL) {
    watchdog('smtp', 'Sending mail to: @to', array(
      '@to' => $message['to'],
    ));
  }

  // Send the message.
  $mail_system = new SmtpMailSystem();
  $mail_system
    ->mailWithoutQueue($message);
}

/**
 * Store failed messages for later.
 *
 * @param array $new_message
 *
 * @return array
 *   All messages that have been saved.
 */
function smtp_failed_messages($message) {
  $queue = DrupalQueue::get('smtp_failure_queue');
  $queue
    ->createItem($message);
}

/**
 * Get the variable value of the enabled provider
 *
 * @param string $name
 *   The name of the variable to return.
 * @param $default
 *   The default value to use if this variable has never been set.
 *
 * @return
 *   The value of the variable. Unserialization is taken care of as necessary.
 */
function smtp_provider_variable_get($name, $default = NULL) {
  $providers = variable_get('smtp_providers', array());
  $current_provider = smtp_current_provider();
  return isset($providers[$current_provider][$name]) ? $providers[$current_provider][$name] : $default;
}

/**
 * Auxiliar function that retrieves the current SMTP provider.
 * It can be used in other places of the code to force a provider,
 * using the $provider param.
 *
 * @param string $provider
 *   The machine name of the provider to be used on this code execution.
 *   Be aware that this parameter only changes the provider on drupal_static
 *   time, so if you need to change the default provider on all requests, please
 *   use the administration interface.
 *
 * @return
 *   The machine name of the current provider.
 */
function smtp_current_provider($provider = NULL) {
  static $drupal_static;
  if (!isset($drupal_static)) {
    $drupal_static =& drupal_static(__FUNCTION__);
  }
  $current_provider =& $drupal_static;
  if (isset($provider)) {
    $current_provider = $provider;
  }
  elseif (!isset($current_provider)) {

    // The default fallback is the default provider
    $default_provider = variable_get('smtp_default_provider', '');
    $current_provider = $default_provider;
  }
  return $current_provider;
}

/**
 * Gets the provider for the first met selection criteria.
 *
 * @param message
 *  The message being sent. Its values will be used to check selection criterias.
 *
 * @return
 *  A string with the machine name of the selected provider.
 *  If none of the selection criterias are satisfied, this function returns NULL.
 */
function smtp_prefered_provider($message) {
  static $drupal_static;
  if (!isset($drupal_static)) {
    $drupal_static =& drupal_static(__FUNCTION__);
  }
  $prefered_provider = NULL;

  // Gets prefered provider from cache
  if (isset($drupal_static['provider'])) {
    $prefered_provider =& $drupal_static['provider'];

    // Checks if conditions are still valid
    foreach ($drupal_static['criteria'] as $key => $value) {
      if (empty($value) || strpos($key, 'message_') !== 0 || $key == 'message_language') {
        continue;
      }
      if (!isset($message[$key]) || $message[$key] != $value) {

        // Conditions changed
        $prefered_provider = NULL;
        break;
      }
    }

    // Language is an object and checked separately
    if (!empty($drupal_static['criteria']['message_language'])) {
      $value = $drupal_static['criteria']['message_language'];
      if (!isset($message['language']) || $message['language']->language != $value) {

        // Conditions changed
        $prefered_provider = NULL;
      }
    }
  }

  // Gets provider from database
  if (empty($prefered_provider)) {
    $query = db_select('smtp_selection_criteria', 'c')
      ->fields('c')
      ->orderBy('weight')
      ->range(0, 1);

    // Adds conditions for the listed keys
    $message_keys = array(
      'module',
      'key',
    );
    foreach ($message_keys as $key) {
      $condition = db_or()
        ->condition("message_{$key}", '');
      if (isset($message[$key])) {
        $condition
          ->condition("message_{$key}", $message[$key]);
      }
      $query
        ->condition($condition);
    }

    // Language is an object and added separately
    $condition = db_or()
      ->condition('message_language', '');
    if (isset($message['language'])) {
      $condition
        ->condition('message_language', $message['language']->language);
    }
    $query
      ->condition($condition);

    // Caches selected provider
    $result = $query
      ->execute()
      ->fetchAssoc();
    if ($result) {
      $prefered_provider = $result['provider'];
      $drupal_static['criteria'] = $result;
    }
  }
  return $prefered_provider;
}

/**
 * Lists selection criterias.
 *
 * @param provider
 *  Optionally filters selection criterias by provider.
 *
 * @return
 *  An associative array of selection criterias keyed by identifiers (cid).
 */
function smtp_list_selection_criterias($provider = NULL) {
  $query = db_select('smtp_selection_criteria', 'c')
    ->fields('c')
    ->orderBy('weight', 'asc');
  if (isset($provider)) {
    $query
      ->condition('provider', $provider);
  }
  $result = $query
    ->execute()
    ->fetchAllAssoc('cid', PDO::FETCH_ASSOC);
  return $result;
}

/**
 * Loads a criteria by its identifier.
 *
 * @return
 *  Associative array with selection criterias' properties.
 *  Returns FALSE if selection criteria does not exist.
 */
function smtp_selection_criteria_load($cid) {
  $result = db_select('smtp_selection_criteria', 'c')
    ->fields('c')
    ->condition('cid', $cid)
    ->execute();
  return $result
    ->fetchAssoc();
}

/**
 * Queue runner for smtp_failure_queue.
 *
 * @param $message
 *   A drupal_mail-formatted message.
 */
function smtp_failure_queue_runner($message) {
  $queue = DrupalQueue::get('smtp_send_queue');
  $queue
    ->createItem($message);
}

Functions

Namesort descending Description
smtp_cron_queue_info Implementation of hook_cron_queue_info().
smtp_current_provider Auxiliar function that retrieves the current SMTP provider. It can be used in other places of the code to force a provider, using the $provider param.
smtp_failed_messages Store failed messages for later.
smtp_failure_queue_runner Queue runner for smtp_failure_queue.
smtp_help Implements hook_help().
smtp_list_selection_criterias Lists selection criterias.
smtp_mail Implements hook_mail().
smtp_menu Implements hook_menu().
smtp_permission Implements hook_permission().
smtp_prefered_provider Gets the provider for the first met selection criteria.
smtp_provider_variable_get Get the variable value of the enabled provider
smtp_selection_criteria_load Loads a criteria by its identifier.
smtp_send_queue smtp_send_queue queuer.
smtp_send_queue_runner
smtp_theme Implements hook_theme().

Constants

Namesort descending Description
SMTP_LOGGING_ALL SMTP logging -- all messages are logged
SMTP_LOGGING_ERRORS SMTP logging -- only errors are logged
SMTP_LOGGING_NONE SMTP logging -- logging is disabled