MDL-36941 core: added events for notifications

This commit is contained in:
Mark Nelson
2018-03-23 12:30:27 +08:00
parent 548936a6c9
commit 376a79c242
9 changed files with 371 additions and 12 deletions
+2
View File
@@ -45,6 +45,8 @@ $string['emailtagline'] = 'This is a copy of a message sent to you at "{$a->site
$string['enabled'] = 'Enabled';
$string['errorcallingprocessor'] = 'Error calling defined output';
$string['errortranslatingdefault'] = 'Error translating default setting provided by plugin, using system defaults instead.';
$string['eventnotificationviewed'] = 'Notification viewed';
$string['eventnotificationsent'] = 'Notification sent';
$string['eventmessagecontactadded'] = 'Message contact added';
$string['eventmessagecontactblocked'] = 'Message contact blocked';
$string['eventmessagecontactremoved'] = 'Message contact removed';
+144
View File
@@ -0,0 +1,144 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Notification sent event.
*
* @package core
* @copyright 2018 Mark Nelson <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\event;
defined('MOODLE_INTERNAL') || die();
/**
* Notification sent event class.
*
* @property-read array $other {
* Extra information about event.
*
* - int courseid: the id of the related course.
* }
*
* @package core
* @copyright 2018 Mark Nelson <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class notification_sent extends base {
/**
* Create event using ids.
*
* @param int $userfromid
* @param int $usertoid
* @param int $notificationid
* @param int $courseid course id the event is related with - SITEID if no relation exists.
* @return notification_sent
*/
public static function create_from_ids($userfromid, $usertoid, $notificationid, $courseid) {
// We may be sending a notification from the 'noreply' address, which means we are not actually sending a
// notification from a valid user. In this case, we will set the userid to 0.
// Check if the userid is valid.
if (!\core_user::is_real_user($userfromid)) {
$userfromid = 0;
}
$event = self::create(
[
'objectid' => $notificationid,
'userid' => $userfromid,
'context' => \context_system::instance(),
'relateduserid' => $usertoid,
'other' => [
'courseid' => $courseid
]
]
);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'notifications';
$this->data['crud'] = 'c';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventnotificationsent', 'message');
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/message/output/popup/notifications.php', array('notificationid' => $this->objectid));
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
// Check if we are sending from a valid user.
if (\core_user::is_real_user($this->userid)) {
return "The user with id '$this->userid' sent a notification to the user with id '$this->relateduserid'.";
}
return "A notification was sent by the system to the user with id '$this->relateduserid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
if (!isset($this->other['courseid'])) {
throw new \coding_exception('The \'courseid\' value must be set in other.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'notifications', 'restore' => base::NOT_MAPPED);
}
public static function get_other_mapping() {
$othermapped = array();
$othermapped['courseid'] = array('db' => 'course', 'restore' => base::NOT_MAPPED);
return $othermapped;
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Notification viewed event.
*
* @package core
* @copyright 2018 Mark Nelson <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\event;
defined('MOODLE_INTERNAL') || die();
/**
* Notification viewed event class.
*
* @package core
* @copyright 2018 Mark Nelson <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class notification_viewed extends base {
/**
* Create event using ids.
*
* @param int $userfromid
* @param int $usertoid
* @param int $notificationid
* @return notification_viewed
*/
public static function create_from_ids($userfromid, $usertoid, $notificationid) {
// We may be sending a notification from the 'noreply' address, which means we are not actually sending a
// notification from a valid user. In this case, we will set the userid to 0.
// Check if the userid is valid.
if (!\core_user::is_real_user($userfromid)) {
$userfromid = 0;
}
// Get the context for the user who received the notification.
$context = \context_user::instance($usertoid, IGNORE_MISSING);
// If the user no longer exists the context value will be false, in this case use the system context.
if ($context === false) {
$context = \context_system::instance();
}
$event = self::create(
[
'objectid' => $notificationid,
'userid' => $usertoid, // Using the user who read the notification as they are the ones performing the action.
'context' => $context,
'relateduserid' => $userfromid
]
);
return $event;
}
/**
* Init method.
*/
protected function init() {
$this->data['objecttable'] = 'notifications';
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_OTHER;
}
/**
* Returns localised general event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventnotificationviewed', 'message');
}
/**
* Returns relevant URL.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/message/output/popup/notifications.php', array('notificationid' => $this->objectid));
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' read a notification from the user with id '$this->relateduserid'.";
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
if (!isset($this->relateduserid)) {
throw new \coding_exception('The \'relateduserid\' must be set.');
}
}
public static function get_objectid_mapping() {
return array('db' => 'notifications', 'restore' => base::NOT_MAPPED);
}
}
+18 -4
View File
@@ -77,8 +77,15 @@ class manager {
require_once($CFG->dirroot.'/message/lib.php'); // This is most probably already included from messagelib.php file.
if (empty($processorlist)) {
// Trigger event for sending a message - we need to do this before marking as read!
if (!$eventdata->notification) {
// Trigger event for sending a message or notification - we need to do this before marking as read!
if ($eventdata->notification) {
\core\event\notification_sent::create_from_ids(
$eventdata->userfrom->id,
$eventdata->userto->id,
$savemessage->id,
$eventdata->courseid
)->trigger();
} else { // Must be a message.
\core\event\message_sent::create_from_ids(
$eventdata->userfrom->id,
$eventdata->userto->id,
@@ -145,8 +152,15 @@ class manager {
}
}
// Trigger event for sending a message - must be done before marking as read.
if (!$eventdata->notification) {
// Trigger event for sending a message or notification - we need to do this before marking as read!
if ($eventdata->notification) {
\core\event\notification_sent::create_from_ids(
$eventdata->userfrom->id,
$eventdata->userto->id,
$savemessage->id,
$eventdata->courseid
)->trigger();
} else { // Must be a message.
\core\event\message_sent::create_from_ids(
$eventdata->userfrom->id,
$eventdata->userto->id,
+3 -1
View File
@@ -483,7 +483,9 @@ class core_messagelib_testcase extends advanced_testcase {
$this->assertFalse($DB->record_exists('messages', array()));
$DB->delete_records('notifications', array());
$events = $eventsink->get_events();
$this->assertCount(0, $events);
$this->assertCount(2, $events);
$this->assertInstanceOf('\core\event\notification_sent', $events[0]);
$this->assertInstanceOf('\core\event\notification_viewed', $events[1]);
$eventsink->clear();
// Will always use the pop-up processor.
+7
View File
@@ -1105,6 +1105,13 @@ class api {
$updatenotification->timeread = $timeread;
$DB->update_record('notifications', $updatenotification);
// Trigger event for reading a notification.
\core\event\notification_viewed::create_from_ids(
$notification->useridfrom,
$notification->useridto,
$notification->id
)->trigger();
}
}
+64
View File
@@ -449,4 +449,68 @@ class core_message_events_testcase extends core_message_messagelib_testcase {
$i++;
}
}
/**
* Test the notification sent event.
*/
public function test_notification_sent() {
// Create a course.
$course = $this->getDataGenerator()->create_course();
// Create users to send notification between.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
// Send a notification.
$notificationid = $this->send_fake_message($user1, $user2, 'Hello world!', 1);
// Containing courseid.
$event = \core\event\notification_sent::create_from_ids($user1->id, $user2->id, $notificationid, $course->id);
// Trigger and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
$this->assertInstanceOf('\core\event\notification_sent', $event);
$this->assertEquals($notificationid, $event->objectid);
$this->assertEquals($user1->id, $event->userid);
$this->assertEquals($user2->id, $event->relateduserid);
$this->assertEquals(context_system::instance(), $event->get_context());
$this->assertEquals($course->id, $event->other['courseid']);
$url = new moodle_url('/message/output/popup/notifications.php', array('notificationid' => $event->objectid));
$this->assertEquals($url, $event->get_url());
}
/**
* Test the notification viewed event.
*/
public function test_notification_viewed() {
global $DB;
// Create users to send notifications between.
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
// Send a notification.
$notificationid = $this->send_fake_message($user1, $user2, 'Hello world!', 1);
// Trigger and capture the event.
$sink = $this->redirectEvents();
$notification = $DB->get_record('notifications', ['id' => $notificationid]);
\core_message\api::mark_notification_as_read($notification);
$events = $sink->get_events();
$event = reset($events);
// Check that the event data is valid.
$this->assertInstanceOf('\core\event\notification_viewed', $event);
$this->assertEquals($notificationid, $event->objectid);
$this->assertEquals($user2->id, $event->userid);
$this->assertEquals($user1->id, $event->relateduserid);
$this->assertEquals(context_user::instance($user2->id), $event->get_context());
$url = new moodle_url('/message/output/popup/notifications.php', array('notificationid' => $event->objectid));
$this->assertEquals($url, $event->get_url());
}
}
+6 -6
View File
@@ -1288,14 +1288,14 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
assign::cron();
$events = $sink->get_events();
// Two messages are sent, one to student and one to teacher. This generates
// Two notifications are sent, one to student and one to teacher. This generates
// four events:
// core\event\message_sent
// core\event\message_viewed
// core\event\message_sent
// core\event\message_viewed.
// core\event\notification_sent
// core\event\notification_viewed
// core\event\notification_sent
// core\event\notification_viewed.
$event = reset($events);
$this->assertInstanceOf('\core\event\message_sent', $event);
$this->assertInstanceOf('\core\event\notification_sent', $event);
$this->assertEquals($assign->get_course()->id, $event->other['courseid']);
$sink->close();
}
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2018032200.01; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2018032200.02; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.