mandrill.module in Mandrill 7
Same filename and directory in other branches
Enables Drupal to send email directly through Mandrill.
Overriding mail handling in Drupal to make Mandrill the default transport layer, requires to change the mail_system variable's default value array('default-system' => 'DefaultMailSystem'). This module uses array('default-system' => 'MailChimpMandrillMailSystem').
File
mandrill.moduleView source
<?php
/**
* @file
* Enables Drupal to send email directly through Mandrill.
*
* Overriding mail handling in Drupal to make Mandrill the default
* transport layer, requires to change the mail_system variable's
* default value array('default-system' => 'DefaultMailSystem').
* This module uses array('default-system' => 'MailChimpMandrillMailSystem').
*/
define('MANDRILL_QUEUE', 'mandrill_queue');
define('MANDRILL_EMAIL_REGEX', '/^\\s*(.+?)\\s*<\\s*([^>]+)\\s*>$/');
/**
* Implements hook_help().
*/
function mandrill_help($path, $arg) {
switch ($path) {
case 'admin/help#mandrill':
return t('Allow for site emails to be sent through Mandrill.');
}
}
/**
* Implements hook_menu().
*/
function mandrill_menu() {
$items = array();
$items['admin/config/services/mandrill'] = array(
'title' => 'Mandrill',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'mandrill_admin_settings',
),
'access arguments' => array(
'administer mandrill',
),
'description' => 'Send emails through the Mandrill transactional email service.',
'file' => 'mandrill.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/services/mandrill/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/config/services/mandrill/test'] = array(
'title' => 'Send test email',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'mandrill_test_form',
),
'access callback' => 'mandrill_test_access',
'description' => 'Send a test email using the Mandrill API.',
'file' => 'mandrill.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 mandrill_test_access() {
$a = user_access('administer mandrill');
$b = variable_get('mandrill_api_key');
return $a & !empty($b);
}
/**
* Implements hook_permission().
*/
function mandrill_permission() {
return array(
'administer mandrill' => array(
'title' => t('Administer Mandrill'),
'description' => t('Perform administration tasks for the Mandrill email service.'),
"restrict access" => TRUE,
),
);
}
/**
* Implements hook_cron_queue_info().
*/
function mandrill_cron_queue_info() {
$queues = array();
$queues[MANDRILL_QUEUE] = array(
'worker callback' => 'mandrill_queue_worker_mailsend',
'time' => variable_get('mandrill_queue_worker_timeout', 15),
);
return $queues;
}
/**
* Sends a queued email.
* @see mandrill_cron_queue_info()
*/
function mandrill_queue_worker_mailsend($data) {
// Send the message stored in the queue item.
mandrill_mailsend($data['message'], $data['function'], $data['args']);
}
/**
* Implements hook_mail().
*/
function mandrill_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.');
}
}
}
/**
* Abstracts sending of messages, allowing queueing option.
*
* @param array $message
* A message array formatted for Mandrill's sending API, plus 2 additional
* indexes for the send_function and an array of $args, if needed by the send
* function.
*
* @return bool
* TRUE if no exception thrown
*/
function mandrill_mailsend($message, $function, $args = array()) {
try {
if (!function_exists($function)) {
watchdog('mandrill', 'Error sending email from %from to %to. Function %function not found.', array(
'%from' => $message['from_email'],
'%to' => $message['to'],
'%function' => $function,
), WATCHDOG_ERROR);
return FALSE;
}
$params = array(
$message,
) + $args;
$results = call_user_func_array($function, $params);
foreach ($results as $result) {
// Allow other modules to react based on a send result.
module_invoke_all('mandrill_mailsend_result', $result);
switch ($result['status']) {
case "error":
case "invalid":
case "rejected":
$to = isset($result['email']) ? $result['email'] : 'recipient';
$status = isset($result['status']) ? $result['status'] : 'message';
$error_message = isset($result['message']) ? $result['message'] : 'no message';
watchdog('mandrill', 'Failed sending email from %from to %to. @status: @message', array(
'%from' => $message['from_email'],
'%to' => $to,
'@status' => $status,
'@message' => $error_message,
), WATCHDOG_ERROR);
return FALSE;
case "queued":
watchdog('mandrill', 'Email from %from to %to queued by Mandrill App.', array(
'%from' => $message['from_email'],
'%to' => $result['email'],
), WATCHDOG_INFO);
break;
}
}
return TRUE;
} catch (MandrillException $e) {
watchdog('mandrill', 'Error sending email from %from to %to. @code: @message', array(
'%from' => $message['from_email'],
'%to' => $message['to'],
'@code' => $e
->getCode(),
'@message' => $e
->getMessage(),
), WATCHDOG_ERROR);
return FALSE;
}
}
/**
* The actual function that calls the API send message.
*
* This is the default function used by mandrill_mailsend().
*
* @array $message
* Associative array containing message data.
*
* @return array
* Results of sending the message.
*
* @throws MandrillException
*/
function mandrill_sender_plain($message) {
if ($mailer = mandrill_get_api_object()) {
return $mailer
->messages_send($message);
}
else {
throw new MandrillException('Missing API key.');
}
}
/**
* Return Mandrill API object for communication with the mailchimp server.
*
* @param bool $reset
* Pass in TRUE to reset the statically cached object.
* @param string $classname
* The Mandrill class to use for sending emails. Passing a parameter allows
* the class used to be overridden, E.g., for tests.
*
* @throws MandrillException
*
* @return Mandrill|bool
* Mandrill Object upon success
* FALSE if variable_get('mandrill_api_key') is unset
*/
function mandrill_get_api_object($reset = FALSE, $classname = 'DrupalMandrill') {
$api =& drupal_static(__FUNCTION__, NULL);
if ($api === NULL || $reset === TRUE) {
$api_key = variable_get('mandrill_api_key', '');
$api_timeout = variable_get('mandrill_api_timeout', 60);
if (empty($api_key)) {
return FALSE;
}
$api = new $classname($api_key, $api_timeout);
}
return $api;
}
/**
* Display the names of the modules that are using Mailsystem.
*
* This is consistent with with Mailsystem's display. In the future, if
* Mailsystem were to provide an API for their labeling, that should be used.
*
* @return array
* Array of all module names indexing to their "display" names,
* and some special items for non-module values like null, default-system,
* and some clarification talked onto the end of the Mandrill module's name.
*/
function mandrill_get_module_key_names() {
$name_array = array(
'' => '--none--',
'default-system' => "Site-wide default",
);
$descriptions = array();
foreach (system_rebuild_module_data() as $item) {
if ($item->status) {
$descriptions[$item->name] = (empty($item->info['package']) ? '' : $item->info['package']) . ' » ' . t('!module module', array(
'!module' => $item->info['name'],
));
}
}
asort($descriptions);
$mailsystem_settings = mailsystem_get();
unset($mailsystem_settings['default-system']);
foreach ($mailsystem_settings as $id => $class) {
// Separate $id into $module and $key.
$module = $id;
while ($module && empty($descriptions[$module])) {
// Remove a key from the end.
$module = implode('_', explode('_', $module, -1));
}
// If an array key of the $mail_system variable is neither "default-system"
// nor begins with a module name, then it should be unset.
if (empty($module)) {
// This shouldn't happen.
}
// Set $title to the human-readable module name.
$title = preg_replace('/^.* » /', '', $descriptions[$module]);
if ($key = substr($id, strlen($module) + 1)) {
$title .= " ({$key} key)";
}
$name_array[$id] = $title;
}
return $name_array;
}
/**
* Get a list of mandrill template objects.
*
* @return array
* An of available templates with complete data or NULL if none are available.
*/
function mandrill_get_templates() {
// Only show the template settings if the mandrill api can be called.
$templates = NULL;
try {
$mailer = mandrill_get_api_object();
$templates = $mailer
->templates_list();
} catch (MandrillException $e) {
drupal_set_message(t('Mandrill: %message', array(
'%message' => check_plain($e
->getMessage()),
)), 'error');
watchdog_exception('mandrill', $e);
}
return $templates;
}
/**
* Get a list of subaccounts.
*/
function mandrill_get_subaccounts() {
$subaccounts = array();
try {
$mandrill = mandrill_get_api_object();
$subaccounts = $mandrill
->subaccounts();
} catch (MandrillException $e) {
drupal_set_message(t('Mandrill: %message', array(
'%message' => check_plain($e
->getMessage()),
)), 'error');
watchdog_exception('mandrill', $e);
}
return $subaccounts;
}
/**
* Helper to return a comma delimited list of mail keys to not log content for.
*
* @return string
* a comma delimited list of mail keys
*/
function mandrill_mail_key_blacklist() {
return variable_get('mandrill_mail_key_blacklist', 'user_password_reset');
}
/**
* 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 mandrill_get_to($to) {
$recipients = array();
$to_array = explode(',', $to);
foreach ($to_array as $email) {
if (preg_match(MANDRILL_EMAIL_REGEX, $email, $matches)) {
$recipients[] = array(
'email' => $matches[2],
'name' => $matches[1],
);
}
else {
$recipients[] = array(
'email' => $email,
);
}
}
return $recipients;
}
/**
* Determine if mail should be processed asynchronously.
*
* @return bool
* True if asyncronous processing is enabled
*/
function mandrill_process_async() {
return variable_get('mandrill_process_async', FALSE);
}
/**
* Returns an array containing the from information for a Mandrill message.
*
* @return array
* array(
* 'email' => 'admin@example.com',
* 'name' => 'My Site',
* )
*/
function mandrill_from() {
$default_from = variable_get('site_mail', ini_get('sendmail_from'));
$email = variable_get('mandrill_from', $default_from);
$name = variable_get('mandrill_from_name', variable_get('site_name'));
return array(
'email' => $email,
'name' => $name,
);
}
Functions
Name | Description |
---|---|
mandrill_cron_queue_info | Implements hook_cron_queue_info(). |
mandrill_from | Returns an array containing the from information for a Mandrill message. |
mandrill_get_api_object | Return Mandrill API object for communication with the mailchimp server. |
mandrill_get_module_key_names | Display the names of the modules that are using Mailsystem. |
mandrill_get_subaccounts | Get a list of subaccounts. |
mandrill_get_templates | Get a list of mandrill template objects. |
mandrill_get_to | Helper to generate an array of recipients. |
mandrill_help | Implements hook_help(). |
mandrill_mail | Implements hook_mail(). |
mandrill_mailsend | Abstracts sending of messages, allowing queueing option. |
mandrill_mail_key_blacklist | Helper to return a comma delimited list of mail keys to not log content for. |
mandrill_menu | Implements hook_menu(). |
mandrill_permission | Implements hook_permission(). |
mandrill_process_async | Determine if mail should be processed asynchronously. |
mandrill_queue_worker_mailsend | Sends a queued email. |
mandrill_sender_plain | The actual function that calls the API send message. |
mandrill_test_access | Access callback for sending test email. |
Constants
Name | Description |
---|---|
MANDRILL_EMAIL_REGEX | |
MANDRILL_QUEUE | @file Enables Drupal to send email directly through Mandrill. |