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