407 lines
11 KiB
Plaintext
407 lines
11 KiB
Plaintext
<?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,
|
|
);
|
|
}
|