mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 17:06:53 +02:00
MDL-65132 core_message: Added API to delete message for all users
This commit is contained in:
parent
a411b499b9
commit
d47e067184
2 changed files with 237 additions and 1 deletions
|
@ -802,8 +802,11 @@ class api {
|
||||||
// If not set, the context is always context_user.
|
// If not set, the context is always context_user.
|
||||||
if (is_null($conversation->contextid)) {
|
if (is_null($conversation->contextid)) {
|
||||||
$convcontext = \context_user::instance($userid);
|
$convcontext = \context_user::instance($userid);
|
||||||
|
// We'll need to check the capability to delete messages for all users in context system when contextid is null.
|
||||||
|
$contexttodeletemessageforall = \context_system::instance();
|
||||||
} else {
|
} else {
|
||||||
$convcontext = \context::instance_by_id($conversation->contextid);
|
$convcontext = \context::instance_by_id($conversation->contextid);
|
||||||
|
$contexttodeletemessageforall = $convcontext;
|
||||||
}
|
}
|
||||||
$conv->name = format_string($conversation->conversationname, true, ['context' => $convcontext]);
|
$conv->name = format_string($conversation->conversationname, true, ['context' => $convcontext]);
|
||||||
|
|
||||||
|
@ -819,6 +822,8 @@ class api {
|
||||||
|
|
||||||
// Add the most recent message information.
|
// Add the most recent message information.
|
||||||
$conv->messages = [];
|
$conv->messages = [];
|
||||||
|
// Add if the user has to allow delete messages for all users in the conversation.
|
||||||
|
$conv->candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $contexttodeletemessageforall);
|
||||||
if ($conversation->smallmessage) {
|
if ($conversation->smallmessage) {
|
||||||
$msg = new \stdClass();
|
$msg = new \stdClass();
|
||||||
$msg->id = $conversation->messageid;
|
$msg->id = $conversation->messageid;
|
||||||
|
@ -983,6 +988,9 @@ class api {
|
||||||
$ismuted = true;
|
$ismuted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the context of the conversation. This will be used to check if the user can delete all messages in the conversation.
|
||||||
|
$deleteallcontext = empty($conversation->contextid) ? $systemcontext : \context::instance_by_id($conversation->contextid);
|
||||||
|
|
||||||
return (object) [
|
return (object) [
|
||||||
'id' => $conversation->id,
|
'id' => $conversation->id,
|
||||||
'name' => $conversation->name,
|
'name' => $conversation->name,
|
||||||
|
@ -995,7 +1003,8 @@ class api {
|
||||||
'unreadcount' => $unreadcount,
|
'unreadcount' => $unreadcount,
|
||||||
'ismuted' => $ismuted,
|
'ismuted' => $ismuted,
|
||||||
'members' => $members,
|
'members' => $members,
|
||||||
'messages' => $messages['messages']
|
'messages' => $messages['messages'],
|
||||||
|
'candeletemessagesforallusers' => has_capability('moodle/site:deleteanymessage', $deleteallcontext)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3324,4 +3333,60 @@ class api {
|
||||||
$DB->delete_records('messages', ['conversationid' => $conversationid]);
|
$DB->delete_records('messages', ['conversationid' => $conversationid]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a user can delete a message for all users.
|
||||||
|
*
|
||||||
|
* @param int $userid the user id of who we want to delete the message for all users
|
||||||
|
* @param int $messageid The message id
|
||||||
|
* @return bool Returns true if a user can delete the message for all users, false otherwise.
|
||||||
|
*/
|
||||||
|
public static function can_delete_message_for_all_users(int $userid, int $messageid) : bool {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$sql = "SELECT mc.id, mc.contextid
|
||||||
|
FROM {message_conversations} mc
|
||||||
|
INNER JOIN {messages} m
|
||||||
|
ON mc.id = m.conversationid
|
||||||
|
WHERE m.id = :messageid";
|
||||||
|
$conversation = $DB->get_record_sql($sql, ['messageid' => $messageid]);
|
||||||
|
|
||||||
|
if (!empty($conversation->contextid)) {
|
||||||
|
return has_capability('moodle/site:deleteanymessage',
|
||||||
|
\context::instance_by_id($conversation->contextid), $userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return has_capability('moodle/site:deleteanymessage', \context_system::instance(), $userid);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete a message for all users.
|
||||||
|
*
|
||||||
|
* This function does not verify any permissions.
|
||||||
|
*
|
||||||
|
* @param int $messageid The message id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function delete_message_for_all_users(int $messageid) {
|
||||||
|
global $DB, $USER;
|
||||||
|
|
||||||
|
if (!$DB->record_exists('messages', ['id' => $messageid])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all members in the conversation where the message belongs.
|
||||||
|
$membersql = "SELECT mcm.id, mcm.userid
|
||||||
|
FROM {message_conversation_members} mcm
|
||||||
|
INNER JOIN {messages} m
|
||||||
|
ON mcm.conversationid = m.conversationid
|
||||||
|
WHERE m.id = :messageid";
|
||||||
|
$params = [
|
||||||
|
'messageid' => $messageid
|
||||||
|
];
|
||||||
|
$members = $DB->get_records_sql($membersql, $params);
|
||||||
|
if ($members) {
|
||||||
|
foreach ($members as $member) {
|
||||||
|
self::delete_message($member->userid, $messageid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6897,6 +6897,177 @@ class core_message_api_testcase extends core_message_messagelib_testcase {
|
||||||
$this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m4]));
|
$this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m4]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the user can delete message for all users as a teacher.
|
||||||
|
*/
|
||||||
|
public function test_can_delete_message_for_all_users_teacher() {
|
||||||
|
global $DB;
|
||||||
|
$this->resetAfterTest(true);
|
||||||
|
|
||||||
|
// Create fake data to test it.
|
||||||
|
list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
|
||||||
|
|
||||||
|
// Allow Teacher can delete messages for all.
|
||||||
|
$editingteacher = $DB->get_record('role', ['shortname' => 'editingteacher']);
|
||||||
|
assign_capability('moodle/site:deleteanymessage', CAP_ALLOW, $editingteacher->id, context_system::instance());
|
||||||
|
|
||||||
|
// Set as the first user.
|
||||||
|
$this->setUser($teacher);
|
||||||
|
|
||||||
|
// Send a message to private conversation and in a group conversation.
|
||||||
|
$messageidind = \core_message\tests\helper::send_fake_message_to_conversation($teacher, $convindividual->id);
|
||||||
|
$messageidgrp = \core_message\tests\helper::send_fake_message_to_conversation($teacher, $convgroup->id);
|
||||||
|
|
||||||
|
// Teacher cannot delete message for everyone in a private conversation.
|
||||||
|
$this->assertFalse(\core_message\api::can_delete_message_for_all_users($teacher->id, $messageidind));
|
||||||
|
|
||||||
|
// Teacher can delete message for everyone in a group conversation.
|
||||||
|
$this->assertTrue(\core_message\api::can_delete_message_for_all_users($teacher->id, $messageidgrp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the user can delete message for all users as a student.
|
||||||
|
*/
|
||||||
|
public function test_can_delete_message_for_all_users_student() {
|
||||||
|
$this->resetAfterTest(true);
|
||||||
|
|
||||||
|
// Create fake data to test it.
|
||||||
|
list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
|
||||||
|
|
||||||
|
// Set as the first user.
|
||||||
|
$this->setUser($student1);
|
||||||
|
|
||||||
|
// Send a message to private conversation and in a group conversation.
|
||||||
|
$messageidind = \core_message\tests\helper::send_fake_message_to_conversation($teacher, $convindividual->id);
|
||||||
|
$messageidgrp = \core_message\tests\helper::send_fake_message_to_conversation($teacher, $convgroup->id);
|
||||||
|
|
||||||
|
// Student1 cannot delete message for everyone in a private conversation.
|
||||||
|
$this->assertFalse(\core_message\api::can_delete_message_for_all_users($student1->id, $messageidind));
|
||||||
|
|
||||||
|
// Student1 cannot delete message for everyone in a group conversation.
|
||||||
|
$this->assertFalse(\core_message\api::can_delete_message_for_all_users($student1->id, $messageidgrp));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests tdelete message for all users in group conversation.
|
||||||
|
*/
|
||||||
|
public function test_delete_message_for_all_users_group_conversation() {
|
||||||
|
global $DB;
|
||||||
|
$this->resetAfterTest(true);
|
||||||
|
|
||||||
|
// Create fake data to test it.
|
||||||
|
list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
|
||||||
|
|
||||||
|
// Send 3 messages to a group conversation.
|
||||||
|
$mgid1 = \core_message\tests\helper::send_fake_message_to_conversation($teacher, $convgroup->id);
|
||||||
|
$mgid2 = \core_message\tests\helper::send_fake_message_to_conversation($student1, $convgroup->id);
|
||||||
|
$mgid3 = \core_message\tests\helper::send_fake_message_to_conversation($student2, $convgroup->id);
|
||||||
|
|
||||||
|
// Delete message 1 for all users.
|
||||||
|
\core_message\api::delete_message_for_all_users($mgid1);
|
||||||
|
|
||||||
|
// Get the messages to check if the message 1 was deleted for teacher.
|
||||||
|
$convmessages1 = \core_message\api::get_conversation_messages($teacher->id, $convgroup->id);
|
||||||
|
// Only has to remains 2 messages.
|
||||||
|
$this->assertCount(2, $convmessages1['messages']);
|
||||||
|
// Check if no one of the two messages is message 1.
|
||||||
|
foreach ($convmessages1['messages'] as $message) {
|
||||||
|
$this->assertNotEquals($mgid1, $message->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the messages to check if the message 1 was deleted for student1.
|
||||||
|
$convmessages2 = \core_message\api::get_conversation_messages($student1->id, $convgroup->id);
|
||||||
|
// Only has to remains 2 messages.
|
||||||
|
$this->assertCount(2, $convmessages2['messages']);
|
||||||
|
// Check if no one of the two messages is message 1.
|
||||||
|
foreach ($convmessages2['messages'] as $message) {
|
||||||
|
$this->assertNotEquals($mgid1, $message->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the messages to check if the message 1 was deleted for student2.
|
||||||
|
$convmessages3 = \core_message\api::get_conversation_messages($student2->id, $convgroup->id);
|
||||||
|
// Only has to remains 2 messages.
|
||||||
|
$this->assertCount(2, $convmessages3['messages']);
|
||||||
|
// Check if no one of the two messages is message 1.
|
||||||
|
foreach ($convmessages3['messages'] as $message) {
|
||||||
|
$this->assertNotEquals($mgid1, $message->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests delete message for all users in private conversation.
|
||||||
|
*/
|
||||||
|
public function test_delete_message_for_all_users_individual_conversation() {
|
||||||
|
global $DB;
|
||||||
|
$this->resetAfterTest(true);
|
||||||
|
|
||||||
|
// Create fake data to test it.
|
||||||
|
list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
|
||||||
|
|
||||||
|
// Send 2 messages in a individual conversation.
|
||||||
|
$mid1 = \core_message\tests\helper::send_fake_message_to_conversation($teacher, $convindividual->id);
|
||||||
|
$mid2 = \core_message\tests\helper::send_fake_message_to_conversation($student1, $convindividual->id);
|
||||||
|
|
||||||
|
// Delete the first message for all users.
|
||||||
|
\core_message\api::delete_message_for_all_users($mid1);
|
||||||
|
|
||||||
|
// Get the messages to check if the message 1 was deleted for teacher.
|
||||||
|
$convmessages1 = \core_message\api::get_conversation_messages($teacher->id, $convindividual->id);
|
||||||
|
// Only has to remains 1 messages for teacher.
|
||||||
|
$this->assertCount(1, $convmessages1['messages']);
|
||||||
|
// Check the one messages remains not is the first message.
|
||||||
|
$this->assertNotEquals($mid1, $convmessages1['messages'][0]->id);
|
||||||
|
|
||||||
|
// Get the messages to check if the message 1 was deleted for student1.
|
||||||
|
$convmessages2 = \core_message\api::get_conversation_messages($student1->id, $convindividual->id);
|
||||||
|
// Only has to remains 1 messages for student1.
|
||||||
|
$this->assertCount(1, $convmessages2['messages']);
|
||||||
|
// Check the one messages remains not is the first message.
|
||||||
|
$this->assertNotEquals($mid1, $convmessages2['messages'][0]->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to seed the database with initial state with data.
|
||||||
|
*/
|
||||||
|
protected function create_delete_message_test_data() {
|
||||||
|
// Create some users.
|
||||||
|
$teacher = self::getDataGenerator()->create_user();
|
||||||
|
$student1 = self::getDataGenerator()->create_user();
|
||||||
|
$student2 = self::getDataGenerator()->create_user();
|
||||||
|
|
||||||
|
// Create a course and enrol the users.
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
$coursecontext = context_course::instance($course->id);
|
||||||
|
$this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
|
||||||
|
$this->getDataGenerator()->enrol_user($student1->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student');
|
||||||
|
|
||||||
|
// Create a group and added the users into.
|
||||||
|
$group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
|
||||||
|
groups_add_member($group1->id, $teacher->id);
|
||||||
|
groups_add_member($group1->id, $student1->id);
|
||||||
|
groups_add_member($group1->id, $student2->id);
|
||||||
|
|
||||||
|
// Create a group conversation linked with the course.
|
||||||
|
$convgroup = \core_message\api::create_conversation(
|
||||||
|
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
|
||||||
|
[$teacher->id, $student1->id, $student2->id],
|
||||||
|
'Group test delete for everyone', \core_message\api::MESSAGE_CONVERSATION_ENABLED,
|
||||||
|
'core_group',
|
||||||
|
'groups',
|
||||||
|
$group1->id,
|
||||||
|
context_course::instance($course->id)->id
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create and individual conversation.
|
||||||
|
$convindividual = \core_message\api::create_conversation(
|
||||||
|
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
|
||||||
|
[$teacher->id, $student1->id]
|
||||||
|
);
|
||||||
|
|
||||||
|
return [$teacher, $student1, $student2, $convgroup, $convindividual];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comparison function for sorting contacts.
|
* Comparison function for sorting contacts.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue