MDL-65132 core_message: Added WS to delete message for all users
[moodle.git] / message / externallib.php
CommitLineData
a623b6b8 1<?php
a623b6b8
JM
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
4615817d 17
a623b6b8
JM
18/**
19 * External message API
20 *
6fbd60ef 21 * @package core_message
4615817d
JM
22 * @category external
23 * @copyright 2011 Jerome Mouneyrac
a623b6b8
JM
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
4615817d 26
e71687ba
JL
27defined('MOODLE_INTERNAL') || die();
28
a623b6b8 29require_once("$CFG->libdir/externallib.php");
705afe6f 30require_once($CFG->dirroot . "/message/lib.php");
a623b6b8 31
5d1017e1 32/**
4615817d 33 * Message external functions
6fbd60ef
AD
34 *
35 * @package core_message
4615817d
JM
36 * @category external
37 * @copyright 2011 Jerome Mouneyrac
75e4f98c 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4615817d 39 * @since Moodle 2.2
5d1017e1
JM
40 */
41class core_message_external extends external_api {
2553e9db
JD
42 /**
43 * Returns description of method parameters
44 *
45 * @return external_function_parameters
46 * @since Moodle 3.6
47 */
48 public static function send_messages_to_conversation_parameters() {
49 return new external_function_parameters(
50 array(
51 'conversationid' => new external_value(PARAM_INT, 'id of the conversation'),
52 'messages' => new external_multiple_structure(
53 new external_single_structure(
54 array(
55 'text' => new external_value(PARAM_RAW, 'the text of the message'),
56 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
57 )
58 )
59 )
60 )
61 );
62 }
63
64 /**
65 * Send messages from the current USER to a conversation.
66 *
67 * This conversation may be any type of conversation, individual or group.
68 *
69 * @param int $conversationid the id of the conversation to which the messages will be sent.
70 * @param array $messages An array of message to send.
71 * @return array the array of messages which were sent (created).
72 * @since Moodle 3.6
73 */
74 public static function send_messages_to_conversation(int $conversationid, array $messages = []) {
75 global $CFG, $USER;
76
77 // Check if messaging is enabled.
78 if (empty($CFG->messaging)) {
79 throw new moodle_exception('disabled', 'message');
80 }
81
82 // Ensure the current user is allowed to run this function.
83 $context = context_system::instance();
84 self::validate_context($context);
85
86 $params = self::validate_parameters(self::send_messages_to_conversation_parameters(), [
87 'conversationid' => $conversationid,
88 'messages' => $messages
89 ]);
90
91 $messages = [];
92 foreach ($params['messages'] as $message) {
a111ab44 93 $createdmessage = \core_message\api::send_message_to_conversation($USER->id, $params['conversationid'], $message['text'],
2553e9db 94 $message['textformat']);
a111ab44
RW
95 $createdmessage->text = message_format_message_text((object) [
96 'smallmessage' => $createdmessage->text,
3a5afbf5 97 'fullmessageformat' => external_validate_format($message['textformat']),
98 'fullmessagetrust' => $createdmessage->fullmessagetrust
a111ab44
RW
99 ]);
100 $messages[] = $createdmessage;
2553e9db
JD
101 }
102
103 return $messages;
104 }
105
106 /**
107 * Returns description of method result value.
108 *
109 * @return external_description
110 * @since Moodle 3.6
111 */
112 public static function send_messages_to_conversation_returns() {
113 return new external_multiple_structure(
114 self::get_conversation_message_structure()
115 );
116 }
117
a623b6b8
JM
118
119 /**
120 * Returns description of method parameters
4615817d 121 *
a623b6b8 122 * @return external_function_parameters
4615817d 123 * @since Moodle 2.2
a623b6b8 124 */
5d1017e1 125 public static function send_instant_messages_parameters() {
a623b6b8
JM
126 return new external_function_parameters(
127 array(
128 'messages' => new external_multiple_structure(
129 new external_single_structure(
130 array(
131 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'),
93ce0e82 132 'text' => new external_value(PARAM_RAW, 'the text of the message'),
14968ca9 133 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
a623b6b8
JM
134 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the message. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL),
135 )
136 )
137 )
138 )
139 );
140 }
141
142 /**
143 * Send private messages from the current USER to other users
144 *
4615817d
JM
145 * @param array $messages An array of message to send.
146 * @return array
147 * @since Moodle 2.2
a623b6b8 148 */
5d1017e1 149 public static function send_instant_messages($messages = array()) {
a623b6b8 150 global $CFG, $USER, $DB;
a623b6b8 151
436bbf89 152 // Check if messaging is enabled.
837941e9 153 if (empty($CFG->messaging)) {
a623b6b8
JM
154 throw new moodle_exception('disabled', 'message');
155 }
156
157 // Ensure the current user is allowed to run this function
bf0f06b1 158 $context = context_system::instance();
a623b6b8
JM
159 self::validate_context($context);
160 require_capability('moodle/site:sendmessage', $context);
161
e3e19387 162 // Ensure the current user is allowed to delete message for everyone.
163 $candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $context);
164
5d1017e1 165 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
a623b6b8
JM
166
167 //retrieve all tousers of the messages
4de00da7 168 $receivers = array();
a623b6b8 169 foreach($params['messages'] as $message) {
4de00da7 170 $receivers[] = $message['touserid'];
a623b6b8 171 }
f219eac7 172 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
a623b6b8 173 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
a623b6b8
JM
174
175 $resultmessages = array();
886b0178 176 $messageids = array();
a623b6b8 177 foreach ($params['messages'] as $message) {
a623b6b8
JM
178 $resultmsg = array(); //the infos about the success of the operation
179
f7dfa9ba
SA
180 // We are going to do some checking.
181 // Code should match /messages/index.php checks.
a623b6b8
JM
182 $success = true;
183
f7dfa9ba 184 // Check the user exists.
a623b6b8
JM
185 if (empty($tousers[$message['touserid']])) {
186 $success = false;
187 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
188 }
189
f7dfa9ba
SA
190 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
191 // Check if the recipient can be messaged by the sender.
192 if ($success && !\core_message\api::can_post_message($tousers[$message['touserid']], $USER)) {
a623b6b8 193 $success = false;
f7dfa9ba 194 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message['touserid'])));
a623b6b8
JM
195 }
196
f7dfa9ba 197 // Now we can send the message (at least try).
a623b6b8 198 if ($success) {
f7dfa9ba 199 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
93ce0e82
JM
200 $success = message_post_message($USER, $tousers[$message['touserid']],
201 $message['text'], external_validate_format($message['textformat']));
a623b6b8
JM
202 }
203
f7dfa9ba 204 // Build the resultmsg.
a623b6b8 205 if (isset($message['clientmsgid'])) {
78736e5d 206 $resultmsg['clientmsgid'] = $message['clientmsgid'];
a623b6b8
JM
207 }
208 if ($success) {
209 $resultmsg['msgid'] = $success;
886b0178 210 $resultmsg['timecreated'] = time();
e3e19387 211 $resultmsg['candeletemessagesforallusers'] = $candeletemessagesforallusers;
886b0178 212 $messageids[] = $success;
a623b6b8 213 } else {
93ce0e82
JM
214 // WARNINGS: for backward compatibility we return this errormessage.
215 // We should have thrown exceptions as these errors prevent results to be returned.
216 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
a623b6b8
JM
217 $resultmsg['msgid'] = -1;
218 $resultmsg['errormessage'] = $errormessage;
219 }
220
221 $resultmessages[] = $resultmsg;
222 }
223
886b0178 224 if (!empty($messageids)) {
3a5afbf5 225 $messagerecords = $DB->get_records_list(
226 'messages',
227 'id',
228 $messageids,
229 '',
230 'id, conversationid, smallmessage, fullmessageformat, fullmessagetrust');
886b0178
RW
231 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) {
232 $id = $resultmessage['msgid'];
233 $resultmessage['conversationid'] = isset($messagerecords[$id]) ? $messagerecords[$id]->conversationid : null;
234 $resultmessage['useridfrom'] = $USER->id;
3a5afbf5 235 $resultmessage['text'] = message_format_message_text((object) [
236 'smallmessage' => $messagerecords[$id]->smallmessage,
237 'fullmessageformat' => external_validate_format($messagerecords[$id]->fullmessageformat),
238 'fullmessagetrust' => $messagerecords[$id]->fullmessagetrust
239 ]);
886b0178
RW
240 return $resultmessage;
241 }, $resultmessages);
242 }
243
a623b6b8
JM
244 return $resultmessages;
245 }
246
247 /**
248 * Returns description of method result value
4615817d 249 *
a623b6b8 250 * @return external_description
4615817d 251 * @since Moodle 2.2
a623b6b8 252 */
5d1017e1 253 public static function send_instant_messages_returns() {
a623b6b8
JM
254 return new external_multiple_structure(
255 new external_single_structure(
256 array(
78736e5d 257 'msgid' => new external_value(PARAM_INT, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
4de00da7 258 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
886b0178
RW
259 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL),
260 'text' => new external_value(PARAM_RAW, 'The text of the message', VALUE_OPTIONAL),
261 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message', VALUE_OPTIONAL),
262 'conversationid' => new external_value(PARAM_INT, 'The conversation id for this message', VALUE_OPTIONAL),
263 'useridfrom' => new external_value(PARAM_INT, 'The user id who sent the message', VALUE_OPTIONAL),
e3e19387 264 'candeletemessagesforallusers' => new external_value(PARAM_BOOL,
265 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false),
a623b6b8
JM
266 )
267 )
268 );
269 }
270
d6731600
FM
271 /**
272 * Create contacts parameters description.
273 *
0b3eadcd 274 * @deprecated since Moodle 3.6
d6731600 275 * @return external_function_parameters
5bcfd504 276 * @since Moodle 2.5
d6731600
FM
277 */
278 public static function create_contacts_parameters() {
279 return new external_function_parameters(
280 array(
281 'userids' => new external_multiple_structure(
282 new external_value(PARAM_INT, 'User ID'),
283 'List of user IDs'
34c2f347
MN
284 ),
285 'userid' => new external_value(PARAM_INT, 'The id of the user we are creating the contacts for, 0 for the
286 current user', VALUE_DEFAULT, 0)
d6731600
FM
287 )
288 );
289 }
290
291 /**
292 * Create contacts.
293 *
0b3eadcd 294 * @deprecated since Moodle 3.6
d6731600 295 * @param array $userids array of user IDs.
34c2f347 296 * @param int $userid The id of the user we are creating the contacts for
d6731600 297 * @return external_description
5bcfd504 298 * @since Moodle 2.5
d6731600 299 */
34c2f347 300 public static function create_contacts($userids, $userid = 0) {
343ba16c 301 global $CFG, $USER;
436bbf89
DM
302
303 // Check if messaging is enabled.
837941e9 304 if (empty($CFG->messaging)) {
436bbf89
DM
305 throw new moodle_exception('disabled', 'message');
306 }
307
343ba16c
SL
308 if (empty($userid)) {
309 $userid = $USER->id;
310 }
311
312 // Validate context.
313 $context = context_system::instance();
314 self::validate_context($context);
315
bb650761
DW
316 $params = array('userids' => $userids, 'userid' => $userid);
317 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
318
343ba16c 319 $capability = 'moodle/site:manageallmessaging';
bb650761 320 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
343ba16c
SL
321 throw new required_capability_exception($context, $capability, 'nopermissions', '');
322 }
323
d6731600
FM
324 $warnings = array();
325 foreach ($params['userids'] as $id) {
bb650761 326 if (!message_add_contact($id, 0, $params['userid'])) {
d6731600
FM
327 $warnings[] = array(
328 'item' => 'user',
329 'itemid' => $id,
330 'warningcode' => 'contactnotcreated',
331 'message' => 'The contact could not be created'
332 );
333 }
334 }
335 return $warnings;
336 }
337
338 /**
339 * Create contacts return description.
340 *
0b3eadcd 341 * @deprecated since Moodle 3.6
d6731600 342 * @return external_description
5bcfd504 343 * @since Moodle 2.5
d6731600
FM
344 */
345 public static function create_contacts_returns() {
346 return new external_warnings();
347 }
348
0b3eadcd
MN
349 /**
350 * Marking the method as deprecated.
351 *
352 * @return bool
353 */
354 public static function create_contacts_is_deprecated() {
355 return true;
356 }
357
d6731600
FM
358 /**
359 * Delete contacts parameters description.
360 *
361 * @return external_function_parameters
5bcfd504 362 * @since Moodle 2.5
d6731600
FM
363 */
364 public static function delete_contacts_parameters() {
365 return new external_function_parameters(
366 array(
367 'userids' => new external_multiple_structure(
368 new external_value(PARAM_INT, 'User ID'),
369 'List of user IDs'
34c2f347
MN
370 ),
371 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the
372 current user', VALUE_DEFAULT, 0)
d6731600
FM
373 )
374 );
375 }
376
377 /**
378 * Delete contacts.
379 *
380 * @param array $userids array of user IDs.
34c2f347 381 * @param int $userid The id of the user we are deleting the contacts for
d6731600 382 * @return null
5bcfd504 383 * @since Moodle 2.5
d6731600 384 */
34c2f347 385 public static function delete_contacts($userids, $userid = 0) {
343ba16c 386 global $CFG, $USER;
436bbf89
DM
387
388 // Check if messaging is enabled.
837941e9 389 if (empty($CFG->messaging)) {
436bbf89
DM
390 throw new moodle_exception('disabled', 'message');
391 }
392
343ba16c
SL
393 if (empty($userid)) {
394 $userid = $USER->id;
395 }
396
397 // Validate context.
398 $context = context_system::instance();
399 self::validate_context($context);
400
bb650761
DW
401 $params = array('userids' => $userids, 'userid' => $userid);
402 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
403
343ba16c 404 $capability = 'moodle/site:manageallmessaging';
bb650761 405 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
343ba16c
SL
406 throw new required_capability_exception($context, $capability, 'nopermissions', '');
407 }
408
d6731600 409 foreach ($params['userids'] as $id) {
bb650761 410 \core_message\api::remove_contact($params['userid'], $id);
d6731600
FM
411 }
412
413 return null;
414 }
415
416 /**
417 * Delete contacts return description.
418 *
419 * @return external_description
5bcfd504 420 * @since Moodle 2.5
d6731600
FM
421 */
422 public static function delete_contacts_returns() {
423 return null;
424 }
425
086409f6
MN
426 /**
427 * Mute conversations parameters description.
428 *
429 * @return external_function_parameters
430 */
431 public static function mute_conversations_parameters() {
432 return new external_function_parameters(
433 [
434 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
435 'conversationids' => new external_multiple_structure(
436 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED)
437 ),
438 ]
439 );
440 }
441
442 /**
443 * Mutes conversations.
444 *
445 * @param int $userid The id of the user who is blocking
446 * @param array $conversationids The list of conversations being muted
447 * @return external_description
448 */
449 public static function mute_conversations(int $userid, array $conversationids) {
450 global $CFG, $USER;
451
452 // Check if messaging is enabled.
453 if (empty($CFG->messaging)) {
454 throw new moodle_exception('disabled', 'message');
455 }
456
457 // Validate context.
458 $context = context_system::instance();
459 self::validate_context($context);
460
461 $params = ['userid' => $userid, 'conversationids' => $conversationids];
462 $params = self::validate_parameters(self::mute_conversations_parameters(), $params);
463
464 $capability = 'moodle/site:manageallmessaging';
465 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
466 throw new required_capability_exception($context, $capability, 'nopermissions', '');
467 }
468
469 foreach ($params['conversationids'] as $conversationid) {
470 if (!\core_message\api::is_conversation_muted($params['userid'], $conversationid)) {
471 \core_message\api::mute_conversation($params['userid'], $conversationid);
472 }
473 }
474
475 return [];
476 }
477
478 /**
479 * Mute conversations return description.
480 *
481 * @return external_description
482 */
483 public static function mute_conversations_returns() {
484 return new external_warnings();
485 }
486
487 /**
488 * Unmute conversations parameters description.
489 *
490 * @return external_function_parameters
491 */
492 public static function unmute_conversations_parameters() {
493 return new external_function_parameters(
494 [
495 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
496 'conversationids' => new external_multiple_structure(
497 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED)
498 ),
499 ]
500 );
501 }
502
503 /**
504 * Unmute conversations.
505 *
506 * @param int $userid The id of the user who is unblocking
507 * @param array $conversationids The list of conversations being muted
508 */
509 public static function unmute_conversations(int $userid, array $conversationids) {
510 global $CFG, $USER;
511
512 // Check if messaging is enabled.
513 if (empty($CFG->messaging)) {
514 throw new moodle_exception('disabled', 'message');
515 }
516
517 // Validate context.
518 $context = context_system::instance();
519 self::validate_context($context);
520
521 $params = ['userid' => $userid, 'conversationids' => $conversationids];
522 $params = self::validate_parameters(self::unmute_conversations_parameters(), $params);
523
524 $capability = 'moodle/site:manageallmessaging';
525 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
526 throw new required_capability_exception($context, $capability, 'nopermissions', '');
527 }
528
529 foreach ($params['conversationids'] as $conversationid) {
530 \core_message\api::unmute_conversation($params['userid'], $conversationid);
531 }
532
533 return [];
534 }
535
536 /**
537 * Unmute conversations return description.
538 *
539 * @return external_description
540 */
541 public static function unmute_conversations_returns() {
542 return new external_warnings();
543 }
544
52284186
MN
545 /**
546 * Block user parameters description.
547 *
548 * @return external_function_parameters
549 */
550 public static function block_user_parameters() {
551 return new external_function_parameters(
552 [
553 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
554 'blockeduserid' => new external_value(PARAM_INT, 'The id of the user being blocked'),
555 ]
556 );
557 }
558
559 /**
560 * Blocks a user.
561 *
562 * @param int $userid The id of the user who is blocking
563 * @param int $blockeduserid The id of the user being blocked
564 * @return external_description
565 */
566 public static function block_user(int $userid, int $blockeduserid) {
567 global $CFG, $USER;
568
569 // Check if messaging is enabled.
570 if (empty($CFG->messaging)) {
571 throw new moodle_exception('disabled', 'message');
572 }
573
574 // Validate context.
575 $context = context_system::instance();
576 self::validate_context($context);
577
bb650761
DW
578 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
579 $params = self::validate_parameters(self::block_user_parameters(), $params);
580
52284186 581 $capability = 'moodle/site:manageallmessaging';
bb650761 582 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
52284186
MN
583 throw new required_capability_exception($context, $capability, 'nopermissions', '');
584 }
585
52284186
MN
586 if (!\core_message\api::is_blocked($params['userid'], $params['blockeduserid'])) {
587 \core_message\api::block_user($params['userid'], $params['blockeduserid']);
588 }
589
590 return [];
591 }
592
593 /**
594 * Block user return description.
595 *
596 * @return external_description
597 */
598 public static function block_user_returns() {
599 return new external_warnings();
600 }
601
602 /**
603 * Unblock user parameters description.
604 *
605 * @return external_function_parameters
606 */
607 public static function unblock_user_parameters() {
608 return new external_function_parameters(
609 [
610 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
611 'unblockeduserid' => new external_value(PARAM_INT, 'The id of the user being unblocked'),
612 ]
613 );
614 }
615
616 /**
617 * Unblock user.
618 *
619 * @param int $userid The id of the user who is unblocking
620 * @param int $unblockeduserid The id of the user being unblocked
621 */
622 public static function unblock_user(int $userid, int $unblockeduserid) {
623 global $CFG, $USER;
624
625 // Check if messaging is enabled.
626 if (empty($CFG->messaging)) {
627 throw new moodle_exception('disabled', 'message');
628 }
629
630 // Validate context.
631 $context = context_system::instance();
632 self::validate_context($context);
633
bb650761
DW
634 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
635 $params = self::validate_parameters(self::unblock_user_parameters(), $params);
636
52284186 637 $capability = 'moodle/site:manageallmessaging';
bb650761 638 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
52284186
MN
639 throw new required_capability_exception($context, $capability, 'nopermissions', '');
640 }
641
52284186
MN
642 \core_message\api::unblock_user($params['userid'], $params['unblockeduserid']);
643
644 return [];
645 }
646
647 /**
648 * Unblock user return description.
649 *
650 * @return external_description
651 */
652 public static function unblock_user_returns() {
653 return new external_warnings();
654 }
655
d6731600
FM
656 /**
657 * Block contacts parameters description.
658 *
0b3eadcd 659 * @deprecated since Moodle 3.6
d6731600 660 * @return external_function_parameters
5bcfd504 661 * @since Moodle 2.5
d6731600
FM
662 */
663 public static function block_contacts_parameters() {
664 return new external_function_parameters(
665 array(
666 'userids' => new external_multiple_structure(
667 new external_value(PARAM_INT, 'User ID'),
668 'List of user IDs'
34c2f347
MN
669 ),
670 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the
671 current user', VALUE_DEFAULT, 0)
d6731600
FM
672 )
673 );
674 }
675
676 /**
677 * Block contacts.
678 *
0b3eadcd 679 * @deprecated since Moodle 3.6
d6731600 680 * @param array $userids array of user IDs.
34c2f347 681 * @param int $userid The id of the user we are blocking the contacts for
d6731600 682 * @return external_description
5bcfd504 683 * @since Moodle 2.5
d6731600 684 */
34c2f347 685 public static function block_contacts($userids, $userid = 0) {
343ba16c 686 global $CFG, $USER;
436bbf89
DM
687
688 // Check if messaging is enabled.
837941e9 689 if (empty($CFG->messaging)) {
436bbf89
DM
690 throw new moodle_exception('disabled', 'message');
691 }
692
343ba16c
SL
693 if (empty($userid)) {
694 $userid = $USER->id;
695 }
696
697 // Validate context.
698 $context = context_system::instance();
699 self::validate_context($context);
700
bb650761
DW
701 $params = array('userids' => $userids, 'userid' => $userid);
702 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
703
343ba16c 704 $capability = 'moodle/site:manageallmessaging';
bb650761 705 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
343ba16c
SL
706 throw new required_capability_exception($context, $capability, 'nopermissions', '');
707 }
708
d6731600
FM
709 $warnings = array();
710 foreach ($params['userids'] as $id) {
bb650761 711 if (!message_block_contact($id, $params['userid'])) {
d6731600
FM
712 $warnings[] = array(
713 'item' => 'user',
714 'itemid' => $id,
715 'warningcode' => 'contactnotblocked',
716 'message' => 'The contact could not be blocked'
717 );
718 }
719 }
720 return $warnings;
721 }
722
723 /**
724 * Block contacts return description.
725 *
0b3eadcd 726 * @deprecated since Moodle 3.6
d6731600 727 * @return external_description
5bcfd504 728 * @since Moodle 2.5
d6731600
FM
729 */
730 public static function block_contacts_returns() {
731 return new external_warnings();
732 }
733
0b3eadcd
MN
734 /**
735 * Marking the method as deprecated.
736 *
737 * @return bool
738 */
739 public static function block_contacts_is_deprecated() {
740 return true;
741 }
742
d6731600
FM
743 /**
744 * Unblock contacts parameters description.
745 *
0b3eadcd 746 * @deprecated since Moodle 3.6
d6731600 747 * @return external_function_parameters
5bcfd504 748 * @since Moodle 2.5
d6731600
FM
749 */
750 public static function unblock_contacts_parameters() {
751 return new external_function_parameters(
752 array(
753 'userids' => new external_multiple_structure(
754 new external_value(PARAM_INT, 'User ID'),
755 'List of user IDs'
34c2f347
MN
756 ),
757 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the
758 current user', VALUE_DEFAULT, 0)
d6731600
FM
759 )
760 );
761 }
762
763 /**
764 * Unblock contacts.
765 *
766 * @param array $userids array of user IDs.
34c2f347 767 * @param int $userid The id of the user we are unblocking the contacts for
d6731600 768 * @return null
5bcfd504 769 * @since Moodle 2.5
d6731600 770 */
34c2f347 771 public static function unblock_contacts($userids, $userid = 0) {
343ba16c 772 global $CFG, $USER;
436bbf89
DM
773
774 // Check if messaging is enabled.
837941e9 775 if (empty($CFG->messaging)) {
436bbf89
DM
776 throw new moodle_exception('disabled', 'message');
777 }
778
343ba16c
SL
779 if (empty($userid)) {
780 $userid = $USER->id;
781 }
782
783 // Validate context.
784 $context = context_system::instance();
785 self::validate_context($context);
786
bb650761
DW
787 $params = array('userids' => $userids, 'userid' => $userid);
788 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
789
343ba16c 790 $capability = 'moodle/site:manageallmessaging';
bb650761 791 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
343ba16c
SL
792 throw new required_capability_exception($context, $capability, 'nopermissions', '');
793 }
794
d6731600 795 foreach ($params['userids'] as $id) {
bb650761 796 message_unblock_contact($id, $params['userid']);
d6731600
FM
797 }
798
799 return null;
800 }
801
802 /**
803 * Unblock contacts return description.
804 *
0b3eadcd 805 * @deprecated since Moodle 3.6
d6731600 806 * @return external_description
5bcfd504 807 * @since Moodle 2.5
d6731600
FM
808 */
809 public static function unblock_contacts_returns() {
810 return null;
811 }
812
0b3eadcd
MN
813 /**
814 * Marking the method as deprecated.
815 *
816 * @return bool
817 */
818 public static function unblock_contacts_is_deprecated() {
819 return true;
820 }
821
52284186
MN
822 /**
823 * Returns contact requests parameters description.
824 *
825 * @return external_function_parameters
826 */
827 public static function get_contact_requests_parameters() {
828 return new external_function_parameters(
829 [
accd6482
MN
830 'userid' => new external_value(PARAM_INT, 'The id of the user we want the requests for'),
831 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
832 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
52284186
MN
833 ]
834 );
835 }
836
837 /**
838 * Handles returning the contact requests for a user.
839 *
840 * This also includes the user data necessary to display information
841 * about the user.
842 *
843 * It will not include blocked users.
844 *
845 * @param int $userid The id of the user we want to get the contact requests for
accd6482
MN
846 * @param int $limitfrom
847 * @param int $limitnum
52284186 848 */
accd6482 849 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) {
52284186
MN
850 global $CFG, $USER;
851
852 // Check if messaging is enabled.
853 if (empty($CFG->messaging)) {
854 throw new moodle_exception('disabled', 'message');
855 }
856
857 // Validate context.
858 $context = context_system::instance();
859 self::validate_context($context);
860
accd6482
MN
861 $params = [
862 'userid' => $userid,
863 'limitfrom' => $limitfrom,
864 'limitnum' => $limitnum
865 ];
52284186
MN
866 $params = self::validate_parameters(self::get_contact_requests_parameters(), $params);
867
52284186 868 $capability = 'moodle/site:manageallmessaging';
bb650761 869 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
52284186
MN
870 throw new required_capability_exception($context, $capability, 'nopermissions', '');
871 }
872
accd6482 873 return \core_message\api::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']);
52284186
MN
874 }
875
876 /**
877 * Returns the contact requests return description.
878 *
879 * @return external_description
880 */
881 public static function get_contact_requests_returns() {
882 return new external_multiple_structure(
daa33803 883 self::get_conversation_member_structure()
52284186
MN
884 );
885 }
886
7d678923
MN
887 /**
888 * Returns the number of contact requests the user has received parameters description.
889 *
890 * @return external_function_parameters
891 */
892 public static function get_received_contact_requests_count_parameters() {
893 return new external_function_parameters(
894 array(
895 'userid' => new external_value(PARAM_INT, 'The id of the user we want to return the number of ' .
896 'received contact requests for', VALUE_REQUIRED),
897 )
898 );
899 }
900
901 /**
902 * Returns the number of contact requests the user has received.
903 *
904 * @param int $userid The ID of the user we want to return the number of received contact requests for
905 * @return external_value
906 */
907 public static function get_received_contact_requests_count(int $userid) {
908 global $CFG, $USER;
909
910 // Check if messaging is enabled.
911 if (empty($CFG->messaging)) {
912 throw new moodle_exception('disabled', 'message');
913 }
914
915 // Validate context.
916 $context = context_system::instance();
917 self::validate_context($context);
918
919 $params = [
920 'userid' => $userid,
921 ];
922 $params = self::validate_parameters(self::get_received_contact_requests_count_parameters(), $params);
923
924 $capability = 'moodle/site:manageallmessaging';
925 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
926 throw new required_capability_exception($context, $capability, 'nopermissions', '');
927 }
928
929 return \core_message\api::get_received_contact_requests_count($params['userid']);
930 }
931
932 /**
933 * Returns the number of contact requests the user has received return description.
934 *
935 * @return external_value
936 */
937 public static function get_received_contact_requests_count_returns() {
938 return new external_value(PARAM_INT, 'The number of received contact requests');
939 }
940
5584c48a
MN
941 /**
942 * Returns get conversation members parameters description.
943 *
944 * @return external_function_parameters
945 */
946 public static function get_conversation_members_parameters() {
947 return new external_function_parameters(
948 [
949 'userid' => new external_value(PARAM_INT, 'The id of the user we are performing this action on behalf of'),
950 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation'),
951 'includecontactrequests' => new external_value(PARAM_BOOL, 'Do we want to include contact requests?',
952 VALUE_DEFAULT, false),
663ccd58
RW
953 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Do we want to include privacy info?',
954 VALUE_DEFAULT, false),
5584c48a
MN
955 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
956 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
957 ]
958 );
959 }
960
961 /**
962 * Returns a list of conversation members.
963 *
964 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
965 * @param int $conversationid The id of the conversation
966 * @param bool $includecontactrequests Do we want to include contact requests with this data?
663ccd58 967 * @param bool $includeprivacyinfo Do we want to include privacy info?
5584c48a
MN
968 * @param int $limitfrom
969 * @param int $limitnum
970 * @return array
971 */
972 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
663ccd58 973 bool $includeprivacyinfo = false, int $limitfrom = 0, int $limitnum = 0) {
5584c48a
MN
974 global $CFG, $USER;
975
976 // Check if messaging is enabled.
977 if (empty($CFG->messaging)) {
978 throw new moodle_exception('disabled', 'message');
979 }
980
981 // Validate context.
982 $context = context_system::instance();
983 self::validate_context($context);
984
bb650761
DW
985 $params = [
986 'userid' => $userid,
987 'conversationid' => $conversationid,
988 'includecontactrequests' => $includecontactrequests,
663ccd58 989 'includeprivacyinfo' => $includeprivacyinfo,
bb650761
DW
990 'limitfrom' => $limitfrom,
991 'limitnum' => $limitnum
992 ];
993 $params = self::validate_parameters(self::get_conversation_members_parameters(), $params);
994
5584c48a 995 $capability = 'moodle/site:manageallmessaging';
bb650761 996 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
5584c48a
MN
997 throw new required_capability_exception($context, $capability, 'nopermissions', '');
998 }
999
bc667050 1000 // The user needs to be a part of the conversation before querying who the members are.
bb650761 1001 if (!\core_message\api::is_user_in_conversation($params['userid'], $params['conversationid'])) {
bc667050
MN
1002 throw new moodle_exception('You are not a member of this conversation.');
1003 }
1004
bb650761 1005 return \core_message\api::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'],
663ccd58 1006 $params['includeprivacyinfo'], $params['limitfrom'], $params['limitnum']);
5584c48a
MN
1007 }
1008
1009 /**
1010 * Returns the get conversation members return description.
1011 *
1012 * @return external_description
1013 */
1014 public static function get_conversation_members_returns() {
1015 return new external_multiple_structure(
34b940f6 1016 self::get_conversation_member_structure()
5584c48a
MN
1017 );
1018 }
1019
52284186
MN
1020 /**
1021 * Creates a contact request parameters description.
1022 *
1023 * @return external_function_parameters
1024 */
1025 public static function create_contact_request_parameters() {
1026 return new external_function_parameters(
1027 [
1028 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1029 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1030 ]
1031 );
1032 }
1033
1034 /**
1035 * Creates a contact request.
1036 *
1037 * @param int $userid The id of the user who is creating the contact request
1038 * @param int $requesteduserid The id of the user being requested
1039 */
1040 public static function create_contact_request(int $userid, int $requesteduserid) {
1041 global $CFG, $USER;
1042
1043 // Check if messaging is enabled.
1044 if (empty($CFG->messaging)) {
1045 throw new moodle_exception('disabled', 'message');
1046 }
1047
1048 // Validate context.
1049 $context = context_system::instance();
1050 self::validate_context($context);
1051
bb650761
DW
1052 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1053 $params = self::validate_parameters(self::create_contact_request_parameters(), $params);
1054
52284186 1055 $capability = 'moodle/site:manageallmessaging';
bb650761 1056 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
52284186
MN
1057 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1058 }
1059
0866b336
RW
1060 $result = [
1061 'warnings' => []
1062 ];
1063
0d203bbf 1064 if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) {
0866b336 1065 $result['warnings'][] = [
0d203bbf
MN
1066 'item' => 'user',
1067 'itemid' => $params['requesteduserid'],
1068 'warningcode' => 'cannotcreatecontactrequest',
1069 'message' => 'You are unable to create a contact request for this user'
1070 ];
0866b336
RW
1071 } else {
1072 if ($requests = \core_message\api::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) {
1073 // There should only ever be one but just in case there are multiple then we can return the first.
1074 $result['request'] = array_shift($requests);
1075 } else {
1076 $result['request'] = \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']);
1077 }
52284186
MN
1078 }
1079
0866b336 1080 return $result;
52284186
MN
1081 }
1082
1083 /**
1084 * Creates a contact request return description.
1085 *
1086 * @return external_description
1087 */
1088 public static function create_contact_request_returns() {
0866b336
RW
1089 return new external_single_structure(
1090 array(
1091 'request' => new external_single_structure(
1092 array(
1093 'id' => new external_value(PARAM_INT, 'Message id'),
1094 'userid' => new external_value(PARAM_INT, 'User from id'),
1095 'requesteduserid' => new external_value(PARAM_INT, 'User to id'),
1096 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1097 ),
1098 'request record',
1099 VALUE_OPTIONAL
1100 ),
1101 'warnings' => new external_warnings()
1102 )
1103 );
52284186
MN
1104 }
1105
1106 /**
1107 * Confirm a contact request parameters description.
1108 *
1109 * @return external_function_parameters
1110 */
1111 public static function confirm_contact_request_parameters() {
1112 return new external_function_parameters(
1113 [
1114 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1115 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1116 ]
1117 );
1118 }
1119
1120 /**
1121 * Confirm a contact request.
1122 *
1123 * @param int $userid The id of the user who is creating the contact request
1124 * @param int $requesteduserid The id of the user being requested
1125 */
1126 public static function confirm_contact_request(int $userid, int $requesteduserid) {
1127 global $CFG, $USER;
1128
1129 // Check if messaging is enabled.
1130 if (empty($CFG->messaging)) {
1131 throw new moodle_exception('disabled', 'message');
1132 }
1133
1134 // Validate context.
1135 $context = context_system::instance();
1136 self::validate_context($context);
1137
bb650761
DW
1138 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1139 $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params);
1140
52284186 1141 $capability = 'moodle/site:manageallmessaging';
bb650761 1142 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) {
52284186
MN
1143 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1144 }
1145
52284186
MN
1146 \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']);
1147
1148 return [];
1149 }
1150
1151 /**
1152 * Confirm a contact request return description.
1153 *
1154 * @return external_description
1155 */
1156 public static function confirm_contact_request_returns() {
1157 return new external_warnings();
1158 }
1159
1160 /**
1161 * Declines a contact request parameters description.
1162 *
1163 * @return external_function_parameters
1164 */
1165 public static function decline_contact_request_parameters() {
1166 return new external_function_parameters(
1167 [
1168 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1169 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1170 ]
1171 );
1172 }
1173
1174 /**
1175 * Declines a contact request.
1176 *
1177 * @param int $userid The id of the user who is creating the contact request
1178 * @param int $requesteduserid The id of the user being requested
1179 */
1180 public static function decline_contact_request(int $userid, int $requesteduserid) {
1181 global $CFG, $USER;
1182
1183 // Check if messaging is enabled.
1184 if (empty($CFG->messaging)) {
1185 throw new moodle_exception('disabled', 'message');
1186 }
1187
1188 // Validate context.
1189 $context = context_system::instance();
1190 self::validate_context($context);
1191
bb650761
DW
1192 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1193 $params = self::validate_parameters(self::decline_contact_request_parameters(), $params);
1194
52284186 1195 $capability = 'moodle/site:manageallmessaging';
bb650761 1196 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) {
52284186
MN
1197 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1198 }
1199
52284186
MN
1200 \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']);
1201
1202 return [];
1203 }
1204
1205 /**
1206 * Declines a contact request return description.
1207 *
1208 * @return external_description
1209 */
1210 public static function decline_contact_request_returns() {
1211 return new external_warnings();
1212 }
1213
a3e3a3a1
MN
1214 /**
1215 * Return the structure of a message area contact.
1216 *
1217 * @return external_single_structure
1218 * @since Moodle 3.2
1219 */
1220 private static function get_messagearea_contact_structure() {
1221 return new external_single_structure(
1222 array(
1223 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
1224 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1225 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1226 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
5bf0ff27 1227 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
89a70ba1 1228 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
a3e3a3a1 1229 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
0802c38a 1230 'lastmessagedate' => new external_value(PARAM_INT, 'Timestamp for last message', VALUE_DEFAULT, null),
a3e3a3a1 1231 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
cb805753 1232 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
a3e3a3a1
MN
1233 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1234 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
dd0c1403 1235 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
a3e3a3a1
MN
1236 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1237 VALUE_DEFAULT, null),
d2708759 1238 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation', VALUE_DEFAULT, null),
a3e3a3a1
MN
1239 )
1240 );
1241 }
1242
6f31927a
JD
1243 /**
1244 * Return the structure of a conversation.
1245 *
1246 * @return external_single_structure
1247 * @since Moodle 3.6
1248 */
1249 private static function get_conversation_structure() {
1250 return new external_single_structure(
1251 array(
1252 'id' => new external_value(PARAM_INT, 'The conversation id'),
e66e867f
JD
1253 'name' => new external_value(PARAM_TEXT, 'The conversation name, if set', VALUE_DEFAULT, null),
1254 'subname' => new external_value(PARAM_TEXT, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null),
003cdcce 1255 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null),
734b198f 1256 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group,3=self)'),
6f31927a 1257 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'),
00c59245
MN
1258 'ismuted' => new external_value(PARAM_BOOL, 'If the user muted this conversation'),
1259 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked this conversation as a favourite'),
6f31927a
JD
1260 'isread' => new external_value(PARAM_BOOL, 'If the user has read all messages in the conversation'),
1261 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1262 VALUE_DEFAULT, null),
1263 'members' => new external_multiple_structure(
34b940f6 1264 self::get_conversation_member_structure()
6f31927a
JD
1265 ),
1266 'messages' => new external_multiple_structure(
1267 self::get_conversation_message_structure()
1268 ),
e3e19387 1269 'candeletemessagesforallusers' => new external_value(PARAM_BOOL,
1270 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false),
6f31927a
JD
1271 )
1272 );
1273 }
1274
fb04293b
SA
1275 /**
1276 * Return the structure of a conversation member.
1277 *
1278 * @return external_single_structure
1279 * @since Moodle 3.6
1280 */
34b940f6 1281 private static function get_conversation_member_structure() {
5584c48a
MN
1282 $result = [
1283 'id' => new external_value(PARAM_INT, 'The user id'),
1284 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
9b39f282 1285 'profileurl' => new external_value(PARAM_URL, 'The link to the user\'s profile page'),
5584c48a
MN
1286 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1287 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1288 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1289 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1290 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
1291 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?'),
d15c1e77 1292 'isdeleted' => new external_value(PARAM_BOOL, 'Is the user deleted?'),
cef1d977
MN
1293 'canmessage' => new external_value(PARAM_BOOL, 'If the user can be messaged'),
1294 'requirescontact' => new external_value(PARAM_BOOL, 'If the user requires to be contacts'),
5584c48a
MN
1295 ];
1296
5e47224a
AN
1297 $result['contactrequests'] = new external_multiple_structure(
1298 new external_single_structure(
1299 [
2be9a4ae
MN
1300 'id' => new external_value(PARAM_INT, 'The id of the contact request'),
1301 'userid' => new external_value(PARAM_INT, 'The id of the user who created the contact request'),
1302 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user confirming the request'),
1303 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the contact request'),
5e47224a
AN
1304 ]
1305 ), 'The contact requests', VALUE_OPTIONAL
1306 );
5584c48a 1307
5e47224a
AN
1308 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1309 array(
1310 'id' => new external_value(PARAM_INT, 'Conversations id'),
1311 'type' => new external_value(PARAM_INT, 'Conversation type: private or public'),
1312 'name' => new external_value(PARAM_TEXT, 'Multilang compatible conversation name'. VALUE_OPTIONAL),
1313 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the conversation'),
1314 ), 'information about conversation', VALUE_OPTIONAL),
1315 'Conversations between users', VALUE_OPTIONAL
1316 );
548cac7d 1317
fb04293b 1318 return new external_single_structure(
5584c48a 1319 $result
fb04293b
SA
1320 );
1321 }
1322
1323 /**
1324 * Return the structure of a message area message.
1325 *
1326 * @return external_single_structure
1327 * @since Moodle 3.6
1328 */
1329 private static function get_conversation_message_structure() {
1330 return new external_single_structure(
1331 array(
1332 'id' => new external_value(PARAM_INT, 'The id of the message'),
1333 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1334 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1335 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1336 )
1337 );
1338 }
1339
94e1db61
MN
1340 /**
1341 * Return the structure of a message area message.
1342 *
1343 * @return external_single_structure
1344 * @since Moodle 3.2
1345 */
1346 private static function get_messagearea_message_structure() {
1347 return new external_single_structure(
1348 array(
1349 'id' => new external_value(PARAM_INT, 'The id of the message'),
89a70ba1
MN
1350 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1351 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
94e1db61
MN
1352 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1353 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
1354 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
1355 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
1356 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
fb1469d8 1357 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
94e1db61
MN
1358 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
1359 )
1360 );
1361 }
1362
cd03b8d7 1363 /**
48e8bdba 1364 * Get messagearea search users in course parameters.
cd03b8d7 1365 *
548cac7d
AA
1366 * @deprecated since 3.6
1367 *
cd03b8d7
MN
1368 * @return external_function_parameters
1369 * @since 3.2
1370 */
48e8bdba 1371 public static function data_for_messagearea_search_users_in_course_parameters() {
cd03b8d7
MN
1372 return new external_function_parameters(
1373 array(
1374 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1375 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
1376 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1377 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1378 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1379 )
1380 );
1381 }
1382
1383 /**
48e8bdba 1384 * Get messagearea search users in course results.
cd03b8d7 1385 *
548cac7d
AA
1386 * @deprecated since 3.6
1387 *
cd03b8d7
MN
1388 * @param int $userid The id of the user who is performing the search
1389 * @param int $courseid The id of the course
1390 * @param string $search The string being searched
1391 * @param int $limitfrom
1392 * @param int $limitnum
1393 * @return stdClass
1394 * @throws moodle_exception
1395 * @since 3.2
1396 */
48e8bdba 1397 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
de55cb1b 1398 $limitnum = 0) {
837941e9 1399 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1400
1401 // Check if messaging is enabled.
837941e9 1402 if (empty($CFG->messaging)) {
cd03b8d7
MN
1403 throw new moodle_exception('disabled', 'message');
1404 }
1405
837941e9
MN
1406 $systemcontext = context_system::instance();
1407
cd03b8d7
MN
1408 $params = array(
1409 'userid' => $userid,
1410 'courseid' => $courseid,
1411 'search' => $search,
1412 'limitfrom' => $limitfrom,
1413 'limitnum' => $limitnum
1414 );
bb650761 1415 $params = self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
837941e9 1416 self::validate_context($systemcontext);
cd03b8d7 1417
bb650761 1418 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1419 throw new moodle_exception('You do not have permission to perform this action.');
1420 }
cd03b8d7 1421
bb650761
DW
1422 $users = \core_message\api::search_users_in_course(
1423 $params['userid'],
1424 $params['courseid'],
1425 $params['search'],
1426 $params['limitfrom'],
1427 $params['limitnum']
1428 );
de55cb1b 1429 $results = new \core_message\output\messagearea\user_search_results($users);
cd03b8d7
MN
1430
1431 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 1432 return $results->export_for_template($renderer);
cd03b8d7
MN
1433 }
1434
1435 /**
48e8bdba 1436 * Get messagearea search users in course returns.
cd03b8d7 1437 *
548cac7d
AA
1438 * @deprecated since 3.6
1439 *
cd03b8d7
MN
1440 * @return external_single_structure
1441 * @since 3.2
1442 */
48e8bdba 1443 public static function data_for_messagearea_search_users_in_course_returns() {
cd03b8d7
MN
1444 return new external_single_structure(
1445 array(
cd03b8d7 1446 'contacts' => new external_multiple_structure(
a3e3a3a1 1447 self::get_messagearea_contact_structure()
cd03b8d7
MN
1448 ),
1449 )
1450 );
1451 }
1452
548cac7d
AA
1453 /**
1454 * Marking the method as deprecated.
1455 *
1456 * @return bool
1457 */
1458 public static function data_for_messagearea_search_users_in_course_is_deprecated() {
1459 return true;
1460 }
1461
cd03b8d7 1462 /**
48e8bdba 1463 * Get messagearea search users parameters.
cd03b8d7 1464 *
548cac7d
AA
1465 * @deprecated since 3.6
1466 *
cd03b8d7
MN
1467 * @return external_function_parameters
1468 * @since 3.2
1469 */
48e8bdba 1470 public static function data_for_messagearea_search_users_parameters() {
cd03b8d7
MN
1471 return new external_function_parameters(
1472 array(
1473 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1474 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1475 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1476 )
1477 );
1478 }
1479
1480 /**
48e8bdba 1481 * Get messagearea search users results.
cd03b8d7 1482 *
548cac7d
AA
1483 * @deprecated since 3.6
1484 *
cd03b8d7
MN
1485 * @param int $userid The id of the user who is performing the search
1486 * @param string $search The string being searched
1487 * @param int $limitnum
1488 * @return stdClass
1489 * @throws moodle_exception
1490 * @since 3.2
1491 */
48e8bdba 1492 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
837941e9 1493 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1494
1495 // Check if messaging is enabled.
837941e9 1496 if (empty($CFG->messaging)) {
cd03b8d7
MN
1497 throw new moodle_exception('disabled', 'message');
1498 }
1499
837941e9
MN
1500 $systemcontext = context_system::instance();
1501
cd03b8d7
MN
1502 $params = array(
1503 'userid' => $userid,
1504 'search' => $search,
1505 'limitnum' => $limitnum
1506 );
bb650761 1507 $params = self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
837941e9 1508 self::validate_context($systemcontext);
cd03b8d7 1509
bb650761 1510 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1511 throw new moodle_exception('You do not have permission to perform this action.');
1512 }
cd03b8d7 1513
bb650761
DW
1514 list($contacts, $courses, $noncontacts) = \core_message\api::search_users(
1515 $params['userid'],
1516 $params['search'],
1517 $params['limitnum']
1518 );
1519
de55cb1b 1520 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
cd03b8d7
MN
1521
1522 $renderer = $PAGE->get_renderer('core_message');
1523 return $search->export_for_template($renderer);
1524 }
1525
1526 /**
48e8bdba 1527 * Get messagearea search users returns.
cd03b8d7 1528 *
548cac7d
AA
1529 * @deprecated since 3.6
1530 *
cd03b8d7
MN
1531 * @return external_single_structure
1532 * @since 3.2
1533 */
48e8bdba 1534 public static function data_for_messagearea_search_users_returns() {
cd03b8d7
MN
1535 return new external_single_structure(
1536 array(
cd03b8d7 1537 'contacts' => new external_multiple_structure(
a3e3a3a1 1538 self::get_messagearea_contact_structure()
cd03b8d7 1539 ),
cd03b8d7
MN
1540 'courses' => new external_multiple_structure(
1541 new external_single_structure(
1542 array(
1543 'id' => new external_value(PARAM_INT, 'The course id'),
7597ab0b
AA
1544 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
1545 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
cd03b8d7
MN
1546 )
1547 )
1548 ),
cd03b8d7 1549 'noncontacts' => new external_multiple_structure(
a3e3a3a1 1550 self::get_messagearea_contact_structure()
cd03b8d7
MN
1551 )
1552 )
1553 );
1554 }
1555
548cac7d
AA
1556 /**
1557 * Marking the method as deprecated.
1558 *
1559 * @return bool
1560 */
1561 public static function data_for_messagearea_search_users_is_deprecated() {
1562 return true;
1563 }
1564
1565 /**
1566 * Get messagearea message search users parameters.
1567 *
1568 * @return external_function_parameters
1569 * @since 3.6
1570 */
1571 public static function message_search_users_parameters() {
1572 return new external_function_parameters(
1573 array(
1574 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1575 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1576 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1577 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1578 )
1579 );
1580 }
1581
1582 /**
1583 * Get search users results.
1584 *
1585 * @param int $userid The id of the user who is performing the search
1586 * @param string $search The string being searched
1587 * @param int $limitfrom
1588 * @param int $limitnum
1589 * @return array
1590 * @throws moodle_exception
1591 * @since 3.6
1592 */
1593 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
41485be2 1594 global $USER;
548cac7d
AA
1595
1596 $systemcontext = context_system::instance();
1597
1598 $params = array(
1599 'userid' => $userid,
1600 'search' => $search,
1601 'limitfrom' => $limitfrom,
1602 'limitnum' => $limitnum
1603 );
1604 $params = self::validate_parameters(self::message_search_users_parameters(), $params);
1605 self::validate_context($systemcontext);
1606
1607 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1608 throw new moodle_exception('You do not have permission to perform this action.');
1609 }
1610
1611 list($contacts, $noncontacts) = \core_message\api::message_search_users(
1612 $params['userid'],
1613 $params['search'],
1614 $params['limitfrom'],
1615 $params['limitnum']);
1616
1617 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1618 }
1619
1620 /**
1621 * Get messagearea message search users returns.
1622 *
1623 * @return external_single_structure
1624 * @since 3.2
1625 */
1626 public static function message_search_users_returns() {
1627 return new external_single_structure(
1628 array(
1629 'contacts' => new external_multiple_structure(
34b940f6 1630 self::get_conversation_member_structure()
548cac7d
AA
1631 ),
1632 'noncontacts' => new external_multiple_structure(
34b940f6 1633 self::get_conversation_member_structure()
548cac7d
AA
1634 )
1635 )
1636 );
1637 }
1638
cd03b8d7
MN
1639 /**
1640 * Get messagearea search messages parameters.
1641 *
1642 * @return external_function_parameters
1643 * @since 3.2
1644 */
1645 public static function data_for_messagearea_search_messages_parameters() {
1646 return new external_function_parameters(
1647 array(
1648 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1649 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1650 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1651 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1652 )
1653 );
1654 }
1655
1656 /**
1657 * Get messagearea search messages results.
1658 *
1659 * @param int $userid The id of the user who is performing the search
1660 * @param string $search The string being searched
1661 * @param int $limitfrom
1662 * @param int $limitnum
1663 * @return stdClass
1664 * @throws moodle_exception
1665 * @since 3.2
1666 */
1667 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
ee45ecc0 1668 global $CFG, $USER;
cd03b8d7
MN
1669
1670 // Check if messaging is enabled.
837941e9 1671 if (empty($CFG->messaging)) {
cd03b8d7
MN
1672 throw new moodle_exception('disabled', 'message');
1673 }
1674
837941e9
MN
1675 $systemcontext = context_system::instance();
1676
cd03b8d7
MN
1677 $params = array(
1678 'userid' => $userid,
1679 'search' => $search,
1680 'limitfrom' => $limitfrom,
1681 'limitnum' => $limitnum
1682
1683 );
bb650761 1684 $params = self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
837941e9 1685 self::validate_context($systemcontext);
cd03b8d7 1686
bb650761 1687 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1688 throw new moodle_exception('You do not have permission to perform this action.');
1689 }
cd03b8d7 1690
bb650761
DW
1691 $messages = \core_message\api::search_messages(
1692 $params['userid'],
1693 $params['search'],
1694 $params['limitfrom'],
1695 $params['limitnum']
1696 );
cd03b8d7 1697
ee45ecc0
MN
1698 $data = new \stdClass();
1699 $data->contacts = [];
1700 foreach ($messages as $message) {
1701 $contact = new \stdClass();
1702 $contact->userid = $message->userid;
1703 $contact->fullname = $message->fullname;
1704 $contact->profileimageurl = $message->profileimageurl;
1705 $contact->profileimageurlsmall = $message->profileimageurlsmall;
1706 $contact->messageid = $message->messageid;
1707 $contact->ismessaging = $message->ismessaging;
1708 $contact->sentfromcurrentuser = false;
1709 if ($message->lastmessage) {
1710 if ($message->userid !== $message->useridfrom) {
1711 $contact->sentfromcurrentuser = true;
1712 }
1713 $contact->lastmessage = shorten_text($message->lastmessage, 60);
1714 } else {
1715 $contact->lastmessage = null;
1716 }
1717 $contact->lastmessagedate = $message->lastmessagedate;
1718 $contact->showonlinestatus = is_null($message->isonline) ? false : true;
1719 $contact->isonline = $message->isonline;
1720 $contact->isblocked = $message->isblocked;
1721 $contact->isread = $message->isread;
1722 $contact->unreadcount = $message->unreadcount;
1723 $contact->conversationid = $message->conversationid;
1724
1725 $data->contacts[] = $contact;
1726 }
1727
1728 return $data;
cd03b8d7
MN
1729 }
1730
1731 /**
1732 * Get messagearea search messages returns.
1733 *
1734 * @return external_single_structure
1735 * @since 3.2
1736 */
1737 public static function data_for_messagearea_search_messages_returns() {
1738 return new external_single_structure(
1739 array(
cd03b8d7 1740 'contacts' => new external_multiple_structure(
a3e3a3a1 1741 self::get_messagearea_contact_structure()
cd03b8d7
MN
1742 )
1743 )
1744 );
1745 }
1746
6f31927a
JD
1747 /**
1748 * Get conversations parameters.
1749 *
1750 * @return external_function_parameters
1751 * @since 3.6
1752 */
1753 public static function get_conversations_parameters() {
1754 return new external_function_parameters(
1755 array(
1756 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1757 'limitfrom' => new external_value(PARAM_INT, 'The offset to start at', VALUE_DEFAULT, 0),
1758 'limitnum' => new external_value(PARAM_INT, 'Limit number of conversations to this', VALUE_DEFAULT, 0),
1759 'type' => new external_value(PARAM_INT, 'Filter by type', VALUE_DEFAULT, null),
1760 'favourites' => new external_value(PARAM_BOOL, 'Whether to restrict the results to contain NO favourite
1761 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1762 VALUE_DEFAULT, null),
734b198f
SA
1763 'mergeself' => new external_value(PARAM_BOOL, 'Whether to include self-conversations (true) or ONLY private
1764 conversations (false) when private conversations are requested.',
1765 VALUE_DEFAULT, false),
6f31927a
JD
1766 )
1767 );
1768 }
1769
1770 /**
1771 * Get the list of conversations for the user.
1772 *
1773 * @param int $userid The id of the user who is performing the search
1774 * @param int $limitfrom
1775 * @param int $limitnum
1776 * @param int|null $type
1777 * @param bool|null $favourites
734b198f
SA
1778 * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false)
1779 * when private conversations are requested.
6f31927a
JD
1780 * @return stdClass
1781 * @throws \moodle_exception if the messaging feature is disabled on the site.
1782 * @since 3.2
1783 */
734b198f
SA
1784 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null,
1785 bool $mergeself = false) {
6f31927a
JD
1786 global $CFG, $USER;
1787
1788 // All the standard BL checks.
1789 if (empty($CFG->messaging)) {
1790 throw new moodle_exception('disabled', 'message');
1791 }
1792
1793 $params = array(
1794 'userid' => $userid,
1795 'limitfrom' => $limitfrom,
1796 'limitnum' => $limitnum,
1797 'type' => $type,
734b198f
SA
1798 'favourites' => $favourites,
1799 'mergeself' => $mergeself
6f31927a 1800 );
bb650761 1801 $params = self::validate_parameters(self::get_conversations_parameters(), $params);
6f31927a
JD
1802
1803 $systemcontext = context_system::instance();
1804 self::validate_context($systemcontext);
1805
bb650761 1806 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
6f31927a
JD
1807 throw new moodle_exception('You do not have permission to perform this action.');
1808 }
1809
bb650761
DW
1810 $conversations = \core_message\api::get_conversations(
1811 $params['userid'],
1812 $params['limitfrom'],
1813 $params['limitnum'],
1814 $params['type'],
734b198f
SA
1815 $params['favourites'],
1816 $params['mergeself']
bb650761
DW
1817 );
1818
6f31927a
JD
1819 return (object) ['conversations' => $conversations];
1820 }
1821
1822 /**
1823 * Get conversations returns.
1824 *
1825 * @return external_single_structure
1826 * @since 3.6
1827 */
1828 public static function get_conversations_returns() {
1829 return new external_single_structure(
1830 [
1831 'conversations' => new external_multiple_structure(
b3bbd4a0 1832 self::get_conversation_structure(true)
6f31927a
JD
1833 )
1834 ]
1835 );
1836 }
1837
4e313026
RW
1838 /**
1839 * Get conversation parameters.
1840 *
1841 * @return external_function_parameters
1842 */
1843 public static function get_conversation_parameters() {
1844 return new external_function_parameters(
1845 array(
1846 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1847 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation to fetch'),
1848 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1849 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1850 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1851 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1852 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1853 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1854 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1855 )
1856 );
1857 }
1858
1859 /**
1860 * Get a single conversation.
1861 *
1862 * @param int $userid The user id to get the conversation for
1863 * @param int $conversationid The id of the conversation to fetch
1864 * @param bool $includecontactrequests Should contact requests be included between members
1865 * @param bool $includeprivacyinfo Should privacy info be included between members
1866 * @param int $memberlimit Limit number of members to load
1867 * @param int $memberoffset Offset members by this amount
1868 * @param int $messagelimit Limit number of messages to load
1869 * @param int $messageoffset Offset the messages
1870 * @param bool $newestmessagesfirst Order messages by newest first
1871 * @return stdClass
1872 * @throws \moodle_exception if the messaging feature is disabled on the site.
1873 */
1874 public static function get_conversation(
1875 int $userid,
1876 int $conversationid,
1877 bool $includecontactrequests = false,
1878 bool $includeprivacyinfo = false,
1879 int $memberlimit = 0,
1880 int $memberoffset = 0,
1881 int $messagelimit = 0,
1882 int $messageoffset = 0,
1883 bool $newestmessagesfirst = true
1884 ) {
1885 global $CFG, $DB, $USER;
1886
1887 // All the standard BL checks.
1888 if (empty($CFG->messaging)) {
1889 throw new moodle_exception('disabled', 'message');
1890 }
1891
1892 $params = [
1893 'userid' => $userid,
1894 'conversationid' => $conversationid,
1895 'includecontactrequests' => $includecontactrequests,
1896 'includeprivacyinfo' => $includeprivacyinfo,
1897 'memberlimit' => $memberlimit,
1898 'memberoffset' => $memberoffset,
1899 'messagelimit' => $messagelimit,
1900 'messageoffset' => $messageoffset,
1901 'newestmessagesfirst' => $newestmessagesfirst
1902 ];
1903 self::validate_parameters(self::get_conversation_parameters(), $params);
1904
1905 $systemcontext = context_system::instance();
1906 self::validate_context($systemcontext);
1907
1908 $conversation = \core_message\api::get_conversation(
1909 $params['userid'],
1910 $params['conversationid'],
1911 $params['includecontactrequests'],
1912 $params['includeprivacyinfo'],
1913 $params['memberlimit'],
1914 $params['memberoffset'],
1915 $params['messagelimit'],
1916 $params['messageoffset'],
1917 $params['newestmessagesfirst']
1918 );
1919
1920 if ($conversation) {
1921 return $conversation;
1922 } else {
1923 // We have to throw an exception here because the external functions annoyingly
1924 // don't accept null to be returned for a single structure.
892356ac 1925 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
4e313026
RW
1926 }
1927 }
1928
1929 /**
1930 * Get conversation returns.
1931 *
1932 * @return external_single_structure
1933 */
1934 public static function get_conversation_returns() {
1935 return self::get_conversation_structure();
1936 }
1937
569c0bae
RW
1938 /**
1939 * Get conversation parameters.
1940 *
1941 * @return external_function_parameters
1942 */
1943 public static function get_conversation_between_users_parameters() {
1944 return new external_function_parameters(
1945 array(
1946 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1947 'otheruserid' => new external_value(PARAM_INT, 'The other user id'),
1948 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1949 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1950 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1951 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1952 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1953 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1954 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1955 )
1956 );
1957 }
1958
1959 /**
1960 * Get a single conversation between users.
1961 *
1962 * @param int $userid The user id to get the conversation for
1963 * @param int $otheruserid The other user id
1964 * @param bool $includecontactrequests Should contact requests be included between members
1965 * @param bool $includeprivacyinfo Should privacy info be included between members
1966 * @param int $memberlimit Limit number of members to load
1967 * @param int $memberoffset Offset members by this amount
1968 * @param int $messagelimit Limit number of messages to load
1969 * @param int $messageoffset Offset the messages
1970 * @param bool $newestmessagesfirst Order messages by newest first
1971 * @return stdClass
1972 * @throws \moodle_exception if the messaging feature is disabled on the site.
1973 */
1974 public static function get_conversation_between_users(
1975 int $userid,
1976 int $otheruserid,
1977 bool $includecontactrequests = false,
1978 bool $includeprivacyinfo = false,
1979 int $memberlimit = 0,
1980 int $memberoffset = 0,
1981 int $messagelimit = 0,
1982 int $messageoffset = 0,
1983 bool $newestmessagesfirst = true
1984 ) {
1985 global $CFG, $DB, $USER;
1986
1987 // All the standard BL checks.
1988 if (empty($CFG->messaging)) {
1989 throw new moodle_exception('disabled', 'message');
1990 }
1991
1992 $params = [
1993 'userid' => $userid,
1994 'otheruserid' => $otheruserid,
1995 'includecontactrequests' => $includecontactrequests,
1996 'includeprivacyinfo' => $includeprivacyinfo,
1997 'memberlimit' => $memberlimit,
1998 'memberoffset' => $memberoffset,
1999 'messagelimit' => $messagelimit,
2000 'messageoffset' => $messageoffset,
2001 'newestmessagesfirst' => $newestmessagesfirst
2002 ];
2003 self::validate_parameters(self::get_conversation_between_users_parameters(), $params);
2004
2005 $systemcontext = context_system::instance();
2006 self::validate_context($systemcontext);
2007
2008 $conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']]);
2009 $conversation = null;
2010
2011 if ($conversationid) {
2012 $conversation = \core_message\api::get_conversation(
2013 $params['userid'],
2014 $conversationid,
2015 $params['includecontactrequests'],
2016 $params['includeprivacyinfo'],
2017 $params['memberlimit'],
2018 $params['memberoffset'],
2019 $params['messagelimit'],
2020 $params['messageoffset'],
2021 $params['newestmessagesfirst']
2022 );
2023 }
2024
2025 if ($conversation) {
2026 return $conversation;
2027 } else {
2028 // We have to throw an exception here because the external functions annoyingly
2029 // don't accept null to be returned for a single structure.
892356ac 2030 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
569c0bae
RW
2031 }
2032 }
2033
2034 /**
2035 * Get conversation returns.
2036 *
2037 * @return external_single_structure
2038 */
2039 public static function get_conversation_between_users_returns() {
2040 return self::get_conversation_structure(true);
2041 }
2042
734b198f
SA
2043 /**
2044 * Get self-conversation parameters.
2045 *
2046 * @return external_function_parameters
2047 */
2048 public static function get_self_conversation_parameters() {
2049 return new external_function_parameters(
2050 array(
2051 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing self-conversations for'),
2052 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
2053 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
2054 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
2055 )
2056 );
2057 }
2058
2059 /**
2060 * Get a single self-conversation.
2061 *
2062 * @param int $userid The user id to get the self-conversation for
2063 * @param int $messagelimit Limit number of messages to load
2064 * @param int $messageoffset Offset the messages
2065 * @param bool $newestmessagesfirst Order messages by newest first
2066 * @return stdClass
2067 * @throws \moodle_exception if the messaging feature is disabled on the site.
2068 * @since Moodle 3.7
2069 */
2070 public static function get_self_conversation(
2071 int $userid,
2072 int $messagelimit = 0,
2073 int $messageoffset = 0,
2074 bool $newestmessagesfirst = true
2075 ) {
2076 global $CFG;
2077
2078 // All the standard BL checks.
2079 if (empty($CFG->messaging)) {
2080 throw new moodle_exception('disabled', 'message');
2081 }
2082
2083 $params = [
2084 'userid' => $userid,
2085 'messagelimit' => $messagelimit,
2086 'messageoffset' => $messageoffset,
2087 'newestmessagesfirst' => $newestmessagesfirst
2088 ];
2089 self::validate_parameters(self::get_self_conversation_parameters(), $params);
2090
2091 $systemcontext = context_system::instance();
2092 self::validate_context($systemcontext);
2093
2094 $conversation = \core_message\api::get_self_conversation($params['userid']);
2095
2096 if ($conversation) {
2097 $conversation = \core_message\api::get_conversation(
2098 $params['userid'],
2099 $conversation->id,
2100 false,
2101 false,
2102 0,
2103 0,
2104 $params['messagelimit'],
2105 $params['messageoffset'],
2106 $params['newestmessagesfirst']
2107 );
2108 }
2109
2110 if ($conversation) {
2111 return $conversation;
2112 } else {
2113 // We have to throw an exception here because the external functions annoyingly
2114 // don't accept null to be returned for a single structure.
2115 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
2116 }
2117 }
2118
2119 /**
2120 * Get conversation returns.
2121 *
2122 * @return external_single_structure
2123 */
2124 public static function get_self_conversation_returns() {
2125 return self::get_conversation_structure();
2126 }
2127
9aa012b5 2128 /**
49aaadc3 2129 * The messagearea conversations parameters.
9aa012b5 2130 *
eb35e0b1 2131 * @deprecated since 3.6
9aa012b5 2132 * @return external_function_parameters
49aaadc3 2133 * @since 3.2
9aa012b5
MN
2134 */
2135 public static function data_for_messagearea_conversations_parameters() {
2136 return new external_function_parameters(
2137 array(
2138 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
2139 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2140 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
2141 )
2142 );
2143 }
2144
2145 /**
2146 * Get messagearea conversations.
2147 *
eb35e0b1
JD
2148 * NOTE FOR FINAL DEPRECATION:
2149 * When removing this method, please also consider removal of get_conversations_legacy_formatter()
2150 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data
2151 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be
2152 * removed.
2153 *
2154 * @deprecated since 3.6
9aa012b5
MN
2155 * @param int $userid The id of the user who we are viewing conversations for
2156 * @param int $limitfrom
2157 * @param int $limitnum
49aaadc3
MN
2158 * @return stdClass
2159 * @throws moodle_exception
2160 * @since 3.2
9aa012b5
MN
2161 */
2162 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 2163 global $CFG, $PAGE, $USER;
9aa012b5
MN
2164
2165 // Check if messaging is enabled.
837941e9 2166 if (empty($CFG->messaging)) {
9aa012b5
MN
2167 throw new moodle_exception('disabled', 'message');
2168 }
2169
837941e9
MN
2170 $systemcontext = context_system::instance();
2171
9aa012b5
MN
2172 $params = array(
2173 'userid' => $userid,
2174 'limitfrom' => $limitfrom,
2175 'limitnum' => $limitnum
2176 );
bb650761 2177 $params = self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
837941e9 2178 self::validate_context($systemcontext);
9aa012b5 2179
bb650761 2180 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2181 throw new moodle_exception('You do not have permission to perform this action.');
2182 }
9aa012b5 2183
bb650761 2184 $conversations = \core_message\api::get_conversations($params['userid'], $params['limitfrom'], $params['limitnum']);
eb35e0b1
JD
2185
2186 // Format the conversations in the legacy style, as the get_conversations method has since been changed.
2187 $conversations = \core_message\helper::get_conversations_legacy_formatter($conversations);
2188
de55cb1b 2189 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
9aa012b5
MN
2190
2191 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 2192 return $conversations->export_for_template($renderer);
9aa012b5
MN
2193 }
2194
2195 /**
49aaadc3 2196 * The messagearea conversations return structure.
9aa012b5 2197 *
eb35e0b1 2198 * @deprecated since 3.6
49aaadc3
MN
2199 * @return external_single_structure
2200 * @since 3.2
9aa012b5
MN
2201 */
2202 public static function data_for_messagearea_conversations_returns() {
49aaadc3 2203 return new external_single_structure(
9aa012b5 2204 array(
9aa012b5 2205 'contacts' => new external_multiple_structure(
a3e3a3a1 2206 self::get_messagearea_contact_structure()
9aa012b5
MN
2207 )
2208 )
2209 );
2210 }
2211
eb35e0b1
JD
2212 /**
2213 * Marking the method as deprecated.
2214 *
2215 * @return bool
2216 */
2217 public static function data_for_messagearea_conversations_is_deprecated() {
2218 return true;
2219 }
2220
9aa012b5 2221 /**
49aaadc3 2222 * The messagearea contacts return parameters.
9aa012b5 2223 *
a6049a79 2224 * @deprecated since 3.6
9aa012b5 2225 * @return external_function_parameters
49aaadc3 2226 * @since 3.2
9aa012b5
MN
2227 */
2228 public static function data_for_messagearea_contacts_parameters() {
2229 return self::data_for_messagearea_conversations_parameters();
2230 }
2231
2232 /**
2233 * Get messagearea contacts parameters.
2234 *
a6049a79 2235 * @deprecated since 3.6
9aa012b5
MN
2236 * @param int $userid The id of the user who we are viewing conversations for
2237 * @param int $limitfrom
2238 * @param int $limitnum
49aaadc3
MN
2239 * @return stdClass
2240 * @throws moodle_exception
2241 * @since 3.2
9aa012b5
MN
2242 */
2243 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 2244 global $CFG, $PAGE, $USER;
9aa012b5
MN
2245
2246 // Check if messaging is enabled.
837941e9 2247 if (empty($CFG->messaging)) {
9aa012b5
MN
2248 throw new moodle_exception('disabled', 'message');
2249 }
2250
837941e9
MN
2251 $systemcontext = context_system::instance();
2252
9aa012b5
MN
2253 $params = array(
2254 'userid' => $userid,
2255 'limitfrom' => $limitfrom,
2256 'limitnum' => $limitnum
2257 );
bb650761 2258 $params = self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
837941e9 2259 self::validate_context($systemcontext);
9aa012b5 2260
bb650761 2261 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2262 throw new moodle_exception('You do not have permission to perform this action.');
2263 }
9aa012b5 2264
bb650761 2265 $contacts = \core_message\api::get_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
de55cb1b 2266 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
9aa012b5
MN
2267
2268 $renderer = $PAGE->get_renderer('core_message');
2269 return $contacts->export_for_template($renderer);
2270 }
2271
2272 /**
49aaadc3 2273 * The messagearea contacts return structure.
9aa012b5 2274 *
a6049a79 2275 * @deprecated since 3.6
49aaadc3
MN
2276 * @return external_single_structure
2277 * @since 3.2
9aa012b5
MN
2278 */
2279 public static function data_for_messagearea_contacts_returns() {
2280 return self::data_for_messagearea_conversations_returns();
2281 }
2282
a6049a79
MN
2283 /**
2284 * Marking the method as deprecated.
2285 *
2286 * @return bool
2287 */
2288 public static function data_for_messagearea_contacts_is_deprecated() {
2289 return true;
2290 }
2291
3cd13828 2292 /**
49aaadc3 2293 * The messagearea messages parameters.
3cd13828 2294 *
a6049a79 2295 * @deprecated since 3.6
3cd13828 2296 * @return external_function_parameters
49aaadc3 2297 * @since 3.2
3cd13828
MN
2298 */
2299 public static function data_for_messagearea_messages_parameters() {
2300 return new external_function_parameters(
2301 array(
2302 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2303 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2304 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
8ec78c48
MN
2305 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2306 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
ffd7798c 2307 'timefrom' => new external_value(PARAM_INT,
fb1469d8 2308 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
3cd13828
MN
2309 )
2310 );
2311 }
2312
2313 /**
2314 * Get messagearea messages.
2315 *
a6049a79 2316 * @deprecated since 3.6
3cd13828
MN
2317 * @param int $currentuserid The current user's id
2318 * @param int $otheruserid The other user's id
2319 * @param int $limitfrom
2320 * @param int $limitnum
8ec78c48 2321 * @param boolean $newest
49aaadc3
MN
2322 * @return stdClass
2323 * @throws moodle_exception
2324 * @since 3.2
3cd13828 2325 */
7b55aaa1 2326 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
ffd7798c 2327 $newest = false, $timefrom = 0) {
837941e9 2328 global $CFG, $PAGE, $USER;
3cd13828
MN
2329
2330 // Check if messaging is enabled.
837941e9 2331 if (empty($CFG->messaging)) {
3cd13828
MN
2332 throw new moodle_exception('disabled', 'message');
2333 }
2334
837941e9
MN
2335 $systemcontext = context_system::instance();
2336
3cd13828
MN
2337 $params = array(
2338 'currentuserid' => $currentuserid,
2339 'otheruserid' => $otheruserid,
2340 'limitfrom' => $limitfrom,
8ec78c48 2341 'limitnum' => $limitnum,
fb1469d8 2342 'newest' => $newest,
ffd7798c 2343 'timefrom' => $timefrom,
3cd13828 2344 );
bb650761 2345 $params = self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
837941e9 2346 self::validate_context($systemcontext);
3cd13828 2347
bb650761 2348 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2349 throw new moodle_exception('You do not have permission to perform this action.');
2350 }
3cd13828 2351
bb650761 2352 if ($params['newest']) {
8ec78c48
MN
2353 $sort = 'timecreated DESC';
2354 } else {
2355 $sort = 'timecreated ASC';
2356 }
fb1469d8
RW
2357
2358 // We need to enforce a one second delay on messages to avoid race conditions of current
2359 // messages still being sent.
2360 //
2361 // There is a chance that we could request messages before the current time's
2362 // second has elapsed and while other messages are being sent in that same second. In which
2363 // case those messages will be lost.
2364 //
2365 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
bb650761 2366 if (!empty($params['timefrom'])) {
ffd7798c 2367 $timeto = time() - 1;
fb1469d8 2368 } else {
ffd7798c 2369 $timeto = 0;
fb1469d8
RW
2370 }
2371
2372 // No requesting messages from the current time, as stated above.
bb650761 2373 if ($params['timefrom'] == time()) {
ffd7798c 2374 $messages = [];
fb1469d8 2375 } else {
bb650761
DW
2376 $messages = \core_message\api::get_messages($params['currentuserid'], $params['otheruserid'], $params['limitfrom'],
2377 $params['limitnum'], $sort, $params['timefrom'], $timeto);
fb1469d8
RW
2378 }
2379
bb650761 2380 $messages = new \core_message\output\messagearea\messages($params['currentuserid'], $params['otheruserid'], $messages);
3cd13828
MN
2381
2382 $renderer = $PAGE->get_renderer('core_message');
2383 return $messages->export_for_template($renderer);
2384 }
2385
2386 /**
49aaadc3 2387 * The messagearea messages return structure.
3cd13828 2388 *
a6049a79 2389 * @deprecated since 3.6
49aaadc3
MN
2390 * @return external_single_structure
2391 * @since 3.2
3cd13828
MN
2392 */
2393 public static function data_for_messagearea_messages_returns() {
49aaadc3 2394 return new external_single_structure(
3cd13828 2395 array(
7b55aaa1
MN
2396 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
2397 the messages on behalf of?'),
3cd13828
MN
2398 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2399 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2400 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
cb805753 2401 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
bf58081d 2402 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
3cd13828 2403 'messages' => new external_multiple_structure(
94e1db61 2404 self::get_messagearea_message_structure()
26dca05d
JP
2405 ),
2406 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
3cd13828
MN
2407 )
2408 );
2409 }
2410
a6049a79
MN
2411 /**
2412 * Marking the method as deprecated.
2413 *
2414 * @return bool
2415 */
2416 public static function data_for_messagearea_messages_is_deprecated() {
2417 return true;
2418 }
2419
fb04293b
SA
2420 /**
2421 * The conversation messages parameters.
2422 *
2423 * @return external_function_parameters
2424 * @since 3.6
2425 */
2426 public static function get_conversation_messages_parameters() {
2427 return new external_function_parameters(
2428 array(
2429 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2430 'convid' => new external_value(PARAM_INT, 'The conversation id'),
2431 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2432 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2433 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
2434 'timefrom' => new external_value(PARAM_INT,
2435 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
2436 )
2437 );
2438 }
2439
2440 /**
2441 * Get conversation messages.
2442 *
2443 * @param int $currentuserid The current user's id.
2444 * @param int $convid The conversation id.
2445 * @param int $limitfrom Return a subset of records, starting at this point (optional).
2446 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
2447 * @param bool $newest True for getting first newest messages, false otherwise.
2448 * @param int $timefrom The time from the conversation messages to get.
2449 * @return stdClass The messages and members who have sent some of these messages.
2450 * @throws moodle_exception
2451 * @since 3.6
2452 */
2453 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
2454 bool $newest = false, int $timefrom = 0) {
2455 global $CFG, $PAGE, $USER;
2456
2457 // Check if messaging is enabled.
2458 if (empty($CFG->messaging)) {
2459 throw new moodle_exception('disabled', 'message');
2460 }
2461
2462 $systemcontext = context_system::instance();
2463
2464 $params = array(
2465 'currentuserid' => $currentuserid,
2466 'convid' => $convid,
2467 'limitfrom' => $limitfrom,
2468 'limitnum' => $limitnum,
2469 'newest' => $newest,
2470 'timefrom' => $timefrom,
2471 );
bb650761 2472 $params = self::validate_parameters(self::get_conversation_messages_parameters(), $params);
fb04293b
SA
2473 self::validate_context($systemcontext);
2474
bb650761 2475 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
fb04293b
SA
2476 throw new moodle_exception('You do not have permission to perform this action.');
2477 }
2478
2479 $sort = $newest ? 'timecreated DESC' : 'timecreated ASC';
2480
2481 // We need to enforce a one second delay on messages to avoid race conditions of current
2482 // messages still being sent.
2483 //
2484 // There is a chance that we could request messages before the current time's
2485 // second has elapsed and while other messages are being sent in that same second. In which
2486 // case those messages will be lost.
2487 //
2488 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
bb650761 2489 $timeto = empty($params['timefrom']) ? 0 : time() - 1;
fb04293b
SA
2490
2491 // No requesting messages from the current time, as stated above.
bb650761 2492 if ($params['timefrom'] == time()) {
fb04293b
SA
2493 $messages = [];
2494 } else {
bb650761
DW
2495 $messages = \core_message\api::get_conversation_messages(
2496 $params['currentuserid'],
2497 $params['convid'],
2498 $params['limitfrom'],
2499 $params['limitnum'],
2500 $sort,
2501 $params['timefrom'],
2502 $timeto);
fb04293b
SA
2503 }
2504
2505 return $messages;
2506 }
2507
2508 /**
2509 * The messagearea messages return structure.
2510 *
2511 * @return external_single_structure
2512 * @since 3.6
2513 */
2514 public static function get_conversation_messages_returns() {
2515 return new external_single_structure(
2516 array(
2517 'id' => new external_value(PARAM_INT, 'The conversation id'),
2518 'members' => new external_multiple_structure(
2519 self::get_conversation_member_structure()
2520 ),
2521 'messages' => new external_multiple_structure(
2522 self::get_conversation_message_structure()
2523 ),
2524 )
2525 );
2526 }
2527
c9b0f33f
MN
2528 /**
2529 * The user contacts return parameters.
2530 *
2531 * @return external_function_parameters
2532 */
2533 public static function get_user_contacts_parameters() {
2534 return new external_function_parameters(
2535 array(
2536 'userid' => new external_value(PARAM_INT, 'The id of the user who we retrieving the contacts for'),
2537 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2538 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
2539 )
2540 );
2541 }
2542
2543 /**
2544 * Get user contacts.
2545 *
2546 * @param int $userid The id of the user who we are viewing conversations for
2547 * @param int $limitfrom
2548 * @param int $limitnum
2549 * @return array
2550 * @throws moodle_exception
2551 */
2552 public static function get_user_contacts(int $userid, int $limitfrom = 0, int $limitnum = 0) {
2553 global $CFG, $USER;
2554
2555 // Check if messaging is enabled.
2556 if (empty($CFG->messaging)) {
2557 throw new moodle_exception('disabled', 'message');
2558 }
2559
2560 $systemcontext = context_system::instance();
2561
2562 $params = array(
2563 'userid' => $userid,
2564 'limitfrom' => $limitfrom,
2565 'limitnum' => $limitnum
2566 );
2567 $params = self::validate_parameters(self::get_user_contacts_parameters(), $params);
2568 self::validate_context($systemcontext);
2569
2570 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2571 throw new moodle_exception('You do not have permission to perform this action.');
2572 }
2573
2574 return \core_message\api::get_user_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
2575 }
2576
2577 /**
2578 * The user contacts return structure.
2579 *
2580 * @return external_multiple_structure
2581 */
2582 public static function get_user_contacts_returns() {
2583 return new external_multiple_structure(
2584 self::get_conversation_member_structure()
2585 );
2586 }
2587
c060cd49 2588 /**
49aaadc3 2589 * The get most recent message return parameters.
c060cd49 2590 *
a6049a79 2591 * @deprecated since 3.6
c060cd49 2592 * @return external_function_parameters
49aaadc3 2593 * @since 3.2
c060cd49
MN
2594 */
2595 public static function data_for_messagearea_get_most_recent_message_parameters() {
2596 return new external_function_parameters(
2597 array(
2598 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2599 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2600 )
2601 );
2602 }
2603
2604 /**
2605 * Get the most recent message in a conversation.
2606 *
a6049a79 2607 * @deprecated since 3.6
c060cd49
MN
2608 * @param int $currentuserid The current user's id
2609 * @param int $otheruserid The other user's id
49aaadc3
MN
2610 * @return stdClass
2611 * @throws moodle_exception
2612 * @since 3.2
c060cd49
MN
2613 */
2614 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
837941e9 2615 global $CFG, $PAGE, $USER;
c060cd49
MN
2616
2617 // Check if messaging is enabled.
837941e9 2618 if (empty($CFG->messaging)) {
c060cd49
MN
2619 throw new moodle_exception('disabled', 'message');
2620 }
2621
837941e9
MN
2622 $systemcontext = context_system::instance();
2623
c060cd49
MN
2624 $params = array(
2625 'currentuserid' => $currentuserid,
2626 'otheruserid' => $otheruserid
2627 );
bb650761 2628 $params = self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
837941e9 2629 self::validate_context($systemcontext);
c060cd49 2630
bb650761 2631 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2632 throw new moodle_exception('You do not have permission to perform this action.');
2633 }
c060cd49 2634
bb650761 2635 $message = \core_message\api::get_most_recent_message($params['currentuserid'], $params['otheruserid']);
de55cb1b 2636 $message = new \core_message\output\messagearea\message($message);
c060cd49
MN
2637
2638 $renderer = $PAGE->get_renderer('core_message');
2639 return $message->export_for_template($renderer);
2640 }
2641
2642 /**
49aaadc3 2643 * The get most recent message return structure.
c060cd49 2644 *
a6049a79 2645 * @deprecated since 3.6
c060cd49 2646 * @return external_single_structure
49aaadc3 2647 * @since 3.2
c060cd49
MN
2648 */
2649 public static function data_for_messagearea_get_most_recent_message_returns() {
94e1db61 2650 return self::get_messagearea_message_structure();
c060cd49
MN
2651 }
2652
a6049a79
MN
2653 /**
2654 * Marking the method as deprecated.
2655 *
2656 * @return bool
2657 */
2658 public static function data_for_messagearea_get_most_recent_message_is_deprecated() {
2659 return true;
2660 }
2661
c6e97f54
MN
2662 /**
2663 * The get profile parameters.
2664 *
a6049a79 2665 * @deprecated since 3.6
c6e97f54 2666 * @return external_function_parameters
49aaadc3 2667 * @since 3.2
c6e97f54
MN
2668 */
2669 public static function data_for_messagearea_get_profile_parameters() {
2670 return new external_function_parameters(
2671 array(
2672 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2673 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
2674 )
2675 );
2676 }
2677
2678 /**
2679 * Get the profile information for a contact.
2680 *
a6049a79 2681 * @deprecated since 3.6
c6e97f54
MN
2682 * @param int $currentuserid The current user's id
2683 * @param int $otheruserid The id of the user whose profile we are viewing
49aaadc3
MN
2684 * @return stdClass
2685 * @throws moodle_exception
2686 * @since 3.2
c6e97f54
MN
2687 */
2688 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
837941e9 2689 global $CFG, $PAGE, $USER;
c6e97f54
MN
2690
2691 // Check if messaging is enabled.
837941e9 2692 if (empty($CFG->messaging)) {
c6e97f54
MN
2693 throw new moodle_exception('disabled', 'message');
2694 }
2695
837941e9
MN
2696 $systemcontext = context_system::instance();
2697
c6e97f54
MN
2698 $params = array(
2699 'currentuserid' => $currentuserid,
2700 'otheruserid' => $otheruserid
2701 );
bb650761 2702 $params = self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
837941e9 2703 self::validate_context($systemcontext);
c6e97f54 2704
bb650761 2705 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2706 throw new moodle_exception('You do not have permission to perform this action.');
2707 }
c6e97f54 2708
bb650761 2709 $profile = \core_message\api::get_profile($params['currentuserid'], $params['otheruserid']);
de55cb1b 2710 $profile = new \core_message\output\messagearea\profile($profile);
c6e97f54
MN
2711
2712 $renderer = $PAGE->get_renderer('core_message');
2713 return $profile->export_for_template($renderer);
2714 }
2715
2716 /**
49aaadc3 2717 * The get profile return structure.
c6e97f54 2718 *
a6049a79 2719 * @deprecated since 3.6
c6e97f54 2720 * @return external_single_structure
49aaadc3 2721 * @since 3.2
c6e97f54
MN
2722 */
2723 public static function data_for_messagearea_get_profile_returns() {
2724 return new external_single_structure(
2725 array(
de55cb1b 2726 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
c6e97f54 2727 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
cc22b515 2728 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
c6e97f54
MN
2729 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
2730 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
2731 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
2732 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
cb805753 2733 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
bf58081d 2734 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
c6e97f54
MN
2735 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
2736 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
2737 )
2738 );
2739 }
2740
a6049a79
MN
2741 /**
2742 * Marking the method as deprecated.
2743 *
2744 * @return bool
2745 */
2746 public static function data_for_messagearea_get_profile_is_deprecated() {
2747 return true;
2748 }
2749
d6731600
FM
2750 /**
2751 * Get contacts parameters description.
2752 *
f8905537 2753 * @deprecated since 3.6
d6731600 2754 * @return external_function_parameters
5bcfd504 2755 * @since Moodle 2.5
d6731600
FM
2756 */
2757 public static function get_contacts_parameters() {
2758 return new external_function_parameters(array());
2759 }
2760
2761 /**
2762 * Get contacts.
2763 *
f8905537 2764 * @deprecated since 3.6
d6731600 2765 * @return external_description
5bcfd504 2766 * @since Moodle 2.5
d6731600
FM
2767 */
2768 public static function get_contacts() {
883ce421 2769 global $CFG, $PAGE, $USER;
436bbf89
DM
2770
2771 // Check if messaging is enabled.
837941e9 2772 if (empty($CFG->messaging)) {
436bbf89
DM
2773 throw new moodle_exception('disabled', 'message');
2774 }
2775
d6731600
FM
2776 require_once($CFG->dirroot . '/user/lib.php');
2777
883ce421
MN
2778 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
2779 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id);
2780 foreach ($contacts as $contact) {
2781 // Set the mode.
2782 $mode = 'offline';
2783 if (\core_message\helper::is_online($contact->lastaccess)) {
2784 $mode = 'online';
2785 }
2786
2787 $newcontact = array(
2788 'id' => $contact->id,
2789 'fullname' => fullname($contact),
2790 'unread' => $contact->messagecount
2791 );
2792
2793 $userpicture = new user_picture($contact);
2794 $userpicture->size = 1; // Size f1.
2795 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2796 $userpicture->size = 0; // Size f2.
2797 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2798
2799 $allcontacts[$mode][$contact->id] = $newcontact;
2800 }
2801
2802 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id);
2803 foreach ($strangers as $contact) {
2804 $newcontact = array(
2805 'id' => $contact->id,
2806 'fullname' => fullname($contact),
2807 'unread' => $contact->messagecount
2808 );
2809
2810 $userpicture = new user_picture($contact);
2811 $userpicture->size = 1; // Size f1.
2812 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2813 $userpicture->size = 0; // Size f2.
2814 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600 2815
883ce421
MN
2816 $allcontacts['strangers'][$contact->id] = $newcontact;
2817 }
d6731600 2818
883ce421
MN
2819 // Add noreply user and support user to the list, if they don't exist.
2820 $supportuser = core_user::get_support_user();
2821 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) {
2822 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
2823 if ($supportuser->messagecount > 0) {
2824 $supportuser->fullname = fullname($supportuser);
2825 $supportuser->unread = $supportuser->messagecount;
2826 $allcontacts['strangers'][$supportuser->id] = $supportuser;
d6731600
FM
2827 }
2828 }
883ce421
MN
2829
2830 $noreplyuser = core_user::get_noreply_user();
2831 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) {
2832 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
2833 if ($noreplyuser->messagecount > 0) {
2834 $noreplyuser->fullname = fullname($noreplyuser);
2835 $noreplyuser->unread = $noreplyuser->messagecount;
2836 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser;
2837 }
2838 }
2839
d6731600
FM
2840 return $allcontacts;
2841 }
2842
2843 /**
2844 * Get contacts return description.
2845 *
f8905537 2846 * @deprecated since 3.6
d6731600 2847 * @return external_description
5bcfd504 2848 * @since Moodle 2.5
d6731600
FM
2849 */
2850 public static function get_contacts_returns() {
2851 return new external_single_structure(
2852 array(
2853 'online' => new external_multiple_structure(
2854 new external_single_structure(
2855 array(
2856 'id' => new external_value(PARAM_INT, 'User ID'),
2857 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2858 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2859 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2860 'unread' => new external_value(PARAM_INT, 'Unread message count')
2861 )
2862 ),
2863 'List of online contacts'
2864 ),
2865 'offline' => new external_multiple_structure(
2866 new external_single_structure(
2867 array(
2868 'id' => new external_value(PARAM_INT, 'User ID'),
2869 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2870 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2871 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2872 'unread' => new external_value(PARAM_INT, 'Unread message count')
2873 )
2874 ),
2875 'List of offline contacts'
2876 ),
2877 'strangers' => new external_multiple_structure(
2878 new external_single_structure(
2879 array(
2880 'id' => new external_value(PARAM_INT, 'User ID'),
2881 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2882 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2883 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2884 'unread' => new external_value(PARAM_INT, 'Unread message count')
2885 )
2886 ),
2887 'List of users that are not in the user\'s contact list but have sent a message'
2888 )
2889 )
2890 );
2891 }
2892
f8905537
MN
2893 /**
2894 * Marking the method as deprecated.
2895 *
2896 * @return bool
2897 */
2898 public static function get_contacts_is_deprecated() {
2899 return true;
2900 }
2901
d6731600
FM
2902 /**
2903 * Search contacts parameters description.
2904 *
2905 * @return external_function_parameters
5bcfd504 2906 * @since Moodle 2.5
d6731600
FM
2907 */
2908 public static function search_contacts_parameters() {
2909 return new external_function_parameters(
2910 array(
2911 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
2912 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
2913 VALUE_DEFAULT, false)
2914 )
2915 );
2916 }
2917
2918 /**
2919 * Search contacts.
2920 *
2921 * @param string $searchtext query string.
2922 * @param bool $onlymycourses limit the search to the user's courses only.
2923 * @return external_description
5bcfd504 2924 * @since Moodle 2.5
d6731600
FM
2925 */
2926 public static function search_contacts($searchtext, $onlymycourses = false) {
d85bedf7 2927 global $CFG, $USER, $PAGE;
11d83ab3 2928 require_once($CFG->dirroot . '/user/lib.php');
436bbf89
DM
2929
2930 // Check if messaging is enabled.
837941e9 2931 if (empty($CFG->messaging)) {
436bbf89
DM
2932 throw new moodle_exception('disabled', 'message');
2933 }
2934
d6731600
FM
2935 require_once($CFG->libdir . '/enrollib.php');
2936
2937 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
2938 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
2939
2940 // Extra validation, we do not allow empty queries.
2941 if ($params['searchtext'] === '') {
2942 throw new moodle_exception('querystringcannotbeempty');
2943 }
2944
2945 $courseids = array();
2946 if ($params['onlymycourses']) {
2947 $mycourses = enrol_get_my_courses(array('id'));
2948 foreach ($mycourses as $mycourse) {
2949 $courseids[] = $mycourse->id;
2950 }
2951 } else {
2952 $courseids[] = SITEID;
2953 }
2954
2955 // Retrieving the users matching the query.
2956 $users = message_search_users($courseids, $params['searchtext']);
2957 $results = array();
2958 foreach ($users as $user) {
2959 $results[$user->id] = $user;
2960 }
2961
2962 // Reorganising information.
2963 foreach ($results as &$user) {
2964 $newuser = array(
2965 'id' => $user->id,
2966 'fullname' => fullname($user)
2967 );
2968
2969 // Avoid undefined property notice as phone not specified.
2970 $user->phone1 = null;
2971 $user->phone2 = null;
2972
d85bedf7
JL
2973 $userpicture = new user_picture($user);
2974 $userpicture->size = 1; // Size f1.
2975 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2976 $userpicture->size = 0; // Size f2.
2977 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
2978
2979 $user = $newuser;
2980 }
2981
2982 return $results;
2983 }
2984
2985 /**
2986 * Search contacts return description.
2987 *
2988 * @return external_description
5bcfd504 2989 * @since Moodle 2.5
d6731600
FM
2990 */
2991 public static function search_contacts_returns() {
2992 return new external_multiple_structure(
2993 new external_single_structure(
2994 array(
2995 'id' => new external_value(PARAM_INT, 'User ID'),
2996 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2997 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2998 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
2999 )
3000 ),
3001 'List of contacts'
3002 );
3003 }
aff9da17
JL
3004
3005 /**
3006 * Get messages parameters description.
3007 *
3008 * @return external_function_parameters
193edf7f 3009 * @since 2.8
aff9da17
JL
3010 */
3011 public static function get_messages_parameters() {
3012 return new external_function_parameters(
3013 array(
6ff4464b 3014 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
127ef540
SH
3015 'useridfrom' => new external_value(
3016 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3017 VALUE_DEFAULT, 0),
3018 'type' => new external_value(
3019 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
3020 VALUE_DEFAULT, 'both'),
6ff4464b 3021 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
127ef540
SH
3022 'newestfirst' => new external_value(
3023 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
3024 VALUE_DEFAULT, true),
aff9da17 3025 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
127ef540
SH
3026 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
3027 )
aff9da17
JL
3028 );
3029 }
3030
3031 /**
3032 * Get messages function implementation.
127ef540
SH
3033 *
3034 * @since 2.8
3035 * @throws invalid_parameter_exception
3036 * @throws moodle_exception
6ff4464b
JL
3037 * @param int $useridto the user id who received the message
3038 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
193edf7f 3039 * @param string $type type of message to return, expected values: notifications, conversations and both
aff9da17 3040 * @param bool $read true for retreiving read messages, false for unread
6ff4464b 3041 * @param bool $newestfirst true for ordering by newest first, false for oldest first
aff9da17
JL
3042 * @param int $limitfrom limit from
3043 * @param int $limitnum limit num
3044 * @return external_description
aff9da17 3045 */
193edf7f 3046 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
aff9da17 3047 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
127ef540 3048 global $CFG, $USER;
aff9da17
JL
3049
3050 $warnings = array();
3051
3052 $params = array(
3053 'useridto' => $useridto,
6ff4464b 3054 'useridfrom' => $useridfrom,
aff9da17
JL
3055 'type' => $type,
3056 'read' => $read,
aff9da17
JL
3057 'newestfirst' => $newestfirst,
3058 'limitfrom' => $limitfrom,
3059 'limitnum' => $limitnum
3060 );
3061
3062 $params = self::validate_parameters(self::get_messages_parameters(), $params);
3063
3064 $context = context_system::instance();
3065 self::validate_context($context);
3066
3067 $useridto = $params['useridto'];
6ff4464b 3068 $useridfrom = $params['useridfrom'];
aff9da17
JL
3069 $type = $params['type'];
3070 $read = $params['read'];
aff9da17
JL
3071 $newestfirst = $params['newestfirst'];
3072 $limitfrom = $params['limitfrom'];
3073 $limitnum = $params['limitnum'];
3074
3075 $allowedvalues = array('notifications', 'conversations', 'both');
3076 if (!in_array($type, $allowedvalues)) {
3077 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
3078 'allowed values are: ' . implode(',', $allowedvalues));
3079 }
3080
3081 // Check if private messaging between users is allowed.
3082 if (empty($CFG->messaging)) {
3083 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
aff9da17
JL
3084 if ($type == "conversations") {
3085 throw new moodle_exception('disabled', 'message');
3086 }
3087 if ($type == "both") {
3088 $warning = array();
3089 $warning['item'] = 'message';
3090 $warning['itemid'] = $USER->id;
3091 $warning['warningcode'] = '1';
3092 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
3093 Only notifications will be returned';
3094 $warnings[] = $warning;
3095 }
3096 }
3097
3098 if (!empty($useridto)) {
6ff4464b
JL
3099 if (core_user::is_real_user($useridto)) {
3100 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3101 } else {
3102 throw new moodle_exception('invaliduser');
3103 }
aff9da17
JL
3104 }
3105
3106 if (!empty($useridfrom)) {
3107 // We use get_user here because the from user can be the noreply or support user.
3108 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3109 }
3110
3111 // Check if the current user is the sender/receiver or just a privileged user.
3112 if ($useridto != $USER->id and $useridfrom != $USER->id and
3113 !has_capability('moodle/site:readallmessages', $context)) {
3114 throw new moodle_exception('accessdenied', 'admin');
3115 }
3116
127ef540 3117 // Which type of messages to retrieve.
193edf7f 3118 $notifications = -1;
aff9da17 3119 if ($type != 'both') {
193edf7f 3120 $notifications = ($type == 'notifications') ? 1 : 0;
aff9da17
JL
3121 }
3122
aff9da17 3123 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
193edf7f 3124 $sort = "mr.timecreated $orderdirection";
aff9da17 3125
193edf7f 3126 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
aff9da17
JL
3127 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
3128
3129 // In some cases, we don't need to get the to/from user objects from the sql query.
3130 $userfromfullname = '';
3131 $usertofullname = '';
3132
3133 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
3134 if (!empty($useridto)) {
3135 $usertofullname = fullname($userto, $canviewfullname);
3136 // The user from may or may not be filled.
3137 if (!empty($useridfrom)) {
3138 $userfromfullname = fullname($userfrom, $canviewfullname);
3139 }
3140 } else {
3141 // If the useridto field is empty, the useridfrom must be filled.
3142 $userfromfullname = fullname($userfrom, $canviewfullname);
3143 }
aff9da17
JL
3144 foreach ($messages as $mid => $message) {
3145
ea21d637 3146 // Do not return deleted messages.
883ce421
MN
3147 if (!$message->notification) {
3148 if (($useridto == $USER->id and $message->timeusertodeleted) or
ea21d637 3149 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
883ce421
MN
3150 unset($messages[$mid]);
3151 continue;
3152 }
ea21d637
JL
3153 }
3154
aff9da17
JL
3155 // We need to get the user from the query.
3156 if (empty($userfromfullname)) {
6ff4464b
JL
3157 // Check for non-reply and support users.
3158 if (core_user::is_real_user($message->useridfrom)) {
127ef540 3159 $user = new stdClass();
6ff4464b
JL
3160 $user = username_load_fields_from_object($user, $message, 'userfrom');
3161 $message->userfromfullname = fullname($user, $canviewfullname);
3162 } else {
3163 $user = core_user::get_user($message->useridfrom);
3164 $message->userfromfullname = fullname($user, $canviewfullname);
3165 }
aff9da17
JL
3166 } else {
3167 $message->userfromfullname = $userfromfullname;
3168 }
3169
3170 // We need to get the user from the query.
3171 if (empty($usertofullname)) {
127ef540 3172 $user = new stdClass();
aff9da17
JL
3173 $user = username_load_fields_from_object($user, $message, 'userto');
3174 $message->usertofullname = fullname($user, $canviewfullname);
3175 } else {
3176 $message->usertofullname = $usertofullname;
3177 }
3178
aff9da17 3179 $message->text = message_format_message_text($message);
aff9da17
JL
3180 $messages[$mid] = (array) $message;
3181 }
3182 }
3183
3184 $results = array(
3185 'messages' => $messages,
3186 'warnings' => $warnings
3187 );
3188
3189 return $results;
3190 }
3191
3192 /**
3193 * Get messages return description.
3194 *
6ff4464b 3195 * @return external_single_structure
193edf7f 3196 * @since 2.8
aff9da17
JL
3197 */
3198 public static function get_messages_returns() {
3199 return new external_single_structure(
3200 array(
3201 'messages' => new external_multiple_structure(
3202 new external_single_structure(
3203 array(
193edf7f 3204 'id' => new external_value(PARAM_INT, 'Message id'),
aff9da17
JL
3205 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
3206 'useridto' => new external_value(PARAM_INT, 'User to id'),
3207 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
3208 'text' => new external_value(PARAM_RAW, 'The message text formated'),
3209 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
193edf7f 3210 'fullmessageformat' => new external_format_value('fullmessage'),
aff9da17
JL
3211 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
3212 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
3213 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
3214 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
3215 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
3216 'timecreated' => new external_value(PARAM_INT, 'Time created'),
3217 'timeread' => new external_value(PARAM_INT, 'Time read'),
3218 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
333d11c9
JL
3219 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name'),
3220 'component' => new external_value(PARAM_TEXT, 'The component that generated the notification',
3221 VALUE_OPTIONAL),
3222 'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL),
3223 'customdata' => new external_value(PARAM_RAW, 'Custom data to be passed to the message processor.
3224 The data here is serialised using json_encode().', VALUE_OPTIONAL),
aff9da17
JL
3225 ), 'message'
3226 )
3227 ),
3228 'warnings' => new external_warnings()
3229 )
3230 );
3274d5ca
RW
3231 }
3232
3274d5ca
RW
3233 /**
3234 * Mark all notifications as read parameters description.
3235 *
3236 * @return external_function_parameters
3237 * @since 3.2
3238 */
3239 public static function mark_all_notifications_as_read_parameters() {
3240 return new external_function_parameters(
3241 array(
3242 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3243 'useridfrom' => new external_value(
3244 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3245 VALUE_DEFAULT, 0),
3246 )
3247 );
3248 }
3249
3250 /**
3251 * Mark all notifications as read function.
3252 *
3253 * @since 3.2
3254 * @throws invalid_parameter_exception
3255 * @throws moodle_exception
3256 * @param int $useridto the user id who received the message
3257 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3258 * @return external_description
3259 */
3260 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
837941e9 3261 global $USER;
3274d5ca
RW
3262
3263 $params = self::validate_parameters(
3264 self::mark_all_notifications_as_read_parameters(),
3265 array(
3266 'useridto' => $useridto,
3267 'useridfrom' => $useridfrom,
3268 )
3269 );
3270
3271 $context = context_system::instance();
3272 self::validate_context($context);
3273
3274 $useridto = $params['useridto'];
3275 $useridfrom = $params['useridfrom'];
3276
3277 if (!empty($useridto)) {
3278 if (core_user::is_real_user($useridto)) {
3279 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3280 } else {
3281 throw new moodle_exception('invaliduser');
3282 }
3283 }
3284
3285 if (!empty($useridfrom)) {
3286 // We use get_user here because the from user can be the noreply or support user.
3287 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3288 }
3289
3290 // Check if the current user is the sender/receiver or just a privileged user.
3291 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 3292 // The deleteanymessage cap seems more reasonable here than readallmessages.
3274d5ca
RW
3293 !has_capability('moodle/site:deleteanymessage', $context)) {
3294 throw new moodle_exception('accessdenied', 'admin');
3295 }
3296
74ad60bf 3297 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom);
3274d5ca
RW
3298
3299 return true;
3300 }
3301
3302 /**
3303 * Mark all notifications as read return description.
3304 *
3305 * @return external_single_structure
3306 * @since 3.2
3307 */
3308 public static function mark_all_notifications_as_read_returns() {
3309 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
3310 }
3311
8c55bd6c
RW
3312 /**
3313 * Get unread conversations count parameters description.
3314 *
3315 * @return external_function_parameters
3316 * @since 3.2
3317 */
3318 public static function get_unread_conversations_count_parameters() {
3319 return new external_function_parameters(
3320 array(
3321 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3322 )
3323 );
3324 }
3325
3326 /**
3327 * Get unread messages count function.
3328 *
3329 * @since 3.2
3330 * @throws invalid_parameter_exception
3331 * @throws moodle_exception
3332 * @param int $useridto the user id who received the message
3333 * @return external_description
3334 */
3335 public static function get_unread_conversations_count($useridto) {
a2c7227a
SL
3336 global $USER, $CFG;
3337
3338 // Check if messaging is enabled.
3339 if (empty($CFG->messaging)) {
3340 throw new moodle_exception('disabled', 'message');
3341 }
8c55bd6c
RW
3342
3343 $params = self::validate_parameters(
3344 self::get_unread_conversations_count_parameters(),
3345 array('useridto' => $useridto)
3346 );
3347
3348 $context = context_system::instance();
3349 self::validate_context($context);
3350
3351 $useridto = $params['useridto'];
3352
3353 if (!empty($useridto)) {
3354 if (core_user::is_real_user($useridto)) {
3355 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3356 } else {
3357 throw new moodle_exception('invaliduser');
3358 }
3359 } else {
3360 $useridto = $USER->id;
3361 }
3362
3363 // Check if the current user is the receiver or just a privileged user.
3364 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
3365 throw new moodle_exception('accessdenied', 'admin');
3366 }
3367
79f6c36c 3368 return \core_message\api::count_unread_conversations($userto);
8c55bd6c
RW
3369 }
3370
3371 /**
3372 * Get unread conversations count return description.
3373 *
3374 * @return external_single_structure
3375 * @since 3.2
3376 */
3377 public static function get_unread_conversations_count_returns() {
3378 return new external_value(PARAM_INT, 'The count of unread messages for the user');
aff9da17
JL
3379 }
3380
60ab2e1b
JL
3381 /**
3382 * Get blocked users parameters description.
3383 *
3384 * @return external_function_parameters
3385 * @since 2.9
3386 */
3387 public static function get_blocked_users_parameters() {
3388 return new external_function_parameters(
3389 array(
3390 'userid' => new external_value(PARAM_INT,
3391 'the user whose blocked users we want to retrieve',
3392 VALUE_REQUIRED),
3393 )
3394 );
3395 }
3396
3397 /**
3398 * Retrieve a list of users blocked
3399 *
3400 * @param int $userid the user whose blocked users we want to retrieve
3401 * @return external_description
3402 * @since 2.9
3403 */
3404 public static function get_blocked_users($userid) {
d85bedf7 3405 global $CFG, $USER, $PAGE;
60ab2e1b
JL
3406
3407 // Warnings array, it can be empty at the end but is mandatory.
3408 $warnings = array();
3409
3410 // Validate params.
3411 $params = array(
3412 'userid' => $userid
3413 );
3414 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
3415 $userid = $params['userid'];
3416
3417 // Validate context.
3418 $context = context_system::instance();
3419 self::validate_context($context);
3420
3421 // Check if private messaging between users is allowed.
3422 if (empty($CFG->messaging)) {
3423 throw new moodle_exception('disabled', 'message');
3424 }
3425
4485f7c5
JL
3426 $user = core_user::get_user($userid, '*', MUST_EXIST);
3427 core_user::require_active_user($user);
60ab2e1b
JL
3428
3429 // Check if we have permissions for retrieve the information.
343ba16c
SL
3430 $capability = 'moodle/site:manageallmessaging';
3431 if (($USER->id != $userid) && !has_capability($capability, $context)) {
3432 throw new required_capability_exception($context, $capability, 'nopermissions', '');
60ab2e1b
JL
3433 }
3434
3435 // Now, we can get safely all the blocked users.
883ce421 3436 $users = \core_message\api::get_blocked_users($user->id);
60ab2e1b
JL
3437
3438 $blockedusers = array();
3439 foreach ($users as $user) {
3440 $newuser = array(
3441 'id' => $user->id,
3442 'fullname' => fullname($user),
3443 );
0b074e88 3444
d85bedf7
JL
3445 $userpicture