MDL-63303 message: add get_conversation to message api
[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 */
1053 private static function get_conversation_structure() {
1054 return new external_single_structure(
1055 array(
1056 'id' => new external_value(PARAM_INT, 'The conversation id'),
1057 'name' => new external_value(PARAM_NOTAGS, 'The conversation name, if set', VALUE_DEFAULT, null),
1058 'subname' => new external_value(PARAM_NOTAGS, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null),
003cdcce 1059 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null),
6f31927a
JD
1060 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group)'),
1061 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'),
1062 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked conversation this conversation as a favourite'),
1063 'isread' => new external_value(PARAM_BOOL, 'If the user has read all messages in the conversation'),
1064 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1065 VALUE_DEFAULT, null),
1066 'members' => new external_multiple_structure(
cef1d977 1067 self::get_conversation_member_structure(true)
6f31927a
JD
1068 ),
1069 'messages' => new external_multiple_structure(
1070 self::get_conversation_message_structure()
1071 ),
1072 )
1073 );
1074 }
1075
fb04293b
SA
1076 /**
1077 * Return the structure of a conversation member.
1078 *
5584c48a 1079 * @param bool $includecontactrequests Are we including contact requests?
548cac7d 1080 * @param bool $includeconversations Are we including conversations?
fb04293b
SA
1081 * @return external_single_structure
1082 * @since Moodle 3.6
1083 */
548cac7d
AA
1084 private static function get_conversation_member_structure(bool $includecontactrequests = false,
1085 bool $includeconversations = false) {
5584c48a
MN
1086 $result = [
1087 'id' => new external_value(PARAM_INT, 'The user id'),
1088 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1089 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1090 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1091 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1092 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1093 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
1094 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?'),
d15c1e77 1095 'isdeleted' => new external_value(PARAM_BOOL, 'Is the user deleted?'),
cef1d977
MN
1096 'canmessage' => new external_value(PARAM_BOOL, 'If the user can be messaged'),
1097 'requirescontact' => new external_value(PARAM_BOOL, 'If the user requires to be contacts'),
5584c48a
MN
1098 ];
1099
1100 if ($includecontactrequests) {
1101 $result['contactrequests'] = new external_multiple_structure(
1102 new external_single_structure(
1103 [
1104 'id' => new external_value(PARAM_INT, 'The id of the message'),
1105 'userid' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1106 'requesteduserid' => new external_value(PARAM_RAW, 'The text of the message'),
1107 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1108 ]
1109 ), 'The contact requests', VALUE_OPTIONAL
1110 );
1111 }
1112
548cac7d
AA
1113 if ($includeconversations) {
1114 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1115 array(
1116 'id' => new external_value(PARAM_INT, 'Conversations id'),
1117 'type' => new external_value(PARAM_INT, 'Conversation type: private or public'),
1118 'name' => new external_value(PARAM_TEXT, 'Multilang compatible conversation name'. VALUE_OPTIONAL),
1119 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the conversation'),
1120 ), 'information about conversation', VALUE_OPTIONAL),
1121 'Conversations between users', VALUE_OPTIONAL
1122 );
1123 }
1124
fb04293b 1125 return new external_single_structure(
5584c48a 1126 $result
fb04293b
SA
1127 );
1128 }
1129
1130 /**
1131 * Return the structure of a message area message.
1132 *
1133 * @return external_single_structure
1134 * @since Moodle 3.6
1135 */
1136 private static function get_conversation_message_structure() {
1137 return new external_single_structure(
1138 array(
1139 'id' => new external_value(PARAM_INT, 'The id of the message'),
1140 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1141 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1142 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1143 )
1144 );
1145 }
1146
94e1db61
MN
1147 /**
1148 * Return the structure of a message area message.
1149 *
1150 * @return external_single_structure
1151 * @since Moodle 3.2
1152 */
1153 private static function get_messagearea_message_structure() {
1154 return new external_single_structure(
1155 array(
1156 'id' => new external_value(PARAM_INT, 'The id of the message'),
89a70ba1
MN
1157 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1158 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
94e1db61
MN
1159 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1160 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
1161 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
1162 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
1163 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
fb1469d8 1164 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
94e1db61
MN
1165 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
1166 )
1167 );
1168 }
1169
cd03b8d7 1170 /**
48e8bdba 1171 * Get messagearea search users in course parameters.
cd03b8d7 1172 *
548cac7d
AA
1173 * @deprecated since 3.6
1174 *
cd03b8d7
MN
1175 * @return external_function_parameters
1176 * @since 3.2
1177 */
48e8bdba 1178 public static function data_for_messagearea_search_users_in_course_parameters() {
cd03b8d7
MN
1179 return new external_function_parameters(
1180 array(
1181 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1182 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
1183 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1184 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1185 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1186 )
1187 );
1188 }
1189
1190 /**
48e8bdba 1191 * Get messagearea search users in course results.
cd03b8d7 1192 *
548cac7d
AA
1193 * @deprecated since 3.6
1194 *
1195 * NOTE: We are deprecating this function but not search_users_in_course API function for backwards compatibility
1196 * with messaging UI. But should be removed once new group messaging UI is in place and old messaging UI is removed.
1197 * Followup: MDL-63915
1198 *
cd03b8d7
MN
1199 * @param int $userid The id of the user who is performing the search
1200 * @param int $courseid The id of the course
1201 * @param string $search The string being searched
1202 * @param int $limitfrom
1203 * @param int $limitnum
1204 * @return stdClass
1205 * @throws moodle_exception
1206 * @since 3.2
1207 */
48e8bdba 1208 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
de55cb1b 1209 $limitnum = 0) {
837941e9 1210 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1211
1212 // Check if messaging is enabled.
837941e9 1213 if (empty($CFG->messaging)) {
cd03b8d7
MN
1214 throw new moodle_exception('disabled', 'message');
1215 }
1216
837941e9
MN
1217 $systemcontext = context_system::instance();
1218
cd03b8d7
MN
1219 $params = array(
1220 'userid' => $userid,
1221 'courseid' => $courseid,
1222 'search' => $search,
1223 'limitfrom' => $limitfrom,
1224 'limitnum' => $limitnum
1225 );
bb650761 1226 $params = self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
837941e9 1227 self::validate_context($systemcontext);
cd03b8d7 1228
bb650761 1229 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1230 throw new moodle_exception('You do not have permission to perform this action.');
1231 }
cd03b8d7 1232
bb650761
DW
1233 $users = \core_message\api::search_users_in_course(
1234 $params['userid'],
1235 $params['courseid'],
1236 $params['search'],
1237 $params['limitfrom'],
1238 $params['limitnum']
1239 );
de55cb1b 1240 $results = new \core_message\output\messagearea\user_search_results($users);
cd03b8d7
MN
1241
1242 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 1243 return $results->export_for_template($renderer);
cd03b8d7
MN
1244 }
1245
1246 /**
48e8bdba 1247 * Get messagearea search users in course returns.
cd03b8d7 1248 *
548cac7d
AA
1249 * @deprecated since 3.6
1250 *
cd03b8d7
MN
1251 * @return external_single_structure
1252 * @since 3.2
1253 */
48e8bdba 1254 public static function data_for_messagearea_search_users_in_course_returns() {
cd03b8d7
MN
1255 return new external_single_structure(
1256 array(
cd03b8d7 1257 'contacts' => new external_multiple_structure(
a3e3a3a1 1258 self::get_messagearea_contact_structure()
cd03b8d7
MN
1259 ),
1260 )
1261 );
1262 }
1263
548cac7d
AA
1264 /**
1265 * Marking the method as deprecated.
1266 *
1267 * @return bool
1268 */
1269 public static function data_for_messagearea_search_users_in_course_is_deprecated() {
1270 return true;
1271 }
1272
cd03b8d7 1273 /**
48e8bdba 1274 * Get messagearea search users parameters.
cd03b8d7 1275 *
548cac7d
AA
1276 * @deprecated since 3.6
1277 *
cd03b8d7
MN
1278 * @return external_function_parameters
1279 * @since 3.2
1280 */
48e8bdba 1281 public static function data_for_messagearea_search_users_parameters() {
cd03b8d7
MN
1282 return new external_function_parameters(
1283 array(
1284 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1285 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1286 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1287 )
1288 );
1289 }
1290
1291 /**
48e8bdba 1292 * Get messagearea search users results.
cd03b8d7 1293 *
548cac7d
AA
1294 * @deprecated since 3.6
1295 *
1296 * NOTE: We are deprecating this function but not search_users API function for backwards compatibility
1297 * with messaging UI. But should be removed once new group messaging UI is in place and old messaging UI is removed.
1298 * Followup: MDL-63915
1299 *
cd03b8d7
MN
1300 * @param int $userid The id of the user who is performing the search
1301 * @param string $search The string being searched
1302 * @param int $limitnum
1303 * @return stdClass
1304 * @throws moodle_exception
1305 * @since 3.2
1306 */
48e8bdba 1307 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
837941e9 1308 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1309
1310 // Check if messaging is enabled.
837941e9 1311 if (empty($CFG->messaging)) {
cd03b8d7
MN
1312 throw new moodle_exception('disabled', 'message');
1313 }
1314
837941e9
MN
1315 $systemcontext = context_system::instance();
1316
cd03b8d7
MN
1317 $params = array(
1318 'userid' => $userid,
1319 'search' => $search,
1320 'limitnum' => $limitnum
1321 );
bb650761 1322 $params = self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
837941e9 1323 self::validate_context($systemcontext);
cd03b8d7 1324
bb650761 1325 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1326 throw new moodle_exception('You do not have permission to perform this action.');
1327 }
cd03b8d7 1328
bb650761
DW
1329 list($contacts, $courses, $noncontacts) = \core_message\api::search_users(
1330 $params['userid'],
1331 $params['search'],
1332 $params['limitnum']
1333 );
1334
de55cb1b 1335 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
cd03b8d7
MN
1336
1337 $renderer = $PAGE->get_renderer('core_message');
1338 return $search->export_for_template($renderer);
1339 }
1340
1341 /**
48e8bdba 1342 * Get messagearea search users returns.
cd03b8d7 1343 *
548cac7d
AA
1344 * @deprecated since 3.6
1345 *
cd03b8d7
MN
1346 * @return external_single_structure
1347 * @since 3.2
1348 */
48e8bdba 1349 public static function data_for_messagearea_search_users_returns() {
cd03b8d7
MN
1350 return new external_single_structure(
1351 array(
cd03b8d7 1352 'contacts' => new external_multiple_structure(
a3e3a3a1 1353 self::get_messagearea_contact_structure()
cd03b8d7 1354 ),
cd03b8d7
MN
1355 'courses' => new external_multiple_structure(
1356 new external_single_structure(
1357 array(
1358 'id' => new external_value(PARAM_INT, 'The course id'),
7597ab0b
AA
1359 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
1360 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
cd03b8d7
MN
1361 )
1362 )
1363 ),
cd03b8d7 1364 'noncontacts' => new external_multiple_structure(
a3e3a3a1 1365 self::get_messagearea_contact_structure()
cd03b8d7
MN
1366 )
1367 )
1368 );
1369 }
1370
548cac7d
AA
1371 /**
1372 * Marking the method as deprecated.
1373 *
1374 * @return bool
1375 */
1376 public static function data_for_messagearea_search_users_is_deprecated() {
1377 return true;
1378 }
1379
1380 /**
1381 * Get messagearea message search users parameters.
1382 *
1383 * @return external_function_parameters
1384 * @since 3.6
1385 */
1386 public static function message_search_users_parameters() {
1387 return new external_function_parameters(
1388 array(
1389 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1390 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1391 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1392 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1393 )
1394 );
1395 }
1396
1397 /**
1398 * Get search users results.
1399 *
1400 * @param int $userid The id of the user who is performing the search
1401 * @param string $search The string being searched
1402 * @param int $limitfrom
1403 * @param int $limitnum
1404 * @return array
1405 * @throws moodle_exception
1406 * @since 3.6
1407 */
1408 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
41485be2 1409 global $USER;
548cac7d
AA
1410
1411 $systemcontext = context_system::instance();
1412
1413 $params = array(
1414 'userid' => $userid,
1415 'search' => $search,
1416 'limitfrom' => $limitfrom,
1417 'limitnum' => $limitnum
1418 );
1419 $params = self::validate_parameters(self::message_search_users_parameters(), $params);
1420 self::validate_context($systemcontext);
1421
1422 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1423 throw new moodle_exception('You do not have permission to perform this action.');
1424 }
1425
1426 list($contacts, $noncontacts) = \core_message\api::message_search_users(
1427 $params['userid'],
1428 $params['search'],
1429 $params['limitfrom'],
1430 $params['limitnum']);
1431
1432 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1433 }
1434
1435 /**
1436 * Get messagearea message search users returns.
1437 *
1438 * @return external_single_structure
1439 * @since 3.2
1440 */
1441 public static function message_search_users_returns() {
1442 return new external_single_structure(
1443 array(
1444 'contacts' => new external_multiple_structure(
1445 self::get_conversation_member_structure(false, true)
1446 ),
1447 'noncontacts' => new external_multiple_structure(
1448 self::get_conversation_member_structure(false, true)
1449 )
1450 )
1451 );
1452 }
1453
cd03b8d7
MN
1454 /**
1455 * Get messagearea search messages parameters.
1456 *
1457 * @return external_function_parameters
1458 * @since 3.2
1459 */
1460 public static function data_for_messagearea_search_messages_parameters() {
1461 return new external_function_parameters(
1462 array(
1463 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1464 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1465 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1466 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1467 )
1468 );
1469 }
1470
1471 /**
1472 * Get messagearea search messages results.
1473 *
1474 * @param int $userid The id of the user who is performing the search
1475 * @param string $search The string being searched
1476 * @param int $limitfrom
1477 * @param int $limitnum
1478 * @return stdClass
1479 * @throws moodle_exception
1480 * @since 3.2
1481 */
1482 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
837941e9 1483 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1484
1485 // Check if messaging is enabled.
837941e9 1486 if (empty($CFG->messaging)) {
cd03b8d7
MN
1487 throw new moodle_exception('disabled', 'message');
1488 }
1489
837941e9
MN
1490 $systemcontext = context_system::instance();
1491
cd03b8d7
MN
1492 $params = array(
1493 'userid' => $userid,
1494 'search' => $search,
1495 'limitfrom' => $limitfrom,
1496 'limitnum' => $limitnum
1497
1498 );
bb650761 1499 $params = self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
837941e9 1500 self::validate_context($systemcontext);
cd03b8d7 1501
bb650761 1502 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1503 throw new moodle_exception('You do not have permission to perform this action.');
1504 }
cd03b8d7 1505
bb650761
DW
1506 $messages = \core_message\api::search_messages(
1507 $params['userid'],
1508 $params['search'],
1509 $params['limitfrom'],
1510 $params['limitnum']
1511 );
de55cb1b 1512 $results = new \core_message\output\messagearea\message_search_results($messages);
cd03b8d7
MN
1513
1514 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 1515 return $results->export_for_template($renderer);
cd03b8d7
MN
1516 }
1517
1518 /**
1519 * Get messagearea search messages returns.
1520 *
1521 * @return external_single_structure
1522 * @since 3.2
1523 */
1524 public static function data_for_messagearea_search_messages_returns() {
1525 return new external_single_structure(
1526 array(
cd03b8d7 1527 'contacts' => new external_multiple_structure(
a3e3a3a1 1528 self::get_messagearea_contact_structure()
cd03b8d7
MN
1529 )
1530 )
1531 );
1532 }
1533
6f31927a
JD
1534 /**
1535 * Get conversations parameters.
1536 *
1537 * @return external_function_parameters
1538 * @since 3.6
1539 */
1540 public static function get_conversations_parameters() {
1541 return new external_function_parameters(
1542 array(
1543 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1544 'limitfrom' => new external_value(PARAM_INT, 'The offset to start at', VALUE_DEFAULT, 0),
1545 'limitnum' => new external_value(PARAM_INT, 'Limit number of conversations to this', VALUE_DEFAULT, 0),
1546 'type' => new external_value(PARAM_INT, 'Filter by type', VALUE_DEFAULT, null),
1547 'favourites' => new external_value(PARAM_BOOL, 'Whether to restrict the results to contain NO favourite
1548 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1549 VALUE_DEFAULT, null),
1550
1551 )
1552 );
1553 }
1554
1555 /**
1556 * Get the list of conversations for the user.
1557 *
1558 * @param int $userid The id of the user who is performing the search
1559 * @param int $limitfrom
1560 * @param int $limitnum
1561 * @param int|null $type
1562 * @param bool|null $favourites
1563 * @return stdClass
1564 * @throws \moodle_exception if the messaging feature is disabled on the site.
1565 * @since 3.2
1566 */
1567 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null) {
1568 global $CFG, $USER;
1569
1570 // All the standard BL checks.
1571 if (empty($CFG->messaging)) {
1572 throw new moodle_exception('disabled', 'message');
1573 }
1574
1575 $params = array(
1576 'userid' => $userid,
1577 'limitfrom' => $limitfrom,
1578 'limitnum' => $limitnum,
1579 'type' => $type,
1580 'favourites' => $favourites
1581 );
bb650761 1582 $params = self::validate_parameters(self::get_conversations_parameters(), $params);
6f31927a
JD
1583
1584 $systemcontext = context_system::instance();
1585 self::validate_context($systemcontext);
1586
bb650761 1587 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
6f31927a
JD
1588 throw new moodle_exception('You do not have permission to perform this action.');
1589 }
1590
bb650761
DW
1591 $conversations = \core_message\api::get_conversations(
1592 $params['userid'],
1593 $params['limitfrom'],
1594 $params['limitnum'],
1595 $params['type'],
1596 $params['favourites']
1597 );
1598
6f31927a
JD
1599 return (object) ['conversations' => $conversations];
1600 }
1601
1602 /**
1603 * Get conversations returns.
1604 *
1605 * @return external_single_structure
1606 * @since 3.6
1607 */
1608 public static function get_conversations_returns() {
1609 return new external_single_structure(
1610 [
1611 'conversations' => new external_multiple_structure(
1612 self::get_conversation_structure()
1613 )
1614 ]
1615 );
1616 }
1617
4e313026
RW
1618 /**
1619 * Get conversation parameters.
1620 *
1621 * @return external_function_parameters
1622 */
1623 public static function get_conversation_parameters() {
1624 return new external_function_parameters(
1625 array(
1626 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1627 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation to fetch'),
1628 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1629 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1630 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1631 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1632 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1633 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1634 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1635 )
1636 );
1637 }
1638
1639 /**
1640 * Get a single conversation.
1641 *
1642 * @param int $userid The user id to get the conversation for
1643 * @param int $conversationid The id of the conversation to fetch
1644 * @param bool $includecontactrequests Should contact requests be included between members
1645 * @param bool $includeprivacyinfo Should privacy info be included between members
1646 * @param int $memberlimit Limit number of members to load
1647 * @param int $memberoffset Offset members by this amount
1648 * @param int $messagelimit Limit number of messages to load
1649 * @param int $messageoffset Offset the messages
1650 * @param bool $newestmessagesfirst Order messages by newest first
1651 * @return stdClass
1652 * @throws \moodle_exception if the messaging feature is disabled on the site.
1653 */
1654 public static function get_conversation(
1655 int $userid,
1656 int $conversationid,
1657 bool $includecontactrequests = false,
1658 bool $includeprivacyinfo = false,
1659 int $memberlimit = 0,
1660 int $memberoffset = 0,
1661 int $messagelimit = 0,
1662 int $messageoffset = 0,
1663 bool $newestmessagesfirst = true
1664 ) {
1665 global $CFG, $DB, $USER;
1666
1667 // All the standard BL checks.
1668 if (empty($CFG->messaging)) {
1669 throw new moodle_exception('disabled', 'message');
1670 }
1671
1672 $params = [
1673 'userid' => $userid,
1674 'conversationid' => $conversationid,
1675 'includecontactrequests' => $includecontactrequests,
1676 'includeprivacyinfo' => $includeprivacyinfo,
1677 'memberlimit' => $memberlimit,
1678 'memberoffset' => $memberoffset,
1679 'messagelimit' => $messagelimit,
1680 'messageoffset' => $messageoffset,
1681 'newestmessagesfirst' => $newestmessagesfirst
1682 ];
1683 self::validate_parameters(self::get_conversation_parameters(), $params);
1684
1685 $systemcontext = context_system::instance();
1686 self::validate_context($systemcontext);
1687
1688 $conversation = \core_message\api::get_conversation(
1689 $params['userid'],
1690 $params['conversationid'],
1691 $params['includecontactrequests'],
1692 $params['includeprivacyinfo'],
1693 $params['memberlimit'],
1694 $params['memberoffset'],
1695 $params['messagelimit'],
1696 $params['messageoffset'],
1697 $params['newestmessagesfirst']
1698 );
1699
1700 if ($conversation) {
1701 return $conversation;
1702 } else {
1703 // We have to throw an exception here because the external functions annoyingly
1704 // don't accept null to be returned for a single structure.
1705 throw new \moodle_exception('Conversation does not exist');
1706 }
1707 }
1708
1709 /**
1710 * Get conversation returns.
1711 *
1712 * @return external_single_structure
1713 */
1714 public static function get_conversation_returns() {
1715 return self::get_conversation_structure();
1716 }
1717
9aa012b5 1718 /**
49aaadc3 1719 * The messagearea conversations parameters.
9aa012b5 1720 *
eb35e0b1 1721 * @deprecated since 3.6
9aa012b5 1722 * @return external_function_parameters
49aaadc3 1723 * @since 3.2
9aa012b5
MN
1724 */
1725 public static function data_for_messagearea_conversations_parameters() {
1726 return new external_function_parameters(
1727 array(
1728 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1729 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1730 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1731 )
1732 );
1733 }
1734
1735 /**
1736 * Get messagearea conversations.
1737 *
eb35e0b1
JD
1738 * NOTE FOR FINAL DEPRECATION:
1739 * When removing this method, please also consider removal of get_conversations_legacy_formatter()
1740 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data
1741 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be
1742 * removed.
1743 *
1744 * @deprecated since 3.6
9aa012b5
MN
1745 * @param int $userid The id of the user who we are viewing conversations for
1746 * @param int $limitfrom
1747 * @param int $limitnum
49aaadc3
MN
1748 * @return stdClass
1749 * @throws moodle_exception
1750 * @since 3.2
9aa012b5
MN
1751 */
1752 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 1753 global $CFG, $PAGE, $USER;
9aa012b5
MN
1754
1755 // Check if messaging is enabled.
837941e9 1756 if (empty($CFG->messaging)) {
9aa012b5
MN
1757 throw new moodle_exception('disabled', 'message');
1758 }
1759
837941e9
MN
1760 $systemcontext = context_system::instance();
1761
9aa012b5
MN
1762 $params = array(
1763 'userid' => $userid,
1764 'limitfrom' => $limitfrom,
1765 'limitnum' => $limitnum
1766 );
bb650761 1767 $params = self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
837941e9 1768 self::validate_context($systemcontext);
9aa012b5 1769
bb650761 1770 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1771 throw new moodle_exception('You do not have permission to perform this action.');
1772 }
9aa012b5 1773
bb650761 1774 $conversations = \core_message\api::get_conversations($params['userid'], $params['limitfrom'], $params['limitnum']);
eb35e0b1
JD
1775
1776 // Format the conversations in the legacy style, as the get_conversations method has since been changed.
1777 $conversations = \core_message\helper::get_conversations_legacy_formatter($conversations);
1778
de55cb1b 1779 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
9aa012b5
MN
1780
1781 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 1782 return $conversations->export_for_template($renderer);
9aa012b5
MN
1783 }
1784
1785 /**
49aaadc3 1786 * The messagearea conversations return structure.
9aa012b5 1787 *
eb35e0b1 1788 * @deprecated since 3.6
49aaadc3
MN
1789 * @return external_single_structure
1790 * @since 3.2
9aa012b5
MN
1791 */
1792 public static function data_for_messagearea_conversations_returns() {
49aaadc3 1793 return new external_single_structure(
9aa012b5 1794 array(
9aa012b5 1795 'contacts' => new external_multiple_structure(
a3e3a3a1 1796 self::get_messagearea_contact_structure()
9aa012b5
MN
1797 )
1798 )
1799 );
1800 }
1801
eb35e0b1
JD
1802 /**
1803 * Marking the method as deprecated.
1804 *
1805 * @return bool
1806 */
1807 public static function data_for_messagearea_conversations_is_deprecated() {
1808 return true;
1809 }
1810
9aa012b5 1811 /**
49aaadc3 1812 * The messagearea contacts return parameters.
9aa012b5 1813 *
a6049a79 1814 * @deprecated since 3.6
9aa012b5 1815 * @return external_function_parameters
49aaadc3 1816 * @since 3.2
9aa012b5
MN
1817 */
1818 public static function data_for_messagearea_contacts_parameters() {
1819 return self::data_for_messagearea_conversations_parameters();
1820 }
1821
1822 /**
1823 * Get messagearea contacts parameters.
1824 *
a6049a79 1825 * @deprecated since 3.6
9aa012b5
MN
1826 * @param int $userid The id of the user who we are viewing conversations for
1827 * @param int $limitfrom
1828 * @param int $limitnum
49aaadc3
MN
1829 * @return stdClass
1830 * @throws moodle_exception
1831 * @since 3.2
9aa012b5
MN
1832 */
1833 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 1834 global $CFG, $PAGE, $USER;
9aa012b5
MN
1835
1836 // Check if messaging is enabled.
837941e9 1837 if (empty($CFG->messaging)) {
9aa012b5
MN
1838 throw new moodle_exception('disabled', 'message');
1839 }
1840
837941e9
MN
1841 $systemcontext = context_system::instance();
1842
9aa012b5
MN
1843 $params = array(
1844 'userid' => $userid,
1845 'limitfrom' => $limitfrom,
1846 'limitnum' => $limitnum
1847 );
bb650761 1848 $params = self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
837941e9 1849 self::validate_context($systemcontext);
9aa012b5 1850
bb650761 1851 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1852 throw new moodle_exception('You do not have permission to perform this action.');
1853 }
9aa012b5 1854
bb650761 1855 $contacts = \core_message\api::get_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
de55cb1b 1856 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
9aa012b5
MN
1857
1858 $renderer = $PAGE->get_renderer('core_message');
1859 return $contacts->export_for_template($renderer);
1860 }
1861
1862 /**
49aaadc3 1863 * The messagearea contacts return structure.
9aa012b5 1864 *
a6049a79 1865 * @deprecated since 3.6
49aaadc3
MN
1866 * @return external_single_structure
1867 * @since 3.2
9aa012b5
MN
1868 */
1869 public static function data_for_messagearea_contacts_returns() {
1870 return self::data_for_messagearea_conversations_returns();
1871 }
1872
a6049a79
MN
1873 /**
1874 * Marking the method as deprecated.
1875 *
1876 * @return bool
1877 */
1878 public static function data_for_messagearea_contacts_is_deprecated() {
1879 return true;
1880 }
1881
3cd13828 1882 /**
49aaadc3 1883 * The messagearea messages parameters.
3cd13828 1884 *
a6049a79 1885 * @deprecated since 3.6
3cd13828 1886 * @return external_function_parameters
49aaadc3 1887 * @since 3.2
3cd13828
MN
1888 */
1889 public static function data_for_messagearea_messages_parameters() {
1890 return new external_function_parameters(
1891 array(
1892 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1893 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1894 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
8ec78c48
MN
1895 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1896 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
ffd7798c 1897 'timefrom' => new external_value(PARAM_INT,
fb1469d8 1898 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
3cd13828
MN
1899 )
1900 );
1901 }
1902
1903 /**
1904 * Get messagearea messages.
1905 *
a6049a79 1906 * @deprecated since 3.6
3cd13828
MN
1907 * @param int $currentuserid The current user's id
1908 * @param int $otheruserid The other user's id
1909 * @param int $limitfrom
1910 * @param int $limitnum
8ec78c48 1911 * @param boolean $newest
49aaadc3
MN
1912 * @return stdClass
1913 * @throws moodle_exception
1914 * @since 3.2
3cd13828 1915 */
7b55aaa1 1916 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
ffd7798c 1917 $newest = false, $timefrom = 0) {
837941e9 1918 global $CFG, $PAGE, $USER;
3cd13828
MN
1919
1920 // Check if messaging is enabled.
837941e9 1921 if (empty($CFG->messaging)) {
3cd13828
MN
1922 throw new moodle_exception('disabled', 'message');
1923 }
1924
837941e9
MN
1925 $systemcontext = context_system::instance();
1926
3cd13828
MN
1927 $params = array(
1928 'currentuserid' => $currentuserid,
1929 'otheruserid' => $otheruserid,
1930 'limitfrom' => $limitfrom,
8ec78c48 1931 'limitnum' => $limitnum,
fb1469d8 1932 'newest' => $newest,
ffd7798c 1933 'timefrom' => $timefrom,
3cd13828 1934 );
bb650761 1935 $params = self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
837941e9 1936 self::validate_context($systemcontext);
3cd13828 1937
bb650761 1938 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
1939 throw new moodle_exception('You do not have permission to perform this action.');
1940 }
3cd13828 1941
bb650761 1942 if ($params['newest']) {
8ec78c48
MN
1943 $sort = 'timecreated DESC';
1944 } else {
1945 $sort = 'timecreated ASC';
1946 }
fb1469d8
RW
1947
1948 // We need to enforce a one second delay on messages to avoid race conditions of current
1949 // messages still being sent.
1950 //
1951 // There is a chance that we could request messages before the current time's
1952 // second has elapsed and while other messages are being sent in that same second. In which
1953 // case those messages will be lost.
1954 //
1955 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
bb650761 1956 if (!empty($params['timefrom'])) {
ffd7798c 1957 $timeto = time() - 1;
fb1469d8 1958 } else {
ffd7798c 1959 $timeto = 0;
fb1469d8
RW
1960 }
1961
1962 // No requesting messages from the current time, as stated above.
bb650761 1963 if ($params['timefrom'] == time()) {
ffd7798c 1964 $messages = [];
fb1469d8 1965 } else {
bb650761
DW
1966 $messages = \core_message\api::get_messages($params['currentuserid'], $params['otheruserid'], $params['limitfrom'],
1967 $params['limitnum'], $sort, $params['timefrom'], $timeto);
fb1469d8
RW
1968 }
1969
bb650761 1970 $messages = new \core_message\output\messagearea\messages($params['currentuserid'], $params['otheruserid'], $messages);
3cd13828
MN
1971
1972 $renderer = $PAGE->get_renderer('core_message');
1973 return $messages->export_for_template($renderer);
1974 }
1975
1976 /**
49aaadc3 1977 * The messagearea messages return structure.
3cd13828 1978 *
a6049a79 1979 * @deprecated since 3.6
49aaadc3
MN
1980 * @return external_single_structure
1981 * @since 3.2
3cd13828
MN
1982 */
1983 public static function data_for_messagearea_messages_returns() {
49aaadc3 1984 return new external_single_structure(
3cd13828 1985 array(
7b55aaa1
MN
1986 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
1987 the messages on behalf of?'),
3cd13828
MN
1988 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1989 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1990 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
cb805753 1991 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
bf58081d 1992 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
3cd13828 1993 'messages' => new external_multiple_structure(
94e1db61 1994 self::get_messagearea_message_structure()
26dca05d
JP
1995 ),
1996 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
3cd13828
MN
1997 )
1998 );
1999 }
2000
a6049a79
MN
2001 /**
2002 * Marking the method as deprecated.
2003 *
2004 * @return bool
2005 */
2006 public static function data_for_messagearea_messages_is_deprecated() {
2007 return true;
2008 }
2009
fb04293b
SA
2010 /**
2011 * The conversation messages parameters.
2012 *
2013 * @return external_function_parameters
2014 * @since 3.6
2015 */
2016 public static function get_conversation_messages_parameters() {
2017 return new external_function_parameters(
2018 array(
2019 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2020 'convid' => new external_value(PARAM_INT, 'The conversation id'),
2021 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2022 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2023 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
2024 'timefrom' => new external_value(PARAM_INT,
2025 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
2026 )
2027 );
2028 }
2029
2030 /**
2031 * Get conversation messages.
2032 *
2033 * @param int $currentuserid The current user's id.
2034 * @param int $convid The conversation id.
2035 * @param int $limitfrom Return a subset of records, starting at this point (optional).
2036 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
2037 * @param bool $newest True for getting first newest messages, false otherwise.
2038 * @param int $timefrom The time from the conversation messages to get.
2039 * @return stdClass The messages and members who have sent some of these messages.
2040 * @throws moodle_exception
2041 * @since 3.6
2042 */
2043 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
2044 bool $newest = false, int $timefrom = 0) {
2045 global $CFG, $PAGE, $USER;
2046
2047 // Check if messaging is enabled.
2048 if (empty($CFG->messaging)) {
2049 throw new moodle_exception('disabled', 'message');
2050 }
2051
2052 $systemcontext = context_system::instance();
2053
2054 $params = array(
2055 'currentuserid' => $currentuserid,
2056 'convid' => $convid,
2057 'limitfrom' => $limitfrom,
2058 'limitnum' => $limitnum,
2059 'newest' => $newest,
2060 'timefrom' => $timefrom,
2061 );
bb650761 2062 $params = self::validate_parameters(self::get_conversation_messages_parameters(), $params);
fb04293b
SA
2063 self::validate_context($systemcontext);
2064
bb650761 2065 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
fb04293b
SA
2066 throw new moodle_exception('You do not have permission to perform this action.');
2067 }
2068
2069 $sort = $newest ? 'timecreated DESC' : 'timecreated ASC';
2070
2071 // We need to enforce a one second delay on messages to avoid race conditions of current
2072 // messages still being sent.
2073 //
2074 // There is a chance that we could request messages before the current time's
2075 // second has elapsed and while other messages are being sent in that same second. In which
2076 // case those messages will be lost.
2077 //
2078 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
bb650761 2079 $timeto = empty($params['timefrom']) ? 0 : time() - 1;
fb04293b
SA
2080
2081 // No requesting messages from the current time, as stated above.
bb650761 2082 if ($params['timefrom'] == time()) {
fb04293b
SA
2083 $messages = [];
2084 } else {
bb650761
DW
2085 $messages = \core_message\api::get_conversation_messages(
2086 $params['currentuserid'],
2087 $params['convid'],
2088 $params['limitfrom'],
2089 $params['limitnum'],
2090 $sort,
2091 $params['timefrom'],
2092 $timeto);
fb04293b
SA
2093 }
2094
2095 return $messages;
2096 }
2097
2098 /**
2099 * The messagearea messages return structure.
2100 *
2101 * @return external_single_structure
2102 * @since 3.6
2103 */
2104 public static function get_conversation_messages_returns() {
2105 return new external_single_structure(
2106 array(
2107 'id' => new external_value(PARAM_INT, 'The conversation id'),
2108 'members' => new external_multiple_structure(
2109 self::get_conversation_member_structure()
2110 ),
2111 'messages' => new external_multiple_structure(
2112 self::get_conversation_message_structure()
2113 ),
2114 )
2115 );
2116 }
2117
c060cd49 2118 /**
49aaadc3 2119 * The get most recent message return parameters.
c060cd49 2120 *
a6049a79 2121 * @deprecated since 3.6
c060cd49 2122 * @return external_function_parameters
49aaadc3 2123 * @since 3.2
c060cd49
MN
2124 */
2125 public static function data_for_messagearea_get_most_recent_message_parameters() {
2126 return new external_function_parameters(
2127 array(
2128 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2129 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2130 )
2131 );
2132 }
2133
2134 /**
2135 * Get the most recent message in a conversation.
2136 *
a6049a79 2137 * @deprecated since 3.6
c060cd49
MN
2138 * @param int $currentuserid The current user's id
2139 * @param int $otheruserid The other user's id
49aaadc3
MN
2140 * @return stdClass
2141 * @throws moodle_exception
2142 * @since 3.2
c060cd49
MN
2143 */
2144 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
837941e9 2145 global $CFG, $PAGE, $USER;
c060cd49
MN
2146
2147 // Check if messaging is enabled.
837941e9 2148 if (empty($CFG->messaging)) {
c060cd49
MN
2149 throw new moodle_exception('disabled', 'message');
2150 }
2151
837941e9
MN
2152 $systemcontext = context_system::instance();
2153
c060cd49
MN
2154 $params = array(
2155 'currentuserid' => $currentuserid,
2156 'otheruserid' => $otheruserid
2157 );
bb650761 2158 $params = self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
837941e9 2159 self::validate_context($systemcontext);
c060cd49 2160
bb650761 2161 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2162 throw new moodle_exception('You do not have permission to perform this action.');
2163 }
c060cd49 2164
bb650761 2165 $message = \core_message\api::get_most_recent_message($params['currentuserid'], $params['otheruserid']);
de55cb1b 2166 $message = new \core_message\output\messagearea\message($message);
c060cd49
MN
2167
2168 $renderer = $PAGE->get_renderer('core_message');
2169 return $message->export_for_template($renderer);
2170 }
2171
2172 /**
49aaadc3 2173 * The get most recent message return structure.
c060cd49 2174 *
a6049a79 2175 * @deprecated since 3.6
c060cd49 2176 * @return external_single_structure
49aaadc3 2177 * @since 3.2
c060cd49
MN
2178 */
2179 public static function data_for_messagearea_get_most_recent_message_returns() {
94e1db61 2180 return self::get_messagearea_message_structure();
c060cd49
MN
2181 }
2182
a6049a79
MN
2183 /**
2184 * Marking the method as deprecated.
2185 *
2186 * @return bool
2187 */
2188 public static function data_for_messagearea_get_most_recent_message_is_deprecated() {
2189 return true;
2190 }
2191
c6e97f54
MN
2192 /**
2193 * The get profile parameters.
2194 *
a6049a79 2195 * @deprecated since 3.6
c6e97f54 2196 * @return external_function_parameters
49aaadc3 2197 * @since 3.2
c6e97f54
MN
2198 */
2199 public static function data_for_messagearea_get_profile_parameters() {
2200 return new external_function_parameters(
2201 array(
2202 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2203 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
2204 )
2205 );
2206 }
2207
2208 /**
2209 * Get the profile information for a contact.
2210 *
a6049a79 2211 * @deprecated since 3.6
c6e97f54
MN
2212 * @param int $currentuserid The current user's id
2213 * @param int $otheruserid The id of the user whose profile we are viewing
49aaadc3
MN
2214 * @return stdClass
2215 * @throws moodle_exception
2216 * @since 3.2
c6e97f54
MN
2217 */
2218 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
837941e9 2219 global $CFG, $PAGE, $USER;
c6e97f54
MN
2220
2221 // Check if messaging is enabled.
837941e9 2222 if (empty($CFG->messaging)) {
c6e97f54
MN
2223 throw new moodle_exception('disabled', 'message');
2224 }
2225
837941e9
MN
2226 $systemcontext = context_system::instance();
2227
c6e97f54
MN
2228 $params = array(
2229 'currentuserid' => $currentuserid,
2230 'otheruserid' => $otheruserid
2231 );
bb650761 2232 $params = self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
837941e9 2233 self::validate_context($systemcontext);
c6e97f54 2234
bb650761 2235 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
837941e9
MN
2236 throw new moodle_exception('You do not have permission to perform this action.');
2237 }
c6e97f54 2238
bb650761 2239 $profile = \core_message\api::get_profile($params['currentuserid'], $params['otheruserid']);
de55cb1b 2240 $profile = new \core_message\output\messagearea\profile($profile);
c6e97f54
MN
2241
2242 $renderer = $PAGE->get_renderer('core_message');
2243 return $profile->export_for_template($renderer);
2244 }
2245
2246 /**
49aaadc3 2247 * The get profile return structure.
c6e97f54 2248 *
a6049a79 2249 * @deprecated since 3.6
c6e97f54 2250 * @return external_single_structure
49aaadc3 2251 * @since 3.2
c6e97f54
MN
2252 */
2253 public static function data_for_messagearea_get_profile_returns() {
2254 return new external_single_structure(
2255 array(
de55cb1b 2256 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
c6e97f54 2257 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
cc22b515 2258 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
c6e97f54
MN
2259 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
2260 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
2261 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
2262 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
cb805753 2263 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
bf58081d 2264 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
c6e97f54
MN
2265 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
2266 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
2267 )
2268 );
2269 }
2270
a6049a79
MN
2271 /**
2272 * Marking the method as deprecated.
2273 *
2274 * @return bool
2275 */
2276 public static function data_for_messagearea_get_profile_is_deprecated() {
2277 return true;
2278 }
2279
d6731600
FM
2280 /**
2281 * Get contacts parameters description.
2282 *
2283 * @return external_function_parameters
5bcfd504 2284 * @since Moodle 2.5
d6731600
FM
2285 */
2286 public static function get_contacts_parameters() {
2287 return new external_function_parameters(array());
2288 }
2289
2290 /**
2291 * Get contacts.
2292 *
d6731600 2293 * @return external_description
5bcfd504 2294 * @since Moodle 2.5
d6731600
FM
2295 */
2296 public static function get_contacts() {
883ce421 2297 global $CFG, $PAGE, $USER;
436bbf89
DM
2298
2299 // Check if messaging is enabled.
837941e9 2300 if (empty($CFG->messaging)) {
436bbf89
DM
2301 throw new moodle_exception('disabled', 'message');
2302 }
2303
d6731600
FM
2304 require_once($CFG->dirroot . '/user/lib.php');
2305
883ce421
MN
2306 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
2307 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id);
2308 foreach ($contacts as $contact) {
2309 // Set the mode.
2310 $mode = 'offline';
2311 if (\core_message\helper::is_online($contact->lastaccess)) {
2312 $mode = 'online';
2313 }
2314
2315 $newcontact = array(
2316 'id' => $contact->id,
2317 'fullname' => fullname($contact),
2318 'unread' => $contact->messagecount
2319 );
2320
2321 $userpicture = new user_picture($contact);
2322 $userpicture->size = 1; // Size f1.
2323 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2324 $userpicture->size = 0; // Size f2.
2325 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2326
2327 $allcontacts[$mode][$contact->id] = $newcontact;
2328 }
2329
2330 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id);
2331 foreach ($strangers as $contact) {
2332 $newcontact = array(
2333 'id' => $contact->id,
2334 'fullname' => fullname($contact),
2335 'unread' => $contact->messagecount
2336 );
2337
2338 $userpicture = new user_picture($contact);
2339 $userpicture->size = 1; // Size f1.
2340 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2341 $userpicture->size = 0; // Size f2.
2342 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600 2343
883ce421
MN
2344 $allcontacts['strangers'][$contact->id] = $newcontact;
2345 }
d6731600 2346
883ce421
MN
2347 // Add noreply user and support user to the list, if they don't exist.
2348 $supportuser = core_user::get_support_user();
2349 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) {
2350 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
2351 if ($supportuser->messagecount > 0) {
2352 $supportuser->fullname = fullname($supportuser);
2353 $supportuser->unread = $supportuser->messagecount;
2354 $allcontacts['strangers'][$supportuser->id] = $supportuser;
d6731600
FM
2355 }
2356 }
883ce421
MN
2357
2358 $noreplyuser = core_user::get_noreply_user();
2359 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) {
2360 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
2361 if ($noreplyuser->messagecount > 0) {
2362 $noreplyuser->fullname = fullname($noreplyuser);
2363 $noreplyuser->unread = $noreplyuser->messagecount;
2364 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser;
2365 }
2366 }
2367
d6731600
FM
2368 return $allcontacts;
2369 }
2370
2371 /**
2372 * Get contacts return description.
2373 *
2374 * @return external_description
5bcfd504 2375 * @since Moodle 2.5
d6731600
FM
2376 */
2377 public static function get_contacts_returns() {
2378 return new external_single_structure(
2379 array(
2380 'online' => new external_multiple_structure(
2381 new external_single_structure(
2382 array(
2383 'id' => new external_value(PARAM_INT, 'User ID'),
2384 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2385 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2386 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2387 'unread' => new external_value(PARAM_INT, 'Unread message count')
2388 )
2389 ),
2390 'List of online contacts'
2391 ),
2392 'offline' => new external_multiple_structure(
2393 new external_single_structure(
2394 array(
2395 'id' => new external_value(PARAM_INT, 'User ID'),
2396 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2397 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2398 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2399 'unread' => new external_value(PARAM_INT, 'Unread message count')
2400 )
2401 ),
2402 'List of offline contacts'
2403 ),
2404 'strangers' => new external_multiple_structure(
2405 new external_single_structure(
2406 array(
2407 'id' => new external_value(PARAM_INT, 'User ID'),
2408 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2409 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2410 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2411 'unread' => new external_value(PARAM_INT, 'Unread message count')
2412 )
2413 ),
2414 'List of users that are not in the user\'s contact list but have sent a message'
2415 )
2416 )
2417 );
2418 }
2419
2420 /**
2421 * Search contacts parameters description.
2422 *
2423 * @return external_function_parameters
5bcfd504 2424 * @since Moodle 2.5
d6731600
FM
2425 */
2426 public static function search_contacts_parameters() {
2427 return new external_function_parameters(
2428 array(
2429 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
2430 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
2431 VALUE_DEFAULT, false)
2432 )
2433 );
2434 }
2435
2436 /**
2437 * Search contacts.
2438 *
2439 * @param string $searchtext query string.
2440 * @param bool $onlymycourses limit the search to the user's courses only.
2441 * @return external_description
5bcfd504 2442 * @since Moodle 2.5
d6731600
FM
2443 */
2444 public static function search_contacts($searchtext, $onlymycourses = false) {
d85bedf7 2445 global $CFG, $USER, $PAGE;
11d83ab3 2446 require_once($CFG->dirroot . '/user/lib.php');
436bbf89
DM
2447
2448 // Check if messaging is enabled.
837941e9 2449 if (empty($CFG->messaging)) {
436bbf89
DM
2450 throw new moodle_exception('disabled', 'message');
2451 }
2452
d6731600
FM
2453 require_once($CFG->libdir . '/enrollib.php');
2454
2455 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
2456 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
2457
2458 // Extra validation, we do not allow empty queries.
2459 if ($params['searchtext'] === '') {
2460 throw new moodle_exception('querystringcannotbeempty');
2461 }
2462
2463 $courseids = array();
2464 if ($params['onlymycourses']) {
2465 $mycourses = enrol_get_my_courses(array('id'));
2466 foreach ($mycourses as $mycourse) {
2467 $courseids[] = $mycourse->id;
2468 }
2469 } else {
2470 $courseids[] = SITEID;
2471 }
2472
2473 // Retrieving the users matching the query.
2474 $users = message_search_users($courseids, $params['searchtext']);
2475 $results = array();
2476 foreach ($users as $user) {
2477 $results[$user->id] = $user;
2478 }
2479
2480 // Reorganising information.
2481 foreach ($results as &$user) {
2482 $newuser = array(
2483 'id' => $user->id,
2484 'fullname' => fullname($user)
2485 );
2486
2487 // Avoid undefined property notice as phone not specified.
2488 $user->phone1 = null;
2489 $user->phone2 = null;
2490
d85bedf7
JL
2491 $userpicture = new user_picture($user);
2492 $userpicture->size = 1; // Size f1.
2493 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2494 $userpicture->size = 0; // Size f2.
2495 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
2496
2497 $user = $newuser;
2498 }
2499
2500 return $results;
2501 }
2502
2503 /**
2504 * Search contacts return description.
2505 *
2506 * @return external_description
5bcfd504 2507 * @since Moodle 2.5
d6731600
FM
2508 */
2509 public static function search_contacts_returns() {
2510 return new external_multiple_structure(
2511 new external_single_structure(
2512 array(
2513 'id' => new external_value(PARAM_INT, 'User ID'),
2514 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2515 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2516 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
2517 )
2518 ),
2519 'List of contacts'
2520 );
2521 }
aff9da17
JL
2522
2523 /**
2524 * Get messages parameters description.
2525 *
2526 * @return external_function_parameters
193edf7f 2527 * @since 2.8
aff9da17
JL
2528 */
2529 public static function get_messages_parameters() {
2530 return new external_function_parameters(
2531 array(
6ff4464b 2532 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
127ef540
SH
2533 'useridfrom' => new external_value(
2534 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2535 VALUE_DEFAULT, 0),
2536 'type' => new external_value(
2537 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
2538 VALUE_DEFAULT, 'both'),
6ff4464b 2539 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
127ef540
SH
2540 'newestfirst' => new external_value(
2541 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
2542 VALUE_DEFAULT, true),
aff9da17 2543 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
127ef540
SH
2544 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
2545 )
aff9da17
JL
2546 );
2547 }
2548
2549 /**
2550 * Get messages function implementation.
127ef540
SH
2551 *
2552 * @since 2.8
2553 * @throws invalid_parameter_exception
2554 * @throws moodle_exception
6ff4464b
JL
2555 * @param int $useridto the user id who received the message
2556 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
193edf7f 2557 * @param string $type type of message to return, expected values: notifications, conversations and both
aff9da17 2558 * @param bool $read true for retreiving read messages, false for unread
6ff4464b 2559 * @param bool $newestfirst true for ordering by newest first, false for oldest first
aff9da17
JL
2560 * @param int $limitfrom limit from
2561 * @param int $limitnum limit num
2562 * @return external_description
aff9da17 2563 */
193edf7f 2564 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
aff9da17 2565 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
127ef540 2566 global $CFG, $USER;
aff9da17
JL
2567
2568 $warnings = array();
2569
2570 $params = array(
2571 'useridto' => $useridto,
6ff4464b 2572 'useridfrom' => $useridfrom,
aff9da17
JL
2573 'type' => $type,
2574 'read' => $read,
aff9da17
JL
2575 'newestfirst' => $newestfirst,
2576 'limitfrom' => $limitfrom,
2577 'limitnum' => $limitnum
2578 );
2579
2580 $params = self::validate_parameters(self::get_messages_parameters(), $params);
2581
2582 $context = context_system::instance();
2583 self::validate_context($context);
2584
2585 $useridto = $params['useridto'];
6ff4464b 2586 $useridfrom = $params['useridfrom'];
aff9da17
JL
2587 $type = $params['type'];
2588 $read = $params['read'];
aff9da17
JL
2589 $newestfirst = $params['newestfirst'];
2590 $limitfrom = $params['limitfrom'];
2591 $limitnum = $params['limitnum'];
2592
2593 $allowedvalues = array('notifications', 'conversations', 'both');
2594 if (!in_array($type, $allowedvalues)) {
2595 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
2596 'allowed values are: ' . implode(',', $allowedvalues));
2597 }
2598
2599 // Check if private messaging between users is allowed.
2600 if (empty($CFG->messaging)) {
2601 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
aff9da17
JL
2602 if ($type == "conversations") {
2603 throw new moodle_exception('disabled', 'message');
2604 }
2605 if ($type == "both") {
2606 $warning = array();
2607 $warning['item'] = 'message';
2608 $warning['itemid'] = $USER->id;
2609 $warning['warningcode'] = '1';
2610 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
2611 Only notifications will be returned';
2612 $warnings[] = $warning;
2613 }
2614 }
2615
2616 if (!empty($useridto)) {
6ff4464b
JL
2617 if (core_user::is_real_user($useridto)) {
2618 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2619 } else {
2620 throw new moodle_exception('invaliduser');
2621 }
aff9da17
JL
2622 }
2623
2624 if (!empty($useridfrom)) {
2625 // We use get_user here because the from user can be the noreply or support user.
2626 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2627 }
2628
2629 // Check if the current user is the sender/receiver or just a privileged user.
2630 if ($useridto != $USER->id and $useridfrom != $USER->id and
2631 !has_capability('moodle/site:readallmessages', $context)) {
2632 throw new moodle_exception('accessdenied', 'admin');
2633 }
2634
127ef540 2635 // Which type of messages to retrieve.
193edf7f 2636 $notifications = -1;
aff9da17 2637 if ($type != 'both') {
193edf7f 2638 $notifications = ($type == 'notifications') ? 1 : 0;
aff9da17
JL
2639 }
2640
aff9da17 2641 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
193edf7f 2642 $sort = "mr.timecreated $orderdirection";
aff9da17 2643
193edf7f 2644 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
aff9da17
JL
2645 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
2646
2647 // In some cases, we don't need to get the to/from user objects from the sql query.
2648 $userfromfullname = '';
2649 $usertofullname = '';
2650
2651 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
2652 if (!empty($useridto)) {
2653 $usertofullname = fullname($userto, $canviewfullname);
2654 // The user from may or may not be filled.
2655 if (!empty($useridfrom)) {
2656 $userfromfullname = fullname($userfrom, $canviewfullname);
2657 }
2658 } else {
2659 // If the useridto field is empty, the useridfrom must be filled.
2660 $userfromfullname = fullname($userfrom, $canviewfullname);
2661 }
aff9da17
JL
2662 foreach ($messages as $mid => $message) {
2663
ea21d637 2664 // Do not return deleted messages.
883ce421
MN
2665 if (!$message->notification) {
2666 if (($useridto == $USER->id and $message->timeusertodeleted) or
ea21d637 2667 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
883ce421
MN
2668 unset($messages[$mid]);
2669 continue;
2670 }
ea21d637
JL
2671 }
2672
aff9da17
JL
2673 // We need to get the user from the query.
2674 if (empty($userfromfullname)) {
6ff4464b
JL
2675 // Check for non-reply and support users.
2676 if (core_user::is_real_user($message->useridfrom)) {
127ef540 2677 $user = new stdClass();
6ff4464b
JL
2678 $user = username_load_fields_from_object($user, $message, 'userfrom');
2679 $message->userfromfullname = fullname($user, $canviewfullname);
2680 } else {
2681 $user = core_user::get_user($message->useridfrom);
2682 $message->userfromfullname = fullname($user, $canviewfullname);
2683 }
aff9da17
JL
2684 } else {
2685 $message->userfromfullname = $userfromfullname;
2686 }
2687
2688 // We need to get the user from the query.
2689 if (empty($usertofullname)) {
127ef540 2690 $user = new stdClass();
aff9da17
JL
2691 $user = username_load_fields_from_object($user, $message, 'userto');
2692 $message->usertofullname = fullname($user, $canviewfullname);
2693 } else {
2694 $message->usertofullname = $usertofullname;
2695 }
2696
aff9da17 2697 $message->text = message_format_message_text($message);
aff9da17
JL
2698 $messages[$mid] = (array) $message;
2699 }
2700 }
2701
2702 $results = array(
2703 'messages' => $messages,
2704 'warnings' => $warnings
2705 );
2706
2707 return $results;
2708 }
2709
2710 /**
2711 * Get messages return description.
2712 *
6ff4464b 2713 * @return external_single_structure
193edf7f 2714 * @since 2.8
aff9da17
JL
2715 */
2716 public static function get_messages_returns() {
2717 return new external_single_structure(
2718 array(
2719 'messages' => new external_multiple_structure(
2720 new external_single_structure(
2721 array(
193edf7f 2722 'id' => new external_value(PARAM_INT, 'Message id'),
aff9da17
JL
2723 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
2724 'useridto' => new external_value(PARAM_INT, 'User to id'),
2725 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
2726 'text' => new external_value(PARAM_RAW, 'The message text formated'),
2727 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
193edf7f 2728 'fullmessageformat' => new external_format_value('fullmessage'),
aff9da17
JL
2729 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
2730 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
2731 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
2732 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
2733 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
2734 'timecreated' => new external_value(PARAM_INT, 'Time created'),
2735 'timeread' => new external_value(PARAM_INT, 'Time read'),
2736 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
2737 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
2738 ), 'message'
2739 )
2740 ),
2741 'warnings' => new external_warnings()
2742 )
2743 );
3274d5ca
RW
2744 }
2745
3274d5ca
RW
2746 /**
2747 * Mark all notifications as read parameters description.
2748 *
2749 * @return external_function_parameters
2750 * @since 3.2
2751 */
2752 public static function mark_all_notifications_as_read_parameters() {
2753 return new external_function_parameters(
2754 array(
2755 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2756 'useridfrom' => new external_value(
2757 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2758 VALUE_DEFAULT, 0),
2759 )
2760 );
2761 }
2762
2763 /**
2764 * Mark all notifications as read function.
2765 *
2766 * @since 3.2
2767 * @throws invalid_parameter_exception
2768 * @throws moodle_exception
2769 * @param int $useridto the user id who received the message
2770 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2771 * @return external_description
2772 */
2773 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
837941e9 2774 global $USER;
3274d5ca
RW
2775
2776 $params = self::validate_parameters(
2777 self::mark_all_notifications_as_read_parameters(),
2778 array(
2779 'useridto' => $useridto,
2780 'useridfrom' => $useridfrom,
2781 )
2782 );
2783
2784 $context = context_system::instance();
2785 self::validate_context($context);
2786
2787 $useridto = $params['useridto'];
2788 $useridfrom = $params['useridfrom'];
2789
2790 if (!empty($useridto)) {
2791 if (core_user::is_real_user($useridto)) {
2792 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2793 } else {
2794 throw new moodle_exception('invaliduser');
2795 }
2796 }
2797
2798 if (!empty($useridfrom)) {
2799 // We use get_user here because the from user can be the noreply or support user.
2800 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2801 }
2802
2803 // Check if the current user is the sender/receiver or just a privileged user.
2804 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 2805 // The deleteanymessage cap seems more reasonable here than readallmessages.
3274d5ca
RW
2806 !has_capability('moodle/site:deleteanymessage', $context)) {
2807 throw new moodle_exception('accessdenied', 'admin');
2808 }
2809
74ad60bf 2810 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom);
3274d5ca
RW
2811
2812 return true;
2813 }
2814
2815 /**
2816 * Mark all notifications as read return description.
2817 *
2818 * @return external_single_structure
2819 * @since 3.2
2820 */
2821 public static function mark_all_notifications_as_read_returns() {
2822 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2823 }
2824
8c55bd6c
RW
2825 /**
2826 * Get unread conversations count parameters description.
2827 *
2828 * @return external_function_parameters
2829 * @since 3.2
2830 */
2831 public static function get_unread_conversations_count_parameters() {
2832 return new external_function_parameters(
2833 array(
2834 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2835 )
2836 );
2837 }
2838
2839 /**
2840 * Get unread messages count function.
2841 *
2842 * @since 3.2
2843 * @throws invalid_parameter_exception
2844 * @throws moodle_exception
2845 * @param int $useridto the user id who received the message
2846 * @return external_description
2847 */
2848 public static function get_unread_conversations_count($useridto) {
a2c7227a
SL
2849 global $USER, $CFG;
2850
2851 // Check if messaging is enabled.
2852 if (empty($CFG->messaging)) {
2853 throw new moodle_exception('disabled', 'message');
2854 }
8c55bd6c
RW
2855
2856 $params = self::validate_parameters(
2857 self::get_unread_conversations_count_parameters(),
2858 array('useridto' => $useridto)
2859 );
2860
2861 $context = context_system::instance();
2862 self::validate_context($context);
2863
2864 $useridto = $params['useridto'];
2865
2866 if (!empty($useridto)) {
2867 if (core_user::is_real_user($useridto)) {
2868 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2869 } else {
2870 throw new moodle_exception('invaliduser');
2871 }
2872 } else {
2873 $useridto = $USER->id;
2874 }
2875
2876 // Check if the current user is the receiver or just a privileged user.
2877 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
2878 throw new moodle_exception('accessdenied', 'admin');
2879 }
2880
79f6c36c 2881 return \core_message\api::count_unread_conversations($userto);
8c55bd6c
RW
2882 }
2883
2884 /**
2885 * Get unread conversations count return description.
2886 *
2887 * @return external_single_structure
2888 * @since 3.2
2889 */
2890 public static function get_unread_conversations_count_returns() {
2891 return new external_value(PARAM_INT, 'The count of unread messages for the user');
aff9da17
JL
2892 }
2893
60ab2e1b
JL
2894 /**
2895 * Get blocked users parameters description.
2896 *
2897 * @return external_function_parameters
2898 * @since 2.9
2899 */
2900 public static function get_blocked_users_parameters() {
2901 return new external_function_parameters(
2902 array(
2903 'userid' => new external_value(PARAM_INT,
2904 'the user whose blocked users we want to retrieve',
2905 VALUE_REQUIRED),
2906 )
2907 );
2908 }
2909
2910 /**
2911 * Retrieve a list of users blocked
2912 *
2913 * @param int $userid the user whose blocked users we want to retrieve
2914 * @return external_description
2915 * @since 2.9
2916 */
2917 public static function get_blocked_users($userid) {
d85bedf7 2918 global $CFG, $USER, $PAGE;
60ab2e1b
JL
2919
2920 // Warnings array, it can be empty at the end but is mandatory.
2921 $warnings = array();
2922
2923 // Validate params.
2924 $params = array(
2925 'userid' => $userid
2926 );
2927 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
2928 $userid = $params['userid'];
2929
2930 // Validate context.
2931 $context = context_system::instance();
2932 self::validate_context($context);
2933
2934 // Check if private messaging between users is allowed.
2935 if (empty($CFG->messaging)) {
2936 throw new moodle_exception('disabled', 'message');
2937 }
2938
4485f7c5
JL
2939 $user = core_user::get_user($userid, '*', MUST_EXIST);
2940 core_user::require_active_user($user);
60ab2e1b
JL
2941
2942 // Check if we have permissions for retrieve the information.
343ba16c
SL
2943 $capability = 'moodle/site:manageallmessaging';
2944 if (($USER->id != $userid) && !has_capability($capability, $context)) {
2945 throw new required_capability_exception($context, $capability, 'nopermissions', '');
60ab2e1b
JL
2946 }
2947
2948 // Now, we can get safely all the blocked users.
883ce421 2949 $users = \core_message\api::get_blocked_users($user->id);
60ab2e1b
JL
2950
2951 $blockedusers = array();
2952 foreach ($users as $user) {
2953 $newuser = array(
2954 'id' => $user->id,
2955 'fullname' => fullname($user),
2956 );
0b074e88 2957
d85bedf7
JL
2958 $userpicture = new user_picture($user);
2959 $userpicture->size = 1; // Size f1.
2960 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
60ab2e1b
JL
2961
2962 $blockedusers[] = $newuser;
2963 }
2964
2965 $results = array(
2966 'users' => $blockedusers,
2967 'warnings' => $warnings
2968 );
2969 return $results;
2970 }
2971
2972 /**
2973 * Get blocked users return description.
2974 *
2975 * @return external_single_structure
2976 * @since 2.9
2977 */
2978 public static function get_blocked_users_returns() {
2979 return new external_single_structure(
2980 array(
2981 'users' => new external_multiple_structure(
2982 new external_single_structure(
2983 array(
2984 'id' => new external_value(PARAM_INT, 'User ID'),
2985 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2986 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
2987 )
2988 ),
2989 'List of blocked users'
2990 ),
2991 'warnings' => new external_warnings()
2992 )
2993 );
2994 }
2995
31c474da
JL
2996 /**
2997 * Returns description of method parameters
2998 *
2999 * @return external_function_parameters
3000 * @since 2.9
3001 */
3002 public static function mark_message_read_parameters() {
3003 return new external_function_parameters(
3004 array(
2b595d96 3005 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'),
7b55aaa1
MN
3006 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
3007 VALUE_DEFAULT, 0)
31c474da
JL
3008 )
3009 );
3010 }
3011
3012 /**
3013 * Mark a single message as read, trigger message_viewed event
3014 *
3015 * @param int $messageid id of the message (in the message table)
3016 * @param int $timeread timestamp for when the message should be marked read
3017 * @return external_description
3018 * @throws invalid_parameter_exception
3019 * @throws moodle_exception
3020 * @since 2.9
3021 */
3022 public static function mark_message_read($messageid, $timeread) {
3023 global $CFG, $DB, $USER;
31c474da
JL
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 'messageid' => $messageid,
3036 'timeread' => $timeread
3037 );
3038 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
3039
0b19d048
RW
3040 if (empty($params['timeread'])) {
3041 $timeread = time();
3042 } else {
3043 $timeread = $params['timeread'];
3044 }
3045
31c474da
JL
3046 // Validate context.
3047 $context = context_system::instance();
3048 self::validate_context($context);
3049
883ce421
MN
3050 $sql = "SELECT m.*, mcm.userid as useridto
3051 FROM {messages} m
3052 INNER JOIN {message_conversations} mc
3053 ON m.conversationid = mc.id
3054 INNER JOIN {message_conversation_members} mcm
3055 ON mcm.conversationid = mc.id
5aac33c7
MN
3056 LEFT JOIN {message_user_actions} mua
3057 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
3058 WHERE mua.id is NULL
3059 AND mcm.userid != m.useridfrom
883ce421 3060 AND m.id = ?";
5aac33c7
MN
3061 $messageparams = [];
3062 $messageparams[] = $USER->id;
3063 $messageparams[] = \core_message\api::MESSAGE_ACTION_READ;
3064 $messageparams[] = $params['messageid'];
3065 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST);
31c474da
JL
3066
3067 if ($message->useridto != $USER->id) {
3068 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
3069 }
3070
548936a6 3071 \core_message\api::mark_message_as_read($USER->id, $message, $timeread);
31c474da
JL
3072
3073 $results = array(
883ce421 3074 'messageid' => $message->id,
31c474da
JL
3075 'warnings' => $warnings
3076 );
3077 return $results;
3078 }
3079
3080 /**
3081 * Returns description of method result value
3082 *
3083 * @return external_description
3084 * @since 2.9
3085 */
3086 public static function mark_message_read_returns() {
3087 return new external_single_structure(
3088 array(
2b595d96
MN
3089 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'),
3090 'warnings' => new external_warnings()
3091 )
3092 );
3093 }
3094
3095 /**
3096 * Returns description of method parameters
3097 *
3098 * @return external_function_parameters
3099 */
3100 public static function mark_notification_read_parameters() {
3101 return new external_function_parameters(
3102 array(
3103 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
3104 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read',
3105 VALUE_DEFAULT, 0)
3106 )
3107 );
3108 }
3109
3110 /**
3111 * Mark a single notification as read.
3112 *
3113 * This will trigger a 'notification_viewed' event.
3114 *
3115 * @param int $notificationid id of the notification
3116 * @param int $timeread timestamp for when the notification should be marked read
3117 * @return external_description
3118 * @throws invalid_parameter_exception
3119 * @throws moodle_exception
3120 */
3121 public static function mark_notification_read($notificationid, $timeread) {
3122 global $CFG, $DB, $USER;
3123
3124 // Check if private messaging between users is allowed.
3125 if (empty($CFG->messaging)) {
3126 throw new moodle_exception('disabled', 'message');
3127 }
3128
3129 // Warnings array, it can be empty at the end but is mandatory.
3130 $warnings = array();
3131
3132 // Validate params.
3133 $params = array(
3134 'notificationid' => $notificationid,
3135 'timeread' => $timeread
3136 );
3137 $params = self::validate_parameters(self::mark_notification_read_parameters(), $params);
3138
3139 if (empty($params['timeread'])) {
3140 $timeread = time();
3141 } else {
3142 $timeread = $params['timeread'];
3143 }
3144
3145 // Validate context.
3146 $context = context_system::instance();
3147 self::validate_context($context);
3148
3149 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST);
3150
3151 if ($notification->useridto != $USER->id) {
3152 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
3153 'notification as read');
3154 }
3155
3156 \core_message\api::mark_notification_as_read($notification, $timeread);
3157
3158 $results = array(
3159 'notificationid' => $notification->id,
3160 'warnings' => $warnings
3161 );
3162
3163 return $results;
3164 }
3165
3166 /**
3167 * Returns description of method result value
3168 *
3169 * @return external_description
3170 */
3171 public static function mark_notification_read_returns() {
3172 return new external_single_structure(
3173 array(
3174 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
31c474da
JL
3175 'warnings' => new external_warnings()
3176 )
3177 );
3178 }
3179
8c55bd6c
RW
3180 /**
3181 * Mark all messages as read parameters description.
3182 *
e4c30994 3183 * @deprecated since 3.6
8c55bd6c
RW
3184 * @return external_function_parameters
3185 * @since 3.2
3186 */
3187 public static function mark_all_messages_as_read_parameters() {
3188 return new external_function_parameters(
3189 array(
3190 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3191 'useridfrom' => new external_value(
3192 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3193 VALUE_DEFAULT, 0),
3194 )
3195 );
3196 }
3197
3198 /**
e4c30994 3199 * Mark all messages as read function.
8c55bd6c 3200 *
e4c30994 3201 * @deprecated since 3.6
8c55bd6c
RW
3202 * @throws invalid_parameter_exception
3203 * @throws moodle_exception
3204 * @param int $useridto the user id who received the message
3205 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3206 * @return external_description
e4c30994 3207 * @since 3.2
8c55bd6c
RW
3208 */
3209 public static function mark_all_messages_as_read($useridto, $useridfrom) {
a2c7227a
SL
3210 global $USER, $CFG;
3211
3212 // Check if messaging is enabled.
3213 if (empty($CFG->messaging)) {
3214 throw new moodle_exception('disabled', 'message');
3215 }
8c55bd6c
RW
3216
3217 $params = self::validate_parameters(
3218 self::mark_all_messages_as_read_parameters(),
3219 array(
3220 'useridto' => $useridto,
3221 'useridfrom' => $useridfrom,
3222 )
3223 );
3224
3225 $context = context_system::instance();
3226 self::validate_context($context);
3227
3228 $useridto = $params['useridto'];
3229 $useridfrom = $params['useridfrom'];
3230
3231 if (!empty($useridto)) {
3232 if (core_user::is_real_user($useridto)) {
3233 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3234 } else {
3235 throw new moodle_exception('invaliduser');
3236 }
3237 }
3238
3239 if (!empty($useridfrom)) {
3240 // We use get_user here because the from user can be the noreply or support user.
3241 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3242 }
3243
3244 // Check if the current user is the sender/receiver or just a privileged user.
3245 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 3246 // The deleteanymessage cap seems more reasonable here than readallmessages.
8c55bd6c
RW
3247 !has_capability('moodle/site:deleteanymessage', $context)) {
3248 throw new moodle_exception('accessdenied', 'admin');
3249 }
3250
74ad60bf
MN
3251 if ($useridfrom) {
3252 if ($conversationid = \core_message\api::get_conversation_between_users([$useridto, $useridfrom])) {
3253 \core_message\api::mark_all_messages_as_read($useridto, $conversationid);
3254 }
3255 } else {
3256 \core_message\api::mark_all_messages_as_read($useridto);
3257 }
8c55bd6c
RW
3258
3259 return true;
3260 }
3261
3262 /**
e4c30994 3263 * Mark all messages as read return description.
8c55bd6c 3264 *
e4c30994 3265 * @deprecated since 3.6
8c55bd6c
RW
3266 * @return external_single_structure
3267 * @since 3.2
3268 */
3269 public static function mark_all_messages_as_read_returns() {
3270 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
3271 }
3272
e4c30994
MN
3273 /**
3274 * Marking the method as deprecated.
3275 *
3276 * @return bool
3277 */
3278 public static function mark_all_messages_as_read_is_deprecated() {
3279 return true;
3280 }
3281
09ec5017
MN
3282 /**
3283 * Mark all conversation messages as read parameters description.
3284 *
3285 * @return external_function_parameters
3286 * @since 3.6
3287 */
3288 public static function mark_all_conversation_messages_as_read_parameters() {
3289 return new external_function_parameters(
3290 array(
3291 'userid' => new external_value(PARAM_INT, 'The user id who who we are marking the messages as read for'),
3292 'conversationid' =>
3293 new external_value(PARAM_INT, 'The conversation id who who we are marking the messages as read for')
3294 )
3295 );
3296 }
3297
3298 /**
3299 * Mark all conversation messages as read function.
3300 *
3301 * @param int $userid The user id of who we want to delete the conversation for
3302 * @param int $conversationid The id of the conversations
3303 * @since 3.6
3304 */
3305 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
3306 global $CFG;
3307
3308 // Check if messaging is enabled.
3309 if (empty($CFG->messaging)) {
3310 throw new moodle_exception('disabled', 'message');
3311 }
3312
3313 $params = array(
3314 'userid' => $userid,
3315 'conversationid' => $conversationid,
3316 );
3317 $params = self::validate_parameters(self::mark_all_conversation_messages_as_read_parameters(), $params);
3318
3319 $context = context_system::instance();
3320 self::validate_context($context);
3321
3322 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3323 core_user::require_active_user($user);
3324
bb650761
DW
3325 if (\core_message\api::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) {
3326 \core_message\api::mark_all_messages_as_read($params['userid'], $params['conversationid']);
09ec5017
MN
3327 } else {
3328 throw new moodle_exception('accessdenied', 'admin');
3329 }
3330 }
3331
3332 /**
3333 * Mark all conversation messages as read return description.
3334 *
3335 * @return external_warnings
3336 * @since 3.6
3337 */
3338 public static function mark_all_conversation_messages_as_read_returns() {
c61353ae 3339 return null;
09ec5017
MN
3340 }
3341
dec0cd99
MN
3342 /**
3343 * Returns description of method parameters.
3344 *
fa024820 3345 * @deprecated since 3.6
dec0cd99
MN
3346 * @return external_function_parameters
3347 * @since 3.2
3348 */
3349 public static function delete_conversation_parameters() {
3350 return new external_function_parameters(
3351 array(
3352 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
3353 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
3354 )
3355 );
3356 }
3357
3358 /**
3359 * Deletes a conversation.
3360 *
fa024820 3361 * @deprecated since 3.6
dec0cd99
MN
3362 * @param int $userid The user id of who we want to delete the conversation for
3363 * @param int $otheruserid The user id of the other user in the conversation
3364 * @return array
3365 * @throws moodle_exception
3366 * @since 3.2
3367 */
3368 public static function delete_conversation($userid, $otheruserid) {
3369 global $CFG;
3370
3371 // Check if private messaging between users is allowed.
3372 if (empty($CFG->messaging)) {
3373 throw new moodle_exception('disabled', 'message');
3374 }
3375
3376 // Warnings array, it can be empty at the end but is mandatory.
3377 $warnings = array();
3378
3379 // Validate params.
3380 $params = array(
3381 'userid' => $userid,
3382 'otheruserid' => $otheruserid,
3383 );
3384 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
3385
3386 // Validate context.
3387 $context = context_system::instance();
3388 self::validate_context($context);
3389
3390 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3391 core_user::require_active_user($user);
3392
bb650761 3393 if (!$conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']])) {
15663b0b
MN
3394 return [];
3395 }
3396
3397 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) {
3398 \core_message\api::delete_conversation_by_id($user->id, $conversationid);
263ad984 3399 $status = true;
dec0cd99
MN
3400 } else {
3401 throw new moodle_exception('You do not have permission to delete messages');
3402 }
3403
3404 $results = array(
3405 'status' => $status,
3406 'warnings' => $warnings
3407 );
3408
3409 return $results;
3410 }
3411
3412 /**
3413 * Returns description of method result value.
3414 *
fa024820 3415 * @deprecated since 3.6
dec0cd99
MN
3416 * @return external_description
3417 * @since 3.2
3418 */
3419 public static function delete_conversation_returns() {
3420 return new external_single_structure(
3421 array(
3422 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
3423 'warnings' => new external_warnings()
3424 )
3425 );
3426 }
3427
fa024820
MN
3428 /**
3429 * Marking the method as deprecated.
3430 *
3431 * @return bool
3432 */
3433 public static function delete_conversation_is_deprecated() {
3434 return true;
3435 }
3436
26f39c88
MN
3437 /**
3438 * Returns description of method parameters.
3439 *
3440 * @return external_function_parameters
3441 * @since 3.6
3442 */
60b67bbc 3443 public static function delete_conversations_by_id_parameters() {
26f39c88
MN
3444 return new external_function_parameters(
3445 array(
3446 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
60b67bbc
MN
3447 'conversationids' => new external_multiple_structure(
3448 new external_value(PARAM_INT, 'The id of the conversation'),
3449 'List of conversation IDs'
3450 ),
26f39c88
MN
3451 )
3452 );
3453 }
3454
3455 /**
3456 * Deletes a conversation.
3457 *
3458 * @param int $userid The user id of who we want to delete the conversation for
60b67bbc 3459 * @param int[] $conversationids The ids of the conversations
26f39c88
MN
3460 * @return array
3461 * @throws moodle_exception
3462 * @since 3.6
3463 */