MDL-64632 core_message: fixed PHP error when users are deleted from DB
authorMark Nelson <markn@moodle.com>
Fri, 1 Feb 2019 01:31:10 +0000 (09:31 +0800)
committerMark Nelson <markn@moodle.com>
Mon, 4 Feb 2019 04:36:22 +0000 (12:36 +0800)
message/classes/api.php
message/classes/helper.php
message/tests/externallib_test.php

index 0b583e7..be8aea6 100644 (file)
@@ -691,6 +691,10 @@ class api {
             // Don't use array_merge, as we lose array keys.
             $memberinfo = $individualmemberinfo + $groupmemberinfo;
 
+            if (empty($memberinfo)) {
+                return [];
+            }
+
             // Update the members array with the member information.
             $deletedmembers = [];
             foreach ($members as $convid => $memberarr) {
index 58dd7aa..0bbdde7 100644 (file)
@@ -589,6 +589,12 @@ class helper {
             }
         }
 
+        // Remove any userids not in $members. This can happen in the case of a user who has been deleted
+        // from the Moodle database table (which can happen in earlier versions of Moodle).
+        $userids = array_filter($userids, function($userid) use ($members) {
+            return isset($members[$userid]);
+        });
+
         // Return member information in the same order as the userids originally provided.
         $members = array_replace(array_flip($userids), $members);
 
index b4be382..6e2cc10 100644 (file)
@@ -5423,6 +5423,41 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
         $this->assertEquals($gc4->id, $conversations[5]['id']);
     }
 
+    /**
+     * Tests retrieving conversations when a conversation contains a deleted from the database user.
+     */
+    public function test_get_conversations_deleted_user_from_database() {
+        global $DB;
+
+        $this->resetAfterTest();
+
+        $user1 = self::getDataGenerator()->create_user();
+        $user2 = self::getDataGenerator()->create_user();
+
+        $conversation = \core_message\api::create_conversation(
+            \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
+            [
+                $user1->id,
+                $user2->id
+            ],
+            'Individual conversation'
+        );
+
+        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'A');
+        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'B');
+        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'C');
+
+        $this->setUser($user1);
+
+        // Delete the second user (from DB as well as this could happen in the past).
+        delete_user($user2);
+        $DB->delete_records('user', ['id' => $user2->id]);
+        $result = core_message_external::get_conversations($user1->id, 0, 20, 1, false);
+        $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result);
+
+        $this->assertEmpty($result['conversations']);
+    }
+
     /**
      * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
      */