From df2544ee7b54a015774eb859c536fb5aaf09fc30 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Fri, 7 Jun 2019 10:58:30 +0100 Subject: [PATCH] MDL-56389 message: allow marking notifications as read up to given time. --- message/classes/api.php | 7 +++++- message/externallib.php | 10 ++++++-- message/tests/externallib_test.php | 40 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/message/classes/api.php b/message/classes/api.php index 0b29e7c8acb..c26fe8bb35a 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -1730,9 +1730,10 @@ class api { * * @param int $touserid the id of the message recipient * @param int|null $fromuserid the id of the message sender, null if all messages + * @param int|null $timecreatedto mark notifications created before this time as read * @return void */ - public static function mark_all_notifications_as_read($touserid, $fromuserid = null) { + public static function mark_all_notifications_as_read($touserid, $fromuserid = null, $timecreatedto = null) { global $DB; $notificationsql = "SELECT n.* @@ -1744,6 +1745,10 @@ class api { $notificationsql .= " AND useridfrom = ?"; $notificationsparams[] = $fromuserid; } + if (!empty($timecreatedto)) { + $notificationsql .= " AND timecreated <= ?"; + $notificationsparams[] = $timecreatedto; + } $notifications = $DB->get_recordset_sql($notificationsql, $notificationsparams); foreach ($notifications as $notification) { diff --git a/message/externallib.php b/message/externallib.php index 3fbff4d2a2c..0b2ac87b942 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -3255,6 +3255,9 @@ class core_message_external extends external_api { 'useridfrom' => new external_value( PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user', VALUE_DEFAULT, 0), + 'timecreatedto' => new external_value( + PARAM_INT, 'mark messages created before this time as read, 0 for all messages', + VALUE_DEFAULT, 0), ) ); } @@ -3267,9 +3270,10 @@ class core_message_external extends external_api { * @throws moodle_exception * @param int $useridto the user id who received the message * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user + * @param int $timecreatedto mark message created before this time as read, 0 for all messages * @return external_description */ - public static function mark_all_notifications_as_read($useridto, $useridfrom) { + public static function mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto = 0) { global $USER; $params = self::validate_parameters( @@ -3277,6 +3281,7 @@ class core_message_external extends external_api { array( 'useridto' => $useridto, 'useridfrom' => $useridfrom, + 'timecreatedto' => $timecreatedto, ) ); @@ -3285,6 +3290,7 @@ class core_message_external extends external_api { $useridto = $params['useridto']; $useridfrom = $params['useridfrom']; + $timecreatedto = $params['timecreatedto']; if (!empty($useridto)) { if (core_user::is_real_user($useridto)) { @@ -3306,7 +3312,7 @@ class core_message_external extends external_api { throw new moodle_exception('accessdenied', 'admin'); } - \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom); + \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto); return true; } diff --git a/message/tests/externallib_test.php b/message/tests/externallib_test.php index 224a5878cc3..1f143991219 100644 --- a/message/tests/externallib_test.php +++ b/message/tests/externallib_test.php @@ -2117,6 +2117,46 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { $this->assertCount(0, $unreadnotifications); } + public function test_mark_all_notifications_as_read_time_created_to() { + global $DB; + + $this->resetAfterTest(true); + + $sender1 = $this->getDataGenerator()->create_user(); + $sender2 = $this->getDataGenerator()->create_user(); + + $recipient = $this->getDataGenerator()->create_user(); + $this->setUser($recipient); + + // Record messages as sent on one second intervals. + $time = time(); + + $this->send_message($sender1, $recipient, 'Message 1', 1, $time); + $this->send_message($sender2, $recipient, 'Message 2', 1, $time + 1); + $this->send_message($sender1, $recipient, 'Message 3', 1, $time + 2); + $this->send_message($sender2, $recipient, 'Message 4', 1, $time + 3); + + // Mark notifications sent from sender1 up until the second message; should only mark the first notification as read. + core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id, $time + 1); + + $params = [$recipient->id]; + + $this->assertEquals(1, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', $params)); + $this->assertEquals(3, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NULL', $params)); + + // Mark all notifications as read from any sender up to the time the third message was sent. + core_message_external::mark_all_notifications_as_read($recipient->id, 0, $time + 2); + + $this->assertEquals(3, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', $params)); + $this->assertEquals(1, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NULL', $params)); + + // Mark all notifications as read from any sender with a time after all messages were sent. + core_message_external::mark_all_notifications_as_read($recipient->id, 0, $time + 10); + + $this->assertEquals(4, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', $params)); + $this->assertEquals(0, $DB->count_records_select('notifications', 'useridto = ? AND timeread IS NULL', $params)); + } + /** * Test get_user_notification_preferences */