MDL-55942 core_message: moved added functionality from message/lib.php
[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 */
501 public static function data_for_messagearea_search_people_in_course($userid, $courseid, $search, $limitfrom = 0, $limitnum = 0) {
837941e9 502 global $CFG, $PAGE, $USER;
cd03b8d7
MN
503
504 // Check if messaging is enabled.
837941e9 505 if (empty($CFG->messaging)) {
cd03b8d7
MN
506 throw new moodle_exception('disabled', 'message');
507 }
508
837941e9
MN
509 $systemcontext = context_system::instance();
510
cd03b8d7
MN
511 $params = array(
512 'userid' => $userid,
513 'courseid' => $courseid,
514 'search' => $search,
515 'limitfrom' => $limitfrom,
516 'limitnum' => $limitnum
517 );
518 self::validate_parameters(self::data_for_messagearea_search_people_in_course_parameters(), $params);
837941e9 519 self::validate_context($systemcontext);
cd03b8d7 520
837941e9
MN
521 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
522 throw new moodle_exception('You do not have permission to perform this action.');
523 }
cd03b8d7
MN
524
525 $search = \core_message\api::search_people_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
526
527 $renderer = $PAGE->get_renderer('core_message');
528 return $search->export_for_template($renderer);
529 }
530
531 /**
532 * Get messagearea search people returns.
533 *
534 * @return external_single_structure
535 * @since 3.2
536 */
537 public static function data_for_messagearea_search_people_in_course_returns() {
538 return new external_single_structure(
539 array(
540 'hascontacts' => new external_value(PARAM_BOOL, 'Are there contacts?'),
541 'contacts' => new external_multiple_structure(
a3e3a3a1 542 self::get_messagearea_contact_structure()
cd03b8d7
MN
543 ),
544 )
545 );
546 }
547
548 /**
549 * Get messagearea search people parameters.
550 *
551 * @return external_function_parameters
552 * @since 3.2
553 */
554 public static function data_for_messagearea_search_people_parameters() {
555 return new external_function_parameters(
556 array(
557 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
558 'search' => new external_value(PARAM_RAW, 'The string being searched'),
559 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
560 )
561 );
562 }
563
564 /**
565 * Get messagearea search people results.
566 *
567 * @param int $userid The id of the user who is performing the search
568 * @param string $search The string being searched
569 * @param int $limitnum
570 * @return stdClass
571 * @throws moodle_exception
572 * @since 3.2
573 */
574 public static function data_for_messagearea_search_people($userid, $search, $limitnum = 0) {
837941e9 575 global $CFG, $PAGE, $USER;
cd03b8d7
MN
576
577 // Check if messaging is enabled.
837941e9 578 if (empty($CFG->messaging)) {
cd03b8d7
MN
579 throw new moodle_exception('disabled', 'message');
580 }
581
837941e9
MN
582 $systemcontext = context_system::instance();
583
cd03b8d7
MN
584 $params = array(
585 'userid' => $userid,
586 'search' => $search,
587 'limitnum' => $limitnum
588 );
589 self::validate_parameters(self::data_for_messagearea_search_people_parameters(), $params);
837941e9 590 self::validate_context($systemcontext);
cd03b8d7 591
837941e9
MN
592 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
593 throw new moodle_exception('You do not have permission to perform this action.');
594 }
cd03b8d7
MN
595
596 $search = \core_message\api::search_people($userid, $search, $limitnum);
597
598 $renderer = $PAGE->get_renderer('core_message');
599 return $search->export_for_template($renderer);
600 }
601
602 /**
603 * Get messagearea search people returns.
604 *
605 * @return external_single_structure
606 * @since 3.2
607 */
608 public static function data_for_messagearea_search_people_returns() {
609 return new external_single_structure(
610 array(
611 'hascontacts' => new external_value(PARAM_BOOL, 'Are there contacts?'),
612 'contacts' => new external_multiple_structure(
a3e3a3a1 613 self::get_messagearea_contact_structure()
cd03b8d7
MN
614 ),
615 'hascourses' => new external_value(PARAM_BOOL, 'Are there courses?'),
616 'courses' => new external_multiple_structure(
617 new external_single_structure(
618 array(
619 'id' => new external_value(PARAM_INT, 'The course id'),
620 'shortname' => new external_value(PARAM_NOTAGS, 'The course shortname'),
621 'fullname' => new external_value(PARAM_NOTAGS, 'The course fullname'),
622 )
623 )
624 ),
625 'hasnoncontacts' => new external_value(PARAM_BOOL, 'Are there non-contacts?'),
626 'noncontacts' => new external_multiple_structure(
a3e3a3a1 627 self::get_messagearea_contact_structure()
cd03b8d7
MN
628 )
629 )
630 );
631 }
632
633 /**
634 * Get messagearea search messages parameters.
635 *
636 * @return external_function_parameters
637 * @since 3.2
638 */
639 public static function data_for_messagearea_search_messages_parameters() {
640 return new external_function_parameters(
641 array(
642 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
643 'search' => new external_value(PARAM_RAW, 'The string being searched'),
644 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
645 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
646 )
647 );
648 }
649
650 /**
651 * Get messagearea search messages results.
652 *
653 * @param int $userid The id of the user who is performing the search
654 * @param string $search The string being searched
655 * @param int $limitfrom
656 * @param int $limitnum
657 * @return stdClass
658 * @throws moodle_exception
659 * @since 3.2
660 */
661 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
837941e9 662 global $CFG, $PAGE, $USER;
cd03b8d7
MN
663
664 // Check if messaging is enabled.
837941e9 665 if (empty($CFG->messaging)) {
cd03b8d7
MN
666 throw new moodle_exception('disabled', 'message');
667 }
668
837941e9
MN
669 $systemcontext = context_system::instance();
670
cd03b8d7
MN
671 $params = array(
672 'userid' => $userid,
673 'search' => $search,
674 'limitfrom' => $limitfrom,
675 'limitnum' => $limitnum
676
677 );
678 self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
837941e9 679 self::validate_context($systemcontext);
cd03b8d7 680
837941e9
MN
681 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
682 throw new moodle_exception('You do not have permission to perform this action.');
683 }
cd03b8d7
MN
684
685 $search = \core_message\api::search_messages($userid, $search, $limitfrom, $limitnum);
686
687 $renderer = $PAGE->get_renderer('core_message');
688 return $search->export_for_template($renderer);
689 }
690
691 /**
692 * Get messagearea search messages returns.
693 *
694 * @return external_single_structure
695 * @since 3.2
696 */
697 public static function data_for_messagearea_search_messages_returns() {
698 return new external_single_structure(
699 array(
700 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
701 'contacts' => new external_multiple_structure(
a3e3a3a1 702 self::get_messagearea_contact_structure()
cd03b8d7
MN
703 )
704 )
705 );
706 }
707
9aa012b5 708 /**
49aaadc3 709 * The messagearea conversations parameters.
9aa012b5
MN
710 *
711 * @return external_function_parameters
49aaadc3 712 * @since 3.2
9aa012b5
MN
713 */
714 public static function data_for_messagearea_conversations_parameters() {
715 return new external_function_parameters(
716 array(
717 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
718 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
719 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
720 )
721 );
722 }
723
724 /**
725 * Get messagearea conversations.
726 *
727 * @param int $userid The id of the user who we are viewing conversations for
728 * @param int $limitfrom
729 * @param int $limitnum
49aaadc3
MN
730 * @return stdClass
731 * @throws moodle_exception
732 * @since 3.2
9aa012b5
MN
733 */
734 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 735 global $CFG, $PAGE, $USER;
9aa012b5
MN
736
737 // Check if messaging is enabled.
837941e9 738 if (empty($CFG->messaging)) {
9aa012b5
MN
739 throw new moodle_exception('disabled', 'message');
740 }
741
837941e9
MN
742 $systemcontext = context_system::instance();
743
9aa012b5
MN
744 $params = array(
745 'userid' => $userid,
746 'limitfrom' => $limitfrom,
747 'limitnum' => $limitnum
748 );
749 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
837941e9 750 self::validate_context($systemcontext);
9aa012b5 751
837941e9
MN
752 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
753 throw new moodle_exception('You do not have permission to perform this action.');
754 }
9aa012b5
MN
755
756 $contacts = \core_message\api::get_conversations($userid, 0, $limitfrom, $limitnum);
757
758 $renderer = $PAGE->get_renderer('core_message');
759 return $contacts->export_for_template($renderer);
760 }
761
762 /**
49aaadc3 763 * The messagearea conversations return structure.
9aa012b5 764 *
49aaadc3
MN
765 * @return external_single_structure
766 * @since 3.2
9aa012b5
MN
767 */
768 public static function data_for_messagearea_conversations_returns() {
49aaadc3 769 return new external_single_structure(
9aa012b5
MN
770 array(
771 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
4d1b76ee 772 'isconversation' => new external_value(PARAM_BOOL, 'Are we storing conversations or contacts?'),
9aa012b5 773 'contacts' => new external_multiple_structure(
a3e3a3a1 774 self::get_messagearea_contact_structure()
9aa012b5
MN
775 )
776 )
777 );
778 }
779
780 /**
49aaadc3 781 * The messagearea contacts return parameters.
9aa012b5
MN
782 *
783 * @return external_function_parameters
49aaadc3 784 * @since 3.2
9aa012b5
MN
785 */
786 public static function data_for_messagearea_contacts_parameters() {
787 return self::data_for_messagearea_conversations_parameters();
788 }
789
790 /**
791 * Get messagearea contacts parameters.
792 *
793 * @param int $userid The id of the user who we are viewing conversations for
794 * @param int $limitfrom
795 * @param int $limitnum
49aaadc3
MN
796 * @return stdClass
797 * @throws moodle_exception
798 * @since 3.2
9aa012b5
MN
799 */
800 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
837941e9 801 global $CFG, $PAGE, $USER;
9aa012b5
MN
802
803 // Check if messaging is enabled.
837941e9 804 if (empty($CFG->messaging)) {
9aa012b5
MN
805 throw new moodle_exception('disabled', 'message');
806 }
807
837941e9
MN
808 $systemcontext = context_system::instance();
809
9aa012b5
MN
810 $params = array(
811 'userid' => $userid,
812 'limitfrom' => $limitfrom,
813 'limitnum' => $limitnum
814 );
815 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
837941e9 816 self::validate_context($systemcontext);
9aa012b5 817
837941e9
MN
818 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
819 throw new moodle_exception('You do not have permission to perform this action.');
820 }
9aa012b5
MN
821
822 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
823
824 $renderer = $PAGE->get_renderer('core_message');
825 return $contacts->export_for_template($renderer);
826 }
827
828 /**
49aaadc3 829 * The messagearea contacts return structure.
9aa012b5 830 *
49aaadc3
MN
831 * @return external_single_structure
832 * @since 3.2
9aa012b5
MN
833 */
834 public static function data_for_messagearea_contacts_returns() {
835 return self::data_for_messagearea_conversations_returns();
836 }
837
3cd13828 838 /**
49aaadc3 839 * The messagearea messages parameters.
3cd13828
MN
840 *
841 * @return external_function_parameters
49aaadc3 842 * @since 3.2
3cd13828
MN
843 */
844 public static function data_for_messagearea_messages_parameters() {
845 return new external_function_parameters(
846 array(
847 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
848 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
849 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
8ec78c48
MN
850 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
851 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
3cd13828
MN
852 )
853 );
854 }
855
856 /**
857 * Get messagearea messages.
858 *
859 * @param int $currentuserid The current user's id
860 * @param int $otheruserid The other user's id
861 * @param int $limitfrom
862 * @param int $limitnum
8ec78c48 863 * @param boolean $newest
49aaadc3
MN
864 * @return stdClass
865 * @throws moodle_exception
866 * @since 3.2
3cd13828 867 */
8ec78c48 868 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0, $newest = false) {
837941e9 869 global $CFG, $PAGE, $USER;
3cd13828
MN
870
871 // Check if messaging is enabled.
837941e9 872 if (empty($CFG->messaging)) {
3cd13828
MN
873 throw new moodle_exception('disabled', 'message');
874 }
875
837941e9
MN
876 $systemcontext = context_system::instance();
877
3cd13828
MN
878 $params = array(
879 'currentuserid' => $currentuserid,
880 'otheruserid' => $otheruserid,
881 'limitfrom' => $limitfrom,
8ec78c48
MN
882 'limitnum' => $limitnum,
883 'newest' => $newest
3cd13828
MN
884 );
885 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
837941e9 886 self::validate_context($systemcontext);
3cd13828 887
837941e9
MN
888 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
889 throw new moodle_exception('You do not have permission to perform this action.');
890 }
3cd13828 891
8ec78c48
MN
892 if ($newest) {
893 $sort = 'timecreated DESC';
894 } else {
895 $sort = 'timecreated ASC';
896 }
897 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom, $limitnum, $sort);
3cd13828
MN
898
899 $renderer = $PAGE->get_renderer('core_message');
900 return $messages->export_for_template($renderer);
901 }
902
903 /**
49aaadc3 904 * The messagearea messages return structure.
3cd13828 905 *
49aaadc3
MN
906 * @return external_single_structure
907 * @since 3.2
3cd13828
MN
908 */
909 public static function data_for_messagearea_messages_returns() {
49aaadc3 910 return new external_single_structure(
3cd13828
MN
911 array(
912 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing the messages on behalf of?'),
913 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
914 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
915 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
bf58081d 916 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
3cd13828 917 'messages' => new external_multiple_structure(
94e1db61 918 self::get_messagearea_message_structure()
3cd13828
MN
919 )
920 )
921 );
922 }
923
c060cd49 924 /**
49aaadc3 925 * The get most recent message return parameters.
c060cd49
MN
926 *
927 * @return external_function_parameters
49aaadc3 928 * @since 3.2
c060cd49
MN
929 */
930 public static function data_for_messagearea_get_most_recent_message_parameters() {
931 return new external_function_parameters(
932 array(
933 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
934 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
935 )
936 );
937 }
938
939 /**
940 * Get the most recent message in a conversation.
941 *
942 * @param int $currentuserid The current user's id
943 * @param int $otheruserid The other user's id
49aaadc3
MN
944 * @return stdClass
945 * @throws moodle_exception
946 * @since 3.2
c060cd49
MN
947 */
948 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
837941e9 949 global $CFG, $PAGE, $USER;
c060cd49
MN
950
951 // Check if messaging is enabled.
837941e9 952 if (empty($CFG->messaging)) {
c060cd49
MN
953 throw new moodle_exception('disabled', 'message');
954 }
955
837941e9
MN
956 $systemcontext = context_system::instance();
957
c060cd49
MN
958 $params = array(
959 'currentuserid' => $currentuserid,
960 'otheruserid' => $otheruserid
961 );
962 self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
837941e9 963 self::validate_context($systemcontext);
c060cd49 964
837941e9
MN
965 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
966 throw new moodle_exception('You do not have permission to perform this action.');
967 }
c060cd49
MN
968
969 $message = \core_message\api::get_most_recent_message($currentuserid, $otheruserid);
970
971 $renderer = $PAGE->get_renderer('core_message');
972 return $message->export_for_template($renderer);
973 }
974
975 /**
49aaadc3 976 * The get most recent message return structure.
c060cd49
MN
977 *
978 * @return external_single_structure
49aaadc3 979 * @since 3.2
c060cd49
MN
980 */
981 public static function data_for_messagearea_get_most_recent_message_returns() {
94e1db61 982 return self::get_messagearea_message_structure();
c060cd49
MN
983 }
984
c6e97f54
MN
985 /**
986 * The get profile parameters.
987 *
988 * @return external_function_parameters
49aaadc3 989 * @since 3.2
c6e97f54
MN
990 */
991 public static function data_for_messagearea_get_profile_parameters() {
992 return new external_function_parameters(
993 array(
994 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
995 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
996 )
997 );
998 }
999
1000 /**
1001 * Get the profile information for a contact.
1002 *
1003 * @param int $currentuserid The current user's id
1004 * @param int $otheruserid The id of the user whose profile we are viewing
49aaadc3
MN
1005 * @return stdClass
1006 * @throws moodle_exception
1007 * @since 3.2
c6e97f54
MN
1008 */
1009 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
837941e9 1010 global $CFG, $PAGE, $USER;
c6e97f54
MN
1011
1012 // Check if messaging is enabled.
837941e9 1013 if (empty($CFG->messaging)) {
c6e97f54
MN
1014 throw new moodle_exception('disabled', 'message');
1015 }
1016
837941e9
MN
1017 $systemcontext = context_system::instance();
1018
c6e97f54
MN
1019 $params = array(
1020 'currentuserid' => $currentuserid,
1021 'otheruserid' => $otheruserid
1022 );
1023 self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
837941e9 1024 self::validate_context($systemcontext);
c6e97f54 1025
837941e9
MN
1026 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1027 throw new moodle_exception('You do not have permission to perform this action.');
1028 }
c6e97f54
MN
1029
1030 $profile = \core_message\api::get_profile($currentuserid, $otheruserid);
1031
1032 $renderer = $PAGE->get_renderer('core_message');
1033 return $profile->export_for_template($renderer);
1034 }
1035
1036 /**
49aaadc3 1037 * The get profile return structure.
c6e97f54
MN
1038 *
1039 * @return external_single_structure
49aaadc3 1040 * @since 3.2
c6e97f54
MN
1041 */
1042 public static function data_for_messagearea_get_profile_returns() {
1043 return new external_single_structure(
1044 array(
1045 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing the profile on behalf of?'),
1046 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1047 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
1048 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
1049 'country' => new external_value(core_user::get_property_type('country'), 'Home country code of the user'),
1050 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
1051 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1052 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1053 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
bf58081d 1054 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
c6e97f54
MN
1055 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
1056 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
1057 )
1058 );
1059 }
1060
d6731600
FM
1061 /**
1062 * Get contacts parameters description.
1063 *
1064 * @return external_function_parameters
5bcfd504 1065 * @since Moodle 2.5
d6731600
FM
1066 */
1067 public static function get_contacts_parameters() {
1068 return new external_function_parameters(array());
1069 }
1070
1071 /**
1072 * Get contacts.
1073 *
1074 * @param array $userids array of user IDs.
1075 * @return external_description
5bcfd504 1076 * @since Moodle 2.5
d6731600
FM
1077 */
1078 public static function get_contacts() {
d85bedf7 1079 global $CFG, $PAGE;
436bbf89
DM
1080
1081 // Check if messaging is enabled.
837941e9 1082 if (empty($CFG->messaging)) {
436bbf89
DM
1083 throw new moodle_exception('disabled', 'message');
1084 }
1085
d6731600
FM
1086 require_once($CFG->dirroot . '/user/lib.php');
1087
1088 list($online, $offline, $strangers) = message_get_contacts();
1089 $allcontacts = array('online' => $online, 'offline' => $offline, 'strangers' => $strangers);
1090 foreach ($allcontacts as $mode => $contacts) {
1091 foreach ($contacts as $key => $contact) {
1092 $newcontact = array(
1093 'id' => $contact->id,
1094 'fullname' => fullname($contact),
1095 'unread' => $contact->messagecount
1096 );
1097
d85bedf7
JL
1098 $userpicture = new user_picture($contact);
1099 $userpicture->size = 1; // Size f1.
1100 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1101 $userpicture->size = 0; // Size f2.
1102 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
1103
1104 $allcontacts[$mode][$key] = $newcontact;
1105 }
1106 }
1107 return $allcontacts;
1108 }
1109
1110 /**
1111 * Get contacts return description.
1112 *
1113 * @return external_description
5bcfd504 1114 * @since Moodle 2.5
d6731600
FM
1115 */
1116 public static function get_contacts_returns() {
1117 return new external_single_structure(
1118 array(
1119 'online' => new external_multiple_structure(
1120 new external_single_structure(
1121 array(
1122 'id' => new external_value(PARAM_INT, 'User ID'),
1123 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1124 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1125 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1126 'unread' => new external_value(PARAM_INT, 'Unread message count')
1127 )
1128 ),
1129 'List of online contacts'
1130 ),
1131 'offline' => new external_multiple_structure(
1132 new external_single_structure(
1133 array(
1134 'id' => new external_value(PARAM_INT, 'User ID'),
1135 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1136 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1137 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1138 'unread' => new external_value(PARAM_INT, 'Unread message count')
1139 )
1140 ),
1141 'List of offline contacts'
1142 ),
1143 'strangers' => new external_multiple_structure(
1144 new external_single_structure(
1145 array(
1146 'id' => new external_value(PARAM_INT, 'User ID'),
1147 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1148 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1149 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1150 'unread' => new external_value(PARAM_INT, 'Unread message count')
1151 )
1152 ),
1153 'List of users that are not in the user\'s contact list but have sent a message'
1154 )
1155 )
1156 );
1157 }
1158
1159 /**
1160 * Search contacts parameters description.
1161 *
1162 * @return external_function_parameters
5bcfd504 1163 * @since Moodle 2.5
d6731600
FM
1164 */
1165 public static function search_contacts_parameters() {
1166 return new external_function_parameters(
1167 array(
1168 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
1169 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
1170 VALUE_DEFAULT, false)
1171 )
1172 );
1173 }
1174
1175 /**
1176 * Search contacts.
1177 *
1178 * @param string $searchtext query string.
1179 * @param bool $onlymycourses limit the search to the user's courses only.
1180 * @return external_description
5bcfd504 1181 * @since Moodle 2.5
d6731600
FM
1182 */
1183 public static function search_contacts($searchtext, $onlymycourses = false) {
d85bedf7 1184 global $CFG, $USER, $PAGE;
11d83ab3 1185 require_once($CFG->dirroot . '/user/lib.php');
436bbf89
DM
1186
1187 // Check if messaging is enabled.
837941e9 1188 if (empty($CFG->messaging)) {
436bbf89
DM
1189 throw new moodle_exception('disabled', 'message');
1190 }
1191
d6731600
FM
1192 require_once($CFG->libdir . '/enrollib.php');
1193
1194 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1195 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
1196
1197 // Extra validation, we do not allow empty queries.
1198 if ($params['searchtext'] === '') {
1199 throw new moodle_exception('querystringcannotbeempty');
1200 }
1201
1202 $courseids = array();
1203 if ($params['onlymycourses']) {
1204 $mycourses = enrol_get_my_courses(array('id'));
1205 foreach ($mycourses as $mycourse) {
1206 $courseids[] = $mycourse->id;
1207 }
1208 } else {
1209 $courseids[] = SITEID;
1210 }
1211
1212 // Retrieving the users matching the query.
1213 $users = message_search_users($courseids, $params['searchtext']);
1214 $results = array();
1215 foreach ($users as $user) {
1216 $results[$user->id] = $user;
1217 }
1218
1219 // Reorganising information.
1220 foreach ($results as &$user) {
1221 $newuser = array(
1222 'id' => $user->id,
1223 'fullname' => fullname($user)
1224 );
1225
1226 // Avoid undefined property notice as phone not specified.
1227 $user->phone1 = null;
1228 $user->phone2 = null;
1229
d85bedf7
JL
1230 $userpicture = new user_picture($user);
1231 $userpicture->size = 1; // Size f1.
1232 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1233 $userpicture->size = 0; // Size f2.
1234 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
1235
1236 $user = $newuser;
1237 }
1238
1239 return $results;
1240 }
1241
1242 /**
1243 * Search contacts return description.
1244 *
1245 * @return external_description
5bcfd504 1246 * @since Moodle 2.5
d6731600
FM
1247 */
1248 public static function search_contacts_returns() {
1249 return new external_multiple_structure(
1250 new external_single_structure(
1251 array(
1252 'id' => new external_value(PARAM_INT, 'User ID'),
1253 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1254 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1255 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
1256 )
1257 ),
1258 'List of contacts'
1259 );
1260 }
aff9da17
JL
1261
1262 /**
1263 * Get messages parameters description.
1264 *
1265 * @return external_function_parameters
193edf7f 1266 * @since 2.8
aff9da17
JL
1267 */
1268 public static function get_messages_parameters() {
1269 return new external_function_parameters(
1270 array(
6ff4464b 1271 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
127ef540
SH
1272 'useridfrom' => new external_value(
1273 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1274 VALUE_DEFAULT, 0),
1275 'type' => new external_value(
1276 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
1277 VALUE_DEFAULT, 'both'),
6ff4464b 1278 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
127ef540
SH
1279 'newestfirst' => new external_value(
1280 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1281 VALUE_DEFAULT, true),
aff9da17 1282 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
127ef540
SH
1283 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
1284 )
aff9da17
JL
1285 );
1286 }
1287
1288 /**
1289 * Get messages function implementation.
127ef540
SH
1290 *
1291 * @since 2.8
1292 * @throws invalid_parameter_exception
1293 * @throws moodle_exception
6ff4464b
JL
1294 * @param int $useridto the user id who received the message
1295 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
193edf7f 1296 * @param string $type type of message to return, expected values: notifications, conversations and both
aff9da17 1297 * @param bool $read true for retreiving read messages, false for unread
6ff4464b 1298 * @param bool $newestfirst true for ordering by newest first, false for oldest first
aff9da17
JL
1299 * @param int $limitfrom limit from
1300 * @param int $limitnum limit num
1301 * @return external_description
aff9da17 1302 */
193edf7f 1303 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
aff9da17 1304 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
127ef540 1305 global $CFG, $USER;
aff9da17
JL
1306
1307 $warnings = array();
1308
1309 $params = array(
1310 'useridto' => $useridto,
6ff4464b 1311 'useridfrom' => $useridfrom,
aff9da17
JL
1312 'type' => $type,
1313 'read' => $read,
aff9da17
JL
1314 'newestfirst' => $newestfirst,
1315 'limitfrom' => $limitfrom,
1316 'limitnum' => $limitnum
1317 );
1318
1319 $params = self::validate_parameters(self::get_messages_parameters(), $params);
1320
1321 $context = context_system::instance();
1322 self::validate_context($context);
1323
1324 $useridto = $params['useridto'];
6ff4464b 1325 $useridfrom = $params['useridfrom'];
aff9da17
JL
1326 $type = $params['type'];
1327 $read = $params['read'];
aff9da17
JL
1328 $newestfirst = $params['newestfirst'];
1329 $limitfrom = $params['limitfrom'];
1330 $limitnum = $params['limitnum'];
1331
1332 $allowedvalues = array('notifications', 'conversations', 'both');
1333 if (!in_array($type, $allowedvalues)) {
1334 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1335 'allowed values are: ' . implode(',', $allowedvalues));
1336 }
1337
1338 // Check if private messaging between users is allowed.
1339 if (empty($CFG->messaging)) {
1340 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
aff9da17
JL
1341 if ($type == "conversations") {
1342 throw new moodle_exception('disabled', 'message');
1343 }
1344 if ($type == "both") {
1345 $warning = array();
1346 $warning['item'] = 'message';
1347 $warning['itemid'] = $USER->id;
1348 $warning['warningcode'] = '1';
1349 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1350 Only notifications will be returned';
1351 $warnings[] = $warning;
1352 }
1353 }
1354
1355 if (!empty($useridto)) {
6ff4464b
JL
1356 if (core_user::is_real_user($useridto)) {
1357 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1358 } else {
1359 throw new moodle_exception('invaliduser');
1360 }
aff9da17
JL
1361 }
1362
1363 if (!empty($useridfrom)) {
1364 // We use get_user here because the from user can be the noreply or support user.
1365 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1366 }
1367
1368 // Check if the current user is the sender/receiver or just a privileged user.
1369 if ($useridto != $USER->id and $useridfrom != $USER->id and
1370 !has_capability('moodle/site:readallmessages', $context)) {
1371 throw new moodle_exception('accessdenied', 'admin');
1372 }
1373
127ef540 1374 // Which type of messages to retrieve.
193edf7f 1375 $notifications = -1;
aff9da17 1376 if ($type != 'both') {
193edf7f 1377 $notifications = ($type == 'notifications') ? 1 : 0;
aff9da17
JL
1378 }
1379
aff9da17 1380 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
193edf7f 1381 $sort = "mr.timecreated $orderdirection";
aff9da17 1382
193edf7f 1383 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
aff9da17
JL
1384 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1385
1386 // In some cases, we don't need to get the to/from user objects from the sql query.
1387 $userfromfullname = '';
1388 $usertofullname = '';
1389
1390 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1391 if (!empty($useridto)) {
1392 $usertofullname = fullname($userto, $canviewfullname);
1393 // The user from may or may not be filled.
1394 if (!empty($useridfrom)) {
1395 $userfromfullname = fullname($userfrom, $canviewfullname);
1396 }
1397 } else {
1398 // If the useridto field is empty, the useridfrom must be filled.
1399 $userfromfullname = fullname($userfrom, $canviewfullname);
1400 }
aff9da17
JL
1401 foreach ($messages as $mid => $message) {
1402
ea21d637
JL
1403 // Do not return deleted messages.
1404 if (($useridto == $USER->id and $message->timeusertodeleted) or
1405 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
1406
1407 unset($messages[$mid]);
1408 continue;
1409 }
1410
aff9da17
JL
1411 // We need to get the user from the query.
1412 if (empty($userfromfullname)) {
6ff4464b
JL
1413 // Check for non-reply and support users.
1414 if (core_user::is_real_user($message->useridfrom)) {
127ef540 1415 $user = new stdClass();
6ff4464b
JL
1416 $user = username_load_fields_from_object($user, $message, 'userfrom');
1417 $message->userfromfullname = fullname($user, $canviewfullname);
1418 } else {
1419 $user = core_user::get_user($message->useridfrom);
1420 $message->userfromfullname = fullname($user, $canviewfullname);
1421 }
aff9da17
JL
1422 } else {
1423 $message->userfromfullname = $userfromfullname;
1424 }
1425
1426 // We need to get the user from the query.
1427 if (empty($usertofullname)) {
127ef540 1428 $user = new stdClass();
aff9da17
JL
1429 $user = username_load_fields_from_object($user, $message, 'userto');
1430 $message->usertofullname = fullname($user, $canviewfullname);
1431 } else {
1432 $message->usertofullname = $usertofullname;
1433 }
1434
193edf7f 1435 // This field is only available in the message_read table.
aff9da17
JL
1436 if (!isset($message->timeread)) {
1437 $message->timeread = 0;
1438 }
1439
aff9da17 1440 $message->text = message_format_message_text($message);
aff9da17
JL
1441 $messages[$mid] = (array) $message;
1442 }
1443 }
1444
1445 $results = array(
1446 'messages' => $messages,
1447 'warnings' => $warnings
1448 );
1449
1450 return $results;
1451 }
1452
1453 /**
1454 * Get messages return description.
1455 *
6ff4464b 1456 * @return external_single_structure
193edf7f 1457 * @since 2.8
aff9da17
JL
1458 */
1459 public static function get_messages_returns() {
1460 return new external_single_structure(
1461 array(
1462 'messages' => new external_multiple_structure(
1463 new external_single_structure(
1464 array(
193edf7f 1465 'id' => new external_value(PARAM_INT, 'Message id'),
aff9da17
JL
1466 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1467 'useridto' => new external_value(PARAM_INT, 'User to id'),
1468 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1469 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1470 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
193edf7f 1471 'fullmessageformat' => new external_format_value('fullmessage'),
aff9da17
JL
1472 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1473 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1474 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
1475 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1476 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1477 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1478 'timeread' => new external_value(PARAM_INT, 'Time read'),
1479 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
1480 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
1481 ), 'message'
1482 )
1483 ),
1484 'warnings' => new external_warnings()
1485 )
1486 );
3274d5ca
RW
1487 }
1488
1489 /**
ada7695d 1490 * Get popup notifications parameters description.
3274d5ca
RW
1491 *
1492 * @return external_function_parameters
1493 * @since 3.2
1494 */
ada7695d 1495 public static function get_popup_notifications_parameters() {
3274d5ca
RW
1496 return new external_function_parameters(
1497 array(
1498 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3274d5ca
RW
1499 'status' => new external_value(
1500 PARAM_ALPHA, 'filter the results to just "read" or "unread" notifications',
1501 VALUE_DEFAULT, ''),
1502 'embeduserto' => new external_value(
1503 PARAM_BOOL, 'true for returning user details for the recipient in each notification',
1504 VALUE_DEFAULT, false),
1505 'embeduserfrom' => new external_value(
1506 PARAM_BOOL, 'true for returning user details for the sender in each notification',
1507 VALUE_DEFAULT, false),
1508 'newestfirst' => new external_value(
1509 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1510 VALUE_DEFAULT, true),
1511 'markasread' => new external_value(
1512 PARAM_BOOL, 'mark notifications as read when they are returned by this function',
1513 VALUE_DEFAULT, false),
1514 'limit' => new external_value(PARAM_INT, 'the number of results to return', VALUE_DEFAULT, 0),
1515 'offset' => new external_value(PARAM_INT, 'offset the result set by a given amount', VALUE_DEFAULT, 0)
1516 )
1517 );
1518 }
1519
1520 /**
1521 * Get notifications function.
1522 *
1523 * @since 3.2
1524 * @throws invalid_parameter_exception
1525 * @throws moodle_exception
c5dd16a1 1526 * @param int $useridto the user id who received the message
c5dd16a1 1527 * @param string $status filter the results to only read or unread notifications
c5dd16a1
RW
1528 * @param bool $embeduserto true to embed the recipient user details in the record for each notification
1529 * @param bool $embeduserfrom true to embed the send user details in the record for each notification
1530 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1531 * @param bool $markasread mark notifications as read when they are returned by this function
1532 * @param int $limit the number of results to return
1533 * @param int $offset offset the result set by a given amount
3274d5ca
RW
1534 * @return external_description
1535 */
0b19d048
RW
1536 public static function get_popup_notifications($useridto, $status, $embeduserto,
1537 $embeduserfrom, $newestfirst, $markasread, $limit, $offset) {
837941e9 1538 global $USER, $PAGE;
3274d5ca
RW
1539
1540 $params = self::validate_parameters(
ada7695d 1541 self::get_popup_notifications_parameters(),
3274d5ca
RW
1542 array(
1543 'useridto' => $useridto,
3274d5ca
RW
1544 'status' => $status,
1545 'embeduserto' => $embeduserto,
1546 'embeduserfrom' => $embeduserfrom,
1547 'newestfirst' => $newestfirst,
1548 'markasread' => $markasread,
1549 'limit' => $limit,
1550 'offset' => $offset,
1551 )
1552 );
1553
1554 $context = context_system::instance();
1555 self::validate_context($context);
1556
1557 $useridto = $params['useridto'];
3274d5ca
RW
1558 $status = $params['status'];
1559 $embeduserto = $params['embeduserto'];
1560 $embeduserfrom = $params['embeduserfrom'];
1561 $newestfirst = $params['newestfirst'];
1562 $markasread = $params['markasread'];
1563 $limit = $params['limit'];
1564 $offset = $params['offset'];
c5dd16a1 1565 $issuperuser = has_capability('moodle/site:readallmessages', $context);
24a76780 1566 $renderer = $PAGE->get_renderer('core_message');
3274d5ca
RW
1567
1568 if (!empty($useridto)) {
1569 if (core_user::is_real_user($useridto)) {
1570 if ($embeduserto) {
1571 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1572 }
1573 } else {
1574 throw new moodle_exception('invaliduser');
1575 }
1576 }
1577
3274d5ca 1578 // Check if the current user is the sender/receiver or just a privileged user.
ada7695d 1579 if ($useridto != $USER->id and !$issuperuser) {
3274d5ca
RW
1580 throw new moodle_exception('accessdenied', 'admin');
1581 }
1582
1583 $sort = $newestfirst ? 'DESC' : 'ASC';
79f6c36c 1584 $notifications = \core_message\api::get_popup_notifications($useridto, $status, $embeduserto, $embeduserfrom, $sort, $limit, $offset);
24a76780 1585 $notificationcontexts = [];
3274d5ca
RW
1586
1587 if ($notifications) {
ada7695d 1588 // In some cases, we don't need to get the to user objects from the sql query.
3274d5ca
RW
1589 $usertofullname = '';
1590
1591 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1592 if (!empty($useridto) && $embeduserto) {
1593 $usertofullname = fullname($userto);
3274d5ca
RW
1594 }
1595
1596 foreach ($notifications as $notification) {
1597
24a76780 1598 $notificationoutput = new \core_message\output\popup_notification($notification, $embeduserto,
0b19d048 1599 $embeduserfrom, $usertofullname);
3274d5ca 1600
24a76780
RW
1601 $notificationcontext = $notificationoutput->export_for_template($renderer);
1602 $notificationcontexts[] = $notificationcontext;
c5dd16a1 1603
24a76780
RW
1604 if ($markasread && !$notificationcontext->read) {
1605 message_mark_message_read($notification, time());
3274d5ca
RW
1606 }
1607 }
1608 }
1609
1610 return array(
24a76780 1611 'notifications' => $notificationcontexts,
79f6c36c 1612 'unreadcount' => \core_message\api::count_unread_popup_notifications($useridto),
3274d5ca
RW
1613 );
1614 }
1615
1616 /**
1617 * Get notifications return description.
1618 *
1619 * @return external_single_structure
1620 * @since 3.2
1621 */
ada7695d 1622 public static function get_popup_notifications_returns() {
3274d5ca
RW
1623 return new external_single_structure(
1624 array(
1625 'notifications' => new external_multiple_structure(
1626 new external_single_structure(
1627 array(
1628 'id' => new external_value(PARAM_INT, 'Notification id (this is not guaranteed to be unique within this result set)'),
1629 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1630 'useridto' => new external_value(PARAM_INT, 'User to id'),
1631 'subject' => new external_value(PARAM_TEXT, 'The notification subject'),
0b19d048 1632 'shortenedsubject' => new external_value(PARAM_TEXT, 'The notification subject shortened with ellipsis'),
3274d5ca
RW
1633 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1634 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
1635 'fullmessageformat' => new external_format_value('fullmessage'),
1636 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1637 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1638 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1639 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1640 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1641 'timecreatedpretty' => new external_value(PARAM_TEXT, 'Time created in a pretty format'),
1642 'timeread' => new external_value(PARAM_INT, 'Time read'),
1643 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name', VALUE_OPTIONAL),
1644 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name', VALUE_OPTIONAL),
1645 'userfromprofileurl' => new external_value(PARAM_URL, 'User from profile url', VALUE_OPTIONAL),
1646 'read' => new external_value(PARAM_BOOL, 'notification read status'),
1647 'deleted' => new external_value(PARAM_BOOL, 'notification deletion status'),
1648 'iconurl' => new external_value(PARAM_URL, 'URL for notification icon'),
1649 'component' => new external_value(PARAM_TEXT, 'The component that generated the notification', VALUE_OPTIONAL),
1650 'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL),
1651 ), 'message'
1652 )
1653 ),
1654 'unreadcount' => new external_value(PARAM_INT, 'the user whose blocked users we want to retrieve'),
1655 )
1656 );
1657 }
1658
1659 /**
1660 * Mark all notifications as read parameters description.
1661 *
1662 * @return external_function_parameters
1663 * @since 3.2
1664 */
1665 public static function mark_all_notifications_as_read_parameters() {
1666 return new external_function_parameters(
1667 array(
1668 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1669 'useridfrom' => new external_value(
1670 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1671 VALUE_DEFAULT, 0),
1672 )
1673 );
1674 }
1675
1676 /**
1677 * Mark all notifications as read function.
1678 *
1679 * @since 3.2
1680 * @throws invalid_parameter_exception
1681 * @throws moodle_exception
1682 * @param int $useridto the user id who received the message
1683 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1684 * @return external_description
1685 */
1686 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
837941e9 1687 global $USER;
3274d5ca
RW
1688
1689 $params = self::validate_parameters(
1690 self::mark_all_notifications_as_read_parameters(),
1691 array(
1692 'useridto' => $useridto,
1693 'useridfrom' => $useridfrom,
1694 )
1695 );
1696
1697 $context = context_system::instance();
1698 self::validate_context($context);
1699
1700 $useridto = $params['useridto'];
1701 $useridfrom = $params['useridfrom'];
1702
1703 if (!empty($useridto)) {
1704 if (core_user::is_real_user($useridto)) {
1705 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1706 } else {
1707 throw new moodle_exception('invaliduser');
1708 }
1709 }
1710
1711 if (!empty($useridfrom)) {
1712 // We use get_user here because the from user can be the noreply or support user.
1713 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1714 }
1715
1716 // Check if the current user is the sender/receiver or just a privileged user.
1717 if ($useridto != $USER->id and $useridfrom != $USER->id and
1718 // deleteanymessage seems more reasonable here than readallmessages.
1719 !has_capability('moodle/site:deleteanymessage', $context)) {
1720 throw new moodle_exception('accessdenied', 'admin');
1721 }
1722
79f6c36c 1723 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_NOTIFICATION);
3274d5ca
RW
1724
1725 return true;
1726 }
1727
1728 /**
1729 * Mark all notifications as read return description.
1730 *
1731 * @return external_single_structure
1732 * @since 3.2
1733 */
1734 public static function mark_all_notifications_as_read_returns() {
1735 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
1736 }
1737
1738 /**
1739 * Get unread notification count parameters description.
1740 *
1741 * @return external_function_parameters
1742 * @since 3.2
1743 */
ada7695d 1744 public static function get_unread_popup_notification_count_parameters() {
3274d5ca
RW
1745 return new external_function_parameters(
1746 array(
1747 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3274d5ca
RW
1748 )
1749 );
1750 }
1751
1752 /**
1753 * Get unread notification count function.
1754 *
1755 * @since 3.2
1756 * @throws invalid_parameter_exception
1757 * @throws moodle_exception
1758 * @param int $useridto the user id who received the message
3274d5ca
RW
1759 * @return external_description
1760 */
ada7695d 1761 public static function get_unread_popup_notification_count($useridto) {
837941e9 1762 global $USER;
3274d5ca
RW
1763
1764 $params = self::validate_parameters(
ada7695d
RW
1765 self::get_unread_popup_notification_count_parameters(),
1766 array('useridto' => $useridto)
3274d5ca
RW
1767 );
1768
1769 $context = context_system::instance();
1770 self::validate_context($context);
1771
1772 $useridto = $params['useridto'];
3274d5ca
RW
1773
1774 if (!empty($useridto)) {
1775 if (core_user::is_real_user($useridto)) {
1776 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1777 } else {
1778 throw new moodle_exception('invaliduser');
1779 }
1780 }
1781
3274d5ca 1782 // Check if the current user is the sender/receiver or just a privileged user.
ada7695d 1783 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
3274d5ca
RW
1784 throw new moodle_exception('accessdenied', 'admin');
1785 }
1786
79f6c36c 1787 return \core_message\api::count_unread_popup_notifications($useridto);
3274d5ca
RW
1788 }
1789
1790 /**
ada7695d 1791 * Get unread popup notification count return description.
3274d5ca
RW
1792 *
1793 * @return external_single_structure
1794 * @since 3.2
1795 */
ada7695d 1796 public static function get_unread_popup_notification_count_returns() {
8c55bd6c
RW
1797 return new external_value(PARAM_INT, 'The count of unread popup notifications');
1798 }
1799
1800 /**
1801 * Get unread conversations count parameters description.
1802 *
1803 * @return external_function_parameters
1804 * @since 3.2
1805 */
1806 public static function get_unread_conversations_count_parameters() {
1807 return new external_function_parameters(
1808 array(
1809 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1810 )
1811 );
1812 }
1813
1814 /**
1815 * Get unread messages count function.
1816 *
1817 * @since 3.2
1818 * @throws invalid_parameter_exception
1819 * @throws moodle_exception
1820 * @param int $useridto the user id who received the message
1821 * @return external_description
1822 */
1823 public static function get_unread_conversations_count($useridto) {
1824 global $USER;
1825
1826 $params = self::validate_parameters(
1827 self::get_unread_conversations_count_parameters(),
1828 array('useridto' => $useridto)
1829 );
1830
1831 $context = context_system::instance();
1832 self::validate_context($context);
1833
1834 $useridto = $params['useridto'];
1835
1836 if (!empty($useridto)) {
1837 if (core_user::is_real_user($useridto)) {
1838 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1839 } else {
1840 throw new moodle_exception('invaliduser');
1841 }
1842 } else {
1843 $useridto = $USER->id;
1844 }
1845
1846 // Check if the current user is the receiver or just a privileged user.
1847 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1848 throw new moodle_exception('accessdenied', 'admin');
1849 }
1850
79f6c36c 1851 return \core_message\api::count_unread_conversations($userto);
8c55bd6c
RW
1852 }
1853
1854 /**
1855 * Get unread conversations count return description.
1856 *
1857 * @return external_single_structure
1858 * @since 3.2
1859 */
1860 public static function get_unread_conversations_count_returns() {
1861 return new external_value(PARAM_INT, 'The count of unread messages for the user');
aff9da17
JL
1862 }
1863
60ab2e1b
JL
1864 /**
1865 * Get blocked users parameters description.
1866 *
1867 * @return external_function_parameters
1868 * @since 2.9
1869 */
1870 public static function get_blocked_users_parameters() {
1871 return new external_function_parameters(
1872 array(
1873 'userid' => new external_value(PARAM_INT,
1874 'the user whose blocked users we want to retrieve',
1875 VALUE_REQUIRED),
1876 )
1877 );
1878 }
1879
1880 /**
1881 * Retrieve a list of users blocked
1882 *
1883 * @param int $userid the user whose blocked users we want to retrieve
1884 * @return external_description
1885 * @since 2.9
1886 */
1887 public static function get_blocked_users($userid) {
d85bedf7 1888 global $CFG, $USER, $PAGE;
60ab2e1b
JL
1889
1890 // Warnings array, it can be empty at the end but is mandatory.
1891 $warnings = array();
1892
1893 // Validate params.
1894 $params = array(
1895 'userid' => $userid
1896 );
1897 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
1898 $userid = $params['userid'];
1899
1900 // Validate context.
1901 $context = context_system::instance();
1902 self::validate_context($context);
1903
1904 // Check if private messaging between users is allowed.
1905 if (empty($CFG->messaging)) {
1906 throw new moodle_exception('disabled', 'message');
1907 }
1908
4485f7c5
JL
1909 $user = core_user::get_user($userid, '*', MUST_EXIST);
1910 core_user::require_active_user($user);
60ab2e1b
JL
1911
1912 // Check if we have permissions for retrieve the information.
1913 if ($userid != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1914 throw new moodle_exception('accessdenied', 'admin');
1915 }
1916
1917 // Now, we can get safely all the blocked users.
1918 $users = message_get_blocked_users($user);
1919
1920 $blockedusers = array();
1921 foreach ($users as $user) {
1922 $newuser = array(
1923 'id' => $user->id,
1924 'fullname' => fullname($user),
1925 );
0b074e88 1926
d85bedf7
JL
1927 $userpicture = new user_picture($user);
1928 $userpicture->size = 1; // Size f1.
1929 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
60ab2e1b
JL
1930
1931 $blockedusers[] = $newuser;
1932 }
1933
1934 $results = array(
1935 'users' => $blockedusers,
1936 'warnings' => $warnings
1937 );
1938 return $results;
1939 }
1940
1941 /**
1942 * Get blocked users return description.
1943 *
1944 * @return external_single_structure
1945 * @since 2.9
1946 */
1947 public static function get_blocked_users_returns() {
1948 return new external_single_structure(
1949 array(
1950 'users' => new external_multiple_structure(
1951 new external_single_structure(
1952 array(
1953 'id' => new external_value(PARAM_INT, 'User ID'),
1954 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1955 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
1956 )
1957 ),
1958 'List of blocked users'
1959 ),
1960 'warnings' => new external_warnings()
1961 )
1962 );
1963 }
1964
31c474da
JL
1965 /**
1966 * Returns description of method parameters
1967 *
1968 * @return external_function_parameters
1969 * @since 2.9
1970 */
1971 public static function mark_message_read_parameters() {
1972 return new external_function_parameters(
1973 array(
1974 'messageid' => new external_value(PARAM_INT, 'id of the message (in the message table)'),
0b19d048 1975 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read', VALUE_DEFAULT, 0)
31c474da
JL
1976 )
1977 );
1978 }
1979
1980 /**
1981 * Mark a single message as read, trigger message_viewed event
1982 *
1983 * @param int $messageid id of the message (in the message table)
1984 * @param int $timeread timestamp for when the message should be marked read
1985 * @return external_description
1986 * @throws invalid_parameter_exception
1987 * @throws moodle_exception
1988 * @since 2.9
1989 */
1990 public static function mark_message_read($messageid, $timeread) {
1991 global $CFG, $DB, $USER;
31c474da
JL
1992
1993 // Check if private messaging between users is allowed.
1994 if (empty($CFG->messaging)) {
1995 throw new moodle_exception('disabled', 'message');
1996 }
1997
1998 // Warnings array, it can be empty at the end but is mandatory.
1999 $warnings = array();
2000
2001 // Validate params.
2002 $params = array(
2003 'messageid' => $messageid,
2004 'timeread' => $timeread
2005 );
2006 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
2007
0b19d048
RW
2008 if (empty($params['timeread'])) {
2009 $timeread = time();
2010 } else {
2011 $timeread = $params['timeread'];
2012 }
2013
31c474da
JL
2014 // Validate context.
2015 $context = context_system::instance();
2016 self::validate_context($context);
2017
2018 $message = $DB->get_record('message', array('id' => $params['messageid']), '*', MUST_EXIST);
2019
2020 if ($message->useridto != $USER->id) {
2021 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2022 }
2023
0b19d048 2024 $messageid = message_mark_message_read($message, $timeread);
31c474da
JL
2025
2026 $results = array(
2027 'messageid' => $messageid,
2028 'warnings' => $warnings
2029 );
2030 return $results;
2031 }
2032
2033 /**
2034 * Returns description of method result value
2035 *
2036 * @return external_description
2037 * @since 2.9
2038 */
2039 public static function mark_message_read_returns() {
2040 return new external_single_structure(
2041 array(
2042 'messageid' => new external_value(PARAM_INT, 'the id of the message in the message_read table'),
2043 'warnings' => new external_warnings()
2044 )
2045 );
2046 }
2047
8c55bd6c
RW
2048 /**
2049 * Mark all messages as read parameters description.
2050 *
2051 * @return external_function_parameters
2052 * @since 3.2
2053 */
2054 public static function mark_all_messages_as_read_parameters() {
2055 return new external_function_parameters(
2056 array(
2057 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2058 'useridfrom' => new external_value(
2059 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2060 VALUE_DEFAULT, 0),
2061 )
2062 );
2063 }
2064
2065 /**
2066 * Mark all notifications as read function.
2067 *
2068 * @since 3.2
2069 * @throws invalid_parameter_exception
2070 * @throws moodle_exception
2071 * @param int $useridto the user id who received the message
2072 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2073 * @return external_description
2074 */
2075 public static function mark_all_messages_as_read($useridto, $useridfrom) {
837941e9 2076 global $USER;
8c55bd6c
RW
2077
2078 $params = self::validate_parameters(
2079 self::mark_all_messages_as_read_parameters(),
2080 array(
2081 'useridto' => $useridto,
2082 'useridfrom' => $useridfrom,
2083 )
2084 );
2085
2086 $context = context_system::instance();
2087 self::validate_context($context);
2088
2089 $useridto = $params['useridto'];
2090 $useridfrom = $params['useridfrom'];
2091
2092 if (!empty($useridto)) {
2093 if (core_user::is_real_user($useridto)) {
2094 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2095 } else {
2096 throw new moodle_exception('invaliduser');
2097 }
2098 }
2099
2100 if (!empty($useridfrom)) {
2101 // We use get_user here because the from user can be the noreply or support user.
2102 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2103 }
2104
2105 // Check if the current user is the sender/receiver or just a privileged user.
2106 if ($useridto != $USER->id and $useridfrom != $USER->id and
2107 // deleteanymessage seems more reasonable here than readallmessages.
2108 !has_capability('moodle/site:deleteanymessage', $context)) {
2109 throw new moodle_exception('accessdenied', 'admin');
2110 }
2111
79f6c36c 2112 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_MESSAGE);
8c55bd6c
RW
2113
2114 return true;
2115 }
2116
2117 /**
2118 * Mark all notifications as read return description.
2119 *
2120 * @return external_single_structure
2121 * @since 3.2
2122 */
2123 public static function mark_all_messages_as_read_returns() {
2124 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2125 }
2126
dec0cd99
MN
2127 /**
2128 * Returns description of method parameters.
2129 *
2130 * @return external_function_parameters
2131 * @since 3.2
2132 */
2133 public static function delete_conversation_parameters() {
2134 return new external_function_parameters(
2135 array(
2136 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
2137 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
2138 )
2139 );
2140 }
2141
2142 /**
2143 * Deletes a conversation.
2144 *
2145 * @param int $userid The user id of who we want to delete the conversation for
2146 * @param int $otheruserid The user id of the other user in the conversation
2147 * @return array
2148 * @throws moodle_exception
2149 * @since 3.2
2150 */
2151 public static function delete_conversation($userid, $otheruserid) {
2152 global $CFG;
2153
2154 // Check if private messaging between users is allowed.
2155 if (empty($CFG->messaging)) {
2156 throw new moodle_exception('disabled', 'message');
2157 }
2158
2159 // Warnings array, it can be empty at the end but is mandatory.
2160 $warnings = array();
2161
2162 // Validate params.
2163 $params = array(
2164 'userid' => $userid,
2165 'otheruserid' => $otheruserid,
2166 );
2167 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
2168
2169 // Validate context.
2170 $context = context_system::instance();
2171 self::validate_context($context);
2172
2173 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2174 core_user::require_active_user($user);
2175
2176 if (\core_message\api::can_delete_conversation($user->id)) {
2177 $status = \core_message\api::delete_conversation($user->id, $otheruserid);
2178 } else {
2179 throw new moodle_exception('You do not have permission to delete messages');
2180 }
2181
2182 $results = array(
2183 'status' => $status,
2184 'warnings' => $warnings
2185 );
2186
2187 return $results;
2188 }
2189
2190 /**
2191 * Returns description of method result value.
2192 *
2193 * @return external_description
2194 * @since 3.2
2195 */
2196 public static function delete_conversation_returns() {
2197 return new external_single_structure(
2198 array(
2199 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
2200 'warnings' => new external_warnings()
2201 )
2202 );
2203 }
2204
419b1128
JL
2205 /**
2206 * Returns description of method parameters
2207 *
2208 * @return external_function_parameters
2209 * @since 3.1
2210 */
2211 public static function delete_message_parameters() {
2212 return new external_function_parameters(
2213 array(
2214 'messageid' => new external_value(PARAM_INT, 'The message id'),
2215 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
2216 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
2217 )
2218 );
2219 }
2220
2221 /**
2222 * Deletes a message
2223 *
2224 * @param int $messageid the message id
2225 * @param int $userid the user id of who we want to delete the message for
2226 * @param bool $read if is a message read (default to true)
2227 * @return external_description
2228 * @throws moodle_exception
2229 * @since 3.1
2230 */
2231 public static function delete_message($messageid, $userid, $read = true) {
2232 global $CFG, $DB;
419b1128
JL
2233
2234 // Check if private messaging between users is allowed.
2235 if (empty($CFG->messaging)) {
2236 throw new moodle_exception('disabled', 'message');
2237 }
2238
2239 // Warnings array, it can be empty at the end but is mandatory.
2240 $warnings = array();
2241
2242 // Validate params.
2243 $params = array(
2244 'messageid' => $messageid,
2245 'userid' => $userid,
2246 'read' => $read
2247 );
2248 $params = self::validate_parameters(self::delete_message_parameters(), $params);
2249
2250 // Validate context.
2251 $context = context_system::instance();
2252 self::validate_context($context);
2253
2254 $messagestable = $params['read'] ? 'message_read' : 'message';
2255 $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
2256
2257 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2258 core_user::require_active_user($user);
2259
2260 $status = false;
2261 if (message_can_delete_message($message, $user->id)) {
2262 $status = message_delete_message($message, $user->id);;
2263 } else {
2264 throw new moodle_exception('You do not have permission to delete this message');
2265 }
2266
2267 $results = array(
2268 'status' => $status,
2269 'warnings' => $warnings
2270 );
2271 return $results;
2272 }
2273
2274 /**
2275 * Returns description of method result value
2276 *
2277 * @return external_description
2278 * @since 3.1
2279 */
2280 public static function delete_message_returns() {
2281 return new external_single_structure(
2282 array(
2283 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
2284 'warnings' => new external_warnings()
2285 )
2286 );
2287 }
2288
a0eabdd3
RW
2289 /**
2290 * Returns description of method parameters
2291 *
2292 * @return external_function_parameters
2293 * @since 3.2
2294 */
2295 public static function message_processor_config_form_parameters() {
2296 return new external_function_parameters(
2297 array(
2298 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
2299 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
2300 'formvalues' => new external_multiple_structure(
2301 new external_single_structure(
2302 array(
2303 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
2304 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
2305 )
2306 ),
2307 'Config form values',
2308 VALUE_REQUIRED
2309 ),
2310 )
2311 );
2312 }
2313
2314 /**
2315 * Processes a message processor config form.
2316 *
2317 * @param int $userid the user id
2318 * @param string $name the name of the processor
2319 * @param array $formvalues the form values
2320 * @return external_description
2321 * @throws moodle_exception
2322 * @since 3.2
2323 */
2324 public static function message_processor_config_form($userid, $name, $formvalues) {
8c125526
RW
2325 global $USER;
2326
a0eabdd3
RW
2327 $params = self::validate_parameters(
2328 self::message_processor_config_form_parameters(),
2329 array(
2330 'userid' => $userid,
2331 'name' => $name,
2332 'formvalues' => $formvalues,
2333 )
2334 );
2335
2336 if (empty($params['userid'])) {
2337 $params['userid'] = $USER->id;
2338 }
2339
2340 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2341 core_user::require_active_user($user);
2342
2343 $processor = get_message_processor($name);
2344 $preferences = [];
2345 $form = new stdClass();
2346
2347 foreach ($formvalues as $formvalue) {
2348 $form->$formvalue['name'] = $formvalue['value'];
2349 }
2350
2351 $processor->process_form($form, $preferences);
2352
2353 if (!empty($preferences)) {
2354 set_user_preferences($preferences, $userid);
2355 }
2356 }
2357
2358 /**
2359 * Returns description of method result value
2360 *
2361 * @return external_description
2362 * @since 3.2
2363 */
2364 public static function message_processor_config_form_returns() {
2365 return null;
2366 }
8c125526
RW
2367
2368 /**
2369 * Returns description of method parameters
2370 *
2371 * @return external_function_parameters
2372 * @since 3.2
2373 */
2374 public static function get_message_processor_parameters() {
2375 return new external_function_parameters(
2376 array(
2377 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
2378 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
2379 )
2380 );
2381 }
2382
2383 /**
2384 * Get a message processor.
2385 *
2386 * @param string $name the name of the processor
2387 * @return external_description
2388 * @throws moodle_exception
2389 * @since 3.2
2390 */
2391 public static function get_message_processor($userid = 0, $name) {
2392 global $USER, $PAGE;
2393
2394 $params = self::validate_parameters(
2395 self::get_message_processor_parameters(),
2396 array(
2397 'userid' => $userid,
2398 'name' => $name,
2399 )
2400 );
2401
2402 if (empty($params['userid'])) {
2403 $params['userid'] = $USER->id;
2404 }
2405
2406 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2407 core_user::require_active_user($user);
2408 self::validate_context(context_user::instance($params['userid']));
2409
2410 $processor = get_message_processor($name);
2411
2412 $processoroutput = new \core_message\output\processor($processor, $user);
2413 $renderer = $PAGE->get_renderer('core_message');
2414
2415 return $processoroutput->export_for_template($renderer);
2416 }
2417
2418 /**
2419 * Returns description of method result value
2420 *
2421 * @return external_description
2422 * @since 3.2
2423 */
2424 public static function get_message_processor_returns() {
2425 return new external_function_parameters(
2426 array(
2427 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
2428 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
2429 )
2430 );
2431 }
a623b6b8 2432}