From 978f233b8bfe562bc150fa73a027b1203bc8af96 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Thu, 28 Feb 2019 14:40:57 +0800 Subject: [PATCH] MDL-64568 core_message: added new method to nuke conversations entirely This method removes all data in the database related to a given conversation. --- message/classes/api.php | 24 ++++++++++ message/tests/api_test.php | 97 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/message/classes/api.php b/message/classes/api.php index 9376f5b93d3..ebbb9f08143 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -3204,4 +3204,28 @@ class api { ] ); } + + /** + * Completely removes all related data in the DB for a given conversation. + * + * @param int $conversationid The id of the conversation + */ + public static function delete_all_conversation_data(int $conversationid) { + global $DB; + + $DB->delete_records('message_conversations', ['id' => $conversationid]); + $DB->delete_records('message_conversation_members', ['conversationid' => $conversationid]); + $DB->delete_records('message_conversation_actions', ['conversationid' => $conversationid]); + + // Now, go through and delete any messages and related message actions for the conversation. + if ($messages = $DB->get_records('messages', ['conversationid' => $conversationid])) { + $messageids = array_keys($messages); + + list($insql, $inparams) = $DB->get_in_or_equal($messageids); + $DB->delete_records_select('message_user_actions', "messageid $insql", $inparams); + + // Delete the messages now. + $DB->delete_records('messages', ['conversationid' => $conversationid]); + } + } } diff --git a/message/tests/api_test.php b/message/tests/api_test.php index ba5ed1888fb..7c7cb7e312d 100644 --- a/message/tests/api_test.php +++ b/message/tests/api_test.php @@ -6439,6 +6439,103 @@ class core_message_api_testcase extends core_message_messagelib_testcase { $counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP]); } + public function test_delete_all_conversation_data() { + global $DB; + + $this->resetAfterTest(); + + $this->setAdminUser(); + + $course1 = $this->getDataGenerator()->create_course(); + $coursecontext1 = context_course::instance($course1->id); + + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + + $this->getDataGenerator()->enrol_user($user1->id, $course1->id); + $this->getDataGenerator()->enrol_user($user2->id, $course1->id); + + $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); + $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); + + // Add users to both groups. + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); + + $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)); + + $groupconversation1 = \core_message\api::get_conversation_by_area( + 'core_group', + 'groups', + $group1->id, + $coursecontext1->id + ); + + $groupconversation2 = \core_message\api::get_conversation_by_area( + 'core_group', + 'groups', + $group2->id, + $coursecontext1->id + ); + + // Send a few messages. + $g1m1 = \core_message\tests\helper::send_fake_message_to_conversation($user1, $groupconversation1->id); + $g1m2 = \core_message\tests\helper::send_fake_message_to_conversation($user2, $groupconversation1->id); + $g1m3 = \core_message\tests\helper::send_fake_message_to_conversation($user1, $groupconversation1->id); + $g1m4 = \core_message\tests\helper::send_fake_message_to_conversation($user2, $groupconversation1->id); + + $g2m1 = \core_message\tests\helper::send_fake_message_to_conversation($user1, $groupconversation2->id); + $g2m2 = \core_message\tests\helper::send_fake_message_to_conversation($user2, $groupconversation2->id); + $g2m3 = \core_message\tests\helper::send_fake_message_to_conversation($user1, $groupconversation2->id); + $g2m4 = \core_message\tests\helper::send_fake_message_to_conversation($user2, $groupconversation2->id); + + // Delete a few messages. + \core_message\api::delete_message($user1->id, $g1m1); + \core_message\api::delete_message($user1->id, $g1m2); + \core_message\api::delete_message($user1->id, $g2m1); + \core_message\api::delete_message($user1->id, $g2m2); + + // Mute the conversations. + \core_message\api::mute_conversation($user1->id, $groupconversation1->id); + \core_message\api::mute_conversation($user1->id, $groupconversation2->id); + + // Now, delete all the data for the group 1 conversation. + \core_message\api::delete_all_conversation_data($groupconversation1->id); + + // Confirm group conversation was deleted just for the group 1 conversation. + $this->assertEquals(0, $DB->count_records('message_conversations', ['id' => $groupconversation1->id])); + $this->assertEquals(1, $DB->count_records('message_conversations', ['id' => $groupconversation2->id])); + + // Confirm conversation members were deleted just for the group 1 conversation. + $this->assertEquals(0, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation1->id])); + $this->assertEquals(2, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation2->id])); + + // Confirm message conversation actions were deleted just for the group 1 conversation. + $this->assertEquals(0, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation1->id])); + $this->assertEquals(1, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation2->id])); + + // Confirm message user actions were deleted just for the group 1 conversation. + $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m1])); + $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m2])); + $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m3])); + $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m4])); + $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m1])); + $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m2])); + $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m3])); + $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m4])); + + // Confirm messages were deleted just for the group 1 conversation. + $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m1])); + $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m2])); + $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m3])); + $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m4])); + $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m1])); + $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m2])); + $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m3])); + $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m4])); + } + /** * Comparison function for sorting contacts. *