diff --git a/classes/steps/actions/email_action_step.php b/classes/steps/actions/email_action_step.php index ccac070..7cd957b 100644 --- a/classes/steps/actions/email_action_step.php +++ b/classes/steps/actions/email_action_step.php @@ -24,7 +24,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class email_action_step extends base_action_step { - use \tool_trigger\helper\datafield_manager; /** @@ -75,7 +74,9 @@ protected function init() { $this->emailsubject = $this->data['emailsubject']; $this->emailcontent = $this->data['emailcontent_editor[text]']; $this->messageplain = format_text_email( - $this->data['emailcontent_editor[text]'], $this->data['emailcontent_editor[format]']); + $this->data['emailcontent_editor[text]'], + $this->data['emailcontent_editor[format]'] + ); } /** @@ -106,17 +107,25 @@ public function execute($step, $trigger, $event, $stepresults) { $emailcontent = $this->render_datafields($this->emailcontent); $messageplain = $this->render_datafields($this->messageplain); - // Check we have a valid email address. - if ($emailto == clean_param($emailto, PARAM_EMAIL)) { + $recipients = array_map('trim', explode(',', $emailto)); + + $firsteventdata = null; + $firstmsgid = null; + + foreach ($recipients as $recipient) { + // Check we have a valid email address. + if ($recipient !== clean_param($recipient, PARAM_EMAIL)) { + continue; + } // Check if user exists and use user record. - $user = $DB->get_record('user', ['email' => $emailto, 'deleted' => 0]); + $user = $DB->get_record('user', ['email' => $recipient, 'deleted' => 0]); // If user not found, use noreply as a base. if (empty($user)) { $user = \core_user::get_noreply_user(); - $user->firstname = $emailto; - $user->email = $emailto; + $user->firstname = $recipient; + $user->email = $recipient; $user->maildisplay = 1; $user->emailstop = 0; } @@ -140,16 +149,23 @@ public function execute($step, $trigger, $event, $stepresults) { throw new \invalid_response_exception('Tried but failed to send message.'); } - $stepresults['email_action_messageid'] = $msgid; - foreach ((array)$eventdata as $key => $value) { + if ($firsteventdata === null) { + $firsteventdata = $eventdata; + $firstmsgid = $msgid; + } + } + + if ($firsteventdata !== null) { + $stepresults['email_action_messageid'] = $firstmsgid; + foreach ((array)$firsteventdata as $key => $value) { if (is_scalar($value)) { $stepresults['email_action_' . $key] = $value; } } - $stepresults['email_action_userfrom_id'] = $eventdata->userfrom->id; - $stepresults['email_action_userfrom_email'] = $eventdata->userfrom->email; - $stepresults['email_action_userto_id'] = $eventdata->userto->id; - $stepresults['email_action_userto_email'] = $eventdata->userto->email; + $stepresults['email_action_userfrom_id'] = $firsteventdata->userfrom->id; + $stepresults['email_action_userfrom_email'] = $firsteventdata->userfrom->email; + $stepresults['email_action_userto_id'] = $firsteventdata->userto->id; + $stepresults['email_action_userto_email'] = $firsteventdata->userto->email; } else { $stepresults['email_action_messageid'] = false; } @@ -164,13 +180,13 @@ public function execute($step, $trigger, $event, $stepresults) { public function form_definition_extra($form, $mform, $customdata) { // To! - $mform->addElement('text', 'emailto', get_string ('emailto', 'tool_trigger')); + $mform->addElement('text', 'emailto', get_string('emailto', 'tool_trigger')); $mform->setType('emailto', PARAM_RAW_TRIMMED); $mform->addRule('emailto', get_string('required'), 'required'); $mform->addHelpButton('emailto', 'emailto', 'tool_trigger'); // Subject! - $mform->addElement('text', 'emailsubject', get_string ('emailsubject', 'tool_trigger')); + $mform->addElement('text', 'emailsubject', get_string('emailsubject', 'tool_trigger')); $mform->setType('emailsubject', PARAM_RAW_TRIMMED); $mform->addRule('emailsubject', get_string('required'), 'required'); $mform->addHelpButton('emailsubject', 'emailsubject', 'tool_trigger'); @@ -213,6 +229,5 @@ public static function add_privacy_metadata($collection, $privacyfields) { */ public static function get_fields() { return self::$stepfields; - } } diff --git a/lang/en/tool_trigger.php b/lang/en/tool_trigger.php index 52924fd..e6db87b 100644 --- a/lang/en/tool_trigger.php +++ b/lang/en/tool_trigger.php @@ -88,7 +88,7 @@ $string['emailsubject'] = 'Subject'; $string['emailsubject_help'] = 'The text to use in the subject of the e-mail'; $string['emailto'] = 'To'; -$string['emailto_help'] = 'Who to send the email to'; +$string['emailto_help'] = 'Who to send the email to. To send to multiple recipients, separate email addresses with commas.'; $string['erroreditstep'] = 'Something went wrong while attempting to save the workflow step. Please try again.'; $string['errorimportworkflow'] = 'Something went wrong while importing the workflow. Please try again.'; $string['erroronfail'] = 'Error on failure'; diff --git a/tests/email_action_step_test.php b/tests/email_action_step_test.php index caa8a30..a8907e6 100644 --- a/tests/email_action_step_test.php +++ b/tests/email_action_step_test.php @@ -19,7 +19,7 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once(__DIR__.'/fixtures/user_event_fixture.php'); +require_once(__DIR__ . '/fixtures/user_event_fixture.php'); /** * Test of the email action @@ -28,6 +28,7 @@ * @author Aaron Wells * @copyright Catalyst IT 2018 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \tool_trigger\steps\actions\email_action_step */ final class email_action_step_test extends \advanced_testcase { use \tool_trigger_user_event_fixture; @@ -60,7 +61,7 @@ public function test_execute_basic(): void { $step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings)); // Run the step. - list($status) = $step->execute(null, null, $this->event, []); + [$status] = $step->execute(null, null, $this->event, []); $this->assertTrue($status); // Retrieve the messages sent (should be just one). @@ -97,7 +98,7 @@ public function test_execute_external_email_address(): void { $step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings)); // Execute the step. - list($status, $stepresults) = $step->execute(null, null, $this->event, []); + [$status, $stepresults] = $step->execute(null, null, $this->event, []); $this->assertTrue($status); // Retrieve the message. @@ -118,6 +119,54 @@ public function test_execute_external_email_address(): void { ); } + public function test_execute_multiple_email_addresses(): void { + $emailstosend = [$this->user1->email, $this->user2->email, 'testusernotinmoodle@example.com']; + $settings = [ + 'emailto' => implode(",", $emailstosend), + 'emailsubject' => 'Subject of the email', + 'emailcontent_editor[text]' => 'Content of the email', + 'emailcontent_editor[format]' => 0, + ]; + $step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings)); + + // Execute the step. + [$status, $stepresults] = $step->execute(null, null, $this->event, []); + $this->assertTrue($status); + + // Retrieve the messages. + $messages = $this->sink->get_messages(); + $this->assertEquals(count($emailstosend), count($messages)); + + $this->assertEquals($this->user1->id, $messages[0]->useridto); + $this->assertEquals($this->user2->id, $messages[1]->useridto); + } + + public function test_execute_multiple_email_addresses_with_datafields(): void { + $emailstosend = [$this->user1->email, $this->user2->email, 'testusernotinmoodle@example.com']; + $settings = [ + 'emailto' => '{user_emails}', + 'emailsubject' => 'Subject of the email', + 'emailcontent_editor[text]' => 'Content of the email', + 'emailcontent_editor[format]' => 0, + ]; + $step = new \tool_trigger\steps\actions\email_action_step(json_encode($settings)); + + // Ensure that this step can accept a string of emails from a previous step. + // Not currently possible with existing steps. + $emailstosend = [$this->user1->email, $this->user2->email]; + $prevstepresults = [ + 'user_emails' => implode(',', $emailstosend), + ]; + + // Execute the step. + [$status] = $step->execute(null, null, $this->event, $prevstepresults); + $this->assertTrue($status); + + // Retrieve the messages. + $messages = $this->sink->get_messages(); + $this->assertEquals(count($emailstosend), count($messages)); + } + public function test_execute_with_datafields(): void { $settings = [ 'emailto' => '{user_email}', @@ -134,7 +183,7 @@ public function test_execute_with_datafields(): void { ]; // Run the step. - list($status) = $step->execute(null, null, $this->event, $prevstepresults); + [$status] = $step->execute(null, null, $this->event, $prevstepresults); $this->assertTrue($status); // Retrieve the messages sent (should be just one).