Merge branch 'MDL-64568-master'
authorAdrian Greeve <abgreeve@gmail.com>
Wed, 13 Mar 2019 07:42:40 +0000 (15:42 +0800)
committerAdrian Greeve <abgreeve@gmail.com>
Wed, 13 Mar 2019 07:42:40 +0000 (15:42 +0800)
group/lib.php
lib/db/upgrade.php
message/classes/api.php
message/tests/api_test.php
version.php

index c2edce9..42e7fbe 100644 (file)
@@ -548,12 +548,20 @@ function groups_delete_group($grouporid) {
         }
     }
 
+    $context = context_course::instance($group->courseid);
+
     // delete group calendar events
     $DB->delete_records('event', array('groupid'=>$groupid));
     //first delete usage in groupings_groups
     $DB->delete_records('groupings_groups', array('groupid'=>$groupid));
     //delete members
     $DB->delete_records('groups_members', array('groupid'=>$groupid));
+
+    // Delete any members in a conversation related to this group.
+    if ($conversation = \core_message\api::get_conversation_by_area('core_group', 'groups', $groupid, $context->id)) {
+        \core_message\api::delete_all_conversation_data($conversation->id);
+    }
+
     //group itself last
     $DB->delete_records('groups', array('id'=>$groupid));
 
index a6b4ae8..e096525 100644 (file)
@@ -2806,5 +2806,42 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2019030800.00);
     }
 
+    if ($oldversion < 2019030800.02) {
+        // Remove any conversations and their members associated with non-existent groups.
+        $sql = "SELECT mc.id
+                  FROM {message_conversations} mc
+             LEFT JOIN {groups} g
+                    ON mc.itemid = g.id
+                 WHERE mc.component = :component
+                   AND mc.itemtype = :itemtype
+                   AND g.id is NULL";
+        $conversations = $DB->get_records_sql($sql, ['component' => 'core_group', 'itemtype' => 'groups']);
+
+        if ($conversations) {
+            $conversationids = array_keys($conversations);
+
+            $DB->delete_records_list('message_conversations', 'id', $conversationids);
+            $DB->delete_records_list('message_conversation_members', 'conversationid', $conversationids);
+            $DB->delete_records_list('message_conversation_actions', 'conversationid', $conversationids);
+
+            // Now, go through each conversation and delete any messages and related message actions.
+            foreach ($conversationids as $conversationid) {
+                if ($messages = $DB->get_records('messages', ['conversationid' => $conversationid])) {
+                    $messageids = array_keys($messages);
+
+                    // Delete the actions.
+                    list($insql, $inparams) = $DB->get_in_or_equal($messageids);
+                    $DB->delete_records_select('message_user_actions', "messageid $insql", $inparams);
+
+                    // Delete the messages.
+                    $DB->delete_records('messages', ['conversationid' => $conversationid]);
+                }
+            }
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2019030800.02);
+    }
+
     return true;
 }
index 9376f5b..ebbb9f0 100644 (file)
@@ -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]);
+        }
+    }
 }
index ba5ed18..7c7cb7e 100644 (file)
@@ -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.
      *
index 5656a45..439bb67 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2019030800.01;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2019030800.02;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.