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