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
{
43 * Returns description of method parameters
45 * @return external_function_parameters
48 public static function send_messages_to_conversation_parameters() {
49 return new external_function_parameters(
51 'conversationid' => new external_value(PARAM_INT
, 'id of the conversation'),
52 'messages' => new external_multiple_structure(
53 new external_single_structure(
55 'text' => new external_value(PARAM_RAW
, 'the text of the message'),
56 'textformat' => new external_format_value('text', VALUE_DEFAULT
, FORMAT_MOODLE
),
65 * Send messages from the current USER to a conversation.
67 * This conversation may be any type of conversation, individual or group.
69 * @param int $conversationid the id of the conversation to which the messages will be sent.
70 * @param array $messages An array of message to send.
71 * @return array the array of messages which were sent (created).
74 public static function send_messages_to_conversation(int $conversationid, array $messages = []) {
77 // Check if messaging is enabled.
78 if (empty($CFG->messaging
)) {
79 throw new moodle_exception('disabled', 'message');
82 // Ensure the current user is allowed to run this function.
83 $context = context_system
::instance();
84 self
::validate_context($context);
86 $params = self
::validate_parameters(self
::send_messages_to_conversation_parameters(), [
87 'conversationid' => $conversationid,
88 'messages' => $messages
92 foreach ($params['messages'] as $message) {
93 $messages[] = \core_message\api
::send_message_to_conversation($USER->id
, $params['conversationid'], $message['text'],
94 $message['textformat']);
101 * Returns description of method result value.
103 * @return external_description
106 public static function send_messages_to_conversation_returns() {
107 return new external_multiple_structure(
108 self
::get_conversation_message_structure()
114 * Returns description of method parameters
116 * @return external_function_parameters
119 public static function send_instant_messages_parameters() {
120 return new external_function_parameters(
122 'messages' => new external_multiple_structure(
123 new external_single_structure(
125 'touserid' => new external_value(PARAM_INT
, 'id of the user to send the private message'),
126 'text' => new external_value(PARAM_RAW
, 'the text of the message'),
127 'textformat' => new external_format_value('text', VALUE_DEFAULT
, FORMAT_MOODLE
),
128 '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
),
137 * Send private messages from the current USER to other users
139 * @param array $messages An array of message to send.
143 public static function send_instant_messages($messages = array()) {
144 global $CFG, $USER, $DB;
146 // Check if messaging is enabled.
147 if (empty($CFG->messaging
)) {
148 throw new moodle_exception('disabled', 'message');
151 // Ensure the current user is allowed to run this function
152 $context = context_system
::instance();
153 self
::validate_context($context);
154 require_capability('moodle/site:sendmessage', $context);
156 $params = self
::validate_parameters(self
::send_instant_messages_parameters(), array('messages' => $messages));
158 //retrieve all tousers of the messages
159 $receivers = array();
160 foreach($params['messages'] as $message) {
161 $receivers[] = $message['touserid'];
163 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
164 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
166 $resultmessages = array();
167 $messageids = array();
168 foreach ($params['messages'] as $message) {
169 $resultmsg = array(); //the infos about the success of the operation
171 // We are going to do some checking.
172 // Code should match /messages/index.php checks.
175 // Check the user exists.
176 if (empty($tousers[$message['touserid']])) {
178 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
181 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
182 // Check if the recipient can be messaged by the sender.
183 if ($success && !\core_message\api
::can_post_message($tousers[$message['touserid']], $USER)) {
185 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user
::get_user($message['touserid'])));
188 // Now we can send the message (at least try).
190 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
191 $success = message_post_message($USER, $tousers[$message['touserid']],
192 $message['text'], external_validate_format($message['textformat']));
195 // Build the resultmsg.
196 if (isset($message['clientmsgid'])) {
197 $resultmsg['clientmsgid'] = $message['clientmsgid'];
200 $resultmsg['msgid'] = $success;
201 $resultmsg['text'] = message_format_message_text((object) [
202 'smallmessage' => $message['text'],
203 'fullmessageformat' => external_validate_format($message['textformat'])
205 $resultmsg['timecreated'] = time();
206 $messageids[] = $success;
208 // WARNINGS: for backward compatibility we return this errormessage.
209 // We should have thrown exceptions as these errors prevent results to be returned.
210 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
211 $resultmsg['msgid'] = -1;
212 $resultmsg['errormessage'] = $errormessage;
215 $resultmessages[] = $resultmsg;
218 if (!empty($messageids)) {
219 $messagerecords = $DB->get_records_list('messages', 'id', $messageids, '', 'id, conversationid');
220 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) {
221 $id = $resultmessage['msgid'];
222 $resultmessage['conversationid'] = isset($messagerecords[$id]) ?
$messagerecords[$id]->conversationid
: null;
223 $resultmessage['useridfrom'] = $USER->id
;
224 return $resultmessage;
228 return $resultmessages;
232 * Returns description of method result value
234 * @return external_description
237 public static function send_instant_messages_returns() {
238 return new external_multiple_structure(
239 new external_single_structure(
241 'msgid' => new external_value(PARAM_INT
, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
242 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT
, 'your own id for the message', VALUE_OPTIONAL
),
243 'errormessage' => new external_value(PARAM_TEXT
, 'error message - if it failed', VALUE_OPTIONAL
),
244 'text' => new external_value(PARAM_RAW
, 'The text of the message', VALUE_OPTIONAL
),
245 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message', VALUE_OPTIONAL
),
246 'conversationid' => new external_value(PARAM_INT
, 'The conversation id for this message', VALUE_OPTIONAL
),
247 'useridfrom' => new external_value(PARAM_INT
, 'The user id who sent the message', VALUE_OPTIONAL
),
254 * Create contacts parameters description.
256 * @deprecated since Moodle 3.6
257 * @return external_function_parameters
260 public static function create_contacts_parameters() {
261 return new external_function_parameters(
263 'userids' => new external_multiple_structure(
264 new external_value(PARAM_INT
, 'User ID'),
267 'userid' => new external_value(PARAM_INT
, 'The id of the user we are creating the contacts for, 0 for the
268 current user', VALUE_DEFAULT
, 0)
276 * @deprecated since Moodle 3.6
277 * @param array $userids array of user IDs.
278 * @param int $userid The id of the user we are creating the contacts for
279 * @return external_description
282 public static function create_contacts($userids, $userid = 0) {
285 // Check if messaging is enabled.
286 if (empty($CFG->messaging
)) {
287 throw new moodle_exception('disabled', 'message');
290 if (empty($userid)) {
295 $context = context_system
::instance();
296 self
::validate_context($context);
298 $params = array('userids' => $userids, 'userid' => $userid);
299 $params = self
::validate_parameters(self
::create_contacts_parameters(), $params);
301 $capability = 'moodle/site:manageallmessaging';
302 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
303 throw new required_capability_exception($context, $capability, 'nopermissions', '');
307 foreach ($params['userids'] as $id) {
308 if (!message_add_contact($id, 0, $params['userid'])) {
312 'warningcode' => 'contactnotcreated',
313 'message' => 'The contact could not be created'
321 * Create contacts return description.
323 * @deprecated since Moodle 3.6
324 * @return external_description
327 public static function create_contacts_returns() {
328 return new external_warnings();
332 * Marking the method as deprecated.
336 public static function create_contacts_is_deprecated() {
341 * Delete contacts parameters description.
343 * @return external_function_parameters
346 public static function delete_contacts_parameters() {
347 return new external_function_parameters(
349 'userids' => new external_multiple_structure(
350 new external_value(PARAM_INT
, 'User ID'),
353 'userid' => new external_value(PARAM_INT
, 'The id of the user we are deleting the contacts for, 0 for the
354 current user', VALUE_DEFAULT
, 0)
362 * @param array $userids array of user IDs.
363 * @param int $userid The id of the user we are deleting the contacts for
367 public static function delete_contacts($userids, $userid = 0) {
370 // Check if messaging is enabled.
371 if (empty($CFG->messaging
)) {
372 throw new moodle_exception('disabled', 'message');
375 if (empty($userid)) {
380 $context = context_system
::instance();
381 self
::validate_context($context);
383 $params = array('userids' => $userids, 'userid' => $userid);
384 $params = self
::validate_parameters(self
::delete_contacts_parameters(), $params);
386 $capability = 'moodle/site:manageallmessaging';
387 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
388 throw new required_capability_exception($context, $capability, 'nopermissions', '');
391 foreach ($params['userids'] as $id) {
392 \core_message\api
::remove_contact($params['userid'], $id);
399 * Delete contacts return description.
401 * @return external_description
404 public static function delete_contacts_returns() {
409 * Block user parameters description.
411 * @return external_function_parameters
413 public static function block_user_parameters() {
414 return new external_function_parameters(
416 'userid' => new external_value(PARAM_INT
, 'The id of the user who is blocking'),
417 'blockeduserid' => new external_value(PARAM_INT
, 'The id of the user being blocked'),
425 * @param int $userid The id of the user who is blocking
426 * @param int $blockeduserid The id of the user being blocked
427 * @return external_description
429 public static function block_user(int $userid, int $blockeduserid) {
432 // Check if messaging is enabled.
433 if (empty($CFG->messaging
)) {
434 throw new moodle_exception('disabled', 'message');
438 $context = context_system
::instance();
439 self
::validate_context($context);
441 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
442 $params = self
::validate_parameters(self
::block_user_parameters(), $params);
444 $capability = 'moodle/site:manageallmessaging';
445 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
446 throw new required_capability_exception($context, $capability, 'nopermissions', '');
449 if (!\core_message\api
::is_blocked($params['userid'], $params['blockeduserid'])) {
450 \core_message\api
::block_user($params['userid'], $params['blockeduserid']);
457 * Block user return description.
459 * @return external_description
461 public static function block_user_returns() {
462 return new external_warnings();
466 * Unblock user parameters description.
468 * @return external_function_parameters
470 public static function unblock_user_parameters() {
471 return new external_function_parameters(
473 'userid' => new external_value(PARAM_INT
, 'The id of the user who is unblocking'),
474 'unblockeduserid' => new external_value(PARAM_INT
, 'The id of the user being unblocked'),
482 * @param int $userid The id of the user who is unblocking
483 * @param int $unblockeduserid The id of the user being unblocked
485 public static function unblock_user(int $userid, int $unblockeduserid) {
488 // Check if messaging is enabled.
489 if (empty($CFG->messaging
)) {
490 throw new moodle_exception('disabled', 'message');
494 $context = context_system
::instance();
495 self
::validate_context($context);
497 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
498 $params = self
::validate_parameters(self
::unblock_user_parameters(), $params);
500 $capability = 'moodle/site:manageallmessaging';
501 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
502 throw new required_capability_exception($context, $capability, 'nopermissions', '');
505 \core_message\api
::unblock_user($params['userid'], $params['unblockeduserid']);
511 * Unblock user return description.
513 * @return external_description
515 public static function unblock_user_returns() {
516 return new external_warnings();
520 * Block contacts parameters description.
522 * @deprecated since Moodle 3.6
523 * @return external_function_parameters
526 public static function block_contacts_parameters() {
527 return new external_function_parameters(
529 'userids' => new external_multiple_structure(
530 new external_value(PARAM_INT
, 'User ID'),
533 'userid' => new external_value(PARAM_INT
, 'The id of the user we are blocking the contacts for, 0 for the
534 current user', VALUE_DEFAULT
, 0)
542 * @deprecated since Moodle 3.6
543 * @param array $userids array of user IDs.
544 * @param int $userid The id of the user we are blocking the contacts for
545 * @return external_description
548 public static function block_contacts($userids, $userid = 0) {
551 // Check if messaging is enabled.
552 if (empty($CFG->messaging
)) {
553 throw new moodle_exception('disabled', 'message');
556 if (empty($userid)) {
561 $context = context_system
::instance();
562 self
::validate_context($context);
564 $params = array('userids' => $userids, 'userid' => $userid);
565 $params = self
::validate_parameters(self
::block_contacts_parameters(), $params);
567 $capability = 'moodle/site:manageallmessaging';
568 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
569 throw new required_capability_exception($context, $capability, 'nopermissions', '');
573 foreach ($params['userids'] as $id) {
574 if (!message_block_contact($id, $params['userid'])) {
578 'warningcode' => 'contactnotblocked',
579 'message' => 'The contact could not be blocked'
587 * Block contacts return description.
589 * @deprecated since Moodle 3.6
590 * @return external_description
593 public static function block_contacts_returns() {
594 return new external_warnings();
598 * Marking the method as deprecated.
602 public static function block_contacts_is_deprecated() {
607 * Unblock contacts parameters description.
609 * @deprecated since Moodle 3.6
610 * @return external_function_parameters
613 public static function unblock_contacts_parameters() {
614 return new external_function_parameters(
616 'userids' => new external_multiple_structure(
617 new external_value(PARAM_INT
, 'User ID'),
620 'userid' => new external_value(PARAM_INT
, 'The id of the user we are unblocking the contacts for, 0 for the
621 current user', VALUE_DEFAULT
, 0)
629 * @param array $userids array of user IDs.
630 * @param int $userid The id of the user we are unblocking the contacts for
634 public static function unblock_contacts($userids, $userid = 0) {
637 // Check if messaging is enabled.
638 if (empty($CFG->messaging
)) {
639 throw new moodle_exception('disabled', 'message');
642 if (empty($userid)) {
647 $context = context_system
::instance();
648 self
::validate_context($context);
650 $params = array('userids' => $userids, 'userid' => $userid);
651 $params = self
::validate_parameters(self
::unblock_contacts_parameters(), $params);
653 $capability = 'moodle/site:manageallmessaging';
654 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
655 throw new required_capability_exception($context, $capability, 'nopermissions', '');
658 foreach ($params['userids'] as $id) {
659 message_unblock_contact($id, $params['userid']);
666 * Unblock contacts return description.
668 * @deprecated since Moodle 3.6
669 * @return external_description
672 public static function unblock_contacts_returns() {
677 * Marking the method as deprecated.
681 public static function unblock_contacts_is_deprecated() {
686 * Returns contact requests parameters description.
688 * @return external_function_parameters
690 public static function get_contact_requests_parameters() {
691 return new external_function_parameters(
693 'userid' => new external_value(PARAM_INT
, 'The id of the user we want the requests for'),
694 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
695 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
701 * Handles returning the contact requests for a user.
703 * This also includes the user data necessary to display information
706 * It will not include blocked users.
708 * @param int $userid The id of the user we want to get the contact requests for
709 * @param int $limitfrom
710 * @param int $limitnum
712 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) {
715 // Check if messaging is enabled.
716 if (empty($CFG->messaging
)) {
717 throw new moodle_exception('disabled', 'message');
721 $context = context_system
::instance();
722 self
::validate_context($context);
726 'limitfrom' => $limitfrom,
727 'limitnum' => $limitnum
729 $params = self
::validate_parameters(self
::get_contact_requests_parameters(), $params);
731 $capability = 'moodle/site:manageallmessaging';
732 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
733 throw new required_capability_exception($context, $capability, 'nopermissions', '');
736 return \core_message\api
::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']);
740 * Returns the contact requests return description.
742 * @return external_description
744 public static function get_contact_requests_returns() {
745 return new external_multiple_structure(
746 self
::get_conversation_member_structure()
751 * Returns get conversation members parameters description.
753 * @return external_function_parameters
755 public static function get_conversation_members_parameters() {
756 return new external_function_parameters(
758 'userid' => new external_value(PARAM_INT
, 'The id of the user we are performing this action on behalf of'),
759 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation'),
760 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Do we want to include contact requests?',
761 VALUE_DEFAULT
, false),
762 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
763 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
769 * Returns a list of conversation members.
771 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
772 * @param int $conversationid The id of the conversation
773 * @param bool $includecontactrequests Do we want to include contact requests with this data?
774 * @param int $limitfrom
775 * @param int $limitnum
778 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
779 int $limitfrom = 0, int $limitnum = 0) {
782 // Check if messaging is enabled.
783 if (empty($CFG->messaging
)) {
784 throw new moodle_exception('disabled', 'message');
788 $context = context_system
::instance();
789 self
::validate_context($context);
793 'conversationid' => $conversationid,
794 'includecontactrequests' => $includecontactrequests,
795 'limitfrom' => $limitfrom,
796 'limitnum' => $limitnum
798 $params = self
::validate_parameters(self
::get_conversation_members_parameters(), $params);
800 $capability = 'moodle/site:manageallmessaging';
801 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
802 throw new required_capability_exception($context, $capability, 'nopermissions', '');
805 // The user needs to be a part of the conversation before querying who the members are.
806 if (!\core_message\api
::is_user_in_conversation($params['userid'], $params['conversationid'])) {
807 throw new moodle_exception('You are not a member of this conversation.');
811 return \core_message\api
::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'],
812 $params['limitfrom'], $params['limitnum']);
816 * Returns the get conversation members return description.
818 * @return external_description
820 public static function get_conversation_members_returns() {
821 return new external_multiple_structure(
822 self
::get_conversation_member_structure(true)
827 * Creates a contact request parameters description.
829 * @return external_function_parameters
831 public static function create_contact_request_parameters() {
832 return new external_function_parameters(
834 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
835 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
841 * Creates a contact request.
843 * @param int $userid The id of the user who is creating the contact request
844 * @param int $requesteduserid The id of the user being requested
846 public static function create_contact_request(int $userid, int $requesteduserid) {
849 // Check if messaging is enabled.
850 if (empty($CFG->messaging
)) {
851 throw new moodle_exception('disabled', 'message');
855 $context = context_system
::instance();
856 self
::validate_context($context);
858 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
859 $params = self
::validate_parameters(self
::create_contact_request_parameters(), $params);
861 $capability = 'moodle/site:manageallmessaging';
862 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
863 throw new required_capability_exception($context, $capability, 'nopermissions', '');
870 if (!\core_message\api
::can_create_contact($params['userid'], $params['requesteduserid'])) {
871 $result['warnings'][] = [
873 'itemid' => $params['requesteduserid'],
874 'warningcode' => 'cannotcreatecontactrequest',
875 'message' => 'You are unable to create a contact request for this user'
878 if ($requests = \core_message\api
::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) {
879 // There should only ever be one but just in case there are multiple then we can return the first.
880 $result['request'] = array_shift($requests);
882 $result['request'] = \core_message\api
::create_contact_request($params['userid'], $params['requesteduserid']);
890 * Creates a contact request return description.
892 * @return external_description
894 public static function create_contact_request_returns() {
895 return new external_single_structure(
897 'request' => new external_single_structure(
899 'id' => new external_value(PARAM_INT
, 'Message id'),
900 'userid' => new external_value(PARAM_INT
, 'User from id'),
901 'requesteduserid' => new external_value(PARAM_INT
, 'User to id'),
902 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
907 'warnings' => new external_warnings()
913 * Confirm a contact request parameters description.
915 * @return external_function_parameters
917 public static function confirm_contact_request_parameters() {
918 return new external_function_parameters(
920 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
921 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
927 * Confirm a contact request.
929 * @param int $userid The id of the user who is creating the contact request
930 * @param int $requesteduserid The id of the user being requested
932 public static function confirm_contact_request(int $userid, int $requesteduserid) {
935 // Check if messaging is enabled.
936 if (empty($CFG->messaging
)) {
937 throw new moodle_exception('disabled', 'message');
941 $context = context_system
::instance();
942 self
::validate_context($context);
944 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
945 $params = self
::validate_parameters(self
::confirm_contact_request_parameters(), $params);
947 $capability = 'moodle/site:manageallmessaging';
948 if (($USER->id
!= $params['requesteduserid']) && !has_capability($capability, $context)) {
949 throw new required_capability_exception($context, $capability, 'nopermissions', '');
952 \core_message\api
::confirm_contact_request($params['userid'], $params['requesteduserid']);
958 * Confirm a contact request return description.
960 * @return external_description
962 public static function confirm_contact_request_returns() {
963 return new external_warnings();
967 * Declines a contact request parameters description.
969 * @return external_function_parameters
971 public static function decline_contact_request_parameters() {
972 return new external_function_parameters(
974 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
975 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
981 * Declines a contact request.
983 * @param int $userid The id of the user who is creating the contact request
984 * @param int $requesteduserid The id of the user being requested
986 public static function decline_contact_request(int $userid, int $requesteduserid) {
989 // Check if messaging is enabled.
990 if (empty($CFG->messaging
)) {
991 throw new moodle_exception('disabled', 'message');
995 $context = context_system
::instance();
996 self
::validate_context($context);
998 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
999 $params = self
::validate_parameters(self
::decline_contact_request_parameters(), $params);
1001 $capability = 'moodle/site:manageallmessaging';
1002 if (($USER->id
!= $params['requesteduserid']) && !has_capability($capability, $context)) {
1003 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1006 \core_message\api
::decline_contact_request($params['userid'], $params['requesteduserid']);
1012 * Declines a contact request return description.
1014 * @return external_description
1016 public static function decline_contact_request_returns() {
1017 return new external_warnings();
1021 * Return the structure of a message area contact.
1023 * @return external_single_structure
1026 private static function get_messagearea_contact_structure() {
1027 return new external_single_structure(
1029 'userid' => new external_value(PARAM_INT
, 'The user\'s id'),
1030 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
1031 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
1032 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
1033 'ismessaging' => new external_value(PARAM_BOOL
, 'If we are messaging the user'),
1034 'sentfromcurrentuser' => new external_value(PARAM_BOOL
, 'Was the last message sent from the current user?'),
1035 'lastmessage' => new external_value(PARAM_NOTAGS
, 'The user\'s last message'),
1036 'lastmessagedate' => new external_value(PARAM_INT
, 'Timestamp for last message', VALUE_DEFAULT
, null),
1037 'messageid' => new external_value(PARAM_INT
, 'The unique search message id', VALUE_DEFAULT
, null),
1038 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1039 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1040 'isread' => new external_value(PARAM_BOOL
, 'If the user has read the message'),
1041 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
1042 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
1043 VALUE_DEFAULT
, null),
1049 * Return the structure of a conversation.
1051 * @return external_single_structure
1054 private static function get_conversation_structure() {
1055 return new external_single_structure(
1057 'id' => new external_value(PARAM_INT
, 'The conversation id'),
1058 'name' => new external_value(PARAM_NOTAGS
, 'The conversation name, if set', VALUE_DEFAULT
, null),
1059 'subname' => new external_value(PARAM_NOTAGS
, 'A subtitle for the conversation name, if set', VALUE_DEFAULT
, null),
1060 'imageurl' => new external_value(PARAM_URL
, 'A link to the conversation picture, if set', VALUE_DEFAULT
, null),
1061 'type' => new external_value(PARAM_INT
, 'The type of the conversation (1=individual,2=group)'),
1062 'membercount' => new external_value(PARAM_INT
, 'Total number of conversation members'),
1063 'isfavourite' => new external_value(PARAM_BOOL
, 'If the user marked conversation this conversation as a favourite'),
1064 'isread' => new external_value(PARAM_BOOL
, 'If the user has read all messages in the conversation'),
1065 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
1066 VALUE_DEFAULT
, null),
1067 'members' => new external_multiple_structure(
1068 self
::get_conversation_member_structure(true)
1070 'messages' => new external_multiple_structure(
1071 self
::get_conversation_message_structure()
1078 * Return the structure of a conversation member.
1080 * @param bool $includecontactrequests Are we including contact requests?
1081 * @param bool $includeconversations Are we including conversations?
1082 * @return external_single_structure
1085 private static function get_conversation_member_structure(bool $includecontactrequests = false,
1086 bool $includeconversations = false) {
1088 'id' => new external_value(PARAM_INT
, 'The user id'),
1089 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
1090 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
1091 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
1092 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1093 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1094 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
1095 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?'),
1096 'isdeleted' => new external_value(PARAM_BOOL
, 'Is the user deleted?'),
1097 'canmessage' => new external_value(PARAM_BOOL
, 'If the user can be messaged'),
1098 'requirescontact' => new external_value(PARAM_BOOL
, 'If the user requires to be contacts'),
1101 if ($includecontactrequests) {
1102 $result['contactrequests'] = new external_multiple_structure(
1103 new external_single_structure(
1105 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1106 'userid' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1107 'requesteduserid' => new external_value(PARAM_RAW
, 'The text of the message'),
1108 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1110 ), 'The contact requests', VALUE_OPTIONAL
1114 if ($includeconversations) {
1115 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1117 'id' => new external_value(PARAM_INT
, 'Conversations id'),
1118 'type' => new external_value(PARAM_INT
, 'Conversation type: private or public'),
1119 'name' => new external_value(PARAM_TEXT
, 'Multilang compatible conversation name'. VALUE_OPTIONAL
),
1120 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the conversation'),
1121 ), 'information about conversation', VALUE_OPTIONAL
),
1122 'Conversations between users', VALUE_OPTIONAL
1126 return new external_single_structure(
1132 * Return the structure of a message area message.
1134 * @return external_single_structure
1137 private static function get_conversation_message_structure() {
1138 return new external_single_structure(
1140 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1141 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1142 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
1143 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1149 * Return the structure of a message area message.
1151 * @return external_single_structure
1154 private static function get_messagearea_message_structure() {
1155 return new external_single_structure(
1157 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1158 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1159 'useridto' => new external_value(PARAM_INT
, 'The id of the user who received the message'),
1160 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
1161 'displayblocktime' => new external_value(PARAM_BOOL
, 'Should we display the block time?'),
1162 'blocktime' => new external_value(PARAM_NOTAGS
, 'The time to display above the message'),
1163 'position' => new external_value(PARAM_ALPHA
, 'The position of the text'),
1164 'timesent' => new external_value(PARAM_NOTAGS
, 'The time the message was sent'),
1165 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1166 'isread' => new external_value(PARAM_INT
, 'Determines if the message was read or not'),
1172 * Get messagearea search users in course parameters.
1174 * @deprecated since 3.6
1176 * @return external_function_parameters
1179 public static function data_for_messagearea_search_users_in_course_parameters() {
1180 return new external_function_parameters(
1182 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1183 'courseid' => new external_value(PARAM_INT
, 'The id of the course'),
1184 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1185 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1186 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1192 * Get messagearea search users in course results.
1194 * @deprecated since 3.6
1196 * NOTE: We are deprecating this function but not search_users_in_course API function for backwards compatibility
1197 * with messaging UI. But should be removed once new group messaging UI is in place and old messaging UI is removed.
1198 * Followup: MDL-63915
1200 * @param int $userid The id of the user who is performing the search
1201 * @param int $courseid The id of the course
1202 * @param string $search The string being searched
1203 * @param int $limitfrom
1204 * @param int $limitnum
1206 * @throws moodle_exception
1209 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
1211 global $CFG, $PAGE, $USER;
1213 // Check if messaging is enabled.
1214 if (empty($CFG->messaging
)) {
1215 throw new moodle_exception('disabled', 'message');
1218 $systemcontext = context_system
::instance();
1221 'userid' => $userid,
1222 'courseid' => $courseid,
1223 'search' => $search,
1224 'limitfrom' => $limitfrom,
1225 'limitnum' => $limitnum
1227 $params = self
::validate_parameters(self
::data_for_messagearea_search_users_in_course_parameters(), $params);
1228 self
::validate_context($systemcontext);
1230 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1231 throw new moodle_exception('You do not have permission to perform this action.');
1234 $users = \core_message\api
::search_users_in_course(
1236 $params['courseid'],
1238 $params['limitfrom'],
1241 $results = new \core_message\output\messagearea\
user_search_results($users);
1243 $renderer = $PAGE->get_renderer('core_message');
1244 return $results->export_for_template($renderer);
1248 * Get messagearea search users in course returns.
1250 * @deprecated since 3.6
1252 * @return external_single_structure
1255 public static function data_for_messagearea_search_users_in_course_returns() {
1256 return new external_single_structure(
1258 'contacts' => new external_multiple_structure(
1259 self
::get_messagearea_contact_structure()
1266 * Marking the method as deprecated.
1270 public static function data_for_messagearea_search_users_in_course_is_deprecated() {
1275 * Get messagearea search users parameters.
1277 * @deprecated since 3.6
1279 * @return external_function_parameters
1282 public static function data_for_messagearea_search_users_parameters() {
1283 return new external_function_parameters(
1285 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1286 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1287 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1293 * Get messagearea search users results.
1295 * @deprecated since 3.6
1297 * NOTE: We are deprecating this function but not search_users API function for backwards compatibility
1298 * with messaging UI. But should be removed once new group messaging UI is in place and old messaging UI is removed.
1299 * Followup: MDL-63915
1301 * @param int $userid The id of the user who is performing the search
1302 * @param string $search The string being searched
1303 * @param int $limitnum
1305 * @throws moodle_exception
1308 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
1309 global $CFG, $PAGE, $USER;
1311 // Check if messaging is enabled.
1312 if (empty($CFG->messaging
)) {
1313 throw new moodle_exception('disabled', 'message');
1316 $systemcontext = context_system
::instance();
1319 'userid' => $userid,
1320 'search' => $search,
1321 'limitnum' => $limitnum
1323 $params = self
::validate_parameters(self
::data_for_messagearea_search_users_parameters(), $params);
1324 self
::validate_context($systemcontext);
1326 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1327 throw new moodle_exception('You do not have permission to perform this action.');
1330 list($contacts, $courses, $noncontacts) = \core_message\api
::search_users(
1336 $search = new \core_message\output\messagearea\
user_search_results($contacts, $courses, $noncontacts);
1338 $renderer = $PAGE->get_renderer('core_message');
1339 return $search->export_for_template($renderer);
1343 * Get messagearea search users returns.
1345 * @deprecated since 3.6
1347 * @return external_single_structure
1350 public static function data_for_messagearea_search_users_returns() {
1351 return new external_single_structure(
1353 'contacts' => new external_multiple_structure(
1354 self
::get_messagearea_contact_structure()
1356 'courses' => new external_multiple_structure(
1357 new external_single_structure(
1359 'id' => new external_value(PARAM_INT
, 'The course id'),
1360 'shortname' => new external_value(PARAM_TEXT
, 'The course shortname'),
1361 'fullname' => new external_value(PARAM_TEXT
, 'The course fullname'),
1365 'noncontacts' => new external_multiple_structure(
1366 self
::get_messagearea_contact_structure()
1373 * Marking the method as deprecated.
1377 public static function data_for_messagearea_search_users_is_deprecated() {
1382 * Get messagearea message search users parameters.
1384 * @return external_function_parameters
1387 public static function message_search_users_parameters() {
1388 return new external_function_parameters(
1390 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1391 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1392 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1393 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1399 * Get search users results.
1401 * @param int $userid The id of the user who is performing the search
1402 * @param string $search The string being searched
1403 * @param int $limitfrom
1404 * @param int $limitnum
1406 * @throws moodle_exception
1409 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
1412 $systemcontext = context_system
::instance();
1415 'userid' => $userid,
1416 'search' => $search,
1417 'limitfrom' => $limitfrom,
1418 'limitnum' => $limitnum
1420 $params = self
::validate_parameters(self
::message_search_users_parameters(), $params);
1421 self
::validate_context($systemcontext);
1423 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1424 throw new moodle_exception('You do not have permission to perform this action.');
1427 list($contacts, $noncontacts) = \core_message\api
::message_search_users(
1430 $params['limitfrom'],
1431 $params['limitnum']);
1433 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1437 * Get messagearea message search users returns.
1439 * @return external_single_structure
1442 public static function message_search_users_returns() {
1443 return new external_single_structure(
1445 'contacts' => new external_multiple_structure(
1446 self
::get_conversation_member_structure(false, true)
1448 'noncontacts' => new external_multiple_structure(
1449 self
::get_conversation_member_structure(false, true)
1456 * Get messagearea search messages parameters.
1458 * @return external_function_parameters
1461 public static function data_for_messagearea_search_messages_parameters() {
1462 return new external_function_parameters(
1464 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1465 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1466 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1467 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1473 * Get messagearea search messages results.
1475 * @param int $userid The id of the user who is performing the search
1476 * @param string $search The string being searched
1477 * @param int $limitfrom
1478 * @param int $limitnum
1480 * @throws moodle_exception
1483 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1484 global $CFG, $PAGE, $USER;
1486 // Check if messaging is enabled.
1487 if (empty($CFG->messaging
)) {
1488 throw new moodle_exception('disabled', 'message');
1491 $systemcontext = context_system
::instance();
1494 'userid' => $userid,
1495 'search' => $search,
1496 'limitfrom' => $limitfrom,
1497 'limitnum' => $limitnum
1500 $params = self
::validate_parameters(self
::data_for_messagearea_search_messages_parameters(), $params);
1501 self
::validate_context($systemcontext);
1503 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1504 throw new moodle_exception('You do not have permission to perform this action.');
1507 $messages = \core_message\api
::search_messages(
1510 $params['limitfrom'],
1513 $results = new \core_message\output\messagearea\
message_search_results($messages);
1515 $renderer = $PAGE->get_renderer('core_message');
1516 return $results->export_for_template($renderer);
1520 * Get messagearea search messages returns.
1522 * @return external_single_structure
1525 public static function data_for_messagearea_search_messages_returns() {
1526 return new external_single_structure(
1528 'contacts' => new external_multiple_structure(
1529 self
::get_messagearea_contact_structure()
1536 * Get conversations parameters.
1538 * @return external_function_parameters
1541 public static function get_conversations_parameters() {
1542 return new external_function_parameters(
1544 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1545 'limitfrom' => new external_value(PARAM_INT
, 'The offset to start at', VALUE_DEFAULT
, 0),
1546 'limitnum' => new external_value(PARAM_INT
, 'Limit number of conversations to this', VALUE_DEFAULT
, 0),
1547 'type' => new external_value(PARAM_INT
, 'Filter by type', VALUE_DEFAULT
, null),
1548 'favourites' => new external_value(PARAM_BOOL
, 'Whether to restrict the results to contain NO favourite
1549 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1550 VALUE_DEFAULT
, null),
1557 * Get the list of conversations for the user.
1559 * @param int $userid The id of the user who is performing the search
1560 * @param int $limitfrom
1561 * @param int $limitnum
1562 * @param int|null $type
1563 * @param bool|null $favourites
1565 * @throws \moodle_exception if the messaging feature is disabled on the site.
1568 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null) {
1571 // All the standard BL checks.
1572 if (empty($CFG->messaging
)) {
1573 throw new moodle_exception('disabled', 'message');
1577 'userid' => $userid,
1578 'limitfrom' => $limitfrom,
1579 'limitnum' => $limitnum,
1581 'favourites' => $favourites
1583 $params = self
::validate_parameters(self
::get_conversations_parameters(), $params);
1585 $systemcontext = context_system
::instance();
1586 self
::validate_context($systemcontext);
1588 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1589 throw new moodle_exception('You do not have permission to perform this action.');
1592 $conversations = \core_message\api
::get_conversations(
1594 $params['limitfrom'],
1595 $params['limitnum'],
1597 $params['favourites']
1600 return (object) ['conversations' => $conversations];
1604 * Get conversations returns.
1606 * @return external_single_structure
1609 public static function get_conversations_returns() {
1610 return new external_single_structure(
1612 'conversations' => new external_multiple_structure(
1613 self
::get_conversation_structure(true)
1620 * Get conversation parameters.
1622 * @return external_function_parameters
1624 public static function get_conversation_parameters() {
1625 return new external_function_parameters(
1627 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1628 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation to fetch'),
1629 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Include contact requests in the members'),
1630 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Include privacy info in the members'),
1631 'memberlimit' => new external_value(PARAM_INT
, 'Limit for number of members', VALUE_DEFAULT
, 0),
1632 'memberoffset' => new external_value(PARAM_INT
, 'Offset for member list', VALUE_DEFAULT
, 0),
1633 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1634 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1635 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1641 * Get a single conversation.
1643 * @param int $userid The user id to get the conversation for
1644 * @param int $conversationid The id of the conversation to fetch
1645 * @param bool $includecontactrequests Should contact requests be included between members
1646 * @param bool $includeprivacyinfo Should privacy info be included between members
1647 * @param int $memberlimit Limit number of members to load
1648 * @param int $memberoffset Offset members by this amount
1649 * @param int $messagelimit Limit number of messages to load
1650 * @param int $messageoffset Offset the messages
1651 * @param bool $newestmessagesfirst Order messages by newest first
1653 * @throws \moodle_exception if the messaging feature is disabled on the site.
1655 public static function get_conversation(
1657 int $conversationid,
1658 bool $includecontactrequests = false,
1659 bool $includeprivacyinfo = false,
1660 int $memberlimit = 0,
1661 int $memberoffset = 0,
1662 int $messagelimit = 0,
1663 int $messageoffset = 0,
1664 bool $newestmessagesfirst = true
1666 global $CFG, $DB, $USER;
1668 // All the standard BL checks.
1669 if (empty($CFG->messaging
)) {
1670 throw new moodle_exception('disabled', 'message');
1674 'userid' => $userid,
1675 'conversationid' => $conversationid,
1676 'includecontactrequests' => $includecontactrequests,
1677 'includeprivacyinfo' => $includeprivacyinfo,
1678 'memberlimit' => $memberlimit,
1679 'memberoffset' => $memberoffset,
1680 'messagelimit' => $messagelimit,
1681 'messageoffset' => $messageoffset,
1682 'newestmessagesfirst' => $newestmessagesfirst
1684 self
::validate_parameters(self
::get_conversation_parameters(), $params);
1686 $systemcontext = context_system
::instance();
1687 self
::validate_context($systemcontext);
1689 $conversation = \core_message\api
::get_conversation(
1691 $params['conversationid'],
1692 $params['includecontactrequests'],
1693 $params['includeprivacyinfo'],
1694 $params['memberlimit'],
1695 $params['memberoffset'],
1696 $params['messagelimit'],
1697 $params['messageoffset'],
1698 $params['newestmessagesfirst']
1701 if ($conversation) {
1702 return $conversation;
1704 // We have to throw an exception here because the external functions annoyingly
1705 // don't accept null to be returned for a single structure.
1706 throw new \
moodle_exception('Conversation does not exist');
1711 * Get conversation returns.
1713 * @return external_single_structure
1715 public static function get_conversation_returns() {
1716 return self
::get_conversation_structure();
1720 * Get conversation parameters.
1722 * @return external_function_parameters
1724 public static function get_conversation_between_users_parameters() {
1725 return new external_function_parameters(
1727 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1728 'otheruserid' => new external_value(PARAM_INT
, 'The other user id'),
1729 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Include contact requests in the members'),
1730 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Include privacy info in the members'),
1731 'memberlimit' => new external_value(PARAM_INT
, 'Limit for number of members', VALUE_DEFAULT
, 0),
1732 'memberoffset' => new external_value(PARAM_INT
, 'Offset for member list', VALUE_DEFAULT
, 0),
1733 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1734 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1735 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1741 * Get a single conversation between users.
1743 * @param int $userid The user id to get the conversation for
1744 * @param int $otheruserid The other user id
1745 * @param bool $includecontactrequests Should contact requests be included between members
1746 * @param bool $includeprivacyinfo Should privacy info be included between members
1747 * @param int $memberlimit Limit number of members to load
1748 * @param int $memberoffset Offset members by this amount
1749 * @param int $messagelimit Limit number of messages to load
1750 * @param int $messageoffset Offset the messages
1751 * @param bool $newestmessagesfirst Order messages by newest first
1753 * @throws \moodle_exception if the messaging feature is disabled on the site.
1755 public static function get_conversation_between_users(
1758 bool $includecontactrequests = false,
1759 bool $includeprivacyinfo = false,
1760 int $memberlimit = 0,
1761 int $memberoffset = 0,
1762 int $messagelimit = 0,
1763 int $messageoffset = 0,
1764 bool $newestmessagesfirst = true
1766 global $CFG, $DB, $USER;
1768 // All the standard BL checks.
1769 if (empty($CFG->messaging
)) {
1770 throw new moodle_exception('disabled', 'message');
1774 'userid' => $userid,
1775 'otheruserid' => $otheruserid,
1776 'includecontactrequests' => $includecontactrequests,
1777 'includeprivacyinfo' => $includeprivacyinfo,
1778 'memberlimit' => $memberlimit,
1779 'memberoffset' => $memberoffset,
1780 'messagelimit' => $messagelimit,
1781 'messageoffset' => $messageoffset,
1782 'newestmessagesfirst' => $newestmessagesfirst
1784 self
::validate_parameters(self
::get_conversation_between_users_parameters(), $params);
1786 $systemcontext = context_system
::instance();
1787 self
::validate_context($systemcontext);
1789 $conversationid = \core_message\api
::get_conversation_between_users([$params['userid'], $params['otheruserid']]);
1790 $conversation = null;
1792 if ($conversationid) {
1793 $conversation = \core_message\api
::get_conversation(
1796 $params['includecontactrequests'],
1797 $params['includeprivacyinfo'],
1798 $params['memberlimit'],
1799 $params['memberoffset'],
1800 $params['messagelimit'],
1801 $params['messageoffset'],
1802 $params['newestmessagesfirst']
1806 if ($conversation) {
1807 return $conversation;
1809 // We have to throw an exception here because the external functions annoyingly
1810 // don't accept null to be returned for a single structure.
1811 throw new \
moodle_exception('Conversation does not exist');
1816 * Get conversation returns.
1818 * @return external_single_structure
1820 public static function get_conversation_between_users_returns() {
1821 return self
::get_conversation_structure(true);
1825 * The messagearea conversations parameters.
1827 * @deprecated since 3.6
1828 * @return external_function_parameters
1831 public static function data_for_messagearea_conversations_parameters() {
1832 return new external_function_parameters(
1834 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1835 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1836 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1842 * Get messagearea conversations.
1844 * NOTE FOR FINAL DEPRECATION:
1845 * When removing this method, please also consider removal of get_conversations_legacy_formatter()
1846 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data
1847 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be
1850 * @deprecated since 3.6
1851 * @param int $userid The id of the user who we are viewing conversations for
1852 * @param int $limitfrom
1853 * @param int $limitnum
1855 * @throws moodle_exception
1858 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
1859 global $CFG, $PAGE, $USER;
1861 // Check if messaging is enabled.
1862 if (empty($CFG->messaging
)) {
1863 throw new moodle_exception('disabled', 'message');
1866 $systemcontext = context_system
::instance();
1869 'userid' => $userid,
1870 'limitfrom' => $limitfrom,
1871 'limitnum' => $limitnum
1873 $params = self
::validate_parameters(self
::data_for_messagearea_conversations_parameters(), $params);
1874 self
::validate_context($systemcontext);
1876 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1877 throw new moodle_exception('You do not have permission to perform this action.');
1880 $conversations = \core_message\api
::get_conversations($params['userid'], $params['limitfrom'], $params['limitnum']);
1882 // Format the conversations in the legacy style, as the get_conversations method has since been changed.
1883 $conversations = \core_message\helper
::get_conversations_legacy_formatter($conversations);
1885 $conversations = new \core_message\output\messagearea\
contacts(null, $conversations);
1887 $renderer = $PAGE->get_renderer('core_message');
1888 return $conversations->export_for_template($renderer);
1892 * The messagearea conversations return structure.
1894 * @deprecated since 3.6
1895 * @return external_single_structure
1898 public static function data_for_messagearea_conversations_returns() {
1899 return new external_single_structure(
1901 'contacts' => new external_multiple_structure(
1902 self
::get_messagearea_contact_structure()
1909 * Marking the method as deprecated.
1913 public static function data_for_messagearea_conversations_is_deprecated() {
1918 * The messagearea contacts return parameters.
1920 * @deprecated since 3.6
1921 * @return external_function_parameters
1924 public static function data_for_messagearea_contacts_parameters() {
1925 return self
::data_for_messagearea_conversations_parameters();
1929 * Get messagearea contacts parameters.
1931 * @deprecated since 3.6
1932 * @param int $userid The id of the user who we are viewing conversations for
1933 * @param int $limitfrom
1934 * @param int $limitnum
1936 * @throws moodle_exception
1939 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
1940 global $CFG, $PAGE, $USER;
1942 // Check if messaging is enabled.
1943 if (empty($CFG->messaging
)) {
1944 throw new moodle_exception('disabled', 'message');
1947 $systemcontext = context_system
::instance();
1950 'userid' => $userid,
1951 'limitfrom' => $limitfrom,
1952 'limitnum' => $limitnum
1954 $params = self
::validate_parameters(self
::data_for_messagearea_contacts_parameters(), $params);
1955 self
::validate_context($systemcontext);
1957 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1958 throw new moodle_exception('You do not have permission to perform this action.');
1961 $contacts = \core_message\api
::get_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
1962 $contacts = new \core_message\output\messagearea\
contacts(null, $contacts);
1964 $renderer = $PAGE->get_renderer('core_message');
1965 return $contacts->export_for_template($renderer);
1969 * The messagearea contacts return structure.
1971 * @deprecated since 3.6
1972 * @return external_single_structure
1975 public static function data_for_messagearea_contacts_returns() {
1976 return self
::data_for_messagearea_conversations_returns();
1980 * Marking the method as deprecated.
1984 public static function data_for_messagearea_contacts_is_deprecated() {
1989 * The messagearea messages parameters.
1991 * @deprecated since 3.6
1992 * @return external_function_parameters
1995 public static function data_for_messagearea_messages_parameters() {
1996 return new external_function_parameters(
1998 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1999 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
2000 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
2001 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
2002 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
2003 'timefrom' => new external_value(PARAM_INT
,
2004 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
2010 * Get messagearea messages.
2012 * @deprecated since 3.6
2013 * @param int $currentuserid The current user's id
2014 * @param int $otheruserid The other user's id
2015 * @param int $limitfrom
2016 * @param int $limitnum
2017 * @param boolean $newest
2019 * @throws moodle_exception
2022 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
2023 $newest = false, $timefrom = 0) {
2024 global $CFG, $PAGE, $USER;
2026 // Check if messaging is enabled.
2027 if (empty($CFG->messaging
)) {
2028 throw new moodle_exception('disabled', 'message');
2031 $systemcontext = context_system
::instance();
2034 'currentuserid' => $currentuserid,
2035 'otheruserid' => $otheruserid,
2036 'limitfrom' => $limitfrom,
2037 'limitnum' => $limitnum,
2038 'newest' => $newest,
2039 'timefrom' => $timefrom,
2041 $params = self
::validate_parameters(self
::data_for_messagearea_messages_parameters(), $params);
2042 self
::validate_context($systemcontext);
2044 if (($USER->id
!= $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2045 throw new moodle_exception('You do not have permission to perform this action.');
2048 if ($params['newest']) {
2049 $sort = 'timecreated DESC';
2051 $sort = 'timecreated ASC';
2054 // We need to enforce a one second delay on messages to avoid race conditions of current
2055 // messages still being sent.
2057 // There is a chance that we could request messages before the current time's
2058 // second has elapsed and while other messages are being sent in that same second. In which
2059 // case those messages will be lost.
2061 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
2062 if (!empty($params['timefrom'])) {
2063 $timeto = time() - 1;
2068 // No requesting messages from the current time, as stated above.
2069 if ($params['timefrom'] == time()) {
2072 $messages = \core_message\api
::get_messages($params['currentuserid'], $params['otheruserid'], $params['limitfrom'],
2073 $params['limitnum'], $sort, $params['timefrom'], $timeto);
2076 $messages = new \core_message\output\messagearea\
messages($params['currentuserid'], $params['otheruserid'], $messages);
2078 $renderer = $PAGE->get_renderer('core_message');
2079 return $messages->export_for_template($renderer);
2083 * The messagearea messages return structure.
2085 * @deprecated since 3.6
2086 * @return external_single_structure
2089 public static function data_for_messagearea_messages_returns() {
2090 return new external_single_structure(
2092 'iscurrentuser' => new external_value(PARAM_BOOL
, 'Is the currently logged in user the user we are viewing
2093 the messages on behalf of?'),
2094 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
2095 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
2096 'otheruserfullname' => new external_value(PARAM_NOTAGS
, 'The other user\'s fullname'),
2097 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
2098 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
2099 'messages' => new external_multiple_structure(
2100 self
::get_messagearea_message_structure()
2102 'isblocked' => new external_value(PARAM_BOOL
, 'Is this user blocked by the current user?', VALUE_DEFAULT
, false),
2108 * Marking the method as deprecated.
2112 public static function data_for_messagearea_messages_is_deprecated() {
2117 * The conversation messages parameters.
2119 * @return external_function_parameters
2122 public static function get_conversation_messages_parameters() {
2123 return new external_function_parameters(
2125 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
2126 'convid' => new external_value(PARAM_INT
, 'The conversation id'),
2127 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
2128 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
2129 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
2130 'timefrom' => new external_value(PARAM_INT
,
2131 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
2137 * Get conversation messages.
2139 * @param int $currentuserid The current user's id.
2140 * @param int $convid The conversation id.
2141 * @param int $limitfrom Return a subset of records, starting at this point (optional).
2142 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
2143 * @param bool $newest True for getting first newest messages, false otherwise.
2144 * @param int $timefrom The time from the conversation messages to get.
2145 * @return stdClass The messages and members who have sent some of these messages.
2146 * @throws moodle_exception
2149 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
2150 bool $newest = false, int $timefrom = 0) {
2151 global $CFG, $PAGE, $USER;
2153 // Check if messaging is enabled.
2154 if (empty($CFG->messaging
)) {
2155 throw new moodle_exception('disabled', 'message');
2158 $systemcontext = context_system
::instance();
2161 'currentuserid' => $currentuserid,
2162 'convid' => $convid,
2163 'limitfrom' => $limitfrom,
2164 'limitnum' => $limitnum,
2165 'newest' => $newest,
2166 'timefrom' => $timefrom,
2168 $params = self
::validate_parameters(self
::get_conversation_messages_parameters(), $params);
2169 self
::validate_context($systemcontext);
2171 if (($USER->id
!= $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2172 throw new moodle_exception('You do not have permission to perform this action.');
2175 $sort = $newest ?
'timecreated DESC' : 'timecreated ASC';
2177 // We need to enforce a one second delay on messages to avoid race conditions of current
2178 // messages still being sent.
2180 // There is a chance that we could request messages before the current time's
2181 // second has elapsed and while other messages are being sent in that same second. In which
2182 // case those messages will be lost.
2184 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
2185 $timeto = empty($params['timefrom']) ?
0 : time() - 1;
2187 // No requesting messages from the current time, as stated above.
2188 if ($params['timefrom'] == time()) {
2191 $messages = \core_message\api
::get_conversation_messages(
2192 $params['currentuserid'],
2194 $params['limitfrom'],
2195 $params['limitnum'],
2197 $params['timefrom'],
2205 * The messagearea messages return structure.
2207 * @return external_single_structure
2210 public static function get_conversation_messages_returns() {
2211 return new external_single_structure(
2213 'id' => new external_value(PARAM_INT
, 'The conversation id'),
2214 'members' => new external_multiple_structure(
2215 self
::get_conversation_member_structure()
2217 'messages' => new external_multiple_structure(
2218 self
::get_conversation_message_structure()
2225 * The get most recent message return parameters.
2227 * @deprecated since 3.6
2228 * @return external_function_parameters
2231 public static function data_for_messagearea_get_most_recent_message_parameters() {
2232 return new external_function_parameters(
2234 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
2235 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
2241 * Get the most recent message in a conversation.
2243 * @deprecated since 3.6
2244 * @param int $currentuserid The current user's id
2245 * @param int $otheruserid The other user's id
2247 * @throws moodle_exception
2250 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
2251 global $CFG, $PAGE, $USER;
2253 // Check if messaging is enabled.
2254 if (empty($CFG->messaging
)) {
2255 throw new moodle_exception('disabled', 'message');
2258 $systemcontext = context_system
::instance();
2261 'currentuserid' => $currentuserid,
2262 'otheruserid' => $otheruserid
2264 $params = self
::validate_parameters(self
::data_for_messagearea_get_most_recent_message_parameters(), $params);
2265 self
::validate_context($systemcontext);
2267 if (($USER->id
!= $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2268 throw new moodle_exception('You do not have permission to perform this action.');
2271 $message = \core_message\api
::get_most_recent_message($params['currentuserid'], $params['otheruserid']);
2272 $message = new \core_message\output\messagearea\
message($message);
2274 $renderer = $PAGE->get_renderer('core_message');
2275 return $message->export_for_template($renderer);
2279 * The get most recent message return structure.
2281 * @deprecated since 3.6
2282 * @return external_single_structure
2285 public static function data_for_messagearea_get_most_recent_message_returns() {
2286 return self
::get_messagearea_message_structure();
2290 * Marking the method as deprecated.
2294 public static function data_for_messagearea_get_most_recent_message_is_deprecated() {
2299 * The get profile parameters.
2301 * @deprecated since 3.6
2302 * @return external_function_parameters
2305 public static function data_for_messagearea_get_profile_parameters() {
2306 return new external_function_parameters(
2308 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
2309 'otheruserid' => new external_value(PARAM_INT
, 'The id of the user whose profile we want to view'),
2315 * Get the profile information for a contact.
2317 * @deprecated since 3.6
2318 * @param int $currentuserid The current user's id
2319 * @param int $otheruserid The id of the user whose profile we are viewing
2321 * @throws moodle_exception
2324 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
2325 global $CFG, $PAGE, $USER;
2327 // Check if messaging is enabled.
2328 if (empty($CFG->messaging
)) {
2329 throw new moodle_exception('disabled', 'message');
2332 $systemcontext = context_system
::instance();
2335 'currentuserid' => $currentuserid,
2336 'otheruserid' => $otheruserid
2338 $params = self
::validate_parameters(self
::data_for_messagearea_get_profile_parameters(), $params);
2339 self
::validate_context($systemcontext);
2341 if (($USER->id
!= $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2342 throw new moodle_exception('You do not have permission to perform this action.');
2345 $profile = \core_message\api
::get_profile($params['currentuserid'], $params['otheruserid']);
2346 $profile = new \core_message\output\messagearea\
profile($profile);
2348 $renderer = $PAGE->get_renderer('core_message');
2349 return $profile->export_for_template($renderer);
2353 * The get profile return structure.
2355 * @deprecated since 3.6
2356 * @return external_single_structure
2359 public static function data_for_messagearea_get_profile_returns() {
2360 return new external_single_structure(
2362 'userid' => new external_value(PARAM_INT
, 'The id of the user whose profile we are viewing'),
2363 'email' => new external_value(core_user
::get_property_type('email'), 'An email address'),
2364 'country' => new external_value(PARAM_TEXT
, 'Home country of the user'),
2365 'city' => new external_value(core_user
::get_property_type('city'), 'Home city of the user'),
2366 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
2367 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
2368 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
2369 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
2370 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
2371 'isblocked' => new external_value(PARAM_BOOL
, 'Is the user blocked?'),
2372 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?')
2378 * Marking the method as deprecated.
2382 public static function data_for_messagearea_get_profile_is_deprecated() {
2387 * Get contacts parameters description.
2389 * @return external_function_parameters
2392 public static function get_contacts_parameters() {
2393 return new external_function_parameters(array());
2399 * @return external_description
2402 public static function get_contacts() {
2403 global $CFG, $PAGE, $USER;
2405 // Check if messaging is enabled.
2406 if (empty($CFG->messaging
)) {
2407 throw new moodle_exception('disabled', 'message');
2410 require_once($CFG->dirroot
. '/user/lib.php');
2412 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
2413 $contacts = \core_message\api
::get_contacts_with_unread_message_count($USER->id
);
2414 foreach ($contacts as $contact) {
2417 if (\core_message\helper
::is_online($contact->lastaccess
)) {
2421 $newcontact = array(
2422 'id' => $contact->id
,
2423 'fullname' => fullname($contact),
2424 'unread' => $contact->messagecount
2427 $userpicture = new user_picture($contact);
2428 $userpicture->size
= 1; // Size f1.
2429 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2430 $userpicture->size
= 0; // Size f2.
2431 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2433 $allcontacts[$mode][$contact->id
] = $newcontact;
2436 $strangers = \core_message\api
::get_non_contacts_with_unread_message_count($USER->id
);
2437 foreach ($strangers as $contact) {
2438 $newcontact = array(
2439 'id' => $contact->id
,
2440 'fullname' => fullname($contact),
2441 'unread' => $contact->messagecount
2444 $userpicture = new user_picture($contact);
2445 $userpicture->size
= 1; // Size f1.
2446 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2447 $userpicture->size
= 0; // Size f2.
2448 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2450 $allcontacts['strangers'][$contact->id
] = $newcontact;
2453 // Add noreply user and support user to the list, if they don't exist.
2454 $supportuser = core_user
::get_support_user();
2455 if (!isset($strangers[$supportuser->id
]) && !$supportuser->deleted
) {
2456 $supportuser->messagecount
= message_count_unread_messages($USER, $supportuser);
2457 if ($supportuser->messagecount
> 0) {
2458 $supportuser->fullname
= fullname($supportuser);
2459 $supportuser->unread
= $supportuser->messagecount
;
2460 $allcontacts['strangers'][$supportuser->id
] = $supportuser;
2464 $noreplyuser = core_user
::get_noreply_user();
2465 if (!isset($strangers[$noreplyuser->id
]) && !$noreplyuser->deleted
) {
2466 $noreplyuser->messagecount
= message_count_unread_messages($USER, $noreplyuser);
2467 if ($noreplyuser->messagecount
> 0) {
2468 $noreplyuser->fullname
= fullname($noreplyuser);
2469 $noreplyuser->unread
= $noreplyuser->messagecount
;
2470 $allcontacts['strangers'][$noreplyuser->id
] = $noreplyuser;
2474 return $allcontacts;
2478 * Get contacts return description.
2480 * @return external_description
2483 public static function get_contacts_returns() {
2484 return new external_single_structure(
2486 'online' => new external_multiple_structure(
2487 new external_single_structure(
2489 'id' => new external_value(PARAM_INT
, 'User ID'),
2490 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2491 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
2492 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
2493 'unread' => new external_value(PARAM_INT
, 'Unread message count')
2496 'List of online contacts'
2498 'offline' => new external_multiple_structure(
2499 new external_single_structure(
2501 'id' => new external_value(PARAM_INT
, 'User ID'),
2502 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2503 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
2504 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
2505 'unread' => new external_value(PARAM_INT
, 'Unread message count')
2508 'List of offline contacts'
2510 'strangers' => new external_multiple_structure(
2511 new external_single_structure(
2513 'id' => new external_value(PARAM_INT
, 'User ID'),
2514 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2515 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
2516 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
2517 'unread' => new external_value(PARAM_INT
, 'Unread message count')
2520 'List of users that are not in the user\'s contact list but have sent a message'
2527 * Search contacts parameters description.
2529 * @return external_function_parameters
2532 public static function search_contacts_parameters() {
2533 return new external_function_parameters(
2535 'searchtext' => new external_value(PARAM_CLEAN
, 'String the user\'s fullname has to match to be found'),
2536 'onlymycourses' => new external_value(PARAM_BOOL
, 'Limit search to the user\'s courses',
2537 VALUE_DEFAULT
, false)
2545 * @param string $searchtext query string.
2546 * @param bool $onlymycourses limit the search to the user's courses only.
2547 * @return external_description
2550 public static function search_contacts($searchtext, $onlymycourses = false) {
2551 global $CFG, $USER, $PAGE;
2552 require_once($CFG->dirroot
. '/user/lib.php');
2554 // Check if messaging is enabled.
2555 if (empty($CFG->messaging
)) {
2556 throw new moodle_exception('disabled', 'message');
2559 require_once($CFG->libdir
. '/enrollib.php');
2561 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
2562 $params = self
::validate_parameters(self
::search_contacts_parameters(), $params);
2564 // Extra validation, we do not allow empty queries.
2565 if ($params['searchtext'] === '') {
2566 throw new moodle_exception('querystringcannotbeempty');
2569 $courseids = array();
2570 if ($params['onlymycourses']) {
2571 $mycourses = enrol_get_my_courses(array('id'));
2572 foreach ($mycourses as $mycourse) {
2573 $courseids[] = $mycourse->id
;
2576 $courseids[] = SITEID
;
2579 // Retrieving the users matching the query.
2580 $users = message_search_users($courseids, $params['searchtext']);
2582 foreach ($users as $user) {
2583 $results[$user->id
] = $user;
2586 // Reorganising information.
2587 foreach ($results as &$user) {
2590 'fullname' => fullname($user)
2593 // Avoid undefined property notice as phone not specified.
2594 $user->phone1
= null;
2595 $user->phone2
= null;
2597 $userpicture = new user_picture($user);
2598 $userpicture->size
= 1; // Size f1.
2599 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2600 $userpicture->size
= 0; // Size f2.
2601 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2610 * Search contacts return description.
2612 * @return external_description
2615 public static function search_contacts_returns() {
2616 return new external_multiple_structure(
2617 new external_single_structure(
2619 'id' => new external_value(PARAM_INT
, 'User ID'),
2620 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2621 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
2622 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
)
2630 * Get messages parameters description.
2632 * @return external_function_parameters
2635 public static function get_messages_parameters() {
2636 return new external_function_parameters(
2638 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2639 'useridfrom' => new external_value(
2640 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2642 'type' => new external_value(
2643 PARAM_ALPHA
, 'type of message to return, expected values are: notifications, conversations and both',
2644 VALUE_DEFAULT
, 'both'),
2645 'read' => new external_value(PARAM_BOOL
, 'true for getting read messages, false for unread', VALUE_DEFAULT
, true),
2646 'newestfirst' => new external_value(
2647 PARAM_BOOL
, 'true for ordering by newest first, false for oldest first',
2648 VALUE_DEFAULT
, true),
2649 'limitfrom' => new external_value(PARAM_INT
, 'limit from', VALUE_DEFAULT
, 0),
2650 'limitnum' => new external_value(PARAM_INT
, 'limit number', VALUE_DEFAULT
, 0)
2656 * Get messages function implementation.
2659 * @throws invalid_parameter_exception
2660 * @throws moodle_exception
2661 * @param int $useridto the user id who received the message
2662 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2663 * @param string $type type of message to return, expected values: notifications, conversations and both
2664 * @param bool $read true for retreiving read messages, false for unread
2665 * @param bool $newestfirst true for ordering by newest first, false for oldest first
2666 * @param int $limitfrom limit from
2667 * @param int $limitnum limit num
2668 * @return external_description
2670 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
2671 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
2674 $warnings = array();
2677 'useridto' => $useridto,
2678 'useridfrom' => $useridfrom,
2681 'newestfirst' => $newestfirst,
2682 'limitfrom' => $limitfrom,
2683 'limitnum' => $limitnum
2686 $params = self
::validate_parameters(self
::get_messages_parameters(), $params);
2688 $context = context_system
::instance();
2689 self
::validate_context($context);
2691 $useridto = $params['useridto'];
2692 $useridfrom = $params['useridfrom'];
2693 $type = $params['type'];
2694 $read = $params['read'];
2695 $newestfirst = $params['newestfirst'];
2696 $limitfrom = $params['limitfrom'];
2697 $limitnum = $params['limitnum'];
2699 $allowedvalues = array('notifications', 'conversations', 'both');
2700 if (!in_array($type, $allowedvalues)) {
2701 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
2702 'allowed values are: ' . implode(',', $allowedvalues));
2705 // Check if private messaging between users is allowed.
2706 if (empty($CFG->messaging
)) {
2707 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
2708 if ($type == "conversations") {
2709 throw new moodle_exception('disabled', 'message');
2711 if ($type == "both") {
2713 $warning['item'] = 'message';
2714 $warning['itemid'] = $USER->id
;
2715 $warning['warningcode'] = '1';
2716 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
2717 Only notifications will be returned';
2718 $warnings[] = $warning;
2722 if (!empty($useridto)) {
2723 if (core_user
::is_real_user($useridto)) {
2724 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2726 throw new moodle_exception('invaliduser');
2730 if (!empty($useridfrom)) {
2731 // We use get_user here because the from user can be the noreply or support user.
2732 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2735 // Check if the current user is the sender/receiver or just a privileged user.
2736 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2737 !has_capability('moodle/site:readallmessages', $context)) {
2738 throw new moodle_exception('accessdenied', 'admin');
2741 // Which type of messages to retrieve.
2742 $notifications = -1;
2743 if ($type != 'both') {
2744 $notifications = ($type == 'notifications') ?
1 : 0;
2747 $orderdirection = $newestfirst ?
'DESC' : 'ASC';
2748 $sort = "mr.timecreated $orderdirection";
2750 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
2751 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
2753 // In some cases, we don't need to get the to/from user objects from the sql query.
2754 $userfromfullname = '';
2755 $usertofullname = '';
2757 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
2758 if (!empty($useridto)) {
2759 $usertofullname = fullname($userto, $canviewfullname);
2760 // The user from may or may not be filled.
2761 if (!empty($useridfrom)) {
2762 $userfromfullname = fullname($userfrom, $canviewfullname);
2765 // If the useridto field is empty, the useridfrom must be filled.
2766 $userfromfullname = fullname($userfrom, $canviewfullname);
2768 foreach ($messages as $mid => $message) {
2770 // Do not return deleted messages.
2771 if (!$message->notification
) {
2772 if (($useridto == $USER->id
and $message->timeusertodeleted
) or
2773 ($useridfrom == $USER->id
and $message->timeuserfromdeleted
)) {
2774 unset($messages[$mid]);
2779 // We need to get the user from the query.
2780 if (empty($userfromfullname)) {
2781 // Check for non-reply and support users.
2782 if (core_user
::is_real_user($message->useridfrom
)) {
2783 $user = new stdClass();
2784 $user = username_load_fields_from_object($user, $message, 'userfrom');
2785 $message->userfromfullname
= fullname($user, $canviewfullname);
2787 $user = core_user
::get_user($message->useridfrom
);
2788 $message->userfromfullname
= fullname($user, $canviewfullname);
2791 $message->userfromfullname
= $userfromfullname;
2794 // We need to get the user from the query.
2795 if (empty($usertofullname)) {
2796 $user = new stdClass();
2797 $user = username_load_fields_from_object($user, $message, 'userto');
2798 $message->usertofullname
= fullname($user, $canviewfullname);
2800 $message->usertofullname
= $usertofullname;
2803 $message->text
= message_format_message_text($message);
2804 $messages[$mid] = (array) $message;
2809 'messages' => $messages,
2810 'warnings' => $warnings
2817 * Get messages return description.
2819 * @return external_single_structure
2822 public static function get_messages_returns() {
2823 return new external_single_structure(
2825 'messages' => new external_multiple_structure(
2826 new external_single_structure(
2828 'id' => new external_value(PARAM_INT
, 'Message id'),
2829 'useridfrom' => new external_value(PARAM_INT
, 'User from id'),
2830 'useridto' => new external_value(PARAM_INT
, 'User to id'),
2831 'subject' => new external_value(PARAM_TEXT
, 'The message subject'),
2832 'text' => new external_value(PARAM_RAW
, 'The message text formated'),
2833 'fullmessage' => new external_value(PARAM_RAW
, 'The message'),
2834 'fullmessageformat' => new external_format_value('fullmessage'),
2835 'fullmessagehtml' => new external_value(PARAM_RAW
, 'The message in html'),
2836 'smallmessage' => new external_value(PARAM_RAW
, 'The shorten message'),
2837 'notification' => new external_value(PARAM_INT
, 'Is a notification?'),
2838 'contexturl' => new external_value(PARAM_RAW
, 'Context URL'),
2839 'contexturlname' => new external_value(PARAM_TEXT
, 'Context URL link name'),
2840 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
2841 'timeread' => new external_value(PARAM_INT
, 'Time read'),
2842 'usertofullname' => new external_value(PARAM_TEXT
, 'User to full name'),
2843 'userfromfullname' => new external_value(PARAM_TEXT
, 'User from full name')
2847 'warnings' => new external_warnings()
2853 * Mark all notifications as read parameters description.
2855 * @return external_function_parameters
2858 public static function mark_all_notifications_as_read_parameters() {
2859 return new external_function_parameters(
2861 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2862 'useridfrom' => new external_value(
2863 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2870 * Mark all notifications as read function.
2873 * @throws invalid_parameter_exception
2874 * @throws moodle_exception
2875 * @param int $useridto the user id who received the message
2876 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2877 * @return external_description
2879 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
2882 $params = self
::validate_parameters(
2883 self
::mark_all_notifications_as_read_parameters(),
2885 'useridto' => $useridto,
2886 'useridfrom' => $useridfrom,
2890 $context = context_system
::instance();
2891 self
::validate_context($context);
2893 $useridto = $params['useridto'];
2894 $useridfrom = $params['useridfrom'];
2896 if (!empty($useridto)) {
2897 if (core_user
::is_real_user($useridto)) {
2898 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2900 throw new moodle_exception('invaliduser');
2904 if (!empty($useridfrom)) {
2905 // We use get_user here because the from user can be the noreply or support user.
2906 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2909 // Check if the current user is the sender/receiver or just a privileged user.
2910 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2911 // The deleteanymessage cap seems more reasonable here than readallmessages.
2912 !has_capability('moodle/site:deleteanymessage', $context)) {
2913 throw new moodle_exception('accessdenied', 'admin');
2916 \core_message\api
::mark_all_notifications_as_read($useridto, $useridfrom);
2922 * Mark all notifications as read return description.
2924 * @return external_single_structure
2927 public static function mark_all_notifications_as_read_returns() {
2928 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
2932 * Get unread conversations count parameters description.
2934 * @return external_function_parameters
2937 public static function get_unread_conversations_count_parameters() {
2938 return new external_function_parameters(
2940 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2946 * Get unread messages count function.
2949 * @throws invalid_parameter_exception
2950 * @throws moodle_exception
2951 * @param int $useridto the user id who received the message
2952 * @return external_description
2954 public static function get_unread_conversations_count($useridto) {
2957 // Check if messaging is enabled.
2958 if (empty($CFG->messaging
)) {
2959 throw new moodle_exception('disabled', 'message');
2962 $params = self
::validate_parameters(
2963 self
::get_unread_conversations_count_parameters(),
2964 array('useridto' => $useridto)
2967 $context = context_system
::instance();
2968 self
::validate_context($context);
2970 $useridto = $params['useridto'];
2972 if (!empty($useridto)) {
2973 if (core_user
::is_real_user($useridto)) {
2974 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2976 throw new moodle_exception('invaliduser');
2979 $useridto = $USER->id
;
2982 // Check if the current user is the receiver or just a privileged user.
2983 if ($useridto != $USER->id
and !has_capability('moodle/site:readallmessages', $context)) {
2984 throw new moodle_exception('accessdenied', 'admin');
2987 return \core_message\api
::count_unread_conversations($userto);
2991 * Get unread conversations count return description.
2993 * @return external_single_structure
2996 public static function get_unread_conversations_count_returns() {
2997 return new external_value(PARAM_INT
, 'The count of unread messages for the user');
3001 * Get blocked users parameters description.
3003 * @return external_function_parameters
3006 public static function get_blocked_users_parameters() {
3007 return new external_function_parameters(
3009 'userid' => new external_value(PARAM_INT
,
3010 'the user whose blocked users we want to retrieve',
3017 * Retrieve a list of users blocked
3019 * @param int $userid the user whose blocked users we want to retrieve
3020 * @return external_description
3023 public static function get_blocked_users($userid) {
3024 global $CFG, $USER, $PAGE;
3026 // Warnings array, it can be empty at the end but is mandatory.
3027 $warnings = array();
3033 $params = self
::validate_parameters(self
::get_blocked_users_parameters(), $params);
3034 $userid = $params['userid'];
3036 // Validate context.
3037 $context = context_system
::instance();
3038 self
::validate_context($context);
3040 // Check if private messaging between users is allowed.
3041 if (empty($CFG->messaging
)) {
3042 throw new moodle_exception('disabled', 'message');
3045 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
3046 core_user
::require_active_user($user);
3048 // Check if we have permissions for retrieve the information.
3049 $capability = 'moodle/site:manageallmessaging';
3050 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
3051 throw new required_capability_exception($context, $capability, 'nopermissions', '');
3054 // Now, we can get safely all the blocked users.
3055 $users = \core_message\api
::get_blocked_users($user->id
);
3057 $blockedusers = array();
3058 foreach ($users as $user) {
3061 'fullname' => fullname($user),
3064 $userpicture = new user_picture($user);
3065 $userpicture->size
= 1; // Size f1.
3066 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
3068 $blockedusers[] = $newuser;
3072 'users' => $blockedusers,
3073 'warnings' => $warnings
3079 * Get blocked users return description.
3081 * @return external_single_structure
3084 public static function get_blocked_users_returns() {
3085 return new external_single_structure(
3087 'users' => new external_multiple_structure(
3088 new external_single_structure(
3090 'id' => new external_value(PARAM_INT
, 'User ID'),
3091 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
3092 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
)
3095 'List of blocked users'
3097 'warnings' => new external_warnings()
3103 * Returns description of method parameters
3105 * @return external_function_parameters
3108 public static function mark_message_read_parameters() {
3109 return new external_function_parameters(
3111 'messageid' => new external_value(PARAM_INT
, 'id of the message in the messages table'),
3112 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the message should be marked read',
3119 * Mark a single message as read, trigger message_viewed event
3121 * @param int $messageid id of the message (in the message table)
3122 * @param int $timeread timestamp for when the message should be marked read
3123 * @return external_description
3124 * @throws invalid_parameter_exception
3125 * @throws moodle_exception
3128 public static function mark_message_read($messageid, $timeread) {
3129 global $CFG, $DB, $USER;
3131 // Check if private messaging between users is allowed.
3132 if (empty($CFG->messaging
)) {
3133 throw new moodle_exception('disabled', 'message');
3136 // Warnings array, it can be empty at the end but is mandatory.
3137 $warnings = array();
3141 'messageid' => $messageid,
3142 'timeread' => $timeread
3144 $params = self
::validate_parameters(self
::mark_message_read_parameters(), $params);
3146 if (empty($params['timeread'])) {
3149 $timeread = $params['timeread'];
3152 // Validate context.
3153 $context = context_system
::instance();
3154 self
::validate_context($context);
3156 $sql = "SELECT m.*, mcm.userid as useridto
3158 INNER JOIN {message_conversations} mc
3159 ON m.conversationid = mc.id
3160 INNER JOIN {message_conversation_members} mcm
3161 ON mcm.conversationid = mc.id
3162 LEFT JOIN {message_user_actions} mua
3163 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
3164 WHERE mua.id is NULL
3165 AND mcm.userid != m.useridfrom
3167 $messageparams = [];
3168 $messageparams[] = $USER->id
;
3169 $messageparams[] = \core_message\api
::MESSAGE_ACTION_READ
;
3170 $messageparams[] = $params['messageid'];
3171 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST
);
3173 if ($message->useridto
!= $USER->id
) {
3174 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
3177 \core_message\api
::mark_message_as_read($USER->id
, $message, $timeread);
3180 'messageid' => $message->id
,
3181 'warnings' => $warnings
3187 * Returns description of method result value
3189 * @return external_description
3192 public static function mark_message_read_returns() {
3193 return new external_single_structure(
3195 'messageid' => new external_value(PARAM_INT
, 'the id of the message in the messages table'),
3196 'warnings' => new external_warnings()
3202 * Returns description of method parameters
3204 * @return external_function_parameters
3206 public static function mark_notification_read_parameters() {
3207 return new external_function_parameters(
3209 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
3210 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the notification should be marked read',
3217 * Mark a single notification as read.
3219 * This will trigger a 'notification_viewed' event.
3221 * @param int $notificationid id of the notification
3222 * @param int $timeread timestamp for when the notification should be marked read
3223 * @return external_description
3224 * @throws invalid_parameter_exception
3225 * @throws moodle_exception
3227 public static function mark_notification_read($notificationid, $timeread) {
3228 global $CFG, $DB, $USER;
3230 // Check if private messaging between users is allowed.
3231 if (empty($CFG->messaging
)) {
3232 throw new moodle_exception('disabled', 'message');
3235 // Warnings array, it can be empty at the end but is mandatory.
3236 $warnings = array();
3240 'notificationid' => $notificationid,
3241 'timeread' => $timeread
3243 $params = self
::validate_parameters(self
::mark_notification_read_parameters(), $params);
3245 if (empty($params['timeread'])) {
3248 $timeread = $params['timeread'];
3251 // Validate context.
3252 $context = context_system
::instance();
3253 self
::validate_context($context);
3255 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST
);
3257 if ($notification->useridto
!= $USER->id
) {
3258 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
3259 'notification as read');
3262 \core_message\api
::mark_notification_as_read($notification, $timeread);
3265 'notificationid' => $notification->id
,
3266 'warnings' => $warnings
3273 * Returns description of method result value
3275 * @return external_description
3277 public static function mark_notification_read_returns() {
3278 return new external_single_structure(
3280 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
3281 'warnings' => new external_warnings()
3287 * Mark all messages as read parameters description.
3289 * @deprecated since 3.6
3290 * @return external_function_parameters
3293 public static function mark_all_messages_as_read_parameters() {
3294 return new external_function_parameters(
3296 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
3297 'useridfrom' => new external_value(
3298 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3305 * Mark all messages as read function.
3307 * @deprecated since 3.6
3308 * @throws invalid_parameter_exception
3309 * @throws moodle_exception
3310 * @param int $useridto the user id who received the message
3311 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3312 * @return external_description
3315 public static function mark_all_messages_as_read($useridto, $useridfrom) {
3318 // Check if messaging is enabled.
3319 if (empty($CFG->messaging
)) {
3320 throw new moodle_exception('disabled', 'message');
3323 $params = self
::validate_parameters(
3324 self
::mark_all_messages_as_read_parameters(),
3326 'useridto' => $useridto,
3327 'useridfrom' => $useridfrom,
3331 $context = context_system
::instance();
3332 self
::validate_context($context);
3334 $useridto = $params['useridto'];
3335 $useridfrom = $params['useridfrom'];
3337 if (!empty($useridto)) {
3338 if (core_user
::is_real_user($useridto)) {
3339 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
3341 throw new moodle_exception('invaliduser');
3345 if (!empty($useridfrom)) {
3346 // We use get_user here because the from user can be the noreply or support user.
3347 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
3350 // Check if the current user is the sender/receiver or just a privileged user.
3351 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
3352 // The deleteanymessage cap seems more reasonable here than readallmessages.
3353 !has_capability('moodle/site:deleteanymessage', $context)) {
3354 throw new moodle_exception('accessdenied', 'admin');
3358 if ($conversationid = \core_message\api
::get_conversation_between_users([$useridto, $useridfrom])) {
3359 \core_message\api
::mark_all_messages_as_read($useridto, $conversationid);
3362 \core_message\api
::mark_all_messages_as_read($useridto);
3369 * Mark all messages as read return description.
3371 * @deprecated since 3.6
3372 * @return external_single_structure
3375 public static function mark_all_messages_as_read_returns() {
3376 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
3380 * Marking the method as deprecated.
3384 public static function mark_all_messages_as_read_is_deprecated() {
3389 * Mark all conversation messages as read parameters description.
3391 * @return external_function_parameters
3394 public static function mark_all_conversation_messages_as_read_parameters() {
3395 return new external_function_parameters(
3397 'userid' => new external_value(PARAM_INT
, 'The user id who who we are marking the messages as read for'),
3399 new external_value(PARAM_INT
, 'The conversation id who who we are marking the messages as read for')
3405 * Mark all conversation messages as read function.
3407 * @param int $userid The user id of who we want to delete the conversation for
3408 * @param int $conversationid The id of the conversations
3411 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
3414 // Check if messaging is enabled.
3415 if (empty($CFG->messaging
)) {
3416 throw new moodle_exception('disabled', 'message');
3420 'userid' => $userid,
3421 'conversationid' => $conversationid,
3423 $params = self
::validate_parameters(self
::mark_all_conversation_messages_as_read_parameters(), $params);
3425 $context = context_system
::instance();
3426 self
::validate_context($context);
3428 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3429 core_user
::require_active_user($user);
3431 if (\core_message\api
::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) {
3432 \core_message\api
::mark_all_messages_as_read($params['userid'], $params['conversationid']);
3434 throw new moodle_exception('accessdenied', 'admin');
3439 * Mark all conversation messages as read return description.
3441 * @return external_warnings
3444 public static function mark_all_conversation_messages_as_read_returns() {
3449 * Returns description of method parameters.
3451 * @deprecated since 3.6
3452 * @return external_function_parameters
3455 public static function delete_conversation_parameters() {
3456 return new external_function_parameters(
3458 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
3459 'otheruserid' => new external_value(PARAM_INT
, 'The user id of the other user in the conversation'),
3465 * Deletes a conversation.
3467 * @deprecated since 3.6
3468 * @param int $userid The user id of who we want to delete the conversation for
3469 * @param int $otheruserid The user id of the other user in the conversation
3471 * @throws moodle_exception
3474 public static function delete_conversation($userid, $otheruserid) {
3477 // Check if private messaging between users is allowed.
3478 if (empty($CFG->messaging
)) {
3479 throw new moodle_exception('disabled', 'message');
3482 // Warnings array, it can be empty at the end but is mandatory.
3483 $warnings = array();
3487 'userid' => $userid,
3488 'otheruserid' => $otheruserid,
3490 $params = self
::validate_parameters(self
::delete_conversation_parameters(), $params);
3492 // Validate context.
3493 $context = context_system
::instance();
3494 self
::validate_context($context);
3496 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3497 core_user
::require_active_user($user);
3499 if (!$conversationid = \core_message\api
::get_conversation_between_users([$params['userid'], $params['otheruserid']])) {
3503 if (\core_message\api
::can_delete_conversation($user->id
, $conversationid)) {
3504 \core_message\api
::delete_conversation_by_id($user->id
, $conversationid);
3507 throw new moodle_exception('You do not have permission to delete messages');
3511 'status' => $status,
3512 'warnings' => $warnings
3519 * Returns description of method result value.
3521 * @deprecated since 3.6
3522 * @return external_description
3525 public static function delete_conversation_returns() {
3526 return new external_single_structure(
3528 'status' => new external_value(PARAM_BOOL
, 'True if the conversation was deleted, false otherwise'),
3529 'warnings' => new external_warnings()
3535 * Marking the method as deprecated.
3539 public static function delete_conversation_is_deprecated() {
3544 * Returns description of method parameters.
3546 * @return external_function_parameters
3549 public static function delete_conversations_by_id_parameters() {
3550 return new external_function_parameters(
3552 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
3553 'conversationids' => new external_multiple_structure(
3554 new external_value(PARAM_INT
, 'The id of the conversation'),
3555 'List of conversation IDs'
3562 * Deletes a conversation.
3564 * @param int $userid The user id of who we want to delete the conversation for
3565 * @param int[] $conversationids The ids of the conversations
3567 * @throws moodle_exception
3570 public static function delete_conversations_by_id($userid, array $conversationids) {
3573 // Check if private messaging between users is allowed.
3574 if (empty($CFG->messaging
)) {
3575 throw new moodle_exception('disabled', 'message');
3580 'userid' => $userid,
3581 'conversationids' => $conversationids,
3583 $params = self
::validate_parameters(self
::delete_conversations_by_id_parameters(), $params);
3585 // Validate context.
3586 $context = context_system
::instance();
3587 self
::validate_context($context);
3589 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3590 core_user
::require_active_user($user);
3592 foreach ($params['conversationids'] as $conversationid) {
3593 if (\core_message\api
::can_delete_conversation($user->id
, $conversationid)) {
3594 \core_message\api
::delete_conversation_by_id($user->id
, $conversationid);
3596 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'");
3604 * Returns description of method result value.
3606 * @return external_description
3609 public static function delete_conversations_by_id_returns() {
3610 return new external_warnings();
3614 * Returns description of method parameters
3616 * @return external_function_parameters
3619 public static function delete_message_parameters() {
3620 return new external_function_parameters(
3622 'messageid' => new external_value(PARAM_INT
, 'The message id'),
3623 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for'),
3624 'read' => new external_value(PARAM_BOOL
, 'If is a message read', VALUE_DEFAULT
, true)
3632 * @param int $messageid the message id
3633 * @param int $userid the user id of who we want to delete the message for
3634 * @param bool $read if is a message read (default to true)
3635 * @return external_description
3636 * @throws moodle_exception
3639 public static function delete_message($messageid, $userid, $read = true) {
3642 // Check if private messaging between users is allowed.
3643 if (empty($CFG->messaging
)) {
3644 throw new moodle_exception('disabled', 'message');
3647 // Warnings array, it can be empty at the end but is mandatory.
3648 $warnings = array();
3652 'messageid' => $messageid,
3653 'userid' => $userid,
3656 $params = self
::validate_parameters(self
::delete_message_parameters(), $params);
3658 // Validate context.
3659 $context = context_system
::instance();
3660 self
::validate_context($context);
3662 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3663 core_user
::require_active_user($user);
3665 if (\core_message\api
::can_delete_message($user->id
, $params['messageid'])) {
3666 $status = \core_message\api
::delete_message($user->id
, $params['messageid']);
3668 throw new moodle_exception('You do not have permission to delete this message');
3672 'status' => $status,
3673 'warnings' => $warnings
3679 * Returns description of method result value
3681 * @return external_description
3684 public static function delete_message_returns() {
3685 return new external_single_structure(
3687 'status' => new external_value(PARAM_BOOL
, 'True if the message was deleted, false otherwise'),
3688 'warnings' => new external_warnings()
3694 * Returns description of method parameters
3696 * @return external_function_parameters
3699 public static function message_processor_config_form_parameters() {
3700 return new external_function_parameters(
3702 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_REQUIRED
),
3703 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor'),
3704 'formvalues' => new external_multiple_structure(
3705 new external_single_structure(
3707 'name' => new external_value(PARAM_TEXT
, 'name of the form element', VALUE_REQUIRED
),
3708 'value' => new external_value(PARAM_RAW
, 'value of the form element', VALUE_REQUIRED
),
3711 'Config form values',
3719 * Processes a message processor config form.
3721 * @param int $userid the user id
3722 * @param string $name the name of the processor
3723 * @param array $formvalues the form values
3724 * @return external_description
3725 * @throws moodle_exception
3728 public static function message_processor_config_form($userid, $name, $formvalues) {
3731 // Check if messaging is enabled.
3732 if (empty($CFG->messaging
)) {
3733 throw new moodle_exception('disabled', 'message');
3736 $params = self
::validate_parameters(
3737 self
::message_processor_config_form_parameters(),
3739 'userid' => $userid,
3741 'formvalues' => $formvalues,
3745 $user = self
::validate_preferences_permissions($params['userid']);
3747 $processor = get_message_processor($params['name']);
3749 $form = new stdClass();
3751 foreach ($params['formvalues'] as $formvalue) {
3752 // Curly braces to ensure interpretation is consistent between
3754 $form->{$formvalue['name']} = $formvalue['value'];
3757 $processor->process_form($form, $preferences);
3759 if (!empty($preferences)) {
3760 set_user_preferences($preferences, $params['userid']);
3765 * Returns description of method result value
3767 * @return external_description
3770 public static function message_processor_config_form_returns() {
3775 * Returns description of method parameters
3777 * @return external_function_parameters
3780 public static function get_message_processor_parameters() {
3781 return new external_function_parameters(
3783 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user'),
3784 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor', VALUE_REQUIRED
),
3790 * Get a message processor.
3792 * @param int $userid
3793 * @param string $name the name of the processor
3794 * @return external_description
3795 * @throws moodle_exception
3798 public static function get_message_processor($userid = 0, $name) {
3799 global $USER, $PAGE, $CFG;
3801 // Check if messaging is enabled.
3802 if (empty($CFG->messaging
)) {
3803 throw new moodle_exception('disabled', 'message');
3806 $params = self
::validate_parameters(
3807 self
::get_message_processor_parameters(),
3809 'userid' => $userid,
3814 if (empty($params['userid'])) {
3815 $params['userid'] = $USER->id
;
3818 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3819 core_user
::require_active_user($user);
3820 self
::validate_context(context_user
::instance($params['userid']));
3822 $processor = get_message_processor($params['name']);
3824 $processoroutput = new \core_message\output\
processor($processor, $user);
3825 $renderer = $PAGE->get_renderer('core_message');
3827 return $processoroutput->export_for_template($renderer);
3831 * Returns description of method result value
3833 * @return external_description
3836 public static function get_message_processor_returns() {
3837 return new external_function_parameters(
3839 'systemconfigured' => new external_value(PARAM_BOOL
, 'Site configuration status'),
3840 'userconfigured' => new external_value(PARAM_BOOL
, 'The user configuration status'),
3846 * Check that the user has enough permission to retrieve message or notifications preferences.
3848 * @param int $userid the user id requesting the preferences
3849 * @return stdClass full user object
3850 * @throws moodle_exception
3853 protected static function validate_preferences_permissions($userid) {
3856 if (empty($userid)) {
3859 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
3860 core_user
::require_active_user($user);
3863 $systemcontext = context_system
::instance();
3864 self
::validate_context($systemcontext);
3866 // Check access control.
3867 if ($user->id
== $USER->id
) {
3868 // Editing own message profile.
3869 require_capability('moodle/user:editownmessageprofile', $systemcontext);
3871 // Teachers, parents, etc.
3872 $personalcontext = context_user
::instance($user->id
);
3873 require_capability('moodle/user:editmessageprofile', $personalcontext);
3879 * Returns a notification or message preference structure.
3881 * @return external_single_structure the structure
3884 protected static function get_preferences_structure() {
3885 return new external_single_structure(
3887 'userid' => new external_value(PARAM_INT
, 'User id'),
3888 'disableall' => new external_value(PARAM_INT
, 'Whether all the preferences are disabled'),
3889 'processors' => new external_multiple_structure(
3890 new external_single_structure(
3892 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3893 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3894 'hassettings' => new external_value(PARAM_BOOL
, 'Whether has settings'),
3895 'contextid' => new external_value(PARAM_INT
, 'Context id'),
3896 'userconfigured' => new external_value(PARAM_INT
, 'Whether is configured by the user'),
3899 'Config form values'
3901 'components' => new external_multiple_structure(
3902 new external_single_structure(
3904 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3905 'notifications' => new external_multiple_structure(
3906 new external_single_structure(
3908 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3909 'preferencekey' => new external_value(PARAM_ALPHANUMEXT
, 'Preference key'),
3910 'processors' => new external_multiple_structure(
3911 new external_single_structure(
3913 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3914 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3915 'locked' => new external_value(PARAM_BOOL
, 'Is locked by admin?'),
3916 'userconfigured' => new external_value(PARAM_INT
, 'Is configured?'),
3917 'loggedin' => new external_single_structure(
3919 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3920 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3921 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3924 'loggedoff' => new external_single_structure(
3926 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3927 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3928 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3933 'Processors values for this notification'
3937 'List of notificaitons for the component'
3941 'Available components'
3948 * Returns description of method parameters
3950 * @return external_function_parameters
3953 public static function get_user_notification_preferences_parameters() {
3954 return new external_function_parameters(
3956 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3962 * Get the notification preferences for a given user.
3964 * @param int $userid id of the user, 0 for current user
3965 * @return external_description
3966 * @throws moodle_exception
3969 public static function get_user_notification_preferences($userid = 0) {
3972 $params = self
::validate_parameters(
3973 self
::get_user_notification_preferences_parameters(),
3975 'userid' => $userid,
3978 $user = self
::validate_preferences_permissions($params['userid']);
3980 $processors = get_message_processors();
3981 $providers = message_get_providers_for_user($user->id
);
3982 $preferences = \core_message\api
::get_all_message_preferences($processors, $providers, $user);
3983 $notificationlist = new \core_message\output\preferences\notification_list
($processors, $providers, $preferences, $user);
3985 $renderer = $PAGE->get_renderer('core_message');
3988 'warnings' => array(),
3989 'preferences' => $notificationlist->export_for_template($renderer)
3995 * Returns description of method result value
3997 * @return external_description
4000 public static function get_user_notification_preferences_returns() {
4001 return new external_function_parameters(
4003 'preferences' => self
::get_preferences_structure(),
4004 'warnings' => new external_warnings(),
4010 * Returns description of method parameters
4012 * @return external_function_parameters
4015 public static function get_user_message_preferences_parameters() {
4016 return new external_function_parameters(
4018 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
4024 * Get the notification preferences for a given user.
4026 * @param int $userid id of the user, 0 for current user
4027 * @return external_description
4028 * @throws moodle_exception
4031 public static function get_user_message_preferences($userid = 0) {
4034 $params = self
::validate_parameters(
4035 self
::get_user_message_preferences_parameters(),
4037 'userid' => $userid,
4041 $user = self
::validate_preferences_permissions($params['userid']);
4043 // Filter out enabled, available system_configured and user_configured processors only.
4044 $readyprocessors = array_filter(get_message_processors(), function($processor) {
4045 return $processor->enabled
&&
4046 $processor->configured
&&
4047 $processor->object->is_user_configured() &&
4048 // Filter out processors that don't have and message preferences to configure.
4049 $processor->object->has_message_preferences();
4052 $providers = array_filter(message_get_providers_for_user($user->id
), function($provider) {
4053 return $provider->component
=== 'moodle';
4055 $preferences = \core_message\api
::get_all_message_preferences($readyprocessors, $providers, $user);
4056 $notificationlistoutput = new \core_message\output\preferences\
message_notification_list($readyprocessors,
4057 $providers, $preferences, $user);
4059 $renderer = $PAGE->get_renderer('core_message');
4062 'warnings' => array(),
4063 'preferences' => $notificationlistoutput->export_for_template($renderer),
4064 'blocknoncontacts' => \core_message\api
::get_user_privacy_messaging_preference($user->id
),
4070 * Returns description of method result value
4072 * @return external_description
4075 public static function get_user_message_preferences_returns() {
4076 return new external_function_parameters(
4078 'preferences' => self
::get_preferences_structure(),
4079 'blocknoncontacts' => new external_value(PARAM_INT
, 'Privacy messaging setting to define who can message you'),
4080 'warnings' => new external_warnings(),
4086 * Returns description of method parameters for the favourite_conversations() method.
4088 * @return external_function_parameters
4090 public static function set_favourite_conversations_parameters() {
4091 return new external_function_parameters(
4093 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
4094 'conversations' => new external_multiple_structure(
4095 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
4102 * Favourite a conversation, or list of conversations for a user.
4104 * @param int $userid the id of the user, or 0 for the current user.
4105 * @param array $conversationids the list of conversations ids to favourite.
4107 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4109 public static function set_favourite_conversations(int $userid, array $conversationids) {
4112 // All the business logic checks that really shouldn't be in here.
4113 if (empty($CFG->messaging
)) {
4114 throw new moodle_exception('disabled', 'message');
4117 'userid' => $userid,
4118 'conversations' => $conversationids
4120 $params = self
::validate_parameters(self
::set_favourite_conversations_parameters(), $params);
4121 $systemcontext = context_system
::instance();
4122 self
::validate_context($systemcontext);
4124 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4125 throw new moodle_exception('You do not have permission to perform this action.');
4128 foreach ($params['conversations'] as $conversationid) {
4129 \core_message\api
::set_favourite_conversation($conversationid, $params['userid']);
4136 * Return a description of the returns for the create_user_favourite_conversations() method.
4138 * @return external_description
4140 public static function set_favourite_conversations_returns() {
4141 return new external_warnings();
4145 * Returns description of method parameters for unfavourite_conversations() method.
4147 * @return external_function_parameters
4149 public static function unset_favourite_conversations_parameters() {
4150 return new external_function_parameters(
4152 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
4153 'conversations' => new external_multiple_structure(
4154 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
4161 * Unfavourite a conversation, or list of conversations for a user.
4163 * @param int $userid the id of the user, or 0 for the current user.
4164 * @param array $conversationids the list of conversations ids unset as favourites.
4166 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4168 public static function unset_favourite_conversations(int $userid, array $conversationids) {
4171 // All the business logic checks that really shouldn't be in here.
4172 if (empty($CFG->messaging
)) {
4173 throw new moodle_exception('disabled', 'message');
4176 'userid' => $userid,
4177 'conversations' => $conversationids
4179 $params = self
::validate_parameters(self
::unset_favourite_conversations_parameters(), $params);
4180 $systemcontext = context_system
::instance();
4181 self
::validate_context($systemcontext);
4183 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4184 throw new moodle_exception('You do not have permission to perform this action.');
4187 foreach ($params['conversations'] as $conversationid) {
4188 \core_message\api
::unset_favourite_conversation($conversationid, $params['userid']);
4195 * Unset favourite conversations return description.
4197 * @return external_description
4199 public static function unset_favourite_conversations_returns() {
4200 return new external_warnings();
4204 * Returns description of method parameters for get_member_info() method.
4206 * @return external_function_parameters
4208 public static function get_member_info_parameters() {
4209 return new external_function_parameters(
4211 'referenceuserid' => new external_value(PARAM_INT
, 'id of the user'),
4212 'userids' => new external_multiple_structure(
4213 new external_value(PARAM_INT
, 'id of members to get')
4215 'includecontactrequests' => new external_value(PARAM_BOOL
, 'include contact requests in response', VALUE_DEFAULT
, false),
4216 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'include privacy info in response', VALUE_DEFAULT
, false)
4222 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid.
4224 * This is the basic structure used when returning members, and includes information about the relationship between each member
4225 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them.
4227 * @param int $referenceuserid the id of the user which check contact and blocked status.
4228 * @param array $userids
4229 * @return array the array of objects containing member info.
4230 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4232 public static function get_member_info(
4233 int $referenceuserid,
4235 bool $includecontactrequests = false,
4236 bool $includeprivacyinfo = false
4240 // All the business logic checks that really shouldn't be in here.
4241 if (empty($CFG->messaging
)) {
4242 throw new moodle_exception('disabled', 'message');
4245 'referenceuserid' => $referenceuserid,
4246 'userids' => $userids,
4247 'includecontactrequests' => $includecontactrequests,
4248 'includeprivacyinfo' => $includeprivacyinfo
4250 $params = self
::validate_parameters(self
::get_member_info_parameters(), $params);
4251 $systemcontext = context_system
::instance();
4252 self
::validate_context($systemcontext);
4254 if (($USER->id
!= $referenceuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4255 throw new moodle_exception('You do not have permission to perform this action.');
4258 return \core_message\helper
::get_member_info(
4259 $params['referenceuserid'],
4261 $params['includecontactrequests'],
4262 $params['includeprivacyinfo']
4267 * Get member info return description.
4269 * @return external_description
4271 public static function get_member_info_returns() {
4272 return new external_multiple_structure(
4273 self
::get_conversation_member_structure(true)