Skip to content

Commit

Permalink
Merge pull request #212 from bugfolder/211_extra_mail_support
Browse files Browse the repository at this point in the history
Issue #211: Add support for CC, BCC, Reply-to to “Send mail” actions.
  • Loading branch information
bugfolder authored Apr 14, 2024
2 parents 095d7f9 + 96751ed commit a79f9b7
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 9 deletions.
57 changes: 50 additions & 7 deletions modules/system.eval.inc
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,28 @@ function rules_action_breadcrumb_set(array $titles, array $paths) {
/**
* Action Implementation: Send mail.
*/
function rules_action_mail($to, $subject, $message, $from, $langcode, $settings, RulesState $state, RulesPlugin $element) {
$to = str_replace(array("\r", "\n"), '', $to);
$from = !empty($from) ? str_replace(array("\r", "\n"), '', $from) : NULL;
function rules_action_mail($to, $cc, $bcc, $reply_to, $subject, $message, $from, $langcode, $settings, RulesState $state, RulesPlugin $element) {
_rules_strip_line_breaks($to, FALSE);

_rules_strip_line_breaks($cc);
_rules_strip_line_breaks($bcc);
_rules_strip_line_breaks($reply_to);
_rules_strip_line_breaks($from);

$params = array(
'subject' => $subject,
'message' => $message,
'langcode' => $langcode,
);

if (!empty($cc)) {
$params['cc'] = $cc;
}
if (!empty($bcc)) {
$params['bcc'] = $bcc;
}
if (!empty($reply_to)) {
$params['reply-to'] = $reply_to;
}
if (!empty($from)) {
$params['from'] = $from;
}
Expand All @@ -116,8 +129,12 @@ function rules_action_mail($to, $subject, $message, $from, $langcode, $settings,
/**
* Action: Send mail to all users of a specific role group(s).
*/
function rules_action_mail_to_users_of_role($roles, $subject, $message, $from, $settings, RulesState $state, RulesPlugin $element) {
$from = !empty($from) ? str_replace(array("\r", "\n"), '', $from) : NULL;
function rules_action_mail_to_users_of_role($roles, $cc, $bcc, $reply_to, $subject, $message, $from, $settings, RulesState $state, RulesPlugin $element) {

_rules_strip_line_breaks($cc);
_rules_strip_line_breaks($bcc);
_rules_strip_line_breaks($reply_to);
_rules_strip_line_breaks($from);

// All authenticated users, which is everybody.
if (in_array(BACKDROP_AUTHENTICATED_ROLE, $roles)) {
Expand All @@ -138,10 +155,19 @@ function rules_action_mail_to_users_of_role($roles, $subject, $message, $from, $
'subject' => $subject,
'message' => $message,
);

if (!empty($cc)) {
$params['cc'] = $cc;
}
if (!empty($bcc)) {
$params['bcc'] = $bcc;
}
if (!empty($reply_to)) {
$params['reply-to'] = $reply_to;
}
if (!empty($from)) {
$params['from'] = $from;
}

// Set a unique key for this mail.
$name = isset($element->root()->name) ? $element->root()->name : 'unnamed';
$key = 'rules_action_mail_to_users_of_role_' . $name . '_' . $element->elementId();
Expand All @@ -166,6 +192,13 @@ function rules_action_mail_to_users_of_role($roles, $subject, $message, $from, $
}
}

/**
* Strip line breaks from a string.
*/
function _rules_strip_line_breaks(&$string, $null_if_empty = TRUE) {
$string = !empty($string) ? str_replace(array("\r", "\n"), '', $string) : ($null_if_empty ? NULL : '');
}

/**
* Implements hook_mail().
*
Expand All @@ -178,6 +211,16 @@ function rules_mail($key, &$message, $params) {
if (!empty($params['from'])) {
$message['from'] = $params['from'];
}
if (!empty($params['cc'])) {
$message['headers']['Cc'] = $params['cc'];
}
if (!empty($params['bcc'])) {
$message['headers']['Bcc'] = $params['bcc'];
}
if (!empty($params['reply-to'])) {
$message['reply-to'] = $params['reply-to'];
$message['headers']['Reply-to'] = $params['reply-to'];
}
}

/**
Expand Down
48 changes: 48 additions & 0 deletions modules/system.rules.inc
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,30 @@ function rules_system_action_info() {
t('User <[email protected]>, Another User <[email protected]>'),
))),
),
'cc' => array(
'type' => 'text',
'label' => t('CC'),
'description' => t("CC recipient(s) (same form as To)"),
'translatable' => TRUE,
'optional' => TRUE,
'allow null' => TRUE,
),
'bcc' => array(
'type' => 'text',
'label' => t('BCC'),
'description' => t("BCC recipient(s) (same form as To)"),
'translatable' => TRUE,
'optional' => TRUE,
'allow null' => TRUE,
),
'reply_to' => array(
'type' => 'text',
'label' => t('Reply-to'),
'description' => t('Reply-to address (same for as To)'),
'translatable' => TRUE,
'optional' => TRUE,
'allow null' => TRUE,
),
'subject' => array(
'type' => 'text',
'label' => t('Subject'),
Expand Down Expand Up @@ -268,6 +292,30 @@ function rules_system_action_info() {
'options list' => 'entity_plus_metadata_user_roles',
'description' => t('Select the roles whose users should receive the mail.'),
),
'cc' => array(
'type' => 'text',
'label' => t('CC'),
'description' => t("CC recipient(s) (same form as To)"),
'translatable' => TRUE,
'optional' => TRUE,
'allow null' => TRUE,
),
'bcc' => array(
'type' => 'text',
'label' => t('BCC'),
'description' => t("BCC recipient(s) (same form as To)"),
'translatable' => TRUE,
'optional' => TRUE,
'allow null' => TRUE,
),
'reply_to' => array(
'type' => 'text',
'label' => t('Reply-to'),
'description' => t('Reply-to address (same for as To)'),
'translatable' => TRUE,
'optional' => TRUE,
'allow null' => TRUE,
),
'subject' => array(
'type' => 'text',
'label' => t('Subject'),
Expand Down
50 changes: 48 additions & 2 deletions tests/rules.test
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
class RulesTestCase extends BackdropWebTestCase {
protected $normal_role;

/**
* Overrides BackdropWebTestCase::setUp().
*/
Expand Down Expand Up @@ -1396,6 +1396,30 @@ class RulesIntegrationTestCase extends BackdropWebTestCase {
config_set('rules.settings','rules_debug_log', 1);
}

/**
* Asserts that the most recently sent email message has the given value in
* the mail's headers.
*
* The field in $name must have the content described in $value.
*
* @param $name
* Name of field or message property to assert. Examples: subject, body, id, ...
* @param $value
* Value of the field to assert.
* @param $message
* Message to display.
*
* @return
* TRUE on pass, FALSE on fail.
*
* @see BackdropWebTestCase::assertMail()
*/
protected function assertMailHeaders($name, $value = '', $message = '') {
$captured_emails = state_get('test_email_collector', array());
$email = end($captured_emails);
return $this->assertTrue($email && isset($email['headers'][$name]) && $email['headers'][$name] == $value, $message, t('Email'));
}

/**
* Just makes sure the access callback run without errors.
*/
Expand Down Expand Up @@ -2114,6 +2138,15 @@ class RulesIntegrationTestCase extends BackdropWebTestCase {
rules_action('mail', $settings + array('from' => '[email protected]'))->execute();
$this->assertMail('from', '[email protected]', 'Specified from address has been used');

rules_action('mail', $settings + array('cc' => '[email protected]'))->execute();
$this->assertMailHeaders('Cc', '[email protected]', 'Specified CC address has been used');

rules_action('mail', $settings + array('bcc' => '[email protected]'))->execute();
$this->assertMailHeaders('Bcc', '[email protected]', 'Specified BCC address has been used');

rules_action('mail', $settings + array('reply_to' => '[email protected]'))->execute();
$this->assertMailHeaders('Reply-to', '[email protected]', 'Specified Reply-to address has been used');

// Test sending mail to all users of a role. First clear the mail
// collector to remove the mail sent in the previous line of code.
state_set('test_email_collector', array());
Expand Down Expand Up @@ -2157,8 +2190,21 @@ class RulesIntegrationTestCase extends BackdropWebTestCase {
$mail = array_pop($mails);
$this->assertTrue($mail['to'] == $user1->mail || $mail['to'] == $user2->mail, 'Mail to user of a role has been sent.');

// Execute action again and check that CC, BCC, and Reply-to were set.
rules_action('mail_to_users_of_role', $settings + array(
'roles' => $roles,
'cc' => '[email protected]',
'bcc' => '[email protected]',
'reply_to' => '[email protected]',
))->execute();
$mails = $this->backdropGetMails();
$mail = array_pop($mails);
$this->assertTrue($mail['headers']['Cc'] == '[email protected]', 'Mail to user of a role has been sent with correct CC.');
$this->assertTrue($mail['headers']['Bcc'] == '[email protected]', 'Mail to user of a role has been sent with correct BCC.');
$this->assertTrue($mail['headers']['Reply-to'] == '[email protected]', 'Mail to user of a role has been sent with correct Reply-to.');

// Execute action again, this time to send mail to both roles.
// This time check that three mails were sent - one for each user..
// This time check that three mails were sent - one for each user.
state_set('test_email_collector', array());
rules_action('mail_to_users_of_role', $settings + array('roles' => array_merge($roles, $additional_roles)))->execute();
$mails = $this->backdropGetMails();
Expand Down

0 comments on commit a79f9b7

Please sign in to comment.