Skip to content

Commit 60d5893

Browse files
authored
Merge branch 'feature/mailsettings' into fix/codecleanup
2 parents 2bb44ca + 0f45643 commit 60d5893

File tree

8 files changed

+333
-5
lines changed

8 files changed

+333
-5
lines changed

classes/task/send_daily_mail.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* Task schedule configuration for the plugintype_pluginname plugin.
19+
*
20+
* @package mod_moodleoverflow
21+
* @copyright 2023, Tamaro Walter
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
namespace mod_moodleoverflow\task;
25+
defined('MOODLE_INTERNAL') || die();
26+
/**
27+
* This task sends a daily mail of unread posts
28+
*/
29+
class send_daily_mail extends \core\task\scheduled_task {
30+
31+
/**
32+
* Return the task's name as shown in admin screens.
33+
*
34+
* @return string
35+
*/
36+
public function get_name() {
37+
return get_string('tasksenddailymail', 'mod_moodleoverflow');
38+
}
39+
40+
/**
41+
* Execute the task.
42+
*/
43+
public function execute() {
44+
global $DB;
45+
// Call your own api.
46+
$users = $DB->get_records_sql('SELECT DISTINCT userid FROM {moodleoverflow_mail_info}');
47+
if (empty($users)) {
48+
mtrace('No daily mail to send.');
49+
return;
50+
}
51+
foreach($users as $user) {
52+
$userdata = $DB->get_records('moodleoverflow_mail_info', array('userid' => $user->userid), 'courseid, forumid'); //order by courseid
53+
$mail = array();
54+
foreach($userdata as $row) {
55+
$currentcourse = $DB->get_record('course', array('id' => $row->courseid), 'fullname');
56+
$currentforum = $DB->get_record('moodleoverflow', array('id' => $row->forumid), 'name');
57+
$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $row->forumdiscussionid), 'name');
58+
$unreadposts = $row->numberofposts;
59+
$string = get_string('digestunreadpost', 'mod_moodleoverflow', array('currentcourse' => $currentcourse->fullname,
60+
'currentforum' => $currentforum->name,
61+
'discussion' => $discussion->name,
62+
'unreadposts' => $unreadposts));
63+
array_push($mail,$string);
64+
}
65+
$message = implode('<br>', $mail);
66+
// mtrace($message);.
67+
// send message to user.
68+
$userto = $DB->get_record('user', array('id' => $user->userid));
69+
$from = \core_user::get_noreply_user();
70+
$subject = get_string('tasksenddailymail', 'mod_moodleoverflow');
71+
72+
email_to_user($userto,$from, $subject,$message);
73+
}
74+
}
75+
}

db/install.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,22 @@
175175
<KEY NAME="moodleoverflowid" TYPE="foreign" FIELDS="moodleoverflowid" REFTABLE="moodleoverflow" REFFIELDS="id"/>
176176
</KEYS>
177177
</TABLE>
178+
<TABLE NAME="moodleoverflow_mail_info" COMMENT="represent the content of the digest mail">
179+
<FIELDS>
180+
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
181+
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true"/>
182+
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true"/>
183+
<FIELD NAME="forumid" TYPE="int" LENGTH="10" NOTNULL="true"/>
184+
<FIELD NAME="forumdiscussionid" TYPE="int" LENGTH="10" NOTNULL="true"/>
185+
<FIELD NAME="numberofposts" TYPE="int" LENGTH="10" NOTNULL="true"/>
186+
</FIELDS>
187+
<KEYS>
188+
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
189+
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
190+
<KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id"/>
191+
<KEY NAME="forumid" TYPE="foreign" FIELDS="forumid" REFTABLE="moodleoverflow" REFFIELDS="id"/>
192+
<KEY NAME="forumdiscussionid" TYPE="foreign" FIELDS="forumdiscussionid" REFTABLE="moodleoverflow_discussions" REFFIELDS="id"/>
193+
</KEYS>
194+
</TABLE>
178195
</TABLES>
179196
</XMLDB>

db/tasks.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,14 @@
4848
'dayofweek' => '*'
4949
),
5050

51+
// Clean old read records.
52+
array(
53+
'classname' => 'mod_moodleoverflow\task\send_daily_mail',
54+
'blocking' => 0,
55+
'minute' => '0',
56+
'hour' => '17',
57+
'day' => '*',
58+
'month' => '*',
59+
'dayofweek' => '*'
60+
)
5161
);

db/upgrade.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,31 @@ function xmldb_moodleoverflow_upgrade($oldversion) {
246246
upgrade_mod_savepoint(true, 2022110700, 'moodleoverflow');
247247
}
248248

