2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
19 * External message API
21 * @package core_message
23 * @copyright 2011 Jerome Mouneyrac
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
29 require_once("$CFG->libdir/externallib.php");
30 require_once($CFG->dirroot . "/message/lib.php");
33 * Message external functions
35 * @package core_message
37 * @copyright 2011 Jerome Mouneyrac
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 class core_message_external extends external_api {
44 * Returns description of method parameters
46 * @return external_function_parameters
49 public static function send_instant_messages_parameters() {
50 return new external_function_parameters(
52 'messages' => new external_multiple_structure(
53 new external_single_structure(
55 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'),
56 'text' => new external_value(PARAM_RAW, 'the text of the message'),
57 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
58 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the message. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL),
67 * Send private messages from the current USER to other users
69 * @param array $messages An array of message to send.
73 public static function send_instant_messages($messages = array()) {
74 global $CFG, $USER, $DB;
76 // Check if messaging is enabled.
77 if (empty($CFG->messaging)) {
78 throw new moodle_exception('disabled', 'message');
81 // Ensure the current user is allowed to run this function
82 $context = context_system::instance();
83 self::validate_context($context);
84 require_capability('moodle/site:sendmessage', $context);
86 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
88 //retrieve all tousers of the messages
90 foreach($params['messages'] as $message) {
91 $receivers[] = $message['touserid'];
93 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
94 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
96 $contactlist = array();
97 $contactsqlparams = array_merge($sqlparams, [$USER->id], [$USER->id], $sqlparams);
98 $rs = $DB->get_recordset_sql("SELECT *
99 FROM {message_contacts}
100 WHERE (userid $sqluserids AND contactid = ?)
101 OR (userid = ? AND contactid $sqluserids)", $contactsqlparams);
102 foreach ($rs as $record) {
103 $useridtouse = $record->userid;
104 if ($record->userid == $USER->id) {
105 $useridtouse = $record->contactid;
107 $contactlist[$useridtouse] = true;
110 $blocksqlparams = array_merge($sqlparams, [$USER->id]);
111 $rs = $DB->get_recordset_sql("SELECT *
112 FROM {message_users_blocked}
113 WHERE userid $sqluserids
114 AND blockeduserid = ?", $blocksqlparams);
115 foreach ($rs as $record) {
116 $blocklist[$record->userid] = true;
120 $canreadallmessages = has_capability('moodle/site:readallmessages', $context);
122 $resultmessages = array();
123 foreach ($params['messages'] as $message) {
124 $resultmsg = array(); //the infos about the success of the operation
126 //we are going to do some checking
127 //code should match /messages/index.php checks
130 //check the user exists
131 if (empty($tousers[$message['touserid']])) {
133 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
136 //check that the touser is not blocking the current user
137 if ($success and !empty($blocklist[$message['touserid']]) and !$canreadallmessages) {
139 $errormessage = get_string('userisblockingyou', 'message');
142 // Check if the user is a contact
143 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
144 $blocknoncontacts = get_user_preferences('message_blocknoncontacts', NULL, $message['touserid']);
145 // message_blocknoncontacts option is on and current user is not in contact list
146 if ($success && empty($contactlist[$message['touserid']]) && !empty($blocknoncontacts)) {
147 // The user isn't a contact and they have selected to block non contacts so this message won't be sent.
149 $errormessage = get_string('userisblockingyounoncontact', 'message',
150 fullname(core_user::get_user($message['touserid'])));
153 //now we can send the message (at least try)
155 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object
156 $success = message_post_message($USER, $tousers[$message['touserid']],
157 $message['text'], external_validate_format($message['textformat']));
160 //build the resultmsg
161 if (isset($message['clientmsgid'])) {
162 $resultmsg['clientmsgid'] = $message['clientmsgid'];
165 $resultmsg['msgid'] = $success;
167 // WARNINGS: for backward compatibility we return this errormessage.
168 // We should have thrown exceptions as these errors prevent results to be returned.
169 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
170 $resultmsg['msgid'] = -1;
171 $resultmsg['errormessage'] = $errormessage;
174 $resultmessages[] = $resultmsg;
177 return $resultmessages;
181 * Returns description of method result value
183 * @return external_description
186 public static function send_instant_messages_returns() {
187 return new external_multiple_structure(
188 new external_single_structure(
190 'msgid' => new external_value(PARAM_INT, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
191 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
192 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL)
199 * Create contacts parameters description.
201 * @deprecated since Moodle 3.6
202 * @return external_function_parameters
205 public static function create_contacts_parameters() {
206 return new external_function_parameters(
208 'userids' => new external_multiple_structure(
209 new external_value(PARAM_INT, 'User ID'),
212 'userid' => new external_value(PARAM_INT, 'The id of the user we are creating the contacts for, 0 for the
213 current user', VALUE_DEFAULT, 0)
221 * @deprecated since Moodle 3.6
222 * @param array $userids array of user IDs.
223 * @param int $userid The id of the user we are creating the contacts for
224 * @return external_description
227 public static function create_contacts($userids, $userid = 0) {
230 // Check if messaging is enabled.
231 if (empty($CFG->messaging)) {
232 throw new moodle_exception('disabled', 'message');
235 if (empty($userid)) {
240 $context = context_system::instance();
241 self::validate_context($context);
243 $capability = 'moodle/site:manageallmessaging';
244 if (($USER->id != $userid) && !has_capability($capability, $context)) {
245 throw new required_capability_exception($context, $capability, 'nopermissions', '');
248 $params = array('userids' => $userids, 'userid' => $userid);
249 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
252 foreach ($params['userids'] as $id) {
253 if (!message_add_contact($id, 0, $userid)) {
257 'warningcode' => 'contactnotcreated',
258 'message' => 'The contact could not be created'
266 * Create contacts return description.
268 * @deprecated since Moodle 3.6
269 * @return external_description
272 public static function create_contacts_returns() {
273 return new external_warnings();
277 * Marking the method as deprecated.
281 public static function create_contacts_is_deprecated() {
286 * Delete contacts parameters description.
288 * @return external_function_parameters
291 public static function delete_contacts_parameters() {
292 return new external_function_parameters(
294 'userids' => new external_multiple_structure(
295 new external_value(PARAM_INT, 'User ID'),
298 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the
299 current user', VALUE_DEFAULT, 0)
307 * @param array $userids array of user IDs.
308 * @param int $userid The id of the user we are deleting the contacts for
312 public static function delete_contacts($userids, $userid = 0) {
315 // Check if messaging is enabled.
316 if (empty($CFG->messaging)) {
317 throw new moodle_exception('disabled', 'message');
320 if (empty($userid)) {
325 $context = context_system::instance();
326 self::validate_context($context);
328 $capability = 'moodle/site:manageallmessaging';
329 if (($USER->id != $userid) && !has_capability($capability, $context)) {
330 throw new required_capability_exception($context, $capability, 'nopermissions', '');
333 $params = array('userids' => $userids, 'userid' => $userid);
334 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
336 foreach ($params['userids'] as $id) {
337 \core_message\api::remove_contact($userid, $id);
344 * Delete contacts return description.
346 * @return external_description
349 public static function delete_contacts_returns() {
354 * Block user parameters description.
356 * @return external_function_parameters
358 public static function block_user_parameters() {
359 return new external_function_parameters(
361 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
362 'blockeduserid' => new external_value(PARAM_INT, 'The id of the user being blocked'),
370 * @param int $userid The id of the user who is blocking
371 * @param int $blockeduserid The id of the user being blocked
372 * @return external_description
374 public static function block_user(int $userid, int $blockeduserid) {
377 // Check if messaging is enabled.
378 if (empty($CFG->messaging)) {
379 throw new moodle_exception('disabled', 'message');
383 $context = context_system::instance();
384 self::validate_context($context);
386 $capability = 'moodle/site:manageallmessaging';
387 if (($USER->id != $userid) && !has_capability($capability, $context)) {
388 throw new required_capability_exception($context, $capability, 'nopermissions', '');
391 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
392 $params = self::validate_parameters(self::block_user_parameters(), $params);
394 if (!\core_message\api::is_blocked($params['userid'], $params['blockeduserid'])) {
395 \core_message\api::block_user($params['userid'], $params['blockeduserid']);
402 * Block user return description.
404 * @return external_description
406 public static function block_user_returns() {
407 return new external_warnings();
411 * Unblock user parameters description.
413 * @return external_function_parameters
415 public static function unblock_user_parameters() {
416 return new external_function_parameters(
418 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
419 'unblockeduserid' => new external_value(PARAM_INT, 'The id of the user being unblocked'),
427 * @param int $userid The id of the user who is unblocking
428 * @param int $unblockeduserid The id of the user being unblocked
430 public static function unblock_user(int $userid, int $unblockeduserid) {
433 // Check if messaging is enabled.
434 if (empty($CFG->messaging)) {
435 throw new moodle_exception('disabled', 'message');
439 $context = context_system::instance();
440 self::validate_context($context);
442 $capability = 'moodle/site:manageallmessaging';
443 if (($USER->id != $userid) && !has_capability($capability, $context)) {
444 throw new required_capability_exception($context, $capability, 'nopermissions', '');
447 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
448 $params = self::validate_parameters(self::unblock_user_parameters(), $params);
450 \core_message\api::unblock_user($params['userid'], $params['unblockeduserid']);
456 * Unblock user return description.
458 * @return external_description
460 public static function unblock_user_returns() {
461 return new external_warnings();
465 * Block contacts parameters description.
467 * @deprecated since Moodle 3.6
468 * @return external_function_parameters
471 public static function block_contacts_parameters() {
472 return new external_function_parameters(
474 'userids' => new external_multiple_structure(
475 new external_value(PARAM_INT, 'User ID'),
478 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the
479 current user', VALUE_DEFAULT, 0)
487 * @deprecated since Moodle 3.6
488 * @param array $userids array of user IDs.
489 * @param int $userid The id of the user we are blocking the contacts for
490 * @return external_description
493 public static function block_contacts($userids, $userid = 0) {
496 // Check if messaging is enabled.
497 if (empty($CFG->messaging)) {
498 throw new moodle_exception('disabled', 'message');
501 if (empty($userid)) {
506 $context = context_system::instance();
507 self::validate_context($context);
509 $capability = 'moodle/site:manageallmessaging';
510 if (($USER->id != $userid) && !has_capability($capability, $context)) {
511 throw new required_capability_exception($context, $capability, 'nopermissions', '');
514 $params = array('userids' => $userids, 'userid' => $userid);
515 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
518 foreach ($params['userids'] as $id) {
519 if (!message_block_contact($id, $userid)) {
523 'warningcode' => 'contactnotblocked',
524 'message' => 'The contact could not be blocked'
532 * Block contacts return description.
534 * @deprecated since Moodle 3.6
535 * @return external_description
538 public static function block_contacts_returns() {
539 return new external_warnings();
543 * Marking the method as deprecated.
547 public static function block_contacts_is_deprecated() {
552 * Unblock contacts parameters description.
554 * @deprecated since Moodle 3.6
555 * @return external_function_parameters
558 public static function unblock_contacts_parameters() {
559 return new external_function_parameters(
561 'userids' => new external_multiple_structure(
562 new external_value(PARAM_INT, 'User ID'),
565 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the
566 current user', VALUE_DEFAULT, 0)
574 * @deprecated since Moodle 3.6
575 * @param array $userids array of user IDs.
576 * @param int $userid The id of the user we are unblocking the contacts for
580 public static function unblock_contacts($userids, $userid = 0) {
583 // Check if messaging is enabled.
584 if (empty($CFG->messaging)) {
585 throw new moodle_exception('disabled', 'message');
588 if (empty($userid)) {
593 $context = context_system::instance();
594 self::validate_context($context);
596 $capability = 'moodle/site:manageallmessaging';
597 if (($USER->id != $userid) && !has_capability($capability, $context)) {
598 throw new required_capability_exception($context, $capability, 'nopermissions', '');
601 $params = array('userids' => $userids, 'userid' => $userid);
602 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
604 foreach ($params['userids'] as $id) {
605 message_unblock_contact($id, $userid);
612 * Unblock contacts return description.
614 * @deprecated since Moodle 3.6
615 * @return external_description
618 public static function unblock_contacts_returns() {
623 * Marking the method as deprecated.
627 public static function unblock_contacts_is_deprecated() {
632 * Returns contact requests parameters description.
634 * @return external_function_parameters
636 public static function get_contact_requests_parameters() {
637 return new external_function_parameters(
639 'userid' => new external_value(PARAM_INT, 'The id of the user we want the requests for')
645 * Handles returning the contact requests for a user.
647 * This also includes the user data necessary to display information
650 * It will not include blocked users.
652 * @param int $userid The id of the user we want to get the contact requests for
654 public static function get_contact_requests(int $userid) {
657 // Check if messaging is enabled.
658 if (empty($CFG->messaging)) {
659 throw new moodle_exception('disabled', 'message');
663 $context = context_system::instance();
664 self::validate_context($context);
666 $capability = 'moodle/site:manageallmessaging';
667 if (($USER->id != $userid) && !has_capability($capability, $context)) {
668 throw new required_capability_exception($context, $capability, 'nopermissions', '');
671 $params = ['userid' => $userid];
672 $params = self::validate_parameters(self::get_contact_requests_parameters(), $params);
674 return \core_message\api::get_contact_requests($params['userid']);
678 * Returns the contact requests return description.
680 * @return external_description
682 public static function get_contact_requests_returns() {
683 return new external_multiple_structure(
684 new external_single_structure(
686 'id' => new external_value(core_user::get_property_type('id'), 'ID of the user'),
687 'contactrequestid' => new external_value(PARAM_INT, 'The ID of the contact request'),
688 'picture' => new external_value(core_user::get_property_type('picture'), 'The picture'),
689 'firstname' => new external_value(core_user::get_property_type('firstname'),
690 'The first name(s) of the user'),
691 'lastname' => new external_value(core_user::get_property_type('lastname'),
692 'The family name of the user'),
693 'firstnamephonetic' => new external_value(core_user::get_property_type('firstnamephonetic'),
694 'The phonetic first name of the user'),
695 'lastnamephonetic' => new external_value(core_user::get_property_type('lastnamephonetic'),
696 'The phonetic last name of the user'),
697 'middlename' => new external_value(core_user::get_property_type('middlename'),
698 'The middle name of the user'),
699 'alternatename' => new external_value(core_user::get_property_type('alternatename'),
700 'The alternate name of the user'),
701 'email' => new external_value(core_user::get_property_type('email'), 'An email address')
708 * Creates a contact request parameters description.
710 * @return external_function_parameters
712 public static function create_contact_request_parameters() {
713 return new external_function_parameters(
715 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
716 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
722 * Creates a contact request.
724 * @param int $userid The id of the user who is creating the contact request
725 * @param int $requesteduserid The id of the user being requested
727 public static function create_contact_request(int $userid, int $requesteduserid) {
730 // Check if messaging is enabled.
731 if (empty($CFG->messaging)) {
732 throw new moodle_exception('disabled', 'message');
736 $context = context_system::instance();
737 self::validate_context($context);
739 $capability = 'moodle/site:manageallmessaging';
740 if (($USER->id != $userid) && !has_capability($capability, $context)) {
741 throw new required_capability_exception($context, $capability, 'nopermissions', '');
744 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
745 $params = self::validate_parameters(self::create_contact_request_parameters(), $params);
747 if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) {
750 'itemid' => $params['requesteduserid'],
751 'warningcode' => 'cannotcreatecontactrequest',
752 'message' => 'You are unable to create a contact request for this user'
757 if (!\core_message\api::does_contact_request_exist($params['userid'], $params['requesteduserid'])) {
758 \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']);
765 * Creates a contact request return description.
767 * @return external_description
769 public static function create_contact_request_returns() {
770 return new external_warnings();
774 * Confirm a contact request parameters description.
776 * @return external_function_parameters
778 public static function confirm_contact_request_parameters() {
779 return new external_function_parameters(
781 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
782 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
788 * Confirm a contact request.
790 * @param int $userid The id of the user who is creating the contact request
791 * @param int $requesteduserid The id of the user being requested
793 public static function confirm_contact_request(int $userid, int $requesteduserid) {
796 // Check if messaging is enabled.
797 if (empty($CFG->messaging)) {
798 throw new moodle_exception('disabled', 'message');
802 $context = context_system::instance();
803 self::validate_context($context);
805 $capability = 'moodle/site:manageallmessaging';
806 if (($USER->id != $requesteduserid) && !has_capability($capability, $context)) {
807 throw new required_capability_exception($context, $capability, 'nopermissions', '');
810 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
811 $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params);
813 \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']);
819 * Confirm a contact request return description.
821 * @return external_description
823 public static function confirm_contact_request_returns() {
824 return new external_warnings();
828 * Declines a contact request parameters description.
830 * @return external_function_parameters
832 public static function decline_contact_request_parameters() {
833 return new external_function_parameters(
835 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
836 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
842 * Declines a contact request.
844 * @param int $userid The id of the user who is creating the contact request
845 * @param int $requesteduserid The id of the user being requested
847 public static function decline_contact_request(int $userid, int $requesteduserid) {
850 // Check if messaging is enabled.
851 if (empty($CFG->messaging)) {
852 throw new moodle_exception('disabled', 'message');
856 $context = context_system::instance();
857 self::validate_context($context);
859 $capability = 'moodle/site:manageallmessaging';
860 if (($USER->id != $requesteduserid) && !has_capability($capability, $context)) {
861 throw new required_capability_exception($context, $capability, 'nopermissions', '');
864 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
865 $params = self::validate_parameters(self::decline_contact_request_parameters(), $params);
867 \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']);
873 * Declines a contact request return description.
875 * @return external_description
877 public static function decline_contact_request_returns() {
878 return new external_warnings();
882 * Return the structure of a message area contact.
884 * @return external_single_structure
887 private static function get_messagearea_contact_structure() {
888 return new external_single_structure(
890 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
891 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
892 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
893 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
894 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
895 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
896 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
897 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
898 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
899 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
900 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
901 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
902 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
903 VALUE_DEFAULT, null),
909 * Return the structure of a message area message.
911 * @return external_single_structure
914 private static function get_messagearea_message_structure() {
915 return new external_single_structure(
917 'id' => new external_value(PARAM_INT, 'The id of the message'),
918 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
919 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
920 'text' => new external_value(PARAM_RAW, 'The text of the message'),
921 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
922 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
923 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
924 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
925 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
926 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
932 * Get messagearea search users in course parameters.
934 * @return external_function_parameters
937 public static function data_for_messagearea_search_users_in_course_parameters() {
938 return new external_function_parameters(
940 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
941 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
942 'search' => new external_value(PARAM_RAW, 'The string being searched'),
943 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
944 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
950 * Get messagearea search users in course results.
952 * @param int $userid The id of the user who is performing the search
953 * @param int $courseid The id of the course
954 * @param string $search The string being searched
955 * @param int $limitfrom
956 * @param int $limitnum
958 * @throws moodle_exception
961 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
963 global $CFG, $PAGE, $USER;
965 // Check if messaging is enabled.
966 if (empty($CFG->messaging)) {
967 throw new moodle_exception('disabled', 'message');
970 $systemcontext = context_system::instance();
974 'courseid' => $courseid,
976 'limitfrom' => $limitfrom,
977 'limitnum' => $limitnum
979 self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
980 self::validate_context($systemcontext);
982 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
983 throw new moodle_exception('You do not have permission to perform this action.');
986 $users = \core_message\api::search_users_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
987 $results = new \core_message\output\messagearea\user_search_results($users);
989 $renderer = $PAGE->get_renderer('core_message');
990 return $results->export_for_template($renderer);
994 * Get messagearea search users in course returns.
996 * @return external_single_structure
999 public static function data_for_messagearea_search_users_in_course_returns() {
1000 return new external_single_structure(
1002 'contacts' => new external_multiple_structure(
1003 self::get_messagearea_contact_structure()
1010 * Get messagearea search users parameters.
1012 * @return external_function_parameters
1015 public static function data_for_messagearea_search_users_parameters() {
1016 return new external_function_parameters(
1018 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1019 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1020 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1026 * Get messagearea search users results.
1028 * @param int $userid The id of the user who is performing the search
1029 * @param string $search The string being searched
1030 * @param int $limitnum
1032 * @throws moodle_exception
1035 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
1036 global $CFG, $PAGE, $USER;
1038 // Check if messaging is enabled.
1039 if (empty($CFG->messaging)) {
1040 throw new moodle_exception('disabled', 'message');
1043 $systemcontext = context_system::instance();
1046 'userid' => $userid,
1047 'search' => $search,
1048 'limitnum' => $limitnum
1050 self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
1051 self::validate_context($systemcontext);
1053 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1054 throw new moodle_exception('You do not have permission to perform this action.');
1057 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($userid, $search, $limitnum);
1058 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
1060 $renderer = $PAGE->get_renderer('core_message');
1061 return $search->export_for_template($renderer);
1065 * Get messagearea search users returns.
1067 * @return external_single_structure
1070 public static function data_for_messagearea_search_users_returns() {
1071 return new external_single_structure(
1073 'contacts' => new external_multiple_structure(
1074 self::get_messagearea_contact_structure()
1076 'courses' => new external_multiple_structure(
1077 new external_single_structure(
1079 'id' => new external_value(PARAM_INT, 'The course id'),
1080 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
1081 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
1085 'noncontacts' => new external_multiple_structure(
1086 self::get_messagearea_contact_structure()
1093 * Get messagearea search messages parameters.
1095 * @return external_function_parameters
1098 public static function data_for_messagearea_search_messages_parameters() {
1099 return new external_function_parameters(
1101 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1102 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1103 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1104 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1110 * Get messagearea search messages results.
1112 * @param int $userid The id of the user who is performing the search
1113 * @param string $search The string being searched
1114 * @param int $limitfrom
1115 * @param int $limitnum
1117 * @throws moodle_exception
1120 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1121 global $CFG, $PAGE, $USER;
1123 // Check if messaging is enabled.
1124 if (empty($CFG->messaging)) {
1125 throw new moodle_exception('disabled', 'message');
1128 $systemcontext = context_system::instance();
1131 'userid' => $userid,
1132 'search' => $search,
1133 'limitfrom' => $limitfrom,
1134 'limitnum' => $limitnum
1137 self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
1138 self::validate_context($systemcontext);
1140 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1141 throw new moodle_exception('You do not have permission to perform this action.');
1144 $messages = \core_message\api::search_messages($userid, $search, $limitfrom, $limitnum);
1145 $results = new \core_message\output\messagearea\message_search_results($messages);
1147 $renderer = $PAGE->get_renderer('core_message');
1148 return $results->export_for_template($renderer);
1152 * Get messagearea search messages returns.
1154 * @return external_single_structure
1157 public static function data_for_messagearea_search_messages_returns() {
1158 return new external_single_structure(
1160 'contacts' => new external_multiple_structure(
1161 self::get_messagearea_contact_structure()
1168 * The messagearea conversations parameters.
1170 * @return external_function_parameters
1173 public static function data_for_messagearea_conversations_parameters() {
1174 return new external_function_parameters(
1176 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1177 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1178 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1184 * Get messagearea conversations.
1186 * @param int $userid The id of the user who we are viewing conversations for
1187 * @param int $limitfrom
1188 * @param int $limitnum
1190 * @throws moodle_exception
1193 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
1194 global $CFG, $PAGE, $USER;
1196 // Check if messaging is enabled.
1197 if (empty($CFG->messaging)) {
1198 throw new moodle_exception('disabled', 'message');
1201 $systemcontext = context_system::instance();
1204 'userid' => $userid,
1205 'limitfrom' => $limitfrom,
1206 'limitnum' => $limitnum
1208 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
1209 self::validate_context($systemcontext);
1211 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1212 throw new moodle_exception('You do not have permission to perform this action.');
1215 $conversations = \core_message\api::get_conversations($userid, $limitfrom, $limitnum);
1216 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
1218 $renderer = $PAGE->get_renderer('core_message');
1219 return $conversations->export_for_template($renderer);
1223 * The messagearea conversations return structure.
1225 * @return external_single_structure
1228 public static function data_for_messagearea_conversations_returns() {
1229 return new external_single_structure(
1231 'contacts' => new external_multiple_structure(
1232 self::get_messagearea_contact_structure()
1239 * The messagearea contacts return parameters.
1241 * @return external_function_parameters
1244 public static function data_for_messagearea_contacts_parameters() {
1245 return self::data_for_messagearea_conversations_parameters();
1249 * Get messagearea contacts parameters.
1251 * @param int $userid The id of the user who we are viewing conversations for
1252 * @param int $limitfrom
1253 * @param int $limitnum
1255 * @throws moodle_exception
1258 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
1259 global $CFG, $PAGE, $USER;
1261 // Check if messaging is enabled.
1262 if (empty($CFG->messaging)) {
1263 throw new moodle_exception('disabled', 'message');
1266 $systemcontext = context_system::instance();
1269 'userid' => $userid,
1270 'limitfrom' => $limitfrom,
1271 'limitnum' => $limitnum
1273 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
1274 self::validate_context($systemcontext);
1276 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1277 throw new moodle_exception('You do not have permission to perform this action.');
1280 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
1281 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
1283 $renderer = $PAGE->get_renderer('core_message');
1284 return $contacts->export_for_template($renderer);
1288 * The messagearea contacts return structure.
1290 * @return external_single_structure
1293 public static function data_for_messagearea_contacts_returns() {
1294 return self::data_for_messagearea_conversations_returns();
1298 * The messagearea messages parameters.
1300 * @return external_function_parameters
1303 public static function data_for_messagearea_messages_parameters() {
1304 return new external_function_parameters(
1306 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1307 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1308 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1309 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1310 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
1311 'timefrom' => new external_value(PARAM_INT,
1312 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
1318 * Get messagearea messages.
1320 * @param int $currentuserid The current user's id
1321 * @param int $otheruserid The other user's id
1322 * @param int $limitfrom
1323 * @param int $limitnum
1324 * @param boolean $newest
1326 * @throws moodle_exception
1329 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
1330 $newest = false, $timefrom = 0) {
1331 global $CFG, $PAGE, $USER;
1333 // Check if messaging is enabled.
1334 if (empty($CFG->messaging)) {
1335 throw new moodle_exception('disabled', 'message');
1338 $systemcontext = context_system::instance();
1341 'currentuserid' => $currentuserid,
1342 'otheruserid' => $otheruserid,
1343 'limitfrom' => $limitfrom,
1344 'limitnum' => $limitnum,
1345 'newest' => $newest,
1346 'timefrom' => $timefrom,
1348 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
1349 self::validate_context($systemcontext);
1351 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1352 throw new moodle_exception('You do not have permission to perform this action.');
1356 $sort = 'timecreated DESC';
1358 $sort = 'timecreated ASC';
1361 // We need to enforce a one second delay on messages to avoid race conditions of current
1362 // messages still being sent.
1364 // There is a chance that we could request messages before the current time's
1365 // second has elapsed and while other messages are being sent in that same second. In which
1366 // case those messages will be lost.
1368 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
1369 if (!empty($timefrom)) {
1370 $timeto = time() - 1;
1375 // No requesting messages from the current time, as stated above.
1376 if ($timefrom == time()) {
1379 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom,
1380 $limitnum, $sort, $timefrom, $timeto);
1383 $messages = new \core_message\output\messagearea\messages($currentuserid, $otheruserid, $messages);
1385 $renderer = $PAGE->get_renderer('core_message');
1386 return $messages->export_for_template($renderer);
1390 * The messagearea messages return structure.
1392 * @return external_single_structure
1395 public static function data_for_messagearea_messages_returns() {
1396 return new external_single_structure(
1398 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
1399 the messages on behalf of?'),
1400 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1401 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1402 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
1403 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1404 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1405 'messages' => new external_multiple_structure(
1406 self::get_messagearea_message_structure()
1408 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
1414 * The get most recent message return parameters.
1416 * @return external_function_parameters
1419 public static function data_for_messagearea_get_most_recent_message_parameters() {
1420 return new external_function_parameters(
1422 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1423 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
1429 * Get the most recent message in a conversation.
1431 * @param int $currentuserid The current user's id
1432 * @param int $otheruserid The other user's id
1434 * @throws moodle_exception
1437 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
1438 global $CFG, $PAGE, $USER;
1440 // Check if messaging is enabled.
1441 if (empty($CFG->messaging)) {
1442 throw new moodle_exception('disabled', 'message');
1445 $systemcontext = context_system::instance();
1448 'currentuserid' => $currentuserid,
1449 'otheruserid' => $otheruserid
1451 self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
1452 self::validate_context($systemcontext);
1454 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1455 throw new moodle_exception('You do not have permission to perform this action.');
1458 $message = \core_message\api::get_most_recent_message($currentuserid, $otheruserid);
1459 $message = new \core_message\output\messagearea\message($message);
1461 $renderer = $PAGE->get_renderer('core_message');
1462 return $message->export_for_template($renderer);
1466 * The get most recent message return structure.
1468 * @return external_single_structure
1471 public static function data_for_messagearea_get_most_recent_message_returns() {
1472 return self::get_messagearea_message_structure();
1476 * The get profile parameters.
1478 * @return external_function_parameters
1481 public static function data_for_messagearea_get_profile_parameters() {
1482 return new external_function_parameters(
1484 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1485 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
1491 * Get the profile information for a contact.
1493 * @param int $currentuserid The current user's id
1494 * @param int $otheruserid The id of the user whose profile we are viewing
1496 * @throws moodle_exception
1499 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
1500 global $CFG, $PAGE, $USER;
1502 // Check if messaging is enabled.
1503 if (empty($CFG->messaging)) {
1504 throw new moodle_exception('disabled', 'message');
1507 $systemcontext = context_system::instance();
1510 'currentuserid' => $currentuserid,
1511 'otheruserid' => $otheruserid
1513 self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
1514 self::validate_context($systemcontext);
1516 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1517 throw new moodle_exception('You do not have permission to perform this action.');
1520 $profile = \core_message\api::get_profile($currentuserid, $otheruserid);
1521 $profile = new \core_message\output\messagearea\profile($profile);
1523 $renderer = $PAGE->get_renderer('core_message');
1524 return $profile->export_for_template($renderer);
1528 * The get profile return structure.
1530 * @return external_single_structure
1533 public static function data_for_messagearea_get_profile_returns() {
1534 return new external_single_structure(
1536 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
1537 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
1538 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
1539 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
1540 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1541 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1542 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1543 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1544 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1545 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
1546 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
1552 * Get contacts parameters description.
1554 * @return external_function_parameters
1557 public static function get_contacts_parameters() {
1558 return new external_function_parameters(array());
1564 * @return external_description
1567 public static function get_contacts() {
1568 global $CFG, $PAGE, $USER;
1570 // Check if messaging is enabled.
1571 if (empty($CFG->messaging)) {
1572 throw new moodle_exception('disabled', 'message');
1575 require_once($CFG->dirroot . '/user/lib.php');
1577 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
1578 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id);
1579 foreach ($contacts as $contact) {
1582 if (\core_message\helper::is_online($contact->lastaccess)) {
1586 $newcontact = array(
1587 'id' => $contact->id,
1588 'fullname' => fullname($contact),
1589 'unread' => $contact->messagecount
1592 $userpicture = new user_picture($contact);
1593 $userpicture->size = 1; // Size f1.
1594 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1595 $userpicture->size = 0; // Size f2.
1596 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1598 $allcontacts[$mode][$contact->id] = $newcontact;
1601 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id);
1602 foreach ($strangers as $contact) {
1603 $newcontact = array(
1604 'id' => $contact->id,
1605 'fullname' => fullname($contact),
1606 'unread' => $contact->messagecount
1609 $userpicture = new user_picture($contact);
1610 $userpicture->size = 1; // Size f1.
1611 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1612 $userpicture->size = 0; // Size f2.
1613 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1615 $allcontacts['strangers'][$contact->id] = $newcontact;
1618 // Add noreply user and support user to the list, if they don't exist.
1619 $supportuser = core_user::get_support_user();
1620 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) {
1621 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
1622 if ($supportuser->messagecount > 0) {
1623 $supportuser->fullname = fullname($supportuser);
1624 $supportuser->unread = $supportuser->messagecount;
1625 $allcontacts['strangers'][$supportuser->id] = $supportuser;
1629 $noreplyuser = core_user::get_noreply_user();
1630 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) {
1631 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
1632 if ($noreplyuser->messagecount > 0) {
1633 $noreplyuser->fullname = fullname($noreplyuser);
1634 $noreplyuser->unread = $noreplyuser->messagecount;
1635 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser;
1639 return $allcontacts;
1643 * Get contacts return description.
1645 * @return external_description
1648 public static function get_contacts_returns() {
1649 return new external_single_structure(
1651 'online' => new external_multiple_structure(
1652 new external_single_structure(
1654 'id' => new external_value(PARAM_INT, 'User ID'),
1655 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1656 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1657 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1658 'unread' => new external_value(PARAM_INT, 'Unread message count')
1661 'List of online contacts'
1663 'offline' => new external_multiple_structure(
1664 new external_single_structure(
1666 'id' => new external_value(PARAM_INT, 'User ID'),
1667 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1668 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1669 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1670 'unread' => new external_value(PARAM_INT, 'Unread message count')
1673 'List of offline contacts'
1675 'strangers' => new external_multiple_structure(
1676 new external_single_structure(
1678 'id' => new external_value(PARAM_INT, 'User ID'),
1679 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1680 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1681 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1682 'unread' => new external_value(PARAM_INT, 'Unread message count')
1685 'List of users that are not in the user\'s contact list but have sent a message'
1692 * Search contacts parameters description.
1694 * @return external_function_parameters
1697 public static function search_contacts_parameters() {
1698 return new external_function_parameters(
1700 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
1701 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
1702 VALUE_DEFAULT, false)
1710 * @param string $searchtext query string.
1711 * @param bool $onlymycourses limit the search to the user's courses only.
1712 * @return external_description
1715 public static function search_contacts($searchtext, $onlymycourses = false) {
1716 global $CFG, $USER, $PAGE;
1717 require_once($CFG->dirroot . '/user/lib.php');
1719 // Check if messaging is enabled.
1720 if (empty($CFG->messaging)) {
1721 throw new moodle_exception('disabled', 'message');
1724 require_once($CFG->libdir . '/enrollib.php');
1726 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1727 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
1729 // Extra validation, we do not allow empty queries.
1730 if ($params['searchtext'] === '') {
1731 throw new moodle_exception('querystringcannotbeempty');
1734 $courseids = array();
1735 if ($params['onlymycourses']) {
1736 $mycourses = enrol_get_my_courses(array('id'));
1737 foreach ($mycourses as $mycourse) {
1738 $courseids[] = $mycourse->id;
1741 $courseids[] = SITEID;
1744 // Retrieving the users matching the query.
1745 $users = message_search_users($courseids, $params['searchtext']);
1747 foreach ($users as $user) {
1748 $results[$user->id] = $user;
1751 // Reorganising information.
1752 foreach ($results as &$user) {
1755 'fullname' => fullname($user)
1758 // Avoid undefined property notice as phone not specified.
1759 $user->phone1 = null;
1760 $user->phone2 = null;
1762 $userpicture = new user_picture($user);
1763 $userpicture->size = 1; // Size f1.
1764 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1765 $userpicture->size = 0; // Size f2.
1766 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1775 * Search contacts return description.
1777 * @return external_description
1780 public static function search_contacts_returns() {
1781 return new external_multiple_structure(
1782 new external_single_structure(
1784 'id' => new external_value(PARAM_INT, 'User ID'),
1785 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1786 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1787 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
1795 * Get messages parameters description.
1797 * @return external_function_parameters
1800 public static function get_messages_parameters() {
1801 return new external_function_parameters(
1803 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1804 'useridfrom' => new external_value(
1805 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1807 'type' => new external_value(
1808 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
1809 VALUE_DEFAULT, 'both'),
1810 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
1811 'newestfirst' => new external_value(
1812 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1813 VALUE_DEFAULT, true),
1814 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
1815 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
1821 * Get messages function implementation.
1824 * @throws invalid_parameter_exception
1825 * @throws moodle_exception
1826 * @param int $useridto the user id who received the message
1827 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1828 * @param string $type type of message to return, expected values: notifications, conversations and both
1829 * @param bool $read true for retreiving read messages, false for unread
1830 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1831 * @param int $limitfrom limit from
1832 * @param int $limitnum limit num
1833 * @return external_description
1835 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
1836 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
1839 $warnings = array();
1842 'useridto' => $useridto,
1843 'useridfrom' => $useridfrom,
1846 'newestfirst' => $newestfirst,
1847 'limitfrom' => $limitfrom,
1848 'limitnum' => $limitnum
1851 $params = self::validate_parameters(self::get_messages_parameters(), $params);
1853 $context = context_system::instance();
1854 self::validate_context($context);
1856 $useridto = $params['useridto'];
1857 $useridfrom = $params['useridfrom'];
1858 $type = $params['type'];
1859 $read = $params['read'];
1860 $newestfirst = $params['newestfirst'];
1861 $limitfrom = $params['limitfrom'];
1862 $limitnum = $params['limitnum'];
1864 $allowedvalues = array('notifications', 'conversations', 'both');
1865 if (!in_array($type, $allowedvalues)) {
1866 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1867 'allowed values are: ' . implode(',', $allowedvalues));
1870 // Check if private messaging between users is allowed.
1871 if (empty($CFG->messaging)) {
1872 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
1873 if ($type == "conversations") {
1874 throw new moodle_exception('disabled', 'message');
1876 if ($type == "both") {
1878 $warning['item'] = 'message';
1879 $warning['itemid'] = $USER->id;
1880 $warning['warningcode'] = '1';
1881 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1882 Only notifications will be returned';
1883 $warnings[] = $warning;
1887 if (!empty($useridto)) {
1888 if (core_user::is_real_user($useridto)) {
1889 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1891 throw new moodle_exception('invaliduser');
1895 if (!empty($useridfrom)) {
1896 // We use get_user here because the from user can be the noreply or support user.
1897 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1900 // Check if the current user is the sender/receiver or just a privileged user.
1901 if ($useridto != $USER->id and $useridfrom != $USER->id and
1902 !has_capability('moodle/site:readallmessages', $context)) {
1903 throw new moodle_exception('accessdenied', 'admin');
1906 // Which type of messages to retrieve.
1907 $notifications = -1;
1908 if ($type != 'both') {
1909 $notifications = ($type == 'notifications') ? 1 : 0;
1912 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
1913 $sort = "mr.timecreated $orderdirection";
1915 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
1916 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1918 // In some cases, we don't need to get the to/from user objects from the sql query.
1919 $userfromfullname = '';
1920 $usertofullname = '';
1922 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1923 if (!empty($useridto)) {
1924 $usertofullname = fullname($userto, $canviewfullname);
1925 // The user from may or may not be filled.
1926 if (!empty($useridfrom)) {
1927 $userfromfullname = fullname($userfrom, $canviewfullname);
1930 // If the useridto field is empty, the useridfrom must be filled.
1931 $userfromfullname = fullname($userfrom, $canviewfullname);
1933 foreach ($messages as $mid => $message) {
1935 // Do not return deleted messages.
1936 if (!$message->notification) {
1937 if (($useridto == $USER->id and $message->timeusertodeleted) or
1938 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
1939 unset($messages[$mid]);
1944 // We need to get the user from the query.
1945 if (empty($userfromfullname)) {
1946 // Check for non-reply and support users.
1947 if (core_user::is_real_user($message->useridfrom)) {
1948 $user = new stdClass();
1949 $user = username_load_fields_from_object($user, $message, 'userfrom');
1950 $message->userfromfullname = fullname($user, $canviewfullname);
1952 $user = core_user::get_user($message->useridfrom);
1953 $message->userfromfullname = fullname($user, $canviewfullname);
1956 $message->userfromfullname = $userfromfullname;
1959 // We need to get the user from the query.
1960 if (empty($usertofullname)) {
1961 $user = new stdClass();
1962 $user = username_load_fields_from_object($user, $message, 'userto');
1963 $message->usertofullname = fullname($user, $canviewfullname);
1965 $message->usertofullname = $usertofullname;
1968 $message->text = message_format_message_text($message);
1969 $messages[$mid] = (array) $message;
1974 'messages' => $messages,
1975 'warnings' => $warnings
1982 * Get messages return description.
1984 * @return external_single_structure
1987 public static function get_messages_returns() {
1988 return new external_single_structure(
1990 'messages' => new external_multiple_structure(
1991 new external_single_structure(
1993 'id' => new external_value(PARAM_INT, 'Message id'),
1994 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1995 'useridto' => new external_value(PARAM_INT, 'User to id'),
1996 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1997 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1998 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
1999 'fullmessageformat' => new external_format_value('fullmessage'),
2000 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
2001 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
2002 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
2003 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
2004 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
2005 'timecreated' => new external_value(PARAM_INT, 'Time created'),
2006 'timeread' => new external_value(PARAM_INT, 'Time read'),
2007 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
2008 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
2012 'warnings' => new external_warnings()
2018 * Mark all notifications as read parameters description.
2020 * @return external_function_parameters
2023 public static function mark_all_notifications_as_read_parameters() {
2024 return new external_function_parameters(
2026 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2027 'useridfrom' => new external_value(
2028 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2035 * Mark all notifications as read function.
2038 * @throws invalid_parameter_exception
2039 * @throws moodle_exception
2040 * @param int $useridto the user id who received the message
2041 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2042 * @return external_description
2044 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
2047 $params = self::validate_parameters(
2048 self::mark_all_notifications_as_read_parameters(),
2050 'useridto' => $useridto,
2051 'useridfrom' => $useridfrom,
2055 $context = context_system::instance();
2056 self::validate_context($context);
2058 $useridto = $params['useridto'];
2059 $useridfrom = $params['useridfrom'];
2061 if (!empty($useridto)) {
2062 if (core_user::is_real_user($useridto)) {
2063 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2065 throw new moodle_exception('invaliduser');
2069 if (!empty($useridfrom)) {
2070 // We use get_user here because the from user can be the noreply or support user.
2071 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2074 // Check if the current user is the sender/receiver or just a privileged user.
2075 if ($useridto != $USER->id and $useridfrom != $USER->id and
2076 // The deleteanymessage cap seems more reasonable here than readallmessages.
2077 !has_capability('moodle/site:deleteanymessage', $context)) {
2078 throw new moodle_exception('accessdenied', 'admin');
2081 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom);
2087 * Mark all notifications as read return description.
2089 * @return external_single_structure
2092 public static function mark_all_notifications_as_read_returns() {
2093 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2097 * Get unread conversations count parameters description.
2099 * @return external_function_parameters
2102 public static function get_unread_conversations_count_parameters() {
2103 return new external_function_parameters(
2105 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2111 * Get unread messages count function.
2114 * @throws invalid_parameter_exception
2115 * @throws moodle_exception
2116 * @param int $useridto the user id who received the message
2117 * @return external_description
2119 public static function get_unread_conversations_count($useridto) {
2122 // Check if messaging is enabled.
2123 if (empty($CFG->messaging)) {
2124 throw new moodle_exception('disabled', 'message');
2127 $params = self::validate_parameters(
2128 self::get_unread_conversations_count_parameters(),
2129 array('useridto' => $useridto)
2132 $context = context_system::instance();
2133 self::validate_context($context);
2135 $useridto = $params['useridto'];
2137 if (!empty($useridto)) {
2138 if (core_user::is_real_user($useridto)) {
2139 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2141 throw new moodle_exception('invaliduser');
2144 $useridto = $USER->id;
2147 // Check if the current user is the receiver or just a privileged user.
2148 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
2149 throw new moodle_exception('accessdenied', 'admin');
2152 return \core_message\api::count_unread_conversations($userto);
2156 * Get unread conversations count return description.
2158 * @return external_single_structure
2161 public static function get_unread_conversations_count_returns() {
2162 return new external_value(PARAM_INT, 'The count of unread messages for the user');
2166 * Get blocked users parameters description.
2168 * @return external_function_parameters
2171 public static function get_blocked_users_parameters() {
2172 return new external_function_parameters(
2174 'userid' => new external_value(PARAM_INT,
2175 'the user whose blocked users we want to retrieve',
2182 * Retrieve a list of users blocked
2184 * @param int $userid the user whose blocked users we want to retrieve
2185 * @return external_description
2188 public static function get_blocked_users($userid) {
2189 global $CFG, $USER, $PAGE;
2191 // Warnings array, it can be empty at the end but is mandatory.
2192 $warnings = array();
2198 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
2199 $userid = $params['userid'];
2201 // Validate context.
2202 $context = context_system::instance();
2203 self::validate_context($context);
2205 // Check if private messaging between users is allowed.
2206 if (empty($CFG->messaging)) {
2207 throw new moodle_exception('disabled', 'message');
2210 $user = core_user::get_user($userid, '*', MUST_EXIST);
2211 core_user::require_active_user($user);
2213 // Check if we have permissions for retrieve the information.
2214 $capability = 'moodle/site:manageallmessaging';
2215 if (($USER->id != $userid) && !has_capability($capability, $context)) {
2216 throw new required_capability_exception($context, $capability, 'nopermissions', '');
2219 // Now, we can get safely all the blocked users.
2220 $users = \core_message\api::get_blocked_users($user->id);
2222 $blockedusers = array();
2223 foreach ($users as $user) {
2226 'fullname' => fullname($user),
2229 $userpicture = new user_picture($user);
2230 $userpicture->size = 1; // Size f1.
2231 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2233 $blockedusers[] = $newuser;
2237 'users' => $blockedusers,
2238 'warnings' => $warnings
2244 * Get blocked users return description.
2246 * @return external_single_structure
2249 public static function get_blocked_users_returns() {
2250 return new external_single_structure(
2252 'users' => new external_multiple_structure(
2253 new external_single_structure(
2255 'id' => new external_value(PARAM_INT, 'User ID'),
2256 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2257 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
2260 'List of blocked users'
2262 'warnings' => new external_warnings()
2268 * Returns description of method parameters
2270 * @return external_function_parameters
2273 public static function mark_message_read_parameters() {
2274 return new external_function_parameters(
2276 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'),
2277 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
2284 * Mark a single message as read, trigger message_viewed event
2286 * @param int $messageid id of the message (in the message table)
2287 * @param int $timeread timestamp for when the message should be marked read
2288 * @return external_description
2289 * @throws invalid_parameter_exception
2290 * @throws moodle_exception
2293 public static function mark_message_read($messageid, $timeread) {
2294 global $CFG, $DB, $USER;
2296 // Check if private messaging between users is allowed.
2297 if (empty($CFG->messaging)) {
2298 throw new moodle_exception('disabled', 'message');
2301 // Warnings array, it can be empty at the end but is mandatory.
2302 $warnings = array();
2306 'messageid' => $messageid,
2307 'timeread' => $timeread
2309 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
2311 if (empty($params['timeread'])) {
2314 $timeread = $params['timeread'];
2317 // Validate context.
2318 $context = context_system::instance();
2319 self::validate_context($context);
2321 $sql = "SELECT m.*, mcm.userid as useridto
2323 INNER JOIN {message_conversations} mc
2324 ON m.conversationid = mc.id
2325 INNER JOIN {message_conversation_members} mcm
2326 ON mcm.conversationid = mc.id
2327 LEFT JOIN {message_user_actions} mua
2328 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
2329 WHERE mua.id is NULL
2330 AND mcm.userid != m.useridfrom
2332 $messageparams = [];
2333 $messageparams[] = $USER->id;
2334 $messageparams[] = \core_message\api::MESSAGE_ACTION_READ;
2335 $messageparams[] = $params['messageid'];
2336 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST);
2338 if ($message->useridto != $USER->id) {
2339 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2342 \core_message\api::mark_message_as_read($USER->id, $message, $timeread);
2345 'messageid' => $message->id,
2346 'warnings' => $warnings
2352 * Returns description of method result value
2354 * @return external_description
2357 public static function mark_message_read_returns() {
2358 return new external_single_structure(
2360 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'),
2361 'warnings' => new external_warnings()
2367 * Returns description of method parameters
2369 * @return external_function_parameters
2371 public static function mark_notification_read_parameters() {
2372 return new external_function_parameters(
2374 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
2375 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read',
2382 * Mark a single notification as read.
2384 * This will trigger a 'notification_viewed' event.
2386 * @param int $notificationid id of the notification
2387 * @param int $timeread timestamp for when the notification should be marked read
2388 * @return external_description
2389 * @throws invalid_parameter_exception
2390 * @throws moodle_exception
2392 public static function mark_notification_read($notificationid, $timeread) {
2393 global $CFG, $DB, $USER;
2395 // Check if private messaging between users is allowed.
2396 if (empty($CFG->messaging)) {
2397 throw new moodle_exception('disabled', 'message');
2400 // Warnings array, it can be empty at the end but is mandatory.
2401 $warnings = array();
2405 'notificationid' => $notificationid,
2406 'timeread' => $timeread
2408 $params = self::validate_parameters(self::mark_notification_read_parameters(), $params);
2410 if (empty($params['timeread'])) {
2413 $timeread = $params['timeread'];
2416 // Validate context.
2417 $context = context_system::instance();
2418 self::validate_context($context);
2420 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST);
2422 if ($notification->useridto != $USER->id) {
2423 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
2424 'notification as read');
2427 \core_message\api::mark_notification_as_read($notification, $timeread);
2430 'notificationid' => $notification->id,
2431 'warnings' => $warnings
2438 * Returns description of method result value
2440 * @return external_description
2442 public static function mark_notification_read_returns() {
2443 return new external_single_structure(
2445 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
2446 'warnings' => new external_warnings()
2452 * Mark all messages as read parameters description.
2454 * @return external_function_parameters
2457 public static function mark_all_messages_as_read_parameters() {
2458 return new external_function_parameters(
2460 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
2461 'useridfrom' => new external_value(
2462 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2469 * Mark all notifications as read function.
2472 * @throws invalid_parameter_exception
2473 * @throws moodle_exception
2474 * @param int $useridto the user id who received the message
2475 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2476 * @return external_description
2478 public static function mark_all_messages_as_read($useridto, $useridfrom) {
2481 // Check if messaging is enabled.
2482 if (empty($CFG->messaging)) {
2483 throw new moodle_exception('disabled', 'message');
2486 $params = self::validate_parameters(
2487 self::mark_all_messages_as_read_parameters(),
2489 'useridto' => $useridto,
2490 'useridfrom' => $useridfrom,
2494 $context = context_system::instance();
2495 self::validate_context($context);
2497 $useridto = $params['useridto'];
2498 $useridfrom = $params['useridfrom'];
2500 if (!empty($useridto)) {
2501 if (core_user::is_real_user($useridto)) {
2502 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
2504 throw new moodle_exception('invaliduser');
2508 if (!empty($useridfrom)) {
2509 // We use get_user here because the from user can be the noreply or support user.
2510 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
2513 // Check if the current user is the sender/receiver or just a privileged user.
2514 if ($useridto != $USER->id and $useridfrom != $USER->id and
2515 // The deleteanymessage cap seems more reasonable here than readallmessages.
2516 !has_capability('moodle/site:deleteanymessage', $context)) {
2517 throw new moodle_exception('accessdenied', 'admin');
2521 if ($conversationid = \core_message\api::get_conversation_between_users([$useridto, $useridfrom])) {
2522 \core_message\api::mark_all_messages_as_read($useridto, $conversationid);
2525 \core_message\api::mark_all_messages_as_read($useridto);
2532 * Mark all notifications as read return description.
2534 * @return external_single_structure
2537 public static function mark_all_messages_as_read_returns() {
2538 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
2542 * Returns description of method parameters.
2544 * @return external_function_parameters
2547 public static function delete_conversation_parameters() {
2548 return new external_function_parameters(
2550 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
2551 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
2557 * Deletes a conversation.
2559 * @param int $userid The user id of who we want to delete the conversation for
2560 * @param int $otheruserid The user id of the other user in the conversation
2562 * @throws moodle_exception
2565 public static function delete_conversation($userid, $otheruserid) {
2568 // Check if private messaging between users is allowed.
2569 if (empty($CFG->messaging)) {
2570 throw new moodle_exception('disabled', 'message');
2573 // Warnings array, it can be empty at the end but is mandatory.
2574 $warnings = array();
2578 'userid' => $userid,
2579 'otheruserid' => $otheruserid,
2581 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
2583 // Validate context.
2584 $context = context_system::instance();
2585 self::validate_context($context);
2587 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2588 core_user::require_active_user($user);
2590 if (\core_message\api::can_delete_conversation($user->id)) {
2591 $status = \core_message\api::delete_conversation($user->id, $otheruserid);
2593 throw new moodle_exception('You do not have permission to delete messages');
2597 'status' => $status,
2598 'warnings' => $warnings
2605 * Returns description of method result value.
2607 * @return external_description
2610 public static function delete_conversation_returns() {
2611 return new external_single_structure(
2613 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
2614 'warnings' => new external_warnings()
2620 * Returns description of method parameters
2622 * @return external_function_parameters
2625 public static function delete_message_parameters() {
2626 return new external_function_parameters(
2628 'messageid' => new external_value(PARAM_INT, 'The message id'),
2629 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
2630 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
2638 * @param int $messageid the message id
2639 * @param int $userid the user id of who we want to delete the message for
2640 * @param bool $read if is a message read (default to true)
2641 * @return external_description
2642 * @throws moodle_exception
2645 public static function delete_message($messageid, $userid, $read = true) {
2648 // Check if private messaging between users is allowed.
2649 if (empty($CFG->messaging)) {
2650 throw new moodle_exception('disabled', 'message');
2653 // Warnings array, it can be empty at the end but is mandatory.
2654 $warnings = array();
2658 'messageid' => $messageid,
2659 'userid' => $userid,
2662 $params = self::validate_parameters(self::delete_message_parameters(), $params);
2664 // Validate context.
2665 $context = context_system::instance();
2666 self::validate_context($context);
2668 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2669 core_user::require_active_user($user);
2671 if (\core_message\api::can_delete_message($user->id, $messageid)) {
2672 $status = \core_message\api::delete_message($user->id, $messageid);
2674 throw new moodle_exception('You do not have permission to delete this message');
2678 'status' => $status,
2679 'warnings' => $warnings
2685 * Returns description of method result value
2687 * @return external_description
2690 public static function delete_message_returns() {
2691 return new external_single_structure(
2693 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
2694 'warnings' => new external_warnings()
2700 * Returns description of method parameters
2702 * @return external_function_parameters
2705 public static function message_processor_config_form_parameters() {
2706 return new external_function_parameters(
2708 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
2709 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
2710 'formvalues' => new external_multiple_structure(
2711 new external_single_structure(
2713 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
2714 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
2717 'Config form values',
2725 * Processes a message processor config form.
2727 * @param int $userid the user id
2728 * @param string $name the name of the processor
2729 * @param array $formvalues the form values
2730 * @return external_description
2731 * @throws moodle_exception
2734 public static function message_processor_config_form($userid, $name, $formvalues) {
2737 // Check if messaging is enabled.
2738 if (empty($CFG->messaging)) {
2739 throw new moodle_exception('disabled', 'message');
2742 $params = self::validate_parameters(
2743 self::message_processor_config_form_parameters(),
2745 'userid' => $userid,
2747 'formvalues' => $formvalues,
2751 $user = self::validate_preferences_permissions($params['userid']);
2753 $processor = get_message_processor($name);
2755 $form = new stdClass();
2757 foreach ($formvalues as $formvalue) {
2758 // Curly braces to ensure interpretation is consistent between
2760 $form->{$formvalue['name']} = $formvalue['value'];
2763 $processor->process_form($form, $preferences);
2765 if (!empty($preferences)) {
2766 set_user_preferences($preferences, $userid);
2771 * Returns description of method result value
2773 * @return external_description
2776 public static function message_processor_config_form_returns() {
2781 * Returns description of method parameters
2783 * @return external_function_parameters
2786 public static function get_message_processor_parameters() {
2787 return new external_function_parameters(
2789 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
2790 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
2796 * Get a message processor.
2798 * @param int $userid
2799 * @param string $name the name of the processor
2800 * @return external_description
2801 * @throws moodle_exception
2804 public static function get_message_processor($userid = 0, $name) {
2805 global $USER, $PAGE, $CFG;
2807 // Check if messaging is enabled.
2808 if (empty($CFG->messaging)) {
2809 throw new moodle_exception('disabled', 'message');
2812 $params = self::validate_parameters(
2813 self::get_message_processor_parameters(),
2815 'userid' => $userid,
2820 if (empty($params['userid'])) {
2821 $params['userid'] = $USER->id;
2824 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2825 core_user::require_active_user($user);
2826 self::validate_context(context_user::instance($params['userid']));
2828 $processor = get_message_processor($name);
2830 $processoroutput = new \core_message\output\processor($processor, $user);
2831 $renderer = $PAGE->get_renderer('core_message');
2833 return $processoroutput->export_for_template($renderer);
2837 * Returns description of method result value
2839 * @return external_description
2842 public static function get_message_processor_returns() {
2843 return new external_function_parameters(
2845 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
2846 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
2852 * Check that the user has enough permission to retrieve message or notifications preferences.
2854 * @param int $userid the user id requesting the preferences
2855 * @return stdClass full user object
2856 * @throws moodle_exception
2859 protected static function validate_preferences_permissions($userid) {
2862 if (empty($userid)) {
2865 $user = core_user::get_user($userid, '*', MUST_EXIST);
2866 core_user::require_active_user($user);
2869 $systemcontext = context_system::instance();
2870 self::validate_context($systemcontext);
2872 // Check access control.
2873 if ($user->id == $USER->id) {
2874 // Editing own message profile.
2875 require_capability('moodle/user:editownmessageprofile', $systemcontext);
2877 // Teachers, parents, etc.
2878 $personalcontext = context_user::instance($user->id);
2879 require_capability('moodle/user:editmessageprofile', $personalcontext);
2885 * Returns a notification or message preference structure.
2887 * @return external_single_structure the structure
2890 protected static function get_preferences_structure() {
2891 return new external_single_structure(
2893 'userid' => new external_value(PARAM_INT, 'User id'),
2894 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
2895 'processors' => new external_multiple_structure(
2896 new external_single_structure(
2898 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2899 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2900 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
2901 'contextid' => new external_value(PARAM_INT, 'Context id'),
2902 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
2905 'Config form values'
2907 'components' => new external_multiple_structure(
2908 new external_single_structure(
2910 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2911 'notifications' => new external_multiple_structure(
2912 new external_single_structure(
2914 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2915 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
2916 'processors' => new external_multiple_structure(
2917 new external_single_structure(
2919 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2920 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2921 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
2922 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
2923 'loggedin' => new external_single_structure(
2925 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2926 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2927 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2930 'loggedoff' => new external_single_structure(
2932 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2933 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2934 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2939 'Processors values for this notification'
2943 'List of notificaitons for the component'
2947 'Available components'
2954 * Returns description of method parameters
2956 * @return external_function_parameters
2959 public static function get_user_notification_preferences_parameters() {
2960 return new external_function_parameters(
2962 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
2968 * Get the notification preferences for a given user.
2970 * @param int $userid id of the user, 0 for current user
2971 * @return external_description
2972 * @throws moodle_exception
2975 public static function get_user_notification_preferences($userid = 0) {
2978 $params = self::validate_parameters(
2979 self::get_user_notification_preferences_parameters(),
2981 'userid' => $userid,
2984 $user = self::validate_preferences_permissions($params['userid']);
2986 $processors = get_message_processors();
2987 $providers = message_get_providers_for_user($user->id);
2988 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2989 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
2991 $renderer = $PAGE->get_renderer('core_message');
2994 'warnings' => array(),
2995 'preferences' => $notificationlist->export_for_template($renderer)
3001 * Returns description of method result value
3003 * @return external_description
3006 public static function get_user_notification_preferences_returns() {
3007 return new external_function_parameters(
3009 'preferences' => self::get_preferences_structure(),
3010 'warnings' => new external_warnings(),
3017 * Returns description of method parameters
3019 * @return external_function_parameters
3022 public static function get_user_message_preferences_parameters() {
3023 return new external_function_parameters(
3025 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
3031 * Get the notification preferences for a given user.
3033 * @param int $userid id of the user, 0 for current user
3034 * @return external_description
3035 * @throws moodle_exception
3038 public static function get_user_message_preferences($userid = 0) {
3041 $params = self::validate_parameters(
3042 self::get_user_message_preferences_parameters(),
3044 'userid' => $userid,
3048 $user = self::validate_preferences_permissions($params['userid']);
3050 // Filter out enabled, available system_configured and user_configured processors only.
3051 $readyprocessors = array_filter(get_message_processors(), function($processor) {
3052 return $processor->enabled &&
3053 $processor->configured &&
3054 $processor->object->is_user_configured() &&
3055 // Filter out processors that don't have and message preferences to configure.
3056 $processor->object->has_message_preferences();
3059 $providers = array_filter(message_get_providers_for_user($user->id), function($provider) {
3060 return $provider->component === 'moodle';
3062 $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user);
3063 $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors,
3064 $providers, $preferences, $user);
3066 $renderer = $PAGE->get_renderer('core_message');
3069 'warnings' => array(),
3070 'preferences' => $notificationlistoutput->export_for_template($renderer),
3071 'blocknoncontacts' => get_user_preferences('message_blocknoncontacts', '', $user->id) ? true : false,
3077 * Returns description of method result value
3079 * @return external_description
3082 public static function get_user_message_preferences_returns() {
3083 return new external_function_parameters(
3085 'preferences' => self::get_preferences_structure(),
3086 'blocknoncontacts' => new external_value(PARAM_BOOL, 'Whether to block or not messages from non contacts'),
3087 'warnings' => new external_warnings(),