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