249+
if($oldversion < 2023022400) {
250+
//Table for information of digest mail.
251+
$table = new xmldb_table('moodleoverflow_mail_info');
252+
253+
// Adding fields to table moodleoverflow_mail_info.
254+
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
255+
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
256+
$table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
257+
$table->add_field('forumid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
258+
$table->add_field('forumdiscussionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
259+
$table->add_field('numberofposts', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
260+
261+
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
262+
$table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
263+
$table->add_key('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
264+
$table->add_key('forumid', XMLDB_KEY_FOREIGN, array('forumid'), 'moodleoverflow', array('id'));
265+
$table->add_key('forumdiscussionid', XMLDB_KEY_FOREIGN, array('forumdiscussionid'), 'moodleoverflow_discussions', array('id'));
266+
267+
// Conditionally launch create table for moodleoverflow_mail_info.
268+
if (!$dbman->table_exists($table)) {
269+
$dbman->create_table($table);
270+
}
271+
272+
// Moodleoverflow savepoint reached.
273+
upgrade_mod_savepoint(true, 2023022400, 'moodleoverflow');
274+
}
249275
return true;
250276
}

lang/en/moodleoverflow.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@
210210
$string['crontask'] = 'Moodleoverflow maintenance jobs';
211211
$string['taskcleanreadrecords'] = 'Moodleoverflow maintenance job to clean old read records';
212212
$string['tasksendmails'] = 'Moodleoverflow maintenance job to send mails';
213+
$string['tasksenddailymail'] = 'Moodleoverflow job to send a daily mail of unread post';
213214
$string['nopermissiontosubscribe'] = 'You do not have the permission to view subscribers';
214215
$string['subscribeenrolledonly'] = 'Sorry, only enrolled users are allowed to subscribe to post notifications.';
215216
$string['everyonecannowchoose'] = 'Everyone can now choose to be subscribed';
@@ -453,3 +454,8 @@
453454
$string['your_post_was_rejected'] = 'Your post was rejected.';
454455
$string['your_post_was_rejected_with_reason'] = 'Your post was rejected with the following reason:';
455456
$string['original_post'] = 'Original post';
457+
458+
459+
// Daily mail message.
460+
$string['digestunreadpost'] = 'Course: {$a->currentcourse} -> {$a->currentforum}, Topic: {$a->discussion} has {$a->unreadposts} unread posts.';
461+

lib.php

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,19 +733,17 @@ function moodleoverflow_send_mails() {
733733
$errorcount[$postid] = 0;
734734
}
735735
}
736-
736+
737737
// Send mails to the users with information about the posts.
738738
if ($users && $posts) {
739-
740739
// Send one mail to every user.
741740
foreach ($users as $userto) {
742-
743741
// Terminate if the process takes more time then two minutes.
744742
core_php_time_limit::raise(120);
745743

746744
// Tracing information.
747745
mtrace('Processing user ' . $userto->id);
748-
746+
mtrace('Mail setting of user: ' . $userto->maildigest);
749747
// Initiate the user caches to save memory.
750748
$userto = clone($userto);
751749
$userto->ciewfullnames = array();
@@ -764,13 +762,43 @@ function moodleoverflow_send_mails() {
764762

765763
// Loop through all posts of this users.
766764
foreach ($posts as $postid => $post) {
765+
767766

768767
// Initiate variables for the post.
769768
$discussion = $discussions[$post->discussion];
770769
$moodleoverflow = $moodleoverflows[$discussion->moodleoverflow];
771770
$course = $courses[$moodleoverflow->course];
772771
$cm =& $coursemodules[$moodleoverflow->id];
773772

773+
/**
774+
* Check if user wants a resume
775+
* in this case: make a new dataset in "moodleoverflow_mail_info" to save the posts data
776+
* Dataset from moodleoverflow_mail_info will be send later in a mail
777+
*/
778+
$usermailsetting = $userto->maildigest;
779+
if($usermailsetting != 0) {
780+
$dataobject = new stdClass();
781+
$dataobject->userid = $userto->id;
782+
$dataobject->courseid = $course->id;
783+
$dataobject->forumid = $moodleoverflow->id;
784+
$dataobject->forumdiscussionid = $discussion->id;
785+
$record = $DB->get_record('moodleoverflow_mail_info', array( 'userid' => $dataobject->userid,
786+
'courseid' => $dataobject->courseid,
787+
'forumid' => $dataobject->forumid,
788+
'forumdiscussionid' => $dataobject->forumdiscussionid), 'numberofposts, id');
789+
if(is_object($record)) {
790+
$dataset = $record;
791+
$dataobject->numberofposts = $dataset->numberofposts + 1;
792+
$dataobject->id = $dataset->id;
793+
$DB->update_record('moodleoverflow_mail_info', $dataobject);
794+
}
795+
else {
796+
$dataobject->numberofposts = 1;
797+
$DB->insert_record('moodleoverflow_mail_info', $dataobject);
798+
}
799+
continue;
800+
}
801+
774802
// Check whether the user is subscribed.
775803
if (!isset($subscribedusers[$moodleoverflow->id][$userto->id])) {
776804
continue;

tests/dailymail_test.php

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* The module moodleoverflow tests.
19+
*
20+
* @package mod_moodleoverflow
21+
* @copyright 2023 Tamaro Walter
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
namespace mod_moodleoverflow;
25+
26+
use mod_moodleoverflow\task\send_mails;
27+
use mod_moodleoverflow\task\send_daily_mail;
28+
29+
defined('MOODLE_INTERNAL') || die();
30+
31+
global $CFG;
32+
require_once($CFG->dirroot . '/mod/moodleoverflow/lib.php');
33+
34+
class mod_moodleoverflow_dailymail_test extends \advanced_testcase {
35+
36+
private $sink;
37+
private $messagesink;
38+
private $course;
39+
private $user;
40+
private $moodleoverflow;
41+
private $discussion;
42+
43+
/**
44+
* Test setUp.
45+
*/
46+
public function setUp(): void {
47+
$this->resetAfterTest();
48+
set_config('maxeditingtime', -10, 'moodleoverflow');
49+
50+
unset_config('noemailever');
51+
$this->sink = $this->redirectEmails();
52+
53+
$this->preventResetByRollback();
54+
$this->messagesink = $this->redirectMessages();
55+
56+
// Create a new course with a moodleoverflow forum.
57+
$this->course = $this->getDataGenerator()->create_course();
58+
$location = array('course' => $this->course->id,'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
59+
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow',$location);
60+
61+
}
62+
63+
/**
64+
* Test tearDown.
65+
*/
66+
public function tearDown(): void {
67+
// Clear all caches.
68+
\mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
69+
\mod_moodleoverflow\subscriptions::reset_discussion_cache();
70+
}
71+
72+
/**
73+
* Function that creates a new user, which adds a new discussion an post to the moodleoverflow.
74+
*/
75+
public function helper_create_user_and_discussion($maildigest) {
76+
// Create a user enrolled in the course as student.
77+
$this->user = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'maildigest' => $maildigest));
78+
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, 'student');
79+
80+
//Create a new discussion and post within the moodleoverflow.
81+
$generator = $this->getDataGenerator()->get_plugin_generator('mod_moodleoverflow');
82+
$this->discussion = $generator->post_to_forum($this->moodleoverflow, $this->user);
83+
}
84+
85+
/**
86+
* Run the send daily mail task.
87+
* @return false|string
88+
*/
89+
private function run_send_daily_mail() {
90+
$mailtask = new send_daily_mail();
91+
ob_start();
92+
$mailtask->execute();
93+
$output = ob_get_contents();
94+
ob_end_clean();
95+
return $output;
96+
}
97+
98+
/**
99+
* Run the send mails task.
100+
* @return false|string
101+
*/
102+
private function run_send_mails() {
103+
$mailtask = new send_mails();
104+
ob_start();
105+
$mailtask->execute();
106+
$output = ob_get_contents();
107+
ob_end_clean();
108+
return $output;
109+
}
110+
111+
/**
112+
* Test if the task send_daily_mail sends a mail to the user
113+
*/
114+
public function test_mail_delivery() {
115+
global $DB;
116+
117+
// Create users with maildigest = on
118+
$this->helper_create_user_and_discussion('1');
119+
120+
// Send a mail and test if the mail was sent.
121+
122+
$this->run_send_mails(); //content2
123+
$this->run_send_daily_mail(); //content
124+
$messages = $this->sink->count();
125+
126+
$this->assertEquals(1, $messages);
127+
}
128+
129+
public function test_content_of_mail_delivery() {
130+
global $DB;
131+
132+
// Creat Users with maildigest = on.
133+
$this->helper_create_user_and_discussion('1');
134+
135+
//send the mails and count the messages.
136+
$this->run_send_mails();
137+
$content = $this->run_send_daily_mail();
138+
$messages = $this->sink->count();
139+
140+
//Build the text that the mail should have.
141+
//Text structure: $string['digestunreadpost'] = 'Course: {$a->currentcourse} -> {$a->currentforum}, Topic: {$a->discussion} has {$a->unreadposts} unread posts.';.
142+
$currentcourse = $this->course->fullname;
143+
$currentforum = $this->moodleoverflow->name;
144+
$currentdiscussion = $this->discussion[0]->name;
145+
$text = 'Course: ' . $currentcourse . ' -> ' . $currentforum . ', Topic: ' . $currentdiscussion . ' has ' . $messages . ' unread posts.';
146+
$content = str_replace("\r\n","",$content);
147+
$text = str_replace("\r\n","",$text);
148+
149+
//$this->assertisInt(0, strcmp($text, $content)); //strcmp compares 2 strings and retuns 0 if equal
150+
//$this->assertEquals($text, $content);
151+
$this->assertStringContainsString($text, $content);
152+
}
153+
154+
public function test_mail_not_send() {
155+
global $DB;
156+
// Creat Users with daily_mail = off.
157+
$this->helper_create_user_and_discussion('0');
158+
159+
// Now send the mails and test if no mail was sent.
160+
$this->run_send_mails();
161+
$this->run_send_daily_mail();
162+
$messages = $this->sink->count();
163+
164+
$this->assertEquals(0,$messages);
165+
}
166+
}

0 commit comments

Comments
 (0)