From 2b595d96f4356ce09eb329ba8f945857cb50171e Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Mon, 5 Feb 2018 14:54:16 +0800 Subject: [PATCH] MDL-36941 core: added new mark notification as read webservice --- lib/db/services.php | 9 +++ message/externallib.php | 89 +++++++++++++++++++++++++++++- message/tests/externallib_test.php | 59 ++++++++++++++++++++ version.php | 2 +- 4 files changed, 156 insertions(+), 3 deletions(-) diff --git a/lib/db/services.php b/lib/db/services.php index 35ba7f998cf..55943d6a39e 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -990,6 +990,15 @@ $functions = array( 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), 'ajax' => true, ), + 'core_message_mark_notification_read' => array( + 'classname' => 'core_message_external', + 'methodname' => 'mark_notification_read', + 'classpath' => 'message/externallib.php', + 'description' => 'Mark a single notification as read, trigger notification_viewed event.', + 'type' => 'write', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + 'ajax' => true, + ), 'core_message_message_processor_config_form' => array( 'classname' => 'core_message_external', 'methodname' => 'message_processor_config_form', diff --git a/message/externallib.php b/message/externallib.php index 77f0418aa43..55fd542d43b 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -1871,7 +1871,7 @@ class core_message_external extends external_api { public static function mark_message_read_parameters() { return new external_function_parameters( array( - 'messageid' => new external_value(PARAM_INT, 'id of the message (in the message table)'), + 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'), 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read', VALUE_DEFAULT, 0) ) @@ -1948,7 +1948,92 @@ class core_message_external extends external_api { public static function mark_message_read_returns() { return new external_single_structure( array( - 'messageid' => new external_value(PARAM_INT, 'the id of the message in the message_read table'), + 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'), + 'warnings' => new external_warnings() + ) + ); + } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + */ + public static function mark_notification_read_parameters() { + return new external_function_parameters( + array( + 'notificationid' => new external_value(PARAM_INT, 'id of the notification'), + 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read', + VALUE_DEFAULT, 0) + ) + ); + } + + /** + * Mark a single notification as read. + * + * This will trigger a 'notification_viewed' event. + * + * @param int $notificationid id of the notification + * @param int $timeread timestamp for when the notification should be marked read + * @return external_description + * @throws invalid_parameter_exception + * @throws moodle_exception + */ + public static function mark_notification_read($notificationid, $timeread) { + global $CFG, $DB, $USER; + + // Check if private messaging between users is allowed. + if (empty($CFG->messaging)) { + throw new moodle_exception('disabled', 'message'); + } + + // Warnings array, it can be empty at the end but is mandatory. + $warnings = array(); + + // Validate params. + $params = array( + 'notificationid' => $notificationid, + 'timeread' => $timeread + ); + $params = self::validate_parameters(self::mark_notification_read_parameters(), $params); + + if (empty($params['timeread'])) { + $timeread = time(); + } else { + $timeread = $params['timeread']; + } + + // Validate context. + $context = context_system::instance(); + self::validate_context($context); + + $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST); + + if ($notification->useridto != $USER->id) { + throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' . + 'notification as read'); + } + + \core_message\api::mark_notification_as_read($notification, $timeread); + + $results = array( + 'notificationid' => $notification->id, + 'warnings' => $warnings + ); + + return $results; + } + + /** + * Returns description of method result value + * + * @return external_description + */ + public static function mark_notification_read_returns() { + return new external_single_structure( + array( + 'notificationid' => new external_value(PARAM_INT, 'id of the notification'), 'warnings' => new external_warnings() ) ); diff --git a/message/tests/externallib_test.php b/message/tests/externallib_test.php index edcbfa171cf..83122b2d1da 100644 --- a/message/tests/externallib_test.php +++ b/message/tests/externallib_test.php @@ -773,7 +773,66 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { } catch (invalid_parameter_exception $e) { $this->assertEquals('invalidparameter', $e->errorcode); } + } + /** + * Test mark_notification_read. + */ + public function test_mark_notification_read() { + $this->resetAfterTest(true); + + $user1 = self::getDataGenerator()->create_user(); + $user2 = self::getDataGenerator()->create_user(); + $user3 = self::getDataGenerator()->create_user(); + + // Login as user1. + $this->setUser($user1); + $this->assertEquals(array(), core_message_external::create_contacts( + array($user2->id, $user3->id))); + + // The user2 sends a couple of notifications to user1. + $this->send_message($user2, $user1, 'Hello there!', 1); + $this->send_message($user2, $user1, 'How you goin?', 1); + $this->send_message($user3, $user1, 'How you goin?', 1); + $this->send_message($user3, $user2, 'How you goin?', 1); + + // Retrieve all notifications sent by user2 (they are currently unread). + $lastnotifications = message_get_messages($user1->id, $user2->id, 1, false); + + $notificationids = array(); + foreach ($lastnotifications as $n) { + $notificationid = core_message_external::mark_notification_read($n->id, time()); + $notificationids[] = external_api::clean_returnvalue(core_message_external::mark_notification_read_returns(), + $notificationid); + } + + // Retrieve all notifications sent (they are currently read). + $lastnotifications = message_get_messages($user1->id, $user2->id, 1, true); + $this->assertCount(2, $lastnotifications); + $this->assertArrayHasKey($notificationids[1]['notificationid'], $lastnotifications); + $this->assertArrayHasKey($notificationids[0]['notificationid'], $lastnotifications); + + // Retrieve all notifications sent by any user (that are currently unread). + $lastnotifications = message_get_messages($user1->id, 0, 1, false); + $this->assertCount(1, $lastnotifications); + + // Invalid notification ids. + try { + $notificationid = core_message_external::mark_notification_read(1337, time()); + $this->fail('Exception expected due invalid notificationid.'); + } catch (dml_missing_record_exception $e) { + $this->assertEquals('invalidrecord', $e->errorcode); + } + + // A notification to a different user. + $lastnotifications = message_get_messages($user2->id, $user3->id, 1, false); + $notificationid = array_pop($lastnotifications)->id; + try { + $notificationid = core_message_external::mark_notification_read($notificationid, time()); + $this->fail('Exception expected due invalid notificationid.'); + } catch (invalid_parameter_exception $e) { + $this->assertEquals('invalidparameter', $e->errorcode); + } } /** diff --git a/version.php b/version.php index f6b43e78387..c910bfd2f1f 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2018032200.02; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2018032200.03; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.