From fc2664501bc3bfee7986134dc704733266b88c96 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Fri, 1 Feb 2019 09:31:10 +0800 Subject: [PATCH] MDL-64632 core_message: fixed PHP error when users are deleted from DB --- message/classes/api.php | 4 ++++ message/classes/helper.php | 6 +++++ message/tests/externallib_test.php | 35 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/message/classes/api.php b/message/classes/api.php index 0b583e735b7..be8aea62842 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -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) { diff --git a/message/classes/helper.php b/message/classes/helper.php index 58dd7aa174e..0bbdde7229c 100644 --- a/message/classes/helper.php +++ b/message/classes/helper.php @@ -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); diff --git a/message/tests/externallib_test.php b/message/tests/externallib_test.php index b4be38273ef..6e2cc10f0f4 100644 --- a/message/tests/externallib_test.php +++ b/message/tests/externallib_test.php @@ -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. */ -- 2.43.0