MDL-67782 message: fix messages max length
[moodle.git] / message / classes / helper.php
CommitLineData
879e2bef
MN
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Contains helper class for the message area.
19 *
20 * @package core_message
21 * @copyright 2016 Mark Nelson <markn@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace core_message;
26
27defined('MOODLE_INTERNAL') || die();
28
8be24909
RW
29require_once($CFG->dirroot . '/message/lib.php');
30
879e2bef
MN
31/**
32 * Helper class for the message area.
33 *
34 * @copyright 2016 Mark Nelson <markn@moodle.com>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class helper {
38
39 /**
1bc2a3b3 40 * @deprecated since 3.6
879e2bef 41 */
1bc2a3b3
MM
42 public static function get_messages() {
43 throw new \coding_exception('\core_message\helper::get_messages has been removed.');
879e2bef
MN
44 }
45
fb04293b
SA
46 /**
47 * Helper function to retrieve conversation messages.
48 *
49 * @param int $userid The current user.
50 * @param int $convid The conversation identifier.
51 * @param int $timedeleted The time the message was deleted
52 * @param int $limitfrom Return a subset of records, starting at this point (optional).
53 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
54 * @param string $sort The column name to order by including optionally direction.
55 * @param int $timefrom The time from the message being sent.
56 * @param int $timeto The time up until the message being sent.
57 * @return array of messages
58 */
59 public static function get_conversation_messages(int $userid, int $convid, int $timedeleted = 0, int $limitfrom = 0,
60 int $limitnum = 0, string $sort = 'timecreated ASC', int $timefrom = 0,
61 int $timeto = 0) : array {
62 global $DB;
63
64 $sql = "SELECT m.id, m.useridfrom, m.subject, m.fullmessage, m.fullmessagehtml,
3a5afbf5 65 m.fullmessageformat, m.fullmessagetrust, m.smallmessage, m.timecreated,
66 mc.contextid, muaread.timecreated AS timeread
fb04293b
SA
67 FROM {message_conversations} mc
68 INNER JOIN {messages} m
69 ON m.conversationid = mc.id
70 LEFT JOIN {message_user_actions} muaread
71 ON (muaread.messageid = m.id
72 AND muaread.userid = :userid1
73 AND muaread.action = :readaction)";
74 $params = ['userid1' => $userid, 'readaction' => api::MESSAGE_ACTION_READ, 'convid' => $convid];
75
76 if (empty($timedeleted)) {
77 $sql .= " LEFT JOIN {message_user_actions} mua
78 ON (mua.messageid = m.id
79 AND mua.userid = :userid2
80 AND mua.action = :deleteaction
81 AND mua.timecreated is NOT NULL)";
82 } else {
83 $sql .= " INNER JOIN {message_user_actions} mua
84 ON (mua.messageid = m.id
85 AND mua.userid = :userid2
86 AND mua.action = :deleteaction
87 AND mua.timecreated = :timedeleted)";
88 $params['timedeleted'] = $timedeleted;
89 }
90
91 $params['userid2'] = $userid;
92 $params['deleteaction'] = api::MESSAGE_ACTION_DELETED;
93
94 $sql .= " WHERE mc.id = :convid";
95
96 if (!empty($timefrom)) {
97 $sql .= " AND m.timecreated >= :timefrom";
98 $params['timefrom'] = $timefrom;
99 }
100
101 if (!empty($timeto)) {
102 $sql .= " AND m.timecreated <= :timeto";
103 $params['timeto'] = $timeto;
104 }
105
106 if (empty($timedeleted)) {
107 $sql .= " AND mua.id is NULL";
108 }
109
110 $sql .= " ORDER BY m.$sort";
111
112 $messages = $DB->get_records_sql($sql, $params, $limitfrom, $limitnum);
113
114 return $messages;
115 }
116
d89d0d65
SA
117 /**
118 * Helper function to return a conversation messages with the involved members (only the ones
119 * who have sent any of these messages).
120 *
121 * @param int $userid The current userid.
122 * @param int $convid The conversation id.
123 * @param array $messages The formated array messages.
124 * @return array A conversation array with the messages and the involved members.
125 */
126 public static function format_conversation_messages(int $userid, int $convid, array $messages) : array {
127 global $USER;
128
129 // Create the conversation array.
130 $conversation = array(
131 'id' => $convid,
132 );
133
134 // Store the messages.
135 $arrmessages = array();
136
d89d0d65
SA
137 foreach ($messages as $message) {
138 // Store the message information.
139 $msg = new \stdClass();
140 $msg->id = $message->id;
141 $msg->useridfrom = $message->useridfrom;
142 $msg->text = message_format_message_text($message);
143 $msg->timecreated = $message->timecreated;
144 $arrmessages[] = $msg;
145 }
146 // Add the messages to the conversation.
147 $conversation['messages'] = $arrmessages;
148
149 // Get the users who have sent any of the $messages.
150 $memberids = array_unique(array_map(function($message) {
151 return $message->useridfrom;
152 }, $messages));
32b4212e
RW
153
154 if (!empty($memberids)) {
155 // Get members information.
156 $conversation['members'] = self::get_member_info($userid, $memberids);
157 } else {
158 $conversation['members'] = array();
159 }
d89d0d65
SA
160
161 return $conversation;
162 }
163
879e2bef 164 /**
1bc2a3b3 165 * @deprecated since 3.6
879e2bef 166 */
1bc2a3b3
MM
167 public static function create_messages() {
168 throw new \coding_exception('\core_message\helper::create_messages has been removed.');
879e2bef
MN
169 }
170
171 /**
de55cb1b 172 * Helper function for creating a contact object.
879e2bef
MN
173 *
174 * @param \stdClass $contact
cd03b8d7 175 * @param string $prefix
de55cb1b 176 * @return \stdClass
879e2bef 177 */
cd03b8d7 178 public static function create_contact($contact, $prefix = '') {
bf58081d 179 global $PAGE;
879e2bef
MN
180
181 // Create the data we are going to pass to the renderable.
cd03b8d7 182 $userfields = \user_picture::unalias($contact, array('lastaccess'), $prefix . 'id', $prefix);
879e2bef
MN
183 $data = new \stdClass();
184 $data->userid = $userfields->id;
89a70ba1 185 $data->useridfrom = null;
879e2bef
MN
186 $data->fullname = fullname($userfields);
187 // Get the user picture data.
188 $userpicture = new \user_picture($userfields);
189 $userpicture->size = 1; // Size f1.
190 $data->profileimageurl = $userpicture->get_url($PAGE)->out(false);
191 $userpicture->size = 0; // Size f2.
192 $data->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
193 // Store the message if we have it.
5bf0ff27 194 $data->ismessaging = false;
cd03b8d7 195 $data->lastmessage = null;
0802c38a 196 $data->lastmessagedate = null;
cd03b8d7 197 $data->messageid = null;
879e2bef 198 if (isset($contact->smallmessage)) {
5bf0ff27 199 $data->ismessaging = true;
54d83992
RW
200 // Strip the HTML tags from the message for displaying in the contact area.
201 $data->lastmessage = clean_param($contact->smallmessage, PARAM_NOTAGS);
0802c38a 202 $data->lastmessagedate = $contact->timecreated;
89a70ba1 203 $data->useridfrom = $contact->useridfrom;
cd03b8d7
MN
204 if (isset($contact->messageid)) {
205 $data->messageid = $contact->messageid;
206 }
879e2bef 207 }
cb805753 208 $data->isonline = null;
4cdc9f73 209 $user = \core_user::get_user($data->userid);
210 if (self::show_online_status($user)) {
cb805753
MN
211 $data->isonline = self::is_online($userfields->lastaccess);
212 }
1f64514d
MN
213 $data->isblocked = isset($contact->blocked) ? (bool) $contact->blocked : false;
214 $data->isread = isset($contact->isread) ? (bool) $contact->isread : false;
c33b7d89 215 $data->unreadcount = isset($contact->unreadcount) ? $contact->unreadcount : null;
d2708759 216 $data->conversationid = $contact->conversationid ?? null;
879e2bef 217
de55cb1b 218 return $data;
879e2bef 219 }
bf58081d 220
cb805753
MN
221 /**
222 * Helper function for checking if we should show the user's online status.
223 *
224 * @param \stdClass $user
225 * @return boolean
226 */
227 public static function show_online_status($user) {
228 global $CFG;
229
230 require_once($CFG->dirroot . '/user/lib.php');
231
232 if ($lastaccess = user_get_user_details($user, null, array('lastaccess'))) {
233 if (isset($lastaccess['lastaccess'])) {
234 return true;
235 }
236 }
237
238 return false;
239 }
240
bf58081d
MN
241 /**
242 * Helper function for checking the time meets the 'online' condition.
243 *
244 * @param int $lastaccess
245 * @return boolean
246 */
247 public static function is_online($lastaccess) {
248 global $CFG;
249
250 // Variable to check if we consider this user online or not.
251 $timetoshowusers = 300; // Seconds default.
252 if (isset($CFG->block_online_users_timetosee)) {
253 $timetoshowusers = $CFG->block_online_users_timetosee * 60;
254 }
255 $time = time() - $timetoshowusers;
256
257 return $lastaccess >= $time;
258 }
79f6c36c
MN
259
260 /**
261 * Get providers preferences.
262 *
263 * @param array $providers
264 * @param int $userid
265 * @return \stdClass
266 */
267 public static function get_providers_preferences($providers, $userid) {
268 $preferences = new \stdClass();
269
270 // Get providers preferences.
271 foreach ($providers as $provider) {
272 foreach (array('loggedin', 'loggedoff') as $state) {
273 $linepref = get_user_preferences('message_provider_' . $provider->component . '_' . $provider->name
274 . '_' . $state, '', $userid);
275 if ($linepref == '') {
276 continue;
277 }
278 $lineprefarray = explode(',', $linepref);
279 $preferences->{$provider->component.'_'.$provider->name.'_'.$state} = array();
280 foreach ($lineprefarray as $pref) {
281 $preferences->{$provider->component.'_'.$provider->name.'_'.$state}[$pref] = 1;
282 }
283 }
284 }
285
286 return $preferences;
287 }
288
289 /**
290 * Requires the JS libraries for the toggle contact button.
291 *
292 * @return void
293 */
294 public static function togglecontact_requirejs() {
295 global $PAGE;
296
297 static $done = false;
298 if ($done) {
299 return;
300 }
301
302 $PAGE->requires->js_call_amd('core_message/toggle_contact_button', 'enhance', array('#toggle-contact-button'));
303 $done = true;
304 }
305
306 /**
307 * Returns the attributes to place on a contact button.
308 *
309 * @param object $user User object.
310 * @param bool $iscontact
311 * @return array
312 */
313 public static function togglecontact_link_params($user, $iscontact = false) {
1bc2a3b3 314 global $USER;
79f6c36c 315 $params = array(
1bc2a3b3 316 'data-currentuserid' => $USER->id,
79f6c36c
MN
317 'data-userid' => $user->id,
318 'data-is-contact' => $iscontact,
319 'id' => 'toggle-contact-button',
320 'role' => 'button',
321 'class' => 'ajax-contact-button',
322 );
323
324 return $params;
325 }
ffd7798c 326
6f9d34bd
MN
327 /**
328 * Requires the JS libraries for the message user button.
329 *
330 * @return void
331 */
332 public static function messageuser_requirejs() {
333 global $PAGE;
334
335 static $done = false;
336 if ($done) {
337 return;
338 }
339
340 $PAGE->requires->js_call_amd('core_message/message_user_button', 'send', array('#message-user-button'));
341 $done = true;
342 }
343
344 /**
345 * Returns the attributes to place on the message user button.
346 *
347 * @param int $useridto
348 * @return array
349 */
350 public static function messageuser_link_params(int $useridto) : array {
351 global $USER;
352
353 return [
354 'id' => 'message-user-button',
355 'role' => 'button',
356 'data-conversationid' => api::get_conversation_between_users([$USER->id, $useridto]),
357 'data-userid' => $useridto,
358 ];
359 }
360
b2cd17e6
MN
361 /**
362 * Returns the conversation hash between users for easy look-ups in the DB.
363 *
364 * @param array $userids
365 * @return string
366 */
367 public static function get_conversation_hash(array $userids) {
368 sort($userids);
369
370 return sha1(implode('-', $userids));
371 }
372
4699b8bc
AN
373 /**
374 * Returns the cache key for the time created value of the last message of this conversation.
375 *
376 * @param int $convid The conversation identifier.
377 * @return string The key.
378 */
379 public static function get_last_message_time_created_cache_key(int $convid) {
380 return $convid;
381 }
382
78348dfc
MN
383 /**
384 * Checks if legacy messages exist for a given user.
385 *
386 * @param int $userid
387 * @return bool
388 */
389 public static function legacy_messages_exist($userid) {
390 global $DB;
391
392 $sql = "SELECT id
393 FROM {message} m
394 WHERE useridfrom = ?
395 OR useridto = ?";
396 $messageexists = $DB->record_exists_sql($sql, [$userid, $userid]);
397
398 $sql = "SELECT id
399 FROM {message_read} m
400 WHERE useridfrom = ?
401 OR useridto = ?";
402 $messagereadexists = $DB->record_exists_sql($sql, [$userid, $userid]);
403
404 return $messageexists || $messagereadexists;
405 }
2a2b86f1
JD
406
407 /**
408 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid.
409 *
410 * This is the basic structure used when returning members, and includes information about the relationship between each member
411 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them.
412 *
413 * @param int $referenceuserid the id of the user which check contact and blocked status.
414 * @param array $userids
054834b0 415 * @param bool $includecontactrequests Do we want to include contact requests with this data?
82e0973c
MN
416 * @param bool $includeprivacyinfo Do we want to include whether the user can message another, and if the user
417 * requires a contact.
2a2b86f1
JD
418 * @return array the array of objects containing member info, indexed by userid.
419 * @throws \coding_exception
420 * @throws \dml_exception
421 */
82e0973c
MN
422 public static function get_member_info(int $referenceuserid, array $userids, bool $includecontactrequests = false,
423 bool $includeprivacyinfo = false) : array {
2a2b86f1
JD
424 global $DB, $PAGE;
425
6981de10
MN
426 // Prevent exception being thrown when array is empty.
427 if (empty($userids)) {
428 return [];
429 }
430
2a2b86f1
JD
431 list($useridsql, $usersparams) = $DB->get_in_or_equal($userids);
432 $userfields = \user_picture::fields('u', array('lastaccess'));
eb5865da 433 $userssql = "SELECT $userfields, u.deleted, mc.id AS contactid, mub.id AS blockedid
2a2b86f1
JD
434 FROM {user} u
435 LEFT JOIN {message_contacts} mc
38004e77 436 ON ((mc.userid = ? AND mc.contactid = u.id) OR (mc.userid = u.id AND mc.contactid = ?))
2a2b86f1
JD
437 LEFT JOIN {message_users_blocked} mub
438 ON (mub.userid = ? AND mub.blockeduserid = u.id)
eb5865da 439 WHERE u.id $useridsql";
38004e77 440 $usersparams = array_merge([$referenceuserid, $referenceuserid, $referenceuserid], $usersparams);
2a2b86f1
JD
441 $otherusers = $DB->get_records_sql($userssql, $usersparams);
442
443 $members = [];
444 foreach ($otherusers as $member) {
445 // Set basic data.
446 $data = new \stdClass();
447 $data->id = $member->id;
448 $data->fullname = fullname($member);
449
9b39f282
MN
450 // Create the URL for their profile.
451 $profileurl = new \moodle_url('/user/profile.php', ['id' => $member->id]);
452 $data->profileurl = $profileurl->out(false);
453
2a2b86f1
JD
454 // Set the user picture data.
455 $userpicture = new \user_picture($member);
456 $userpicture->size = 1; // Size f1.
457 $data->profileimageurl = $userpicture->get_url($PAGE)->out(false);
458 $userpicture->size = 0; // Size f2.
459 $data->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
460
461 // Set online status indicators.
52beee65
MN
462 $data->isonline = false;
463 $data->showonlinestatus = false;
464 if (!$member->deleted) {
465 $data->isonline = self::show_online_status($member) ? self::is_online($member->lastaccess) : null;
466 $data->showonlinestatus = is_null($data->isonline) ? false : true;
467 }
2a2b86f1
JD
468
469 // Set contact and blocked status indicators.
470 $data->iscontact = ($member->contactid) ? true : false;
66fffdbc
MN
471
472 // We don't want that a user has been blocked if they can message the user anyways.
473 $canmessageifblocked = api::can_send_message($referenceuserid, $member->id, true);
474 $data->isblocked = ($member->blockedid && !$canmessageifblocked) ? true : false;
2a2b86f1 475
eb5865da
JD
476 $data->isdeleted = ($member->deleted) ? true : false;
477
82e0973c
MN
478 $data->requirescontact = null;
479 $data->canmessage = null;
90403c5d 480 $data->canmessageevenifblocked = null;
82e0973c
MN
481 if ($includeprivacyinfo) {
482 $privacysetting = api::get_user_privacy_messaging_preference($member->id);
483 $data->requirescontact = $privacysetting == api::MESSAGE_PRIVACY_ONLYCONTACTS;
484
66fffdbc
MN
485 // Here we check that if the sender wanted to block the recipient, the
486 // recipient would still be able to message them regardless.
487 $data->canmessageevenifblocked = !$data->isdeleted && $canmessageifblocked;
06d046c1 488 $data->canmessage = !$data->isdeleted && api::can_send_message($member->id, $referenceuserid);
82e0973c
MN
489 }
490
cef1d977
MN
491 // Populate the contact requests, even if we don't need them.
492 $data->contactrequests = [];
493
2a2b86f1
JD
494 $members[$data->id] = $data;
495 }
054834b0
MN
496
497 // Check if we want to include contact requests as well.
498 if (!empty($members) && $includecontactrequests) {
499 list($useridsql, $usersparams) = $DB->get_in_or_equal($userids);
500
5c675c50
MN
501 $wheresql = "(userid $useridsql AND requesteduserid = ?) OR (userid = ? AND requesteduserid $useridsql)";
502 $params = array_merge($usersparams, [$referenceuserid, $referenceuserid], $usersparams);
503 if ($contactrequests = $DB->get_records_select('message_contact_requests', $wheresql, $params,
504 'timecreated ASC, id ASC')) {
054834b0
MN
505 foreach ($contactrequests as $contactrequest) {
506 if (isset($members[$contactrequest->userid])) {
507 $members[$contactrequest->userid]->contactrequests[] = $contactrequest;
508 }
509 if (isset($members[$contactrequest->requesteduserid])) {
510 $members[$contactrequest->requesteduserid]->contactrequests[] = $contactrequest;
511 }
512 }
513 }
514 }
515
fc266450
MN
516 // Remove any userids not in $members. This can happen in the case of a user who has been deleted
517 // from the Moodle database table (which can happen in earlier versions of Moodle).
518 $userids = array_filter($userids, function($userid) use ($members) {
519 return isset($members[$userid]);
520 });
521
9e6734a7
JD
522 // Return member information in the same order as the userids originally provided.
523 $members = array_replace(array_flip($userids), $members);
524
2a2b86f1
JD
525 return $members;
526 }
eb35e0b1 527 /**
1bc2a3b3 528 * @deprecated since 3.6
eb35e0b1 529 */
1bc2a3b3
MM
530 public static function get_conversations_legacy_formatter() {
531 throw new \coding_exception('\core_message\helper::get_conversations_legacy_formatter has been removed.');
eb35e0b1 532 }
fd998fc6
MN
533
534 /**
535 * Renders the messaging widget.
536 *
537 * @param bool $isdrawer Are we are rendering the drawer or is this on a full page?
538 * @param int|null $sendtouser The ID of the user we want to send a message to
539 * @param int|null $conversationid The ID of the conversation we want to load
6cb33ce7 540 * @param string|null $view The first view to load in the message widget
fd998fc6
MN
541 * @return string The HTML.
542 */
6cb33ce7
RW
543 public static function render_messaging_widget(
544 bool $isdrawer,
545 int $sendtouser = null,
546 int $conversationid = null,
547 string $view = null
548 ) {
fd998fc6
MN
549 global $USER, $CFG, $PAGE;
550
551 // Early bail out conditions.
552 if (empty($CFG->messaging) || !isloggedin() || isguestuser() || user_not_fully_set_up($USER) ||
553 get_user_preferences('auth_forcepasswordchange') ||
554 (!$USER->policyagreed && !is_siteadmin() &&
555 ($manager = new \core_privacy\local\sitepolicy\manager()) && $manager->is_defined())) {
556 return '';
557 }
558
559 $renderer = $PAGE->get_renderer('core');
560 $requestcount = \core_message\api::get_received_contact_requests_count($USER->id);
561 $contactscount = \core_message\api::count_contacts($USER->id);
562
563 $choices = [];
564 $choices[] = [
565 'value' => \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
566 'text' => get_string('contactableprivacy_onlycontacts', 'message')
567 ];
568 $choices[] = [
569 'value' => \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
570 'text' => get_string('contactableprivacy_coursemember', 'message')
571 ];
572 if (!empty($CFG->messagingallusers)) {
573 // Add the MESSAGE_PRIVACY_SITE option when site-wide messaging between users is enabled.
574 $choices[] = [
575 'value' => \core_message\api::MESSAGE_PRIVACY_SITE,
576 'text' => get_string('contactableprivacy_site', 'message')
577 ];
578 }
579
580 // Enter to send.
581 $entertosend = get_user_preferences('message_entertosend', $CFG->messagingdefaultpressenter, $USER);
582
6408ea75
MN
583 $notification = '';
584 if (!get_user_preferences('core_message_migrate_data', false)) {
585 $notification = get_string('messagingdatahasnotbeenmigrated', 'message');
586 }
587
fd998fc6
MN
588 if ($isdrawer) {
589 $template = 'core_message/message_drawer';
590 $messageurl = new \moodle_url('/message/index.php');
591 } else {
592 $template = 'core_message/message_index';
593 $messageurl = null;
594 }
595
596 $templatecontext = [
597 'contactrequestcount' => $requestcount,
598 'loggedinuser' => [
599 'id' => $USER->id,
600 'midnight' => usergetmidnight(time())
601 ],
8be24909
RW
602 // The starting timeout value for message polling.
603 'messagepollmin' => $CFG->messagingminpoll ?? MESSAGE_DEFAULT_MIN_POLL_IN_SECONDS,
604 // The maximum value that message polling timeout can reach.
605 'messagepollmax' => $CFG->messagingmaxpoll ?? MESSAGE_DEFAULT_MAX_POLL_IN_SECONDS,
606 // The timeout to reset back to after the max polling time has been reached.
607 'messagepollaftermax' => $CFG->messagingtimeoutpoll ?? MESSAGE_DEFAULT_TIMEOUT_POLL_IN_SECONDS,
fd998fc6
MN
608 'contacts' => [
609 'sectioncontacts' => [
610 'placeholders' => array_fill(0, $contactscount > 50 ? 50 : $contactscount, true)
611 ],
612 'sectionrequests' => [
613 'placeholders' => array_fill(0, $requestcount > 50 ? 50 : $requestcount, true)
614 ],
615 ],
616 'settings' => [
617 'privacy' => $choices,
618 'entertosend' => $entertosend
619 ],
620 'overview' => [
6408ea75
MN
621 'messageurl' => $messageurl,
622 'notification' => $notification
fd998fc6 623 ],
4060fcc6 624 'isdrawer' => $isdrawer,
f8f15423
FR
625 'showemojipicker' => !empty($CFG->allowemojipicker),
626 'messagemaxlength' => api::MESSAGE_MAX_LENGTH,
fd998fc6
MN
627 ];
628
6cb33ce7
RW
629 if ($sendtouser || $conversationid) {
630 $route = [
631 'path' => 'view-conversation',
632 'params' => $conversationid ? [$conversationid] : [null, 'create', $sendtouser]
633 ];
634 } else if ($view === 'contactrequests') {
635 $route = [
636 'path' => 'view-contacts',
637 'params' => ['requests']
638 ];
639 } else {
640 $route = null;
d5d4a5aa
MN
641 }
642
6cb33ce7 643 $templatecontext['route'] = json_encode($route);
fd998fc6
MN
644
645 return $renderer->render_from_template($template, $templatecontext);
646 }
3edac090
JD
647
648 /**
649 * Returns user details for a user, if they are visible to the current user in the message search.
650 *
651 * This method checks the visibility of a user specifically for the purpose of inclusion in the message search results.
652 * Visibility depends on the site-wide messaging setting 'messagingallusers':
653 * If enabled, visibility depends only on the core notion of visibility; a visible site or course profile.
654 * If disabled, visibility requires that the user be sharing a course with the searching user, and have a visible profile there.
655 * The current user is always returned.
656 *
657 * @param \stdClass $user
658 * @return array the array of userdetails, if visible, or an empty array otherwise.
659 */
660 public static function search_get_user_details(\stdClass $user) : array {
661 global $CFG, $USER;
662 require_once($CFG->dirroot . '/user/lib.php');
663
664 if ($CFG->messagingallusers || $user->id == $USER->id) {
665 return \user_get_user_details_courses($user) ?? []; // This checks visibility of site and course profiles.
666 } else {
667 // Messaging specific: user must share a course with the searching user AND have a visible profile there.
668 $sharedcourses = enrol_get_shared_courses($USER, $user);
669 foreach ($sharedcourses as $course) {
670 if (user_can_view_profile($user, $course)) {
671 $userdetails = user_get_user_details($user, $course);
672 if (!is_null($userdetails)) {
673 return $userdetails;
674 }
675 }
676 }
677 }
678 return [];
679 }
eda6bc19 680}