Skip to content

Commit 3ef42fd

Browse files
Merge pull request #250 from catalyst/issue97-MOODLE_404_STABLE-multiple_emails
Issue #97: Add support for specifying multiple email addresses
2 parents 860d3fc + 161db3c commit 3ef42fd

3 files changed

Lines changed: 85 additions & 21 deletions

File tree

classes/steps/actions/email_action_step.php

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2525
*/
2626
class email_action_step extends base_action_step {
27-
2827
use \tool_trigger\helper\datafield_manager;
2928

3029
/**
@@ -75,7 +74,9 @@ protected function init() {
7574
$this->emailsubject = $this->data['emailsubject'];
7675
$this->emailcontent = $this->data['emailcontent_editor[text]'];
7776
$this->messageplain = format_text_email(
78-
$this->data['emailcontent_editor[text]'], $this->data['emailcontent_editor[format]']);
77+
$this->data['emailcontent_editor[text]'],
78+
$this->data['emailcontent_editor[format]']
79+
);
7980
}
8081

8182
/**
@@ -106,17 +107,25 @@ public function execute($step, $trigger, $event, $stepresults) {
106107
$emailcontent = $this->render_datafields($this->emailcontent);
107108
$messageplain = $this->render_datafields($this->messageplain);
108109

109-
// Check we have a valid email address.
110-
if ($emailto == clean_param($emailto, PARAM_EMAIL)) {
110+
$recipients = array_map('trim', explode(',', $emailto));
111+
112+
$firsteventdata = null;
113+
$firstmsgid = null;
114+
115+
foreach ($recipients as $recipient) {
116+
// Check we have a valid email address.
117+
if ($recipient !== clean_param($recipient, PARAM_EMAIL)) {
118+
continue;
119+
}
111120

112121
// Check if user exists and use user record.
113-
$user = $DB->get_record('user', ['email' => $emailto, 'deleted' => 0]);
122+
$user = $DB->get_record('user', ['email' => $recipient, 'deleted' => 0]);
114123

115124
// If user not found, use noreply as a base.
116125
if (empty($user)) {
117126
$user = \core_user::get_noreply_user();
118-
$user->firstname = $emailto;
119-
$user->email = $emailto;
127+
$user->firstname = $recipient;
128+
$user->email = $recipient;
120129
$user->maildisplay = 1;
121130
$user->emailstop = 0;
122131
}
@@ -140,16 +149,23 @@ public function execute($step, $trigger, $event, $stepresults) {
140149
throw new \invalid_response_exception('Tried but failed to send message.');
141150
}
142151

143-
$stepresults['email_action_messageid'] = $msgid;
144-
foreach ((array)$eventdata as $key => $value) {
152+
if ($firsteventdata === null) {
153+
$firsteventdata = $eventdata;
154+
$firstmsgid = $msgid;
155+
}
156+
}
157+
158+
if ($firsteventdata !== null) {
159+
$stepresults['email_action_messageid'] = $firstmsgid;
160+
foreach ((array)$firsteventdata as $key => $value) {
145161
if (is_scalar($value)) {
146162
$stepresults['email_action_' . $key] = $value;
147163
}
148164
}
149-
$stepresults['email_action_userfrom_id'] = $eventdata->userfrom->id;
150-
$stepresults['email_action_userfrom_email'] = $eventdata->userfrom->email;
151-
$stepresults['email_action_userto_id'] = $eventdata->userto->id;
152-
$stepresults['email_action_userto_email'] = $eventdata->userto->email;
165+
$stepresults['email_action_userfrom_id'] = $firsteventdata->userfrom->id;
166+
$stepresults['email_action_userfrom_email'] = $firsteventdata->userfrom->email;
167+
$stepresults['email_action_userto_id'] = $firsteventdata->userto->id;
168+
$stepresults['email_action_userto_email'] = $firsteventdata->userto->email;
153169
} else {
154170
$stepresults['email_action_messageid'] = false;
155171
}
@@ -164,13 +180,13 @@ public function execute($step, $trigger, $event, $stepresults) {
164180
public function form_definition_extra($form, $mform, $customdata) {
165181

166182
// To!
167-
$mform->addElement('text', 'emailto', get_string ('emailto', 'tool_trigger'));
183+
$mform->addElement('text', 'emailto', get_string('emailto', 'tool_trigger'));
168184
$mform->setType('emailto', PARAM_RAW_TRIMMED);
169185
$mform->addRule('emailto', get_string('required'), 'required');
170186
$mform->addHelpButton('emailto', 'emailto', 'tool_trigger');
171187

172188
// Subject!
173-
$mform->addElement('text', 'emailsubject', get_string ('emailsubject', 'tool_trigger'));
189+
$mform->addElement('text', 'emailsubject', get_string('emailsubject', 'tool_trigger'));
174190
$mform->setType('emailsubject', PARAM_RAW_TRIMMED);
175191
$mform->addRule('emailsubject', get_string('required'), 'required');
176192
$mform->addHelpButton('emailsubject', 'emailsubject', 'tool_trigger');
@@ -213,6 +229,5 @@ public static function add_privacy_metadata($collection, $privacyfields) {
213229
*/
214230
public static function get_fields() {
215231
return self::$stepfields;
216-
217232
}
218233
}

