Skip to content

Commit 6f1d450

Browse files
authored
Merge pull request #212 from learnweb/redesign/mail
Redesign of the mail functionality
2 parents 1a1297e + 83af04c commit 6f1d450

16 files changed

+787
-1282
lines changed

classes/manager/mail_manager.php

Lines changed: 304 additions & 467 deletions
Large diffs are not rendered by default.

classes/output/moodleoverflow_email.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
namespace mod_moodleoverflow\output;
2626

2727
use mod_moodleoverflow\anonymous;
28+
use mod_moodleoverflow\subscriptions;
2829

2930
/**
3031
* Moodleoverflow email renderable for use in e-mail.
@@ -251,8 +252,7 @@ public function __set($name, $value) {
251252
public function get_unsubscribediscussionlink() {
252253

253254
// Check whether the moodleoverflow is subscribable.
254-
$subscribable = \mod_moodleoverflow\subscriptions::is_subscribable($this->moodleoverflow,
255-
\context_module::instance($this->cm->id));
255+
$subscribable = subscriptions::is_subscribable($this->moodleoverflow, \context_module::instance($this->cm->id));
256256
if (!$subscribable) {
257257
return null;
258258
}
@@ -432,7 +432,7 @@ public function get_replylink() {
432432
* @return string
433433
*/
434434
public function get_unsubscribemoodleoverflowlink() {
435-
if (!\mod_moodleoverflow\subscriptions::is_subscribable($this->moodleoverflow,
435+
if (!subscriptions::is_subscribable($this->moodleoverflow,
436436
\context_module::instance($this->cm->id))) {
437437
return null;
438438
}

classes/subscriptions.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,8 @@ public static function get_subscribed_users($moodleoverflow, $context, $fields =
536536

537537
// Default fields if none are submitted.
538538
if (empty($fields)) {
539-
if ($CFG->branch >= 311) {
540-
$allnames = \core_user\fields::for_name()->get_sql('u', false, '', '', false)->selects;
541-
} else {
542-
$allnames = get_all_user_name_fields(true, 'u');
543-
}
539+
$allnames = \core_user\fields::for_name()->get_sql('u', false, '', '', false)->selects;
540+
544541
$fields = "u.id, u.username, $allnames, u.maildisplay, u.mailformat, u.maildigest,
545542
u.imagealt, u.email, u.emailstop, u.city, u.country, u.lastaccess, u.lastlogin,
546543
u.picture, u.timezone, u.theme, u.lang, u.trackforums, u.mnethostid";

classes/task/send_daily_mail.php renamed to classes/task/send_daily_mails.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
/**
2727
* This task sends a daily mail of unread posts
2828
*/
29-
class send_daily_mail extends \core\task\scheduled_task {
29+
class send_daily_mails extends \core\task\scheduled_task {
3030

3131
/**
3232
* Return the task's name as shown in admin screens.
3333
*
3434
* @return string
3535
*/
3636
public function get_name() {
37-
return get_string('tasksenddailymail', 'mod_moodleoverflow');
37+
return get_string('tasksenddailymails', 'mod_moodleoverflow');
3838
}
3939

4040
/**
@@ -88,7 +88,7 @@ public function execute() {
8888
$message = implode('<br>', $mail);
8989
$userto = $DB->get_record('user', ['id' => $user->userid]);
9090
$from = \core_user::get_noreply_user();
91-
$subject = get_string('tasksenddailymail', 'mod_moodleoverflow');
91+
$subject = get_string('tasksenddailymails', 'mod_moodleoverflow');
9292
email_to_user($userto, $from, $subject, $message);
9393
$DB->delete_records('moodleoverflow_mail_info', ['userid' => $user->userid]);
9494
}

classes/task/send_mails.php

Lines changed: 21 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -18,151 +18,49 @@
1818
* A scheduled task for moodleoverflow cron.
1919
*
2020
* @package mod_moodleoverflow
21-
* @copyright 2017 Kennet Winter <k_wint10@uni-muenster.de>
21+
* @copyright 2025 Tamaro Walter
2222
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2323
*/
2424

2525
namespace mod_moodleoverflow\task;
2626

27-
use core\session\exception;
28-
use mod_moodleoverflow\anonymous;
29-
use mod_moodleoverflow\output\moodleoverflow_email;
30-
31-
defined('MOODLE_INTERNAL') || die();
32-
require_once(__DIR__ . '/../../locallib.php');
27+
use coding_exception;
28+
use core\notification;
29+
use Exception;
30+
use lang_string;
31+
use mod_moodleoverflow\manager\mail_manager;
3332

3433
/**
35-
* Class for sending mails to users who have subscribed a moodleoverflow.
34+
* Class for sending mails to users that need to review a moodleoverflow post.
3635
*
3736
* @package mod_moodleoverflow
38-
* @copyright 2017 Kennet Winter <k_wint10@uni-muenster.de>
37+
* @copyright 2025 Tamaro Walter
3938
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4039
*/
4140
class send_mails extends \core\task\scheduled_task {
4241

4342
/**
44-
* Get a descriptive name for this task (shown to admins).
43+
* Get a descriptive name for this task (shwon to admins).
4544
*
46-
* @return string
45+
* @return lang_string|string
46+
* @throws coding_exception
4747
*/
48-
public function get_name() {
48+
public function get_name(): lang_string|string {
4949
return get_string('tasksendmails', 'mod_moodleoverflow');
5050
}
5151

5252
/**
5353
* Runs moodleoverflow cron.
54+
*
55+
* @return bool
5456
*/
55-
public function execute() {
56-
57-
// Send mail notifications.
58-
moodleoverflow_send_mails();
59-
60-
$this->send_review_notifications();
61-
62-
// The cron is finished.
63-
return true;
64-
65-
}
66-
67-
/**
68-
* Sends initial notifications for needed reviews to all users with review capability.
69-
*/
70-
public function send_review_notifications() {
71-
global $DB, $OUTPUT, $PAGE, $CFG;
72-
73-
$rendererhtml = $PAGE->get_renderer('mod_moodleoverflow', 'email', 'htmlemail');
74-
$renderertext = $PAGE->get_renderer('mod_moodleoverflow', 'email', 'textemail');
75-
76-
$postinfos = $DB->get_records_sql(
77-
'SELECT p.*, d.course as cid, d.moodleoverflow as mid, d.id as did FROM {moodleoverflow_posts} p ' .
78-
'JOIN {moodleoverflow_discussions} d ON p.discussion = d.id ' .
79-
"WHERE p.mailed = :mailpending AND p.reviewed = 0 AND p.created < :timecutoff " .
80-
"ORDER BY d.course, d.moodleoverflow, d.id",
81-
[
82-
'mailpending' => MOODLEOVERFLOW_MAILED_PENDING,
83-
'timecutoff' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime'),
84-
]
85-
);
86-
87-
if (empty($postinfos)) {
88-
mtrace('No review notifications to send.');
89-
return;
90-
}
91-
92-
$course = null;
93-
$moodleoverflow = null;
94-
$usersto = null;
95-
$cm = null;
96-
$discussion = null;
97-
$success = [];
98-
99-
foreach ($postinfos as $postinfo) {
100-
if ($course == null || $course->id != $postinfo->cid) {
101-
$course = get_course($postinfo->cid);
102-
}
103-
104-
if ($moodleoverflow == null || $moodleoverflow->id != $postinfo->mid) {
105-
$cm = get_coursemodule_from_instance('moodleoverflow', $postinfo->mid, 0, false, MUST_EXIST);
106-
$modulecontext = \context_module::instance($cm->id);
107-
$userswithcapability = get_users_by_capability($modulecontext, 'mod/moodleoverflow:reviewpost');
108-
$coursecontext = \context_course::instance($course->id);
109-
$usersenrolled = get_enrolled_users($coursecontext);
110-
$usersto = [];
111-
foreach ($userswithcapability as $user) {
112-
if (in_array($user, $usersenrolled)) {
113-
array_push($usersto, $user);
114-
}
115-
}
116-
117-
$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $postinfo->mid], '*', MUST_EXIST);
118-
}
119-
120-
if ($discussion == null || $discussion->id != $postinfo->did) {
121-
$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $postinfo->did], '*', MUST_EXIST);
122-
}
123-
124-
$post = $postinfo;
125-
$userfrom = \core_user::get_user($postinfo->userid, '*', MUST_EXIST);
126-
$userfrom->anonymous = anonymous::is_post_anonymous($discussion, $moodleoverflow, $postinfo->userid);
127-
128-
foreach ($usersto as $userto) {
129-
try {
130-
// Check for moodle version. Version 401 supported until 8 December 2025.
131-
if ($CFG->branch >= 402) {
132-
\core\cron::setup_user($userto, $course);
133-
} else {
134-
cron_setup_user($userto, $course);
135-
}
136-
137-
$maildata = new moodleoverflow_email($course, $cm, $moodleoverflow, $discussion,
138-
$post, $userfrom, $userto, false);
139-
140-
$textcontext = $maildata->export_for_template($renderertext, true);
141-
$htmlcontext = $maildata->export_for_template($rendererhtml, false);
142-
143-
email_to_user(
144-
$userto,
145-
\core_user::get_noreply_user(),
146-
get_string('email_review_needed_subject', 'moodleoverflow', $textcontext),
147-
$OUTPUT->render_from_template('mod_moodleoverflow/email_review_needed_text', $textcontext),
148-
$OUTPUT->render_from_template('mod_moodleoverflow/email_review_needed_html', $htmlcontext)
149-
);
150-
} catch (exception $e) {
151-
mtrace("Error sending review notification for post $post->id to user $userto->id!");
152-
}
153-
}
154-
$success[] = $post->id;
155-
}
156-
157-
if (!empty($success)) {
158-
list($insql, $inparams) = $DB->get_in_or_equal($success);
159-
$DB->set_field_select(
160-
'moodleoverflow_posts', 'mailed', MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS,
161-
'id ' . $insql, $inparams
162-
);
163-
mtrace('Sent review notifications for ' . count($success) . ' posts successfully!');
57+
public function execute(): bool {
58+
try {
59+
mail_manager::moodleoverflow_send_mails();
60+
} catch (Exception $e) {
61+
notification::error(get_string('error_sending_mails', 'mod_moodleoverflow', $e->getMessage()));
62+
return false;
16463
}
64+
return true;
16565
}
166-
16766
}
168-

0 commit comments

Comments
 (0)