updated mailgun, mailsystem, honeypot, googleanalitycs, features, content_taxonomy

This commit is contained in:
2019-05-13 17:55:28 +02:00
parent 2ffad14939
commit e08a2639c6
54 changed files with 1911 additions and 423 deletions

View File

@@ -0,0 +1 @@
Mailgun module documentation is here: https://www.drupal.org/node/2547591.

View File

@@ -0,0 +1,12 @@
{
"name": "drupal/mailgun",
"description": "Provides integration with the Mailgun PHP library.",
"type": "drupal-module",
"homepage": "https://www.drupal.org/project/mailgun",
"license": "GPL-2.0+",
"require": {
"guzzlehttp/psr7": "~1.3",
"php-http/guzzle6-adapter": "^1.0",
"mailgun/mailgun-php": "~2.0"
}
}

View File

@@ -16,11 +16,12 @@
* @return array
* An array containing form items to place on the module settings page.
*/
function mailgun_admin_settings($form, &$form_state) {
$library = libraries_detect('mailgun');
if (!$library['installed']) {
drupal_set_message(t('The Mailgun PHP library is not installed. Please see <a href="@url">documentation</a> for more information.', array('@url' => url('https://www.drupal.org/node/2547591'))), 'error');
function mailgun_admin_settings(array $form, array &$form_state) {
// Check if the Mailgun PHP library is installed.
if (!mailgun_check_library()) {
drupal_set_message(t('The Mailgun PHP library is not installed. Please see Installation section in the !link.', array(
'!link' => l(t('documentation'), MAILGUN_DOCUMENTATION_LINK),
)), 'error');
}
$key = variable_get('mailgun_api_key', '');
@@ -28,7 +29,9 @@ function mailgun_admin_settings($form, &$form_state) {
$form['mailgun_api_key'] = array(
'#title' => t('Mailgun API key'),
'#type' => 'textfield',
'#description' => t('Get your Secret API key from the <a href="@url">Mailgun dashboard</a>.', array('@url' => url('https://mailgun.com/app/dashboard'))),
'#description' => t('Get your Secret API key from the !link.', array(
'!link' => l(t('Mailgun dashboard'), MAILGUN_DASHBOARD_LINK),
)),
'#default_value' => $key,
'#required' => TRUE,
);
@@ -37,23 +40,25 @@ function mailgun_admin_settings($form, &$form_state) {
if (!empty($key)) {
try {
$client = mailgun_get_client($key);
} catch (Exception $e) {
watchdog('mailgun', 'An exception occurred. @code: @message', array('@code' => $e->getCode(), '@message' => $e->getMessage()), WATCHDOG_WARNING, 'admin/config/system/mailgun');
}
catch (Exception $e) {
watchdog('mailgun', 'An exception occurred. @code: @message', array(
'@code' => $e->getCode(),
'@message' => $e->getMessage(),
), WATCHDOG_WARNING, MAILGUN_ADMIN_PAGE);
drupal_set_message(t('Mailgun: %message', array('%message' => $e->getMessage())), 'error');
}
}
// Display settings only when a valid API key is present and client is active
// Display settings only when a valid API key is present and client is active.
if ($client) {
$domain_options = array(
'_sender' => t('Get domain from sender address'),
);
$domains = array();
$result = $client->get('domains');
if ($result && $result->http_response_code == 200) {
foreach ($result->http_response_body->items as $domain) {
$domains[$domain->name] = $domain;
$domain_options[$domain->name] = $domain->name;
$result = $client->domains()->index();
if (!empty($result)) {
foreach ($result->getDomains() as $domain) {
$domain_options[$domain->getName()] = $domain->getName();
}
}
@@ -61,7 +66,7 @@ function mailgun_admin_settings($form, &$form_state) {
'#title' => t('Domain'),
'#type' => 'select',
'#options' => $domain_options,
'#description' => t('Mails will be sent using this domain'),
'#description' => t('Mails will be sent using this domain.'),
'#default_value' => variable_get('mailgun_domain', '_sender'),
);
@@ -69,31 +74,70 @@ function mailgun_admin_settings($form, &$form_state) {
'#title' => t('Test mode'),
'#type' => 'checkbox',
'#default_value' => variable_get('mailgun_test', FALSE),
'#description' => t('Enables sending in test mode'),
);
$form['mailgun_queue'] = array(
'#title' => t('Queue mails'),
'#type' => 'checkbox',
'#description' => t('Mails will be queued and sent during cron runs. Useful for sending a large number of emails.'),
'#default_value' => variable_get('mailgun_queue', FALSE),
'#description' => t('Mailgun will accept the message but will not send it. This is useful for testing purposes.'),
);
$form['mailgun_log'] = array(
'#title' => t('Log mails'),
'#type' => 'checkbox',
'#description' => t('Log mails sent through Mailgun. Should not be enabled on production sites. Messages fail to send will be logged regardless of this setting.'),
'#description' => t('Log all mails sent through Mailgun. Messages fail to send will be logged regardless of this setting.'),
'#default_value' => variable_get('mailgun_log', FALSE),
);
$form['extra'] = array(
'#type' => 'fieldset',
'#title' => t('Additional settings'),
'#description' => t('These default settings apply to messages sent using Mailgun and may be overriden on a per-message basis.'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
// We have the same options for all settings.
$options = array(
'default' => t('Use default setting'),
'enabled' => t('Enabled'),
'disabled' => t('Disabled'),
);
$form['extra']['tracking'] = array(
'#type' => 'fieldset',
'#title' => t('Tracking'),
);
$form['extra']['tracking']['mailgun_tracking'] = array(
'#title' => t('Enable tracking'),
'#type' => 'select',
'#options' => $options,
'#description' => t('Whether to enable event tracking by default or not. See !link for details.', array(
'!link' => l(t('Tracking Messages'), 'https://documentation.mailgun.com/user_manual.html#tracking-messages'),
)),
'#default_value' => variable_get('mailgun_tracking', 'default'),
);
$form['extra']['tracking']['mailgun_tracking_clicks'] = array(
'#title' => t('Enable click tracking'),
'#type' => 'select',
'#options' => $options,
'#description' => t('Whether to enable click tracking by default or not.'),
'#default_value' => variable_get('mailgun_tracking_clicks', 'default'),
);
$form['extra']['tracking']['mailgun_tracking_opens'] = array(
'#title' => t('Enable open tracking'),
'#type' => 'select',
'#options' => $options,
'#description' => t('Whether to enable open tracking by default or not.'),
'#default_value' => variable_get('mailgun_tracking_opens', 'default'),
);
$formats = array('_none' => t('- None -'));
foreach (filter_formats() as $format) {
if ($format->format == 'php_code') {
if ($format->format === 'php_code') {
continue;
}
$formats[$format->format] = t($format->name);
$formats[$format->format] = $format->name;
}
$form['mailgun_format'] = array(
$form['extra']['mailgun_format'] = array(
'#title' => t('Text format'),
'#type' => 'select',
'#description' => t('Specify an additional text format to filter the message through before sending the email.'),
@@ -101,36 +145,24 @@ function mailgun_admin_settings($form, &$form_state) {
'#default_value' => variable_get('mailgun_format', '_none'),
);
$form['defaults'] = array(
'#type' => 'fieldset',
'#title' => t('Default settings'),
'#description' => t('These default settings apply to messages sent using Mailgun and may be overriden on a per-message basis.'),
'#collapsible' => FALSE,
'#collapsed' => FALSE,
$form['extra']['mailgun_queue'] = array(
'#title' => t('Queue mails'),
'#type' => 'checkbox',
'#description' => t('Mails will be queued and sent during cron runs. Useful for sending a large number of emails.'),
'#default_value' => variable_get('mailgun_queue', FALSE),
);
$form['defaults']['mailgun_tracking'] = array(
'#title' => t('Enable tracking'),
'#type' => 'select',
'#options' => array('default' => t('Use default setting'), 'enabled' => t('Enabled'), 'disabled' => t('Disabled')),
'#description' => t('Whether to enable event tracking by default or not. See <a href="@url">Tracking Messages</a> for details.', array('@url' => url('https://documentation.mailgun.com/user_manual.html#tracking-messages'))),
'#default_value' => variable_get('mailgun_tracking', 'default'),
);
$form['defaults']['mailgun_tracking_clicks'] = array(
'#title' => t('Enable click tracking'),
'#type' => 'select',
'#options' => array('default' => t('Use default setting'), 'enabled' => t('Enabled'), 'disabled' => t('Disabled')),
'#description' => t('Whether to enable click tracking by default or not.'),
'#default_value' => variable_get('mailgun_tracking_clicks', 'default'),
);
$form['defaults']['mailgun_tracking_opens'] = array(
'#title' => t('Enable open tracking'),
'#type' => 'select',
'#options' => array('default' => t('Use default setting'), 'enabled' => t('Enabled'), 'disabled' => t('Disabled')),
'#description' => t('Whether to enable open tracking by default or not.'),
'#default_value' => variable_get('mailgun_tracking_opens', 'default'),
$form['extra']['mailgun_tagging_mailkey'] = array(
'#type' => 'checkbox',
'#title' => t('Enable tags by mail key'),
'#description' => t('See !url for details.', array(
'!url' => l(t('Tagging'), 'https://documentation.mailgun.com/user_manual.html#tagging', array(
'attributes' => array(
'onclick' => "target='_blank'",
),
)),
)),
'#default_value' => variable_get('mailgun_tagging_mailkey', TRUE),
);
}
@@ -150,11 +182,21 @@ function mailgun_admin_settings_validate($form, &$form_state) {
// The API key has changed. Perform validation.
$form_state['values']['mailgun_api_key'] = trim($form_state['values']['mailgun_api_key']);
$client = mailgun_get_client($form_state['values']['mailgun_api_key']);
if ($client === FALSE) {
drupal_set_message(t('Could not connect to Mailgun API. Please check your settings'), 'warning');
return;
}
try {
$result = $client->get('domains');
$client->domains()->index();
drupal_set_message(t('Your API key has been successfully validated.'));
} catch (Exception $e) {
form_set_error('mailgun_api_key', t('An exception occurred. @code: @message', array('@code' => $e->getCode(), '@message' => $e->getMessage())));
}
catch (Exception $e) {
form_set_error('mailgun_api_key', t('An exception occurred. @code: @message', array(
'@code' => $e->getCode(),
'@message' => $e->getMessage(),
)));
}
}
}
@@ -173,9 +215,11 @@ function mailgun_test_form($form, &$form_state) {
'#required' => TRUE,
);
$message = "Howdy!\n\nIf this e-mail is displayed correctly and delivered sound and safe, congrats! You have successfully configured Mailgun.";
$message .= ' Visit the <a href="@project">project page</a> to contribute or read <a href="@documentation">documentation</a> to learn more.';
$message = t($message, array('@project' => url('https://www.drupal.org/project/mailgun'), '@documentation' => url('https://www.drupal.org/node/2547591')));
$message = "Howdy!\n\nIf this e-mail is displayed correctly and delivered sound and safe, congrats! You have successfully configured Mailgun. ";
$message .= t('Visit the !project to contribute or read !documentation to learn more.', array(
'!project' => l(t('project page'), 'https://www.drupal.org/project/mailgun'),
'!documentation' => l(t('documentation'), MAILGUN_DOCUMENTATION_LINK),
));
$form['message'] = array(
'#type' => 'textarea',
'#title' => t('Message'),
@@ -196,7 +240,7 @@ function mailgun_test_form($form, &$form_state) {
);
$form['cancel'] = array(
'#type' => 'link',
'#href' => 'admin/config/system/mailgun',
'#href' => MAILGUN_ADMIN_PAGE,
'#title' => t('Cancel'),
);
@@ -205,17 +249,26 @@ function mailgun_test_form($form, &$form_state) {
/**
* Form submission handler for mailgun_test_form().
*
* Send the test e-mail.
*/
function mailgun_test_form_submit($form, &$form_state) {
$to = $form_state['values']['to'];
$body = explode('\n', $form_state['values']['message']);
$params = array(
'message' => $form_state['values']['message'],
'message' => $body,
'attachment' => $form_state['values']['attachment'],
);
$site_name = variable_get('site_name', '');
$default_from = variable_get('site_mail', ini_get('sendmail_from'));
$from = (!empty($site_name)) ? $site_name . ' <' . $default_from . '>' : $default_from;
$result = drupal_mail('mailgun', 'test', $to, $GLOBALS['language'], $params, $from);
drupal_set_message(t('Test email sent from %from to %to. If you have the "Log mails" setting enabled, check the <a href="@url">database log</a> for details.', array('%from' => $result['from'], '%to' => $result['to'], '@url' => url('admin/reports/dblog'))), 'status');
drupal_set_message(t('Test email sent from %from to %to. If you have the "Log mails" setting enabled, check the <a href="@url">database log</a> for details.',
array(
'%from' => $result['from'],
'%to' => $result['to'],
'@url' => url('admin/reports/dblog'),
)), 'status');
}

View File

@@ -1,16 +1,17 @@
package = Mail
name = Mailgun
description = "Provides integration with Mailgun's email sending API."
core = 7.x
package = Mailgun
dependencies[] = libraries
dependencies[] = mailsystem
php = 5.5
configure = admin/config/system/mailgun
files[] = mailgun.mail.inc
; Information added by Drupal.org packaging script on 2016-06-26
version = "7.x-1.6+0-dev"
dependencies[] = mailsystem (>=2.x)
; Information added by Drupal.org packaging script on 2017-12-06
version = "7.x-1.6"
core = "7.x"
project = "mailgun"
datestamp = "1466914444"
datestamp = "1512586085"

View File

@@ -1,6 +1,5 @@
<?php
/**
* @file
* Install, update and uninstall functions for the Mailgun module.
@@ -11,7 +10,19 @@
*/
function mailgun_uninstall() {
// Delete variables.
$variables = array('mailgun_api_key', 'mailgun_from_action', 'mailgun_from_name', 'mailgun_from_mail', 'mailgun_tracking', 'mailgun_tracking_clicks', 'mailgun_tracking_opens', 'mailgun_queue', 'mailgun_log', 'mailgun_format');
$variables = array(
'mailgun_api_key',
'mailgun_from_action',
'mailgun_from_name',
'mailgun_from_mail',
'mailgun_tracking',
'mailgun_tracking_clicks',
'mailgun_tracking_opens',
'mailgun_queue',
'mailgun_log',
'mailgun_format',
'mailgun_tagging_mailkey',
);
foreach ($variables as $variable) {
variable_del($variable);
}
@@ -32,3 +43,28 @@ function mailgun_disable() {
mailsystem_clear(array('mailgun_test' => 'MailgunMailSystem'));
watchdog('mailgun', 'Mailgun has been disabled.');
}
/**
* Implements hook_requirements().
*/
function mailgun_requirements($phase) {
// Ensure translations don't break during installation.
$t = get_t();
$requirements = array();
if ($phase === 'runtime') {
$requirements['mailgun']['title'] = $t('Mailgun');
if (mailgun_check_library()) {
$requirements['mailgun']['value'] = $t('The Mailgun library is installed correctly.');
$requirements['mailgun']['severity'] = REQUIREMENT_OK;
}
else {
$requirements['mailgun']['value'] = $t('The Mailgun library has not been installed correctly.');
$requirements['mailgun']['severity'] = REQUIREMENT_ERROR;
}
}
return $requirements;
}

View File

@@ -2,14 +2,14 @@
/**
* @file
* Implements Mailgun as a Drupal MailSystemInterface
* Implements Mailgun as a Drupal MailSystemInterface.
*/
/**
* Modify the Drupal mail system to use Mailgun when sending e-mails.
*/
class MailgunMailSystem implements MailSystemInterface {
/**
* Concatenate and wrap the e-mail body for either plain-text or HTML e-mails.
*
@@ -25,26 +25,34 @@ class MailgunMailSystem implements MailSystemInterface {
$message['body'] = implode("\n\n", $message['body']);
}
// If a text format is specified in Mailgun settings, run the message through it.
// Run the message through text format if specified in Mailgun settings.
$format = variable_get('mailgun_format', '_none');
if ($format != '_none') {
if ($format !== '_none') {
$message['body'] = check_markup($message['body'], $format);
}
// Wrap body with theme function.
$message['body'] = theme('mailgun_message', array(
'subject' => $message['subject'],
'body' => $message['body'],
'message' => $message,
));
return $message;
}
/**
* Send the e-mail message.
*
* @see drupal_mail()
* @see https://documentation.mailgun.com/api-sending.html#sending
*
* @param array $message
* A message array, as described in hook_mail_alter(). $message['params'] may contain additional parameters. See mailgun_send().
* A message array, as described in hook_mail_alter(). $message['params']
* may contain additional parameters. See mailgun_send().
*
* @return bool
* TRUE if the mail was successfully accepted or queued, FALSE otherwise.
*
* @see drupal_mail()
* @see https://documentation.mailgun.com/api-sending.html#sending
*/
public function mail(array $message) {
// Build the Mailgun message array.
@@ -52,7 +60,7 @@ class MailgunMailSystem implements MailSystemInterface {
'from' => $message['from'],
'to' => $message['to'],
'subject' => $message['subject'],
'text' => check_plain($message['body']),
'text' => drupal_html_to_text($message['body']),
'html' => $message['body'],
);
@@ -72,23 +80,32 @@ class MailgunMailSystem implements MailSystemInterface {
$params = array();
// Populate default settings.
if ($variable = variable_get('mailgun_tracking', 'default') != 'default') {
$params['o:tracking'] = $variable;
if (($variable = variable_get('mailgun_tracking', 'default')) !== 'default') {
$params['o:tracking'] = ($variable === 'enabled');
}
if ($variable = variable_get('mailgun_tracking_clicks', 'default') != 'default') {
$params['o:tracking-clicks'] = $variable;
if (($variable = variable_get('mailgun_tracking_clicks', 'default')) !== 'default') {
$params['o:tracking-clicks'] = ($variable === 'enabled');
}
if ($variable = variable_get('mailgun_tracking_opens', 'default') != 'default') {
$params['o:tracking-opens'] = $variable;
if (($variable = variable_get('mailgun_tracking_opens', 'default')) !== 'default') {
$params['o:tracking-opens'] = ($variable === 'enabled');
}
// For a full list of allowed parameters, see: https://documentation.mailgun.com/api-sending.html#sending.
$allowed_params = array('o:tag', 'o:campaign', 'o:deliverytime', 'o:dkim', 'o:testmode', 'o:tracking', 'o:tracking-clicks', 'o:tracking-opens');
// For a full list of allowed parameters,
// see: https://documentation.mailgun.com/api-sending.html#sending.
$allowed_params = array(
'o:tag',
'o:campaign',
'o:deliverytime',
'o:dkim',
'o:testmode',
'o:tracking',
'o:tracking-clicks',
'o:tracking-opens',
);
foreach ($message['params'] as $key => $value) {
// Check if it's one of the known parameters.
$allowed = (in_array($key, $allowed_params)) ? TRUE : FALSE;
// If more options become available but are not yet supported by the module, uncomment the following line.
//$allowed = (substr($key, 0, 2) == 'o:') ? TRUE : FALSE;
$allowed = in_array($key, $allowed_params) ? TRUE : FALSE;
if ($allowed) {
$params[$key] = $value;
}
@@ -96,14 +113,51 @@ class MailgunMailSystem implements MailSystemInterface {
if (substr($key, 0, 2) == 'h:' || substr($key, 0, 2) == 'v:') {
$params[$key] = $value;
}
// Add additional HIME headers, like Reply-to if it exists.
if ($key === 'headers' && is_array($value)) {
foreach ($value as $headers_key => $headers_value) {
$params['h:' . $headers_key] = $headers_value;
}
}
}
// Add default tags by mail key if enabled.
if (variable_get('mailgun_tagging_mailkey', TRUE)) {
$params['o:tag'][] = $message['id'];
}
// Make sure the files provided in the attachments array exist.
if (!empty($message['params']['attachments'])) {
$params['attachments'] = array();
$params['attachment'] = array();
foreach ($message['params']['attachments'] as $attachment) {
if (file_exists($attachment)) {
$params['attachments'][] = $attachment;
if (is_array($attachment)) {
// `filecontent` attachment key can be used by MimeMail as data
// of the related file.
if (array_key_exists('filecontent', $attachment)) {
$temp_file = tmpfile();
fwrite($temp_file, $attachment['filecontent']);
$temp_f_meta_data = stream_get_meta_data($temp_file);
$_attachment = array(
'filePath' => $temp_f_meta_data['uri'],
);
if (array_key_exists('filename', $attachment)) {
$_attachment['remoteName'] = $attachment['filename'];
}
$params['attachment'][] = $_attachment;
}
elseif (array_key_exists('filepath', $attachment) && file_exists($attachment['filepath'])) {
$_attachment = array(
'filePath' => $attachment['filepath'],
);
if (array_key_exists('filename', $attachment)) {
$_attachment['remoteName'] = $attachment['filename'];
}
$params['attachment'][] = $_attachment;
}
}
elseif (file_exists($attachment)) {
$params['attachment'][] = $attachment;
}
}
}

View File

@@ -5,13 +5,19 @@
* Provides integration with Mailgun's email sending API.
*/
use Mailgun\Mailgun;
define('MAILGUN_DOCUMENTATION_LINK', 'https://www.drupal.org/node/2547591');
define('MAILGUN_DASHBOARD_LINK', 'https://mailgun.com/app/dashboard');
define('MAILGUN_ADMIN_PAGE', 'admin/config/services/mailgun');
/**
* Implements hook_menu().
*/
function mailgun_menu() {
$items = array();
$items['admin/config/system/mailgun'] = array(
$items[MAILGUN_ADMIN_PAGE] = array(
'title' => 'Mailgun',
'description' => 'Configure Mailgun settings.',
'page callback' => 'drupal_get_form',
@@ -19,12 +25,12 @@ function mailgun_menu() {
'access arguments' => array('administer mailgun'),
'file' => 'mailgun.admin.inc',
);
$items['admin/config/system/mailgun/settings'] = array(
$items[MAILGUN_ADMIN_PAGE . '/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/config/system/mailgun/test'] = array(
$items[MAILGUN_ADMIN_PAGE . '/test'] = array(
'title' => 'Send test email',
'page callback' => 'drupal_get_form',
'page arguments' => array('mailgun_test_form'),
@@ -46,7 +52,25 @@ function mailgun_permission() {
'administer mailgun' => array(
'title' => t('Administer Mailgun'),
'description' => t('Perform administration tasks for the Mailgun e-mail sending service.'),
"restrict access" => TRUE,
'restrict access' => TRUE,
),
);
}
/**
* Implements hook_theme().
*/
function mailgun_theme($existing, $type, $theme, $path) {
return array(
'mailgun_message' => array(
'variables' => array(
'subject' => NULL,
'body' => NULL,
'message' => array(),
),
'template' => 'mailgun-message',
'path' => drupal_get_path('module', 'mailgun') . '/templates',
'mail theme' => TRUE,
),
);
}
@@ -56,12 +80,13 @@ function mailgun_permission() {
*/
function mailgun_help($path, $arg) {
switch ($path) {
case 'admin/config/system/mailgun':
return '<p>' . t('See <a href="@url">documentation</a> for instructions on installing and configuring Mailgun.', array('@url' => url('https://www.drupal.org/node/2547591'))) . '</p>';
break;
case 'admin/config/system/mailgun/test':
case MAILGUN_ADMIN_PAGE:
return '<p>' . t('See !link for instructions on installing and configuring Mailgun.', array(
'!link' => l(t('documentation'), MAILGUN_DOCUMENTATION_LINK),
)) . '</p>';
case MAILGUN_ADMIN_PAGE . '/test':
return '<p>' . t('Use this form to send a test e-mail to ensure you have correctly configured Mailgun.') . '</p>';
break;
}
}
@@ -98,14 +123,17 @@ function mailgun_mail($key, &$message, $params) {
function mailgun_libraries_info() {
$libraries['mailgun'] = array(
'name' => 'Mailgun PHP library',
'vendor url' => 'https://documentation.mailgun.com/wrappers.html#php',
'download url' => 'https://github.com/mailgun/mailgun-php/archive/v1.7.2.zip',
'path' => 'vendor',
'vendor url' => 'https://documentation.mailgun.com/en/latest/libraries.html#php',
'download url' => 'https://github.com/mailgun/mailgun-php',
'version arguments' => array(
'file' => 'src/Mailgun/Constants/Constants.php',
// const SDK_VERSION = "1.7";
'pattern' => '/const SDK_VERSION = \"((\d+)\.(\d+))\";/',
'file' => 'vendor/mailgun/mailgun-php/CHANGELOG.md',
'pattern' => '/##\W+((\d+)\.(\d+))/',
),
// Path to the 'autoload.php' created by Composer.
'path' => 'vendor',
'files' => array(
'php' => array('autoload.php'),
),
@@ -114,28 +142,77 @@ function mailgun_libraries_info() {
return $libraries;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function mailgun_form_libraries_admin_library_status_form_alter(&$form, &$form_state, $form_id) {
$library = drupal_array_get_nested_value($form_state, array(
'build_info', 'args', 0,
));
if (empty($library['machine name']) || $library['machine name'] !== 'mailgun') {
return;
}
// Libraries module provides own instruction "How to install the library".
// We override it because this instruction is not correct and may confuse.
$form['instructions'] = array(
'#markup' => t('The Mailgun PHP library is not installed. Please see Installation section in the !link.', array(
'!link' => l(t('documentation'), MAILGUN_DOCUMENTATION_LINK),
)),
);
}
/**
* Get the Mailgun client to access Mailgun's endpoints.
*
* @param string $key
* The Mailgun API key. Leave empty to use the API key saved in database.
*
* @return \Mailgun\Mailgun
* Mailgun object.
*/
function mailgun_get_client($key = '') {
// Check if the Mailgun PHP library is installed.
$library = libraries_load('mailgun');
if (!$library['installed']) {
watchdog('mailgun', 'Mailgun client initialization failed: Unable to load the Mailgun PHP library.', NULL, WATCHDOG_ERROR);
if (!mailgun_check_library()) {
watchdog('mailgun', 'Mailgun client initialization failed: Unable to load the Mailgun PHP library.', array(), WATCHDOG_ERROR);
return FALSE;
}
$key = (empty($key)) ? variable_get('mailgun_api_key', '') : $key;
if (empty($key)) {
watchdog('mailgun', 'Mailgun client initialization failed: Missing API key.', NULL, WATCHDOG_ERROR);
watchdog('mailgun', 'Mailgun client initialization failed: Missing API key.', array(), WATCHDOG_ERROR);
return FALSE;
}
$client = new \Mailgun\Mailgun($key);
return $client;
return Mailgun::create($key);
}
/**
* Detect if Mailgun library is installed.
*
* @return bool
* TRUE if library is installed, FALSE otherwise.
*/
function mailgun_check_library() {
if (module_exists('libraries')) {
libraries_load('mailgun');
}
if (method_exists('\Mailgun\Mailgun', 'create')) {
return TRUE;
}
return FALSE;
}
/**
* Prepares variables for mailgun-message.tpl.php.
*
* Adds id/module/key-specific hook suggestions.
*
* @see templates/mailgun-message.tpl.php
*/
function template_preprocess_mailgun_message(&$variables) {
$variables['theme_hook_suggestions'][] = 'mailgun_message__' . $variables['message']['id'];
$variables['theme_hook_suggestions'][] = 'mailgun_message__' . $variables['message']['module'];
$variables['theme_hook_suggestions'][] = 'mailgun_message__' . $variables['message']['key'];
}
/**
@@ -146,31 +223,50 @@ function mailgun_get_client($key = '') {
* - from: The e-mail addressthe message will be sent from.
* - to: The e-mail addressthe message will be sent to.
* - subject: The subject of the message.
* - text: The plain-text version of the message. Processed using check_plain().
* - text: The plain-text version of the message. Processed using
* drupal_html_to_text().
* - html: The original message content. May contain HTML tags.
* - cc: One or more carbon copy recipients. If multiple, separate with commas.
* - bcc: One or more blind carbon copy recipients. If multiple, separate with commas.
* - o:tag: An array containing the tags to add to the message. See: https://documentation.mailgun.com/user_manual.html#tagging.
* - o:campaign: The campaign ID this message belongs to. See: https://documentation.mailgun.com/user_manual.html#um-campaign-analytics.
* - o:deliverytime: Desired time of delivery. Messages can be scheduled for a maximum of 3 days in the future. See: https://documentation.mailgun.com/api-intro.html#date-format.
* - o:dkim: Boolean indicating whether or not to enable DKIM signatures on per-message basis.
* - o:testmode: Boolean indicating whether or not to enable test mode. See: https://documentation.mailgun.com/user_manual.html#manual-testmode.
* - o:tracking: Boolean indicating whether or not to toggle tracking on a per-message basis. See: https://documentation.mailgun.com/user_manual.html#tracking-messages.
* - o:tracking-clicks: Boolean or string "htmlonly" indicating whether or not to toggle clicks tracking on a per-message basis. Has higher priority than domain-level setting.
* - o:tracking-opens: Boolean indicating whether or not to toggle clicks tracking on a per-message basis. Has higher priority than domain-level setting.
* - h:X-My-Header: h: prefix followed by an arbitrary value allows to append a custom MIME header to the message (X-My-Header in this case). For example, h:Reply-To to specify Reply-To address.
* - v:my-var: v: prefix followed by an arbitrary name allows to attach a custom JSON data to the message. See: https://documentation.mailgun.com/user_manual.html#manual-customdata.
* - cc: One or more carbon copy recipients. If multiple, separate with
* commas.
* - bcc: One or more blind carbon copy recipients. If multiple, separate
* with commas.
* - o:tag: An array containing the tags to add to the message.
* See: https://documentation.mailgun.com/user_manual.html#tagging.
* - o:campaign: The campaign ID this message belongs to.
* https://documentation.mailgun.com/user_manual.html#um-campaign-analytics
* - o:deliverytime: Desired time of delivery. Messages can be scheduled for
* a maximum of 3 days in the future.
* See: https://documentation.mailgun.com/api-intro.html#date-format.
* - o:dkim: Boolean indicating whether or not to enable DKIM signatures on
* per-message basis.
* - o:testmode: Boolean indicating whether or not to enable test mode.
* See: https://documentation.mailgun.com/user_manual.html#manual-testmode.
* - o:tracking: Boolean indicating whether or not to toggle tracking on a
* per-message basis.
* See: https://documentation.mailgun.com/user_manual.html#tracking-messages.
* - o:tracking-clicks: Boolean or string "htmlonly" indicating whether or
* not to toggle clicks tracking on a per-message basis. Has higher
* priority than domain-level setting.
* - o:tracking-opens: Boolean indicating whether or not to toggle clicks
* tracking on a per-message basis. Has higher priority than domain-level
* setting.
* - h:X-My-Header: h: prefix followed by an arbitrary value allows to append
* a custom MIME header to the message (X-My-Header in this case).
* For example, h:Reply-To to specify Reply-To address.
* - v:my-var: v: prefix followed by an arbitrary name allows to attach a
* custom JSON data to the message.
* See: https://documentation.mailgun.com/user_manual.html#manual-customdata.
*
* @return bool
* TRUE if the mail was successfully accepted, FALSE otherwise.
*/
function mailgun_send($mailgun_message) {
function mailgun_send(array $mailgun_message) {
$client = mailgun_get_client();
if (!$client) {
return FALSE;
}
// Test mode
// Test mode. Mailgun will accept the message but will not send it.
if (variable_get('mailgun_test', FALSE)) {
$mailgun_message['o:testmode'] = 'yes';
}
@@ -179,35 +275,43 @@ function mailgun_send($mailgun_message) {
$mailgun_message += $mailgun_message['params'];
unset($mailgun_message['params']);
if (variable_get('mailgun_domain', '_sender') == '_sender') {
// Extract the domain from the sender's email address. Use regular expression to check since it could be either a plain email address or in the form "Name <example@example.com>".
if (variable_get('mailgun_domain', '_sender') === '_sender') {
// Extract the domain from the sender's email address.
// Use regular expression to check since it could be either a plain email
// address or in the form "Name <example@example.com>".
$tokens = (preg_match('/^\s*(.+?)\s*<\s*([^>]+)\s*>$/', $mailgun_message['from'], $matches) === 1) ? explode('@', $matches[2]) : explode('@', $mailgun_message['from']);
$mail_domain = array_pop($tokens);
// Retrieve a list of available domains first.
$domains = array();
try {
$result = $client->get('domains');
if ($result->http_response_code == 200) {
foreach ($result->http_response_body->items as $item) {
$domains[$item->name] = $item->name;
$result = $client->domains()->index();
if (!empty($result)) {
foreach ($result->getDomains() as $domain) {
$domains[$domain->getName()] = $domain->getName();
}
}
else {
watchdog('mailgun', 'Mailgun server returned a %code error. Could not retrieve domain list.', array('%code' => $result->http_response_code), WATCHDOG_ERROR);
watchdog('mailgun', 'Could not retrieve domain list.', array(), WATCHDOG_ERROR);
}
} catch (Exception $e) {
watchdog('mailgun', 'An exception occurred while retrieving domains. @code: @message', array('@code' => $e->getCode(), '@message' => $e->getMessage()), WATCHDOG_ERROR);
}
catch (Exception $e) {
watchdog('mailgun', 'An exception occurred while retrieving domains. @code: @message', array(
'@code' => $e->getCode(),
'@message' => $e->getMessage(),
), WATCHDOG_ERROR);
}
if (empty($domains)) {
// No domain available. Although this shouldn't happen, doesn't hurt to check.
// No domain available.
// Although this shouldn't happen, doesn't hurt to check.
return FALSE;
}
// Now, we need to get the working domain. This is generally the domain the From address is on or the root domain of it.
// Now, we need to get the working domain. This is generally the domain the
// From address is on or the root domain of it.
$working_domain = '';
if ($key = array_search($mail_domain, $domains) !== FALSE) {
if (in_array($mail_domain, $domains, TRUE)) {
// Great. Found it.
$working_domain = $mail_domain;
}
@@ -222,10 +326,13 @@ function mailgun_send($mailgun_message) {
}
}
// There is a chance that the user is attempting to send from an email address that's on a domain not yet added to the Mailgun account.
// There is a chance that the user is attempting to send from an email
// address that's on a domain not yet added to the Mailgun account.
// In that case, abort sending and report error.
if (empty($working_domain)) {
watchdog('mailgun', 'Unable to locate a working domain for From address %mail. Aborting sending.', array('%mail' => $mailgun_message['from']), WATCHDOG_ERROR);
watchdog('mailgun', 'Unable to locate a working domain for From address %mail. Aborting sending.', array(
'%mail' => $mailgun_message['from'],
), WATCHDOG_ERROR);
return FALSE;
}
}
@@ -233,29 +340,46 @@ function mailgun_send($mailgun_message) {
$working_domain = variable_get('mailgun_domain', '');
}
// Attachments
$post_data = array();
if (!empty($mailgun_message['attachments'])) {
// Send message with attachments.
$post_data['attachment'] = $mailgun_message['attachments'];
unset($mailgun_message['attachments']);
// Send message with attachments.
if (!empty($mailgun_message['attachment'])) {
foreach ($mailgun_message['attachment'] as &$attachment) {
// Ignore array constructions. Not sure what values can be here.
if (is_array($attachment)) {
continue;
}
$attachment = array('filePath' => $attachment);
}
}
try {
$result = $client->sendMessage($working_domain, $mailgun_message, $post_data);
// For a list of HTTP response codes, see: https://documentation.mailgun.com/api-intro.html#errors.
if ($result->http_response_code == 200) {
try {
$result = $client->messages()->send($working_domain, $mailgun_message);
if (!empty($result)) {
if (variable_get('mailgun_log', FALSE)) {
watchdog('mailgun', 'Successfully sent message from %from to %to. %code: %message.', array('%from' => $mailgun_message['from'], '%to' => $mailgun_message['to'], '%code' => $result->http_response_code, '%message' => $result->http_response_body->message));
watchdog('mailgun', 'Successfully sent message from %from to %to. %message.', array(
'%from' => $mailgun_message['from'],
'%to' => $mailgun_message['to'],
'%message' => $result->getMessage(),
));
}
return TRUE;
}
else {
watchdog('mailgun', 'Failed to send message from %from to %to. %code: %message.', array('%from' => $mailgun_message['from'], '%to' => $mailgun_message['to'], '%code' => $result->http_response_code, '%message' => $result->http_response_body->message), WATCHDOG_ERROR);
watchdog('mailgun', 'Failed to send message from %from to %to. %message.', array(
'%from' => $mailgun_message['from'],
'%to' => $mailgun_message['to'],
'%message' => $result->getMessage(),
), WATCHDOG_ERROR);
return FALSE;
}
} catch (Exception $e) {
watchdog('mailgun', 'Exception occurred while trying to send test email from %from to %to. @code: @message.', array('%from' => $mailgun_message['from'], '%to' => $mailgun_message['to'], '@code' => $e->getCode(), '@message' => $e->getMessage()));
}
catch (Exception $e) {
watchdog('mailgun', 'Exception occurred while trying to send test email from %from to %to. @code: @message.', array(
'%from' => $mailgun_message['from'],
'%to' => $mailgun_message['to'],
'@code' => $e->getCode(),
'@message' => $e->getMessage(),
));
return FALSE;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* @file
* Default theme implementation of Mailgun mail.
*
* Available variables:
* - $subject: The message subject.
* - $body: The message body.
*
* @see template_preprocess_mailgun_message()
*/
?>
<html>
<head>
<style type="text/css">
body {
font-family: Verdana, Arial, sans-serif;
font-size: 12px;
}
</style>
</head>
<body>
<div>
<?php print $body; ?>
</div>
</body>
</html>

View File

@@ -407,7 +407,8 @@ function _mailsystem_html_to_text(DOMNode $node, array $allowed_tags, array &$no
// Copy each child node to output.
if ($node->hasChildNodes()) {
foreach ($node->childNodes as $child) {
$child_text .= _mailsystem_html_to_text($child, $allowed_tags, $notes, $line_length - drupal_strlen($indent), $parents, $child_count); }
$child_text .= _mailsystem_html_to_text($child, $allowed_tags, $notes, $line_length - drupal_strlen($indent), $parents, $child_count);
}
}
// We only add prefix and suffix if the child nodes were non-empty.
if ($child_text > '') {
@@ -416,7 +417,7 @@ function _mailsystem_html_to_text(DOMNode $node, array $allowed_tags, array &$no
$child_text = drupal_strtoupper($child_text);
}
// Don't add a newline to an existing newline.
if ($suffix === $eol && drupal_substr($child_text, - drupal_strlen($eol)) === $eol) {
if ($suffix === $eol && drupal_substr($child_text, -drupal_strlen($eol)) === $eol) {
$suffix = '';
}
// Trim spaces around newlines except with <pre> or inline tags.
@@ -496,7 +497,7 @@ function _mailsystem_html_to_text_table(DOMNode $node, $allowed_tags = NULL, arr
$footer[] = $current;
break;
default: // Either 'tbody' or 'table'
default: // Either 'tbody' or 'table'.
$body[] = $current;
break;
}
@@ -647,7 +648,7 @@ function _mailsystem_html_to_text_table(DOMNode $node, $allowed_tags = NULL, arr
}
// Generate the row separator line.
$separator = '+';
for($i = 0; $i < $num_cols; $i++) {
for ($i = 0; $i < $num_cols; $i++) {
$separator .= str_repeat('-', $widths[$i]) . '+';
}
$separator .= $eol;

View File

@@ -4,6 +4,7 @@
* @file
* Administrative form for setting the mail_system variable.
*/
function mailsystem_admin_settings() {
$args = array(
'!interface' => url('http://api.drupal.org/api/drupal/includes--mail.inc/interface/MailSystemInterface/7'),
@@ -49,13 +50,13 @@ function mailsystem_admin_settings() {
'#default_value' => $mail_system[mailsystem_default_id()],
);
$mailsystem_classes = array(
mailsystem_default_id() => t('Remove this setting.')
mailsystem_default_id() => t('Remove this setting.'),
) + $mailsystem_classes;
foreach (array_diff_key($mail_system, $mail_defaults) as $id => $class) {
// Separate $id into $module and $key.
$module = $id;
while ($module && empty($descriptions[$module])) {
// Remove a key from the end
// Remove a key from the end.
$module = implode('_', explode('_', $module, -1));
}
// If an array key of the $mail_system variable is neither "default-system"
@@ -91,11 +92,11 @@ function mailsystem_admin_settings() {
}
}
$form['mailsystem']['mailsystem_theme'] = array(
'#type' => 'select',
'#title' => t('Theme to render the emails'),
'#description' => t('Select the theme that will be used to render the emails. This can be either the current theme, the default theme, the domain theme or any active theme.'),
'#options' => $theme_options,
'#default_value' => variable_get('mailsystem_theme', 'current'),
'#type' => 'select',
'#title' => t('Theme to render the emails'),
'#description' => t('Select the theme that will be used to render the emails. This can be either the current theme, the default theme, the domain theme or any active theme.'),
'#options' => $theme_options,
'#default_value' => variable_get('mailsystem_theme', 'current'),
);
$form['class'] = array(
'#type' => 'fieldset',
@@ -168,7 +169,7 @@ function mailsystem_admin_settings_submit($form, &$form_state) {
empty($form_state['values'][$default_id])
? mailsystem_default_value()
: $form_state['values'][$default_id]
)
),
);
foreach (element_children($form_state['values']['mailsystem']) as $module) {
$class = $form_state['values']['mailsystem'][$module];

View File

@@ -1,14 +1,12 @@
package = Mail
name = Mail System
description = Provides a user interface for per-module and site-wide mail_system selection.
php = 5.0
core = 7.x
configure = admin/config/system/mailsystem
dependencies[] = filter
; Information added by drupal.org packaging script on 2012-04-10
version = "7.x-2.34"
; Information added by Drupal.org packaging script on 2018-07-12
version = "7.x-2.35"
core = "7.x"
project = "mailsystem"
datestamp = "1334082653"
datestamp = "1531385928"

View File

@@ -132,15 +132,23 @@ function mailsystem_create_class($classes) {
}
$class_name = implode('__', $classes);
// Ensure that the mailsystem directory exists.
$class_dir = file_build_uri('mailsystem');
if (!file_prepare_directory($class_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
// First we try the private filesystem.
$private_files = variable_get('file_private_path', '');
$private_files_full = $private_files . '/mailsystem';
$public_files = variable_get('file_public_path', conf_path() . '/files');
$public_files_full = $public_files . '/mailsystem';
if ($private_files && file_prepare_directory($private_files_full, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
$class_dir = $private_files . '/mailsystem';
}
// If private filesystem is not defined or writable, we use the public filesystem.
elseif (file_prepare_directory($public_files_full, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
$class_dir = $public_files . '/mailsystem';
}
else {
return FALSE;
}
// Build the class filename.
$class_file = drupal_realpath($class_dir) . DIRECTORY_SEPARATOR . "$class_name.mail.inc";
// Strip DRUPAL_ROOT.
$drupal_root = drupal_realpath(DRUPAL_ROOT) . DIRECTORY_SEPARATOR;
$class_file = preg_replace('#^' . preg_quote($drupal_root, '#') . '#', '', $class_file);
$class_file = $class_dir . DIRECTORY_SEPARATOR . "$class_name.mail.inc";
// Build the class implementation as a string.
$class_contents = '<?php
class ' . $class_name . ' implements MailSystemInterface {';
@@ -181,17 +189,19 @@ class ' . $class_name . ' implements MailSystemInterface {';
$file_condition = db_and()
->condition('filename', $class_file);
db_delete('registry_file')
->condition($file_condition);
->condition($file_condition)
->execute();
db_delete('registry')->condition(
db_or()->condition($class_condition)
->condition($file_condition)
);
)->execute();
// Make sure that registry functions are available.
require_once 'includes/registry.inc';
// Parse the newly-created class file and add it to the registry.
_registry_parse_file($class_file, $class_contents, 'mailsystem');
// Clear the mailsystem cache so that it will pick up the new class.
// Clear the mailsystem caches so that it will pick up the new class.
drupal_static_reset('mailsystem_get_classes');
cache_clear_all('mailsystem_get_classes', 'cache');
drupal_set_message(
t('Class <code>%class</code> written to <code>%file</code>.',
array('%class' => $class_name, '%file' => $class_file)
@@ -257,7 +267,13 @@ function mailsystem_clear(array $setting) {
* Returns a list of classes which implement MailSystemInterface.
*/
function &mailsystem_get_classes() {
// Load static cache.
$mailsystem_classes = &drupal_static(__FUNCTION__);
// Check persistent cache if necessary.
if (!isset($mailsystem_classes) && $cache = cache_get('mailsystem_get_classes')) {
$mailsystem_classes = $cache->data;
}
// Load from db if no cache was hit.
if (!isset($mailsystem_classes)) {
$mailsystem_classes = array();
// @todo Is there a better way to find all mail-related classes?
@@ -282,14 +298,14 @@ function &mailsystem_get_classes() {
->execute()
->fetchAllKeyed();
foreach ($mail_classes as $classname => $classfile) {
if ( file_exists($classfile)
if (file_exists($classfile)
&& drupal_autoload_class($classname)
) {
$all_classes[$classname] = 1;
}
}
foreach ($all_classes as $classname => $autoload) {
if ( ($autoload || preg_match('/MailSystem/', $classname))
if (($autoload || preg_match('/MailSystem/', $classname))
&& ($object = new $classname)
&& ($object instanceof MailSystemInterface)
) {
@@ -311,6 +327,8 @@ function &mailsystem_get_classes() {
}
}
ksort($mailsystem_classes);
// Store in persistent cache.
cache_set('mailsystem_get_classes', $mailsystem_classes, 'cache', CACHE_TEMPORARY);
}
return $mailsystem_classes;
}
@@ -324,10 +342,10 @@ function mailsystem_theme_registry_alter(&$theme_registry) {
}
/**
* Retrieves the key of the theme used to render the emails.
*
* @todo Add some kind of hook to let other modules alter this behavior.
*/
* Retrieves the key of the theme used to render the emails.
*
* @todo Add some kind of hook to let other modules alter this behavior.
*/
function mailsystem_get_mail_theme() {
global $theme_key;
$theme = variable_get('mailsystem_theme', 'current');
@@ -335,9 +353,11 @@ function mailsystem_get_mail_theme() {
case 'default':
$theme = variable_get('theme_default', NULL);
break;
case 'current':
$theme = $theme_key;
break;
case 'domain':
// Fetch the theme for the current domain.
if (module_exists('domain_theme')) {

View File

@@ -1,13 +1,13 @@
<?php
/**
* @file
* The theme system, which controls the output of email messages.
*/
* @file
* The theme system, which controls the output of email messages.
*/
/**
* Implements hook_theme_registry_alter().
*/
* Implements hook_theme_registry_alter().
*/
function mailsystem_theme_theme_registry_alter(&$theme_registry) {
global $theme_key;
static $recursion_prevention = FALSE;
@@ -26,6 +26,10 @@ function mailsystem_theme_theme_registry_alter(&$theme_registry) {
if (isset($themes[$mailsystem_theme])) {
$theme = clone $themes[$mailsystem_theme];
if (isset($theme)) {
// Swap to the mailsystem theme.
$old_theme = $theme_key;
mailsystem_theme_swap_theme($mailsystem_theme);
// Establish variables for further processing.
$base_theme = array();
if (isset($theme->base_themes)) {
@@ -42,10 +46,10 @@ function mailsystem_theme_theme_registry_alter(&$theme_registry) {
// Include template files to let _theme_load_registry add preprocess
// functions.
include_once(drupal_get_path('theme', $theme->name) . '/template.php');
foreach ($base_theme as $base) {
include_once(drupal_get_path('theme', $base->name) . '/template.php');
include_once drupal_get_path('theme', $base->name) . '/template.php';
}
include_once drupal_get_path('theme', $theme->name) . '/template.php';
// Get the theme_registry cache.
$cache = _theme_load_registry($theme, $base_theme, $theme_engine);
@@ -75,8 +79,46 @@ function mailsystem_theme_theme_registry_alter(&$theme_registry) {
}
}
}
// Swap back to the original theme.
mailsystem_theme_swap_theme($old_theme);
}
}
}
$recursion_prevention = FALSE;
}
/**
* Helper to swap themes safely for use by mailsystem_theme_theme_registry_alter().
*/
function mailsystem_theme_swap_theme($new_theme) {
// Make sure the theme exists.
$themes = list_themes();
if (empty($themes[$new_theme])) {
return;
}
// Both theme/theme_key are set to the new theme.
global $theme, $theme_key;
$theme = $theme_key = $new_theme;
// Create the base_theme_info.
global $base_theme_info;
$base_theme = array();
$ancestor = $theme;
while ($ancestor && isset($themes[$ancestor]->base_theme)) {
$ancestor = $themes[$ancestor]->base_theme;
$base_theme[] = $themes[$ancestor];
}
$base_theme_info = array_reverse($base_theme);
// Some other theme related globals.
global $theme_engine, $theme_info, $theme_path;
$theme_engine = $themes[$theme]->engine;
$theme_info = $themes[$theme];
$theme_path = dirname($themes[$theme]->filename);
// We need to reset the drupal_alter and module_implements statics.
drupal_static_reset('drupal_alter');
drupal_static_reset('module_implements');
}