MDL-63547 core_message: deprecate delete_conversation web service
[moodle.git] / message / externallib.php
CommitLineData
a623b6b8 1<?php
a623b6b8
JM
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
4615817d 17
a623b6b8
JM
18/**
19 * External message API
20 *
6fbd60ef 21 * @package core_message
4615817d
JM
22 * @category external
23 * @copyright 2011 Jerome Mouneyrac
a623b6b8
JM
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
4615817d 26
e71687ba
JL
27defined('MOODLE_INTERNAL') || die();
28
a623b6b8 29require_once("$CFG->libdir/externallib.php");
705afe6f 30require_once($CFG->dirroot . "/message/lib.php");
a623b6b8 31
5d1017e1 32/**
4615817d 33 * Message external functions
6fbd60ef
AD
34 *
35 * @package core_message
4615817d
JM
36 * @category external
37 * @copyright 2011 Jerome Mouneyrac
75e4f98c 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4615817d 39 * @since Moodle 2.2
5d1017e1
JM
40 */
41class core_message_external extends external_api {
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
0d203bbf
MN
747 if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) {
748 $warning[] = [
749 'item' => 'user',
750 'itemid' => $params['requesteduserid'],
751 'warningcode' => 'cannotcreatecontactrequest',
752 'message' => 'You are unable to create a contact request for this user'
753 ];
754 return $warning;
755 }
756
52284186
MN
757 if (!\core_message\api::does_contact_request_exist($params['userid'], $params['requesteduserid'])) {
758 \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']);
759 }
760
761 return [];
762 }
763
764 /**
765 * Creates a contact request return description.
766 *
767 * @return external_description
768 */
769 public static function create_contact_request_returns() {
770 return new external_warnings();
771 }
772
773 /**
774 * Confirm a contact request parameters description.
775 *
776 * @return external_function_parameters
777 */
778 public static function confirm_contact_request_parameters() {
779 return new external_function_parameters(
780 [
781 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
782 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
783 ]
784 );
785 }
786
787 /**
788 * Confirm a contact request.
789 *
790 * @param int $userid The id of the user who is creating the contact request
791 * @param int $requesteduserid The id of the user being requested
792 */
793 public static function confirm_contact_request(int $userid, int $requesteduserid) {
794 global $CFG, $USER;
795
796 // Check if messaging is enabled.
797 if (empty($CFG->messaging)) {
798 throw new moodle_exception('disabled', 'message');
799 }
800
801 // Validate context.
802 $context = context_system::instance();
803 self::validate_context($context);
804
805 $capability = 'moodle/site:manageallmessaging';
806 if (($USER->id != $requesteduserid) && !has_capability($capability, $context)) {
807 throw new required_capability_exception($context, $capability, 'nopermissions', '');
808 }
809
810 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
811 $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params);
812
813 \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']);
814
815 return [];
816 }
817
818 /**
819 * Confirm a contact request return description.
820 *
821 * @return external_description
822 */
823 public static function confirm_contact_request_returns() {
824 return new external_warnings();
825 }
826
827 /**
828 * Declines a contact request parameters description.
829 *
830 * @return external_function_parameters
831 */
832 public static function decline_contact_request_parameters() {
833 return new external_function_parameters(
834 [
835 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
836 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
837 ]
838 );
839 }
840
841 /**
842 * Declines a contact request.
843 *
844 * @param int $userid The id of the user who is creating the contact request
845 * @param int $requesteduserid The id of the user being requested
846 */
847 public static function decline_contact_request(int $userid, int $requesteduserid) {
848 global $CFG, $USER;
849
850 // Check if messaging is enabled.
851 if (empty($CFG->messaging)) {
852 throw new moodle_exception('disabled', 'message');
853 }
854
855 // Validate context.
856 $context = context_system::instance();
857 self::validate_context($context);
858
859 $capability = 'moodle/site:manageallmessaging';
860 if (($USER->id != $requesteduserid) && !has_capability($capability, $context)) {
861 throw new required_capability_exception($context, $capability, 'nopermissions', '');
862 }
863
864 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
865 $params = self::validate_parameters(self::decline_contact_request_parameters(), $params);
866
867 \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']);
868
869 return [];
870 }
871
872 /**
873 * Declines a contact request return description.
874 *
875 * @return external_description
876 */
877 public static function decline_contact_request_returns() {
878 return new external_warnings();
879 }
880
a3e3a3a1
MN
881 /**
882 * Return the structure of a message area contact.
883 *
884 * @return external_single_structure
885 * @since Moodle 3.2
886 */
887 private static function get_messagearea_contact_structure() {
888 return new external_single_structure(
889 array(
890 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
891 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
892 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
893 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
5bf0ff27 894 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
89a70ba1 895 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
a3e3a3a1
MN
896 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
897 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
cb805753 898 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
a3e3a3a1
MN
899 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
900 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
dd0c1403 901 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
a3e3a3a1
MN
902 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
903 VALUE_DEFAULT, null),
904 )
905 );
906 }
907
94e1db61
MN
908 /**
909 * Return the structure of a message area message.
910 *
911 * @return external_single_structure
912 * @since Moodle 3.2
913 */
914 private static function get_messagearea_message_structure() {
915 return new external_single_structure(
916 array(
917 'id' => new external_value(PARAM_INT, 'The id of the message'),
89a70ba1
MN
918 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
919 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
94e1db61
MN
920 'text' => new external_value(PARAM_RAW, 'The text of the message'),
921 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
922 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
923 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
924 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
fb1469d8 925 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
94e1db61
MN
926 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
927 )
928 );
929 }
930
cd03b8d7 931 /**
48e8bdba 932 * Get messagearea search users in course parameters.
cd03b8d7
MN
933 *
934 * @return external_function_parameters
935 * @since 3.2
936 */
48e8bdba 937 public static function data_for_messagearea_search_users_in_course_parameters() {
cd03b8d7
MN
938 return new external_function_parameters(
939 array(
940 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
941 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
942 'search' => new external_value(PARAM_RAW, 'The string being searched'),
943 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
944 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
945 )
946 );
947 }
948
949 /**
48e8bdba 950 * Get messagearea search users in course results.
cd03b8d7
MN
951 *
952 * @param int $userid The id of the user who is performing the search
953 * @param int $courseid The id of the course
954 * @param string $search The string being searched
955 * @param int $limitfrom
956 * @param int $limitnum
957 * @return stdClass
958 * @throws moodle_exception
959 * @since 3.2
960 */
48e8bdba 961 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
de55cb1b 962 $limitnum = 0) {
837941e9 963 global $CFG, $PAGE, $USER;
cd03b8d7
MN
964
965 // Check if messaging is enabled.
837941e9 966 if (empty($CFG->messaging)) {
cd03b8d7
MN
967 throw new moodle_exception('disabled', 'message');
968 }
969
837941e9
MN
970 $systemcontext = context_system::instance();
971
cd03b8d7
MN
972 $params = array(
973 'userid' => $userid,
974 'courseid' => $courseid,
975 'search' => $search,
976 'limitfrom' => $limitfrom,
977 'limitnum' => $limitnum
978 );
48e8bdba 979 self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
837941e9 980 self::validate_context($systemcontext);
cd03b8d7 981
837941e9
MN
982 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
983 throw new moodle_exception('You do not have permission to perform this action.');
984 }
cd03b8d7 985
de55cb1b
MN
986 $users = \core_message\api::search_users_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
987 $results = new \core_message\output\messagearea\user_search_results($users);
cd03b8d7
MN
988
989 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 990 return $results->export_for_template($renderer);
cd03b8d7
MN
991 }
992
993 /**
48e8bdba 994 * Get messagearea search users in course returns.
cd03b8d7
MN
995 *
996 * @return external_single_structure
997 * @since 3.2
998 */
48e8bdba 999 public static function data_for_messagearea_search_users_in_course_returns() {
cd03b8d7
MN
1000 return new external_single_structure(
1001 array(
cd03b8d7 1002 'contacts' => new external_multiple_structure(
a3e3a3a1 1003 self::get_messagearea_contact_structure()
cd03b8d7
MN
1004 ),
1005 )
1006 );
1007 }
1008
1009 /**
48e8bdba 1010 * Get messagearea search users parameters.
cd03b8d7
MN
1011 *
1012 * @return external_function_parameters
1013 * @since 3.2
1014 */
48e8bdba 1015 public static function data_for_messagearea_search_users_parameters() {
cd03b8d7
MN
1016 return new external_function_parameters(
1017 array(
1018 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1019 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1020 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1021 )
1022 );
1023 }
1024
1025 /**
48e8bdba 1026 * Get messagearea search users results.
cd03b8d7
MN
1027 *
1028 * @param int $userid The id of the user who is performing the search
1029 * @param string $search The string being searched
1030 * @param int $limitnum
1031 * @return stdClass
1032 * @throws moodle_exception
1033 * @since 3.2
1034 */
48e8bdba 1035 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
837941e9 1036 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1037
1038 // Check if messaging is enabled.
837941e9 1039 if (empty($CFG->messaging)) {
cd03b8d7
MN
1040 throw new moodle_exception('disabled', 'message');
1041 }
1042
837941e9
MN
1043 $systemcontext = context_system::instance();
1044
cd03b8d7
MN
1045 $params = array(
1046 'userid' => $userid,
1047 'search' => $search,
1048 'limitnum' => $limitnum
1049 );
48e8bdba 1050 self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
837941e9 1051 self::validate_context($systemcontext);
cd03b8d7 1052
837941e9
MN
1053 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1054 throw new moodle_exception('You do not have permission to perform this action.');
1055 }
cd03b8d7 1056
de55cb1b
MN
1057 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($userid, $search, $limitnum);
1058 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
cd03b8d7
MN
1059
1060 $renderer = $PAGE->get_renderer('core_message');
1061 return $search->export_for_template($renderer);
1062 }
1063
1064 /**
48e8bdba 1065 * Get messagearea search users returns.
cd03b8d7
MN
1066 *
1067 * @return external_single_structure
1068 * @since 3.2
1069 */
48e8bdba 1070 public static function data_for_messagearea_search_users_returns() {
cd03b8d7
MN
1071 return new external_single_structure(
1072 array(
cd03b8d7 1073 'contacts' => new external_multiple_structure(
a3e3a3a1 1074 self::get_messagearea_contact_structure()
cd03b8d7 1075 ),
cd03b8d7
MN
1076 'courses' => new external_multiple_structure(
1077 new external_single_structure(
1078 array(
1079 'id' => new external_value(PARAM_INT, 'The course id'),
7597ab0b
AA
1080 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
1081 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
cd03b8d7
MN
1082 )
1083 )
1084 ),
cd03b8d7 1085 'noncontacts' => new external_multiple_structure(
a3e3a3a1 1086 self::get_messagearea_contact_structure()
cd03b8d7
MN
1087 )
1088 )
1089 );
1090 }
1091
1092 /**
1093 * Get messagearea search messages parameters.
1094 *
1095 * @return external_function_parameters
1096 * @since 3.2
1097 */
1098 public static function data_for_messagearea_search_messages_parameters() {
1099 return new external_function_parameters(
1100 array(
1101 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1102 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1103 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1104 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1105 )
1106 );
1107 }
1108
1109 /**
1110 * Get messagearea search messages results.
1111 *
1112 * @param int $userid The id of the user who is performing the search
1113 * @param string $search The string being searched
1114 * @param int $limitfrom
1115 * @param int $limitnum
1116 * @return stdClass
1117 * @throws moodle_exception
1118 * @since 3.2
1119 */
1120 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
837941e9 1121 global $CFG, $PAGE, $USER;
cd03b8d7
MN
1122
1123 // Check if messaging is enabled.
837941e9 1124 if (empty($CFG->messaging)) {
cd03b8d7
MN
1125 throw new moodle_exception('disabled', 'message');
1126 }
1127
837941e9
MN
1128 $systemcontext = context_system::instance();
1129
cd03b8d7
MN
1130 $params = array(
1131 'userid' => $userid,
1132 'search' => $search,
1133 'limitfrom' => $limitfrom,
1134 'limitnum' => $limitnum
1135
1136 );
1137 self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
837941e9 1138 self::validate_context($systemcontext);
cd03b8d7 1139
837941e9
MN
1140 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1141 throw new moodle_exception('You do not have permission to perform this action.');
1142 }
cd03b8d7 1143
de55cb1b
MN
1144 $messages = \core_message\api::search_messages($userid, $search, $limitfrom, $limitnum);
1145 $results = new \core_message\output\messagearea\message_search_results($messages);
cd03b8d7
MN
1146
1147 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 1148 return $results->export_for_template($renderer);
cd03b8d7
MN
1149 }
1150
1151 /**
1152 * Get messagearea search messages returns.
1153 *
1154 * @return external_single_structure
1155 * @since 3.2
1156 */
1157 public static function data_for_messagearea_search_messages_returns() {
1158 return new external_single_structure(
1159 array(
cd03b8d7 1160 'contacts' => new external_multiple_structure(
a3e3a3a1 1161 self::get_messagearea_contact_structure()
cd03b8d7
MN
1162 )
1163 )
1164 );
1165 }
1166
9aa012b5 1167 /**
49aaadc3 1168 * The messagearea conversations parameters.
9aa012b5
MN
1169 *
1170 * @return external_function_parameters
49aaadc3 1171 * @since 3.2
9aa012b5
MN
1172 */
1173 public static function data_for_messagearea_conversations_parameters() {
1174 return new external_function_parameters(
1175 array(
1176 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1177 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1178 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1179 )
1180 );
1181 }
1182
1183 /**
1184 * Get messagearea conversations.
1185 *
1186 * @param int $userid The id of the user who we are viewing conversations for
1187 * @param int $limitfrom
1188 * @param int $limitnum
49aaadc3
MN
1189 * @return stdClass
1190 * @throws moodle_exception
1191 * @since 3.2
9aa012b5
MN
1192 */
1193 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 1194 global $CFG, $PAGE, $USER;
9aa012b5
MN
1195
1196 // Check if messaging is enabled.
837941e9 1197 if (empty($CFG->messaging)) {
9aa012b5
MN
1198 throw new moodle_exception('disabled', 'message');
1199 }
1200
837941e9
MN
1201 $systemcontext = context_system::instance();
1202
9aa012b5
MN
1203 $params = array(
1204 'userid' => $userid,
1205 'limitfrom' => $limitfrom,
1206 'limitnum' => $limitnum
1207 );
1208 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
837941e9 1209 self::validate_context($systemcontext);
9aa012b5 1210
837941e9
MN
1211 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1212 throw new moodle_exception('You do not have permission to perform this action.');
1213 }
9aa012b5 1214
de55cb1b
MN
1215 $conversations = \core_message\api::get_conversations($userid, $limitfrom, $limitnum);
1216 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
9aa012b5
MN
1217
1218 $renderer = $PAGE->get_renderer('core_message');
de55cb1b 1219 return $conversations->export_for_template($renderer);
9aa012b5
MN
1220 }
1221
1222 /**
49aaadc3 1223 * The messagearea conversations return structure.
9aa012b5 1224 *
49aaadc3
MN
1225 * @return external_single_structure
1226 * @since 3.2
9aa012b5
MN
1227 */
1228 public static function data_for_messagearea_conversations_returns() {
49aaadc3 1229 return new external_single_structure(
9aa012b5 1230 array(
9aa012b5 1231 'contacts' => new external_multiple_structure(
a3e3a3a1 1232 self::get_messagearea_contact_structure()
9aa012b5
MN
1233 )
1234 )
1235 );
1236 }
1237
1238 /**
49aaadc3 1239 * The messagearea contacts return parameters.
9aa012b5
MN
1240 *
1241 * @return external_function_parameters
49aaadc3 1242 * @since 3.2
9aa012b5
MN
1243 */
1244 public static function data_for_messagearea_contacts_parameters() {
1245 return self::data_for_messagearea_conversations_parameters();
1246 }
1247
1248 /**
1249 * Get messagearea contacts parameters.
1250 *
1251 * @param int $userid The id of the user who we are viewing conversations for
1252 * @param int $limitfrom
1253 * @param int $limitnum
49aaadc3
MN
1254 * @return stdClass
1255 * @throws moodle_exception
1256 * @since 3.2
9aa012b5
MN
1257 */
1258 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 1259 global $CFG, $PAGE, $USER;
9aa012b5
MN
1260
1261 // Check if messaging is enabled.
837941e9 1262 if (empty($CFG->messaging)) {
9aa012b5
MN
1263 throw new moodle_exception('disabled', 'message');
1264 }
1265
837941e9
MN
1266 $systemcontext = context_system::instance();
1267
9aa012b5
MN
1268 $params = array(
1269 'userid' => $userid,
1270 'limitfrom' => $limitfrom,
1271 'limitnum' => $limitnum
1272 );
1273 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
837941e9 1274 self::validate_context($systemcontext);
9aa012b5 1275
837941e9
MN
1276 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1277 throw new moodle_exception('You do not have permission to perform this action.');
1278 }
9aa012b5
MN
1279
1280 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
de55cb1b 1281 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
9aa012b5
MN
1282
1283 $renderer = $PAGE->get_renderer('core_message');
1284 return $contacts->export_for_template($renderer);
1285 }
1286
1287 /**
49aaadc3 1288 * The messagearea contacts return structure.
9aa012b5 1289 *
49aaadc3
MN
1290 * @return external_single_structure
1291 * @since 3.2
9aa012b5
MN
1292 */
1293 public static function data_for_messagearea_contacts_returns() {
1294 return self::data_for_messagearea_conversations_returns();
1295 }
1296
3cd13828 1297 /**
49aaadc3 1298 * The messagearea messages parameters.
3cd13828
MN
1299 *
1300 * @return external_function_parameters
49aaadc3 1301 * @since 3.2
3cd13828
MN
1302 */
1303 public static function data_for_messagearea_messages_parameters() {
1304 return new external_function_parameters(
1305 array(
1306 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1307 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1308 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
8ec78c48
MN
1309 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1310 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
ffd7798c 1311 'timefrom' => new external_value(PARAM_INT,
fb1469d8 1312 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
3cd13828
MN
1313 )
1314 );
1315 }
1316
1317 /**
1318 * Get messagearea messages.
1319 *
1320 * @param int $currentuserid The current user's id
1321 * @param int $otheruserid The other user's id
1322 * @param int $limitfrom
1323 * @param int $limitnum
8ec78c48 1324 * @param boolean $newest
49aaadc3
MN
1325 * @return stdClass
1326 * @throws moodle_exception
1327 * @since 3.2
3cd13828 1328 */
7b55aaa1 1329 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
ffd7798c 1330 $newest = false, $timefrom = 0) {
837941e9 1331 global $CFG, $PAGE, $USER;
3cd13828
MN
1332
1333 // Check if messaging is enabled.
837941e9 1334 if (empty($CFG->messaging)) {
3cd13828
MN
1335 throw new moodle_exception('disabled', 'message');
1336 }
1337
837941e9
MN
1338 $systemcontext = context_system::instance();
1339
3cd13828
MN
1340 $params = array(
1341 'currentuserid' => $currentuserid,
1342 'otheruserid' => $otheruserid,
1343 'limitfrom' => $limitfrom,
8ec78c48 1344 'limitnum' => $limitnum,
fb1469d8 1345 'newest' => $newest,
ffd7798c 1346 'timefrom' => $timefrom,
3cd13828
MN
1347 );
1348 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
837941e9 1349 self::validate_context($systemcontext);
3cd13828 1350
837941e9
MN
1351 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1352 throw new moodle_exception('You do not have permission to perform this action.');
1353 }
3cd13828 1354
8ec78c48
MN
1355 if ($newest) {
1356 $sort = 'timecreated DESC';
1357 } else {
1358 $sort = 'timecreated ASC';
1359 }
fb1469d8
RW
1360
1361 // We need to enforce a one second delay on messages to avoid race conditions of current
1362 // messages still being sent.
1363 //
1364 // There is a chance that we could request messages before the current time's
1365 // second has elapsed and while other messages are being sent in that same second. In which
1366 // case those messages will be lost.
1367 //
1368 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
ffd7798c
MN
1369 if (!empty($timefrom)) {
1370 $timeto = time() - 1;
fb1469d8 1371 } else {
ffd7798c 1372 $timeto = 0;
fb1469d8
RW
1373 }
1374
1375 // No requesting messages from the current time, as stated above.
ffd7798c
MN
1376 if ($timefrom == time()) {
1377 $messages = [];
fb1469d8
RW
1378 } else {
1379 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom,
ffd7798c 1380 $limitnum, $sort, $timefrom, $timeto);
fb1469d8
RW
1381 }
1382
de55cb1b 1383 $messages = new \core_message\output\messagearea\messages($currentuserid, $otheruserid, $messages);
3cd13828
MN
1384
1385 $renderer = $PAGE->get_renderer('core_message');
1386 return $messages->export_for_template($renderer);
1387 }
1388
1389 /**
49aaadc3 1390 * The messagearea messages return structure.
3cd13828 1391 *
49aaadc3
MN
1392 * @return external_single_structure
1393 * @since 3.2
3cd13828
MN
1394 */
1395 public static function data_for_messagearea_messages_returns() {
49aaadc3 1396 return new external_single_structure(
3cd13828 1397 array(
7b55aaa1
MN
1398 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
1399 the messages on behalf of?'),
3cd13828
MN
1400 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1401 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1402 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
cb805753 1403 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
bf58081d 1404 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
3cd13828 1405 'messages' => new external_multiple_structure(
94e1db61 1406 self::get_messagearea_message_structure()
26dca05d
JP
1407 ),
1408 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
3cd13828
MN
1409 )
1410 );
1411 }
1412
c060cd49 1413 /**
49aaadc3 1414 * The get most recent message return parameters.
c060cd49
MN
1415 *
1416 * @return external_function_parameters
49aaadc3 1417 * @since 3.2
c060cd49
MN
1418 */
1419 public static function data_for_messagearea_get_most_recent_message_parameters() {
1420 return new external_function_parameters(
1421 array(
1422 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1423 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1424 )
1425 );
1426 }
1427
1428 /**
1429 * Get the most recent message in a conversation.
1430 *
1431 * @param int $currentuserid The current user's id
1432 * @param int $otheruserid The other user's id
49aaadc3
MN
1433 * @return stdClass
1434 * @throws moodle_exception
1435 * @since 3.2
c060cd49
MN
1436 */
1437 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
837941e9 1438 global $CFG, $PAGE, $USER;
c060cd49
MN
1439
1440 // Check if messaging is enabled.
837941e9 1441 if (empty($CFG->messaging)) {
c060cd49
MN
1442 throw new moodle_exception('disabled', 'message');
1443 }
1444
837941e9
MN
1445 $systemcontext = context_system::instance();
1446
c060cd49
MN
1447 $params = array(
1448 'currentuserid' => $currentuserid,
1449 'otheruserid' => $otheruserid
1450 );
1451 self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
837941e9 1452 self::validate_context($systemcontext);
c060cd49 1453
837941e9
MN
1454 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1455 throw new moodle_exception('You do not have permission to perform this action.');
1456 }
c060cd49
MN
1457
1458 $message = \core_message\api::get_most_recent_message($currentuserid, $otheruserid);
de55cb1b 1459 $message = new \core_message\output\messagearea\message($message);
c060cd49
MN
1460
1461 $renderer = $PAGE->get_renderer('core_message');
1462 return $message->export_for_template($renderer);
1463 }
1464
1465 /**
49aaadc3 1466 * The get most recent message return structure.
c060cd49
MN
1467 *
1468 * @return external_single_structure
49aaadc3 1469 * @since 3.2
c060cd49
MN
1470 */
1471 public static function data_for_messagearea_get_most_recent_message_returns() {
94e1db61 1472 return self::get_messagearea_message_structure();
c060cd49
MN
1473 }
1474
c6e97f54
MN
1475 /**
1476 * The get profile parameters.
1477 *
1478 * @return external_function_parameters
49aaadc3 1479 * @since 3.2
c6e97f54
MN
1480 */
1481 public static function data_for_messagearea_get_profile_parameters() {
1482 return new external_function_parameters(
1483 array(
1484 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1485 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
1486 )
1487 );
1488 }
1489
1490 /**
1491 * Get the profile information for a contact.
1492 *
1493 * @param int $currentuserid The current user's id
1494 * @param int $otheruserid The id of the user whose profile we are viewing
49aaadc3
MN
1495 * @return stdClass
1496 * @throws moodle_exception
1497 * @since 3.2
c6e97f54
MN
1498 */
1499 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
837941e9 1500 global $CFG, $PAGE, $USER;
c6e97f54
MN
1501
1502 // Check if messaging is enabled.
837941e9 1503 if (empty($CFG->messaging)) {
c6e97f54
MN
1504 throw new moodle_exception('disabled', 'message');
1505 }
1506
837941e9
MN
1507 $systemcontext = context_system::instance();
1508
c6e97f54
MN
1509 $params = array(
1510 'currentuserid' => $currentuserid,
1511 'otheruserid' => $otheruserid
1512 );
1513 self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
837941e9 1514 self::validate_context($systemcontext);
c6e97f54 1515
837941e9
MN
1516 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1517 throw new moodle_exception('You do not have permission to perform this action.');
1518 }
c6e97f54
MN
1519
1520 $profile = \core_message\api::get_profile($currentuserid, $otheruserid);
de55cb1b 1521 $profile = new \core_message\output\messagearea\profile($profile);
c6e97f54
MN
1522
1523 $renderer = $PAGE->get_renderer('core_message');
1524 return $profile->export_for_template($renderer);
1525 }
1526
1527 /**
49aaadc3 1528 * The get profile return structure.
c6e97f54
MN
1529 *
1530 * @return external_single_structure
49aaadc3 1531 * @since 3.2
c6e97f54
MN
1532 */
1533 public static function data_for_messagearea_get_profile_returns() {
1534 return new external_single_structure(
1535 array(
de55cb1b 1536 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
c6e97f54 1537 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
cc22b515 1538 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
c6e97f54
MN
1539 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
1540 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1541 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1542 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
cb805753 1543 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
bf58081d 1544 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
c6e97f54
MN
1545 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
1546 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
1547 )
1548 );
1549 }
1550
d6731600
FM
1551 /**
1552 * Get contacts parameters description.
1553 *
1554 * @return external_function_parameters
5bcfd504 1555 * @since Moodle 2.5
d6731600
FM
1556 */
1557 public static function get_contacts_parameters() {
1558 return new external_function_parameters(array());
1559 }
1560
1561 /**
1562 * Get contacts.
1563 *
d6731600 1564 * @return external_description
5bcfd504 1565 * @since Moodle 2.5
d6731600
FM
1566 */
1567 public static function get_contacts() {
883ce421 1568 global $CFG, $PAGE, $USER;
436bbf89
DM
1569
1570 // Check if messaging is enabled.
837941e9 1571 if (empty($CFG->messaging)) {
436bbf89
DM
1572 throw new moodle_exception('disabled', 'message');
1573 }
1574
d6731600
FM
1575 require_once($CFG->dirroot . '/user/lib.php');
1576
883ce421
MN
1577 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
1578 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id);
1579 foreach ($contacts as $contact) {
1580 // Set the mode.
1581 $mode = 'offline';
1582 if (\core_message\helper::is_online($contact->lastaccess)) {
1583 $mode = 'online';
1584 }
1585
1586 $newcontact = array(
1587 'id' => $contact->id,
1588 'fullname' => fullname($contact),
1589 'unread' => $contact->messagecount
1590 );
1591
1592 $userpicture = new user_picture($contact);
1593 $userpicture->size = 1; // Size f1.
1594 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1595 $userpicture->size = 0; // Size f2.
1596 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1597
1598 $allcontacts[$mode][$contact->id] = $newcontact;
1599 }
1600
1601 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id);
1602 foreach ($strangers as $contact) {
1603 $newcontact = array(
1604 'id' => $contact->id,
1605 'fullname' => fullname($contact),
1606 'unread' => $contact->messagecount
1607 );
1608
1609 $userpicture = new user_picture($contact);
1610 $userpicture->size = 1; // Size f1.
1611 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1612 $userpicture->size = 0; // Size f2.
1613 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600 1614
883ce421
MN
1615 $allcontacts['strangers'][$contact->id] = $newcontact;
1616 }
d6731600 1617
883ce421
MN
1618 // Add noreply user and support user to the list, if they don't exist.
1619 $supportuser = core_user::get_support_user();
1620 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) {
1621 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
1622 if ($supportuser->messagecount > 0) {
1623 $supportuser->fullname = fullname($supportuser);
1624 $supportuser->unread = $supportuser->messagecount;
1625 $allcontacts['strangers'][$supportuser->id] = $supportuser;
d6731600
FM
1626 }
1627 }
883ce421
MN
1628
1629 $noreplyuser = core_user::get_noreply_user();
1630 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) {
1631 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
1632 if ($noreplyuser->messagecount > 0) {
1633 $noreplyuser->fullname = fullname($noreplyuser);
1634 $noreplyuser->unread = $noreplyuser->messagecount;
1635 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser;
1636 }
1637 }
1638
d6731600
FM
1639 return $allcontacts;
1640 }
1641
1642 /**
1643 * Get contacts return description.
1644 *
1645 * @return external_description
5bcfd504 1646 * @since Moodle 2.5
d6731600
FM
1647 */
1648 public static function get_contacts_returns() {
1649 return new external_single_structure(
1650 array(
1651 'online' => new external_multiple_structure(
1652 new external_single_structure(
1653 array(
1654 'id' => new external_value(PARAM_INT, 'User ID'),
1655 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1656 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1657 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1658 'unread' => new external_value(PARAM_INT, 'Unread message count')
1659 )
1660 ),
1661 'List of online contacts'
1662 ),
1663 'offline' => new external_multiple_structure(
1664 new external_single_structure(
1665 array(
1666 'id' => new external_value(PARAM_INT, 'User ID'),
1667 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1668 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1669 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1670 'unread' => new external_value(PARAM_INT, 'Unread message count')
1671 )
1672 ),
1673 'List of offline contacts'
1674 ),
1675 'strangers' => new external_multiple_structure(
1676 new external_single_structure(
1677 array(
1678 'id' => new external_value(PARAM_INT, 'User ID'),
1679 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1680 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1681 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1682 'unread' => new external_value(PARAM_INT, 'Unread message count')
1683 )
1684 ),
1685 'List of users that are not in the user\'s contact list but have sent a message'
1686 )
1687 )
1688 );
1689 }
1690
1691 /**
1692 * Search contacts parameters description.
1693 *
1694 * @return external_function_parameters
5bcfd504 1695 * @since Moodle 2.5
d6731600
FM
1696 */
1697 public static function search_contacts_parameters() {
1698 return new external_function_parameters(
1699 array(
1700 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
1701 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
1702 VALUE_DEFAULT, false)
1703 )
1704 );
1705 }
1706
1707 /**
1708 * Search contacts.
1709 *
1710 * @param string $searchtext query string.
1711 * @param bool $onlymycourses limit the search to the user's courses only.
1712 * @return external_description
5bcfd504 1713 * @since Moodle 2.5
d6731600
FM
1714 */
1715 public static function search_contacts($searchtext, $onlymycourses = false) {
d85bedf7 1716 global $CFG, $USER, $PAGE;
11d83ab3 1717 require_once($CFG->dirroot . '/user/lib.php');
436bbf89
DM
1718
1719 // Check if messaging is enabled.
837941e9 1720 if (empty($CFG->messaging)) {
436bbf89
DM
1721 throw new moodle_exception('disabled', 'message');
1722 }
1723
d6731600
FM
1724 require_once($CFG->libdir . '/enrollib.php');
1725
1726 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1727 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
1728
1729 // Extra validation, we do not allow empty queries.
1730 if ($params['searchtext'] === '') {
1731 throw new moodle_exception('querystringcannotbeempty');
1732 }
1733
1734 $courseids = array();
1735 if ($params['onlymycourses']) {
1736 $mycourses = enrol_get_my_courses(array('id'));
1737 foreach ($mycourses as $mycourse) {
1738 $courseids[] = $mycourse->id;
1739 }
1740 } else {
1741 $courseids[] = SITEID;
1742 }
1743
1744 // Retrieving the users matching the query.
1745 $users = message_search_users($courseids, $params['searchtext']);
1746 $results = array();
1747 foreach ($users as $user) {
1748 $results[$user->id] = $user;
1749 }
1750
1751 // Reorganising information.
1752 foreach ($results as &$user) {
1753 $newuser = array(
1754 'id' => $user->id,
1755 'fullname' => fullname($user)
1756 );
1757
1758 // Avoid undefined property notice as phone not specified.
1759 $user->phone1 = null;
1760 $user->phone2 = null;
1761
d85bedf7
JL
1762 $userpicture = new user_picture($user);
1763 $userpicture->size = 1; // Size f1.
1764 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1765 $userpicture->size = 0; // Size f2.
1766 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
1767
1768 $user = $newuser;
1769 }
1770
1771 return $results;
1772 }
1773
1774 /**
1775 * Search contacts return description.
1776 *
1777 * @return external_description
5bcfd504 1778 * @since Moodle 2.5
d6731600
FM
1779 */
1780 public static function search_contacts_returns() {
1781 return new external_multiple_structure(
1782 new external_single_structure(
1783 array(
1784 'id' => new external_value(PARAM_INT, 'User ID'),
1785 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1786 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1787 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
1788 )
1789 ),
1790 'List of contacts'
1791 );
1792 }
aff9da17
JL
1793
1794 /**
1795 * Get messages parameters description.
1796 *
1797 * @return external_function_parameters
193edf7f 1798 * @since 2.8
aff9da17
JL
1799 */
1800 public static function get_messages_parameters() {
1801 return new external_function_parameters(
1802 array(
6ff4464b 1803 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
127ef540
SH
1804 'useridfrom' => new external_value(
1805 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1806 VALUE_DEFAULT, 0),
1807 'type' => new external_value(
1808 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
1809 VALUE_DEFAULT, 'both'),
6ff4464b 1810 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
127ef540
SH
1811 'newestfirst' => new external_value(
1812 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1813 VALUE_DEFAULT, true),
aff9da17 1814 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
127ef540
SH
1815 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
1816 )
aff9da17
JL
1817 );
1818 }
1819
1820 /**
1821 * Get messages function implementation.
127ef540
SH
1822 *
1823 * @since 2.8
1824 * @throws invalid_parameter_exception
1825 * @throws moodle_exception
6ff4464b
JL
1826 * @param int $useridto the user id who received the message
1827 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
193edf7f 1828 * @param string $type type of message to return, expected values: notifications, conversations and both
aff9da17 1829 * @param bool $read true for retreiving read messages, false for unread
6ff4464b 1830 * @param bool $newestfirst true for ordering by newest first, false for oldest first
aff9da17
JL
1831 * @param int $limitfrom limit from
1832 * @param int $limitnum limit num
1833 * @return external_description
aff9da17 1834 */
193edf7f 1835 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
aff9da17 1836 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
127ef540 1837 global $CFG, $USER;
aff9da17
JL
1838
1839 $warnings = array();
1840
1841 $params = array(
1842 'useridto' => $useridto,
6ff4464b 1843 'useridfrom' => $useridfrom,
aff9da17
JL
1844 'type' => $type,
1845 'read' => $read,
aff9da17
JL
1846 'newestfirst' => $newestfirst,
1847 'limitfrom' => $limitfrom,
1848 'limitnum' => $limitnum
1849 );
1850
1851 $params = self::validate_parameters(self::get_messages_parameters(), $params);
1852
1853 $context = context_system::instance();
1854 self::validate_context($context);
1855
1856 $useridto = $params['useridto'];
6ff4464b 1857 $useridfrom = $params['useridfrom'];
aff9da17
JL
1858 $type = $params['type'];
1859 $read = $params['read'];
aff9da17
JL
1860 $newestfirst = $params['newestfirst'];
1861 $limitfrom = $params['limitfrom'];
1862 $limitnum = $params['limitnum'];
1863
1864 $allowedvalues = array('notifications', 'conversations', 'both');
1865 if (!in_array($type, $allowedvalues)) {
1866 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1867 'allowed values are: ' . implode(',', $allowedvalues));
1868 }
1869
1870 // Check if private messaging between users is allowed.
1871 if (empty($CFG->messaging)) {
1872 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
aff9da17
JL
1873 if ($type == "conversations") {
1874 throw new moodle_exception('disabled', 'message');
1875 }
1876 if ($type == "both") {
1877 $warning = array();
1878 $warning['item'] = 'message';
1879 $warning['itemid'] = $USER->id;
1880 $warning['warningcode'] = '1';
1881 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1882 Only notifications will be returned';
1883 $warnings[] = $warning;
1884 }
1885 }
1886
1887 if (!empty($useridto)) {
6ff4464b
JL
1888 if (core_user::is_real_user($useridto)) {
1889 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1890 } else {
1891 throw new moodle_exception('invaliduser');
1892 }
aff9da17
JL
1893 }
1894
1895 if (!empty($useridfrom)) {
1896 // We use get_user here because the from user can be the noreply or support user.
1897 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1898 }
1899
1900 // Check if the current user is the sender/receiver or just a privileged user.
1901 if ($useridto != $USER->id and $useridfrom != $USER->id and
1902 !has_capability('moodle/site:readallmessages', $context)) {
1903 throw new moodle_exception('accessdenied', 'admin');
1904 }
1905
127ef540 1906 // Which type of messages to retrieve.
193edf7f 1907 $notifications = -1;
aff9da17 1908 if ($type != 'both') {
193edf7f 1909 $notifications = ($type == 'notifications') ? 1 : 0;
aff9da17
JL
1910 }
1911
aff9da17 1912 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
193edf7f 1913 $sort = "mr.timecreated $orderdirection";
aff9da17 1914
193edf7f 1915 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
aff9da17
JL
1916 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1917
1918 // In some cases, we don't need to get the to/from user objects from the sql query.
1919 $userfromfullname = '';
1920 $usertofullname = '';
1921
1922 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1923 if (!empty($useridto)) {
1924 $usertofullname = fullname($userto, $canviewfullname);
1925 // The user from may or may not be filled.
1926 if (!empty($useridfrom)) {
1927 $userfromfullname = fullname($userfrom, $canviewfullname);
1928 }
1929 } else {
1930 // If the useridto field is empty, the useridfrom must be filled.
1931 $userfromfullname = fullname($userfrom, $canviewfullname);
1932 }
aff9da17
JL
1933 foreach ($messages as $mid => $message) {
1934
ea21d637 1935 // Do not return deleted messages.
883ce421
MN
1936 if (!$message->notification) {
1937 if (($useridto == $USER->id and $message->timeusertodeleted) or
ea21d637 1938 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
883ce421
MN
1939 unset($messages[$mid]);
1940 continue;
1941 }
ea21d637
JL
1942 }
1943
aff9da17
JL
1944 // We need to get the user from the query.
1945 if (empty($userfromfullname)) {
6ff4464b
JL
1946 // Check for non-reply and support users.
1947 if (core_user::is_real_user($message->useridfrom)) {
127ef540 1948 $user = new stdClass();
6ff4464b
JL
1949 $user = username_load_fields_from_object($user, $message, 'userfrom');
1950 $message->userfromfullname = fullname($user, $canviewfullname);
1951 } else {
1952 $user = core_user::get_user($message->useridfrom);
1953 $message->userfromfullname = fullname($user, $canviewfullname);
1954 }
aff9da17
JL
1955 } else {
1956 $message->userfromfullname = $userfromfullname;
1957 }
1958
1959 // We need to get the user from the query.
1960 if (empty($usertofullname)) {
127ef540 1961 $user = new stdClass();
aff9da17
JL
1962 $user = username_load_fields_from_object($user, $message, 'userto');
1963 $message->usertofullname = fullname($user, $canviewfullname);
1964 } else {
1965 $message->usertofullname = $usertofullname;
1966 }
1967
aff9da17 1968 $message->text = message_format_message_text($message);
aff9da17
JL
1969 $messages[$mid] = (array) $message;
1970 }
1971 }
1972
1973 $results = array(
1974 'messages' => $messages,
1975 'warnings' => $warnings
1976 );
1977
1978 return $results;
1979 }
1980
1981 /**
1982 * Get messages return description.
1983 *
6ff4464b 1984 * @return external_single_structure
193edf7f 1985 * @since 2.8
aff9da17
JL
1986 */
1987 public static function get_messages_returns() {
1988 return new external_single_structure(
1989 array(
1990 'messages' => new external_multiple_structure(
1991 new external_single_structure(
1992 array(
193edf7f 1993 'id' => new external_value(PARAM_INT, 'Message id'),
aff9da17
JL
1994 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1995 'useridto' => new external_value(PARAM_INT, 'User to id'),
1996 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1997 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1998 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
193edf7f 1999 'fullmessageformat' => new external_format_value('fullmessage'),
aff9da17
JL
2000 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
2001 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
2002 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
2003 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
2004 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
2005 'timecreated' => new external_value(PARAM_INT, 'Time created'),
2006 'timeread' => new external_value(PARAM_INT, 'Time read'),
2007 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
2008 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
2009 ), 'message'
2010 )
2011 ),
2012 'warnings' => new external_warnings()
2013 )
2014 );
3274d5ca
RW
2015 }
2016
3274d5ca
RW
2017 /**
2018 * Mark all notifications as read parameters description.
2019 *
2020 * @return external_function_parameters
2021 * @since 3.2
2022 */
2023 public static function mark_all_notifications_as_read_parameters() {
2024 return new external_function_parameters(
2025 array(
2026 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2027 'useridfrom' => new external_value(
2028 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2029 VALUE_DEFAULT, 0),
2030 )
2031 );
2032 }
2033
2034 /**
2035 * Mark all notifications as read function.
2036 *
2037 * @since 3.2
2038 * @throws invalid_parameter_exception
2039 * @throws moodle_exception
2040 * @param int $useridto the user id who received the message
2041 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2042 * @return external_description
2043 */
2044 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
837941e9 2045 global $USER;
3274d5ca
RW
2046
2047 $params = self::validate_parameters(
2048 self::mark_all_notifications_as_read_parameters(),
2049 array(
2050 'useridto' => $useridto,
2051 'useridfrom' => $useridfrom,
2052 )
2053 );
2054
2055 $context = context_system::instance();
2056 self::validate_context($context);
2057
2058 $useridto = $params['useridto'];
2059 $useridfrom = $params['useridfrom'];
2060
2061 if (!empty($useridto)) {
2062 if (core_user::is_real_user($useridto)) {
2063 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2064 } else {
2065 throw new moodle_exception('invaliduser');
2066 }
2067 }
2068
2069 if (!empty($useridfrom)) {
2070 // We use get_user here because the from user can be the noreply or support user.
2071 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2072 }
2073
2074 // Check if the current user is the sender/receiver or just a privileged user.
2075 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 2076 // The deleteanymessage cap seems more reasonable here than readallmessages.
3274d5ca
RW
2077 !has_capability('moodle/site:deleteanymessage', $context)) {
2078 throw new moodle_exception('accessdenied', 'admin');
2079 }
2080
74ad60bf 2081 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom);
3274d5ca
RW
2082
2083 return true;
2084 }
2085
2086 /**
2087 * Mark all notifications as read return description.
2088 *
2089 * @return external_single_structure
2090 * @since 3.2
2091 */
2092 public static function mark_all_notifications_as_read_returns() {
2093 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2094 }
2095
8c55bd6c
RW
2096 /**
2097 * Get unread conversations count parameters description.
2098 *
2099 * @return external_function_parameters
2100 * @since 3.2
2101 */
2102 public static function get_unread_conversations_count_parameters() {
2103 return new external_function_parameters(
2104 array(
2105 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2106 )
2107 );
2108 }
2109
2110 /**
2111 * Get unread messages count function.
2112 *
2113 * @since 3.2
2114 * @throws invalid_parameter_exception
2115 * @throws moodle_exception
2116 * @param int $useridto the user id who received the message
2117 * @return external_description
2118 */
2119 public static function get_unread_conversations_count($useridto) {
a2c7227a
SL
2120 global $USER, $CFG;
2121
2122 // Check if messaging is enabled.
2123 if (empty($CFG->messaging)) {
2124 throw new moodle_exception('disabled', 'message');
2125 }
8c55bd6c
RW
2126
2127 $params = self::validate_parameters(
2128 self::get_unread_conversations_count_parameters(),
2129 array('useridto' => $useridto)
2130 );
2131
2132 $context = context_system::instance();
2133 self::validate_context($context);
2134
2135 $useridto = $params['useridto'];
2136
2137 if (!empty($useridto)) {
2138 if (core_user::is_real_user($useridto)) {
2139 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2140 } else {
2141 throw new moodle_exception('invaliduser');
2142 }
2143 } else {
2144 $useridto = $USER->id;
2145 }
2146
2147 // Check if the current user is the receiver or just a privileged user.
2148 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
2149 throw new moodle_exception('accessdenied', 'admin');
2150 }
2151
79f6c36c 2152 return \core_message\api::count_unread_conversations($userto);
8c55bd6c
RW
2153 }
2154
2155 /**
2156 * Get unread conversations count return description.
2157 *
2158 * @return external_single_structure
2159 * @since 3.2
2160 */
2161 public static function get_unread_conversations_count_returns() {
2162 return new external_value(PARAM_INT, 'The count of unread messages for the user');
aff9da17
JL
2163 }
2164
60ab2e1b
JL
2165 /**
2166 * Get blocked users parameters description.
2167 *
2168 * @return external_function_parameters
2169 * @since 2.9
2170 */
2171 public static function get_blocked_users_parameters() {
2172 return new external_function_parameters(
2173 array(
2174 'userid' => new external_value(PARAM_INT,
2175 'the user whose blocked users we want to retrieve',
2176 VALUE_REQUIRED),
2177 )
2178 );
2179 }
2180
2181 /**
2182 * Retrieve a list of users blocked
2183 *
2184 * @param int $userid the user whose blocked users we want to retrieve
2185 * @return external_description
2186 * @since 2.9
2187 */
2188 public static function get_blocked_users($userid) {
d85bedf7 2189 global $CFG, $USER, $PAGE;
60ab2e1b
JL
2190
2191 // Warnings array, it can be empty at the end but is mandatory.
2192 $warnings = array();
2193
2194 // Validate params.
2195 $params = array(
2196 'userid' => $userid
2197 );
2198 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
2199 $userid = $params['userid'];
2200
2201 // Validate context.
2202 $context = context_system::instance();
2203 self::validate_context($context);
2204
2205 // Check if private messaging between users is allowed.
2206 if (empty($CFG->messaging)) {
2207 throw new moodle_exception('disabled', 'message');
2208 }
2209
4485f7c5
JL
2210 $user = core_user::get_user($userid, '*', MUST_EXIST);
2211 core_user::require_active_user($user);
60ab2e1b
JL
2212
2213 // Check if we have permissions for retrieve the information.
343ba16c
SL
2214 $capability = 'moodle/site:manageallmessaging';
2215 if (($USER->id != $userid) && !has_capability($capability, $context)) {
2216 throw new required_capability_exception($context, $capability, 'nopermissions', '');
60ab2e1b
JL
2217 }
2218
2219 // Now, we can get safely all the blocked users.
883ce421 2220 $users = \core_message\api::get_blocked_users($user->id);
60ab2e1b
JL
2221
2222 $blockedusers = array();
2223 foreach ($users as $user) {
2224 $newuser = array(
2225 'id' => $user->id,
2226 'fullname' => fullname($user),
2227 );
0b074e88 2228
d85bedf7
JL
2229 $userpicture = new user_picture($user);
2230 $userpicture->size = 1; // Size f1.
2231 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
60ab2e1b
JL
2232
2233 $blockedusers[] = $newuser;
2234 }
2235
2236 $results = array(
2237 'users' => $blockedusers,
2238 'warnings' => $warnings
2239 );
2240 return $results;
2241 }
2242
2243 /**
2244 * Get blocked users return description.
2245 *
2246 * @return external_single_structure
2247 * @since 2.9
2248 */
2249 public static function get_blocked_users_returns() {
2250 return new external_single_structure(
2251 array(
2252 'users' => new external_multiple_structure(
2253 new external_single_structure(
2254 array(
2255 'id' => new external_value(PARAM_INT, 'User ID'),
2256 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2257 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
2258 )
2259 ),
2260 'List of blocked users'
2261 ),
2262 'warnings' => new external_warnings()
2263 )
2264 );
2265 }
2266
31c474da
JL
2267 /**
2268 * Returns description of method parameters
2269 *
2270 * @return external_function_parameters
2271 * @since 2.9
2272 */
2273 public static function mark_message_read_parameters() {
2274 return new external_function_parameters(
2275 array(
2b595d96 2276 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'),
7b55aaa1
MN
2277 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
2278 VALUE_DEFAULT, 0)
31c474da
JL
2279 )
2280 );
2281 }
2282
2283 /**
2284 * Mark a single message as read, trigger message_viewed event
2285 *
2286 * @param int $messageid id of the message (in the message table)
2287 * @param int $timeread timestamp for when the message should be marked read
2288 * @return external_description
2289 * @throws invalid_parameter_exception
2290 * @throws moodle_exception
2291 * @since 2.9
2292 */
2293 public static function mark_message_read($messageid, $timeread) {
2294 global $CFG, $DB, $USER;
31c474da
JL
2295
2296 // Check if private messaging between users is allowed.
2297 if (empty($CFG->messaging)) {
2298 throw new moodle_exception('disabled', 'message');
2299 }
2300
2301 // Warnings array, it can be empty at the end but is mandatory.
2302 $warnings = array();
2303
2304 // Validate params.
2305 $params = array(
2306 'messageid' => $messageid,
2307 'timeread' => $timeread
2308 );
2309 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
2310
0b19d048
RW
2311 if (empty($params['timeread'])) {
2312 $timeread = time();
2313 } else {
2314 $timeread = $params['timeread'];
2315 }
2316
31c474da
JL
2317 // Validate context.
2318 $context = context_system::instance();
2319 self::validate_context($context);
2320
883ce421
MN
2321 $sql = "SELECT m.*, mcm.userid as useridto
2322 FROM {messages} m
2323 INNER JOIN {message_conversations} mc
2324 ON m.conversationid = mc.id
2325 INNER JOIN {message_conversation_members} mcm
2326 ON mcm.conversationid = mc.id
5aac33c7
MN
2327 LEFT JOIN {message_user_actions} mua
2328 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
2329 WHERE mua.id is NULL
2330 AND mcm.userid != m.useridfrom
883ce421 2331 AND m.id = ?";
5aac33c7
MN
2332 $messageparams = [];
2333 $messageparams[] = $USER->id;
2334 $messageparams[] = \core_message\api::MESSAGE_ACTION_READ;
2335 $messageparams[] = $params['messageid'];
2336 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST);
31c474da
JL
2337
2338 if ($message->useridto != $USER->id) {
2339 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2340 }
2341
548936a6 2342 \core_message\api::mark_message_as_read($USER->id, $message, $timeread);
31c474da
JL
2343
2344 $results = array(
883ce421 2345 'messageid' => $message->id,
31c474da
JL
2346 'warnings' => $warnings
2347 );
2348 return $results;
2349 }
2350
2351 /**
2352 * Returns description of method result value
2353 *
2354 * @return external_description
2355 * @since 2.9
2356 */
2357 public static function mark_message_read_returns() {
2358 return new external_single_structure(
2359 array(
2b595d96
MN
2360 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'),
2361 'warnings' => new external_warnings()
2362 )
2363 );
2364 }
2365
2366 /**
2367 * Returns description of method parameters
2368 *
2369 * @return external_function_parameters
2370 */
2371 public static function mark_notification_read_parameters() {
2372 return new external_function_parameters(
2373 array(
2374 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
2375 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read',
2376 VALUE_DEFAULT, 0)
2377 )
2378 );
2379 }
2380
2381 /**
2382 * Mark a single notification as read.
2383 *
2384 * This will trigger a 'notification_viewed' event.
2385 *
2386 * @param int $notificationid id of the notification
2387 * @param int $timeread timestamp for when the notification should be marked read
2388 * @return external_description
2389 * @throws invalid_parameter_exception
2390 * @throws moodle_exception
2391 */
2392 public static function mark_notification_read($notificationid, $timeread) {
2393 global $CFG, $DB, $USER;
2394
2395 // Check if private messaging between users is allowed.
2396 if (empty($CFG->messaging)) {
2397 throw new moodle_exception('disabled', 'message');
2398 }
2399
2400 // Warnings array, it can be empty at the end but is mandatory.
2401 $warnings = array();
2402
2403 // Validate params.
2404 $params = array(
2405 'notificationid' => $notificationid,
2406 'timeread' => $timeread
2407 );
2408 $params = self::validate_parameters(self::mark_notification_read_parameters(), $params);
2409
2410 if (empty($params['timeread'])) {
2411 $timeread = time();
2412 } else {
2413 $timeread = $params['timeread'];
2414 }
2415
2416 // Validate context.
2417 $context = context_system::instance();
2418 self::validate_context($context);
2419
2420 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST);
2421
2422 if ($notification->useridto != $USER->id) {
2423 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
2424 'notification as read');
2425 }
2426
2427 \core_message\api::mark_notification_as_read($notification, $timeread);
2428
2429 $results = array(
2430 'notificationid' => $notification->id,
2431 'warnings' => $warnings
2432 );
2433
2434 return $results;
2435 }
2436
2437 /**
2438 * Returns description of method result value
2439 *
2440 * @return external_description
2441 */
2442 public static function mark_notification_read_returns() {
2443 return new external_single_structure(
2444 array(
2445 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
31c474da
JL
2446 'warnings' => new external_warnings()
2447 )
2448 );
2449 }
2450
8c55bd6c
RW
2451 /**
2452 * Mark all messages as read parameters description.
2453 *
2454 * @return external_function_parameters
2455 * @since 3.2
2456 */
2457 public static function mark_all_messages_as_read_parameters() {
2458 return new external_function_parameters(
2459 array(
2460 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2461 'useridfrom' => new external_value(
2462 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2463 VALUE_DEFAULT, 0),
2464 )
2465 );
2466 }
2467
2468 /**
2469 * Mark all notifications as read function.
2470 *
2471 * @since 3.2
2472 * @throws invalid_parameter_exception
2473 * @throws moodle_exception
2474 * @param int $useridto the user id who received the message
2475 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2476 * @return external_description
2477 */
2478 public static function mark_all_messages_as_read($useridto, $useridfrom) {
a2c7227a
SL
2479 global $USER, $CFG;
2480
2481 // Check if messaging is enabled.
2482 if (empty($CFG->messaging)) {
2483 throw new moodle_exception('disabled', 'message');
2484 }
8c55bd6c
RW
2485
2486 $params = self::validate_parameters(
2487 self::mark_all_messages_as_read_parameters(),
2488 array(
2489 'useridto' => $useridto,
2490 'useridfrom' => $useridfrom,
2491 )
2492 );
2493
2494 $context = context_system::instance();
2495 self::validate_context($context);
2496
2497 $useridto = $params['useridto'];
2498 $useridfrom = $params['useridfrom'];
2499
2500 if (!empty($useridto)) {
2501 if (core_user::is_real_user($useridto)) {
2502 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2503 } else {
2504 throw new moodle_exception('invaliduser');
2505 }
2506 }
2507
2508 if (!empty($useridfrom)) {
2509 // We use get_user here because the from user can be the noreply or support user.
2510 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2511 }
2512
2513 // Check if the current user is the sender/receiver or just a privileged user.
2514 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 2515 // The deleteanymessage cap seems more reasonable here than readallmessages.
8c55bd6c
RW
2516 !has_capability('moodle/site:deleteanymessage', $context)) {
2517 throw new moodle_exception('accessdenied', 'admin');
2518 }
2519
74ad60bf
MN
2520 if ($useridfrom) {
2521 if ($conversationid = \core_message\api::get_conversation_between_users([$useridto, $useridfrom])) {
2522 \core_message\api::mark_all_messages_as_read($useridto, $conversationid);
2523 }
2524 } else {
2525 \core_message\api::mark_all_messages_as_read($useridto);
2526 }
8c55bd6c
RW
2527
2528 return true;
2529 }
2530
2531 /**
2532 * Mark all notifications as read return description.
2533 *
2534 * @return external_single_structure
2535 * @since 3.2
2536 */
2537 public static function mark_all_messages_as_read_returns() {
2538 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2539 }
2540
dec0cd99
MN
2541 /**
2542 * Returns description of method parameters.
2543 *
fa024820 2544 * @deprecated since 3.6
dec0cd99
MN
2545 * @return external_function_parameters
2546 * @since 3.2
2547 */
2548 public static function delete_conversation_parameters() {
2549 return new external_function_parameters(
2550 array(
2551 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
2552 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
2553 )
2554 );
2555 }
2556
2557 /**
2558 * Deletes a conversation.
2559 *
fa024820 2560 * @deprecated since 3.6
dec0cd99
MN
2561 * @param int $userid The user id of who we want to delete the conversation for
2562 * @param int $otheruserid The user id of the other user in the conversation
2563 * @return array
2564 * @throws moodle_exception
2565 * @since 3.2
2566 */
2567 public static function delete_conversation($userid, $otheruserid) {
2568 global $CFG;
2569
2570 // Check if private messaging between users is allowed.
2571 if (empty($CFG->messaging)) {
2572 throw new moodle_exception('disabled', 'message');
2573 }
2574
2575 // Warnings array, it can be empty at the end but is mandatory.
2576 $warnings = array();
2577
2578 // Validate params.
2579 $params = array(
2580 'userid' => $userid,
2581 'otheruserid' => $otheruserid,
2582 );
2583 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
2584
2585 // Validate context.
2586 $context = context_system::instance();
2587 self::validate_context($context);
2588
2589 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2590 core_user::require_active_user($user);
2591
15663b0b
MN
2592 if (!$conversationid = \core_message\api::get_conversation_between_users([$userid, $otheruserid])) {
2593 return [];
2594 }
2595
2596 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) {
2597 \core_message\api::delete_conversation_by_id($user->id, $conversationid);
263ad984 2598 $status = true;
dec0cd99
MN
2599 } else {
2600 throw new moodle_exception('You do not have permission to delete messages');
2601 }
2602
2603 $results = array(
2604 'status' => $status,
2605 'warnings' => $warnings
2606 );
2607
2608 return $results;
2609 }
2610
2611 /**
2612 * Returns description of method result value.
2613 *
fa024820 2614 * @deprecated since 3.6
dec0cd99
MN
2615 * @return external_description
2616 * @since 3.2
2617 */
2618 public static function delete_conversation_returns() {
2619 return new external_single_structure(
2620 array(
2621 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
2622 'warnings' => new external_warnings()
2623 )
2624 );
2625 }
2626
fa024820
MN
2627 /**
2628 * Marking the method as deprecated.
2629 *
2630 * @return bool
2631 */
2632 public static function delete_conversation_is_deprecated() {
2633 return true;
2634 }
2635
419b1128
JL
2636 /**
2637 * Returns description of method parameters
2638 *
2639 * @return external_function_parameters
2640 * @since 3.1
2641 */
2642 public static function delete_message_parameters() {
2643 return new external_function_parameters(
2644 array(
2645 'messageid' => new external_value(PARAM_INT, 'The message id'),
2646 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
2647 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
2648 )
2649 );
2650 }
2651
2652 /**
2653 * Deletes a message
2654 *
2655 * @param int $messageid the message id
2656 * @param int $userid the user id of who we want to delete the message for
2657 * @param bool $read if is a message read (default to true)
2658 * @return external_description
2659 * @throws moodle_exception
2660 * @since 3.1
2661 */
2662 public static function delete_message($messageid, $userid, $read = true) {
883ce421 2663 global $CFG;
419b1128
JL
2664
2665 // Check if private messaging between users is allowed.
2666 if (empty($CFG->messaging)) {
2667 throw new moodle_exception('disabled', 'message');
2668 }
2669
2670 // Warnings array, it can be empty at the end but is mandatory.
2671 $warnings = array();
2672
2673 // Validate params.
2674 $params = array(
2675 'messageid' => $messageid,
2676 'userid' => $userid,
2677 'read' => $read
2678 );
2679 $params = self::validate_parameters(self::delete_message_parameters(), $params);
2680
2681 // Validate context.
2682 $context = context_system::instance();
2683 self::validate_context($context);
2684
419b1128
JL
2685 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2686 core_user::require_active_user($user);
2687
883ce421
MN
2688 if (\core_message\api::can_delete_message($user->id, $messageid)) {
2689 $status = \core_message\api::delete_message($user->id, $messageid);
419b1128
JL
2690 } else {
2691 throw new moodle_exception('You do not have permission to delete this message');
2692 }
2693
2694 $results = array(
2695 'status' => $status,
2696 'warnings' => $warnings
2697 );
2698 return $results;
2699 }
2700
2701 /**
2702 * Returns description of method result value
2703 *
2704 * @return external_description
2705 * @since 3.1
2706 */
2707 public static function delete_message_returns() {
2708 return new external_single_structure(
2709 array(
2710 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
2711 'warnings' => new external_warnings()
2712 )
2713 );
2714 }
2715
a0eabdd3
RW
2716 /**
2717 * Returns description of method parameters
2718 *
2719 * @return external_function_parameters
2720 * @since 3.2
2721 */
2722 public static function message_processor_config_form_parameters() {
2723 return new external_function_parameters(
2724 array(
2725 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
2726 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
2727 'formvalues' => new external_multiple_structure(
2728 new external_single_structure(
2729 array(
2730 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
2731 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
2732 )
2733 ),
2734 'Config form values',
2735 VALUE_REQUIRED
2736 ),
2737 )
2738 );
2739 }
2740
2741 /**
2742 * Processes a message processor config form.
2743 *
2744 * @param int $userid the user id
2745 * @param string $name the name of the processor
2746 * @param array $formvalues the form values
2747 * @return external_description
2748 * @throws moodle_exception
2749 * @since 3.2
2750 */
2751 public static function message_processor_config_form($userid, $name, $formvalues) {
a2c7227a
SL
2752 global $USER, $CFG;
2753
2754 // Check if messaging is enabled.
2755 if (empty($CFG->messaging)) {
2756 throw new moodle_exception('disabled', 'message');
2757 }
8c125526 2758
a0eabdd3
RW
2759 $params = self::validate_parameters(
2760 self::message_processor_config_form_parameters(),
2761 array(
2762 'userid' => $userid,
2763 'name' => $name,
2764 'formvalues' => $formvalues,
2765 )
2766 );
2767
6e65554e 2768 $user = self::validate_preferences_permissions($params['userid']);
a0eabdd3
RW
2769
2770 $processor = get_message_processor($name);
2771 $preferences = [];
2772 $form = new stdClass();
2773
2774 foreach ($formvalues as $formvalue) {
cdff0944
RW
2775 // Curly braces to ensure interpretation is consistent between
2776 // php 5 and php 7.
2777 $form->{$formvalue['name']} = $formvalue['value'];
a0eabdd3
RW
2778 }
2779
2780 $processor->process_form($form, $preferences);
2781
2782 if (!empty($preferences)) {
2783 set_user_preferences($preferences, $userid);
2784 }
2785 }
2786
2787 /**
2788 * Returns description of method result value
2789 *
2790 * @return external_description
2791 * @since 3.2
2792 */
2793 public static function message_processor_config_form_returns() {
2794 return null;
2795 }
8c125526
RW
2796
2797 /**
2798 * Returns description of method parameters
2799 *
2800 * @return external_function_parameters
2801 * @since 3.2
2802 */
2803 public static function get_message_processor_parameters() {
2804 return new external_function_parameters(
2805 array(
2806 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
2807 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
2808 )
2809 );
2810 }
2811
2812 /**
2813 * Get a message processor.
2814 *
7b55aaa1
MN
2815 * @param int $userid
2816 * @param string $name the name of the processor
8c125526
RW
2817 * @return external_description
2818 * @throws moodle_exception
2819 * @since 3.2
2820 */
2821 public static function get_message_processor($userid = 0, $name) {
a2c7227a
SL
2822 global $USER, $PAGE, $CFG;
2823
2824 // Check if messaging is enabled.
2825 if (empty($CFG->messaging)) {
2826 throw new moodle_exception('disabled', 'message');
2827 }
8c125526
RW
2828
2829 $params = self::validate_parameters(
2830 self::get_message_processor_parameters(),
2831 array(
2832 'userid' => $userid,
2833 'name' => $name,
2834 )
2835 );
2836
2837 if (empty($params['userid'])) {
2838 $params['userid'] = $USER->id;
2839 }
2840
2841 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2842 core_user::require_active_user($user);
2843 self::validate_context(context_user::instance($params['userid']));
2844
2845 $processor = get_message_processor($name);
2846
2847 $processoroutput = new \core_message\output\processor($processor, $user);
2848 $renderer = $PAGE->get_renderer('core_message');
2849
2850 return $processoroutput->export_for_template($renderer);
2851 }
2852
2853 /**
2854 * Returns description of method result value
2855 *
2856 * @return external_description
2857 * @since 3.2
2858 */
2859 public static function get_message_processor_returns() {
2860 return new external_function_parameters(
2861 array(
2862 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
2863 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
2864 )
2865 );
2866 }
e86f0cb4 2867
2521afd2
JL
2868 /**
2869 * Check that the user has enough permission to retrieve message or notifications preferences.
2870 *
2871 * @param int $userid the user id requesting the preferences
2872 * @return stdClass full user object
2873 * @throws moodle_exception
2874 * @since Moodle 3.2
2875 */
2876 protected static function validate_preferences_permissions($userid) {
2877 global $USER;
2878
2879 if (empty($userid)) {
2880 $user = $USER;
2881 } else {
2882 $user = core_user::get_user($userid, '*', MUST_EXIST);
2883 core_user::require_active_user($user);
2884 }
2885
2886 $systemcontext = context_system::instance();
2887 self::validate_context($systemcontext);
2888
2889 // Check access control.
2890 if ($user->id == $USER->id) {
2891 // Editing own message profile.
2892 require_capability('moodle/user:editownmessageprofile', $systemcontext);
2893 } else {
2894 // Teachers, parents, etc.
2895 $personalcontext = context_user::instance($user->id);
2896 require_capability('moodle/user:editmessageprofile', $personalcontext);
2897 }
2898 return $user;
2899 }
2900
2901 /**
2902 * Returns a notification or message preference structure.
2903 *
2904 * @return external_single_structure the structure
2905 * @since Moodle 3.2
2906 */
2907 protected static function get_preferences_structure() {
2908 return new external_single_structure(
2909 array(
2910 'userid' => new external_value(PARAM_INT, 'User id'),
2911 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
2912 'processors' => new external_multiple_structure(
2913 new external_single_structure(
2914 array(
2915 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2916 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2917 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
2918 'contextid' => new external_value(PARAM_INT, 'Context id'),
2919 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
2920 )
2921 ),
2922 'Config form values'
2923 ),
2924 'components' => new external_multiple_structure(
2925 new external_single_structure(
2926 array(
2927 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2928 'notifications' => new external_multiple_structure(
2929 new external_single_structure(
2930 array(
2931 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2932 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
2933 'processors' => new external_multiple_structure(
2934 new external_single_structure(
2935 array(
2936 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2937 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2938 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
2939 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
2940 'loggedin' => new external_single_structure(
2941 array(
2942 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2943 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2944 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2945 )
2946 ),
2947 'loggedoff' => new external_single_structure(
2948 array(
2949 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2950 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2951 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2952 )
2953 ),
2954 )
2955 ),
2956 'Processors values for this notification'
2957 ),
2958 )
2959 ),
2960 'List of notificaitons for the component'
2961 ),
2962 )
2963 ),
2964 'Available components'
2965 ),
2966 )
2967 );
2968 }
2969
e86f0cb4
JL
2970 /**
2971 * Returns description of method parameters
2972 *
2973 * @return external_function_parameters
2974 * @since 3.2
2975 */
2976 public static function get_user_notification_preferences_parameters() {
2977 return new external_function_parameters(
2978 array(
2979 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
2980 )
2981 );
2982 }
2983
2984 /**
2985 * Get the notification preferences for a given user.
2986 *
2987 * @param int $userid id of the user, 0 for current user
2988 * @return external_description
2989 * @throws moodle_exception
2990 * @since 3.2
2991 */
2992 public static function get_user_notification_preferences($userid = 0) {
2521afd2 2993 global $PAGE;
a2c7227a 2994
e86f0cb4
JL
2995 $params = self::validate_parameters(
2996 self::get_user_notification_preferences_parameters(),
2997 array(
2998 'userid' => $userid,
2999 )
3000 );
2521afd2 3001 $user = self::validate_preferences_permissions($params['userid']);
e86f0cb4
JL
3002
3003 $processors = get_message_processors();
3004 $providers = message_get_providers_for_user($user->id);
1686d93a 3005 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
e86f0cb4
JL
3006 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
3007
3008 $renderer = $PAGE->get_renderer('core_message');
3009
3010 $result = array(
3011 'warnings' => array(),
3012 'preferences' => $notificationlist->export_for_template($renderer)
3013 );
3014 return $result;
3015 }
3016
3017 /**
3018 * Returns description of method result value
3019 *
3020 * @return external_description
3021 * @since 3.2
3022 */
3023 public static function get_user_notification_preferences_returns() {
3024 return new external_function_parameters(
3025 array(
2521afd2
JL
3026 'preferences' => self::get_preferences_structure(),
3027 'warnings' => new external_warnings(),
3028 )
3029 );
3030 }
3031
2521afd2
JL
3032 /**
3033 * Returns description of method parameters
3034 *
3035 * @return external_function_parameters
3036 * @since 3.2
3037 */
3038 public static function get_user_message_preferences_parameters() {
3039 return new external_function_parameters(
3040 array(
3041 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
3042 )
3043 );
3044 }
3045
3046 /**
3047 * Get the notification preferences for a given user.
3048 *
3049 * @param int $userid id of the user, 0 for current user
3050 * @return external_description
3051 * @throws moodle_exception
3052 * @since 3.2
3053 */
3054 public static function get_user_message_preferences($userid = 0) {
3055 global $PAGE;
3056
3057 $params = self::validate_parameters(
3058 self::get_user_message_preferences_parameters(),
3059 array(
3060 'userid' => $userid,
3061 )
3062 );
3063
3064 $user = self::validate_preferences_permissions($params['userid']);
3065
3066 // Filter out enabled, available system_configured and user_configured processors only.
3067 $readyprocessors = array_filter(get_message_processors(), function($processor) {
3068 return $processor->enabled &&
3069 $processor->configured &&
3070 $processor->object->is_user_configured() &&
3071 // Filter out processors that don't have and message preferences to configure.
3072 $processor->object->has_message_preferences();
3073 });
3074
3075 $providers = array_filter(message_get_providers_for_user($user->id), function($provider) {
3076 return $provider->component === 'moodle';
3077 });
3078 $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user);
3079 $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors,
3080 $providers, $preferences, $user);
3081
3082 $renderer = $PAGE->get_renderer('core_message');
3083
3084 $result = array(
3085 'warnings' => array(),
3086 'preferences' => $notificationlistoutput->export_for_template($renderer),
3087 'blocknoncontacts' => get_user_preferences('message_blocknoncontacts', '', $user->id) ? true : false,
3088 );
3089 return $result;
3090 }
3091
3092 /**
3093 * Returns description of method result value
3094 *
3095 * @return external_description
3096 * @since 3.2
3097 */
3098 public static function get_user_message_preferences_returns() {
3099 return new external_function_parameters(
3100 array(
3101 'preferences' => self::get_preferences_structure(),
3102 'blocknoncontacts' => new external_value(PARAM_BOOL, 'Whether to block or not messages from non contacts'),
e86f0cb4
JL
3103 'warnings' => new external_warnings(),
3104 )
3105 );
3106 }
a623b6b8 3107}