mirror of
https://github.com/moodle/moodle.git
synced 2025-04-24 09:55:33 +02:00
MDL-54708 message: add backend APIs for notifications popover
This commit is contained in:
parent
12d8c7b222
commit
3274d5ca66
@ -537,6 +537,8 @@
|
||||
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="timeuserfromdeleted" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="timeusertodeleted" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="component" TYPE="char" LENGTH="200" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="eventtype" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
@ -563,6 +565,8 @@
|
||||
<FIELD NAME="timeread" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="timeuserfromdeleted" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="timeusertodeleted" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="component" TYPE="char" LENGTH="200" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="eventtype" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
|
@ -706,6 +706,31 @@ $functions = array(
|
||||
'description' => 'Retrieve a list of messages sent and received by a user (conversations, notifications or both)',
|
||||
'type' => 'read',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
'ajax' => true,
|
||||
),
|
||||
'core_message_get_notifications' => array(
|
||||
'classname' => 'core_message_external',
|
||||
'methodname' => 'get_notifications',
|
||||
'classpath' => 'message/externallib.php',
|
||||
'description' => 'Retrieve a list of notifications sent and received by a user',
|
||||
'type' => 'read',
|
||||
'ajax' => true,
|
||||
),
|
||||
'core_message_get_unread_notification_count' => array(
|
||||
'classname' => 'core_message_external',
|
||||
'methodname' => 'get_unread_notification_count',
|
||||
'classpath' => 'message/externallib.php',
|
||||
'description' => 'Retrieve the count of unread notifications for a given user',
|
||||
'type' => 'read',
|
||||
'ajax' => true,
|
||||
),
|
||||
'core_message_mark_all_notifications_as_read' => array(
|
||||
'classname' => 'core_message_external',
|
||||
'methodname' => 'mark_all_notifications_as_read',
|
||||
'classpath' => 'message/externallib.php',
|
||||
'description' => 'Retrieve the count of unread notifications for a given user',
|
||||
'type' => 'write',
|
||||
'ajax' => true,
|
||||
),
|
||||
'core_message_mark_message_read' => array(
|
||||
'classname' => 'core_message_external',
|
||||
|
@ -2228,5 +2228,44 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2016100501.00);
|
||||
}
|
||||
|
||||
if ($oldversion < 2016100700.01) {
|
||||
// Define field component to be added to message.
|
||||
$table = new xmldb_table('message');
|
||||
$field = new xmldb_field('component', XMLDB_TYPE_CHAR, '200', null, null, null, null, 'timeusertodeleted');
|
||||
|
||||
// Conditionally launch add field component.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Define field eventtype to be added to message.
|
||||
$field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
|
||||
|
||||
// Conditionally launch add field eventtype.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Define field component to be added to message_read.
|
||||
$table = new xmldb_table('message_read');
|
||||
$field = new xmldb_field('component', XMLDB_TYPE_CHAR, '200', null, null, null, null, 'timeusertodeleted');
|
||||
|
||||
// Conditionally launch add field component.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Define field eventtype to be added to message_read.
|
||||
$field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
|
||||
|
||||
// Conditionally launch add field eventtype.
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2016100700.01);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -127,6 +127,8 @@ function message_send($eventdata) {
|
||||
$savemessage->fullmessagehtml = $eventdata->fullmessagehtml;
|
||||
$savemessage->smallmessage = $eventdata->smallmessage;
|
||||
$savemessage->notification = $eventdata->notification;
|
||||
$savemessage->eventtype = $eventdata->name;
|
||||
$savemessage->component = $eventdata->component;
|
||||
|
||||
if (!empty($eventdata->contexturl)) {
|
||||
$savemessage->contexturl = (string)$eventdata->contexturl;
|
||||
|
@ -160,7 +160,16 @@ class renderer_base {
|
||||
throw new moodle_exception('Unknown template: ' . $templatename);
|
||||
}
|
||||
}
|
||||
return trim($template->render($context));
|
||||
|
||||
$renderedTemplate = trim($template->render($context));
|
||||
|
||||
// If we had an existing uniqid helper then we need to restore it to allow
|
||||
// handle nested calls of render_from_template.
|
||||
if ($uniqidHelper) {
|
||||
$mustache->addHelper('uniqid', $uniqidHelper);
|
||||
}
|
||||
|
||||
return $renderedTemplate;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1176,6 +1176,390 @@ class core_message_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notifications parameters description.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function get_notifications_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
|
||||
'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),
|
||||
'status' => new external_value(
|
||||
PARAM_ALPHA, 'filter the results to just "read" or "unread" notifications',
|
||||
VALUE_DEFAULT, ''),
|
||||
'embeduserto' => new external_value(
|
||||
PARAM_BOOL, 'true for returning user details for the recipient in each notification',
|
||||
VALUE_DEFAULT, false),
|
||||
'embeduserfrom' => new external_value(
|
||||
PARAM_BOOL, 'true for returning user details for the sender in each notification',
|
||||
VALUE_DEFAULT, false),
|
||||
'newestfirst' => new external_value(
|
||||
PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
|
||||
VALUE_DEFAULT, true),
|
||||
'markasread' => new external_value(
|
||||
PARAM_BOOL, 'mark notifications as read when they are returned by this function',
|
||||
VALUE_DEFAULT, false),
|
||||
'limit' => new external_value(PARAM_INT, 'the number of results to return', VALUE_DEFAULT, 0),
|
||||
'offset' => new external_value(PARAM_INT, 'offset the result set by a given amount', VALUE_DEFAULT, 0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notifications function.
|
||||
*
|
||||
* @since 3.2
|
||||
* @throws invalid_parameter_exception
|
||||
* @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 string $status filter the results to only read or unread notifications
|
||||
* @param bool $embeduserto true to embed the recipient user details in the record for each notification
|
||||
* @param bool $embeduserfrom true to embed the send user details in the record for each notification
|
||||
* @param bool $newestfirst true for ordering by newest first, false for oldest first
|
||||
* @param bool $markasread mark notifications as read when they are returned by this function
|
||||
* @param int $limit the number of results to return
|
||||
* @param int $offset offset the result set by a given amount
|
||||
* @return external_description
|
||||
*/
|
||||
public static function get_notifications($useridto, $useridfrom, $status, $embeduserto, $embeduserfrom, $newestfirst, $markasread, $limit, $offset) {
|
||||
global $CFG, $USER, $OUTPUT;
|
||||
|
||||
$params = self::validate_parameters(
|
||||
self::get_notifications_parameters(),
|
||||
array(
|
||||
'useridto' => $useridto,
|
||||
'useridfrom' => $useridfrom,
|
||||
'status' => $status,
|
||||
'embeduserto' => $embeduserto,
|
||||
'embeduserfrom' => $embeduserfrom,
|
||||
'newestfirst' => $newestfirst,
|
||||
'markasread' => $markasread,
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
)
|
||||
);
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
|
||||
$useridto = $params['useridto'];
|
||||
$useridfrom = $params['useridfrom'];
|
||||
$status = $params['status'];
|
||||
$embeduserto = $params['embeduserto'];
|
||||
$embeduserfrom = $params['embeduserfrom'];
|
||||
$newestfirst = $params['newestfirst'];
|
||||
$markasread = $params['markasread'];
|
||||
$limit = $params['limit'];
|
||||
$offset = $params['offset'];
|
||||
|
||||
if (!empty($useridto)) {
|
||||
if (core_user::is_real_user($useridto)) {
|
||||
if ($embeduserto) {
|
||||
$userto = core_user::get_user($useridto, '*', MUST_EXIST);
|
||||
}
|
||||
} else {
|
||||
throw new moodle_exception('invaliduser');
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($useridfrom) && $embeduserfrom) {
|
||||
// We use get_user here because the from user can be the noreply or support user.
|
||||
$userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
// Check if the current user is the sender/receiver or just a privileged user.
|
||||
if ($useridto != $USER->id and $useridfrom != $USER->id and
|
||||
!has_capability('moodle/site:readallmessages', $context)) {
|
||||
throw new moodle_exception('accessdenied', 'admin');
|
||||
}
|
||||
|
||||
$sort = $newestfirst ? 'DESC' : 'ASC';
|
||||
$notifications = message_get_notifications($useridto, $useridfrom, $status, $embeduserto, $embeduserfrom, $sort, $limit, $offset);
|
||||
|
||||
if ($notifications) {
|
||||
// In some cases, we don't need to get the to/from user objects from the sql query.
|
||||
$userfromfullname = '';
|
||||
$usertofullname = '';
|
||||
|
||||
// In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
|
||||
if (!empty($useridto) && $embeduserto) {
|
||||
$usertofullname = fullname($userto);
|
||||
// The user from may or may not be filled.
|
||||
if (!empty($useridfrom) && $embeduserfrom) {
|
||||
$userfromfullname = fullname($userfrom);
|
||||
}
|
||||
} else if (!empty($useridfrom) && $embeduserfrom) {
|
||||
// If the useridto field is empty, the useridfrom must be filled.
|
||||
$userfromfullname = fullname($userfrom);
|
||||
}
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
|
||||
if (($useridto == $USER->id and $notification->timeusertodeleted) or
|
||||
($useridfrom == $USER->id and $notification->timeuserfromdeleted)) {
|
||||
|
||||
$notification->deleted = true;
|
||||
} else {
|
||||
$notification->deleted = false;
|
||||
}
|
||||
|
||||
// We need to get the user from the query.
|
||||
if ($embeduserfrom) {
|
||||
if (empty($userfromfullname)) {
|
||||
// Check for non-reply and support users.
|
||||
if (core_user::is_real_user($notification->useridfrom)) {
|
||||
$user = new stdClass();
|
||||
$user = username_load_fields_from_object($user, $notification, 'userfrom');
|
||||
$profileurl = new moodle_url('/user/profile.php', array('id' => $notification->useridfrom));
|
||||
$notification->userfromfullname = fullname($user);
|
||||
$notification->userfromprofileurl = $profileurl->out();
|
||||
} else {
|
||||
$notification->userfromfullname = get_string('coresystem');
|
||||
}
|
||||
} else {
|
||||
$notification->userfromfullname = $userfromfullname;
|
||||
}
|
||||
}
|
||||
|
||||
// We need to get the user from the query.
|
||||
if ($embeduserto) {
|
||||
if (empty($usertofullname)) {
|
||||
$user = new stdClass();
|
||||
$user = username_load_fields_from_object($user, $notification, 'userto');
|
||||
$notification->usertofullname = fullname($user);
|
||||
} else {
|
||||
$notification->usertofullname = $usertofullname;
|
||||
}
|
||||
}
|
||||
|
||||
$notification->timecreatedpretty = get_string('ago', 'message', format_time(time() - $notification->timecreated));
|
||||
$notification->text = message_format_message_text($notification);
|
||||
$notification->read = $notification->timeread ? true : false;
|
||||
|
||||
if (!empty($notification->component) && substr($notification->component, 0, 4) == 'mod_') {
|
||||
$iconurl = $OUTPUT->pix_url('icon', $notification->component);
|
||||
} else {
|
||||
$iconurl = $OUTPUT->pix_url('i/marker', 'core');
|
||||
}
|
||||
|
||||
$notification->iconurl = $iconurl->out();
|
||||
|
||||
if ($markasread && !$notification->read) {
|
||||
// Have to clone here because this function mutates the given data. Naughty, naughty...
|
||||
message_mark_message_read(clone $notification, time());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'notifications' => $notifications,
|
||||
'unreadcount' => message_count_unread_notifications($useridto, $useridfrom),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notifications return description.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function get_notifications_returns() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'notifications' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Notification id (this is not guaranteed to be unique within this result set)'),
|
||||
'useridfrom' => new external_value(PARAM_INT, 'User from id'),
|
||||
'useridto' => new external_value(PARAM_INT, 'User to id'),
|
||||
'subject' => new external_value(PARAM_TEXT, 'The notification subject'),
|
||||
'text' => new external_value(PARAM_RAW, 'The message text formated'),
|
||||
'fullmessage' => new external_value(PARAM_RAW, 'The message'),
|
||||
'fullmessageformat' => new external_format_value('fullmessage'),
|
||||
'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
|
||||
'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
|
||||
'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
|
||||
'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
|
||||
'timecreated' => new external_value(PARAM_INT, 'Time created'),
|
||||
'timecreatedpretty' => new external_value(PARAM_TEXT, 'Time created in a pretty format'),
|
||||
'timeread' => new external_value(PARAM_INT, 'Time read'),
|
||||
'usertofullname' => new external_value(PARAM_TEXT, 'User to full name', VALUE_OPTIONAL),
|
||||
'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name', VALUE_OPTIONAL),
|
||||
'userfromprofileurl' => new external_value(PARAM_URL, 'User from profile url', VALUE_OPTIONAL),
|
||||
'read' => new external_value(PARAM_BOOL, 'notification read status'),
|
||||
'deleted' => new external_value(PARAM_BOOL, 'notification deletion status'),
|
||||
'iconurl' => new external_value(PARAM_URL, 'URL for notification icon'),
|
||||
'component' => new external_value(PARAM_TEXT, 'The component that generated the notification', VALUE_OPTIONAL),
|
||||
'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL),
|
||||
), 'message'
|
||||
)
|
||||
),
|
||||
'unreadcount' => new external_value(PARAM_INT, 'the user whose blocked users we want to retrieve'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all notifications as read parameters description.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function mark_all_notifications_as_read_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
|
||||
'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),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all notifications as read function.
|
||||
*
|
||||
* @since 3.2
|
||||
* @throws invalid_parameter_exception
|
||||
* @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
|
||||
* @return external_description
|
||||
*/
|
||||
public static function mark_all_notifications_as_read($useridto, $useridfrom) {
|
||||
global $CFG, $USER;
|
||||
|
||||
$params = self::validate_parameters(
|
||||
self::mark_all_notifications_as_read_parameters(),
|
||||
array(
|
||||
'useridto' => $useridto,
|
||||
'useridfrom' => $useridfrom,
|
||||
)
|
||||
);
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
|
||||
$useridto = $params['useridto'];
|
||||
$useridfrom = $params['useridfrom'];
|
||||
|
||||
if (!empty($useridto)) {
|
||||
if (core_user::is_real_user($useridto)) {
|
||||
$userto = core_user::get_user($useridto, '*', MUST_EXIST);
|
||||
} else {
|
||||
throw new moodle_exception('invaliduser');
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($useridfrom)) {
|
||||
// We use get_user here because the from user can be the noreply or support user.
|
||||
$userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
// Check if the current user is the sender/receiver or just a privileged user.
|
||||
if ($useridto != $USER->id and $useridfrom != $USER->id and
|
||||
// deleteanymessage seems more reasonable here than readallmessages.
|
||||
!has_capability('moodle/site:deleteanymessage', $context)) {
|
||||
throw new moodle_exception('accessdenied', 'admin');
|
||||
}
|
||||
|
||||
message_mark_all_read_for_user($useridto, $useridfrom, 'notification');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all notifications as read return description.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function mark_all_notifications_as_read_returns() {
|
||||
return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unread notification count parameters description.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function get_unread_notification_count_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
|
||||
'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),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unread notification count function.
|
||||
*
|
||||
* @since 3.2
|
||||
* @throws invalid_parameter_exception
|
||||
* @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
|
||||
* @return external_description
|
||||
*/
|
||||
public static function get_unread_notification_count($useridto, $useridfrom) {
|
||||
global $CFG, $USER;
|
||||
|
||||
$params = self::validate_parameters(
|
||||
self::get_unread_notification_count_parameters(),
|
||||
array(
|
||||
'useridto' => $useridto,
|
||||
'useridfrom' => $useridfrom,
|
||||
)
|
||||
);
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
|
||||
$useridto = $params['useridto'];
|
||||
$useridfrom = $params['useridfrom'];
|
||||
|
||||
if (!empty($useridto)) {
|
||||
if (core_user::is_real_user($useridto)) {
|
||||
$userto = core_user::get_user($useridto, '*', MUST_EXIST);
|
||||
} else {
|
||||
throw new moodle_exception('invaliduser');
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($useridfrom)) {
|
||||
// We use get_user here because the from user can be the noreply or support user.
|
||||
$userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
|
||||
}
|
||||
|
||||
// Check if the current user is the sender/receiver or just a privileged user.
|
||||
if ($useridto != $USER->id and $useridfrom != $USER->id and
|
||||
!has_capability('moodle/site:readallmessages', $context)) {
|
||||
throw new moodle_exception('accessdenied', 'admin');
|
||||
}
|
||||
|
||||
return message_count_unread_notifications($useridto, $useridfrom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unread notification count return description.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function get_unread_notification_count_returns() {
|
||||
return new external_value(PARAM_INT, 'the user whose blocked users we want to retrieve');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blocked users parameters description.
|
||||
*
|
||||
|
156
message/lib.php
156
message/lib.php
@ -47,6 +47,12 @@ define('MESSAGE_SEARCH_MAX_RESULTS', 200);
|
||||
define('MESSAGE_CONTACTS_PER_PAGE',10);
|
||||
define('MESSAGE_MAX_COURSE_NAME_LENGTH', 30);
|
||||
|
||||
define('MESSAGE_UNREAD','unread');
|
||||
define('MESSAGE_READ','read');
|
||||
define('MESSAGE_TYPE_NOTIFICATION','notification');
|
||||
define('MESSAGE_TYPE_MESSAGE','message');
|
||||
|
||||
|
||||
/**
|
||||
* Define contants for messaging default settings population. For unambiguity of
|
||||
* plugin developer intentions we use 4-bit value (LSB numbering):
|
||||
@ -1467,10 +1473,42 @@ function message_move_userfrom_unread2read($userid) {
|
||||
* @return void
|
||||
*/
|
||||
function message_mark_messages_read($touserid, $fromuserid) {
|
||||
return message_mark_all_read_for_user($touserid, $fromuserid);
|
||||
}
|
||||
|
||||
/**
|
||||
* marks ALL messages being sent from $fromuserid to $touserid as read. Can
|
||||
* be filtered by type.
|
||||
*
|
||||
* @param int $touserid the id of the message recipient
|
||||
* @param int $fromuserid the id of the message sender
|
||||
* @param string $type filter the messages by type, either MESSAGE_TYPE_NOTIFICATION, MESSAGE_TYPE_MESSAGE or '' for all.
|
||||
* @return void
|
||||
*/
|
||||
function message_mark_all_read_for_user($touserid, $fromuserid = 0, $type = '') {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT m.* FROM {message} m WHERE m.useridto=:useridto AND m.useridfrom=:useridfrom';
|
||||
$messages = $DB->get_recordset_sql($sql, array('useridto' => $touserid,'useridfrom' => $fromuserid));
|
||||
$params = array();
|
||||
$where = '';
|
||||
|
||||
if (!empty($touserid)) {
|
||||
$params['useridto'] = $touserid;
|
||||
}
|
||||
|
||||
if (!empty($fromuserid)) {
|
||||
$params['useridfrom'] = $fromuserid;
|
||||
}
|
||||
|
||||
if (!empty($type)) {
|
||||
if (strtolower($type) == MESSAGE_TYPE_NOTIFICATION) {
|
||||
$params['notification'] = 1;
|
||||
} else if (strtolower($type) == MESSAGE_TYPE_MESSAGE) {
|
||||
$params['notification'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = sprintf('SELECT m.* FROM {message} m WHERE m.%s = ?', implode('= ? AND m.', array_keys($params)));
|
||||
$messages = $DB->get_recordset_sql($sql, array_values($params));
|
||||
|
||||
foreach ($messages as $message) {
|
||||
message_mark_message_read($message, time());
|
||||
@ -1770,6 +1808,120 @@ function message_get_messages($useridto, $useridfrom = 0, $notifications = -1, $
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get notifications to and from the specified users.
|
||||
*
|
||||
* @param int $useridto the user id who received the notification
|
||||
* @param int $useridfrom the user id who sent the notification. -10 or -20 for no-reply or support user
|
||||
* @param bool $status MESSAGE_READ for retrieving read notifications, MESSAGE_UNREAD for unread, empty for both
|
||||
* @param string $sort the column name to order by including optionally direction
|
||||
* @param bool $embeduserto embed the to user details in the notification response
|
||||
* @param bool $embeduserfrom embed the from user details in the notification response
|
||||
* @param int $limit limit the number of result returned
|
||||
* @param int $offset offset the result set by this amount
|
||||
* @return array array of notification records
|
||||
* @since 3.1
|
||||
*/
|
||||
function message_get_notifications($useridto = 0, $useridfrom = 0, $status = '',
|
||||
$embeduserto = false, $embeduserfrom = false, $sort = 'DESC', $limit = 0, $offset = 0) {
|
||||
global $DB;
|
||||
|
||||
if (!empty($status) && $status != MESSAGE_READ && $status != MESSAGE_UNREAD) {
|
||||
throw new moodle_exception(sprintf('invalid parameter: status: must be "%s" or "%s"',
|
||||
MESSAGE_READ, MESSAGE_UNREAD));
|
||||
}
|
||||
|
||||
$sort = strtoupper($sort);
|
||||
if ($sort != 'DESC' && $sort != 'ASC') {
|
||||
throw new moodle_exception('invalid parameter: sort: must be "DESC" or "ASC"');
|
||||
}
|
||||
|
||||
$params = array();
|
||||
|
||||
$buildtablesql = function($table, $prefix, $additionalfields) use ($useridto, $useridfrom, $embeduserto, $embeduserfrom) {
|
||||
$params = array();
|
||||
$fields = "concat('$prefix', $prefix.id) as uniqueid, $prefix.id, $prefix.useridfrom, $prefix.useridto,
|
||||
$prefix.subject, $prefix.fullmessage, $prefix.fullmessageformat,
|
||||
$prefix.fullmessagehtml, $prefix.smallmessage, $prefix.notification, $prefix.contexturl,
|
||||
$prefix.contexturlname, $prefix.timecreated, $prefix.timeuserfromdeleted, $prefix.timeusertodeleted,
|
||||
$prefix.component, $prefix.eventtype, $additionalfields";
|
||||
$where = '';
|
||||
$joinsql = '';
|
||||
|
||||
if (empty($useridto)) {
|
||||
$where .= " AND $prefix.useridfrom = :{$prefix}useridfrom";
|
||||
$params["{$prefix}useridfrom"] = $useridfrom;
|
||||
} else {
|
||||
$where .= " AND $prefix.useridto = :{$prefix}useridto";
|
||||
$params["{$prefix}useridto"] = $useridto;
|
||||
|
||||
if (!empty($useridfrom)) {
|
||||
$where .= " AND $prefix.useridfrom = :{$prefix}useridfrom";
|
||||
$params["{$prefix}useridfrom"] = $useridfrom;
|
||||
}
|
||||
}
|
||||
|
||||
if ($embeduserto) {
|
||||
$embedprefix = "{$prefix}ut";
|
||||
$fields .= ", " . get_all_user_name_fields(true, $embedprefix, '', 'userto');
|
||||
$joinsql .= " LEFT JOIN {user} $embedprefix ON $embedprefix.id = $prefix.useridto";
|
||||
}
|
||||
|
||||
if ($embeduserfrom) {
|
||||
$embedprefix = "{$prefix}uf";
|
||||
$fields .= ", " . get_all_user_name_fields(true, $embedprefix, '', 'userfrom');
|
||||
$joinsql .= " LEFT JOIN {user} $embedprefix ON $embedprefix.id = $prefix.useridfrom";
|
||||
}
|
||||
|
||||
return array(sprintf("SELECT %s FROM %s %s %s WHERE %s.notification = 1 %s", $fields, $table, $prefix, $joinsql, $prefix, $where), $params);
|
||||
};
|
||||
|
||||
$sql = '';
|
||||
switch ($status) {
|
||||
case MESSAGE_READ:
|
||||
list($sql, $readparams) = $buildtablesql('{message_read}', 'r', 'r.timeread');
|
||||
$params = array_merge($params, $readparams);
|
||||
break;
|
||||
case MESSAGE_UNREAD:
|
||||
list($sql, $unreadparams) = $buildtablesql('{message}', 'u', '0 as timeread');
|
||||
$params = array_merge($params, $unreadparams);
|
||||
break;
|
||||
default:
|
||||
list($readsql, $readparams) = $buildtablesql('{message_read}', 'r', 'r.timeread');
|
||||
list($unreadsql, $unreadparams) = $buildtablesql('{message}', 'u', '0 as timeread');
|
||||
$sql = sprintf("SELECT * FROM (%s UNION %s) f", $readsql, $unreadsql);
|
||||
$params = array_merge($params, $readparams, $unreadparams);
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY timecreated $sort, timeread $sort, id $sort";
|
||||
|
||||
return array_values($DB->get_records_sql($sql, $params, $offset, $limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the unread notifications for a user.
|
||||
*
|
||||
* @param int $useridto the user id who received the notification
|
||||
* @param int $useridfrom the user id who sent the notification. -10 or -20 for no-reply or support user
|
||||
* @return int count of the unread notifications
|
||||
* @since 3.1
|
||||
*/
|
||||
function message_count_unread_notifications($useridto = 0, $useridfrom = 0) {
|
||||
global $USER, $DB;
|
||||
|
||||
if (empty($useridto)) {
|
||||
$useridto = $USER->id;
|
||||
}
|
||||
|
||||
if (!empty($useridfrom)) {
|
||||
return $DB->count_records_select('message', "useridto = ? AND useridfrom = ? AND notification = 1",
|
||||
array($useridto, $useridfrom), "COUNT('id')");
|
||||
} else {
|
||||
return $DB->count_records_select('message', "useridto = ? AND notification = 1",
|
||||
array($useridto), "COUNT('id')");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires the JS libraries to send a message using a dialog.
|
||||
*
|
||||
|
@ -63,6 +63,63 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
|
||||
$insert = $DB->insert_record('message', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a fake unread notification.
|
||||
*
|
||||
* {@link message_send()} does not support transaction, this function will simulate a message
|
||||
* sent from a user to another. We should stop using it once {@link message_send()} will support
|
||||
* transactions. This is not clean at all, this is just used to add rows to the table.
|
||||
*
|
||||
* @param stdClass $userfrom user object of the one sending the message.
|
||||
* @param stdClass $userto user object of the one receiving the message.
|
||||
* @param string $message message to send.
|
||||
* @param int $timecreated time the message was created.
|
||||
* @return int the id of the message
|
||||
*/
|
||||
protected function send_fake_unread_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0) {
|
||||
global $DB;
|
||||
|
||||
$record = new stdClass();
|
||||
$record->useridfrom = $userfrom->id;
|
||||
$record->useridto = $userto->id;
|
||||
$record->notification = 1;
|
||||
$record->subject = 'No subject';
|
||||
$record->fullmessage = $message;
|
||||
$record->smallmessage = $message;
|
||||
$record->timecreated = $timecreated ? $timecreated : time();
|
||||
|
||||
return $DB->insert_record('message', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a fake read notification.
|
||||
*
|
||||
* {@link message_send()} does not support transaction, this function will simulate a message
|
||||
* sent from a user to another. We should stop using it once {@link message_send()} will support
|
||||
* transactions. This is not clean at all, this is just used to add rows to the table.
|
||||
*
|
||||
* @param stdClass $userfrom user object of the one sending the message.
|
||||
* @param stdClass $userto user object of the one receiving the message.
|
||||
* @param string $message message to send.
|
||||
* @param int $timecreated time the message was created.
|
||||
* @return int the id of the message
|
||||
*/
|
||||
protected function send_fake_read_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0, $timeread = 0) {
|
||||
global $DB;
|
||||
|
||||
$record = new stdClass();
|
||||
$record->useridfrom = $userfrom->id;
|
||||
$record->useridto = $userto->id;
|
||||
$record->notification = 1;
|
||||
$record->subject = 'No subject';
|
||||
$record->fullmessage = $message;
|
||||
$record->smallmessage = $message;
|
||||
$record->timecreated = $timecreated ? $timecreated : time();
|
||||
$record->timeread = $timeread ? $timeread : time();
|
||||
|
||||
return $DB->insert_record('message_read', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test send_instant_messages
|
||||
*/
|
||||
@ -821,4 +878,214 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
|
||||
|
||||
}
|
||||
|
||||
public function test_get_notifications_no_user_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::get_notifications(-2132131, 0, '', false, false, true, false, 0, 0);
|
||||
}
|
||||
|
||||
public function test_get_notifications_access_denied_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($user);
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::get_notifications($sender->id, 0, '', false, false, true, false, 0, 0);
|
||||
}
|
||||
|
||||
public function test_get_notifications_as_recipient() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Sendy', 'lastname' => 'Sender'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Recipy', 'lastname' => 'Recipient'));
|
||||
|
||||
$notificationids = array(
|
||||
$this->send_fake_unread_notification($sender, $recipient),
|
||||
$this->send_fake_unread_notification($sender, $recipient),
|
||||
$this->send_fake_read_notification($sender, $recipient),
|
||||
$this->send_fake_read_notification($sender, $recipient),
|
||||
);
|
||||
|
||||
// Confirm that admin has super powers to retrieve any notifications.
|
||||
$this->setAdminUser();
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, '', false, false, true, false, 0, 0);
|
||||
$this->assertCount(4, $result['notifications']);
|
||||
|
||||
$this->setUser($recipient);
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, '', false, false, true, false, 0, 0);
|
||||
$this->assertCount(4, $result['notifications']);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, MESSAGE_UNREAD, false, true, true, false, 0, 0);
|
||||
$this->assertCount(2, $result['notifications']);
|
||||
$this->assertObjectHasAttribute('userfromfullname', $result['notifications'][0]);
|
||||
$this->assertObjectNotHasAttribute('usertofullname', $result['notifications'][0]);
|
||||
$this->assertObjectHasAttribute('userfromfullname', $result['notifications'][1]);
|
||||
$this->assertObjectNotHasAttribute('usertofullname', $result['notifications'][1]);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, MESSAGE_UNREAD, true, true, true, false, 0, 0);
|
||||
$this->assertCount(2, $result['notifications']);
|
||||
$this->assertObjectHasAttribute('userfromfullname', $result['notifications'][0]);
|
||||
$this->assertObjectHasAttribute('usertofullname', $result['notifications'][0]);
|
||||
$this->assertObjectHasAttribute('userfromfullname', $result['notifications'][1]);
|
||||
$this->assertObjectHasAttribute('usertofullname', $result['notifications'][1]);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, MESSAGE_UNREAD, true, true, true, true, 0, 0);
|
||||
$this->assertCount(2, $result['notifications']);
|
||||
$this->assertEquals(0, $result['unreadcount']);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, MESSAGE_UNREAD, true, true, true, true, 0, 0);
|
||||
$this->assertCount(0, $result['notifications']);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, MESSAGE_READ, true, true, true, true, 0, 0);
|
||||
$this->assertCount(4, $result['notifications']);
|
||||
}
|
||||
|
||||
public function test_get_notification_limit_offset() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Sendy', 'lastname' => 'Sender'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Recipy', 'lastname' => 'Recipient'));
|
||||
|
||||
$this->setUser($recipient);
|
||||
|
||||
$notificationids = array(
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Notification', 1),
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Notification', 2),
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Notification', 3),
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Notification', 4),
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Notification', 5),
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Notification', 6),
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Notification', 7),
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Notification', 8),
|
||||
);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, '', false, false, true, false, 2, 0);
|
||||
|
||||
$this->assertEquals($result['notifications'][0]->id, $notificationids[7]);
|
||||
$this->assertEquals($result['notifications'][1]->id, $notificationids[6]);
|
||||
|
||||
$result = core_message_external::get_notifications($recipient->id, 0, '', false, false, true, false, 2, 2);
|
||||
|
||||
$this->assertEquals($result['notifications'][0]->id, $notificationids[5]);
|
||||
$this->assertEquals($result['notifications'][1]->id, $notificationids[4]);
|
||||
}
|
||||
|
||||
public function test_mark_all_notifications_as_read_invalid_user_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::mark_all_notifications_as_read(-2132131, 0);
|
||||
}
|
||||
|
||||
public function test_mark_all_notifications_as_read_access_denied_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($user);
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::mark_all_notifications_as_read($sender->id, 0);
|
||||
}
|
||||
|
||||
public function test_mark_all_notifications_as_read_missing_from_user_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($sender);
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::mark_all_notifications_as_read($sender->id, 99999);
|
||||
}
|
||||
|
||||
public function test_mark_all_notifications_as_read() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender1 = $this->getDataGenerator()->create_user();
|
||||
$sender2 = $this->getDataGenerator()->create_user();
|
||||
$sender3 = $this->getDataGenerator()->create_user();
|
||||
$recipient = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($recipient);
|
||||
|
||||
$notificationids = array(
|
||||
$this->send_fake_unread_notification($sender1, $recipient, 'Notification', 1),
|
||||
$this->send_fake_unread_notification($sender1, $recipient, 'Notification', 2),
|
||||
$this->send_fake_unread_notification($sender2, $recipient, 'Notification', 3),
|
||||
$this->send_fake_unread_notification($sender2, $recipient, 'Notification', 4),
|
||||
$this->send_fake_unread_notification($sender3, $recipient, 'Notification', 5),
|
||||
$this->send_fake_unread_notification($sender3, $recipient, 'Notification', 6),
|
||||
);
|
||||
|
||||
core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id);
|
||||
$readresult = core_message_external::get_notifications($recipient->id, 0, 'read', false, false, true, false, 0, 0);
|
||||
$unreadresult = core_message_external::get_notifications($recipient->id, 0, 'unread', false, false, true, false, 0, 0);
|
||||
|
||||
$this->assertCount(2, $readresult['notifications']);
|
||||
$this->assertCount(4, $unreadresult['notifications']);
|
||||
|
||||
core_message_external::mark_all_notifications_as_read($recipient->id, 0);
|
||||
$readresult = core_message_external::get_notifications($recipient->id, 0, 'read', false, false, true, false, 0, 0);
|
||||
$unreadresult = core_message_external::get_notifications($recipient->id, 0, 'unread', false, false, true, false, 0, 0);
|
||||
|
||||
$this->assertCount(6, $readresult['notifications']);
|
||||
$this->assertCount(0, $unreadresult['notifications']);
|
||||
}
|
||||
|
||||
public function test_get_unread_notification_count_invalid_user_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::get_unread_notification_count(-2132131, 0);
|
||||
}
|
||||
|
||||
public function test_get_unread_notification_count_access_denied_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($user);
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::get_unread_notification_count($sender->id, 0);
|
||||
}
|
||||
|
||||
public function test_get_unread_notification_count_missing_from_user_exception() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($sender);
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$result = core_message_external::get_unread_notification_count($sender->id, 99999);
|
||||
}
|
||||
|
||||
public function test_get_unread_notification_count() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$sender1 = $this->getDataGenerator()->create_user();
|
||||
$sender2 = $this->getDataGenerator()->create_user();
|
||||
$sender3 = $this->getDataGenerator()->create_user();
|
||||
$recipient = $this->getDataGenerator()->create_user();
|
||||
|
||||
$this->setUser($recipient);
|
||||
|
||||
$notificationids = array(
|
||||
$this->send_fake_unread_notification($sender1, $recipient, 'Notification', 1),
|
||||
$this->send_fake_unread_notification($sender1, $recipient, 'Notification', 2),
|
||||
$this->send_fake_unread_notification($sender2, $recipient, 'Notification', 3),
|
||||
$this->send_fake_unread_notification($sender2, $recipient, 'Notification', 4),
|
||||
$this->send_fake_unread_notification($sender3, $recipient, 'Notification', 5),
|
||||
$this->send_fake_unread_notification($sender3, $recipient, 'Notification', 6),
|
||||
);
|
||||
|
||||
$count = core_message_external::get_unread_notification_count($recipient->id, $sender1->id);
|
||||
$this->assertEquals($count, 2);
|
||||
|
||||
$count = core_message_external::get_unread_notification_count($recipient->id, 0);
|
||||
$this->assertEquals($count, 6);
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,63 @@ class core_message_messagelib_testcase extends advanced_testcase {
|
||||
return $DB->insert_record('message', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a fake unread notification.
|
||||
*
|
||||
* {@link message_send()} does not support transaction, this function will simulate a message
|
||||
* sent from a user to another. We should stop using it once {@link message_send()} will support
|
||||
* transactions. This is not clean at all, this is just used to add rows to the table.
|
||||
*
|
||||
* @param stdClass $userfrom user object of the one sending the message.
|
||||
* @param stdClass $userto user object of the one receiving the message.
|
||||
* @param string $message message to send.
|
||||
* @param int $timecreated time the message was created.
|
||||
* @return int the id of the message
|
||||
*/
|
||||
protected function send_fake_unread_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0) {
|
||||
global $DB;
|
||||
|
||||
$record = new stdClass();
|
||||
$record->useridfrom = $userfrom->id;
|
||||
$record->useridto = $userto->id;
|
||||
$record->notification = 1;
|
||||
$record->subject = 'No subject';
|
||||
$record->fullmessage = $message;
|
||||
$record->smallmessage = $message;
|
||||
$record->timecreated = $timecreated ? $timecreated : time();
|
||||
|
||||
return $DB->insert_record('message', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a fake read notification.
|
||||
*
|
||||
* {@link message_send()} does not support transaction, this function will simulate a message
|
||||
* sent from a user to another. We should stop using it once {@link message_send()} will support
|
||||
* transactions. This is not clean at all, this is just used to add rows to the table.
|
||||
*
|
||||
* @param stdClass $userfrom user object of the one sending the message.
|
||||
* @param stdClass $userto user object of the one receiving the message.
|
||||
* @param string $message message to send.
|
||||
* @param int $timecreated time the message was created.
|
||||
* @return int the id of the message
|
||||
*/
|
||||
protected function send_fake_read_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0, $timeread = 0) {
|
||||
global $DB;
|
||||
|
||||
$record = new stdClass();
|
||||
$record->useridfrom = $userfrom->id;
|
||||
$record->useridto = $userto->id;
|
||||
$record->notification = 1;
|
||||
$record->subject = 'No subject';
|
||||
$record->fullmessage = $message;
|
||||
$record->smallmessage = $message;
|
||||
$record->timecreated = $timecreated ? $timecreated : time();
|
||||
$record->timeread = $timeread ? $timeread : time();
|
||||
|
||||
return $DB->insert_record('message_read', $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test message_get_blocked_users.
|
||||
*/
|
||||
@ -870,4 +927,337 @@ class core_message_messagelib_testcase extends advanced_testcase {
|
||||
|
||||
$this->assertTrue(message_is_user_blocked($recipient, $sender));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function will return only read notifications if requested.
|
||||
*/
|
||||
public function test_message_get_notifications_read_only() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 1', 2);
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 2', 4);
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, MESSAGE_READ);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 1');
|
||||
|
||||
// Check if we request read and unread but there are only read messages, it should
|
||||
// still return those correctly.
|
||||
$notifications = message_get_notifications($recipient->id, 0, '');
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function will return only unread notifications if requested.
|
||||
*/
|
||||
public function test_message_get_notifications_unread_only() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 1', 2);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 2', 4);
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, MESSAGE_UNREAD);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 1');
|
||||
|
||||
// Check if we request read and unread but there are only read messages, it should
|
||||
// still return those correctly.
|
||||
$notifications = message_get_notifications($recipient->id, 0, '');
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function will return the correct notifications when both
|
||||
* read and unread notifications are included.
|
||||
*/
|
||||
public function test_message_get_notifications_mixed() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 1', 1);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 2', 2);
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 3', 3, 1);
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 4', 3, 2);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 5', 4);
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 5');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 4');
|
||||
$this->assertEquals($notifications[2]->fullmessage, 'Message 3');
|
||||
$this->assertEquals($notifications[3]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[4]->fullmessage, 'Message 1');
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, MESSAGE_READ);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 4');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 3');
|
||||
$this->assertEquals($notifications[2]->fullmessage, 'Message 1');
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, MESSAGE_UNREAD);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 5');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function works correctly with limiting and offsetting
|
||||
* the result set if requested.
|
||||
*/
|
||||
public function test_message_get_notifications_all_with_limit_and_offset() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 1', 1);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 2', 2);
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 3', 3, 1);
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 4', 3, 2);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 5', 4);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 6', 5);
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, '', false, false, 'DESC', 2, 0);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 6');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 5');
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, '', false, false, 'DESC', 2, 2);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 4');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 3');
|
||||
|
||||
$notifications = message_get_notifications($recipient->id, 0, '', false, false, 'DESC', 0, 3);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 3');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[2]->fullmessage, 'Message 1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function returns correct values if specifying
|
||||
* a sender.
|
||||
*/
|
||||
public function test_message_get_notifications_multiple_senders() {
|
||||
$sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
|
||||
$recipient1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
$recipient2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test4', 'lastname' => 'User4'));
|
||||
|
||||
$this->send_fake_read_notification($sender1, $recipient1, 'Message 1', 1);
|
||||
$this->send_fake_unread_notification($sender1, $recipient1, 'Message 2', 2);
|
||||
$this->send_fake_read_notification($sender1, $recipient2, 'Message 3', 3);
|
||||
$this->send_fake_unread_notification($sender1, $recipient2, 'Message 4', 4);
|
||||
$this->send_fake_read_notification($sender2, $recipient1, 'Message 5', 5);
|
||||
$this->send_fake_unread_notification($sender2, $recipient1, 'Message 6', 6);
|
||||
$this->send_fake_read_notification($sender2, $recipient2, 'Message 7', 7);
|
||||
$this->send_fake_unread_notification($sender2, $recipient2, 'Message 8', 8);
|
||||
|
||||
$notifications = message_get_notifications(0, $sender1->id, '', false, false, 'DESC');
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 4');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 3');
|
||||
$this->assertEquals($notifications[2]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[3]->fullmessage, 'Message 1');
|
||||
|
||||
$notifications = message_get_notifications(0, $sender1->id, '', false, false, 'DESC', 2, 2);
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 1');
|
||||
|
||||
$notifications = message_get_notifications($recipient1->id, $sender1->id, '', false, false, 'DESC');
|
||||
|
||||
$this->assertEquals($notifications[0]->fullmessage, 'Message 2');
|
||||
$this->assertEquals($notifications[1]->fullmessage, 'Message 1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function returns embedded user details for the
|
||||
* sender if requested.
|
||||
*/
|
||||
public function test_message_get_notifications_embed_sender() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 1', 1);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 2', 2);
|
||||
|
||||
$notifications = message_get_notifications(0, $sender->id, '', false, true, 'DESC');
|
||||
|
||||
$func = function($type) {
|
||||
return function($notification) use ($type) {
|
||||
$user = new stdClass();
|
||||
$user = username_load_fields_from_object($user, $notification, $type);
|
||||
return $user;
|
||||
};
|
||||
};
|
||||
$senders = array_map($func('userfrom'), $notifications);
|
||||
$recipients = array_map($func('userto'), $notifications);
|
||||
|
||||
$this->assertEquals($senders[0]->firstname, 'Test1');
|
||||
$this->assertEquals($senders[0]->lastname, 'User1');
|
||||
$this->assertEquals($senders[1]->firstname, 'Test1');
|
||||
$this->assertEquals($senders[1]->lastname, 'User1');
|
||||
|
||||
// Make sure we didn't get recipient details when they weren't requested.
|
||||
$this->assertEmpty($recipients[0]->firstname);
|
||||
$this->assertEmpty($recipients[0]->lastname);
|
||||
$this->assertEmpty($recipients[1]->firstname);
|
||||
$this->assertEmpty($recipients[1]->lastname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function returns embedded user details for the
|
||||
* recipient if requested.
|
||||
*/
|
||||
public function test_message_get_notifications_embed_recipient() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 1', 1);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 2', 2);
|
||||
|
||||
$notifications = message_get_notifications(0, $sender->id, '', true, false, 'DESC');
|
||||
|
||||
$func = function($type) {
|
||||
return function($notification) use ($type) {
|
||||
$user = new stdClass();
|
||||
$user = username_load_fields_from_object($user, $notification, $type);
|
||||
return $user;
|
||||
};
|
||||
};
|
||||
$senders = array_map($func('userfrom'), $notifications);
|
||||
$recipients = array_map($func('userto'), $notifications);
|
||||
|
||||
$this->assertEquals($recipients[0]->firstname, 'Test2');
|
||||
$this->assertEquals($recipients[0]->lastname, 'User2');
|
||||
$this->assertEquals($recipients[1]->firstname, 'Test2');
|
||||
$this->assertEquals($recipients[1]->lastname, 'User2');
|
||||
|
||||
// Make sure we didn't get sender details when they weren't requested.
|
||||
$this->assertEmpty($senders[0]->firstname);
|
||||
$this->assertEmpty($senders[0]->lastname);
|
||||
$this->assertEmpty($senders[1]->firstname);
|
||||
$this->assertEmpty($senders[1]->lastname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the message_get_notifications function returns embedded all user details.
|
||||
*/
|
||||
public function test_message_get_notifications_embed_both() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_read_notification($sender, $recipient, 'Message 1', 1);
|
||||
$this->send_fake_unread_notification($sender, $recipient, 'Message 2', 2);
|
||||
|
||||
$notifications = message_get_notifications(0, $sender->id, '', true, true, 'DESC');
|
||||
|
||||
$func = function($type) {
|
||||
return function($notification) use ($type) {
|
||||
$user = new stdClass();
|
||||
$user = username_load_fields_from_object($user, $notification, $type);
|
||||
return $user;
|
||||
};
|
||||
};
|
||||
$senders = array_map($func('userfrom'), $notifications);
|
||||
$recipients = array_map($func('userto'), $notifications);
|
||||
|
||||
$this->assertEquals($recipients[0]->firstname, 'Test2');
|
||||
$this->assertEquals($recipients[0]->lastname, 'User2');
|
||||
$this->assertEquals($recipients[1]->firstname, 'Test2');
|
||||
$this->assertEquals($recipients[1]->lastname, 'User2');
|
||||
|
||||
// Make sure we didn't get sender details when they weren't requested.
|
||||
$this->assertEquals($senders[0]->firstname, 'Test1');
|
||||
$this->assertEquals($senders[0]->lastname, 'User1');
|
||||
$this->assertEquals($senders[1]->firstname, 'Test1');
|
||||
$this->assertEquals($senders[1]->lastname, 'User1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test message_count_unread_notifications.
|
||||
*/
|
||||
public function test_message_count_unread_notifications() {
|
||||
$sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
$recipient1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
|
||||
$recipient2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test4', 'lastname' => 'User4'));
|
||||
|
||||
$this->send_fake_unread_notification($sender1, $recipient1);
|
||||
$this->send_fake_unread_notification($sender1, $recipient1);
|
||||
$this->send_fake_unread_notification($sender1, $recipient2);
|
||||
$this->send_fake_unread_notification($sender2, $recipient1);
|
||||
$this->send_fake_unread_notification($sender2, $recipient2);
|
||||
$this->send_fake_unread_notification($sender2, $recipient2);
|
||||
|
||||
$this->assertEquals(message_count_unread_notifications($recipient1->id, $sender1->id), 2);
|
||||
$this->assertEquals(message_count_unread_notifications($recipient2->id, $sender1->id), 1);
|
||||
$this->assertEquals(message_count_unread_notifications($recipient1->id, $sender2->id), 1);
|
||||
$this->assertEquals(message_count_unread_notifications($recipient2->id, $sender2->id), 2);
|
||||
$this->assertEquals(message_count_unread_notifications($recipient1->id, 0), 3);
|
||||
$this->assertEquals(message_count_unread_notifications($recipient2->id, 0), 3);
|
||||
}
|
||||
|
||||
|
||||
public function test_message_mark_all_read_for_user_touser() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_unread_notification($sender, $recipient);
|
||||
$this->send_fake_unread_notification($sender, $recipient);
|
||||
$this->send_fake_unread_notification($sender, $recipient);
|
||||
$this->send_fake_message($sender, $recipient);
|
||||
$this->send_fake_message($sender, $recipient);
|
||||
$this->send_fake_message($sender, $recipient);
|
||||
|
||||
message_mark_all_read_for_user($recipient->id);
|
||||
$this->assertEquals(message_count_unread_messages($recipient), 0);
|
||||
}
|
||||
|
||||
public function test_message_mark_all_read_for_user_touser_with_fromuser() {
|
||||
$sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_unread_notification($sender1, $recipient);
|
||||
$this->send_fake_unread_notification($sender1, $recipient);
|
||||
$this->send_fake_unread_notification($sender1, $recipient);
|
||||
$this->send_fake_message($sender1, $recipient);
|
||||
$this->send_fake_message($sender1, $recipient);
|
||||
$this->send_fake_message($sender1, $recipient);
|
||||
$this->send_fake_unread_notification($sender2, $recipient);
|
||||
$this->send_fake_unread_notification($sender2, $recipient);
|
||||
$this->send_fake_unread_notification($sender2, $recipient);
|
||||
$this->send_fake_message($sender2, $recipient);
|
||||
$this->send_fake_message($sender2, $recipient);
|
||||
$this->send_fake_message($sender2, $recipient);
|
||||
|
||||
message_mark_all_read_for_user($recipient->id, $sender1->id);
|
||||
$this->assertEquals(message_count_unread_messages($recipient), 6);
|
||||
}
|
||||
|
||||
public function test_message_mark_all_read_for_user_touser_with_type() {
|
||||
$sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
|
||||
$recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
|
||||
|
||||
$this->send_fake_unread_notification($sender, $recipient);
|
||||
$this->send_fake_unread_notification($sender, $recipient);
|
||||
$this->send_fake_unread_notification($sender, $recipient);
|
||||
$this->send_fake_message($sender, $recipient);
|
||||
$this->send_fake_message($sender, $recipient);
|
||||
$this->send_fake_message($sender, $recipient);
|
||||
|
||||
message_mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_NOTIFICATION);
|
||||
$this->assertEquals(message_count_unread_messages($recipient), 3);
|
||||
|
||||
message_mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_MESSAGE);
|
||||
$this->assertEquals(message_count_unread_messages($recipient), 0);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2016100700.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2016100700.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user