lang/en/tool_trigger.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
$string['emailsubject'] = 'Subject';
8989
$string['emailsubject_help'] = 'The text to use in the subject of the e-mail';
9090
$string['emailto'] = 'To';
91-
$string['emailto_help'] = 'Who to send the email to';
91+
$string['emailto_help'] = 'Who to send the email to. To send to multiple recipients, separate email addresses with commas.';
9292
$string['erroreditstep'] = 'Something went wrong while attempting to save the workflow step. Please try again.';
9393
$string['errorimportworkflow'] = 'Something went wrong while importing the workflow. Please try again.';
9494
$string['erroronfail'] = 'Error on failure';

tests/email_action_step_test.php

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
defined('MOODLE_INTERNAL') || die();
2020

2121
global $CFG;
22-
require_once(__DIR__.'/fixtures/user_event_fixture.php');
22+
require_once(__DIR__ . '/fixtures/user_event_fixture.php');
2323

2424
/**
2525
* Test of the email action
@@ -28,6 +28,7 @@
2828
* @author Aaron Wells <aaronw@catalyst.net.nz>
2929
* @copyright Catalyst IT 2018
3030
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31+
* @covers \tool_trigger\steps\actions\email_action_step
3132
*/
3233
final class email_action_step_test extends \advanced_testcase {
3334
use \tool_trigger_user_event_fixture;
@@ -60,7 +61,7 @@ public function test_execute_basic(): void {
6061
$step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings));
6162

6263
// Run the step.
63-
list($status) = $step->execute(null, null, $this->event, []);
64+
[$status] = $step->execute(null, null, $this->event, []);
6465
$this->assertTrue($status);
6566

6667
// Retrieve the messages sent (should be just one).
@@ -97,7 +98,7 @@ public function test_execute_external_email_address(): void {
9798
$step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings));
9899

99100
// Execute the step.
100-
list($status, $stepresults) = $step->execute(null, null, $this->event, []);
101+
[$status, $stepresults] = $step->execute(null, null, $this->event, []);
101102
$this->assertTrue($status);
102103

103104
// Retrieve the message.
@@ -118,6 +119,54 @@ public function test_execute_external_email_address(): void {
118119
);
119120
}
120121

122+
public function test_execute_multiple_email_addresses(): void {
123+
$emailstosend = [$this->user1->email, $this->user2->email, 'testusernotinmoodle@example.com'];
124+
$settings = [
125+
'emailto' => implode(",", $emailstosend),
126+
'emailsubject' => 'Subject of the email',
127+
'emailcontent_editor[text]' => 'Content of the email',
128+
'emailcontent_editor[format]' => 0,
129+
];
130+
$step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings));
131+
132+
// Execute the step.
133+
[$status, $stepresults] = $step->execute(null, null, $this->event, []);
134+
$this->assertTrue($status);
135+
136+
// Retrieve the messages.
137+
$messages = $this->sink->get_messages();
138+
$this->assertEquals(count($emailstosend), count($messages));
139+
140+
$this->assertEquals($this->user1->id, $messages[0]->useridto);
141+
$this->assertEquals($this->user2->id, $messages[1]->useridto);
142+
}
143+
144+
public function test_execute_multiple_email_addresses_with_datafields(): void {
145+
$emailstosend = [$this->user1->email, $this->user2->email, 'testusernotinmoodle@example.com'];
146+
$settings = [
147+
'emailto' => '{user_emails}',
148+
'emailsubject' => 'Subject of the email',
149+
'emailcontent_editor[text]' => 'Content of the email',
150+
'emailcontent_editor[format]' => 0,
151+
];
152+
$step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings));
153+
154+
// Ensure that this step can accept a string of emails from a previous step.
155+
// Not currently possible with existing steps.
156+
$emailstosend = [$this->user1->email, $this->user2->email];
157+
$prevstepresults = [
158+
'user_emails' => implode(',', $emailstosend),
159+
];
160+
161+
// Execute the step.
162+
[$status] = $step->execute(null, null, $this->event, $prevstepresults);
163+
$this->assertTrue($status);
164+
165+
// Retrieve the messages.
166+
$messages = $this->sink->get_messages();
167+
$this->assertEquals(count($emailstosend), count($messages));
168+
}
169+
121170
public function test_execute_with_datafields(): void {
122171
$settings = [
123172
'emailto' => '{user_email}',
@@ -134,7 +183,7 @@ public function test_execute_with_datafields(): void {
134183
];
135184

136185
// Run the step.
137-
list($status) = $step->execute(null, null, $this->event, $prevstepresults);
186+
[$status] = $step->execute(null, null, $this->event, $prevstepresults);
138187
$this->assertTrue($status);
139188

140189
// Retrieve the messages sent (should be just one).

0 commit comments

Comments
 (0)