MDL-55942 core_message: cleaned the index.php page
[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
a623b6b8 27require_once("$CFG->libdir/externallib.php");
705afe6f 28require_once($CFG->dirroot . "/message/lib.php");
a623b6b8 29
5d1017e1 30/**
4615817d 31 * Message external functions
6fbd60ef
AD
32 *
33 * @package core_message
4615817d
JM
34 * @category external
35 * @copyright 2011 Jerome Mouneyrac
75e4f98c 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4615817d 37 * @since Moodle 2.2
5d1017e1
JM
38 */
39class core_message_external extends external_api {
a623b6b8
JM
40
41 /**
42 * Returns description of method parameters
4615817d 43 *
a623b6b8 44 * @return external_function_parameters
4615817d 45 * @since Moodle 2.2
a623b6b8 46 */
5d1017e1 47 public static function send_instant_messages_parameters() {
a623b6b8
JM
48 return new external_function_parameters(
49 array(
50 'messages' => new external_multiple_structure(
51 new external_single_structure(
52 array(
53 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'),
93ce0e82 54 'text' => new external_value(PARAM_RAW, 'the text of the message'),
14968ca9 55 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
a623b6b8
JM
56 '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),
57 )
58 )
59 )
60 )
61 );
62 }
63
64 /**
65 * Send private messages from the current USER to other users
66 *
4615817d
JM
67 * @param array $messages An array of message to send.
68 * @return array
69 * @since Moodle 2.2
a623b6b8 70 */
5d1017e1 71 public static function send_instant_messages($messages = array()) {
a623b6b8 72 global $CFG, $USER, $DB;
a623b6b8 73
436bbf89 74 // Check if messaging is enabled.
837941e9 75 if (empty($CFG->messaging)) {
a623b6b8
JM
76 throw new moodle_exception('disabled', 'message');
77 }
78
79 // Ensure the current user is allowed to run this function
bf0f06b1 80 $context = context_system::instance();
a623b6b8
JM
81 self::validate_context($context);
82 require_capability('moodle/site:sendmessage', $context);
83
5d1017e1 84 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
a623b6b8
JM
85
86 //retrieve all tousers of the messages
4de00da7 87 $receivers = array();
a623b6b8 88 foreach($params['messages'] as $message) {
4de00da7 89 $receivers[] = $message['touserid'];
a623b6b8 90 }
4de00da7 91 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers, SQL_PARAMS_NAMED, 'userid_');
a623b6b8 92 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
4de00da7
DC
93 $blocklist = array();
94 $contactlist = array();
a623b6b8 95 $sqlparams['contactid'] = $USER->id;
4de00da7
DC
96 $rs = $DB->get_recordset_sql("SELECT *
97 FROM {message_contacts}
98 WHERE userid $sqluserids
99 AND contactid = :contactid", $sqlparams);
100 foreach ($rs as $record) {
101 if ($record->blocked) {
102 // $record->userid is blocking current user
103 $blocklist[$record->userid] = true;
104 } else {
105 // $record->userid have current user as contact
106 $contactlist[$record->userid] = true;
107 }
108 }
109 $rs->close();
a623b6b8
JM
110
111 $canreadallmessages = has_capability('moodle/site:readallmessages', $context);
112
113 $resultmessages = array();
114 foreach ($params['messages'] as $message) {
a623b6b8
JM
115 $resultmsg = array(); //the infos about the success of the operation
116
117 //we are going to do some checking
118 //code should match /messages/index.php checks
119 $success = true;
120
121 //check the user exists
122 if (empty($tousers[$message['touserid']])) {
123 $success = false;
124 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
125 }
126
127 //check that the touser is not blocking the current user
4de00da7 128 if ($success and !empty($blocklist[$message['touserid']]) and !$canreadallmessages) {
a623b6b8
JM
129 $success = false;
130 $errormessage = get_string('userisblockingyou', 'message');
131 }
132
78736e5d 133 // Check if the user is a contact
4615817d 134 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
4de00da7
DC
135 $blocknoncontacts = get_user_preferences('message_blocknoncontacts', NULL, $message['touserid']);
136 // message_blocknoncontacts option is on and current user is not in contact list
137 if ($success && empty($contactlist[$message['touserid']]) && !empty($blocknoncontacts)) {
78736e5d
SH
138 // The user isn't a contact and they have selected to block non contacts so this message won't be sent.
139 $success = false;
126a4bc4
CS
140 $errormessage = get_string('userisblockingyounoncontact', 'message',
141 fullname(core_user::get_user($message['touserid'])));
a623b6b8
JM
142 }
143
144 //now we can send the message (at least try)
145 if ($success) {
4615817d 146 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object
93ce0e82
JM
147 $success = message_post_message($USER, $tousers[$message['touserid']],
148 $message['text'], external_validate_format($message['textformat']));
a623b6b8
JM
149 }
150
151 //build the resultmsg
152 if (isset($message['clientmsgid'])) {
78736e5d 153 $resultmsg['clientmsgid'] = $message['clientmsgid'];
a623b6b8
JM
154 }
155 if ($success) {
156 $resultmsg['msgid'] = $success;
157 } else {
93ce0e82
JM
158 // WARNINGS: for backward compatibility we return this errormessage.
159 // We should have thrown exceptions as these errors prevent results to be returned.
160 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
a623b6b8
JM
161 $resultmsg['msgid'] = -1;
162 $resultmsg['errormessage'] = $errormessage;
163 }
164
165 $resultmessages[] = $resultmsg;
166 }
167
168 return $resultmessages;
169 }
170
171 /**
172 * Returns description of method result value
4615817d 173 *
a623b6b8 174 * @return external_description
4615817d 175 * @since Moodle 2.2
a623b6b8 176 */
5d1017e1 177 public static function send_instant_messages_returns() {
a623b6b8
JM
178 return new external_multiple_structure(
179 new external_single_structure(
180 array(
78736e5d 181 '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 182 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
78736e5d 183 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL)
a623b6b8
JM
184 )
185 )
186 );
187 }
188
d6731600
FM
189 /**
190 * Create contacts parameters description.
191 *
192 * @return external_function_parameters
5bcfd504 193 * @since Moodle 2.5
d6731600
FM
194 */
195 public static function create_contacts_parameters() {
196 return new external_function_parameters(
197 array(
198 'userids' => new external_multiple_structure(
199 new external_value(PARAM_INT, 'User ID'),
200 'List of user IDs'
34c2f347
MN
201 ),
202 'userid' => new external_value(PARAM_INT, 'The id of the user we are creating the contacts for, 0 for the
203 current user', VALUE_DEFAULT, 0)
d6731600
FM
204 )
205 );
206 }
207
208 /**
209 * Create contacts.
210 *
211 * @param array $userids array of user IDs.
34c2f347 212 * @param int $userid The id of the user we are creating the contacts for
d6731600 213 * @return external_description
5bcfd504 214 * @since Moodle 2.5
d6731600 215 */
34c2f347 216 public static function create_contacts($userids, $userid = 0) {
436bbf89
DM
217 global $CFG;
218
219 // Check if messaging is enabled.
837941e9 220 if (empty($CFG->messaging)) {
436bbf89
DM
221 throw new moodle_exception('disabled', 'message');
222 }
223
34c2f347 224 $params = array('userids' => $userids, 'userid' => $userid);
d6731600
FM
225 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
226
227 $warnings = array();
228 foreach ($params['userids'] as $id) {
34c2f347 229 if (!message_add_contact($id, 0, $userid)) {
d6731600
FM
230 $warnings[] = array(
231 'item' => 'user',
232 'itemid' => $id,
233 'warningcode' => 'contactnotcreated',
234 'message' => 'The contact could not be created'
235 );
236 }
237 }
238 return $warnings;
239 }
240
241 /**
242 * Create contacts return description.
243 *
244 * @return external_description
5bcfd504 245 * @since Moodle 2.5
d6731600
FM
246 */
247 public static function create_contacts_returns() {
248 return new external_warnings();
249 }
250
251 /**
252 * Delete contacts parameters description.
253 *
254 * @return external_function_parameters
5bcfd504 255 * @since Moodle 2.5
d6731600
FM
256 */
257 public static function delete_contacts_parameters() {
258 return new external_function_parameters(
259 array(
260 'userids' => new external_multiple_structure(
261 new external_value(PARAM_INT, 'User ID'),
262 'List of user IDs'
34c2f347
MN
263 ),
264 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the
265 current user', VALUE_DEFAULT, 0)
d6731600
FM
266 )
267 );
268 }
269
270 /**
271 * Delete contacts.
272 *
273 * @param array $userids array of user IDs.
34c2f347 274 * @param int $userid The id of the user we are deleting the contacts for
d6731600 275 * @return null
5bcfd504 276 * @since Moodle 2.5
d6731600 277 */
34c2f347 278 public static function delete_contacts($userids, $userid = 0) {
436bbf89
DM
279 global $CFG;
280
281 // Check if messaging is enabled.
837941e9 282 if (empty($CFG->messaging)) {
436bbf89
DM
283 throw new moodle_exception('disabled', 'message');
284 }
285
34c2f347 286 $params = array('userids' => $userids, 'userid' => $userid);
d6731600
FM
287 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
288
289 foreach ($params['userids'] as $id) {
34c2f347 290 message_remove_contact($id, $userid);
d6731600
FM
291 }
292
293 return null;
294 }
295
296 /**
297 * Delete contacts return description.
298 *
299 * @return external_description
5bcfd504 300 * @since Moodle 2.5
d6731600
FM
301 */
302 public static function delete_contacts_returns() {
303 return null;
304 }
305
306 /**
307 * Block contacts parameters description.
308 *
309 * @return external_function_parameters
5bcfd504 310 * @since Moodle 2.5
d6731600
FM
311 */
312 public static function block_contacts_parameters() {
313 return new external_function_parameters(
314 array(
315 'userids' => new external_multiple_structure(
316 new external_value(PARAM_INT, 'User ID'),
317 'List of user IDs'
34c2f347
MN
318 ),
319 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the
320 current user', VALUE_DEFAULT, 0)
d6731600
FM
321 )
322 );
323 }
324
325 /**
326 * Block contacts.
327 *
328 * @param array $userids array of user IDs.
34c2f347 329 * @param int $userid The id of the user we are blocking the contacts for
d6731600 330 * @return external_description
5bcfd504 331 * @since Moodle 2.5
d6731600 332 */
34c2f347 333 public static function block_contacts($userids, $userid = 0) {
436bbf89
DM
334 global $CFG;
335
336 // Check if messaging is enabled.
837941e9 337 if (empty($CFG->messaging)) {
436bbf89
DM
338 throw new moodle_exception('disabled', 'message');
339 }
340
34c2f347 341 $params = array('userids' => $userids, 'userid' => $userid);
d6731600
FM
342 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
343
344 $warnings = array();
345 foreach ($params['userids'] as $id) {
34c2f347 346 if (!message_block_contact($id, $userid)) {
d6731600
FM
347 $warnings[] = array(
348 'item' => 'user',
349 'itemid' => $id,
350 'warningcode' => 'contactnotblocked',
351 'message' => 'The contact could not be blocked'
352 );
353 }
354 }
355 return $warnings;
356 }
357
358 /**
359 * Block contacts return description.
360 *
361 * @return external_description
5bcfd504 362 * @since Moodle 2.5
d6731600
FM
363 */
364 public static function block_contacts_returns() {
365 return new external_warnings();
366 }
367
368 /**
369 * Unblock contacts parameters description.
370 *
371 * @return external_function_parameters
5bcfd504 372 * @since Moodle 2.5
d6731600
FM
373 */
374 public static function unblock_contacts_parameters() {
375 return new external_function_parameters(
376 array(
377 'userids' => new external_multiple_structure(
378 new external_value(PARAM_INT, 'User ID'),
379 'List of user IDs'
34c2f347
MN
380 ),
381 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the
382 current user', VALUE_DEFAULT, 0)
d6731600
FM
383 )
384 );
385 }
386
387 /**
388 * Unblock contacts.
389 *
390 * @param array $userids array of user IDs.
34c2f347 391 * @param int $userid The id of the user we are unblocking the contacts for
d6731600 392 * @return null
5bcfd504 393 * @since Moodle 2.5
d6731600 394 */
34c2f347 395 public static function unblock_contacts($userids, $userid = 0) {
436bbf89
DM
396 global $CFG;
397
398 // Check if messaging is enabled.
837941e9 399 if (empty($CFG->messaging)) {
436bbf89
DM
400 throw new moodle_exception('disabled', 'message');
401 }
402
34c2f347 403 $params = array('userids' => $userids, 'userid' => $userid);
d6731600
FM
404 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
405
406 foreach ($params['userids'] as $id) {
34c2f347 407 message_unblock_contact($id, $userid);
d6731600
FM
408 }
409
410 return null;
411 }
412
413 /**
414 * Unblock contacts return description.
415 *
416 * @return external_description
5bcfd504 417 * @since Moodle 2.5
d6731600
FM
418 */
419 public static function unblock_contacts_returns() {
420 return null;
421 }
422
a3e3a3a1
MN
423 /**
424 * Return the structure of a message area contact.
425 *
426 * @return external_single_structure
427 * @since Moodle 3.2
428 */
429 private static function get_messagearea_contact_structure() {
430 return new external_single_structure(
431 array(
432 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
433 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
434 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
435 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
5bf0ff27 436 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
89a70ba1 437 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
a3e3a3a1
MN
438 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
439 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
440 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
441 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
dd0c1403 442 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
a3e3a3a1
MN
443 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
444 VALUE_DEFAULT, null),
445 )
446 );
447 }
448
94e1db61
MN
449 /**
450 * Return the structure of a message area message.
451 *
452 * @return external_single_structure
453 * @since Moodle 3.2
454 */
455 private static function get_messagearea_message_structure() {
456 return new external_single_structure(
457 array(
458 'id' => new external_value(PARAM_INT, 'The id of the message'),
89a70ba1
MN
459 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
460 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
94e1db61
MN
461 'text' => new external_value(PARAM_RAW, 'The text of the message'),
462 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
463 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
464 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
465 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
466 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
467 )
468 );
469 }
470
cd03b8d7
MN
471 /**
472 * Get messagearea search people parameters.
473 *
474 * @return external_function_parameters
475 * @since 3.2
476 */
477 public static function data_for_messagearea_search_people_in_course_parameters() {
478 return new external_function_parameters(
479 array(
480 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
481 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
482 'search' => new external_value(PARAM_RAW, 'The string being searched'),
483 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
484 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
485 )
486 );
487 }
488
489 /**
490 * Get messagearea search people results.
491 *
492 * @param int $userid The id of the user who is performing the search
493 * @param int $courseid The id of the course
494 * @param string $search The string being searched
495 * @param int $limitfrom
496 * @param int $limitnum
497 * @return stdClass
498 * @throws moodle_exception
499 * @since 3.2
500 */
7b55aaa1
MN
501 public static function data_for_messagearea_search_people_in_course($userid, $courseid, $search, $limitfrom = 0,
502 $limitnum = 0) {
837941e9 503 global $CFG, $PAGE, $USER;
cd03b8d7
MN
504
505 // Check if messaging is enabled.
837941e9 506 if (empty($CFG->messaging)) {
cd03b8d7
MN
507 throw new moodle_exception('disabled', 'message');
508 }
509
837941e9
MN
510 $systemcontext = context_system::instance();
511
cd03b8d7
MN
512 $params = array(
513 'userid' => $userid,
514 'courseid' => $courseid,
515 'search' => $search,
516 'limitfrom' => $limitfrom,
517 'limitnum' => $limitnum
518 );
519 self::validate_parameters(self::data_for_messagearea_search_people_in_course_parameters(), $params);
837941e9 520 self::validate_context($systemcontext);
cd03b8d7 521
837941e9
MN
522 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
523 throw new moodle_exception('You do not have permission to perform this action.');
524 }
cd03b8d7
MN
525
526 $search = \core_message\api::search_people_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
527
528 $renderer = $PAGE->get_renderer('core_message');
529 return $search->export_for_template($renderer);
530 }
531
532 /**
533 * Get messagearea search people returns.
534 *
535 * @return external_single_structure
536 * @since 3.2
537 */
538 public static function data_for_messagearea_search_people_in_course_returns() {
539 return new external_single_structure(
540 array(
541 'hascontacts' => new external_value(PARAM_BOOL, 'Are there contacts?'),
542 'contacts' => new external_multiple_structure(
a3e3a3a1 543 self::get_messagearea_contact_structure()
cd03b8d7
MN
544 ),
545 )
546 );
547 }
548
549 /**
550 * Get messagearea search people parameters.
551 *
552 * @return external_function_parameters
553 * @since 3.2
554 */
555 public static function data_for_messagearea_search_people_parameters() {
556 return new external_function_parameters(
557 array(
558 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
559 'search' => new external_value(PARAM_RAW, 'The string being searched'),
560 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
561 )
562 );
563 }
564
565 /**
566 * Get messagearea search people results.
567 *
568 * @param int $userid The id of the user who is performing the search
569 * @param string $search The string being searched
570 * @param int $limitnum
571 * @return stdClass
572 * @throws moodle_exception
573 * @since 3.2
574 */
575 public static function data_for_messagearea_search_people($userid, $search, $limitnum = 0) {
837941e9 576 global $CFG, $PAGE, $USER;
cd03b8d7
MN
577
578 // Check if messaging is enabled.
837941e9 579 if (empty($CFG->messaging)) {
cd03b8d7
MN
580 throw new moodle_exception('disabled', 'message');
581 }
582
837941e9
MN
583 $systemcontext = context_system::instance();
584
cd03b8d7
MN
585 $params = array(
586 'userid' => $userid,
587 'search' => $search,
588 'limitnum' => $limitnum
589 );
590 self::validate_parameters(self::data_for_messagearea_search_people_parameters(), $params);
837941e9 591 self::validate_context($systemcontext);
cd03b8d7 592
837941e9
MN
593 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
594 throw new moodle_exception('You do not have permission to perform this action.');
595 }
cd03b8d7
MN
596
597 $search = \core_message\api::search_people($userid, $search, $limitnum);
598
599 $renderer = $PAGE->get_renderer('core_message');
600 return $search->export_for_template($renderer);
601 }
602
603 /**
604 * Get messagearea search people returns.
605 *
606 * @return external_single_structure
607 * @since 3.2
608 */
609 public static function data_for_messagearea_search_people_returns() {
610 return new external_single_structure(
611 array(
612 'hascontacts' => new external_value(PARAM_BOOL, 'Are there contacts?'),
613 'contacts' => new external_multiple_structure(
a3e3a3a1 614 self::get_messagearea_contact_structure()
cd03b8d7
MN
615 ),
616 'hascourses' => new external_value(PARAM_BOOL, 'Are there courses?'),
617 'courses' => new external_multiple_structure(
618 new external_single_structure(
619 array(
620 'id' => new external_value(PARAM_INT, 'The course id'),
621 'shortname' => new external_value(PARAM_NOTAGS, 'The course shortname'),
622 'fullname' => new external_value(PARAM_NOTAGS, 'The course fullname'),
623 )
624 )
625 ),
626 'hasnoncontacts' => new external_value(PARAM_BOOL, 'Are there non-contacts?'),
627 'noncontacts' => new external_multiple_structure(
a3e3a3a1 628 self::get_messagearea_contact_structure()
cd03b8d7
MN
629 )
630 )
631 );
632 }
633
634 /**
635 * Get messagearea search messages parameters.
636 *
637 * @return external_function_parameters
638 * @since 3.2
639 */
640 public static function data_for_messagearea_search_messages_parameters() {
641 return new external_function_parameters(
642 array(
643 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
644 'search' => new external_value(PARAM_RAW, 'The string being searched'),
645 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
646 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
647 )
648 );
649 }
650
651 /**
652 * Get messagearea search messages results.
653 *
654 * @param int $userid The id of the user who is performing the search
655 * @param string $search The string being searched
656 * @param int $limitfrom
657 * @param int $limitnum
658 * @return stdClass
659 * @throws moodle_exception
660 * @since 3.2
661 */
662 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
837941e9 663 global $CFG, $PAGE, $USER;
cd03b8d7
MN
664
665 // Check if messaging is enabled.
837941e9 666 if (empty($CFG->messaging)) {
cd03b8d7
MN
667 throw new moodle_exception('disabled', 'message');
668 }
669
837941e9
MN
670 $systemcontext = context_system::instance();
671
cd03b8d7
MN
672 $params = array(
673 'userid' => $userid,
674 'search' => $search,
675 'limitfrom' => $limitfrom,
676 'limitnum' => $limitnum
677
678 );
679 self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
837941e9 680 self::validate_context($systemcontext);
cd03b8d7 681
837941e9
MN
682 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
683 throw new moodle_exception('You do not have permission to perform this action.');
684 }
cd03b8d7
MN
685
686 $search = \core_message\api::search_messages($userid, $search, $limitfrom, $limitnum);
687
688 $renderer = $PAGE->get_renderer('core_message');
689 return $search->export_for_template($renderer);
690 }
691
692 /**
693 * Get messagearea search messages returns.
694 *
695 * @return external_single_structure
696 * @since 3.2
697 */
698 public static function data_for_messagearea_search_messages_returns() {
699 return new external_single_structure(
700 array(
701 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
702 'contacts' => new external_multiple_structure(
a3e3a3a1 703 self::get_messagearea_contact_structure()
cd03b8d7
MN
704 )
705 )
706 );
707 }
708
9aa012b5 709 /**
49aaadc3 710 * The messagearea conversations parameters.
9aa012b5
MN
711 *
712 * @return external_function_parameters
49aaadc3 713 * @since 3.2
9aa012b5
MN
714 */
715 public static function data_for_messagearea_conversations_parameters() {
716 return new external_function_parameters(
717 array(
718 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
719 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
720 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
721 )
722 );
723 }
724
725 /**
726 * Get messagearea conversations.
727 *
728 * @param int $userid The id of the user who we are viewing conversations for
729 * @param int $limitfrom
730 * @param int $limitnum
49aaadc3
MN
731 * @return stdClass
732 * @throws moodle_exception
733 * @since 3.2
9aa012b5
MN
734 */
735 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 736 global $CFG, $PAGE, $USER;
9aa012b5
MN
737
738 // Check if messaging is enabled.
837941e9 739 if (empty($CFG->messaging)) {
9aa012b5
MN
740 throw new moodle_exception('disabled', 'message');
741 }
742
837941e9
MN
743 $systemcontext = context_system::instance();
744
9aa012b5
MN
745 $params = array(
746 'userid' => $userid,
747 'limitfrom' => $limitfrom,
748 'limitnum' => $limitnum
749 );
750 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
837941e9 751 self::validate_context($systemcontext);
9aa012b5 752
837941e9
MN
753 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
754 throw new moodle_exception('You do not have permission to perform this action.');
755 }
9aa012b5
MN
756
757 $contacts = \core_message\api::get_conversations($userid, 0, $limitfrom, $limitnum);
758
759 $renderer = $PAGE->get_renderer('core_message');
760 return $contacts->export_for_template($renderer);
761 }
762
763 /**
49aaadc3 764 * The messagearea conversations return structure.
9aa012b5 765 *
49aaadc3
MN
766 * @return external_single_structure
767 * @since 3.2
9aa012b5
MN
768 */
769 public static function data_for_messagearea_conversations_returns() {
49aaadc3 770 return new external_single_structure(
9aa012b5
MN
771 array(
772 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
4d1b76ee 773 'isconversation' => new external_value(PARAM_BOOL, 'Are we storing conversations or contacts?'),
9aa012b5 774 'contacts' => new external_multiple_structure(
a3e3a3a1 775 self::get_messagearea_contact_structure()
9aa012b5
MN
776 )
777 )
778 );
779 }
780
781 /**
49aaadc3 782 * The messagearea contacts return parameters.
9aa012b5
MN
783 *
784 * @return external_function_parameters
49aaadc3 785 * @since 3.2
9aa012b5
MN
786 */
787 public static function data_for_messagearea_contacts_parameters() {
788 return self::data_for_messagearea_conversations_parameters();
789 }
790
791 /**
792 * Get messagearea contacts parameters.
793 *
794 * @param int $userid The id of the user who we are viewing conversations for
795 * @param int $limitfrom
796 * @param int $limitnum
49aaadc3
MN
797 * @return stdClass
798 * @throws moodle_exception
799 * @since 3.2
9aa012b5
MN
800 */
801 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 802 global $CFG, $PAGE, $USER;
9aa012b5
MN
803
804 // Check if messaging is enabled.
837941e9 805 if (empty($CFG->messaging)) {
9aa012b5
MN
806 throw new moodle_exception('disabled', 'message');
807 }
808
837941e9
MN
809 $systemcontext = context_system::instance();
810
9aa012b5
MN
811 $params = array(
812 'userid' => $userid,
813 'limitfrom' => $limitfrom,
814 'limitnum' => $limitnum
815 );
816 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
837941e9 817 self::validate_context($systemcontext);
9aa012b5 818
837941e9
MN
819 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
820 throw new moodle_exception('You do not have permission to perform this action.');
821 }
9aa012b5
MN
822
823 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
824
825 $renderer = $PAGE->get_renderer('core_message');
826 return $contacts->export_for_template($renderer);
827 }
828
829 /**
49aaadc3 830 * The messagearea contacts return structure.
9aa012b5 831 *
49aaadc3
MN
832 * @return external_single_structure
833 * @since 3.2
9aa012b5
MN
834 */
835 public static function data_for_messagearea_contacts_returns() {
836 return self::data_for_messagearea_conversations_returns();
837 }
838
3cd13828 839 /**
49aaadc3 840 * The messagearea messages parameters.
3cd13828
MN
841 *
842 * @return external_function_parameters
49aaadc3 843 * @since 3.2
3cd13828
MN
844 */
845 public static function data_for_messagearea_messages_parameters() {
846 return new external_function_parameters(
847 array(
848 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
849 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
850 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
8ec78c48
MN
851 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
852 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
3cd13828
MN
853 )
854 );
855 }
856
857 /**
858 * Get messagearea messages.
859 *
860 * @param int $currentuserid The current user's id
861 * @param int $otheruserid The other user's id
862 * @param int $limitfrom
863 * @param int $limitnum
8ec78c48 864 * @param boolean $newest
49aaadc3
MN
865 * @return stdClass
866 * @throws moodle_exception
867 * @since 3.2
3cd13828 868 */
7b55aaa1
MN
869 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
870 $newest = false) {
837941e9 871 global $CFG, $PAGE, $USER;
3cd13828
MN
872
873 // Check if messaging is enabled.
837941e9 874 if (empty($CFG->messaging)) {
3cd13828
MN
875 throw new moodle_exception('disabled', 'message');
876 }
877
837941e9
MN
878 $systemcontext = context_system::instance();
879
3cd13828
MN
880 $params = array(
881 'currentuserid' => $currentuserid,
882 'otheruserid' => $otheruserid,
883 'limitfrom' => $limitfrom,
8ec78c48
MN
884 'limitnum' => $limitnum,
885 'newest' => $newest
3cd13828
MN
886 );
887 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
837941e9 888 self::validate_context($systemcontext);
3cd13828 889
837941e9
MN
890 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
891 throw new moodle_exception('You do not have permission to perform this action.');
892 }
3cd13828 893
8ec78c48
MN
894 if ($newest) {
895 $sort = 'timecreated DESC';
896 } else {
897 $sort = 'timecreated ASC';
898 }
899 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom, $limitnum, $sort);
3cd13828
MN
900
901 $renderer = $PAGE->get_renderer('core_message');
902 return $messages->export_for_template($renderer);
903 }
904
905 /**
49aaadc3 906 * The messagearea messages return structure.
3cd13828 907 *
49aaadc3
MN
908 * @return external_single_structure
909 * @since 3.2
3cd13828
MN
910 */
911 public static function data_for_messagearea_messages_returns() {
49aaadc3 912 return new external_single_structure(
3cd13828 913 array(
7b55aaa1
MN
914 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
915 the messages on behalf of?'),
3cd13828
MN
916 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
917 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
918 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
bf58081d 919 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
3cd13828 920 'messages' => new external_multiple_structure(
94e1db61 921 self::get_messagearea_message_structure()
3cd13828
MN
922 )
923 )
924 );
925 }
926
c060cd49 927 /**
49aaadc3 928 * The get most recent message return parameters.
c060cd49
MN
929 *
930 * @return external_function_parameters
49aaadc3 931 * @since 3.2
c060cd49
MN
932 */
933 public static function data_for_messagearea_get_most_recent_message_parameters() {
934 return new external_function_parameters(
935 array(
936 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
937 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
938 )
939 );
940 }
941
942 /**
943 * Get the most recent message in a conversation.
944 *
945 * @param int $currentuserid The current user's id
946 * @param int $otheruserid The other user's id
49aaadc3
MN
947 * @return stdClass
948 * @throws moodle_exception
949 * @since 3.2
c060cd49
MN
950 */
951 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
837941e9 952 global $CFG, $PAGE, $USER;
c060cd49
MN
953
954 // Check if messaging is enabled.
837941e9 955 if (empty($CFG->messaging)) {
c060cd49
MN
956 throw new moodle_exception('disabled', 'message');
957 }
958
837941e9
MN
959 $systemcontext = context_system::instance();
960
c060cd49
MN
961 $params = array(
962 'currentuserid' => $currentuserid,
963 'otheruserid' => $otheruserid
964 );
965 self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
837941e9 966 self::validate_context($systemcontext);
c060cd49 967
837941e9
MN
968 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
969 throw new moodle_exception('You do not have permission to perform this action.');
970 }
c060cd49
MN
971
972 $message = \core_message\api::get_most_recent_message($currentuserid, $otheruserid);
973
974 $renderer = $PAGE->get_renderer('core_message');
975 return $message->export_for_template($renderer);
976 }
977
978 /**
49aaadc3 979 * The get most recent message return structure.
c060cd49
MN
980 *
981 * @return external_single_structure
49aaadc3 982 * @since 3.2
c060cd49
MN
983 */
984 public static function data_for_messagearea_get_most_recent_message_returns() {
94e1db61 985 return self::get_messagearea_message_structure();
c060cd49
MN
986 }
987
c6e97f54
MN
988 /**
989 * The get profile parameters.
990 *
991 * @return external_function_parameters
49aaadc3 992 * @since 3.2
c6e97f54
MN
993 */
994 public static function data_for_messagearea_get_profile_parameters() {
995 return new external_function_parameters(
996 array(
997 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
998 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
999 )
1000 );
1001 }
1002
1003 /**
1004 * Get the profile information for a contact.
1005 *
1006 * @param int $currentuserid The current user's id
1007 * @param int $otheruserid The id of the user whose profile we are viewing
49aaadc3
MN
1008 * @return stdClass
1009 * @throws moodle_exception
1010 * @since 3.2
c6e97f54
MN
1011 */
1012 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
837941e9 1013 global $CFG, $PAGE, $USER;
c6e97f54
MN
1014
1015 // Check if messaging is enabled.
837941e9 1016 if (empty($CFG->messaging)) {
c6e97f54
MN
1017 throw new moodle_exception('disabled', 'message');
1018 }
1019
837941e9
MN
1020 $systemcontext = context_system::instance();
1021
c6e97f54
MN
1022 $params = array(
1023 'currentuserid' => $currentuserid,
1024 'otheruserid' => $otheruserid
1025 );
1026 self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
837941e9 1027 self::validate_context($systemcontext);
c6e97f54 1028
837941e9
MN
1029 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1030 throw new moodle_exception('You do not have permission to perform this action.');
1031 }
c6e97f54
MN
1032
1033 $profile = \core_message\api::get_profile($currentuserid, $otheruserid);
1034
1035 $renderer = $PAGE->get_renderer('core_message');
1036 return $profile->export_for_template($renderer);
1037 }
1038
1039 /**
49aaadc3 1040 * The get profile return structure.
c6e97f54
MN
1041 *
1042 * @return external_single_structure
49aaadc3 1043 * @since 3.2
c6e97f54
MN
1044 */
1045 public static function data_for_messagearea_get_profile_returns() {
1046 return new external_single_structure(
1047 array(
7b55aaa1
MN
1048 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
1049 the profile on behalf of?'),
c6e97f54
MN
1050 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1051 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
1052 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
1053 'country' => new external_value(core_user::get_property_type('country'), 'Home country code of the user'),
1054 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
1055 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1056 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1057 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
bf58081d 1058 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
c6e97f54
MN
1059 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
1060 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
1061 )
1062 );
1063 }
1064
d6731600
FM
1065 /**
1066 * Get contacts parameters description.
1067 *
1068 * @return external_function_parameters
5bcfd504 1069 * @since Moodle 2.5
d6731600
FM
1070 */
1071 public static function get_contacts_parameters() {
1072 return new external_function_parameters(array());
1073 }
1074
1075 /**
1076 * Get contacts.
1077 *
d6731600 1078 * @return external_description
5bcfd504 1079 * @since Moodle 2.5
d6731600
FM
1080 */
1081 public static function get_contacts() {
d85bedf7 1082 global $CFG, $PAGE;
436bbf89
DM
1083
1084 // Check if messaging is enabled.
837941e9 1085 if (empty($CFG->messaging)) {
436bbf89
DM
1086 throw new moodle_exception('disabled', 'message');
1087 }
1088
d6731600
FM
1089 require_once($CFG->dirroot . '/user/lib.php');
1090
1091 list($online, $offline, $strangers) = message_get_contacts();
1092 $allcontacts = array('online' => $online, 'offline' => $offline, 'strangers' => $strangers);
1093 foreach ($allcontacts as $mode => $contacts) {
1094 foreach ($contacts as $key => $contact) {
1095 $newcontact = array(
1096 'id' => $contact->id,
1097 'fullname' => fullname($contact),
1098 'unread' => $contact->messagecount
1099 );
1100
d85bedf7
JL
1101 $userpicture = new user_picture($contact);
1102 $userpicture->size = 1; // Size f1.
1103 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1104 $userpicture->size = 0; // Size f2.
1105 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
1106
1107 $allcontacts[$mode][$key] = $newcontact;
1108 }
1109 }
1110 return $allcontacts;
1111 }
1112
1113 /**
1114 * Get contacts return description.
1115 *
1116 * @return external_description
5bcfd504 1117 * @since Moodle 2.5
d6731600
FM
1118 */
1119 public static function get_contacts_returns() {
1120 return new external_single_structure(
1121 array(
1122 'online' => new external_multiple_structure(
1123 new external_single_structure(
1124 array(
1125 'id' => new external_value(PARAM_INT, 'User ID'),
1126 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1127 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1128 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1129 'unread' => new external_value(PARAM_INT, 'Unread message count')
1130 )
1131 ),
1132 'List of online contacts'
1133 ),
1134 'offline' => new external_multiple_structure(
1135 new external_single_structure(
1136 array(
1137 'id' => new external_value(PARAM_INT, 'User ID'),
1138 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1139 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1140 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1141 'unread' => new external_value(PARAM_INT, 'Unread message count')
1142 )
1143 ),
1144 'List of offline contacts'
1145 ),
1146 'strangers' => new external_multiple_structure(
1147 new external_single_structure(
1148 array(
1149 'id' => new external_value(PARAM_INT, 'User ID'),
1150 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1151 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1152 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1153 'unread' => new external_value(PARAM_INT, 'Unread message count')
1154 )
1155 ),
1156 'List of users that are not in the user\'s contact list but have sent a message'
1157 )
1158 )
1159 );
1160 }
1161
1162 /**
1163 * Search contacts parameters description.
1164 *
1165 * @return external_function_parameters
5bcfd504 1166 * @since Moodle 2.5
d6731600
FM
1167 */
1168 public static function search_contacts_parameters() {
1169 return new external_function_parameters(
1170 array(
1171 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
1172 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
1173 VALUE_DEFAULT, false)
1174 )
1175 );
1176 }
1177
1178 /**
1179 * Search contacts.
1180 *
1181 * @param string $searchtext query string.
1182 * @param bool $onlymycourses limit the search to the user's courses only.
1183 * @return external_description
5bcfd504 1184 * @since Moodle 2.5
d6731600
FM
1185 */
1186 public static function search_contacts($searchtext, $onlymycourses = false) {
d85bedf7 1187 global $CFG, $USER, $PAGE;
11d83ab3 1188 require_once($CFG->dirroot . '/user/lib.php');
436bbf89
DM
1189
1190 // Check if messaging is enabled.
837941e9 1191 if (empty($CFG->messaging)) {
436bbf89
DM
1192 throw new moodle_exception('disabled', 'message');
1193 }
1194
d6731600
FM
1195 require_once($CFG->libdir . '/enrollib.php');
1196
1197 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1198 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
1199
1200 // Extra validation, we do not allow empty queries.
1201 if ($params['searchtext'] === '') {
1202 throw new moodle_exception('querystringcannotbeempty');
1203 }
1204
1205 $courseids = array();
1206 if ($params['onlymycourses']) {
1207 $mycourses = enrol_get_my_courses(array('id'));
1208 foreach ($mycourses as $mycourse) {
1209 $courseids[] = $mycourse->id;
1210 }
1211 } else {
1212 $courseids[] = SITEID;
1213 }
1214
1215 // Retrieving the users matching the query.
1216 $users = message_search_users($courseids, $params['searchtext']);
1217 $results = array();
1218 foreach ($users as $user) {
1219 $results[$user->id] = $user;
1220 }
1221
1222 // Reorganising information.
1223 foreach ($results as &$user) {
1224 $newuser = array(
1225 'id' => $user->id,
1226 'fullname' => fullname($user)
1227 );
1228
1229 // Avoid undefined property notice as phone not specified.
1230 $user->phone1 = null;
1231 $user->phone2 = null;
1232
d85bedf7
JL
1233 $userpicture = new user_picture($user);
1234 $userpicture->size = 1; // Size f1.
1235 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1236 $userpicture->size = 0; // Size f2.
1237 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
1238
1239 $user = $newuser;
1240 }
1241
1242 return $results;
1243 }
1244
1245 /**
1246 * Search contacts return description.
1247 *
1248 * @return external_description
5bcfd504 1249 * @since Moodle 2.5
d6731600
FM
1250 */
1251 public static function search_contacts_returns() {
1252 return new external_multiple_structure(
1253 new external_single_structure(
1254 array(
1255 'id' => new external_value(PARAM_INT, 'User ID'),
1256 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1257 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1258 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
1259 )
1260 ),
1261 'List of contacts'
1262 );
1263 }
aff9da17
JL
1264
1265 /**
1266 * Get messages parameters description.
1267 *
1268 * @return external_function_parameters
193edf7f 1269 * @since 2.8
aff9da17
JL
1270 */
1271 public static function get_messages_parameters() {
1272 return new external_function_parameters(
1273 array(
6ff4464b 1274 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
127ef540
SH
1275 'useridfrom' => new external_value(
1276 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1277 VALUE_DEFAULT, 0),
1278 'type' => new external_value(
1279 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
1280 VALUE_DEFAULT, 'both'),
6ff4464b 1281 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
127ef540
SH
1282 'newestfirst' => new external_value(
1283 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1284 VALUE_DEFAULT, true),
aff9da17 1285 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
127ef540
SH
1286 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
1287 )
aff9da17
JL
1288 );
1289 }
1290
1291 /**
1292 * Get messages function implementation.
127ef540
SH
1293 *
1294 * @since 2.8
1295 * @throws invalid_parameter_exception
1296 * @throws moodle_exception
6ff4464b
JL
1297 * @param int $useridto the user id who received the message
1298 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
193edf7f 1299 * @param string $type type of message to return, expected values: notifications, conversations and both
aff9da17 1300 * @param bool $read true for retreiving read messages, false for unread
6ff4464b 1301 * @param bool $newestfirst true for ordering by newest first, false for oldest first
aff9da17
JL
1302 * @param int $limitfrom limit from
1303 * @param int $limitnum limit num
1304 * @return external_description
aff9da17 1305 */
193edf7f 1306 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
aff9da17 1307 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
127ef540 1308 global $CFG, $USER;
aff9da17
JL
1309
1310 $warnings = array();
1311
1312 $params = array(
1313 'useridto' => $useridto,
6ff4464b 1314 'useridfrom' => $useridfrom,
aff9da17
JL
1315 'type' => $type,
1316 'read' => $read,
aff9da17
JL
1317 'newestfirst' => $newestfirst,
1318 'limitfrom' => $limitfrom,
1319 'limitnum' => $limitnum
1320 );
1321
1322 $params = self::validate_parameters(self::get_messages_parameters(), $params);
1323
1324 $context = context_system::instance();
1325 self::validate_context($context);
1326
1327 $useridto = $params['useridto'];
6ff4464b 1328 $useridfrom = $params['useridfrom'];
aff9da17
JL
1329 $type = $params['type'];
1330 $read = $params['read'];
aff9da17
JL
1331 $newestfirst = $params['newestfirst'];
1332 $limitfrom = $params['limitfrom'];
1333 $limitnum = $params['limitnum'];
1334
1335 $allowedvalues = array('notifications', 'conversations', 'both');
1336 if (!in_array($type, $allowedvalues)) {
1337 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1338 'allowed values are: ' . implode(',', $allowedvalues));
1339 }
1340
1341 // Check if private messaging between users is allowed.
1342 if (empty($CFG->messaging)) {
1343 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
aff9da17
JL
1344 if ($type == "conversations") {
1345 throw new moodle_exception('disabled', 'message');
1346 }
1347 if ($type == "both") {
1348 $warning = array();
1349 $warning['item'] = 'message';
1350 $warning['itemid'] = $USER->id;
1351 $warning['warningcode'] = '1';
1352 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1353 Only notifications will be returned';
1354 $warnings[] = $warning;
1355 }
1356 }
1357
1358 if (!empty($useridto)) {
6ff4464b
JL
1359 if (core_user::is_real_user($useridto)) {
1360 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1361 } else {
1362 throw new moodle_exception('invaliduser');
1363 }
aff9da17
JL
1364 }
1365
1366 if (!empty($useridfrom)) {
1367 // We use get_user here because the from user can be the noreply or support user.
1368 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1369 }
1370
1371 // Check if the current user is the sender/receiver or just a privileged user.
1372 if ($useridto != $USER->id and $useridfrom != $USER->id and
1373 !has_capability('moodle/site:readallmessages', $context)) {
1374 throw new moodle_exception('accessdenied', 'admin');
1375 }
1376
127ef540 1377 // Which type of messages to retrieve.
193edf7f 1378 $notifications = -1;
aff9da17 1379 if ($type != 'both') {
193edf7f 1380 $notifications = ($type == 'notifications') ? 1 : 0;
aff9da17
JL
1381 }
1382
aff9da17 1383 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
193edf7f 1384 $sort = "mr.timecreated $orderdirection";
aff9da17 1385
193edf7f 1386 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
aff9da17
JL
1387 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1388
1389 // In some cases, we don't need to get the to/from user objects from the sql query.
1390 $userfromfullname = '';
1391 $usertofullname = '';
1392
1393 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1394 if (!empty($useridto)) {
1395 $usertofullname = fullname($userto, $canviewfullname);
1396 // The user from may or may not be filled.
1397 if (!empty($useridfrom)) {
1398 $userfromfullname = fullname($userfrom, $canviewfullname);
1399 }
1400 } else {
1401 // If the useridto field is empty, the useridfrom must be filled.
1402 $userfromfullname = fullname($userfrom, $canviewfullname);
1403 }
aff9da17
JL
1404 foreach ($messages as $mid => $message) {
1405
ea21d637
JL
1406 // Do not return deleted messages.
1407 if (($useridto == $USER->id and $message->timeusertodeleted) or
1408 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
1409
1410 unset($messages[$mid]);
1411 continue;
1412 }
1413
aff9da17
JL
1414 // We need to get the user from the query.
1415 if (empty($userfromfullname)) {
6ff4464b
JL
1416 // Check for non-reply and support users.
1417 if (core_user::is_real_user($message->useridfrom)) {
127ef540 1418 $user = new stdClass();
6ff4464b
JL
1419 $user = username_load_fields_from_object($user, $message, 'userfrom');
1420 $message->userfromfullname = fullname($user, $canviewfullname);
1421 } else {
1422 $user = core_user::get_user($message->useridfrom);
1423 $message->userfromfullname = fullname($user, $canviewfullname);
1424 }
aff9da17
JL
1425 } else {
1426 $message->userfromfullname = $userfromfullname;
1427 }
1428
1429 // We need to get the user from the query.
1430 if (empty($usertofullname)) {
127ef540 1431 $user = new stdClass();
aff9da17
JL
1432 $user = username_load_fields_from_object($user, $message, 'userto');
1433 $message->usertofullname = fullname($user, $canviewfullname);
1434 } else {
1435 $message->usertofullname = $usertofullname;
1436 }
1437
193edf7f 1438 // This field is only available in the message_read table.
aff9da17
JL
1439 if (!isset($message->timeread)) {
1440 $message->timeread = 0;
1441 }
1442
aff9da17 1443 $message->text = message_format_message_text($message);
aff9da17
JL
1444 $messages[$mid] = (array) $message;
1445 }
1446 }
1447
1448 $results = array(
1449 'messages' => $messages,
1450 'warnings' => $warnings
1451 );
1452
1453 return $results;
1454 }
1455
1456 /**
1457 * Get messages return description.
1458 *
6ff4464b 1459 * @return external_single_structure
193edf7f 1460 * @since 2.8
aff9da17
JL
1461 */
1462 public static function get_messages_returns() {
1463 return new external_single_structure(
1464 array(
1465 'messages' => new external_multiple_structure(
1466 new external_single_structure(
1467 array(
193edf7f 1468 'id' => new external_value(PARAM_INT, 'Message id'),
aff9da17
JL
1469 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1470 'useridto' => new external_value(PARAM_INT, 'User to id'),
1471 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1472 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1473 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
193edf7f 1474 'fullmessageformat' => new external_format_value('fullmessage'),
aff9da17
JL
1475 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1476 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1477 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
1478 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1479 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1480 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1481 'timeread' => new external_value(PARAM_INT, 'Time read'),
1482 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
1483 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
1484 ), 'message'
1485 )
1486 ),
1487 'warnings' => new external_warnings()
1488 )
1489 );
3274d5ca
RW
1490 }
1491
1492 /**
ada7695d 1493 * Get popup notifications parameters description.
3274d5ca
RW
1494 *
1495 * @return external_function_parameters
1496 * @since 3.2
1497 */
ada7695d 1498 public static function get_popup_notifications_parameters() {
3274d5ca
RW
1499 return new external_function_parameters(
1500 array(
1501 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3274d5ca
RW
1502 'status' => new external_value(
1503 PARAM_ALPHA, 'filter the results to just "read" or "unread" notifications',
1504 VALUE_DEFAULT, ''),
1505 'embeduserto' => new external_value(
1506 PARAM_BOOL, 'true for returning user details for the recipient in each notification',
1507 VALUE_DEFAULT, false),
1508 'embeduserfrom' => new external_value(
1509 PARAM_BOOL, 'true for returning user details for the sender in each notification',
1510 VALUE_DEFAULT, false),
1511 'newestfirst' => new external_value(
1512 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1513 VALUE_DEFAULT, true),
1514 'markasread' => new external_value(
1515 PARAM_BOOL, 'mark notifications as read when they are returned by this function',
1516 VALUE_DEFAULT, false),
1517 'limit' => new external_value(PARAM_INT, 'the number of results to return', VALUE_DEFAULT, 0),
1518 'offset' => new external_value(PARAM_INT, 'offset the result set by a given amount', VALUE_DEFAULT, 0)
1519 )
1520 );
1521 }
1522
1523 /**
1524 * Get notifications function.
1525 *
1526 * @since 3.2
1527 * @throws invalid_parameter_exception
1528 * @throws moodle_exception
c5dd16a1 1529 * @param int $useridto the user id who received the message
c5dd16a1 1530 * @param string $status filter the results to only read or unread notifications
c5dd16a1
RW
1531 * @param bool $embeduserto true to embed the recipient user details in the record for each notification
1532 * @param bool $embeduserfrom true to embed the send user details in the record for each notification
1533 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1534 * @param bool $markasread mark notifications as read when they are returned by this function
1535 * @param int $limit the number of results to return
1536 * @param int $offset offset the result set by a given amount
3274d5ca
RW
1537 * @return external_description
1538 */
0b19d048
RW
1539 public static function get_popup_notifications($useridto, $status, $embeduserto,
1540 $embeduserfrom, $newestfirst, $markasread, $limit, $offset) {
837941e9 1541 global $USER, $PAGE;
3274d5ca
RW
1542
1543 $params = self::validate_parameters(
ada7695d 1544 self::get_popup_notifications_parameters(),
3274d5ca
RW
1545 array(
1546 'useridto' => $useridto,
3274d5ca
RW
1547 'status' => $status,
1548 'embeduserto' => $embeduserto,
1549 'embeduserfrom' => $embeduserfrom,
1550 'newestfirst' => $newestfirst,
1551 'markasread' => $markasread,
1552 'limit' => $limit,
1553 'offset' => $offset,
1554 )
1555 );
1556
1557 $context = context_system::instance();
1558 self::validate_context($context);
1559
1560 $useridto = $params['useridto'];
3274d5ca
RW
1561 $status = $params['status'];
1562 $embeduserto = $params['embeduserto'];
1563 $embeduserfrom = $params['embeduserfrom'];
1564 $newestfirst = $params['newestfirst'];
1565 $markasread = $params['markasread'];
1566 $limit = $params['limit'];
1567 $offset = $params['offset'];
c5dd16a1 1568 $issuperuser = has_capability('moodle/site:readallmessages', $context);
24a76780 1569 $renderer = $PAGE->get_renderer('core_message');
3274d5ca
RW
1570
1571 if (!empty($useridto)) {
1572 if (core_user::is_real_user($useridto)) {
1573 if ($embeduserto) {
1574 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1575 }
1576 } else {
1577 throw new moodle_exception('invaliduser');
1578 }
1579 }
1580
3274d5ca 1581 // Check if the current user is the sender/receiver or just a privileged user.
ada7695d 1582 if ($useridto != $USER->id and !$issuperuser) {
3274d5ca
RW
1583 throw new moodle_exception('accessdenied', 'admin');
1584 }
1585
1586 $sort = $newestfirst ? 'DESC' : 'ASC';
7b55aaa1
MN
1587 $notifications = \core_message\api::get_popup_notifications($useridto, $status, $embeduserto,
1588 $embeduserfrom, $sort, $limit, $offset);
24a76780 1589 $notificationcontexts = [];
3274d5ca
RW
1590
1591 if ($notifications) {
ada7695d 1592 // In some cases, we don't need to get the to user objects from the sql query.
3274d5ca
RW
1593 $usertofullname = '';
1594
1595 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1596 if (!empty($useridto) && $embeduserto) {
1597 $usertofullname = fullname($userto);
3274d5ca
RW
1598 }
1599
1600 foreach ($notifications as $notification) {
1601
24a76780 1602 $notificationoutput = new \core_message\output\popup_notification($notification, $embeduserto,
0b19d048 1603 $embeduserfrom, $usertofullname);
3274d5ca 1604
24a76780
RW
1605 $notificationcontext = $notificationoutput->export_for_template($renderer);
1606 $notificationcontexts[] = $notificationcontext;
c5dd16a1 1607
24a76780
RW
1608 if ($markasread && !$notificationcontext->read) {
1609 message_mark_message_read($notification, time());
3274d5ca
RW
1610 }
1611 }
1612 }
1613
1614 return array(
24a76780 1615 'notifications' => $notificationcontexts,
79f6c36c 1616 'unreadcount' => \core_message\api::count_unread_popup_notifications($useridto),
3274d5ca
RW
1617 );
1618 }
1619
1620 /**
1621 * Get notifications return description.
1622 *
1623 * @return external_single_structure
1624 * @since 3.2
1625 */
ada7695d 1626 public static function get_popup_notifications_returns() {
3274d5ca
RW
1627 return new external_single_structure(
1628 array(
1629 'notifications' => new external_multiple_structure(
1630 new external_single_structure(
1631 array(
7b55aaa1
MN
1632 'id' => new external_value(PARAM_INT, 'Notification id (this is not guaranteed to be unique
1633 within this result set)'),
3274d5ca
RW
1634 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1635 'useridto' => new external_value(PARAM_INT, 'User to id'),
1636 'subject' => new external_value(PARAM_TEXT, 'The notification subject'),
7b55aaa1
MN
1637 'shortenedsubject' => new external_value(PARAM_TEXT, 'The notification subject shortened
1638 with ellipsis'),
3274d5ca
RW
1639 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1640 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
1641 'fullmessageformat' => new external_format_value('fullmessage'),
1642 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1643 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1644 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1645 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1646 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1647 'timecreatedpretty' => new external_value(PARAM_TEXT, 'Time created in a pretty format'),
1648 'timeread' => new external_value(PARAM_INT, 'Time read'),
1649 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name', VALUE_OPTIONAL),
1650 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name', VALUE_OPTIONAL),
1651 'userfromprofileurl' => new external_value(PARAM_URL, 'User from profile url', VALUE_OPTIONAL),
1652 'read' => new external_value(PARAM_BOOL, 'notification read status'),
1653 'deleted' => new external_value(PARAM_BOOL, 'notification deletion status'),
1654 'iconurl' => new external_value(PARAM_URL, 'URL for notification icon'),
7b55aaa1
MN
1655 'component' => new external_value(PARAM_TEXT, 'The component that generated the notification',
1656 VALUE_OPTIONAL),
3274d5ca
RW
1657 'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL),
1658 ), 'message'
1659 )
1660 ),
1661 'unreadcount' => new external_value(PARAM_INT, 'the user whose blocked users we want to retrieve'),
1662 )
1663 );
1664 }
1665
1666 /**
1667 * Mark all notifications as read parameters description.
1668 *
1669 * @return external_function_parameters
1670 * @since 3.2
1671 */
1672 public static function mark_all_notifications_as_read_parameters() {
1673 return new external_function_parameters(
1674 array(
1675 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1676 'useridfrom' => new external_value(
1677 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1678 VALUE_DEFAULT, 0),
1679 )
1680 );
1681 }
1682
1683 /**
1684 * Mark all notifications as read function.
1685 *
1686 * @since 3.2
1687 * @throws invalid_parameter_exception
1688 * @throws moodle_exception
1689 * @param int $useridto the user id who received the message
1690 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1691 * @return external_description
1692 */
1693 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
837941e9 1694 global $USER;
3274d5ca
RW
1695
1696 $params = self::validate_parameters(
1697 self::mark_all_notifications_as_read_parameters(),
1698 array(
1699 'useridto' => $useridto,
1700 'useridfrom' => $useridfrom,
1701 )
1702 );
1703
1704 $context = context_system::instance();
1705 self::validate_context($context);
1706
1707 $useridto = $params['useridto'];
1708 $useridfrom = $params['useridfrom'];
1709
1710 if (!empty($useridto)) {
1711 if (core_user::is_real_user($useridto)) {
1712 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1713 } else {
1714 throw new moodle_exception('invaliduser');
1715 }
1716 }
1717
1718 if (!empty($useridfrom)) {
1719 // We use get_user here because the from user can be the noreply or support user.
1720 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1721 }
1722
1723 // Check if the current user is the sender/receiver or just a privileged user.
1724 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 1725 // The deleteanymessage cap seems more reasonable here than readallmessages.
3274d5ca
RW
1726 !has_capability('moodle/site:deleteanymessage', $context)) {
1727 throw new moodle_exception('accessdenied', 'admin');
1728 }
1729
79f6c36c 1730 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_NOTIFICATION);
3274d5ca
RW
1731
1732 return true;
1733 }
1734
1735 /**
1736 * Mark all notifications as read return description.
1737 *
1738 * @return external_single_structure
1739 * @since 3.2
1740 */
1741 public static function mark_all_notifications_as_read_returns() {
1742 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
1743 }
1744
1745 /**
1746 * Get unread notification count parameters description.
1747 *
1748 * @return external_function_parameters
1749 * @since 3.2
1750 */
ada7695d 1751 public static function get_unread_popup_notification_count_parameters() {
3274d5ca
RW
1752 return new external_function_parameters(
1753 array(
1754 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3274d5ca
RW
1755 )
1756 );
1757 }
1758
1759 /**
1760 * Get unread notification count function.
1761 *
1762 * @since 3.2
1763 * @throws invalid_parameter_exception
1764 * @throws moodle_exception
1765 * @param int $useridto the user id who received the message
3274d5ca
RW
1766 * @return external_description
1767 */
ada7695d 1768 public static function get_unread_popup_notification_count($useridto) {
837941e9 1769 global $USER;
3274d5ca
RW
1770
1771 $params = self::validate_parameters(
ada7695d
RW
1772 self::get_unread_popup_notification_count_parameters(),
1773 array('useridto' => $useridto)
3274d5ca
RW
1774 );
1775
1776 $context = context_system::instance();
1777 self::validate_context($context);
1778
1779 $useridto = $params['useridto'];
3274d5ca
RW
1780
1781 if (!empty($useridto)) {
1782 if (core_user::is_real_user($useridto)) {
1783 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1784 } else {
1785 throw new moodle_exception('invaliduser');
1786 }
1787 }
1788
3274d5ca 1789 // Check if the current user is the sender/receiver or just a privileged user.
ada7695d 1790 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
3274d5ca
RW
1791 throw new moodle_exception('accessdenied', 'admin');
1792 }
1793
79f6c36c 1794 return \core_message\api::count_unread_popup_notifications($useridto);
3274d5ca
RW
1795 }
1796
1797 /**
ada7695d 1798 * Get unread popup notification count return description.
3274d5ca
RW
1799 *
1800 * @return external_single_structure
1801 * @since 3.2
1802 */
ada7695d 1803 public static function get_unread_popup_notification_count_returns() {
8c55bd6c
RW
1804 return new external_value(PARAM_INT, 'The count of unread popup notifications');
1805 }
1806
1807 /**
1808 * Get unread conversations count parameters description.
1809 *
1810 * @return external_function_parameters
1811 * @since 3.2
1812 */
1813 public static function get_unread_conversations_count_parameters() {
1814 return new external_function_parameters(
1815 array(
1816 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1817 )
1818 );
1819 }
1820
1821 /**
1822 * Get unread messages count function.
1823 *
1824 * @since 3.2
1825 * @throws invalid_parameter_exception
1826 * @throws moodle_exception
1827 * @param int $useridto the user id who received the message
1828 * @return external_description
1829 */
1830 public static function get_unread_conversations_count($useridto) {
1831 global $USER;
1832
1833 $params = self::validate_parameters(
1834 self::get_unread_conversations_count_parameters(),
1835 array('useridto' => $useridto)
1836 );
1837
1838 $context = context_system::instance();
1839 self::validate_context($context);
1840
1841 $useridto = $params['useridto'];
1842
1843 if (!empty($useridto)) {
1844 if (core_user::is_real_user($useridto)) {
1845 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1846 } else {
1847 throw new moodle_exception('invaliduser');
1848 }
1849 } else {
1850 $useridto = $USER->id;
1851 }
1852
1853 // Check if the current user is the receiver or just a privileged user.
1854 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1855 throw new moodle_exception('accessdenied', 'admin');
1856 }
1857
79f6c36c 1858 return \core_message\api::count_unread_conversations($userto);
8c55bd6c
RW
1859 }
1860
1861 /**
1862 * Get unread conversations count return description.
1863 *
1864 * @return external_single_structure
1865 * @since 3.2
1866 */
1867 public static function get_unread_conversations_count_returns() {
1868 return new external_value(PARAM_INT, 'The count of unread messages for the user');
aff9da17
JL
1869 }
1870
60ab2e1b
JL
1871 /**
1872 * Get blocked users parameters description.
1873 *
1874 * @return external_function_parameters
1875 * @since 2.9
1876 */
1877 public static function get_blocked_users_parameters() {
1878 return new external_function_parameters(
1879 array(
1880 'userid' => new external_value(PARAM_INT,
1881 'the user whose blocked users we want to retrieve',
1882 VALUE_REQUIRED),
1883 )
1884 );
1885 }
1886
1887 /**
1888 * Retrieve a list of users blocked
1889 *
1890 * @param int $userid the user whose blocked users we want to retrieve
1891 * @return external_description
1892 * @since 2.9
1893 */
1894 public static function get_blocked_users($userid) {
d85bedf7 1895 global $CFG, $USER, $PAGE;
60ab2e1b
JL
1896
1897 // Warnings array, it can be empty at the end but is mandatory.
1898 $warnings = array();
1899
1900 // Validate params.
1901 $params = array(
1902 'userid' => $userid
1903 );
1904 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
1905 $userid = $params['userid'];
1906
1907 // Validate context.
1908 $context = context_system::instance();
1909 self::validate_context($context);
1910
1911 // Check if private messaging between users is allowed.
1912 if (empty($CFG->messaging)) {
1913 throw new moodle_exception('disabled', 'message');
1914 }
1915
4485f7c5
JL
1916 $user = core_user::get_user($userid, '*', MUST_EXIST);
1917 core_user::require_active_user($user);
60ab2e1b
JL
1918
1919 // Check if we have permissions for retrieve the information.
1920 if ($userid != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1921 throw new moodle_exception('accessdenied', 'admin');
1922 }
1923
1924 // Now, we can get safely all the blocked users.
1925 $users = message_get_blocked_users($user);
1926
1927 $blockedusers = array();
1928 foreach ($users as $user) {
1929 $newuser = array(
1930 'id' => $user->id,
1931 'fullname' => fullname($user),
1932 );
0b074e88 1933
d85bedf7
JL
1934 $userpicture = new user_picture($user);
1935 $userpicture->size = 1; // Size f1.
1936 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
60ab2e1b
JL
1937
1938 $blockedusers[] = $newuser;
1939 }
1940
1941 $results = array(
1942 'users' => $blockedusers,
1943 'warnings' => $warnings
1944 );
1945 return $results;
1946 }
1947
1948 /**
1949 * Get blocked users return description.
1950 *
1951 * @return external_single_structure
1952 * @since 2.9
1953 */
1954 public static function get_blocked_users_returns() {
1955 return new external_single_structure(
1956 array(
1957 'users' => new external_multiple_structure(
1958 new external_single_structure(
1959 array(
1960 'id' => new external_value(PARAM_INT, 'User ID'),
1961 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1962 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
1963 )
1964 ),
1965 'List of blocked users'
1966 ),
1967 'warnings' => new external_warnings()
1968 )
1969 );
1970 }
1971
31c474da
JL
1972 /**
1973 * Returns description of method parameters
1974 *
1975 * @return external_function_parameters
1976 * @since 2.9
1977 */
1978 public static function mark_message_read_parameters() {
1979 return new external_function_parameters(
1980 array(
1981 'messageid' => new external_value(PARAM_INT, 'id of the message (in the message table)'),
7b55aaa1
MN
1982 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
1983 VALUE_DEFAULT, 0)
31c474da
JL
1984 )
1985 );
1986 }
1987
1988 /**
1989 * Mark a single message as read, trigger message_viewed event
1990 *
1991 * @param int $messageid id of the message (in the message table)
1992 * @param int $timeread timestamp for when the message should be marked read
1993 * @return external_description
1994 * @throws invalid_parameter_exception
1995 * @throws moodle_exception
1996 * @since 2.9
1997 */
1998 public static function mark_message_read($messageid, $timeread) {
1999 global $CFG, $DB, $USER;
31c474da
JL
2000
2001 // Check if private messaging between users is allowed.
2002 if (empty($CFG->messaging)) {
2003 throw new moodle_exception('disabled', 'message');
2004 }
2005
2006 // Warnings array, it can be empty at the end but is mandatory.
2007 $warnings = array();
2008
2009 // Validate params.
2010 $params = array(
2011 'messageid' => $messageid,
2012 'timeread' => $timeread
2013 );
2014 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
2015
0b19d048
RW
2016 if (empty($params['timeread'])) {
2017 $timeread = time();
2018 } else {
2019 $timeread = $params['timeread'];
2020 }
2021
31c474da
JL
2022 // Validate context.
2023 $context = context_system::instance();
2024 self::validate_context($context);
2025
2026 $message = $DB->get_record('message', array('id' => $params['messageid']), '*', MUST_EXIST);
2027
2028 if ($message->useridto != $USER->id) {
2029 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2030 }
2031
0b19d048 2032 $messageid = message_mark_message_read($message, $timeread);
31c474da
JL
2033
2034 $results = array(
2035 'messageid' => $messageid,
2036 'warnings' => $warnings
2037 );
2038 return $results;
2039 }
2040
2041 /**
2042 * Returns description of method result value
2043 *
2044 * @return external_description
2045 * @since 2.9
2046 */
2047 public static function mark_message_read_returns() {
2048 return new external_single_structure(
2049 array(
2050 'messageid' => new external_value(PARAM_INT, 'the id of the message in the message_read table'),
2051 'warnings' => new external_warnings()
2052 )
2053 );
2054 }
2055
8c55bd6c
RW
2056 /**
2057 * Mark all messages as read parameters description.
2058 *
2059 * @return external_function_parameters
2060 * @since 3.2
2061 */
2062 public static function mark_all_messages_as_read_parameters() {
2063 return new external_function_parameters(
2064 array(
2065 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2066 'useridfrom' => new external_value(
2067 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2068 VALUE_DEFAULT, 0),
2069 )
2070 );
2071 }
2072
2073 /**
2074 * Mark all notifications as read function.
2075 *
2076 * @since 3.2
2077 * @throws invalid_parameter_exception
2078 * @throws moodle_exception
2079 * @param int $useridto the user id who received the message
2080 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2081 * @return external_description
2082 */
2083 public static function mark_all_messages_as_read($useridto, $useridfrom) {
837941e9 2084 global $USER;
8c55bd6c
RW
2085
2086 $params = self::validate_parameters(
2087 self::mark_all_messages_as_read_parameters(),
2088 array(
2089 'useridto' => $useridto,
2090 'useridfrom' => $useridfrom,
2091 )
2092 );
2093
2094 $context = context_system::instance();
2095 self::validate_context($context);
2096
2097 $useridto = $params['useridto'];
2098 $useridfrom = $params['useridfrom'];
2099
2100 if (!empty($useridto)) {
2101 if (core_user::is_real_user($useridto)) {
2102 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2103 } else {
2104 throw new moodle_exception('invaliduser');
2105 }
2106 }
2107
2108 if (!empty($useridfrom)) {
2109 // We use get_user here because the from user can be the noreply or support user.
2110 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2111 }
2112
2113 // Check if the current user is the sender/receiver or just a privileged user.
2114 if ($useridto != $USER->id and $useridfrom != $USER->id and
7b55aaa1 2115 // The deleteanymessage cap seems more reasonable here than readallmessages.
8c55bd6c
RW
2116 !has_capability('moodle/site:deleteanymessage', $context)) {
2117 throw new moodle_exception('accessdenied', 'admin');
2118 }
2119
79f6c36c 2120 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_MESSAGE);
8c55bd6c
RW
2121
2122 return true;
2123 }
2124
2125 /**
2126 * Mark all notifications as read return description.
2127 *
2128 * @return external_single_structure
2129 * @since 3.2
2130 */
2131 public static function mark_all_messages_as_read_returns() {
2132 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2133 }
2134
dec0cd99
MN
2135 /**
2136 * Returns description of method parameters.
2137 *
2138 * @return external_function_parameters
2139 * @since 3.2
2140 */
2141 public static function delete_conversation_parameters() {
2142 return new external_function_parameters(
2143 array(
2144 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
2145 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
2146 )
2147 );
2148 }
2149
2150 /**
2151 * Deletes a conversation.
2152 *
2153 * @param int $userid The user id of who we want to delete the conversation for
2154 * @param int $otheruserid The user id of the other user in the conversation
2155 * @return array
2156 * @throws moodle_exception
2157 * @since 3.2
2158 */
2159 public static function delete_conversation($userid, $otheruserid) {
2160 global $CFG;
2161
2162 // Check if private messaging between users is allowed.
2163 if (empty($CFG->messaging)) {
2164 throw new moodle_exception('disabled', 'message');
2165 }
2166
2167 // Warnings array, it can be empty at the end but is mandatory.
2168 $warnings = array();
2169
2170 // Validate params.
2171 $params = array(
2172 'userid' => $userid,
2173 'otheruserid' => $otheruserid,
2174 );
2175 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
2176
2177 // Validate context.
2178 $context = context_system::instance();
2179 self::validate_context($context);
2180
2181 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2182 core_user::require_active_user($user);
2183
2184 if (\core_message\api::can_delete_conversation($user->id)) {
2185 $status = \core_message\api::delete_conversation($user->id, $otheruserid);
2186 } else {
2187 throw new moodle_exception('You do not have permission to delete messages');
2188 }
2189
2190 $results = array(
2191 'status' => $status,
2192 'warnings' => $warnings
2193 );
2194
2195 return $results;
2196 }
2197
2198 /**
2199 * Returns description of method result value.
2200 *
2201 * @return external_description
2202 * @since 3.2
2203 */
2204 public static function delete_conversation_returns() {
2205 return new external_single_structure(
2206 array(
2207 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
2208 'warnings' => new external_warnings()
2209 )
2210 );
2211 }
2212
419b1128
JL
2213 /**
2214 * Returns description of method parameters
2215 *
2216 * @return external_function_parameters
2217 * @since 3.1
2218 */
2219 public static function delete_message_parameters() {
2220 return new external_function_parameters(
2221 array(
2222 'messageid' => new external_value(PARAM_INT, 'The message id'),
2223 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
2224 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
2225 )
2226 );
2227 }
2228
2229 /**
2230 * Deletes a message
2231 *
2232 * @param int $messageid the message id
2233 * @param int $userid the user id of who we want to delete the message for
2234 * @param bool $read if is a message read (default to true)
2235 * @return external_description
2236 * @throws moodle_exception
2237 * @since 3.1
2238 */
2239 public static function delete_message($messageid, $userid, $read = true) {
2240 global $CFG, $DB;
419b1128
JL
2241
2242 // Check if private messaging between users is allowed.
2243 if (empty($CFG->messaging)) {
2244 throw new moodle_exception('disabled', 'message');
2245 }
2246
2247 // Warnings array, it can be empty at the end but is mandatory.
2248 $warnings = array();
2249
2250 // Validate params.
2251 $params = array(
2252 'messageid' => $messageid,
2253 'userid' => $userid,
2254 'read' => $read
2255 );
2256 $params = self::validate_parameters(self::delete_message_parameters(), $params);
2257
2258 // Validate context.
2259 $context = context_system::instance();
2260 self::validate_context($context);
2261
2262 $messagestable = $params['read'] ? 'message_read' : 'message';
2263 $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
2264
2265 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2266 core_user::require_active_user($user);
2267
2268 $status = false;
2269 if (message_can_delete_message($message, $user->id)) {
2270 $status = message_delete_message($message, $user->id);;
2271 } else {
2272 throw new moodle_exception('You do not have permission to delete this message');
2273 }
2274
2275 $results = array(
2276 'status' => $status,
2277 'warnings' => $warnings
2278 );
2279 return $results;
2280 }
2281
2282 /**
2283 * Returns description of method result value
2284 *
2285 * @return external_description
2286 * @since 3.1
2287 */
2288 public static function delete_message_returns() {
2289 return new external_single_structure(
2290 array(
2291 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
2292 'warnings' => new external_warnings()
2293 )
2294 );
2295 }
2296
a0eabdd3
RW
2297 /**
2298 * Returns description of method parameters
2299 *
2300 * @return external_function_parameters
2301 * @since 3.2
2302 */
2303 public static function message_processor_config_form_parameters() {
2304 return new external_function_parameters(
2305 array(
2306 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
2307 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
2308 'formvalues' => new external_multiple_structure(
2309 new external_single_structure(
2310 array(
2311 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
2312 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
2313 )
2314 ),
2315 'Config form values',
2316 VALUE_REQUIRED
2317 ),
2318 )
2319 );
2320 }
2321
2322 /**
2323 * Processes a message processor config form.
2324 *
2325 * @param int $userid the user id
2326 * @param string $name the name of the processor
2327 * @param array $formvalues the form values
2328 * @return external_description
2329 * @throws moodle_exception
2330 * @since 3.2
2331 */
2332 public static function message_processor_config_form($userid, $name, $formvalues) {
8c125526
RW
2333 global $USER;
2334
a0eabdd3
RW
2335 $params = self::validate_parameters(
2336 self::message_processor_config_form_parameters(),
2337 array(
2338 'userid' => $userid,
2339 'name' => $name,
2340 'formvalues' => $formvalues,
2341 )
2342 );
2343
2344 if (empty($params['userid'])) {
2345 $params['userid'] = $USER->id;
2346 }
2347
2348 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2349 core_user::require_active_user($user);
2350
2351 $processor = get_message_processor($name);
2352 $preferences = [];
2353 $form = new stdClass();
2354
2355 foreach ($formvalues as $formvalue) {
2356 $form->$formvalue['name'] = $formvalue['value'];
2357 }
2358
2359 $processor->process_form($form, $preferences);
2360
2361 if (!empty($preferences)) {
2362 set_user_preferences($preferences, $userid);
2363 }
2364 }
2365
2366 /**
2367 * Returns description of method result value
2368 *
2369 * @return external_description
2370 * @since 3.2
2371 */
2372 public static function message_processor_config_form_returns() {
2373 return null;
2374 }
8c125526
RW
2375
2376 /**
2377 * Returns description of method parameters
2378 *
2379 * @return external_function_parameters
2380 * @since 3.2
2381 */
2382 public static function get_message_processor_parameters() {
2383 return new external_function_parameters(
2384 array(
2385 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
2386 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
2387 )
2388 );
2389 }
2390
2391 /**
2392 * Get a message processor.
2393 *
7b55aaa1
MN
2394 * @param int $userid
2395 * @param string $name the name of the processor
8c125526
RW
2396 * @return external_description
2397 * @throws moodle_exception
2398 * @since 3.2
2399 */
2400 public static function get_message_processor($userid = 0, $name) {
2401 global $USER, $PAGE;
2402
2403 $params = self::validate_parameters(
2404 self::get_message_processor_parameters(),
2405 array(
2406 'userid' => $userid,
2407 'name' => $name,
2408 )
2409 );
2410
2411 if (empty($params['userid'])) {
2412 $params['userid'] = $USER->id;
2413 }
2414
2415 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2416 core_user::require_active_user($user);
2417 self::validate_context(context_user::instance($params['userid']));
2418
2419 $processor = get_message_processor($name);
2420
2421 $processoroutput = new \core_message\output\processor($processor, $user);
2422 $renderer = $PAGE->get_renderer('core_message');
2423
2424 return $processoroutput->export_for_template($renderer);
2425 }
2426
2427 /**
2428 * Returns description of method result value
2429 *
2430 * @return external_description
2431 * @since 3.2
2432 */
2433 public static function get_message_processor_returns() {
2434 return new external_function_parameters(
2435 array(
2436 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
2437 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
2438 )
2439 );
2440 }
a623b6b8 2441}