MDL-64426 core_message: fix filter support in api::get_conversations()
authorJake Dallimore <jake@moodle.com>
Tue, 18 Dec 2018 09:24:53 +0000 (17:24 +0800)
committerJake Dallimore <jake@moodle.com>
Tue, 8 Jan 2019 07:50:43 +0000 (15:50 +0800)
Conversation name and subname should support filters, so the data should
be passed through format_string, and advertised in the external params
as PARAM_TEXT.

message/classes/api.php
message/externallib.php

index a138fe4..b43aaf6 100644 (file)
@@ -555,7 +555,7 @@ class api {
 
         $sql = "SELECT m.id as messageid, mc.id as id, mc.name as conversationname, mc.type as conversationtype, m.useridfrom,
                        m.smallmessage, m.fullmessage, m.fullmessageformat, m.fullmessagehtml, m.timecreated, mc.component,
-                       mc.itemtype, mc.itemid
+                       mc.itemtype, mc.itemid, mc.contextid
                   FROM {message_conversations} mc
             INNER JOIN {message_conversation_members} mcm
                     ON (mcm.conversationid = mc.id AND mcm.userid = :userid3)
@@ -750,6 +750,10 @@ class api {
         $unreadcounts = $DB->get_records_sql($unreadcountssql, [$userid, self::MESSAGE_ACTION_READ, self::MESSAGE_ACTION_DELETED,
             $userid, $userid]);
 
+        // Because we'll be calling format_string on each conversation name and passing contexts, we preload them here.
+        // This warms the cache and saves potentially hitting the DB once for each context fetch below.
+        \context_helper::preload_contexts_by_id(array_column($conversations, 'contextid'));
+
         // Now, create the final return structure.
         $arrconversations = [];
         foreach ($conversations as $conversation) {
@@ -768,7 +772,16 @@ class api {
 
             $conv = new \stdClass();
             $conv->id = $conversation->id;
-            $conv->name = $conversation->conversationname;
+
+            // Name should be formatted and depends on the context the conversation resides in.
+            // If not set, the context is always context_user.
+            if (is_null($conversation->contextid)) {
+                $convcontext = \context_user::instance_by_id($userid);
+            } else {
+                $convcontext = \context::instance_by_id($conversation->contextid);
+            }
+            $conv->name = format_string($conversation->conversationname, true, ['context' => $convcontext]);
+
             $conv->subname = $convextrafields[$conv->id]['subname'] ?? null;
             $conv->imageurl = $convextrafields[$conv->id]['imageurl'] ?? null;
             $conv->type = $conversation->conversationtype;
index b03af2a..c9c6631 100644 (file)
@@ -1118,8 +1118,8 @@ class core_message_external extends external_api {
         return new external_single_structure(
             array(
                 '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),
+                'name' => new external_value(PARAM_TEXT, 'The conversation name, if set', VALUE_DEFAULT, null),
+                'subname' => new external_value(PARAM_TEXT, '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'),