diff --git a/message/classes/api.php b/message/classes/api.php index b732e0324c9..0130f9f314a 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -276,14 +276,17 @@ class api { } /** - * Gets the subnames for any conversations linked to components. + * Gets extra fields, like image url and subname for any conversations linked to components. * * The subname is like a subtitle for the conversation, to compliment it's name. + * The imageurl is the location of the image for the conversation, as might be seen on a listing of conversations for a user. * * @param array $conversations a list of conversations records. * @return array the array of subnames, index by conversation id. + * @throws \coding_exception + * @throws \dml_exception */ - protected static function get_linked_conversation_subnames(array $conversations) { + protected static function get_linked_conversation_extra_fields(array $conversations) : array { global $DB; $linkedconversations = []; @@ -299,11 +302,11 @@ class api { // TODO: MDL-63814: Working out the subname for linked conversations should be done in a generic way. // Get the itemid, but only for course group linked conversation for now. - $convsubnames = []; + $extrafields = []; if (!empty($linkeditems = $linkedconversations['core_group']['groups'])) { // Format: [conversationid => itemid]. // Get the name of the course to which the group belongs. list ($groupidsql, $groupidparams) = $DB->get_in_or_equal(array_values($linkeditems), SQL_PARAMS_NAMED, 'groupid'); - $sql = "SELECT g.id, c.shortname + $sql = "SELECT g.*, c.shortname as courseshortname FROM {groups} g JOIN {course} c ON g.courseid = c.id @@ -311,11 +314,16 @@ class api { $courseinfo = $DB->get_records_sql($sql, $groupidparams); foreach ($linkeditems as $convid => $groupid) { if (array_key_exists($groupid, $courseinfo)) { - $convsubnames[$convid] = format_string($courseinfo[$groupid]->shortname); + $group = $courseinfo[$groupid]; + // Subname. + $extrafields[$convid]['subname'] = format_string($courseinfo[$groupid]->courseshortname); + + // Imageurl. + $extrafields[$convid]['imageurl'] = get_group_picture_url($group, $group->courseid, true)->out(false); } } } - return $convsubnames; + return $extrafields; } @@ -431,10 +439,12 @@ class api { return []; } - // COMPONENT-LINKED CONVERSATION SUBNAME. - // This subname will vary, depending on the component which created the linked conversation. + // COMPONENT-LINKED CONVERSATION FIELDS. + // Conversations linked to components may have extra information, such as: + // - subname: Essentially a subtitle for the conversation. So you'd have "name: subname". + // - imageurl: A URL to the image for the linked conversation. // For now, this is ONLY course groups. - $convsubnames = self::get_linked_conversation_subnames($conversations); + $convextrafields = self::get_linked_conversation_extra_fields($conversations); // MEMBERS. // Ideally, we want to get 1 member for each conversation, but this depends on the type and whether there is a recent @@ -555,7 +565,8 @@ class api { $conv = new \stdClass(); $conv->id = $conversation->id; $conv->name = $conversation->conversationname; - $conv->subname = $convsubnames[$conv->id] ?? null; + $conv->subname = $convextrafields[$conv->id]['subname'] ?? null; + $conv->imageurl = $convextrafields[$conv->id]['imageurl'] ?? null; $conv->type = $conversation->conversationtype; $conv->membercount = $membercounts[$conv->id]->membercount; $conv->isfavourite = in_array($conv->id, $favouriteconversationids); diff --git a/message/externallib.php b/message/externallib.php index c0c55f0b437..fcafb714e7d 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -955,6 +955,7 @@ class core_message_external extends external_api { 'id' => new external_value(PARAM_INT, 'The conversation id'), 'name' => new external_value(PARAM_NOTAGS, 'The conversation name, if set', VALUE_DEFAULT, null), 'subname' => new external_value(PARAM_NOTAGS, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null), + 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null), 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group)'), 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'), 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked conversation this conversation as a favourite'), diff --git a/message/tests/api_test.php b/message/tests/api_test.php index 89567e2968f..aec029b7ffa 100644 --- a/message/tests/api_test.php +++ b/message/tests/api_test.php @@ -792,6 +792,7 @@ class core_message_api_testcase extends core_message_messagelib_testcase { $this->assertObjectHasAttribute('id', $conv); $this->assertObjectHasAttribute('name', $conv); $this->assertObjectHasAttribute('subname', $conv); + $this->assertObjectHasAttribute('imageurl', $conv); $this->assertObjectHasAttribute('type', $conv); $this->assertObjectHasAttribute('isfavourite', $conv); $this->assertObjectHasAttribute('membercount', $conv); @@ -1016,6 +1017,8 @@ class core_message_api_testcase extends core_message_messagelib_testcase { * Test verifying that group linked conversations are returned and contain a subname matching the course name. */ public function test_get_conversations_group_linked() { + global $CFG; + // Create some users. $user1 = self::getDataGenerator()->create_user(); $user2 = self::getDataGenerator()->create_user(); @@ -1028,14 +1031,21 @@ class core_message_api_testcase extends core_message_messagelib_testcase { $this->getDataGenerator()->enrol_user($user1->id, $course1->id); $this->getDataGenerator()->enrol_user($user2->id, $course1->id); $this->getDataGenerator()->enrol_user($user3->id, $course1->id); - $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1)); + $group1 = $this->getDataGenerator()->create_group([ + 'courseid' => $course1->id, + 'enablemessaging' => 1, + 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png' + ]); // Add users to group1. $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); $conversations = \core_message\api::get_conversations($user1->id); + $this->assertEquals(2, $conversations[0]->membercount); $this->assertEquals($course1->shortname, $conversations[0]->subname); + $groupimageurl = get_group_picture_url($group1, $group1->courseid, true); + $this->assertEquals($groupimageurl, $conversations[0]->imageurl); } /** diff --git a/message/tests/externallib_test.php b/message/tests/externallib_test.php index 1d2667dfdff..6857ccbe77a 100644 --- a/message/tests/externallib_test.php +++ b/message/tests/externallib_test.php @@ -4443,6 +4443,7 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { $this->assertArrayHasKey('id', $conv); $this->assertArrayHasKey('name', $conv); $this->assertArrayHasKey('subname', $conv); + $this->assertArrayHasKey('imageurl', $conv); $this->assertArrayHasKey('type', $conv); $this->assertArrayHasKey('membercount', $conv); $this->assertArrayHasKey('isfavourite', $conv); @@ -4679,6 +4680,45 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { } } + /** + * Test verifying that group linked conversations are returned and contain a subname matching the course name. + */ + public function test_get_conversations_group_linked() { + $this->resetAfterTest(); + global $CFG; + + // Create some users. + $user1 = self::getDataGenerator()->create_user(); + $user2 = self::getDataGenerator()->create_user(); + $user3 = self::getDataGenerator()->create_user(); + + $course1 = $this->getDataGenerator()->create_course(); + + // Create a group with a linked conversation. + $this->setAdminUser(); + $this->getDataGenerator()->enrol_user($user1->id, $course1->id); + $this->getDataGenerator()->enrol_user($user2->id, $course1->id); + $this->getDataGenerator()->enrol_user($user3->id, $course1->id); + $group1 = $this->getDataGenerator()->create_group([ + 'courseid' => $course1->id, + 'enablemessaging' => 1, + 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png' + ]); + + // Add users to group1. + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)); + $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id)); + + $result = core_message_external::get_conversations($user1->id, 0, 20, null, false); + $result = external_api::clean_returnvalue(core_message_external::get_conversations_returns(), $result); + $conversations = $result['conversations']; + + $this->assertEquals(2, $conversations[0]['membercount']); + $this->assertEquals($course1->shortname, $conversations[0]['subname']); + $groupimageurl = get_group_picture_url($group1, $group1->courseid, true); + $this->assertEquals($groupimageurl, $conversations[0]['imageurl']); + } + /** * Test returning members in a conversation with no contact requests. */