Commit 79d80fb3 authored by sun's avatar sun

Issue #811774 by sun, elliotttf: Ported to Drupal 7.

parent 6c33838b
PHPMailer 6.x-3.x, xxxx-xx-xx
PHPMailer 7.x-3.x, xxxx-xx-xx
-----------------------------
#811774 by sun, elliotttf: Ported to Drupal 7.
PHPMailer 6.x-3.1, 2011-06-05
-----------------------------
by sun: Fixed PHP E_STRICT warnings.
by smk-ka: Added a note to the README how to configure other popular
......
......@@ -9,7 +9,7 @@
* Base PHPMailer for Drupal implementation with support for SMTP keep-alive
* and setting a custom Return-Path.
*/
class DrupalPHPMailer extends PHPMailer {
class DrupalPHPMailer extends PHPMailer implements MailSystemInterface {
/**
* Stores the Return-Path, which may be different from Sender.
*/
......@@ -43,7 +43,7 @@ class DrupalPHPMailer extends PHPMailer {
$this->SMTPDebug = variable_get('smtp_debug', 0);
// Adjust path to SMTP class.
$this->PluginDir = './'. phpmailer_get_path() .'/';
$this->PluginDir = DRUPAL_ROOT . '/' . libraries_get_path('phpmailer') . '/';
}
/**
......@@ -180,5 +180,144 @@ class DrupalPHPMailer extends PHPMailer {
return $result;
}
/**
* Concatenates and wraps the e-mail body for plain-text mails.
*
* Mails contain HTML by default. When using PHPMailer without MimeMail
* module, plain-text e-mails are sent, which require the same processing as
* in the DefaultMailSystem implementation.
*
* @see DefaultMailSystem::format()
*
* @param $message
* A message array, as described in hook_mail_alter().
*
* @return
* The formatted $message.
*/
public function format(array $message) {
// Join the body array into one string.
$message['body'] = implode("\n\n", $message['body']);
// Convert any HTML to plain-text.
$message['body'] = drupal_html_to_text($message['body']);
// Wrap the mail body for sending.
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
/**
* Sends an e-mail message composed by drupal_mail().
*
* @param $message
* A message array, as described in hook_mail_alter().
* @return
* TRUE if the mail was successfully accepted, otherwise FALSE.
*
* @see PHPMailer::Send()
*/
public function mail(array $message) {
try {
// Parse 'From' e-mail address.
$from = phpmailer_parse_address($message['from']);
$from = reset($from);
$this->From = $from['mail'];
if ($from['name'] != '') {
$this->FromName = $from['name'];
}
unset($message['headers']['From']);
if (variable_get('phpmailer_debug_email', '') === '') {
// Set recipients.
foreach (phpmailer_parse_address($message['to']) as $address) {
$this->AddAddress($address['mail'], $address['name']);
}
// Extract CCs and BCCs from headers.
if (isset($message['headers']['CC'])) {
foreach (phpmailer_parse_address($message['headers']['CC']) as $address) {
$this->AddCC($address['mail'], $address['name']);
}
}
if (isset($message['headers']['BCC'])) {
foreach (phpmailer_parse_address($message['headers']['BCC']) as $address) {
$this->AddBCC($address['mail'], $address['name']);
}
}
}
else {
// Reroute to debug e-mail address.
$this->AddAddress(variable_get('phpmailer_debug_email', ''));
}
unset($message['headers']['CC'], $message['headers']['BCC']);
// Extract Reply-To from headers.
if (isset($message['headers']['Reply-To'])) {
foreach (phpmailer_parse_address($message['headers']['Reply-To']) as $address) {
$this->AddReplyTo($address['mail'], $address['name']);
}
unset($message['headers']['Reply-To']);
}
elseif (variable_get('smtp_always_replyto', FALSE)) {
// If no Reply-To header has been explicitly set, use the From address to
// be able to respond to e-mails sent via Google Mail.
$this->AddReplyTo($from['mail'], $from['name']);
}
// Extract Content-Type and charset.
if (isset($message['headers']['Content-Type'])) {
$content_type = explode(';', $message['headers']['Content-Type']);
$this->ContentType = trim(array_shift($content_type));
foreach ($content_type as $param) {
$param = explode('=', $param, 2);
$key = trim($param[0]);
if ($key == 'charset') {
$this->CharSet = trim($param[1]);
}
else {
$this->ContentType .= '; ' . $key . '=' . trim($param[1]);
}
}
unset($message['headers']['Content-Type']);
}
// Set additional properties.
$properties = array(
'X-Priority' => 'Priority',
'Content-Transfer-Encoding' => 'Encoding',
'Sender' => 'Sender',
'Message-ID' => 'MessageID',
// Custom property.
// @see DrupalPHPMailer::CreateHeader()
'Return-Path' => 'ReturnPath',
);
foreach ($properties as $source => $property) {
if (isset($message['headers'][$source])) {
$this->$property = $message['headers'][$source];
unset($message['headers'][$source]);
}
}
// This one is always set by PHPMailer.
unset($message['headers']['MIME-Version']);
// Add remaining header lines.
// Note: Any header lines MUST already be checked by the caller for unwanted
// newline characters to avoid header injection.
// @see PHPMailer::SecureHeader()
foreach ($message['headers'] as $key => $value) {
$this->AddCustomHeader("$key:$value");
}
$this->Subject = $message['subject'];
$this->Body = $message['body'];
return $this->Send();
}
catch (phpmailerException $e) {
drupal_set_message(t('Sending of at least one e-mail failed. The error returned was:<br />@error.', array('@error' => $e->getMessage())), 'error');
watchdog('phpmailer', $e->getMessage(), NULL, WATCHDOG_ERROR);
return FALSE;
}
}
}
......@@ -6,121 +6,24 @@
*/
/**
* Send out an e-mail.
* Sends an already formatted e-mail message composed by drupal_mail().
*
* @param $message
* Message array structure.
* A message array, as described in hook_mail_alter().
* @return
* TRUE if the mail was successfully accepted, otherwise FALSE.
*
* @see DrupalPHPMailer::mail()
*
* @todo Consider to either drop this entirely, or move into phpmailer.module
* as singleton to instantiate the DrupalPHPMailer class.
*/
function phpmailer_send($message) {
static $mail;
$mail = &drupal_static(__FUNCTION__);
if (!isset($mail)) {
if (!phpmailer_load_library()) {
return FALSE;
}
$mail = new DrupalPHPMailer();
}
try {
// Parse 'From' e-mail address.
$from = phpmailer_parse_address($message['from']);
$from = reset($from);
$mail->From = $from['mail'];
if ($from['name'] != '') {
$mail->FromName = $from['name'];
}
unset($message['headers']['From']);
if (variable_get('phpmailer_debug_email', '') === '') {
// Set recipients.
foreach (phpmailer_parse_address($message['to']) as $address) {
$mail->AddAddress($address['mail'], $address['name']);
}
// Extract CCs and BCCs from headers.
if (isset($message['headers']['CC'])) {
foreach (phpmailer_parse_address($message['headers']['CC']) as $address) {
$mail->AddCC($address['mail'], $address['name']);
}
}
if (isset($message['headers']['BCC'])) {
foreach (phpmailer_parse_address($message['headers']['BCC']) as $address) {
$mail->AddBCC($address['mail'], $address['name']);
}
}
}
else {
// Reroute to debug e-mail address.
$mail->AddAddress(variable_get('phpmailer_debug_email', ''));
}
unset($message['headers']['CC'], $message['headers']['BCC']);
// Extract Reply-To from headers.
if (isset($message['headers']['Reply-To'])) {
foreach (phpmailer_parse_address($message['headers']['Reply-To']) as $address) {
$mail->AddReplyTo($address['mail'], $address['name']);
}
unset($message['headers']['Reply-To']);
}
elseif (variable_get('smtp_always_replyto', FALSE)) {
// If no Reply-To header has been explicitly set, use the From address to
// be able to respond to e-mails sent via Google Mail.
$mail->AddReplyTo($from['mail'], $from['name']);
}
// Extract Content-Type and charset.
if (isset($message['headers']['Content-Type'])) {
$content_type = explode(';', $message['headers']['Content-Type']);
$mail->ContentType = trim(array_shift($content_type));
foreach ($content_type as $param) {
$param = explode('=', $param, 2);
$key = trim($param[0]);
if ($key == 'charset') {
$mail->CharSet = trim($param[1]);
}
else {
$mail->ContentType .= '; ' . $key . '=' . trim($param[1]);
}
}
unset($message['headers']['Content-Type']);
}
// Set additional properties.
$properties = array(
'X-Priority' => 'Priority',
'Content-Transfer-Encoding' => 'Encoding',
'Sender' => 'Sender',
'Message-ID' => 'MessageID',
// Custom property.
// @see DrupalPHPMailer::CreateHeader()
'Return-Path' => 'ReturnPath',
);
foreach ($properties as $source => $property) {
if (isset($message['headers'][$source])) {
$mail->$property = $message['headers'][$source];
unset($message['headers'][$source]);
}
}
// This one is always set by PHPMailer.
unset($message['headers']['MIME-Version']);
// Add remaining header lines.
// Note: Any header lines MUST already be checked by the caller for unwanted
// newline characters to avoid header injection.
// @see PHPMailer::SecureHeader()
foreach ($message['headers'] as $key => $value) {
$mail->AddCustomHeader("$key:$value");
}
$mail->Subject = $message['subject'];
$mail->Body = $message['body'];
return $mail->Send();
}
catch (phpmailerException $e) {
drupal_set_message(t('Sending of at least one e-mail failed. The error returned was:<br />@error.', array('@error' => $e->getMessage())), 'error');
watchdog('phpmailer', $e->getMessage(), NULL, WATCHDOG_ERROR);
return FALSE;
}
return $mail->mail($message);
}
......@@ -15,9 +15,6 @@ function mimemail_phpmailer_send($message) {
static $mail;
if (!isset($mail)) {
if (!phpmailer_load_library()) {
return FALSE;
}
$mail = new DrupalPHPMailer();
// Keep linefeed style in sync.
$mail->LE = variable_get('mimemail_crlf', "\n");
......
......@@ -24,7 +24,7 @@ function phpmailer_settings_form($form_state) {
if (module_exists('mimemail') && variable_get('mimemail_alter', 0)) {
$form['smtp_on']['#disabled'] = TRUE;
$form['smtp_on']['#default_value'] = 0;
$form['smtp_on']['#description'] = t('MimeMail has been detected. To enable PHPMailer for mail transport, go to the <a href="@url">MimeMail settings page</a> and select PHPMailer from the available e-mail engines.', array('@url' => url('admin/settings/mimemail')));
$form['smtp_on']['#description'] = t('MimeMail has been detected. To enable PHPMailer for mail transport, go to the <a href="@url">MimeMail settings page</a> and select PHPMailer from the available e-mail engines.', array('@url' => url('admin/config/system/mimemail')));
}
elseif (!variable_get('smtp_on', 0) && empty($form_state['post']['smtp_on'])) {
drupal_set_message(t('PHPMailer is currently disabled.'), 'warning');
......@@ -181,13 +181,29 @@ function phpmailer_settings_form_submit($form, &$form_state) {
// Enable/disable mail sending subsystem.
if ($form_state['values']['smtp_on']) {
if (!phpmailer_enabled()) {
variable_set('smtp_library', drupal_get_filename('module', 'phpmailer'));
$mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
$mail_system['default-system'] = 'DrupalPHPMailer';
variable_set('mail_system', $mail_system);
drupal_set_message(t('PHPMailer will be used to deliver all site e-mails.'));
watchdog('phpmailer', 'PHPMailer has been enabled.');
}
}
else if (phpmailer_enabled()) {
variable_del('smtp_library');
// Remove PHPMailer from all mail keys it is configured for.
$mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
foreach ($mail_system as $key => $class) {
if ($class == 'DrupalPHPMailer') {
if ($key != 'default-system') {
unset($mail_system[$key]);
}
else {
$mail_system[$key] = 'DefaultMailSystem';
}
}
}
variable_set('mail_system', $mail_system);
drupal_set_message(t('PHPMailer has been disabled.'));
watchdog('phpmailer', 'PHPMailer has been disabled.');
}
......@@ -214,7 +230,7 @@ function phpmailer_settings_form_submit($form, &$form_state) {
*/
function phpmailer_mail($key, &$message, $params) {
$message['subject'] = t('PHPMailer test e-mail');
$message['body'][] = t('Your site is properly configured to send e-mails using the PHPMailer library.');
$message['body'][] = t('Your site is properly configured to send e-mails using the <strong>PHPMailer</strong> library.');
}
/**
......@@ -251,6 +267,6 @@ function phpmailer_preview() {
}
print $body;
exit;
drupal_exit();
}
......@@ -2,4 +2,10 @@ name = PHPMailer
description = Integrates the PHPMailer library for SMTP e-mail delivery.
dependencies[] = libraries
package = Mail
core = 6.x
\ No newline at end of file
core = 7.x
configure = admin/config/system/phpmailer
files[] = includes/phpmailer.class.inc
files[] = tests/phpmailer.test
; Libraries
;files[] = class.phpmailer.php
;files[] = class.smtp.php
......@@ -13,7 +13,7 @@ function phpmailer_requirements($phase) {
// Ensure translations don't break at install time.
$t = get_t();
if ($phase == 'runtime' && phpmailer_load_library()) {
if ($phase == 'runtime' && phpmailer_library_exists()) {
$mail = new PHPMailer();
$requirements['phpmailer'] = array(
'title' => $t('PHPMailer library'),
......@@ -24,7 +24,9 @@ function phpmailer_requirements($phase) {
else {
drupal_load('module', 'libraries');
$path = libraries_get_path('phpmailer');
if (!file_exists('./' . $path . '/class.phpmailer.php') || !file_exists('./' . $path . '/class.smtp.php')) {
if (!$path || !file_exists(DRUPAL_ROOT . '/' . $path . '/class.phpmailer.php') || !file_exists(DRUPAL_ROOT . '/' . $path . '/class.smtp.php')) {
// Since Libraries 2.x, $path is FALSE if the library does not exist.
$path = 'sites/all/libraries/phpmailer';
$requirements['phpmailer'] = array(
'title' => $t('PHPMailer library'),
'value' => $t('Missing'),
......@@ -45,6 +47,10 @@ function phpmailer_requirements($phase) {
* Implementation of hook_uninstall().
*/
function phpmailer_uninstall() {
$mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
$mail_system['default-system'] = 'DefaultMailSystem';
variable_set('mail_system', $mail_system);
variable_del('smtp_on');
variable_del('smtp_host');
variable_del('smtp_hostbackup');
......@@ -57,3 +63,17 @@ function phpmailer_uninstall() {
variable_del('smtp_debug');
}
/**
* Enable PHPMailer as default mail system if it has been before.
*/
function phpmailer_update_7000() {
// @todo Check whether the library exists?
if (strpos(variable_get('smtp_library', ''), 'phpmailer')) {
$mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
$mail_system['default-system'] = 'DrupalPHPMailer';
variable_set('mail_system', $mail_system);
// PHPMailer was the default mail engine, so it should be safe to remove the
// variable.
variable_del('smtp_library');
}
}
......@@ -8,15 +8,20 @@
/**
* Implementation of hook_perm().
*/
function phpmailer_perm() {
return array('administer phpmailer settings');
function phpmailer_permission() {
return array(
'administer phpmailer settings' => array(
'title' => t('Administer PHPMailer settings'),
'restrict access' => TRUE,
),
);
}
/**
* Implementation of hook_menu().
*/
function phpmailer_menu() {
$items['admin/settings/phpmailer'] = array(
$items['admin/config/system/phpmailer'] = array(
'title' => 'PHPMailer',
'description' => 'Configure PHPMailer settings.',
'page callback' => 'drupal_get_form',
......@@ -45,7 +50,7 @@ function phpmailer_form_mimemail_admin_settings_alter(&$form, &$form_state) {
$mimemail_alter = &$form['mimemail']['mimemail_alter'];
$mimemail_alter['#disabled'] = TRUE;
$mimemail_alter['#default_value'] = 0;
$mimemail_alter['#description'] = t('PHPMailer has been set to deliver all site messages. To let Mime Mail apply styles and formatting to system e-mails but still use PHPMailer for mail transport, uncheck <em>Use PHPMailer to send e-mails</em> first on the <a href="@url">PHPMailer settings page</a>. Then activate this setting and choose PHPMailer from the list of e-mail engines below.', array('@url' => url('admin/settings/phpmailer')));
$mimemail_alter['#description'] = t('PHPMailer has been set to deliver all site messages. To let Mime Mail apply styles and formatting to system e-mails but still use PHPMailer for mail transport, uncheck <em>Use PHPMailer to send e-mails</em> first on the <a href="@url">PHPMailer settings page</a>. Then activate this setting and choose PHPMailer from the list of e-mail engines below.', array('@url' => url('admin/config/system/phpmailer')));
}
// @todo Move to MimeMail project.
$form['preview'] = array(
......@@ -60,23 +65,19 @@ function phpmailer_form_mimemail_admin_settings_alter(&$form, &$form_state) {
* Determine if PHPMailer is used to deliver e-mails.
*/
function phpmailer_enabled() {
return strpos(variable_get('smtp_library', ''), 'phpmailer');
}
if (phpmailer_enabled() && !function_exists('drupal_mail_wrapper')) {
/**
* Implementation of drupal_mail_wrapper().
*/
function drupal_mail_wrapper($message) {
module_load_include('inc', 'phpmailer', 'includes/phpmailer.drupal');
return phpmailer_send($message);
}
// We need to rely on our 'smtp_on' variable, since PHPMailer may not be
// configured as the default mail system.
return (bool) variable_get('smtp_on', 0);
}
/**
* Implementation of hook_mailengine().
*/
function phpmailer_mailengine($op, $message = array()) {
if (!phpmailer_library_exists()) {
return;
}
switch ($op) {
case 'name':
return t('PHPMailer');
......@@ -85,7 +86,7 @@ function phpmailer_mailengine($op, $message = array()) {
return t('Mailing engine using the PHPMailer library.');
case 'settings':
$form['info']['#value'] = t('To configure your mail server settings, visit the <a href="@url">PHPMailer settings page</a>.', array('@url' => url('admin/settings/phpmailer')));
$form['info']['#value'] = t('To configure your mail server settings, visit the <a href="@url">PHPMailer settings page</a>.', array('@url' => url('admin/config/system/phpmailer')));
return $form;
case 'multiple':
......@@ -174,7 +175,7 @@ function phpmailer_preview_access() {
function phpmailer_enable() {
if (!phpmailer_enabled() && !(module_exists('mimemail') && variable_get('mimemail_engine', 'mimemail') == 'phpmailer')) {
$t = get_t();
drupal_set_message($t('PHPMailer has been installed, but is currently disabled. <a href="@settings-url">Configure it now</a>.', array('@settings-url' => url('admin/settings/phpmailer'))));
drupal_set_message($t('PHPMailer has been installed, but is currently disabled. <a href="@settings-url">Configure it now</a>.', array('@settings-url' => url('admin/config/system/phpmailer'))));
}
}
......@@ -183,7 +184,20 @@ function phpmailer_enable() {
*/
function phpmailer_disable() {
if (phpmailer_enabled()) {
variable_del('smtp_library');
// Remove PHPMailer from all mail keys it is configured for.
$mail_system = variable_get('mail_system', array('default-system' => 'DefaultMailSystem'));
foreach ($mail_system as $key => $class) {
if ($class == 'DrupalPHPMailer') {
if ($key != 'default-system') {
unset($mail_system[$key]);
}
else {
$mail_system[$key] = 'DefaultMailSystem';
}
}
}
variable_set('mail_system', $mail_system);
variable_del('smtp_on');
drupal_set_message(t('PHPMailer has been disabled.'));
}
......@@ -194,34 +208,33 @@ function phpmailer_disable() {
}
/**
* Load PHPMailer class from libraries path.
* Implements hook_registry_files_alter().
*
* @todo Consider to move this into Libraries API.
*/
function phpmailer_load_library() {
if (!class_exists('PHPMailer')) {
if (!($library_path = phpmailer_get_path())) {
watchdog('phpmailer', 'Could not load PHPMailer library.', array(), WATCHDOG_ERROR);
return FALSE;
}
require_once './'. $library_path .'/class.phpmailer.php';
function phpmailer_registry_files_alter(&$files, $modules) {
$library_path = libraries_get_path('phpmailer');
if (!$library_path) {
return;
}
if (!class_exists('DrupalPHPMailer')) {
module_load_include('inc', 'phpmailer', 'includes/phpmailer.class');
foreach (array('class.phpmailer.php', 'class.pop3.php', 'class.smtp.php') as $filename) {
$files[$library_path . '/' . $filename] = array(
'module' => 'phpmailer',
'weight' => 0,
);
}
return TRUE;
}
/**
* Get path to PHPMailer library.
* Returns whether PHPMailer library files exist.
*/
function phpmailer_get_path() {
function phpmailer_library_exists() {
$exists = FALSE;
$library_path = libraries_get_path('phpmailer');
if (!file_exists('./'. $library_path .'/class.phpmailer.php')) {
// Provide backwards compatibility for existing installations of
// PHPMailer module.
$library_path = drupal_get_path('module', 'phpmailer') .'/phpmailer';
if (!file_exists('./'. $library_path .'/class.phpmailer.php')) {
return FALSE;
if ($library_path) {
foreach (array('class.phpmailer.php', 'class.pop3.php', 'class.smtp.php') as $filename) {
$exists = ($exists && file_exists(DRUPAL_ROOT . '/' . $library_path . '/' . $filename));
}
}
return $library_path;
return $exists;
}
......@@ -6,14 +6,11 @@
*/
class PHPMailerUnitTestCase extends DrupalUnitTestCase {
/**
* Implementation of getInfo().
*/
public static function getInfo() {
return array(
'name' => t('E-mail address parser'),
'description' => t('Validates e-mail address extraction.'),
'group' => t('PHPMailer'),
'name' => 'E-mail address parser',
'description' => 'Validates e-mail address extraction.',
'group' => 'PHPMailer',
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment