1- From be38c7d7675cb5b5cc1673b1c4c9b2e0fe9a9509 Mon Sep 17 00:00:00 2001
1+ From f996d8c971e25b352725c00094da63c866facb61 Mon Sep 17 00:00:00 2001
22From: Matthew Hilton <matthewhilton@catalyst-au.net>
33Date: Thu, 6 Nov 2025 14:57:48 +1000
44Subject: [PATCH] MDL-69724 email: Add before_email_to_user hook
55
66---
77 .upgradenotes/MDL-69724-2025111105250585.yml | 9 ++
8- lib/moodlelib.php | 39 +++++
9- public/lib/classes/email.php | 149 ++++++++++++++++++
8+ lib/classes/email.php | 149 ++++++++++++++++++
109 .../hook/email/before_email_to_user.php | 41 +++++
10+ lib/moodlelib.php | 39 +++++
1111 4 files changed, 238 insertions(+)
1212 create mode 100644 .upgradenotes/MDL-69724-2025111105250585.yml
13- create mode 100644 public/ lib/classes/email.php
14- create mode 100644 public/ lib/classes/hook/email/before_email_to_user.php
13+ create mode 100644 lib/classes/email.php
14+ create mode 100644 lib/classes/hook/email/before_email_to_user.php
1515
1616diff --git a/.upgradenotes/MDL-69724-2025111105250585.yml b/.upgradenotes/MDL-69724-2025111105250585.yml
1717new file mode 100644
@@ -28,69 +28,11 @@ index 00000000000..8d72db9e8a1
2828+ headers, or add reasons to block the email. If any block reasons are
2929+ added, the email is stopped from being sent and the reasons are output.
3030+ type: improved
31- diff --git a/lib/moodlelib.php b/lib/moodlelib.php
32- index b734820bffc..289eef1a74d 100644
33- --- a/lib/moodlelib.php
34- +++ b/lib/moodlelib.php
35- @@ -29,7 +29,9 @@
36- */
37-
38- use core\di;
39- + use core\email;
40- use core\hook;
41- + use core\hook\email\before_email_to_user;
42-
43- defined('MOODLE_INTERNAL') || die();
44-
45- @@ -5580,6 +5582,43 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
46-
47- global $CFG, $PAGE, $SITE;
48-
49- + // Emit email to hook subscribers, who may modify the email.
50- + $email = new email(
51- + $user,
52- + $from,
53- + $subject,
54- + $messagetext,
55- + $messagehtml,
56- + $attachment,
57- + $attachname,
58- + $usetrueaddress,
59- + $replyto,
60- + $replytoname,
61- + $wordwrapwidth
62- + );
63- + $hook = new before_email_to_user($email);
64- + \core\di::get(\core\hook\manager::class)->dispatch($hook);
65- +
66- + // Read back out the data from the hook, as it may have been modified by a hook callback.
67- + $user = $hook->email->user;
68- + $from = $hook->email->from;
69- + $from->customheaders = $hook->email->get_additional_headers();
70- + $subject = $hook->email->subject;
71- + $messagetext = $hook->email->messagetext;
72- + $messagehtml = $hook->email->messagehtml;
73- + $attachment = $hook->email->attachment;
74- + $attachname = $hook->email->attachname;
75- + $usetrueaddress = $hook->email->usetrueaddress;
76- + $replyto = $hook->email->replyto;
77- + $replytoname = $hook->email->replytoname;
78- + $wordwrapwidth = $hook->email->wordwrapwidth;
79- +
80- + // Allow plugins to block this email - if blocked log why.
81- + if ($hook->email->is_blocked()) {
82- + debugging("email_to_user: blocked by hook subscriber: " . implode(', ', $hook->email->get_block_reasons()));
83- + return false;
84- + }
85- +
86- if (empty($user) or empty($user->id)) {
87- debugging('Can not send email to null user', DEBUG_DEVELOPER);
88- return false;
89- diff --git a/public/lib/classes/email.php b/public/lib/classes/email.php
31+ diff --git a/lib/classes/email.php b/lib/classes/email.php
9032new file mode 100644
9133index 00000000000..a080a5c0feb
9234--- /dev/null
93- +++ b/public/ lib/classes/email.php
35+ +++ b/lib/classes/email.php
9436@@ -0,0 +1,149 @@
9537+ <?php
9638+ // This file is part of Moodle - http://moodle.org/
@@ -241,11 +183,11 @@ index 00000000000..a080a5c0feb
241183+ return $this->additionalheaders;
242184+ }
243185+ }
244- diff --git a/public/ lib/classes/hook/email/before_email_to_user.php b/public /lib/classes/hook/email/before_email_to_user.php
186+ diff --git a/lib/classes/hook/email/before_email_to_user.php b/lib/classes/hook/email/before_email_to_user.php
245187new file mode 100644
246188index 00000000000..0dbcb427e1d
247189--- /dev/null
248- +++ b/public/ lib/classes/hook/email/before_email_to_user.php
190+ +++ b/lib/classes/hook/email/before_email_to_user.php
249191@@ -0,0 +1,41 @@
250192+ <?php
251193+ // This file is part of Moodle - http://moodle.org/
@@ -288,6 +230,64 @@ index 00000000000..0dbcb427e1d
288230+ ) {
289231+ }
290232+ }
233+ diff --git a/lib/moodlelib.php b/lib/moodlelib.php
234+ index b734820bffc..289eef1a74d 100644
235+ --- a/lib/moodlelib.php
236+ +++ b/lib/moodlelib.php
237+ @@ -29,7 +29,9 @@
238+ */
239+
240+ use core\di;
241+ + use core\email;
242+ use core\hook;
243+ + use core\hook\email\before_email_to_user;
244+
245+ defined('MOODLE_INTERNAL') || die();
246+
247+ @@ -5580,6 +5582,43 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
248+
249+ global $CFG, $PAGE, $SITE;
250+
251+ + // Emit email to hook subscribers, who may modify the email.
252+ + $email = new email(
253+ + $user,
254+ + $from,
255+ + $subject,
256+ + $messagetext,
257+ + $messagehtml,
258+ + $attachment,
259+ + $attachname,
260+ + $usetrueaddress,
261+ + $replyto,
262+ + $replytoname,
263+ + $wordwrapwidth
264+ + );
265+ + $hook = new before_email_to_user($email);
266+ + \core\di::get(\core\hook\manager::class)->dispatch($hook);
267+ +
268+ + // Read back out the data from the hook, as it may have been modified by a hook callback.
269+ + $user = $hook->email->user;
270+ + $from = $hook->email->from;
271+ + $from->customheaders = $hook->email->get_additional_headers();
272+ + $subject = $hook->email->subject;
273+ + $messagetext = $hook->email->messagetext;
274+ + $messagehtml = $hook->email->messagehtml;
275+ + $attachment = $hook->email->attachment;
276+ + $attachname = $hook->email->attachname;
277+ + $usetrueaddress = $hook->email->usetrueaddress;
278+ + $replyto = $hook->email->replyto;
279+ + $replytoname = $hook->email->replytoname;
280+ + $wordwrapwidth = $hook->email->wordwrapwidth;
281+ +
282+ + // Allow plugins to block this email - if blocked log why.
283+ + if ($hook->email->is_blocked()) {
284+ + debugging("email_to_user: blocked by hook subscriber: " . implode(', ', $hook->email->get_block_reasons()));
285+ + return false;
286+ + }
287+ +
288+ if (empty($user) or empty($user->id)) {
289+ debugging('Can not send email to null user', DEBUG_DEVELOPER);
290+ return false;
291291- -
2922922.43.0
293293
0 commit comments