MDL-58859 analytics: Fix migration to core bugs and pre-migration issues
[moodle.git] / message / externallib.php
blobb0f38eb12171aaa90c864d0df4f7ab3e3440b391
1 <?php
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.
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/>.
18 /**
19 * External message API
21 * @package core_message
22 * @category external
23 * @copyright 2011 Jerome Mouneyrac
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 require_once("$CFG->libdir/externallib.php");
28 require_once($CFG->dirroot . "/message/lib.php");
30 /**
31 * Message external functions
33 * @package core_message
34 * @category external
35 * @copyright 2011 Jerome Mouneyrac
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 * @since Moodle 2.2
39 class core_message_external extends external_api {
41 /**
42 * Returns description of method parameters
44 * @return external_function_parameters
45 * @since Moodle 2.2
47 public static function send_instant_messages_parameters() {
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'),
54 'text' => new external_value(PARAM_RAW, 'the text of the message'),
55 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
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),
64 /**
65 * Send private messages from the current USER to other users
67 * @param array $messages An array of message to send.
68 * @return array
69 * @since Moodle 2.2
71 public static function send_instant_messages($messages = array()) {
72 global $CFG, $USER, $DB;
74 // Check if messaging is enabled.
75 if (empty($CFG->messaging)) {
76 throw new moodle_exception('disabled', 'message');
79 // Ensure the current user is allowed to run this function
80 $context = context_system::instance();
81 self::validate_context($context);
82 require_capability('moodle/site:sendmessage', $context);
84 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
86 //retrieve all tousers of the messages
87 $receivers = array();
88 foreach($params['messages'] as $message) {
89 $receivers[] = $message['touserid'];
91 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers, SQL_PARAMS_NAMED, 'userid_');
92 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
93 $blocklist = array();
94 $contactlist = array();
95 $sqlparams['contactid'] = $USER->id;
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;
109 $rs->close();
111 $canreadallmessages = has_capability('moodle/site:readallmessages', $context);
113 $resultmessages = array();
114 foreach ($params['messages'] as $message) {
115 $resultmsg = array(); //the infos about the success of the operation
117 //we are going to do some checking
118 //code should match /messages/index.php checks
119 $success = true;
121 //check the user exists
122 if (empty($tousers[$message['touserid']])) {
123 $success = false;
124 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
127 //check that the touser is not blocking the current user
128 if ($success and !empty($blocklist[$message['touserid']]) and !$canreadallmessages) {
129 $success = false;
130 $errormessage = get_string('userisblockingyou', 'message');
133 // Check if the user is a contact
134 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
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)) {
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;
140 $errormessage = get_string('userisblockingyounoncontact', 'message',
141 fullname(core_user::get_user($message['touserid'])));
144 //now we can send the message (at least try)
145 if ($success) {
146 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object
147 $success = message_post_message($USER, $tousers[$message['touserid']],
148 $message['text'], external_validate_format($message['textformat']));
151 //build the resultmsg
152 if (isset($message['clientmsgid'])) {
153 $resultmsg['clientmsgid'] = $message['clientmsgid'];
155 if ($success) {
156 $resultmsg['msgid'] = $success;
157 } else {
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 .
161 $resultmsg['msgid'] = -1;
162 $resultmsg['errormessage'] = $errormessage;
165 $resultmessages[] = $resultmsg;
168 return $resultmessages;
172 * Returns description of method result value
174 * @return external_description
175 * @since Moodle 2.2
177 public static function send_instant_messages_returns() {
178 return new external_multiple_structure(
179 new external_single_structure(
180 array(
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'),
182 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
183 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL)
190 * Create contacts parameters description.
192 * @return external_function_parameters
193 * @since Moodle 2.5
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'
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)
209 * Create contacts.
211 * @param array $userids array of user IDs.
212 * @param int $userid The id of the user we are creating the contacts for
213 * @return external_description
214 * @since Moodle 2.5
216 public static function create_contacts($userids, $userid = 0) {
217 global $CFG, $USER;
219 // Check if messaging is enabled.
220 if (empty($CFG->messaging)) {
221 throw new moodle_exception('disabled', 'message');
224 if (empty($userid)) {
225 $userid = $USER->id;
228 // Validate context.
229 $context = context_system::instance();
230 self::validate_context($context);
232 $capability = 'moodle/site:manageallmessaging';
233 if (($USER->id != $userid) && !has_capability($capability, $context)) {
234 throw new required_capability_exception($context, $capability, 'nopermissions', '');
237 $params = array('userids' => $userids, 'userid' => $userid);
238 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
240 $warnings = array();
241 foreach ($params['userids'] as $id) {
242 if (!message_add_contact($id, 0, $userid)) {
243 $warnings[] = array(
244 'item' => 'user',
245 'itemid' => $id,
246 'warningcode' => 'contactnotcreated',
247 'message' => 'The contact could not be created'
251 return $warnings;
255 * Create contacts return description.
257 * @return external_description
258 * @since Moodle 2.5
260 public static function create_contacts_returns() {
261 return new external_warnings();
265 * Delete contacts parameters description.
267 * @return external_function_parameters
268 * @since Moodle 2.5
270 public static function delete_contacts_parameters() {
271 return new external_function_parameters(
272 array(
273 'userids' => new external_multiple_structure(
274 new external_value(PARAM_INT, 'User ID'),
275 'List of user IDs'
277 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the
278 current user', VALUE_DEFAULT, 0)
284 * Delete contacts.
286 * @param array $userids array of user IDs.
287 * @param int $userid The id of the user we are deleting the contacts for
288 * @return null
289 * @since Moodle 2.5
291 public static function delete_contacts($userids, $userid = 0) {
292 global $CFG, $USER;
294 // Check if messaging is enabled.
295 if (empty($CFG->messaging)) {
296 throw new moodle_exception('disabled', 'message');
299 if (empty($userid)) {
300 $userid = $USER->id;
303 // Validate context.
304 $context = context_system::instance();
305 self::validate_context($context);
307 $capability = 'moodle/site:manageallmessaging';
308 if (($USER->id != $userid) && !has_capability($capability, $context)) {
309 throw new required_capability_exception($context, $capability, 'nopermissions', '');
312 $params = array('userids' => $userids, 'userid' => $userid);
313 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
315 foreach ($params['userids'] as $id) {
316 message_remove_contact($id, $userid);
319 return null;
323 * Delete contacts return description.
325 * @return external_description
326 * @since Moodle 2.5
328 public static function delete_contacts_returns() {
329 return null;
333 * Block contacts parameters description.
335 * @return external_function_parameters
336 * @since Moodle 2.5
338 public static function block_contacts_parameters() {
339 return new external_function_parameters(
340 array(
341 'userids' => new external_multiple_structure(
342 new external_value(PARAM_INT, 'User ID'),
343 'List of user IDs'
345 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the
346 current user', VALUE_DEFAULT, 0)
352 * Block contacts.
354 * @param array $userids array of user IDs.
355 * @param int $userid The id of the user we are blocking the contacts for
356 * @return external_description
357 * @since Moodle 2.5
359 public static function block_contacts($userids, $userid = 0) {
360 global $CFG, $USER;
362 // Check if messaging is enabled.
363 if (empty($CFG->messaging)) {
364 throw new moodle_exception('disabled', 'message');
367 if (empty($userid)) {
368 $userid = $USER->id;
371 // Validate context.
372 $context = context_system::instance();
373 self::validate_context($context);
375 $capability = 'moodle/site:manageallmessaging';
376 if (($USER->id != $userid) && !has_capability($capability, $context)) {
377 throw new required_capability_exception($context, $capability, 'nopermissions', '');
380 $params = array('userids' => $userids, 'userid' => $userid);
381 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
383 $warnings = array();
384 foreach ($params['userids'] as $id) {
385 if (!message_block_contact($id, $userid)) {
386 $warnings[] = array(
387 'item' => 'user',
388 'itemid' => $id,
389 'warningcode' => 'contactnotblocked',
390 'message' => 'The contact could not be blocked'
394 return $warnings;
398 * Block contacts return description.
400 * @return external_description
401 * @since Moodle 2.5
403 public static function block_contacts_returns() {
404 return new external_warnings();
408 * Unblock contacts parameters description.
410 * @return external_function_parameters
411 * @since Moodle 2.5
413 public static function unblock_contacts_parameters() {
414 return new external_function_parameters(
415 array(
416 'userids' => new external_multiple_structure(
417 new external_value(PARAM_INT, 'User ID'),
418 'List of user IDs'
420 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the
421 current user', VALUE_DEFAULT, 0)
427 * Unblock contacts.
429 * @param array $userids array of user IDs.
430 * @param int $userid The id of the user we are unblocking the contacts for
431 * @return null
432 * @since Moodle 2.5
434 public static function unblock_contacts($userids, $userid = 0) {
435 global $CFG, $USER;
437 // Check if messaging is enabled.
438 if (empty($CFG->messaging)) {
439 throw new moodle_exception('disabled', 'message');
442 if (empty($userid)) {
443 $userid = $USER->id;
446 // Validate context.
447 $context = context_system::instance();
448 self::validate_context($context);
450 $capability = 'moodle/site:manageallmessaging';
451 if (($USER->id != $userid) && !has_capability($capability, $context)) {
452 throw new required_capability_exception($context, $capability, 'nopermissions', '');
455 $params = array('userids' => $userids, 'userid' => $userid);
456 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
458 foreach ($params['userids'] as $id) {
459 message_unblock_contact($id, $userid);
462 return null;
466 * Unblock contacts return description.
468 * @return external_description
469 * @since Moodle 2.5
471 public static function unblock_contacts_returns() {
472 return null;
476 * Return the structure of a message area contact.
478 * @return external_single_structure
479 * @since Moodle 3.2
481 private static function get_messagearea_contact_structure() {
482 return new external_single_structure(
483 array(
484 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
485 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
486 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
487 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
488 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
489 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
490 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
491 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
492 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
493 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
494 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
495 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
496 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
497 VALUE_DEFAULT, null),
503 * Return the structure of a message area message.
505 * @return external_single_structure
506 * @since Moodle 3.2
508 private static function get_messagearea_message_structure() {
509 return new external_single_structure(
510 array(
511 'id' => new external_value(PARAM_INT, 'The id of the message'),
512 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
513 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
514 'text' => new external_value(PARAM_RAW, 'The text of the message'),
515 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
516 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
517 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
518 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
519 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
520 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
526 * Get messagearea search users in course parameters.
528 * @return external_function_parameters
529 * @since 3.2
531 public static function data_for_messagearea_search_users_in_course_parameters() {
532 return new external_function_parameters(
533 array(
534 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
535 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
536 'search' => new external_value(PARAM_RAW, 'The string being searched'),
537 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
538 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
544 * Get messagearea search users in course results.
546 * @param int $userid The id of the user who is performing the search
547 * @param int $courseid The id of the course
548 * @param string $search The string being searched
549 * @param int $limitfrom
550 * @param int $limitnum
551 * @return stdClass
552 * @throws moodle_exception
553 * @since 3.2
555 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
556 $limitnum = 0) {
557 global $CFG, $PAGE, $USER;
559 // Check if messaging is enabled.
560 if (empty($CFG->messaging)) {
561 throw new moodle_exception('disabled', 'message');
564 $systemcontext = context_system::instance();
566 $params = array(
567 'userid' => $userid,
568 'courseid' => $courseid,
569 'search' => $search,
570 'limitfrom' => $limitfrom,
571 'limitnum' => $limitnum
573 self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
574 self::validate_context($systemcontext);
576 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
577 throw new moodle_exception('You do not have permission to perform this action.');
580 $users = \core_message\api::search_users_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
581 $results = new \core_message\output\messagearea\user_search_results($users);
583 $renderer = $PAGE->get_renderer('core_message');
584 return $results->export_for_template($renderer);
588 * Get messagearea search users in course returns.
590 * @return external_single_structure
591 * @since 3.2
593 public static function data_for_messagearea_search_users_in_course_returns() {
594 return new external_single_structure(
595 array(
596 'contacts' => new external_multiple_structure(
597 self::get_messagearea_contact_structure()
604 * Get messagearea search users parameters.
606 * @return external_function_parameters
607 * @since 3.2
609 public static function data_for_messagearea_search_users_parameters() {
610 return new external_function_parameters(
611 array(
612 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
613 'search' => new external_value(PARAM_RAW, 'The string being searched'),
614 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
620 * Get messagearea search users results.
622 * @param int $userid The id of the user who is performing the search
623 * @param string $search The string being searched
624 * @param int $limitnum
625 * @return stdClass
626 * @throws moodle_exception
627 * @since 3.2
629 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
630 global $CFG, $PAGE, $USER;
632 // Check if messaging is enabled.
633 if (empty($CFG->messaging)) {
634 throw new moodle_exception('disabled', 'message');
637 $systemcontext = context_system::instance();
639 $params = array(
640 'userid' => $userid,
641 'search' => $search,
642 'limitnum' => $limitnum
644 self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
645 self::validate_context($systemcontext);
647 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
648 throw new moodle_exception('You do not have permission to perform this action.');
651 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($userid, $search, $limitnum);
652 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
654 $renderer = $PAGE->get_renderer('core_message');
655 return $search->export_for_template($renderer);
659 * Get messagearea search users returns.
661 * @return external_single_structure
662 * @since 3.2
664 public static function data_for_messagearea_search_users_returns() {
665 return new external_single_structure(
666 array(
667 'contacts' => new external_multiple_structure(
668 self::get_messagearea_contact_structure()
670 'courses' => new external_multiple_structure(
671 new external_single_structure(
672 array(
673 'id' => new external_value(PARAM_INT, 'The course id'),
674 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
675 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
679 'noncontacts' => new external_multiple_structure(
680 self::get_messagearea_contact_structure()
687 * Get messagearea search messages parameters.
689 * @return external_function_parameters
690 * @since 3.2
692 public static function data_for_messagearea_search_messages_parameters() {
693 return new external_function_parameters(
694 array(
695 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
696 'search' => new external_value(PARAM_RAW, 'The string being searched'),
697 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
698 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
704 * Get messagearea search messages results.
706 * @param int $userid The id of the user who is performing the search
707 * @param string $search The string being searched
708 * @param int $limitfrom
709 * @param int $limitnum
710 * @return stdClass
711 * @throws moodle_exception
712 * @since 3.2
714 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
715 global $CFG, $PAGE, $USER;
717 // Check if messaging is enabled.
718 if (empty($CFG->messaging)) {
719 throw new moodle_exception('disabled', 'message');
722 $systemcontext = context_system::instance();
724 $params = array(
725 'userid' => $userid,
726 'search' => $search,
727 'limitfrom' => $limitfrom,
728 'limitnum' => $limitnum
731 self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
732 self::validate_context($systemcontext);
734 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
735 throw new moodle_exception('You do not have permission to perform this action.');
738 $messages = \core_message\api::search_messages($userid, $search, $limitfrom, $limitnum);
739 $results = new \core_message\output\messagearea\message_search_results($messages);
741 $renderer = $PAGE->get_renderer('core_message');
742 return $results->export_for_template($renderer);
746 * Get messagearea search messages returns.
748 * @return external_single_structure
749 * @since 3.2
751 public static function data_for_messagearea_search_messages_returns() {
752 return new external_single_structure(
753 array(
754 'contacts' => new external_multiple_structure(
755 self::get_messagearea_contact_structure()
762 * The messagearea conversations parameters.
764 * @return external_function_parameters
765 * @since 3.2
767 public static function data_for_messagearea_conversations_parameters() {
768 return new external_function_parameters(
769 array(
770 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
771 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
772 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
778 * Get messagearea conversations.
780 * @param int $userid The id of the user who we are viewing conversations for
781 * @param int $limitfrom
782 * @param int $limitnum
783 * @return stdClass
784 * @throws moodle_exception
785 * @since 3.2
787 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
788 global $CFG, $PAGE, $USER;
790 // Check if messaging is enabled.
791 if (empty($CFG->messaging)) {
792 throw new moodle_exception('disabled', 'message');
795 $systemcontext = context_system::instance();
797 $params = array(
798 'userid' => $userid,
799 'limitfrom' => $limitfrom,
800 'limitnum' => $limitnum
802 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
803 self::validate_context($systemcontext);
805 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
806 throw new moodle_exception('You do not have permission to perform this action.');
809 $conversations = \core_message\api::get_conversations($userid, $limitfrom, $limitnum);
810 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
812 $renderer = $PAGE->get_renderer('core_message');
813 return $conversations->export_for_template($renderer);
817 * The messagearea conversations return structure.
819 * @return external_single_structure
820 * @since 3.2
822 public static function data_for_messagearea_conversations_returns() {
823 return new external_single_structure(
824 array(
825 'contacts' => new external_multiple_structure(
826 self::get_messagearea_contact_structure()
833 * The messagearea contacts return parameters.
835 * @return external_function_parameters
836 * @since 3.2
838 public static function data_for_messagearea_contacts_parameters() {
839 return self::data_for_messagearea_conversations_parameters();
843 * Get messagearea contacts parameters.
845 * @param int $userid The id of the user who we are viewing conversations for
846 * @param int $limitfrom
847 * @param int $limitnum
848 * @return stdClass
849 * @throws moodle_exception
850 * @since 3.2
852 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
853 global $CFG, $PAGE, $USER;
855 // Check if messaging is enabled.
856 if (empty($CFG->messaging)) {
857 throw new moodle_exception('disabled', 'message');
860 $systemcontext = context_system::instance();
862 $params = array(
863 'userid' => $userid,
864 'limitfrom' => $limitfrom,
865 'limitnum' => $limitnum
867 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
868 self::validate_context($systemcontext);
870 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
871 throw new moodle_exception('You do not have permission to perform this action.');
874 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
875 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
877 $renderer = $PAGE->get_renderer('core_message');
878 return $contacts->export_for_template($renderer);
882 * The messagearea contacts return structure.
884 * @return external_single_structure
885 * @since 3.2
887 public static function data_for_messagearea_contacts_returns() {
888 return self::data_for_messagearea_conversations_returns();
892 * The messagearea messages parameters.
894 * @return external_function_parameters
895 * @since 3.2
897 public static function data_for_messagearea_messages_parameters() {
898 return new external_function_parameters(
899 array(
900 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
901 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
902 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
903 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
904 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
905 'timefrom' => new external_value(PARAM_INT,
906 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
912 * Get messagearea messages.
914 * @param int $currentuserid The current user's id
915 * @param int $otheruserid The other user's id
916 * @param int $limitfrom
917 * @param int $limitnum
918 * @param boolean $newest
919 * @return stdClass
920 * @throws moodle_exception
921 * @since 3.2
923 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
924 $newest = false, $timefrom = 0) {
925 global $CFG, $PAGE, $USER;
927 // Check if messaging is enabled.
928 if (empty($CFG->messaging)) {
929 throw new moodle_exception('disabled', 'message');
932 $systemcontext = context_system::instance();
934 $params = array(
935 'currentuserid' => $currentuserid,
936 'otheruserid' => $otheruserid,
937 'limitfrom' => $limitfrom,
938 'limitnum' => $limitnum,
939 'newest' => $newest,
940 'timefrom' => $timefrom,
942 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
943 self::validate_context($systemcontext);
945 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
946 throw new moodle_exception('You do not have permission to perform this action.');
949 if ($newest) {
950 $sort = 'timecreated DESC';
951 } else {
952 $sort = 'timecreated ASC';
955 // We need to enforce a one second delay on messages to avoid race conditions of current
956 // messages still being sent.
958 // There is a chance that we could request messages before the current time's
959 // second has elapsed and while other messages are being sent in that same second. In which
960 // case those messages will be lost.
962 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
963 if (!empty($timefrom)) {
964 $timeto = time() - 1;
965 } else {
966 $timeto = 0;
969 // No requesting messages from the current time, as stated above.
970 if ($timefrom == time()) {
971 $messages = [];
972 } else {
973 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom,
974 $limitnum, $sort, $timefrom, $timeto);
977 $messages = new \core_message\output\messagearea\messages($currentuserid, $otheruserid, $messages);
979 $renderer = $PAGE->get_renderer('core_message');
980 return $messages->export_for_template($renderer);
984 * The messagearea messages return structure.
986 * @return external_single_structure
987 * @since 3.2
989 public static function data_for_messagearea_messages_returns() {
990 return new external_single_structure(
991 array(
992 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
993 the messages on behalf of?'),
994 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
995 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
996 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
997 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
998 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
999 'messages' => new external_multiple_structure(
1000 self::get_messagearea_message_structure()
1002 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
1008 * The get most recent message return parameters.
1010 * @return external_function_parameters
1011 * @since 3.2
1013 public static function data_for_messagearea_get_most_recent_message_parameters() {
1014 return new external_function_parameters(
1015 array(
1016 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1017 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1023 * Get the most recent message in a conversation.
1025 * @param int $currentuserid The current user's id
1026 * @param int $otheruserid The other user's id
1027 * @return stdClass
1028 * @throws moodle_exception
1029 * @since 3.2
1031 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
1032 global $CFG, $PAGE, $USER;
1034 // Check if messaging is enabled.
1035 if (empty($CFG->messaging)) {
1036 throw new moodle_exception('disabled', 'message');
1039 $systemcontext = context_system::instance();
1041 $params = array(
1042 'currentuserid' => $currentuserid,
1043 'otheruserid' => $otheruserid
1045 self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
1046 self::validate_context($systemcontext);
1048 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1049 throw new moodle_exception('You do not have permission to perform this action.');
1052 $message = \core_message\api::get_most_recent_message($currentuserid, $otheruserid);
1053 $message = new \core_message\output\messagearea\message($message);
1055 $renderer = $PAGE->get_renderer('core_message');
1056 return $message->export_for_template($renderer);
1060 * The get most recent message return structure.
1062 * @return external_single_structure
1063 * @since 3.2
1065 public static function data_for_messagearea_get_most_recent_message_returns() {
1066 return self::get_messagearea_message_structure();
1070 * The get profile parameters.
1072 * @return external_function_parameters
1073 * @since 3.2
1075 public static function data_for_messagearea_get_profile_parameters() {
1076 return new external_function_parameters(
1077 array(
1078 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1079 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
1085 * Get the profile information for a contact.
1087 * @param int $currentuserid The current user's id
1088 * @param int $otheruserid The id of the user whose profile we are viewing
1089 * @return stdClass
1090 * @throws moodle_exception
1091 * @since 3.2
1093 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
1094 global $CFG, $PAGE, $USER;
1096 // Check if messaging is enabled.
1097 if (empty($CFG->messaging)) {
1098 throw new moodle_exception('disabled', 'message');
1101 $systemcontext = context_system::instance();
1103 $params = array(
1104 'currentuserid' => $currentuserid,
1105 'otheruserid' => $otheruserid
1107 self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
1108 self::validate_context($systemcontext);
1110 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1111 throw new moodle_exception('You do not have permission to perform this action.');
1114 $profile = \core_message\api::get_profile($currentuserid, $otheruserid);
1115 $profile = new \core_message\output\messagearea\profile($profile);
1117 $renderer = $PAGE->get_renderer('core_message');
1118 return $profile->export_for_template($renderer);
1122 * The get profile return structure.
1124 * @return external_single_structure
1125 * @since 3.2
1127 public static function data_for_messagearea_get_profile_returns() {
1128 return new external_single_structure(
1129 array(
1130 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
1131 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
1132 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
1133 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
1134 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1135 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1136 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1137 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1138 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1139 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
1140 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
1146 * Get contacts parameters description.
1148 * @return external_function_parameters
1149 * @since Moodle 2.5
1151 public static function get_contacts_parameters() {
1152 return new external_function_parameters(array());
1156 * Get contacts.
1158 * @return external_description
1159 * @since Moodle 2.5
1161 public static function get_contacts() {
1162 global $CFG, $PAGE;
1164 // Check if messaging is enabled.
1165 if (empty($CFG->messaging)) {
1166 throw new moodle_exception('disabled', 'message');
1169 require_once($CFG->dirroot . '/user/lib.php');
1171 list($online, $offline, $strangers) = message_get_contacts();
1172 $allcontacts = array('online' => $online, 'offline' => $offline, 'strangers' => $strangers);
1173 foreach ($allcontacts as $mode => $contacts) {
1174 foreach ($contacts as $key => $contact) {
1175 $newcontact = array(
1176 'id' => $contact->id,
1177 'fullname' => fullname($contact),
1178 'unread' => $contact->messagecount
1181 $userpicture = new user_picture($contact);
1182 $userpicture->size = 1; // Size f1.
1183 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1184 $userpicture->size = 0; // Size f2.
1185 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1187 $allcontacts[$mode][$key] = $newcontact;
1190 return $allcontacts;
1194 * Get contacts return description.
1196 * @return external_description
1197 * @since Moodle 2.5
1199 public static function get_contacts_returns() {
1200 return new external_single_structure(
1201 array(
1202 'online' => new external_multiple_structure(
1203 new external_single_structure(
1204 array(
1205 'id' => new external_value(PARAM_INT, 'User ID'),
1206 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1207 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1208 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1209 'unread' => new external_value(PARAM_INT, 'Unread message count')
1212 'List of online contacts'
1214 'offline' => new external_multiple_structure(
1215 new external_single_structure(
1216 array(
1217 'id' => new external_value(PARAM_INT, 'User ID'),
1218 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1219 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1220 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1221 'unread' => new external_value(PARAM_INT, 'Unread message count')
1224 'List of offline contacts'
1226 'strangers' => new external_multiple_structure(
1227 new external_single_structure(
1228 array(
1229 'id' => new external_value(PARAM_INT, 'User ID'),
1230 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1231 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1232 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1233 'unread' => new external_value(PARAM_INT, 'Unread message count')
1236 'List of users that are not in the user\'s contact list but have sent a message'
1243 * Search contacts parameters description.
1245 * @return external_function_parameters
1246 * @since Moodle 2.5
1248 public static function search_contacts_parameters() {
1249 return new external_function_parameters(
1250 array(
1251 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
1252 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
1253 VALUE_DEFAULT, false)
1259 * Search contacts.
1261 * @param string $searchtext query string.
1262 * @param bool $onlymycourses limit the search to the user's courses only.
1263 * @return external_description
1264 * @since Moodle 2.5
1266 public static function search_contacts($searchtext, $onlymycourses = false) {
1267 global $CFG, $USER, $PAGE;
1268 require_once($CFG->dirroot . '/user/lib.php');
1270 // Check if messaging is enabled.
1271 if (empty($CFG->messaging)) {
1272 throw new moodle_exception('disabled', 'message');
1275 require_once($CFG->libdir . '/enrollib.php');
1277 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1278 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
1280 // Extra validation, we do not allow empty queries.
1281 if ($params['searchtext'] === '') {
1282 throw new moodle_exception('querystringcannotbeempty');
1285 $courseids = array();
1286 if ($params['onlymycourses']) {
1287 $mycourses = enrol_get_my_courses(array('id'));
1288 foreach ($mycourses as $mycourse) {
1289 $courseids[] = $mycourse->id;
1291 } else {
1292 $courseids[] = SITEID;
1295 // Retrieving the users matching the query.
1296 $users = message_search_users($courseids, $params['searchtext']);
1297 $results = array();
1298 foreach ($users as $user) {
1299 $results[$user->id] = $user;
1302 // Reorganising information.
1303 foreach ($results as &$user) {
1304 $newuser = array(
1305 'id' => $user->id,
1306 'fullname' => fullname($user)
1309 // Avoid undefined property notice as phone not specified.
1310 $user->phone1 = null;
1311 $user->phone2 = null;
1313 $userpicture = new user_picture($user);
1314 $userpicture->size = 1; // Size f1.
1315 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1316 $userpicture->size = 0; // Size f2.
1317 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1319 $user = $newuser;
1322 return $results;
1326 * Search contacts return description.
1328 * @return external_description
1329 * @since Moodle 2.5
1331 public static function search_contacts_returns() {
1332 return new external_multiple_structure(
1333 new external_single_structure(
1334 array(
1335 'id' => new external_value(PARAM_INT, 'User ID'),
1336 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1337 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1338 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
1341 'List of contacts'
1346 * Get messages parameters description.
1348 * @return external_function_parameters
1349 * @since 2.8
1351 public static function get_messages_parameters() {
1352 return new external_function_parameters(
1353 array(
1354 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1355 'useridfrom' => new external_value(
1356 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1357 VALUE_DEFAULT, 0),
1358 'type' => new external_value(
1359 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
1360 VALUE_DEFAULT, 'both'),
1361 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
1362 'newestfirst' => new external_value(
1363 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1364 VALUE_DEFAULT, true),
1365 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
1366 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
1372 * Get messages function implementation.
1374 * @since 2.8
1375 * @throws invalid_parameter_exception
1376 * @throws moodle_exception
1377 * @param int $useridto the user id who received the message
1378 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1379 * @param string $type type of message to return, expected values: notifications, conversations and both
1380 * @param bool $read true for retreiving read messages, false for unread
1381 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1382 * @param int $limitfrom limit from
1383 * @param int $limitnum limit num
1384 * @return external_description
1386 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
1387 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
1388 global $CFG, $USER;
1390 $warnings = array();
1392 $params = array(
1393 'useridto' => $useridto,
1394 'useridfrom' => $useridfrom,
1395 'type' => $type,
1396 'read' => $read,
1397 'newestfirst' => $newestfirst,
1398 'limitfrom' => $limitfrom,
1399 'limitnum' => $limitnum
1402 $params = self::validate_parameters(self::get_messages_parameters(), $params);
1404 $context = context_system::instance();
1405 self::validate_context($context);
1407 $useridto = $params['useridto'];
1408 $useridfrom = $params['useridfrom'];
1409 $type = $params['type'];
1410 $read = $params['read'];
1411 $newestfirst = $params['newestfirst'];
1412 $limitfrom = $params['limitfrom'];
1413 $limitnum = $params['limitnum'];
1415 $allowedvalues = array('notifications', 'conversations', 'both');
1416 if (!in_array($type, $allowedvalues)) {
1417 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1418 'allowed values are: ' . implode(',', $allowedvalues));
1421 // Check if private messaging between users is allowed.
1422 if (empty($CFG->messaging)) {
1423 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
1424 if ($type == "conversations") {
1425 throw new moodle_exception('disabled', 'message');
1427 if ($type == "both") {
1428 $warning = array();
1429 $warning['item'] = 'message';
1430 $warning['itemid'] = $USER->id;
1431 $warning['warningcode'] = '1';
1432 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1433 Only notifications will be returned';
1434 $warnings[] = $warning;
1438 if (!empty($useridto)) {
1439 if (core_user::is_real_user($useridto)) {
1440 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1441 } else {
1442 throw new moodle_exception('invaliduser');
1446 if (!empty($useridfrom)) {
1447 // We use get_user here because the from user can be the noreply or support user.
1448 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1451 // Check if the current user is the sender/receiver or just a privileged user.
1452 if ($useridto != $USER->id and $useridfrom != $USER->id and
1453 !has_capability('moodle/site:readallmessages', $context)) {
1454 throw new moodle_exception('accessdenied', 'admin');
1457 // Which type of messages to retrieve.
1458 $notifications = -1;
1459 if ($type != 'both') {
1460 $notifications = ($type == 'notifications') ? 1 : 0;
1463 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
1464 $sort = "mr.timecreated $orderdirection";
1466 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
1467 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1469 // In some cases, we don't need to get the to/from user objects from the sql query.
1470 $userfromfullname = '';
1471 $usertofullname = '';
1473 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1474 if (!empty($useridto)) {
1475 $usertofullname = fullname($userto, $canviewfullname);
1476 // The user from may or may not be filled.
1477 if (!empty($useridfrom)) {
1478 $userfromfullname = fullname($userfrom, $canviewfullname);
1480 } else {
1481 // If the useridto field is empty, the useridfrom must be filled.
1482 $userfromfullname = fullname($userfrom, $canviewfullname);
1484 foreach ($messages as $mid => $message) {
1486 // Do not return deleted messages.
1487 if (($useridto == $USER->id and $message->timeusertodeleted) or
1488 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
1490 unset($messages[$mid]);
1491 continue;
1494 // We need to get the user from the query.
1495 if (empty($userfromfullname)) {
1496 // Check for non-reply and support users.
1497 if (core_user::is_real_user($message->useridfrom)) {
1498 $user = new stdClass();
1499 $user = username_load_fields_from_object($user, $message, 'userfrom');
1500 $message->userfromfullname = fullname($user, $canviewfullname);
1501 } else {
1502 $user = core_user::get_user($message->useridfrom);
1503 $message->userfromfullname = fullname($user, $canviewfullname);
1505 } else {
1506 $message->userfromfullname = $userfromfullname;
1509 // We need to get the user from the query.
1510 if (empty($usertofullname)) {
1511 $user = new stdClass();
1512 $user = username_load_fields_from_object($user, $message, 'userto');
1513 $message->usertofullname = fullname($user, $canviewfullname);
1514 } else {
1515 $message->usertofullname = $usertofullname;
1518 // This field is only available in the message_read table.
1519 if (!isset($message->timeread)) {
1520 $message->timeread = 0;
1523 $message->text = message_format_message_text($message);
1524 $messages[$mid] = (array) $message;
1528 $results = array(
1529 'messages' => $messages,
1530 'warnings' => $warnings
1533 return $results;
1537 * Get messages return description.
1539 * @return external_single_structure
1540 * @since 2.8
1542 public static function get_messages_returns() {
1543 return new external_single_structure(
1544 array(
1545 'messages' => new external_multiple_structure(
1546 new external_single_structure(
1547 array(
1548 'id' => new external_value(PARAM_INT, 'Message id'),
1549 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1550 'useridto' => new external_value(PARAM_INT, 'User to id'),
1551 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1552 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1553 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
1554 'fullmessageformat' => new external_format_value('fullmessage'),
1555 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1556 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1557 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
1558 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1559 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1560 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1561 'timeread' => new external_value(PARAM_INT, 'Time read'),
1562 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
1563 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
1564 ), 'message'
1567 'warnings' => new external_warnings()
1573 * Mark all notifications as read parameters description.
1575 * @return external_function_parameters
1576 * @since 3.2
1578 public static function mark_all_notifications_as_read_parameters() {
1579 return new external_function_parameters(
1580 array(
1581 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1582 'useridfrom' => new external_value(
1583 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1584 VALUE_DEFAULT, 0),
1590 * Mark all notifications as read function.
1592 * @since 3.2
1593 * @throws invalid_parameter_exception
1594 * @throws moodle_exception
1595 * @param int $useridto the user id who received the message
1596 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1597 * @return external_description
1599 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
1600 global $USER;
1602 $params = self::validate_parameters(
1603 self::mark_all_notifications_as_read_parameters(),
1604 array(
1605 'useridto' => $useridto,
1606 'useridfrom' => $useridfrom,
1610 $context = context_system::instance();
1611 self::validate_context($context);
1613 $useridto = $params['useridto'];
1614 $useridfrom = $params['useridfrom'];
1616 if (!empty($useridto)) {
1617 if (core_user::is_real_user($useridto)) {
1618 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1619 } else {
1620 throw new moodle_exception('invaliduser');
1624 if (!empty($useridfrom)) {
1625 // We use get_user here because the from user can be the noreply or support user.
1626 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1629 // Check if the current user is the sender/receiver or just a privileged user.
1630 if ($useridto != $USER->id and $useridfrom != $USER->id and
1631 // The deleteanymessage cap seems more reasonable here than readallmessages.
1632 !has_capability('moodle/site:deleteanymessage', $context)) {
1633 throw new moodle_exception('accessdenied', 'admin');
1636 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_NOTIFICATION);
1638 return true;
1642 * Mark all notifications as read return description.
1644 * @return external_single_structure
1645 * @since 3.2
1647 public static function mark_all_notifications_as_read_returns() {
1648 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
1652 * Get unread conversations count parameters description.
1654 * @return external_function_parameters
1655 * @since 3.2
1657 public static function get_unread_conversations_count_parameters() {
1658 return new external_function_parameters(
1659 array(
1660 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1666 * Get unread messages count function.
1668 * @since 3.2
1669 * @throws invalid_parameter_exception
1670 * @throws moodle_exception
1671 * @param int $useridto the user id who received the message
1672 * @return external_description
1674 public static function get_unread_conversations_count($useridto) {
1675 global $USER, $CFG;
1677 // Check if messaging is enabled.
1678 if (empty($CFG->messaging)) {
1679 throw new moodle_exception('disabled', 'message');
1682 $params = self::validate_parameters(
1683 self::get_unread_conversations_count_parameters(),
1684 array('useridto' => $useridto)
1687 $context = context_system::instance();
1688 self::validate_context($context);
1690 $useridto = $params['useridto'];
1692 if (!empty($useridto)) {
1693 if (core_user::is_real_user($useridto)) {
1694 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1695 } else {
1696 throw new moodle_exception('invaliduser');
1698 } else {
1699 $useridto = $USER->id;
1702 // Check if the current user is the receiver or just a privileged user.
1703 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1704 throw new moodle_exception('accessdenied', 'admin');
1707 return \core_message\api::count_unread_conversations($userto);
1711 * Get unread conversations count return description.
1713 * @return external_single_structure
1714 * @since 3.2
1716 public static function get_unread_conversations_count_returns() {
1717 return new external_value(PARAM_INT, 'The count of unread messages for the user');
1721 * Get blocked users parameters description.
1723 * @return external_function_parameters
1724 * @since 2.9
1726 public static function get_blocked_users_parameters() {
1727 return new external_function_parameters(
1728 array(
1729 'userid' => new external_value(PARAM_INT,
1730 'the user whose blocked users we want to retrieve',
1731 VALUE_REQUIRED),
1737 * Retrieve a list of users blocked
1739 * @param int $userid the user whose blocked users we want to retrieve
1740 * @return external_description
1741 * @since 2.9
1743 public static function get_blocked_users($userid) {
1744 global $CFG, $USER, $PAGE;
1746 // Warnings array, it can be empty at the end but is mandatory.
1747 $warnings = array();
1749 // Validate params.
1750 $params = array(
1751 'userid' => $userid
1753 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
1754 $userid = $params['userid'];
1756 // Validate context.
1757 $context = context_system::instance();
1758 self::validate_context($context);
1760 // Check if private messaging between users is allowed.
1761 if (empty($CFG->messaging)) {
1762 throw new moodle_exception('disabled', 'message');
1765 $user = core_user::get_user($userid, '*', MUST_EXIST);
1766 core_user::require_active_user($user);
1768 // Check if we have permissions for retrieve the information.
1769 $capability = 'moodle/site:manageallmessaging';
1770 if (($USER->id != $userid) && !has_capability($capability, $context)) {
1771 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1774 // Now, we can get safely all the blocked users.
1775 $users = message_get_blocked_users($user);
1777 $blockedusers = array();
1778 foreach ($users as $user) {
1779 $newuser = array(
1780 'id' => $user->id,
1781 'fullname' => fullname($user),
1784 $userpicture = new user_picture($user);
1785 $userpicture->size = 1; // Size f1.
1786 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1788 $blockedusers[] = $newuser;
1791 $results = array(
1792 'users' => $blockedusers,
1793 'warnings' => $warnings
1795 return $results;
1799 * Get blocked users return description.
1801 * @return external_single_structure
1802 * @since 2.9
1804 public static function get_blocked_users_returns() {
1805 return new external_single_structure(
1806 array(
1807 'users' => new external_multiple_structure(
1808 new external_single_structure(
1809 array(
1810 'id' => new external_value(PARAM_INT, 'User ID'),
1811 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1812 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
1815 'List of blocked users'
1817 'warnings' => new external_warnings()
1823 * Returns description of method parameters
1825 * @return external_function_parameters
1826 * @since 2.9
1828 public static function mark_message_read_parameters() {
1829 return new external_function_parameters(
1830 array(
1831 'messageid' => new external_value(PARAM_INT, 'id of the message (in the message table)'),
1832 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
1833 VALUE_DEFAULT, 0)
1839 * Mark a single message as read, trigger message_viewed event
1841 * @param int $messageid id of the message (in the message table)
1842 * @param int $timeread timestamp for when the message should be marked read
1843 * @return external_description
1844 * @throws invalid_parameter_exception
1845 * @throws moodle_exception
1846 * @since 2.9
1848 public static function mark_message_read($messageid, $timeread) {
1849 global $CFG, $DB, $USER;
1851 // Check if private messaging between users is allowed.
1852 if (empty($CFG->messaging)) {
1853 throw new moodle_exception('disabled', 'message');
1856 // Warnings array, it can be empty at the end but is mandatory.
1857 $warnings = array();
1859 // Validate params.
1860 $params = array(
1861 'messageid' => $messageid,
1862 'timeread' => $timeread
1864 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
1866 if (empty($params['timeread'])) {
1867 $timeread = time();
1868 } else {
1869 $timeread = $params['timeread'];
1872 // Validate context.
1873 $context = context_system::instance();
1874 self::validate_context($context);
1876 $message = $DB->get_record('message', array('id' => $params['messageid']), '*', MUST_EXIST);
1878 if ($message->useridto != $USER->id) {
1879 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
1882 $messageid = message_mark_message_read($message, $timeread);
1884 $results = array(
1885 'messageid' => $messageid,
1886 'warnings' => $warnings
1888 return $results;
1892 * Returns description of method result value
1894 * @return external_description
1895 * @since 2.9
1897 public static function mark_message_read_returns() {
1898 return new external_single_structure(
1899 array(
1900 'messageid' => new external_value(PARAM_INT, 'the id of the message in the message_read table'),
1901 'warnings' => new external_warnings()
1907 * Mark all messages as read parameters description.
1909 * @return external_function_parameters
1910 * @since 3.2
1912 public static function mark_all_messages_as_read_parameters() {
1913 return new external_function_parameters(
1914 array(
1915 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1916 'useridfrom' => new external_value(
1917 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1918 VALUE_DEFAULT, 0),
1924 * Mark all notifications as read function.
1926 * @since 3.2
1927 * @throws invalid_parameter_exception
1928 * @throws moodle_exception
1929 * @param int $useridto the user id who received the message
1930 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1931 * @return external_description
1933 public static function mark_all_messages_as_read($useridto, $useridfrom) {
1934 global $USER, $CFG;
1936 // Check if messaging is enabled.
1937 if (empty($CFG->messaging)) {
1938 throw new moodle_exception('disabled', 'message');
1941 $params = self::validate_parameters(
1942 self::mark_all_messages_as_read_parameters(),
1943 array(
1944 'useridto' => $useridto,
1945 'useridfrom' => $useridfrom,
1949 $context = context_system::instance();
1950 self::validate_context($context);
1952 $useridto = $params['useridto'];
1953 $useridfrom = $params['useridfrom'];
1955 if (!empty($useridto)) {
1956 if (core_user::is_real_user($useridto)) {
1957 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1958 } else {
1959 throw new moodle_exception('invaliduser');
1963 if (!empty($useridfrom)) {
1964 // We use get_user here because the from user can be the noreply or support user.
1965 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1968 // Check if the current user is the sender/receiver or just a privileged user.
1969 if ($useridto != $USER->id and $useridfrom != $USER->id and
1970 // The deleteanymessage cap seems more reasonable here than readallmessages.
1971 !has_capability('moodle/site:deleteanymessage', $context)) {
1972 throw new moodle_exception('accessdenied', 'admin');
1975 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_MESSAGE);
1977 return true;
1981 * Mark all notifications as read return description.
1983 * @return external_single_structure
1984 * @since 3.2
1986 public static function mark_all_messages_as_read_returns() {
1987 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
1991 * Returns description of method parameters.
1993 * @return external_function_parameters
1994 * @since 3.2
1996 public static function delete_conversation_parameters() {
1997 return new external_function_parameters(
1998 array(
1999 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
2000 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
2006 * Deletes a conversation.
2008 * @param int $userid The user id of who we want to delete the conversation for
2009 * @param int $otheruserid The user id of the other user in the conversation
2010 * @return array
2011 * @throws moodle_exception
2012 * @since 3.2
2014 public static function delete_conversation($userid, $otheruserid) {
2015 global $CFG;
2017 // Check if private messaging between users is allowed.
2018 if (empty($CFG->messaging)) {
2019 throw new moodle_exception('disabled', 'message');
2022 // Warnings array, it can be empty at the end but is mandatory.
2023 $warnings = array();
2025 // Validate params.
2026 $params = array(
2027 'userid' => $userid,
2028 'otheruserid' => $otheruserid,
2030 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
2032 // Validate context.
2033 $context = context_system::instance();
2034 self::validate_context($context);
2036 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2037 core_user::require_active_user($user);
2039 if (\core_message\api::can_delete_conversation($user->id)) {
2040 $status = \core_message\api::delete_conversation($user->id, $otheruserid);
2041 } else {
2042 throw new moodle_exception('You do not have permission to delete messages');
2045 $results = array(
2046 'status' => $status,
2047 'warnings' => $warnings
2050 return $results;
2054 * Returns description of method result value.
2056 * @return external_description
2057 * @since 3.2
2059 public static function delete_conversation_returns() {
2060 return new external_single_structure(
2061 array(
2062 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
2063 'warnings' => new external_warnings()
2069 * Returns description of method parameters
2071 * @return external_function_parameters
2072 * @since 3.1
2074 public static function delete_message_parameters() {
2075 return new external_function_parameters(
2076 array(
2077 'messageid' => new external_value(PARAM_INT, 'The message id'),
2078 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
2079 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
2085 * Deletes a message
2087 * @param int $messageid the message id
2088 * @param int $userid the user id of who we want to delete the message for
2089 * @param bool $read if is a message read (default to true)
2090 * @return external_description
2091 * @throws moodle_exception
2092 * @since 3.1
2094 public static function delete_message($messageid, $userid, $read = true) {
2095 global $CFG, $DB;
2097 // Check if private messaging between users is allowed.
2098 if (empty($CFG->messaging)) {
2099 throw new moodle_exception('disabled', 'message');
2102 // Warnings array, it can be empty at the end but is mandatory.
2103 $warnings = array();
2105 // Validate params.
2106 $params = array(
2107 'messageid' => $messageid,
2108 'userid' => $userid,
2109 'read' => $read
2111 $params = self::validate_parameters(self::delete_message_parameters(), $params);
2113 // Validate context.
2114 $context = context_system::instance();
2115 self::validate_context($context);
2117 $messagestable = $params['read'] ? 'message_read' : 'message';
2118 $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
2120 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2121 core_user::require_active_user($user);
2123 $status = false;
2124 if (message_can_delete_message($message, $user->id)) {
2125 $status = message_delete_message($message, $user->id);;
2126 } else {
2127 throw new moodle_exception('You do not have permission to delete this message');
2130 $results = array(
2131 'status' => $status,
2132 'warnings' => $warnings
2134 return $results;
2138 * Returns description of method result value
2140 * @return external_description
2141 * @since 3.1
2143 public static function delete_message_returns() {
2144 return new external_single_structure(
2145 array(
2146 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
2147 'warnings' => new external_warnings()
2153 * Returns description of method parameters
2155 * @return external_function_parameters
2156 * @since 3.2
2158 public static function message_processor_config_form_parameters() {
2159 return new external_function_parameters(
2160 array(
2161 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
2162 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
2163 'formvalues' => new external_multiple_structure(
2164 new external_single_structure(
2165 array(
2166 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
2167 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
2170 'Config form values',
2171 VALUE_REQUIRED
2178 * Processes a message processor config form.
2180 * @param int $userid the user id
2181 * @param string $name the name of the processor
2182 * @param array $formvalues the form values
2183 * @return external_description
2184 * @throws moodle_exception
2185 * @since 3.2
2187 public static function message_processor_config_form($userid, $name, $formvalues) {
2188 global $USER, $CFG;
2190 // Check if messaging is enabled.
2191 if (empty($CFG->messaging)) {
2192 throw new moodle_exception('disabled', 'message');
2195 $params = self::validate_parameters(
2196 self::message_processor_config_form_parameters(),
2197 array(
2198 'userid' => $userid,
2199 'name' => $name,
2200 'formvalues' => $formvalues,
2204 $user = self::validate_preferences_permissions($params['userid']);
2206 $processor = get_message_processor($name);
2207 $preferences = [];
2208 $form = new stdClass();
2210 foreach ($formvalues as $formvalue) {
2211 // Curly braces to ensure interpretation is consistent between
2212 // php 5 and php 7.
2213 $form->{$formvalue['name']} = $formvalue['value'];
2216 $processor->process_form($form, $preferences);
2218 if (!empty($preferences)) {
2219 set_user_preferences($preferences, $userid);
2224 * Returns description of method result value
2226 * @return external_description
2227 * @since 3.2
2229 public static function message_processor_config_form_returns() {
2230 return null;
2234 * Returns description of method parameters
2236 * @return external_function_parameters
2237 * @since 3.2
2239 public static function get_message_processor_parameters() {
2240 return new external_function_parameters(
2241 array(
2242 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
2243 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
2249 * Get a message processor.
2251 * @param int $userid
2252 * @param string $name the name of the processor
2253 * @return external_description
2254 * @throws moodle_exception
2255 * @since 3.2
2257 public static function get_message_processor($userid = 0, $name) {
2258 global $USER, $PAGE, $CFG;
2260 // Check if messaging is enabled.
2261 if (empty($CFG->messaging)) {
2262 throw new moodle_exception('disabled', 'message');
2265 $params = self::validate_parameters(
2266 self::get_message_processor_parameters(),
2267 array(
2268 'userid' => $userid,
2269 'name' => $name,
2273 if (empty($params['userid'])) {
2274 $params['userid'] = $USER->id;
2277 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2278 core_user::require_active_user($user);
2279 self::validate_context(context_user::instance($params['userid']));
2281 $processor = get_message_processor($name);
2283 $processoroutput = new \core_message\output\processor($processor, $user);
2284 $renderer = $PAGE->get_renderer('core_message');
2286 return $processoroutput->export_for_template($renderer);
2290 * Returns description of method result value
2292 * @return external_description
2293 * @since 3.2
2295 public static function get_message_processor_returns() {
2296 return new external_function_parameters(
2297 array(
2298 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
2299 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
2305 * Check that the user has enough permission to retrieve message or notifications preferences.
2307 * @param int $userid the user id requesting the preferences
2308 * @return stdClass full user object
2309 * @throws moodle_exception
2310 * @since Moodle 3.2
2312 protected static function validate_preferences_permissions($userid) {
2313 global $USER;
2315 if (empty($userid)) {
2316 $user = $USER;
2317 } else {
2318 $user = core_user::get_user($userid, '*', MUST_EXIST);
2319 core_user::require_active_user($user);
2322 $systemcontext = context_system::instance();
2323 self::validate_context($systemcontext);
2325 // Check access control.
2326 if ($user->id == $USER->id) {
2327 // Editing own message profile.
2328 require_capability('moodle/user:editownmessageprofile', $systemcontext);
2329 } else {
2330 // Teachers, parents, etc.
2331 $personalcontext = context_user::instance($user->id);
2332 require_capability('moodle/user:editmessageprofile', $personalcontext);
2334 return $user;
2338 * Returns a notification or message preference structure.
2340 * @return external_single_structure the structure
2341 * @since Moodle 3.2
2343 protected static function get_preferences_structure() {
2344 return new external_single_structure(
2345 array(
2346 'userid' => new external_value(PARAM_INT, 'User id'),
2347 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
2348 'processors' => new external_multiple_structure(
2349 new external_single_structure(
2350 array(
2351 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2352 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2353 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
2354 'contextid' => new external_value(PARAM_INT, 'Context id'),
2355 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
2358 'Config form values'
2360 'components' => new external_multiple_structure(
2361 new external_single_structure(
2362 array(
2363 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2364 'notifications' => new external_multiple_structure(
2365 new external_single_structure(
2366 array(
2367 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2368 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
2369 'processors' => new external_multiple_structure(
2370 new external_single_structure(
2371 array(
2372 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2373 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2374 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
2375 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
2376 'loggedin' => new external_single_structure(
2377 array(
2378 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2379 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2380 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2383 'loggedoff' => new external_single_structure(
2384 array(
2385 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2386 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2387 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2392 'Processors values for this notification'
2396 'List of notificaitons for the component'
2400 'Available components'
2407 * Returns description of method parameters
2409 * @return external_function_parameters
2410 * @since 3.2
2412 public static function get_user_notification_preferences_parameters() {
2413 return new external_function_parameters(
2414 array(
2415 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
2421 * Get the notification preferences for a given user.
2423 * @param int $userid id of the user, 0 for current user
2424 * @return external_description
2425 * @throws moodle_exception
2426 * @since 3.2
2428 public static function get_user_notification_preferences($userid = 0) {
2429 global $PAGE;
2431 $params = self::validate_parameters(
2432 self::get_user_notification_preferences_parameters(),
2433 array(
2434 'userid' => $userid,
2437 $user = self::validate_preferences_permissions($params['userid']);
2439 $processors = get_message_processors();
2440 $providers = message_get_providers_for_user($user->id);
2441 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2442 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
2444 $renderer = $PAGE->get_renderer('core_message');
2446 $result = array(
2447 'warnings' => array(),
2448 'preferences' => $notificationlist->export_for_template($renderer)
2450 return $result;
2454 * Returns description of method result value
2456 * @return external_description
2457 * @since 3.2
2459 public static function get_user_notification_preferences_returns() {
2460 return new external_function_parameters(
2461 array(
2462 'preferences' => self::get_preferences_structure(),
2463 'warnings' => new external_warnings(),
2470 * Returns description of method parameters
2472 * @return external_function_parameters
2473 * @since 3.2
2475 public static function get_user_message_preferences_parameters() {
2476 return new external_function_parameters(
2477 array(
2478 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
2484 * Get the notification preferences for a given user.
2486 * @param int $userid id of the user, 0 for current user
2487 * @return external_description
2488 * @throws moodle_exception
2489 * @since 3.2
2491 public static function get_user_message_preferences($userid = 0) {
2492 global $PAGE;
2494 $params = self::validate_parameters(
2495 self::get_user_message_preferences_parameters(),
2496 array(
2497 'userid' => $userid,
2501 $user = self::validate_preferences_permissions($params['userid']);
2503 // Filter out enabled, available system_configured and user_configured processors only.
2504 $readyprocessors = array_filter(get_message_processors(), function($processor) {
2505 return $processor->enabled &&
2506 $processor->configured &&
2507 $processor->object->is_user_configured() &&
2508 // Filter out processors that don't have and message preferences to configure.
2509 $processor->object->has_message_preferences();
2512 $providers = array_filter(message_get_providers_for_user($user->id), function($provider) {
2513 return $provider->component === 'moodle';
2515 $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user);
2516 $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors,
2517 $providers, $preferences, $user);
2519 $renderer = $PAGE->get_renderer('core_message');
2521 $result = array(
2522 'warnings' => array(),
2523 'preferences' => $notificationlistoutput->export_for_template($renderer),
2524 'blocknoncontacts' => get_user_preferences('message_blocknoncontacts', '', $user->id) ? true : false,
2526 return $result;
2530 * Returns description of method result value
2532 * @return external_description
2533 * @since 3.2
2535 public static function get_user_message_preferences_returns() {
2536 return new external_function_parameters(
2537 array(
2538 'preferences' => self::get_preferences_structure(),
2539 'blocknoncontacts' => new external_value(PARAM_BOOL, 'Whether to block or not messages from non contacts'),
2540 'warnings' => new external_warnings(),