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