You are here

sparkpost.module in Sparkpost email 7

Same filename and directory in other branches
  1. 8.2 sparkpost.module
  2. 8 sparkpost.module
  3. 7.2 sparkpost.module

Sparkpost integration.

File

sparkpost.module
View source
<?php

/**
 * @file
 * Sparkpost integration.
 */
define('SPARKPOST_EMAIL_REGEX', '/^\\s*(.+?)\\s*<\\s*([^>]+)\\s*>$/');
define('SPARKPOST_QUEUE_NAME', 'sparkpost_mail_queue');

/**
 * Implements hook_menu().
 */
function sparkpost_menu() {
  $items = array();
  $items['admin/config/services/sparkpost'] = array(
    'title' => 'Sparkpost',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'sparkpost_admin_settings',
    ),
    'access arguments' => array(
      'administer sparkpost',
    ),
    'description' => 'Send emails through the Sparkpost transactional email service.',
    'file' => 'sparkpost.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/services/sparkpost/settings'] = array(
    'title' => 'Settings',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  $items['admin/config/services/sparkpost/test'] = array(
    'title' => 'Send test email',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'sparkpost_test_form',
    ),
    'access callback' => 'sparkpost_test_access',
    'description' => 'Send a test email using the Sparkpost API.',
    'file' => 'sparkpost.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 1,
  );
  return $items;
}

/**
 * Access callback for sending test email.
 *
 * @return bool
 *   True if current user has access to send test messages
 */
function sparkpost_test_access() {
  $a = user_access('administer sparkpost');
  $b = variable_get('sparkpost_api_key');
  return $a & !empty($b);
}

/**
 * Implements hook_permission().
 */
function sparkpost_permission() {
  return array(
    'administer sparkpost' => array(
      'title' => t('Administer Sparkpost'),
      'description' => t('Perform administration tasks for the Sparkpost email service.'),
      "restrict access" => TRUE,
    ),
  );
}

/**
 * Implements hook_mail().
 */
function sparkpost_mail($key, &$message, $params) {
  if ($key == 'test') {
    $message['subject'] = $params['subject'];
    $message['body'] = $params['body'];
    if ($params['include_attachment']) {
      $message['attachments'][] = drupal_realpath('misc/druplicon.png');
      $message['body'][] = t('The Drupal icon is included as an attachment to test the attachment functionality.');
    }
  }
}

/**
 * Returns an array containing the from information for a Sparkpost message.
 *
 * @return array
 *   array(
 *     'email' => 'admin@example.com',
 *     'name' => 'My Site',
 *   )
 */
function sparkpost_from() {
  $default_from = variable_get('site_mail', ini_get('sendmail_from'));
  $email = variable_get('sparkpost_from', $default_from);
  $name = variable_get('sparkpost_from_name', variable_get('site_name'));
  return array(
    'email' => $email,
    'name' => $name,
  );
}

/**
 * Helper to generate an array of recipients.
 *
 * @param mixed $to
 *   a comma delimited list of email addresses in 1 of 2 forms:
 *   user@domain.com
 *   any number of names <user@domain.com>
 *
 * @return array
 *   array of email addresses
 */
function sparkpost_get_to($to) {
  $recipients = array();
  $to_array = explode(',', $to);
  foreach ($to_array as $email) {
    if (preg_match(SPARKPOST_EMAIL_REGEX, $email, $matches)) {
      $recipients[] = array(
        'address' => array(
          'name' => $matches[1],
          'email' => $matches[2],
        ),
      );
    }
    else {
      $recipients[] = array(
        'address' => array(
          'email' => $email,
        ),
      );
    }
  }
  return $recipients;
}

/**
 * Get list of cc recipients.
 *
 * @param string $cc
 *   Comma separated list of Cc recipients.
 * @param array $to
 *   List of recipients created by sparkpost_get_to().
 *
 * @return array
 *   List of recipients to merged with sparkpost_get_to() results.
 */
function sparkpost_get_cc($cc, array $to) {
  $recipients = array();

  // Explode recipient list.
  $cc_array = explode(',', $cc);

  // Prepare header_to value.
  $header_to = implode(',', array_map(function ($recipient) {
    return $recipient['address']['email'];
  }, $to));
  foreach ($cc_array as $email) {
    if (preg_match(SPARKPOST_EMAIL_REGEX, $email, $matches)) {
      $email = $matches[2];
    }
    $recipients[] = array(
      'address' => array(
        'email' => $email,
        'header_to' => $header_to,
      ),
    );
  }
  return $recipients;
}

/**
 * Sand mail using Guzzle and Sparkpost.
 *
 * @param SparkpostMessageWrapperInterface $message_wrapper
 *   Message array.
 *
 * @return bool
 */
