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