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