function sparkpost_mailsend(SparkpostMessageWrapperInterface $message_wrapper) {
  try {
    if (!class_exists('\\Ivory\\HttpAdapter\\Guzzle6HttpAdapter') || !class_exists('\\GuzzleHttp\\Client') || !class_exists('\\SparkPost\\SparkPost')) {
      throw new Exception('Missing Composer dependencies, check admin/config/system/composer-manager/packages');
    }
    $httpAdapter = new \Ivory\HttpAdapter\Guzzle6HttpAdapter(new \GuzzleHttp\Client());
    $sparky = new \SparkPost\SparkPost($httpAdapter, [
      'key' => variable_get('sparkpost_api_key'),
    ]);

    // Set custom timeout value.
    $config = $sparky->httpAdapter
      ->getConfiguration();
    $config
      ->setTimeout(variable_get('sparkpost_timeout', 10));
    $sparky->httpAdapter
      ->setConfiguration($config);

    // Build your email and send it!
    $results = $sparky->transmission
      ->send($message_wrapper
      ->getSparkpostMessage());

    // Add results array to message wrapper.
    $message_wrapper
      ->setResult($results);

    // Let other modules do something on success.
    module_invoke_all('sparkpost_mailsend_success', $message_wrapper);
    return TRUE;
  } catch (\SparkPost\APIResponseException $e) {
    $message_wrapper
      ->setApiResponseException($e);
  } catch (Exception $e) {

    // Undefined exception.
    watchdog_exception('sparkpost', $e);
  }

  // Let other modules do something on error.
  module_invoke_all('sparkpost_mailsend_error', $message_wrapper);
  return FALSE;
}

/**
 * Implements hook_cron_queue_info().
 */
function sparkpost_cron_queue_info() {
  $queues[SPARKPOST_QUEUE_NAME] = array(
    'worker callback' => 'sparkpost_mailsend',
    'time' => 60,
    'skip on cron' => variable_get('sparkpost_skip_cron', FALSE),
  );
  return $queues;
}

/**
 * Limit headers to SparkPost whitelist.
 *
 * @param array $headers
 *   Array of headers.
 *
 * @return array
 *   Array of headers.
 */
function sparkpost_allowed_headers($headers = array()) {
  foreach ($headers as $header => $value) {
    if (strpos($header, 'X-') === 0) {
      continue;
    }
    elseif (in_array($header, array(
      'Return-Path',
      'Cc',
    ))) {

      // Only Return-Path and Cc are supported.
      // Bcc recipients will be added to recipient list automatically and
      // removed from here.
      continue;
    }
    unset($headers[$header]);
  }
  return $headers;
}

/**
 * Implements hook_sparkpost_mailsend_error().
 */
function sparkpost_sparkpost_mailsend_error(SparkpostMessageWrapper $message_wrapper) {
  $e = $message_wrapper
    ->getApiResponseException();
  if ($e instanceof \SparkPost\APIResponseException) {
    $message_arguments = array(
      '%message' => $e
        ->getMessage(),
      '@code' => $e
        ->getCode(),
      '@api_code' => $e
        ->getAPICode(),
      '%api_message' => $e
        ->getAPIMessage(),
      '%api_description' => $e
        ->getAPIDescription(),
    );

    // Log error to watchdog.
    watchdog('sparkpost', 'Message could not be sent: @code: %message;  @api_code: %api_message %api_description', $message_arguments, WATCHDOG_ERROR);

    // In addition, if debug is on, dump message_wrapper as well.
    if (variable_get('sparkpost_debug', TRUE)) {
      $message_arguments = array(
        '!message_wrapper' => print_r($message_wrapper, TRUE),
      );
      watchdog('sparkpost', 'Debug: <pre>!message_wrapper</pre>', $message_arguments, WATCHDOG_DEBUG);
    }
  }
}

Functions

Namesort descending Description
sparkpost_allowed_headers Limit headers to SparkPost whitelist.
sparkpost_cron_queue_info Implements hook_cron_queue_info().
sparkpost_from Returns an array containing the from information for a Sparkpost message.
sparkpost_get_cc Get list of cc recipients.
sparkpost_get_to Helper to generate an array of recipients.
sparkpost_mail Implements hook_mail().
sparkpost_mailsend Sand mail using Guzzle and Sparkpost.
sparkpost_menu Implements hook_menu().
sparkpost_permission Implements hook_permission().
sparkpost_sparkpost_mailsend_error Implements hook_sparkpost_mailsend_error().
sparkpost_test_access Access callback for sending test email.

Constants

Namesort descending Description
SPARKPOST_EMAIL_REGEX @file Sparkpost integration.
SPARKPOST_QUEUE_NAME