summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2012-01-21 10:24:52 -0800
committerwebchick <webchick@24967.no-reply.drupal.org>2012-01-21 10:24:52 -0800
commit138745688bcbed1a20b301ed616e5ed0796ecb5e (patch)
tree562afc5ec24a4cf5c58ec500c56f7d9c6014c6b0
parent4303ae6e48e140696e1a9c923bcdf913fa63c88d (diff)
downloadbrdo-138745688bcbed1a20b301ed616e5ed0796ecb5e.tar.gz
brdo-138745688bcbed1a20b301ed616e5ed0796ecb5e.tar.bz2
Issue #800434 by pillarsdotnet, plach, bart.hanssens: Added drupal_mail(), allow hook_mail_alter() implementation to cancel mail.
-rw-r--r--includes/mail.inc46
-rw-r--r--modules/simpletest/simpletest.module13
-rw-r--r--modules/simpletest/tests/mail.test24
-rw-r--r--modules/system/system.api.php8
4 files changed, 80 insertions, 11 deletions
diff --git a/includes/mail.inc b/includes/mail.inc
index 7272df972..13a6f4643 100644
--- a/includes/mail.inc
+++ b/includes/mail.inc
@@ -57,6 +57,12 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
* user_mail_tokens($variables, $data, $options);
* switch($key) {
* case 'notice':
+ * // If the recipient can receive such notices by instant-message, do
+ * // not send by email.
+ * if (example_im_send($key, $message, $params)) {
+ * $message['send'] = FALSE;
+ * break;
+ * }
* $langcode = $message['language']->language;
* $message['subject'] = t('Notification from !site', $variables, array('langcode' => $langcode));
* $message['body'][] = t("Dear !username\n\nThere is new content available on the site.", $variables, array('langcode' => $langcode));
@@ -65,6 +71,19 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
* }
* @endcode
*
+ * Another example, which uses drupal_mail() to format a message for sending
+ * later:
+ *
+ * @code
+ * $params = array('current_conditions' => $data);
+ * $to = 'user@example.com';
+ * $message = drupal_mail('example', 'notice', $to, $language, $params, FALSE);
+ * // Only add to the spool if sending was not canceled.
+ * if ($message['send']) {
+ * example_spool_message($message);
+ * }
+ * @endcode
+ *
* @param $module
* A module name to invoke hook_mail() on. The {$module}_mail() hook will be
* called to complete the $message structure which will already contain common
@@ -86,8 +105,10 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER
* @param $from
* Sets From to this value, if given.
* @param $send
- * Send the message directly, without calling drupal_mail_system()->mail()
- * manually.
+ * If TRUE, drupal_mail() will call drupal_mail_system()->mail() to deliver
+ * the message, and store the result in $message['result']. Modules
+ * implementing hook_mail_alter() may cancel sending by setting
+ * $message['send'] to FALSE.
*
* @return
* The $message array structure containing all details of the
@@ -108,6 +129,7 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
'from' => isset($from) ? $from : $default_from,
'language' => $language,
'params' => $params,
+ 'send' => TRUE,
'subject' => '',
'body' => array()
);
@@ -148,12 +170,20 @@ function drupal_mail($module, $key, $to, $language, $params = array(), $from = N
// Optionally send e-mail.
if ($send) {
- $message['result'] = $system->mail($message);
-
- // Log errors
- if (!$message['result']) {
- watchdog('mail', 'Error sending e-mail (from %from to %to).', array('%from' => $message['from'], '%to' => $message['to']), WATCHDOG_ERROR);
- drupal_set_message(t('Unable to send e-mail. Contact the site administrator if the problem persists.'), 'error');
+ // The original caller requested sending. Sending was canceled by one or
+ // more hook_mail_alter() implementations. We set 'result' to NULL, because
+ // FALSE indicates an error in sending.
+ if (empty($message['send'])) {
+ $message['result'] = NULL;
+ }
+ // Sending was originally requested and was not canceled.
+ else {
+ $message['result'] = $system->mail($message);
+ // Log errors.
+ if (!$message['result']) {
+ watchdog('mail', 'Error sending e-mail (from %from to %to).', array('%from' => $message['from'], '%to' => $message['to']), WATCHDOG_ERROR);
+ drupal_set_message(t('Unable to send e-mail. Contact the site administrator if the problem persists.'), 'error');
+ }
}
}
diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module
index b820f5307..980bc1463 100644
--- a/modules/simpletest/simpletest.module
+++ b/modules/simpletest/simpletest.module
@@ -504,3 +504,16 @@ function simpletest_clean_results_table($test_id = NULL) {
}
return 0;
}
+
+/**
+ * Implements hook_mail_alter().
+ *
+ * Aborts sending of messages with ID 'simpletest_cancel_test'.
+ *
+ * @see MailTestCase::testCancelMessage()
+ */
+function simpletest_mail_alter(&$message) {
+ if ($message['id'] == 'simpletest_cancel_test') {
+ $message['send'] = FALSE;
+ }
+}
diff --git a/modules/simpletest/tests/mail.test b/modules/simpletest/tests/mail.test
index a6c7b40e5..09dcde60c 100644
--- a/modules/simpletest/tests/mail.test
+++ b/modules/simpletest/tests/mail.test
@@ -22,7 +22,7 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
}
function setUp() {
- parent::setUp();
+ parent::setUp(array('simpletest'));
// Set MailTestCase (i.e. this class) as the SMTP library
variable_set('mail_system', array('default-system' => 'MailTestCase'));
@@ -35,10 +35,28 @@ class MailTestCase extends DrupalWebTestCase implements MailSystemInterface {
global $language;
// Use MailTestCase for sending a message.
- $message = drupal_mail('simpletest', 'mail_test', 'testing@drupal.org', $language);
+ $message = drupal_mail('simpletest', 'mail_test', 'testing@example.com', $language);
// Assert whether the message was sent through the send function.
- $this->assertEqual(self::$sent_message['to'], 'testing@drupal.org', t('Pluggable mail system is extendable.'));
+ $this->assertEqual(self::$sent_message['to'], 'testing@example.com', t('Pluggable mail system is extendable.'));
+ }
+
+ /**
+ * Test that message sending may be canceled.
+ *
+ * @see simpletest_mail_alter()
+ */
+ function testCancelMessage() {
+ global $language;
+
+ // Reset the class variable holding a copy of the last sent message.
+ self::$sent_message = NULL;
+
+ // Send a test message that simpletest_mail_alter should cancel.
+ $message = drupal_mail('simpletest', 'cancel_test', 'cancel@example.com', $language);
+
+ // Assert that the message was not actually sent.
+ $this->assertNull(self::$sent_message, 'Message was canceled.');
}
/**
diff --git a/modules/system/system.api.php b/modules/system/system.api.php
index a2e71d2cc..b2ae3192f 100644
--- a/modules/system/system.api.php
+++ b/modules/system/system.api.php
@@ -1903,11 +1903,19 @@ function hook_image_toolkits() {
* - 'language':
* The language object used to build the message before hook_mail_alter()
* is invoked.
+ * - 'send':
+ * Set to FALSE to abort sending this email message.
*
* @see drupal_mail()
*/
function hook_mail_alter(&$message) {
if ($message['id'] == 'modulename_messagekey') {
+ if (!example_notifications_optin($message['to'], $message['id'])) {
+ // If the recipient has opted to not receive such messages, cancel
+ // sending.
+ $message['send'] = FALSE;
+ return;
+ }
$message['body'][] = "--\nMail sent out from " . variable_get('site_name', t('Drupal'));
}
}