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 $createdmessage = \core_message\api
::send_message_to_conversation($USER->id
, $params['conversationid'], $message['text'],
94 $message['textformat']);
95 $createdmessage->text
= message_format_message_text((object) [
96 'smallmessage' => $createdmessage->text
,
97 'fullmessageformat' => external_validate_format($message['textformat']),
98 'fullmessagetrust' => $createdmessage->fullmessagetrust
100 $messages[] = $createdmessage;
107 * Returns description of method result value.
109 * @return external_description
112 public static function send_messages_to_conversation_returns() {
113 return new external_multiple_structure(
114 self
::get_conversation_message_structure()
120 * Returns description of method parameters
122 * @return external_function_parameters
125 public static function send_instant_messages_parameters() {
126 return new external_function_parameters(
128 'messages' => new external_multiple_structure(
129 new external_single_structure(
131 'touserid' => new external_value(PARAM_INT
, 'id of the user to send the private message'),
132 'text' => new external_value(PARAM_RAW
, 'the text of the message'),
133 'textformat' => new external_format_value('text', VALUE_DEFAULT
, FORMAT_MOODLE
),
134 '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
),
143 * Send private messages from the current USER to other users
145 * @param array $messages An array of message to send.
149 public static function send_instant_messages($messages = array()) {
150 global $CFG, $USER, $DB;
152 // Check if messaging is enabled.
153 if (empty($CFG->messaging
)) {
154 throw new moodle_exception('disabled', 'message');
157 // Ensure the current user is allowed to run this function
158 $context = context_system
::instance();
159 self
::validate_context($context);
160 require_capability('moodle/site:sendmessage', $context);
162 // Ensure the current user is allowed to delete message for everyone.
163 $candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $context);
165 $params = self
::validate_parameters(self
::send_instant_messages_parameters(), array('messages' => $messages));
167 //retrieve all tousers of the messages
168 $receivers = array();
169 foreach($params['messages'] as $message) {
170 $receivers[] = $message['touserid'];
172 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
173 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
175 $resultmessages = array();
176 $messageids = array();
177 foreach ($params['messages'] as $message) {
178 $resultmsg = array(); //the infos about the success of the operation
180 // We are going to do some checking.
181 // Code should match /messages/index.php checks.
184 // Check the user exists.
185 if (empty($tousers[$message['touserid']])) {
187 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
190 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
191 // Check if the recipient can be messaged by the sender.
192 if ($success && !\core_message\api
::can_send_message($tousers[$message['touserid']]->id
, $USER->id
)) {
194 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user
::get_user($message['touserid'])));
197 // Now we can send the message (at least try).
199 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
200 $success = message_post_message($USER, $tousers[$message['touserid']],
201 $message['text'], external_validate_format($message['textformat']));
204 // Build the resultmsg.
205 if (isset($message['clientmsgid'])) {
206 $resultmsg['clientmsgid'] = $message['clientmsgid'];
209 $resultmsg['msgid'] = $success;
210 $resultmsg['timecreated'] = time();
211 $resultmsg['candeletemessagesforallusers'] = $candeletemessagesforallusers;
212 $messageids[] = $success;
214 // WARNINGS: for backward compatibility we return this errormessage.
215 // We should have thrown exceptions as these errors prevent results to be returned.
216 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
217 $resultmsg['msgid'] = -1;
218 $resultmsg['errormessage'] = $errormessage;
221 $resultmessages[] = $resultmsg;
224 if (!empty($messageids)) {
225 $messagerecords = $DB->get_records_list(
230 'id, conversationid, smallmessage, fullmessageformat, fullmessagetrust');
231 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) {
232 $id = $resultmessage['msgid'];
233 $resultmessage['conversationid'] = isset($messagerecords[$id]) ?
$messagerecords[$id]->conversationid
: null;
234 $resultmessage['useridfrom'] = $USER->id
;
235 $resultmessage['text'] = message_format_message_text((object) [
236 'smallmessage' => $messagerecords[$id]->smallmessage
,
237 'fullmessageformat' => external_validate_format($messagerecords[$id]->fullmessageformat
),
238 'fullmessagetrust' => $messagerecords[$id]->fullmessagetrust
240 return $resultmessage;
244 return $resultmessages;
248 * Returns description of method result value
250 * @return external_description
253 public static function send_instant_messages_returns() {
254 return new external_multiple_structure(
255 new external_single_structure(
257 'msgid' => new external_value(PARAM_INT
, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
258 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT
, 'your own id for the message', VALUE_OPTIONAL
),
259 'errormessage' => new external_value(PARAM_TEXT
, 'error message - if it failed', VALUE_OPTIONAL
),
260 'text' => new external_value(PARAM_RAW
, 'The text of the message', VALUE_OPTIONAL
),
261 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message', VALUE_OPTIONAL
),
262 'conversationid' => new external_value(PARAM_INT
, 'The conversation id for this message', VALUE_OPTIONAL
),
263 'useridfrom' => new external_value(PARAM_INT
, 'The user id who sent the message', VALUE_OPTIONAL
),
264 'candeletemessagesforallusers' => new external_value(PARAM_BOOL
,
265 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT
, false),
272 * Delete contacts parameters description.
274 * @return external_function_parameters
277 public static function delete_contacts_parameters() {
278 return new external_function_parameters(
280 'userids' => new external_multiple_structure(
281 new external_value(PARAM_INT
, 'User ID'),
284 'userid' => new external_value(PARAM_INT
, 'The id of the user we are deleting the contacts for, 0 for the
285 current user', VALUE_DEFAULT
, 0)
293 * @param array $userids array of user IDs.
294 * @param int $userid The id of the user we are deleting the contacts for
298 public static function delete_contacts($userids, $userid = 0) {
301 // Check if messaging is enabled.
302 if (empty($CFG->messaging
)) {
303 throw new moodle_exception('disabled', 'message');
306 if (empty($userid)) {
311 $context = context_system
::instance();
312 self
::validate_context($context);
314 $params = array('userids' => $userids, 'userid' => $userid);
315 $params = self
::validate_parameters(self
::delete_contacts_parameters(), $params);
317 $capability = 'moodle/site:manageallmessaging';
318 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
319 throw new required_capability_exception($context, $capability, 'nopermissions', '');
322 foreach ($params['userids'] as $id) {
323 \core_message\api
::remove_contact($params['userid'], $id);
330 * Delete contacts return description.
332 * @return external_description
335 public static function delete_contacts_returns() {
340 * Mute conversations parameters description.
342 * @return external_function_parameters
344 public static function mute_conversations_parameters() {
345 return new external_function_parameters(
347 'userid' => new external_value(PARAM_INT
, 'The id of the user who is blocking'),
348 'conversationids' => new external_multiple_structure(
349 new external_value(PARAM_INT
, 'id of the conversation', VALUE_REQUIRED
)
356 * Mutes conversations.
358 * @param int $userid The id of the user who is blocking
359 * @param array $conversationids The list of conversations being muted
360 * @return external_description
362 public static function mute_conversations(int $userid, array $conversationids) {
365 // Check if messaging is enabled.
366 if (empty($CFG->messaging
)) {
367 throw new moodle_exception('disabled', 'message');
371 $context = context_system
::instance();
372 self
::validate_context($context);
374 $params = ['userid' => $userid, 'conversationids' => $conversationids];
375 $params = self
::validate_parameters(self
::mute_conversations_parameters(), $params);
377 $capability = 'moodle/site:manageallmessaging';
378 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
379 throw new required_capability_exception($context, $capability, 'nopermissions', '');
382 foreach ($params['conversationids'] as $conversationid) {
383 if (!\core_message\api
::is_conversation_muted($params['userid'], $conversationid)) {
384 \core_message\api
::mute_conversation($params['userid'], $conversationid);
392 * Mute conversations return description.
394 * @return external_description
396 public static function mute_conversations_returns() {
397 return new external_warnings();
401 * Unmute conversations parameters description.
403 * @return external_function_parameters
405 public static function unmute_conversations_parameters() {
406 return new external_function_parameters(
408 'userid' => new external_value(PARAM_INT
, 'The id of the user who is unblocking'),
409 'conversationids' => new external_multiple_structure(
410 new external_value(PARAM_INT
, 'id of the conversation', VALUE_REQUIRED
)
417 * Unmute conversations.
419 * @param int $userid The id of the user who is unblocking
420 * @param array $conversationids The list of conversations being muted
422 public static function unmute_conversations(int $userid, array $conversationids) {
425 // Check if messaging is enabled.
426 if (empty($CFG->messaging
)) {
427 throw new moodle_exception('disabled', 'message');
431 $context = context_system
::instance();
432 self
::validate_context($context);
434 $params = ['userid' => $userid, 'conversationids' => $conversationids];
435 $params = self
::validate_parameters(self
::unmute_conversations_parameters(), $params);
437 $capability = 'moodle/site:manageallmessaging';
438 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
439 throw new required_capability_exception($context, $capability, 'nopermissions', '');
442 foreach ($params['conversationids'] as $conversationid) {
443 \core_message\api
::unmute_conversation($params['userid'], $conversationid);
450 * Unmute conversations return description.
452 * @return external_description
454 public static function unmute_conversations_returns() {
455 return new external_warnings();
459 * Block user parameters description.
461 * @return external_function_parameters
463 public static function block_user_parameters() {
464 return new external_function_parameters(
466 'userid' => new external_value(PARAM_INT
, 'The id of the user who is blocking'),
467 'blockeduserid' => new external_value(PARAM_INT
, 'The id of the user being blocked'),
475 * @param int $userid The id of the user who is blocking
476 * @param int $blockeduserid The id of the user being blocked
477 * @return external_description
479 public static function block_user(int $userid, int $blockeduserid) {
482 // Check if messaging is enabled.
483 if (empty($CFG->messaging
)) {
484 throw new moodle_exception('disabled', 'message');
488 $context = context_system
::instance();
489 self
::validate_context($context);
491 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
492 $params = self
::validate_parameters(self
::block_user_parameters(), $params);
494 $capability = 'moodle/site:manageallmessaging';
495 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
496 throw new required_capability_exception($context, $capability, 'nopermissions', '');
499 // If the blocking is going to be useless then don't do it.
500 if (\core_message\api
::can_send_message($userid, $blockeduserid, true)) {
504 if (!\core_message\api
::is_blocked($params['userid'], $params['blockeduserid'])) {
505 \core_message\api
::block_user($params['userid'], $params['blockeduserid']);
512 * Block user return description.
514 * @return external_description
516 public static function block_user_returns() {
517 return new external_warnings();
521 * Unblock user parameters description.
523 * @return external_function_parameters
525 public static function unblock_user_parameters() {
526 return new external_function_parameters(
528 'userid' => new external_value(PARAM_INT
, 'The id of the user who is unblocking'),
529 'unblockeduserid' => new external_value(PARAM_INT
, 'The id of the user being unblocked'),
537 * @param int $userid The id of the user who is unblocking
538 * @param int $unblockeduserid The id of the user being unblocked
540 public static function unblock_user(int $userid, int $unblockeduserid) {
543 // Check if messaging is enabled.
544 if (empty($CFG->messaging
)) {
545 throw new moodle_exception('disabled', 'message');
549 $context = context_system
::instance();
550 self
::validate_context($context);
552 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
553 $params = self
::validate_parameters(self
::unblock_user_parameters(), $params);
555 $capability = 'moodle/site:manageallmessaging';
556 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
557 throw new required_capability_exception($context, $capability, 'nopermissions', '');
560 \core_message\api
::unblock_user($params['userid'], $params['unblockeduserid']);
566 * Unblock user return description.
568 * @return external_description
570 public static function unblock_user_returns() {
571 return new external_warnings();
575 * Returns contact requests parameters description.
577 * @return external_function_parameters
579 public static function get_contact_requests_parameters() {
580 return new external_function_parameters(
582 'userid' => new external_value(PARAM_INT
, 'The id of the user we want the requests for'),
583 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
584 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
590 * Handles returning the contact requests for a user.
592 * This also includes the user data necessary to display information
595 * It will not include blocked users.
597 * @param int $userid The id of the user we want to get the contact requests for
598 * @param int $limitfrom
599 * @param int $limitnum
601 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) {
604 // Check if messaging is enabled.
605 if (empty($CFG->messaging
)) {
606 throw new moodle_exception('disabled', 'message');
610 $context = context_system
::instance();
611 self
::validate_context($context);
615 'limitfrom' => $limitfrom,
616 'limitnum' => $limitnum
618 $params = self
::validate_parameters(self
::get_contact_requests_parameters(), $params);
620 $capability = 'moodle/site:manageallmessaging';
621 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
622 throw new required_capability_exception($context, $capability, 'nopermissions', '');
625 return \core_message\api
::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']);
629 * Returns the contact requests return description.
631 * @return external_description
633 public static function get_contact_requests_returns() {
634 return new external_multiple_structure(
635 self
::get_conversation_member_structure()
640 * Returns the number of contact requests the user has received parameters description.
642 * @return external_function_parameters
644 public static function get_received_contact_requests_count_parameters() {
645 return new external_function_parameters(
647 'userid' => new external_value(PARAM_INT
, 'The id of the user we want to return the number of ' .
648 'received contact requests for', VALUE_REQUIRED
),
654 * Returns the number of contact requests the user has received.
656 * @param int $userid The ID of the user we want to return the number of received contact requests for
657 * @return external_value
659 public static function get_received_contact_requests_count(int $userid) {
662 // Check if messaging is enabled.
663 if (empty($CFG->messaging
)) {
664 throw new moodle_exception('disabled', 'message');
668 $context = context_system
::instance();
669 self
::validate_context($context);
674 $params = self
::validate_parameters(self
::get_received_contact_requests_count_parameters(), $params);
676 $capability = 'moodle/site:manageallmessaging';
677 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
678 throw new required_capability_exception($context, $capability, 'nopermissions', '');
681 return \core_message\api
::get_received_contact_requests_count($params['userid']);
685 * Returns the number of contact requests the user has received return description.
687 * @return external_value
689 public static function get_received_contact_requests_count_returns() {
690 return new external_value(PARAM_INT
, 'The number of received contact requests');
694 * Returns get conversation members parameters description.
696 * @return external_function_parameters
698 public static function get_conversation_members_parameters() {
699 return new external_function_parameters(
701 'userid' => new external_value(PARAM_INT
, 'The id of the user we are performing this action on behalf of'),
702 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation'),
703 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Do we want to include contact requests?',
704 VALUE_DEFAULT
, false),
705 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Do we want to include privacy info?',
706 VALUE_DEFAULT
, false),
707 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
708 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
714 * Returns a list of conversation members.
716 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
717 * @param int $conversationid The id of the conversation
718 * @param bool $includecontactrequests Do we want to include contact requests with this data?
719 * @param bool $includeprivacyinfo Do we want to include privacy info?
720 * @param int $limitfrom
721 * @param int $limitnum
724 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
725 bool $includeprivacyinfo = false, int $limitfrom = 0, int $limitnum = 0) {
728 // Check if messaging is enabled.
729 if (empty($CFG->messaging
)) {
730 throw new moodle_exception('disabled', 'message');
734 $context = context_system
::instance();
735 self
::validate_context($context);
739 'conversationid' => $conversationid,
740 'includecontactrequests' => $includecontactrequests,
741 'includeprivacyinfo' => $includeprivacyinfo,
742 'limitfrom' => $limitfrom,
743 'limitnum' => $limitnum
745 $params = self
::validate_parameters(self
::get_conversation_members_parameters(), $params);
747 $capability = 'moodle/site:manageallmessaging';
748 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
749 throw new required_capability_exception($context, $capability, 'nopermissions', '');
752 // The user needs to be a part of the conversation before querying who the members are.
753 if (!\core_message\api
::is_user_in_conversation($params['userid'], $params['conversationid'])) {
754 throw new moodle_exception('You are not a member of this conversation.');
757 return \core_message\api
::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'],
758 $params['includeprivacyinfo'], $params['limitfrom'], $params['limitnum']);
762 * Returns the get conversation members return description.
764 * @return external_description
766 public static function get_conversation_members_returns() {
767 return new external_multiple_structure(
768 self
::get_conversation_member_structure()
773 * Creates a contact request parameters description.
775 * @return external_function_parameters
777 public static function create_contact_request_parameters() {
778 return new external_function_parameters(
780 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
781 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
787 * Creates a contact request.
789 * @param int $userid The id of the user who is creating the contact request
790 * @param int $requesteduserid The id of the user being requested
792 public static function create_contact_request(int $userid, int $requesteduserid) {
795 // Check if messaging is enabled.
796 if (empty($CFG->messaging
)) {
797 throw new moodle_exception('disabled', 'message');
801 $context = context_system
::instance();
802 self
::validate_context($context);
804 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
805 $params = self
::validate_parameters(self
::create_contact_request_parameters(), $params);
807 $capability = 'moodle/site:manageallmessaging';
808 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
809 throw new required_capability_exception($context, $capability, 'nopermissions', '');
816 if (!\core_message\api
::can_create_contact($params['userid'], $params['requesteduserid'])) {
817 $result['warnings'][] = [
819 'itemid' => $params['requesteduserid'],
820 'warningcode' => 'cannotcreatecontactrequest',
821 'message' => 'You are unable to create a contact request for this user'
824 if ($requests = \core_message\api
::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) {
825 // There should only ever be one but just in case there are multiple then we can return the first.
826 $result['request'] = array_shift($requests);
828 $result['request'] = \core_message\api
::create_contact_request($params['userid'], $params['requesteduserid']);
836 * Creates a contact request return description.
838 * @return external_description
840 public static function create_contact_request_returns() {
841 return new external_single_structure(
843 'request' => new external_single_structure(
845 'id' => new external_value(PARAM_INT
, 'Message id'),
846 'userid' => new external_value(PARAM_INT
, 'User from id'),
847 'requesteduserid' => new external_value(PARAM_INT
, 'User to id'),
848 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
853 'warnings' => new external_warnings()
859 * Confirm a contact request parameters description.
861 * @return external_function_parameters
863 public static function confirm_contact_request_parameters() {
864 return new external_function_parameters(
866 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
867 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
873 * Confirm a contact request.
875 * @param int $userid The id of the user who is creating the contact request
876 * @param int $requesteduserid The id of the user being requested
878 public static function confirm_contact_request(int $userid, int $requesteduserid) {
881 // Check if messaging is enabled.
882 if (empty($CFG->messaging
)) {
883 throw new moodle_exception('disabled', 'message');
887 $context = context_system
::instance();
888 self
::validate_context($context);
890 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
891 $params = self
::validate_parameters(self
::confirm_contact_request_parameters(), $params);
893 $capability = 'moodle/site:manageallmessaging';
894 if (($USER->id
!= $params['requesteduserid']) && !has_capability($capability, $context)) {
895 throw new required_capability_exception($context, $capability, 'nopermissions', '');
898 \core_message\api
::confirm_contact_request($params['userid'], $params['requesteduserid']);
904 * Confirm a contact request return description.
906 * @return external_description
908 public static function confirm_contact_request_returns() {
909 return new external_warnings();
913 * Declines a contact request parameters description.
915 * @return external_function_parameters
917 public static function decline_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 * Declines 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 decline_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
::decline_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
::decline_contact_request($params['userid'], $params['requesteduserid']);
958 * Declines a contact request return description.
960 * @return external_description
962 public static function decline_contact_request_returns() {
963 return new external_warnings();
967 * Return the structure of a message area contact.
969 * @return external_single_structure
972 private static function get_messagearea_contact_structure() {
973 return new external_single_structure(
975 'userid' => new external_value(PARAM_INT
, 'The user\'s id'),
976 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
977 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
978 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
979 'ismessaging' => new external_value(PARAM_BOOL
, 'If we are messaging the user'),
980 'sentfromcurrentuser' => new external_value(PARAM_BOOL
, 'Was the last message sent from the current user?'),
981 'lastmessage' => new external_value(PARAM_NOTAGS
, 'The user\'s last message'),
982 'lastmessagedate' => new external_value(PARAM_INT
, 'Timestamp for last message', VALUE_DEFAULT
, null),
983 'messageid' => new external_value(PARAM_INT
, 'The unique search message id', VALUE_DEFAULT
, null),
984 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
985 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
986 'isread' => new external_value(PARAM_BOOL
, 'If the user has read the message'),
987 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
988 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
989 VALUE_DEFAULT
, null),
990 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation', VALUE_DEFAULT
, null),
996 * Return the structure of a conversation.
998 * @return external_single_structure
1001 private static function get_conversation_structure() {
1002 return new external_single_structure(
1004 'id' => new external_value(PARAM_INT
, 'The conversation id'),
1005 'name' => new external_value(PARAM_RAW
, 'The conversation name, if set', VALUE_DEFAULT
, null),
1006 'subname' => new external_value(PARAM_RAW
, 'A subtitle for the conversation name, if set', VALUE_DEFAULT
, null),
1007 'imageurl' => new external_value(PARAM_URL
, 'A link to the conversation picture, if set', VALUE_DEFAULT
, null),
1008 'type' => new external_value(PARAM_INT
, 'The type of the conversation (1=individual,2=group,3=self)'),
1009 'membercount' => new external_value(PARAM_INT
, 'Total number of conversation members'),
1010 'ismuted' => new external_value(PARAM_BOOL
, 'If the user muted this conversation'),
1011 'isfavourite' => new external_value(PARAM_BOOL
, 'If the user marked this conversation as a favourite'),
1012 'isread' => new external_value(PARAM_BOOL
, 'If the user has read all messages in the conversation'),
1013 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
1014 VALUE_DEFAULT
, null),
1015 'members' => new external_multiple_structure(
1016 self
::get_conversation_member_structure()
1018 'messages' => new external_multiple_structure(
1019 self
::get_conversation_message_structure()
1021 'candeletemessagesforallusers' => new external_value(PARAM_BOOL
,
1022 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT
, false),
1028 * Return the structure of a conversation member.
1030 * @return external_single_structure
1033 private static function get_conversation_member_structure() {
1035 'id' => new external_value(PARAM_INT
, 'The user id'),
1036 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
1037 'profileurl' => new external_value(PARAM_URL
, 'The link to the user\'s profile page'),
1038 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
1039 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
1040 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1041 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1042 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
1043 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?'),
1044 'isdeleted' => new external_value(PARAM_BOOL
, 'Is the user deleted?'),
1045 'canmessageevenifblocked' => new external_value(PARAM_BOOL
,
1046 'If the user can still message even if they get blocked'),
1047 'canmessage' => new external_value(PARAM_BOOL
, 'If the user can be messaged'),
1048 'requirescontact' => new external_value(PARAM_BOOL
, 'If the user requires to be contacts'),
1051 $result['contactrequests'] = new external_multiple_structure(
1052 new external_single_structure(
1054 'id' => new external_value(PARAM_INT
, 'The id of the contact request'),
1055 'userid' => new external_value(PARAM_INT
, 'The id of the user who created the contact request'),
1056 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user confirming the request'),
1057 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the contact request'),
1059 ), 'The contact requests', VALUE_OPTIONAL
1062 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1064 'id' => new external_value(PARAM_INT
, 'Conversations id'),
1065 'type' => new external_value(PARAM_INT
, 'Conversation type: private or public'),
1066 'name' => new external_value(PARAM_RAW
, 'Multilang compatible conversation name'. VALUE_OPTIONAL
),
1067 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the conversation'),
1068 ), 'information about conversation', VALUE_OPTIONAL
),
1069 'Conversations between users', VALUE_OPTIONAL
1072 return new external_single_structure(
1078 * Return the structure of a message area message.
1080 * @return external_single_structure
1083 private static function get_conversation_message_structure() {
1084 return new external_single_structure(
1086 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1087 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1088 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
1089 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1095 * Get messagearea message search users parameters.
1097 * @return external_function_parameters
1100 public static function message_search_users_parameters() {
1101 return new external_function_parameters(
1103 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1104 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1105 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1106 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1112 * Get search users results.
1114 * @param int $userid The id of the user who is performing the search
1115 * @param string $search The string being searched
1116 * @param int $limitfrom
1117 * @param int $limitnum
1119 * @throws moodle_exception
1122 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
1125 $systemcontext = context_system
::instance();
1128 'userid' => $userid,
1129 'search' => $search,
1130 'limitfrom' => $limitfrom,
1131 'limitnum' => $limitnum
1133 $params = self
::validate_parameters(self
::message_search_users_parameters(), $params);
1134 self
::validate_context($systemcontext);
1136 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1137 throw new moodle_exception('You do not have permission to perform this action.');
1140 list($contacts, $noncontacts) = \core_message\api
::message_search_users(
1143 $params['limitfrom'],
1144 $params['limitnum']);
1146 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1150 * Get messagearea message search users returns.
1152 * @return external_single_structure
1155 public static function message_search_users_returns() {
1156 return new external_single_structure(
1158 'contacts' => new external_multiple_structure(
1159 self
::get_conversation_member_structure()
1161 'noncontacts' => new external_multiple_structure(
1162 self
::get_conversation_member_structure()
1169 * Get messagearea search messages parameters.
1171 * @return external_function_parameters
1174 public static function data_for_messagearea_search_messages_parameters() {
1175 return new external_function_parameters(
1177 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1178 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1179 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1180 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1186 * Get messagearea search messages results.
1188 * @param int $userid The id of the user who is performing the search
1189 * @param string $search The string being searched
1190 * @param int $limitfrom
1191 * @param int $limitnum
1193 * @throws moodle_exception
1196 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1199 // Check if messaging is enabled.
1200 if (empty($CFG->messaging
)) {
1201 throw new moodle_exception('disabled', 'message');
1204 $systemcontext = context_system
::instance();
1207 'userid' => $userid,
1208 'search' => $search,
1209 'limitfrom' => $limitfrom,
1210 'limitnum' => $limitnum
1213 $params = self
::validate_parameters(self
::data_for_messagearea_search_messages_parameters(), $params);
1214 self
::validate_context($systemcontext);
1216 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1217 throw new moodle_exception('You do not have permission to perform this action.');
1220 $messages = \core_message\api
::search_messages(
1223 $params['limitfrom'],
1227 $data = new \
stdClass();
1228 $data->contacts
= [];
1229 foreach ($messages as $message) {
1230 $contact = new \
stdClass();
1231 $contact->userid
= $message->userid
;
1232 $contact->fullname
= $message->fullname
;
1233 $contact->profileimageurl
= $message->profileimageurl
;
1234 $contact->profileimageurlsmall
= $message->profileimageurlsmall
;
1235 $contact->messageid
= $message->messageid
;
1236 $contact->ismessaging
= $message->ismessaging
;
1237 $contact->sentfromcurrentuser
= false;
1238 if ($message->lastmessage
) {
1239 if ($message->userid
!== $message->useridfrom
) {
1240 $contact->sentfromcurrentuser
= true;
1242 $contact->lastmessage
= shorten_text($message->lastmessage
, 60);
1244 $contact->lastmessage
= null;
1246 $contact->lastmessagedate
= $message->lastmessagedate
;
1247 $contact->showonlinestatus
= is_null($message->isonline
) ?
false : true;
1248 $contact->isonline
= $message->isonline
;
1249 $contact->isblocked
= $message->isblocked
;
1250 $contact->isread
= $message->isread
;
1251 $contact->unreadcount
= $message->unreadcount
;
1252 $contact->conversationid
= $message->conversationid
;
1254 $data->contacts
[] = $contact;
1261 * Get messagearea search messages returns.
1263 * @return external_single_structure
1266 public static function data_for_messagearea_search_messages_returns() {
1267 return new external_single_structure(
1269 'contacts' => new external_multiple_structure(
1270 self
::get_messagearea_contact_structure()
1277 * Get conversations parameters.
1279 * @return external_function_parameters
1282 public static function get_conversations_parameters() {
1283 return new external_function_parameters(
1285 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1286 'limitfrom' => new external_value(PARAM_INT
, 'The offset to start at', VALUE_DEFAULT
, 0),
1287 'limitnum' => new external_value(PARAM_INT
, 'Limit number of conversations to this', VALUE_DEFAULT
, 0),
1288 'type' => new external_value(PARAM_INT
, 'Filter by type', VALUE_DEFAULT
, null),
1289 'favourites' => new external_value(PARAM_BOOL
, 'Whether to restrict the results to contain NO favourite
1290 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1291 VALUE_DEFAULT
, null),
1292 'mergeself' => new external_value(PARAM_BOOL
, 'Whether to include self-conversations (true) or ONLY private
1293 conversations (false) when private conversations are requested.',
1294 VALUE_DEFAULT
, false),
1300 * Get the list of conversations for the user.
1302 * @param int $userid The id of the user who is performing the search
1303 * @param int $limitfrom
1304 * @param int $limitnum
1305 * @param int|null $type
1306 * @param bool|null $favourites
1307 * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false)
1308 * when private conversations are requested.
1310 * @throws \moodle_exception if the messaging feature is disabled on the site.
1313 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null,
1314 bool $mergeself = false) {
1317 // All the standard BL checks.
1318 if (empty($CFG->messaging
)) {
1319 throw new moodle_exception('disabled', 'message');
1323 'userid' => $userid,
1324 'limitfrom' => $limitfrom,
1325 'limitnum' => $limitnum,
1327 'favourites' => $favourites,
1328 'mergeself' => $mergeself
1330 $params = self
::validate_parameters(self
::get_conversations_parameters(), $params);
1332 $systemcontext = context_system
::instance();
1333 self
::validate_context($systemcontext);
1335 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1336 throw new moodle_exception('You do not have permission to perform this action.');
1339 $conversations = \core_message\api
::get_conversations(
1341 $params['limitfrom'],
1342 $params['limitnum'],
1344 $params['favourites'],
1345 $params['mergeself']
1348 return (object) ['conversations' => $conversations];
1352 * Get conversations returns.
1354 * @return external_single_structure
1357 public static function get_conversations_returns() {
1358 return new external_single_structure(
1360 'conversations' => new external_multiple_structure(
1361 self
::get_conversation_structure(true)
1368 * Get conversation parameters.
1370 * @return external_function_parameters
1372 public static function get_conversation_parameters() {
1373 return new external_function_parameters(
1375 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1376 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation to fetch'),
1377 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Include contact requests in the members'),
1378 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Include privacy info in the members'),
1379 'memberlimit' => new external_value(PARAM_INT
, 'Limit for number of members', VALUE_DEFAULT
, 0),
1380 'memberoffset' => new external_value(PARAM_INT
, 'Offset for member list', VALUE_DEFAULT
, 0),
1381 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1382 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1383 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1389 * Get a single conversation.
1391 * @param int $userid The user id to get the conversation for
1392 * @param int $conversationid The id of the conversation to fetch
1393 * @param bool $includecontactrequests Should contact requests be included between members
1394 * @param bool $includeprivacyinfo Should privacy info be included between members
1395 * @param int $memberlimit Limit number of members to load
1396 * @param int $memberoffset Offset members by this amount
1397 * @param int $messagelimit Limit number of messages to load
1398 * @param int $messageoffset Offset the messages
1399 * @param bool $newestmessagesfirst Order messages by newest first
1401 * @throws \moodle_exception if the messaging feature is disabled on the site.
1403 public static function get_conversation(
1405 int $conversationid,
1406 bool $includecontactrequests = false,
1407 bool $includeprivacyinfo = false,
1408 int $memberlimit = 0,
1409 int $memberoffset = 0,
1410 int $messagelimit = 0,
1411 int $messageoffset = 0,
1412 bool $newestmessagesfirst = true
1414 global $CFG, $DB, $USER;
1416 // All the standard BL checks.
1417 if (empty($CFG->messaging
)) {
1418 throw new moodle_exception('disabled', 'message');
1422 'userid' => $userid,
1423 'conversationid' => $conversationid,
1424 'includecontactrequests' => $includecontactrequests,
1425 'includeprivacyinfo' => $includeprivacyinfo,
1426 'memberlimit' => $memberlimit,
1427 'memberoffset' => $memberoffset,
1428 'messagelimit' => $messagelimit,
1429 'messageoffset' => $messageoffset,
1430 'newestmessagesfirst' => $newestmessagesfirst
1432 self
::validate_parameters(self
::get_conversation_parameters(), $params);
1434 $systemcontext = context_system
::instance();
1435 self
::validate_context($systemcontext);
1437 $conversation = \core_message\api
::get_conversation(
1439 $params['conversationid'],
1440 $params['includecontactrequests'],
1441 $params['includeprivacyinfo'],
1442 $params['memberlimit'],
1443 $params['memberoffset'],
1444 $params['messagelimit'],
1445 $params['messageoffset'],
1446 $params['newestmessagesfirst']
1449 if ($conversation) {
1450 return $conversation;
1452 // We have to throw an exception here because the external functions annoyingly
1453 // don't accept null to be returned for a single structure.
1454 throw new \
moodle_exception('errorconversationdoesnotexist', 'message');
1459 * Get conversation returns.
1461 * @return external_single_structure
1463 public static function get_conversation_returns() {
1464 return self
::get_conversation_structure();
1468 * Get conversation parameters.
1470 * @return external_function_parameters
1472 public static function get_conversation_between_users_parameters() {
1473 return new external_function_parameters(
1475 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1476 'otheruserid' => new external_value(PARAM_INT
, 'The other user id'),
1477 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Include contact requests in the members'),
1478 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Include privacy info in the members'),
1479 'memberlimit' => new external_value(PARAM_INT
, 'Limit for number of members', VALUE_DEFAULT
, 0),
1480 'memberoffset' => new external_value(PARAM_INT
, 'Offset for member list', VALUE_DEFAULT
, 0),
1481 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1482 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1483 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1489 * Get a single conversation between users.
1491 * @param int $userid The user id to get the conversation for
1492 * @param int $otheruserid The other user id
1493 * @param bool $includecontactrequests Should contact requests be included between members
1494 * @param bool $includeprivacyinfo Should privacy info be included between members
1495 * @param int $memberlimit Limit number of members to load
1496 * @param int $memberoffset Offset members by this amount
1497 * @param int $messagelimit Limit number of messages to load
1498 * @param int $messageoffset Offset the messages
1499 * @param bool $newestmessagesfirst Order messages by newest first
1501 * @throws \moodle_exception if the messaging feature is disabled on the site.
1503 public static function get_conversation_between_users(
1506 bool $includecontactrequests = false,
1507 bool $includeprivacyinfo = false,
1508 int $memberlimit = 0,
1509 int $memberoffset = 0,
1510 int $messagelimit = 0,
1511 int $messageoffset = 0,
1512 bool $newestmessagesfirst = true
1514 global $CFG, $DB, $USER;
1516 // All the standard BL checks.
1517 if (empty($CFG->messaging
)) {
1518 throw new moodle_exception('disabled', 'message');
1522 'userid' => $userid,
1523 'otheruserid' => $otheruserid,
1524 'includecontactrequests' => $includecontactrequests,
1525 'includeprivacyinfo' => $includeprivacyinfo,
1526 'memberlimit' => $memberlimit,
1527 'memberoffset' => $memberoffset,
1528 'messagelimit' => $messagelimit,
1529 'messageoffset' => $messageoffset,
1530 'newestmessagesfirst' => $newestmessagesfirst
1532 self
::validate_parameters(self
::get_conversation_between_users_parameters(), $params);
1534 $systemcontext = context_system
::instance();
1535 self
::validate_context($systemcontext);
1537 $conversationid = \core_message\api
::get_conversation_between_users([$params['userid'], $params['otheruserid']]);
1538 $conversation = null;
1540 if ($conversationid) {
1541 $conversation = \core_message\api
::get_conversation(
1544 $params['includecontactrequests'],
1545 $params['includeprivacyinfo'],
1546 $params['memberlimit'],
1547 $params['memberoffset'],
1548 $params['messagelimit'],
1549 $params['messageoffset'],
1550 $params['newestmessagesfirst']
1554 if ($conversation) {
1555 return $conversation;
1557 // We have to throw an exception here because the external functions annoyingly
1558 // don't accept null to be returned for a single structure.
1559 throw new \
moodle_exception('errorconversationdoesnotexist', 'message');
1564 * Get conversation returns.
1566 * @return external_single_structure
1568 public static function get_conversation_between_users_returns() {
1569 return self
::get_conversation_structure(true);
1573 * Get self-conversation parameters.
1575 * @return external_function_parameters
1577 public static function get_self_conversation_parameters() {
1578 return new external_function_parameters(
1580 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing self-conversations for'),
1581 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1582 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1583 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1589 * Get a single self-conversation.
1591 * @param int $userid The user id to get the self-conversation for
1592 * @param int $messagelimit Limit number of messages to load
1593 * @param int $messageoffset Offset the messages
1594 * @param bool $newestmessagesfirst Order messages by newest first
1596 * @throws \moodle_exception if the messaging feature is disabled on the site.
1599 public static function get_self_conversation(
1601 int $messagelimit = 0,
1602 int $messageoffset = 0,
1603 bool $newestmessagesfirst = true
1607 // All the standard BL checks.
1608 if (empty($CFG->messaging
)) {
1609 throw new moodle_exception('disabled', 'message');
1613 'userid' => $userid,
1614 'messagelimit' => $messagelimit,
1615 'messageoffset' => $messageoffset,
1616 'newestmessagesfirst' => $newestmessagesfirst
1618 self
::validate_parameters(self
::get_self_conversation_parameters(), $params);
1620 $systemcontext = context_system
::instance();
1621 self
::validate_context($systemcontext);
1623 $conversation = \core_message\api
::get_self_conversation($params['userid']);
1625 if ($conversation) {
1626 $conversation = \core_message\api
::get_conversation(
1633 $params['messagelimit'],
1634 $params['messageoffset'],
1635 $params['newestmessagesfirst']
1639 if ($conversation) {
1640 return $conversation;
1642 // We have to throw an exception here because the external functions annoyingly
1643 // don't accept null to be returned for a single structure.
1644 throw new \
moodle_exception('errorconversationdoesnotexist', 'message');
1649 * Get conversation returns.
1651 * @return external_single_structure
1653 public static function get_self_conversation_returns() {
1654 return self
::get_conversation_structure();
1658 * The conversation messages parameters.
1660 * @return external_function_parameters
1663 public static function get_conversation_messages_parameters() {
1664 return new external_function_parameters(
1666 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1667 'convid' => new external_value(PARAM_INT
, 'The conversation id'),
1668 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1669 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1670 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
1671 'timefrom' => new external_value(PARAM_INT
,
1672 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
1678 * Get conversation messages.
1680 * @param int $currentuserid The current user's id.
1681 * @param int $convid The conversation id.
1682 * @param int $limitfrom Return a subset of records, starting at this point (optional).
1683 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
1684 * @param bool $newest True for getting first newest messages, false otherwise.
1685 * @param int $timefrom The time from the conversation messages to get.
1686 * @return array The messages and members who have sent some of these messages.
1687 * @throws moodle_exception
1690 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
1691 bool $newest = false, int $timefrom = 0) {
1694 // Check if messaging is enabled.
1695 if (empty($CFG->messaging
)) {
1696 throw new moodle_exception('disabled', 'message');
1699 $systemcontext = context_system
::instance();
1702 'currentuserid' => $currentuserid,
1703 'convid' => $convid,
1704 'limitfrom' => $limitfrom,
1705 'limitnum' => $limitnum,
1706 'newest' => $newest,
1707 'timefrom' => $timefrom,
1709 $params = self
::validate_parameters(self
::get_conversation_messages_parameters(), $params);
1710 self
::validate_context($systemcontext);
1712 if (($USER->id
!= $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1713 throw new moodle_exception('You do not have permission to perform this action.');
1716 // Check that the user belongs to the conversation.
1717 if (!\core_message\api
::is_user_in_conversation($params['currentuserid'], $params['convid'])) {
1718 throw new moodle_exception('User is not part of conversation.');
1721 $sort = $newest ?
'timecreated DESC' : 'timecreated ASC';
1723 // We need to enforce a one second delay on messages to avoid race conditions of current
1724 // messages still being sent.
1726 // There is a chance that we could request messages before the current time's
1727 // second has elapsed and while other messages are being sent in that same second. In which
1728 // case those messages will be lost.
1730 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
1731 $timeto = empty($params['timefrom']) ?
0 : time() - 1;
1733 // No requesting messages from the current time, as stated above.
1734 if ($params['timefrom'] == time()) {
1737 $messages = \core_message\api
::get_conversation_messages(
1738 $params['currentuserid'],
1740 $params['limitfrom'],
1741 $params['limitnum'],
1743 $params['timefrom'],
1751 * The messagearea messages return structure.
1753 * @return external_single_structure
1756 public static function get_conversation_messages_returns() {
1757 return new external_single_structure(
1759 'id' => new external_value(PARAM_INT
, 'The conversation id'),
1760 'members' => new external_multiple_structure(
1761 self
::get_conversation_member_structure()
1763 'messages' => new external_multiple_structure(
1764 self
::get_conversation_message_structure()
1771 * The user contacts return parameters.
1773 * @return external_function_parameters
1775 public static function get_user_contacts_parameters() {
1776 return new external_function_parameters(
1778 'userid' => new external_value(PARAM_INT
, 'The id of the user who we retrieving the contacts for'),
1779 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1780 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1786 * Get user contacts.
1788 * @param int $userid The id of the user who we are viewing conversations for
1789 * @param int $limitfrom
1790 * @param int $limitnum
1792 * @throws moodle_exception
1794 public static function get_user_contacts(int $userid, int $limitfrom = 0, int $limitnum = 0) {
1797 // Check if messaging is enabled.
1798 if (empty($CFG->messaging
)) {
1799 throw new moodle_exception('disabled', 'message');
1802 $systemcontext = context_system
::instance();
1805 'userid' => $userid,
1806 'limitfrom' => $limitfrom,
1807 'limitnum' => $limitnum
1809 $params = self
::validate_parameters(self
::get_user_contacts_parameters(), $params);
1810 self
::validate_context($systemcontext);
1812 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1813 throw new moodle_exception('You do not have permission to perform this action.');
1816 return \core_message\api
::get_user_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
1820 * The user contacts return structure.
1822 * @return external_multiple_structure
1824 public static function get_user_contacts_returns() {
1825 return new external_multiple_structure(
1826 self
::get_conversation_member_structure()
1831 * Search contacts parameters description.
1833 * @return external_function_parameters
1836 public static function search_contacts_parameters() {
1837 return new external_function_parameters(
1839 'searchtext' => new external_value(PARAM_CLEAN
, 'String the user\'s fullname has to match to be found'),
1840 'onlymycourses' => new external_value(PARAM_BOOL
, 'Limit search to the user\'s courses',
1841 VALUE_DEFAULT
, false)
1849 * @param string $searchtext query string.
1850 * @param bool $onlymycourses limit the search to the user's courses only.
1851 * @return external_description
1854 public static function search_contacts($searchtext, $onlymycourses = false) {
1855 global $CFG, $USER, $PAGE;
1856 require_once($CFG->dirroot
. '/user/lib.php');
1858 // Check if messaging is enabled.
1859 if (empty($CFG->messaging
)) {
1860 throw new moodle_exception('disabled', 'message');
1863 require_once($CFG->libdir
. '/enrollib.php');
1865 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1866 $params = self
::validate_parameters(self
::search_contacts_parameters(), $params);
1868 // Extra validation, we do not allow empty queries.
1869 if ($params['searchtext'] === '') {
1870 throw new moodle_exception('querystringcannotbeempty');
1873 $courseids = array();
1874 if ($params['onlymycourses']) {
1875 $mycourses = enrol_get_my_courses(array('id'));
1876 foreach ($mycourses as $mycourse) {
1877 $courseids[] = $mycourse->id
;
1880 $courseids[] = SITEID
;
1883 // Retrieving the users matching the query.
1884 $users = message_search_users($courseids, $params['searchtext']);
1886 foreach ($users as $user) {
1887 $results[$user->id
] = $user;
1890 // Reorganising information.
1891 foreach ($results as &$user) {
1894 'fullname' => fullname($user)
1897 // Avoid undefined property notice as phone not specified.
1898 $user->phone1
= null;
1899 $user->phone2
= null;
1901 $userpicture = new user_picture($user);
1902 $userpicture->size
= 1; // Size f1.
1903 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1904 $userpicture->size
= 0; // Size f2.
1905 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1914 * Search contacts return description.
1916 * @return external_description
1919 public static function search_contacts_returns() {
1920 return new external_multiple_structure(
1921 new external_single_structure(
1923 'id' => new external_value(PARAM_INT
, 'User ID'),
1924 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1925 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1926 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
)
1934 * Get messages parameters description.
1936 * @return external_function_parameters
1939 public static function get_messages_parameters() {
1940 return new external_function_parameters(
1942 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
1943 'useridfrom' => new external_value(
1944 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1946 'type' => new external_value(
1947 PARAM_ALPHA
, 'type of message to return, expected values are: notifications, conversations and both',
1948 VALUE_DEFAULT
, 'both'),
1949 'read' => new external_value(PARAM_BOOL
, 'true for getting read messages, false for unread', VALUE_DEFAULT
, true),
1950 'newestfirst' => new external_value(
1951 PARAM_BOOL
, 'true for ordering by newest first, false for oldest first',
1952 VALUE_DEFAULT
, true),
1953 'limitfrom' => new external_value(PARAM_INT
, 'limit from', VALUE_DEFAULT
, 0),
1954 'limitnum' => new external_value(PARAM_INT
, 'limit number', VALUE_DEFAULT
, 0)
1960 * Get messages function implementation.
1963 * @throws invalid_parameter_exception
1964 * @throws moodle_exception
1965 * @param int $useridto the user id who received the message
1966 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1967 * @param string $type type of message to return, expected values: notifications, conversations and both
1968 * @param bool $read true for retreiving read messages, false for unread
1969 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1970 * @param int $limitfrom limit from
1971 * @param int $limitnum limit num
1972 * @return external_description
1974 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
1975 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
1978 $warnings = array();
1981 'useridto' => $useridto,
1982 'useridfrom' => $useridfrom,
1985 'newestfirst' => $newestfirst,
1986 'limitfrom' => $limitfrom,
1987 'limitnum' => $limitnum
1990 $params = self
::validate_parameters(self
::get_messages_parameters(), $params);
1992 $context = context_system
::instance();
1993 self
::validate_context($context);
1995 $useridto = $params['useridto'];
1996 $useridfrom = $params['useridfrom'];
1997 $type = $params['type'];
1998 $read = $params['read'];
1999 $newestfirst = $params['newestfirst'];
2000 $limitfrom = $params['limitfrom'];
2001 $limitnum = $params['limitnum'];
2003 $allowedvalues = array('notifications', 'conversations', 'both');
2004 if (!in_array($type, $allowedvalues)) {
2005 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
2006 'allowed values are: ' . implode(',', $allowedvalues));
2009 // Check if private messaging between users is allowed.
2010 if (empty($CFG->messaging
)) {
2011 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
2012 if ($type == "conversations") {
2013 throw new moodle_exception('disabled', 'message');
2015 if ($type == "both") {
2017 $warning['item'] = 'message';
2018 $warning['itemid'] = $USER->id
;
2019 $warning['warningcode'] = '1';
2020 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
2021 Only notifications will be returned';
2022 $warnings[] = $warning;
2026 if (!empty($useridto)) {
2027 if (core_user
::is_real_user($useridto)) {
2028 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2030 throw new moodle_exception('invaliduser');
2034 if (!empty($useridfrom)) {
2035 // We use get_user here because the from user can be the noreply or support user.
2036 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2039 // Check if the current user is the sender/receiver or just a privileged user.
2040 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2041 !has_capability('moodle/site:readallmessages', $context)) {
2042 throw new moodle_exception('accessdenied', 'admin');
2045 // Which type of messages to retrieve.
2046 $notifications = -1;
2047 if ($type != 'both') {
2048 $notifications = ($type == 'notifications') ?
1 : 0;
2051 $orderdirection = $newestfirst ?
'DESC' : 'ASC';
2052 $sort = "mr.timecreated $orderdirection";
2054 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
2055 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
2057 // In some cases, we don't need to get the to/from user objects from the sql query.
2058 $userfromfullname = '';
2059 $usertofullname = '';
2061 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
2062 if (!empty($useridto)) {
2063 $usertofullname = fullname($userto, $canviewfullname);
2064 // The user from may or may not be filled.
2065 if (!empty($useridfrom)) {
2066 $userfromfullname = fullname($userfrom, $canviewfullname);
2069 // If the useridto field is empty, the useridfrom must be filled.
2070 $userfromfullname = fullname($userfrom, $canviewfullname);
2072 foreach ($messages as $mid => $message) {
2074 // Do not return deleted messages.
2075 if (!$message->notification
) {
2076 if (($useridto == $USER->id
and $message->timeusertodeleted
) or
2077 ($useridfrom == $USER->id
and $message->timeuserfromdeleted
)) {
2078 unset($messages[$mid]);
2083 // We need to get the user from the query.
2084 if (empty($userfromfullname)) {
2085 // Check for non-reply and support users.
2086 if (core_user
::is_real_user($message->useridfrom
)) {
2087 $user = new stdClass();
2088 $user = username_load_fields_from_object($user, $message, 'userfrom');
2089 $message->userfromfullname
= fullname($user, $canviewfullname);
2091 $user = core_user
::get_user($message->useridfrom
);
2092 $message->userfromfullname
= fullname($user, $canviewfullname);
2095 $message->userfromfullname
= $userfromfullname;
2098 // We need to get the user from the query.
2099 if (empty($usertofullname)) {
2100 $user = new stdClass();
2101 $user = username_load_fields_from_object($user, $message, 'userto');
2102 $message->usertofullname
= fullname($user, $canviewfullname);
2104 $message->usertofullname
= $usertofullname;
2107 $message->text
= message_format_message_text($message);
2108 $messages[$mid] = (array) $message;
2113 'messages' => $messages,
2114 'warnings' => $warnings
2121 * Get messages return description.
2123 * @return external_single_structure
2126 public static function get_messages_returns() {
2127 return new external_single_structure(
2129 'messages' => new external_multiple_structure(
2130 new external_single_structure(
2132 'id' => new external_value(PARAM_INT
, 'Message id'),
2133 'useridfrom' => new external_value(PARAM_INT
, 'User from id'),
2134 'useridto' => new external_value(PARAM_INT
, 'User to id'),
2135 'subject' => new external_value(PARAM_TEXT
, 'The message subject'),
2136 'text' => new external_value(PARAM_RAW
, 'The message text formated'),
2137 'fullmessage' => new external_value(PARAM_RAW
, 'The message'),
2138 'fullmessageformat' => new external_format_value('fullmessage'),
2139 'fullmessagehtml' => new external_value(PARAM_RAW
, 'The message in html'),
2140 'smallmessage' => new external_value(PARAM_RAW
, 'The shorten message'),
2141 'notification' => new external_value(PARAM_INT
, 'Is a notification?'),
2142 'contexturl' => new external_value(PARAM_RAW
, 'Context URL'),
2143 'contexturlname' => new external_value(PARAM_TEXT
, 'Context URL link name'),
2144 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
2145 'timeread' => new external_value(PARAM_INT
, 'Time read'),
2146 'usertofullname' => new external_value(PARAM_TEXT
, 'User to full name'),
2147 'userfromfullname' => new external_value(PARAM_TEXT
, 'User from full name'),
2148 'component' => new external_value(PARAM_TEXT
, 'The component that generated the notification',
2150 'eventtype' => new external_value(PARAM_TEXT
, 'The type of notification', VALUE_OPTIONAL
),
2151 'customdata' => new external_value(PARAM_RAW
, 'Custom data to be passed to the message processor.
2152 The data here is serialised using json_encode().', VALUE_OPTIONAL
),
2156 'warnings' => new external_warnings()
2162 * Mark all notifications as read parameters description.
2164 * @return external_function_parameters
2167 public static function mark_all_notifications_as_read_parameters() {
2168 return new external_function_parameters(
2170 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2171 'useridfrom' => new external_value(
2172 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2174 'timecreatedto' => new external_value(
2175 PARAM_INT
, 'mark messages created before this time as read, 0 for all messages',
2182 * Mark all notifications as read function.
2185 * @throws invalid_parameter_exception
2186 * @throws moodle_exception
2187 * @param int $useridto the user id who received the message
2188 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2189 * @param int $timecreatedto mark message created before this time as read, 0 for all messages
2190 * @return external_description
2192 public static function mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto = 0) {
2195 $params = self
::validate_parameters(
2196 self
::mark_all_notifications_as_read_parameters(),
2198 'useridto' => $useridto,
2199 'useridfrom' => $useridfrom,
2200 'timecreatedto' => $timecreatedto,
2204 $context = context_system
::instance();
2205 self
::validate_context($context);
2207 $useridto = $params['useridto'];
2208 $useridfrom = $params['useridfrom'];
2209 $timecreatedto = $params['timecreatedto'];
2211 if (!empty($useridto)) {
2212 if (core_user
::is_real_user($useridto)) {
2213 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2215 throw new moodle_exception('invaliduser');
2219 if (!empty($useridfrom)) {
2220 // We use get_user here because the from user can be the noreply or support user.
2221 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2224 // Check if the current user is the sender/receiver or just a privileged user.
2225 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2226 // The deleteanymessage cap seems more reasonable here than readallmessages.
2227 !has_capability('moodle/site:deleteanymessage', $context)) {
2228 throw new moodle_exception('accessdenied', 'admin');
2231 \core_message\api
::mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto);
2237 * Mark all notifications as read return description.
2239 * @return external_single_structure
2242 public static function mark_all_notifications_as_read_returns() {
2243 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
2247 * Get unread conversations count parameters description.
2249 * @return external_function_parameters
2252 public static function get_unread_conversations_count_parameters() {
2253 return new external_function_parameters(
2255 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2261 * Get unread messages count function.
2264 * @throws invalid_parameter_exception
2265 * @throws moodle_exception
2266 * @param int $useridto the user id who received the message
2267 * @return external_description
2269 public static function get_unread_conversations_count($useridto) {
2272 // Check if messaging is enabled.
2273 if (empty($CFG->messaging
)) {
2274 throw new moodle_exception('disabled', 'message');
2277 $params = self
::validate_parameters(
2278 self
::get_unread_conversations_count_parameters(),
2279 array('useridto' => $useridto)
2282 $context = context_system
::instance();
2283 self
::validate_context($context);
2285 $useridto = $params['useridto'];
2287 if (!empty($useridto)) {
2288 if (core_user
::is_real_user($useridto)) {
2289 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2291 throw new moodle_exception('invaliduser');
2294 $useridto = $USER->id
;
2297 // Check if the current user is the receiver or just a privileged user.
2298 if ($useridto != $USER->id
and !has_capability('moodle/site:readallmessages', $context)) {
2299 throw new moodle_exception('accessdenied', 'admin');
2302 return \core_message\api
::count_unread_conversations($userto);
2306 * Get unread conversations count return description.
2308 * @return external_single_structure
2311 public static function get_unread_conversations_count_returns() {
2312 return new external_value(PARAM_INT
, 'The count of unread messages for the user');
2316 * Get blocked users parameters description.
2318 * @return external_function_parameters
2321 public static function get_blocked_users_parameters() {
2322 return new external_function_parameters(
2324 'userid' => new external_value(PARAM_INT
,
2325 'the user whose blocked users we want to retrieve',
2332 * Retrieve a list of users blocked
2334 * @param int $userid the user whose blocked users we want to retrieve
2335 * @return external_description
2338 public static function get_blocked_users($userid) {
2339 global $CFG, $USER, $PAGE;
2341 // Warnings array, it can be empty at the end but is mandatory.
2342 $warnings = array();
2348 $params = self
::validate_parameters(self
::get_blocked_users_parameters(), $params);
2349 $userid = $params['userid'];
2351 // Validate context.
2352 $context = context_system
::instance();
2353 self
::validate_context($context);
2355 // Check if private messaging between users is allowed.
2356 if (empty($CFG->messaging
)) {
2357 throw new moodle_exception('disabled', 'message');
2360 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
2361 core_user
::require_active_user($user);
2363 // Check if we have permissions for retrieve the information.
2364 $capability = 'moodle/site:manageallmessaging';
2365 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
2366 throw new required_capability_exception($context, $capability, 'nopermissions', '');
2369 // Now, we can get safely all the blocked users.
2370 $users = \core_message\api
::get_blocked_users($user->id
);
2372 $blockedusers = array();
2373 foreach ($users as $user) {
2376 'fullname' => fullname($user),
2379 $userpicture = new user_picture($user);
2380 $userpicture->size
= 1; // Size f1.
2381 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2383 $blockedusers[] = $newuser;
2387 'users' => $blockedusers,
2388 'warnings' => $warnings
2394 * Get blocked users return description.
2396 * @return external_single_structure
2399 public static function get_blocked_users_returns() {
2400 return new external_single_structure(
2402 'users' => new external_multiple_structure(
2403 new external_single_structure(
2405 'id' => new external_value(PARAM_INT
, 'User ID'),
2406 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2407 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
)
2410 'List of blocked users'
2412 'warnings' => new external_warnings()
2418 * Returns description of method parameters
2420 * @return external_function_parameters
2423 public static function mark_message_read_parameters() {
2424 return new external_function_parameters(
2426 'messageid' => new external_value(PARAM_INT
, 'id of the message in the messages table'),
2427 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the message should be marked read',
2434 * Mark a single message as read, trigger message_viewed event
2436 * @param int $messageid id of the message (in the message table)
2437 * @param int $timeread timestamp for when the message should be marked read
2438 * @return external_description
2439 * @throws invalid_parameter_exception
2440 * @throws moodle_exception
2443 public static function mark_message_read($messageid, $timeread) {
2444 global $CFG, $DB, $USER;
2446 // Check if private messaging between users is allowed.
2447 if (empty($CFG->messaging
)) {
2448 throw new moodle_exception('disabled', 'message');
2451 // Warnings array, it can be empty at the end but is mandatory.
2452 $warnings = array();
2456 'messageid' => $messageid,
2457 'timeread' => $timeread
2459 $params = self
::validate_parameters(self
::mark_message_read_parameters(), $params);
2461 if (empty($params['timeread'])) {
2464 $timeread = $params['timeread'];
2467 // Validate context.
2468 $context = context_system
::instance();
2469 self
::validate_context($context);
2471 $sql = "SELECT m.*, mcm.userid as useridto
2473 INNER JOIN {message_conversations} mc
2474 ON m.conversationid = mc.id
2475 INNER JOIN {message_conversation_members} mcm
2476 ON mcm.conversationid = mc.id
2477 LEFT JOIN {message_user_actions} mua
2478 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
2479 WHERE mua.id is NULL
2480 AND mcm.userid != m.useridfrom
2482 $messageparams = [];
2483 $messageparams[] = $USER->id
;
2484 $messageparams[] = \core_message\api
::MESSAGE_ACTION_READ
;
2485 $messageparams[] = $params['messageid'];
2486 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST
);
2488 if ($message->useridto
!= $USER->id
) {
2489 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2492 \core_message\api
::mark_message_as_read($USER->id
, $message, $timeread);
2495 'messageid' => $message->id
,
2496 'warnings' => $warnings
2502 * Returns description of method result value
2504 * @return external_description
2507 public static function mark_message_read_returns() {
2508 return new external_single_structure(
2510 'messageid' => new external_value(PARAM_INT
, 'the id of the message in the messages table'),
2511 'warnings' => new external_warnings()
2517 * Returns description of method parameters
2519 * @return external_function_parameters
2521 public static function mark_notification_read_parameters() {
2522 return new external_function_parameters(
2524 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
2525 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the notification should be marked read',
2532 * Mark a single notification as read.
2534 * This will trigger a 'notification_viewed' event.
2536 * @param int $notificationid id of the notification
2537 * @param int $timeread timestamp for when the notification should be marked read
2538 * @return external_description
2539 * @throws invalid_parameter_exception
2540 * @throws moodle_exception
2542 public static function mark_notification_read($notificationid, $timeread) {
2543 global $CFG, $DB, $USER;
2545 // Warnings array, it can be empty at the end but is mandatory.
2546 $warnings = array();
2550 'notificationid' => $notificationid,
2551 'timeread' => $timeread
2553 $params = self
::validate_parameters(self
::mark_notification_read_parameters(), $params);
2555 if (empty($params['timeread'])) {
2558 $timeread = $params['timeread'];
2561 // Validate context.
2562 $context = context_system
::instance();
2563 self
::validate_context($context);
2565 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST
);
2567 if ($notification->useridto
!= $USER->id
) {
2568 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
2569 'notification as read');
2572 \core_message\api
::mark_notification_as_read($notification, $timeread);
2575 'notificationid' => $notification->id
,
2576 'warnings' => $warnings
2583 * Returns description of method result value
2585 * @return external_description
2587 public static function mark_notification_read_returns() {
2588 return new external_single_structure(
2590 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
2591 'warnings' => new external_warnings()
2597 * Mark all conversation messages as read parameters description.
2599 * @return external_function_parameters
2602 public static function mark_all_conversation_messages_as_read_parameters() {
2603 return new external_function_parameters(
2605 'userid' => new external_value(PARAM_INT
, 'The user id who who we are marking the messages as read for'),
2607 new external_value(PARAM_INT
, 'The conversation id who who we are marking the messages as read for')
2613 * Mark all conversation messages as read function.
2615 * @param int $userid The user id of who we want to delete the conversation for
2616 * @param int $conversationid The id of the conversations
2619 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
2622 // Check if messaging is enabled.
2623 if (empty($CFG->messaging
)) {
2624 throw new moodle_exception('disabled', 'message');
2628 'userid' => $userid,
2629 'conversationid' => $conversationid,
2631 $params = self
::validate_parameters(self
::mark_all_conversation_messages_as_read_parameters(), $params);
2633 $context = context_system
::instance();
2634 self
::validate_context($context);
2636 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2637 core_user
::require_active_user($user);
2639 if (\core_message\api
::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) {
2640 \core_message\api
::mark_all_messages_as_read($params['userid'], $params['conversationid']);
2642 throw new moodle_exception('accessdenied', 'admin');
2647 * Mark all conversation messages as read return description.
2649 * @return external_warnings
2652 public static function mark_all_conversation_messages_as_read_returns() {
2657 * Returns description of method parameters.
2659 * @return external_function_parameters
2662 public static function delete_conversations_by_id_parameters() {
2663 return new external_function_parameters(
2665 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
2666 'conversationids' => new external_multiple_structure(
2667 new external_value(PARAM_INT
, 'The id of the conversation'),
2668 'List of conversation IDs'
2675 * Deletes a conversation.
2677 * @param int $userid The user id of who we want to delete the conversation for
2678 * @param int[] $conversationids The ids of the conversations
2680 * @throws moodle_exception
2683 public static function delete_conversations_by_id($userid, array $conversationids) {
2686 // Check if private messaging between users is allowed.
2687 if (empty($CFG->messaging
)) {
2688 throw new moodle_exception('disabled', 'message');
2693 'userid' => $userid,
2694 'conversationids' => $conversationids,
2696 $params = self
::validate_parameters(self
::delete_conversations_by_id_parameters(), $params);
2698 // Validate context.
2699 $context = context_system
::instance();
2700 self
::validate_context($context);
2702 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2703 core_user
::require_active_user($user);
2705 foreach ($params['conversationids'] as $conversationid) {
2706 if (\core_message\api
::can_delete_conversation($user->id
, $conversationid)) {
2707 \core_message\api
::delete_conversation_by_id($user->id
, $conversationid);
2709 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'");
2717 * Returns description of method result value.
2719 * @return external_description
2722 public static function delete_conversations_by_id_returns() {
2723 return new external_warnings();
2727 * Returns description of method parameters
2729 * @return external_function_parameters
2732 public static function delete_message_parameters() {
2733 return new external_function_parameters(
2735 'messageid' => new external_value(PARAM_INT
, 'The message id'),
2736 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for'),
2737 'read' => new external_value(PARAM_BOOL
, 'If is a message read', VALUE_DEFAULT
, true)
2745 * @param int $messageid the message id
2746 * @param int $userid the user id of who we want to delete the message for
2747 * @param bool $read if is a message read (default to true)
2748 * @return external_description
2749 * @throws moodle_exception
2752 public static function delete_message($messageid, $userid, $read = true) {
2755 // Check if private messaging between users is allowed.
2756 if (empty($CFG->messaging
)) {
2757 throw new moodle_exception('disabled', 'message');
2760 // Warnings array, it can be empty at the end but is mandatory.
2761 $warnings = array();
2765 'messageid' => $messageid,
2766 'userid' => $userid,
2769 $params = self
::validate_parameters(self
::delete_message_parameters(), $params);
2771 // Validate context.
2772 $context = context_system
::instance();
2773 self
::validate_context($context);
2775 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2776 core_user
::require_active_user($user);
2778 if (\core_message\api
::can_delete_message($user->id
, $params['messageid'])) {
2779 $status = \core_message\api
::delete_message($user->id
, $params['messageid']);
2781 throw new moodle_exception('You do not have permission to delete this message');
2785 'status' => $status,
2786 'warnings' => $warnings
2792 * Returns description of method result value
2794 * @return external_description
2797 public static function delete_message_returns() {
2798 return new external_single_structure(
2800 'status' => new external_value(PARAM_BOOL
, 'True if the message was deleted, false otherwise'),
2801 'warnings' => new external_warnings()
2807 * Returns description of method parameters
2809 * @return external_function_parameters
2812 public static function message_processor_config_form_parameters() {
2813 return new external_function_parameters(
2815 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_REQUIRED
),
2816 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor'),
2817 'formvalues' => new external_multiple_structure(
2818 new external_single_structure(
2820 'name' => new external_value(PARAM_TEXT
, 'name of the form element', VALUE_REQUIRED
),
2821 'value' => new external_value(PARAM_RAW
, 'value of the form element', VALUE_REQUIRED
),
2824 'Config form values',
2832 * Processes a message processor config form.
2834 * @param int $userid the user id
2835 * @param string $name the name of the processor
2836 * @param array $formvalues the form values
2837 * @return external_description
2838 * @throws moodle_exception
2841 public static function message_processor_config_form($userid, $name, $formvalues) {
2844 // Check if messaging is enabled.
2845 if (empty($CFG->messaging
)) {
2846 throw new moodle_exception('disabled', 'message');
2849 $params = self
::validate_parameters(
2850 self
::message_processor_config_form_parameters(),
2852 'userid' => $userid,
2854 'formvalues' => $formvalues,
2858 $user = self
::validate_preferences_permissions($params['userid']);
2860 $processor = get_message_processor($params['name']);
2862 $form = new stdClass();
2864 foreach ($params['formvalues'] as $formvalue) {
2865 // Curly braces to ensure interpretation is consistent between
2867 $form->{$formvalue['name']} = $formvalue['value'];
2870 $processor->process_form($form, $preferences);
2872 if (!empty($preferences)) {
2873 set_user_preferences($preferences, $params['userid']);
2878 * Returns description of method result value
2880 * @return external_description
2883 public static function message_processor_config_form_returns() {
2888 * Returns description of method parameters
2890 * @return external_function_parameters
2893 public static function get_message_processor_parameters() {
2894 return new external_function_parameters(
2896 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user'),
2897 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor', VALUE_REQUIRED
),
2903 * Get a message processor.
2905 * @param int $userid
2906 * @param string $name the name of the processor
2907 * @return external_description
2908 * @throws moodle_exception
2911 public static function get_message_processor($userid = 0, $name) {
2912 global $USER, $PAGE, $CFG;
2914 // Check if messaging is enabled.
2915 if (empty($CFG->messaging
)) {
2916 throw new moodle_exception('disabled', 'message');
2919 $params = self
::validate_parameters(
2920 self
::get_message_processor_parameters(),
2922 'userid' => $userid,
2927 if (empty($params['userid'])) {
2928 $params['userid'] = $USER->id
;
2931 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2932 core_user
::require_active_user($user);
2933 self
::validate_context(context_user
::instance($params['userid']));
2935 $processor = get_message_processor($params['name']);
2937 $processoroutput = new \core_message\output\
processor($processor, $user);
2938 $renderer = $PAGE->get_renderer('core_message');
2940 return $processoroutput->export_for_template($renderer);
2944 * Returns description of method result value
2946 * @return external_description
2949 public static function get_message_processor_returns() {
2950 return new external_function_parameters(
2952 'systemconfigured' => new external_value(PARAM_BOOL
, 'Site configuration status'),
2953 'userconfigured' => new external_value(PARAM_BOOL
, 'The user configuration status'),
2959 * Check that the user has enough permission to retrieve message or notifications preferences.
2961 * @param int $userid the user id requesting the preferences
2962 * @return stdClass full user object
2963 * @throws moodle_exception
2966 protected static function validate_preferences_permissions($userid) {
2969 if (empty($userid)) {
2972 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
2973 core_user
::require_active_user($user);
2976 $systemcontext = context_system
::instance();
2977 self
::validate_context($systemcontext);
2979 // Check access control.
2980 if ($user->id
== $USER->id
) {
2981 // Editing own message profile.
2982 require_capability('moodle/user:editownmessageprofile', $systemcontext);
2984 // Teachers, parents, etc.
2985 $personalcontext = context_user
::instance($user->id
);
2986 require_capability('moodle/user:editmessageprofile', $personalcontext);
2992 * Returns a notification or message preference structure.
2994 * @return external_single_structure the structure
2997 protected static function get_preferences_structure() {
2998 return new external_single_structure(
3000 'userid' => new external_value(PARAM_INT
, 'User id'),
3001 'disableall' => new external_value(PARAM_INT
, 'Whether all the preferences are disabled'),
3002 'processors' => new external_multiple_structure(
3003 new external_single_structure(
3005 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3006 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3007 'hassettings' => new external_value(PARAM_BOOL
, 'Whether has settings'),
3008 'contextid' => new external_value(PARAM_INT
, 'Context id'),
3009 'userconfigured' => new external_value(PARAM_INT
, 'Whether is configured by the user'),
3012 'Config form values'
3014 'components' => new external_multiple_structure(
3015 new external_single_structure(
3017 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3018 'notifications' => new external_multiple_structure(
3019 new external_single_structure(
3021 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3022 'preferencekey' => new external_value(PARAM_ALPHANUMEXT
, 'Preference key'),
3023 'processors' => new external_multiple_structure(
3024 new external_single_structure(
3026 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3027 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3028 'locked' => new external_value(PARAM_BOOL
, 'Is locked by admin?'),
3029 'lockedmessage' => new external_value(PARAM_TEXT
,
3030 'Text to display if locked', VALUE_OPTIONAL
),
3031 'userconfigured' => new external_value(PARAM_INT
, 'Is configured?'),
3032 'loggedin' => new external_single_structure(
3034 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3035 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3036 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3039 'loggedoff' => new external_single_structure(
3041 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3042 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3043 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3048 'Processors values for this notification'
3052 'List of notificaitons for the component'
3056 'Available components'
3063 * Returns description of method parameters
3065 * @return external_function_parameters
3068 public static function get_user_notification_preferences_parameters() {
3069 return new external_function_parameters(
3071 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3077 * Get the notification preferences for a given user.
3079 * @param int $userid id of the user, 0 for current user
3080 * @return external_description
3081 * @throws moodle_exception
3084 public static function get_user_notification_preferences($userid = 0) {
3087 $params = self
::validate_parameters(
3088 self
::get_user_notification_preferences_parameters(),
3090 'userid' => $userid,
3093 $user = self
::validate_preferences_permissions($params['userid']);
3095 $processors = get_message_processors();
3096 $providers = message_get_providers_for_user($user->id
);
3097 $preferences = \core_message\api
::get_all_message_preferences($processors, $providers, $user);
3098 $notificationlist = new \core_message\output\preferences\notification_list
($processors, $providers, $preferences, $user);
3100 $renderer = $PAGE->get_renderer('core_message');
3103 'warnings' => array(),
3104 'preferences' => $notificationlist->export_for_template($renderer)
3110 * Returns description of method result value
3112 * @return external_description
3115 public static function get_user_notification_preferences_returns() {
3116 return new external_function_parameters(
3118 'preferences' => self
::get_preferences_structure(),
3119 'warnings' => new external_warnings(),
3125 * Returns description of method parameters
3127 * @return external_function_parameters
3130 public static function get_user_message_preferences_parameters() {
3131 return new external_function_parameters(
3133 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3139 * Get the notification preferences for a given user.
3141 * @param int $userid id of the user, 0 for current user
3142 * @return external_description
3143 * @throws moodle_exception
3146 public static function get_user_message_preferences($userid = 0) {
3149 $params = self
::validate_parameters(
3150 self
::get_user_message_preferences_parameters(),
3152 'userid' => $userid,
3156 $user = self
::validate_preferences_permissions($params['userid']);
3158 // Filter out enabled, available system_configured and user_configured processors only.
3159 $readyprocessors = array_filter(get_message_processors(), function($processor) {
3160 return $processor->enabled
&&
3161 $processor->configured
&&
3162 $processor->object->is_user_configured() &&
3163 // Filter out processors that don't have and message preferences to configure.
3164 $processor->object->has_message_preferences();
3167 $providers = array_filter(message_get_providers_for_user($user->id
), function($provider) {
3168 return $provider->component
=== 'moodle';
3170 $preferences = \core_message\api
::get_all_message_preferences($readyprocessors, $providers, $user);
3171 $notificationlistoutput = new \core_message\output\preferences\
message_notification_list($readyprocessors,
3172 $providers, $preferences, $user);
3174 $renderer = $PAGE->get_renderer('core_message');
3176 $entertosend = get_user_preferences('message_entertosend', $CFG->messagingdefaultpressenter
, $user);
3179 'warnings' => array(),
3180 'preferences' => $notificationlistoutput->export_for_template($renderer),
3181 'blocknoncontacts' => \core_message\api
::get_user_privacy_messaging_preference($user->id
),
3182 'entertosend' => $entertosend
3188 * Returns description of method result value
3190 * @return external_description
3193 public static function get_user_message_preferences_returns() {
3194 return new external_function_parameters(
3196 'preferences' => self
::get_preferences_structure(),
3197 'blocknoncontacts' => new external_value(PARAM_INT
, 'Privacy messaging setting to define who can message you'),
3198 'entertosend' => new external_value(PARAM_BOOL
, 'User preference for using enter to send messages'),
3199 'warnings' => new external_warnings(),
3205 * Returns description of method parameters for the favourite_conversations() method.
3207 * @return external_function_parameters
3209 public static function set_favourite_conversations_parameters() {
3210 return new external_function_parameters(
3212 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
3213 'conversations' => new external_multiple_structure(
3214 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
3221 * Favourite a conversation, or list of conversations for a user.
3223 * @param int $userid the id of the user, or 0 for the current user.
3224 * @param array $conversationids the list of conversations ids to favourite.
3226 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3228 public static function set_favourite_conversations(int $userid, array $conversationids) {
3231 // All the business logic checks that really shouldn't be in here.
3232 if (empty($CFG->messaging
)) {
3233 throw new moodle_exception('disabled', 'message');
3236 'userid' => $userid,
3237 'conversations' => $conversationids
3239 $params = self
::validate_parameters(self
::set_favourite_conversations_parameters(), $params);
3240 $systemcontext = context_system
::instance();
3241 self
::validate_context($systemcontext);
3243 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3244 throw new moodle_exception('You do not have permission to perform this action.');
3247 foreach ($params['conversations'] as $conversationid) {
3248 \core_message\api
::set_favourite_conversation($conversationid, $params['userid']);
3255 * Return a description of the returns for the create_user_favourite_conversations() method.
3257 * @return external_description
3259 public static function set_favourite_conversations_returns() {
3260 return new external_warnings();
3264 * Returns description of method parameters for unfavourite_conversations() method.
3266 * @return external_function_parameters
3268 public static function unset_favourite_conversations_parameters() {
3269 return new external_function_parameters(
3271 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
3272 'conversations' => new external_multiple_structure(
3273 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
3280 * Unfavourite a conversation, or list of conversations for a user.
3282 * @param int $userid the id of the user, or 0 for the current user.
3283 * @param array $conversationids the list of conversations ids unset as favourites.
3285 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3287 public static function unset_favourite_conversations(int $userid, array $conversationids) {
3290 // All the business logic checks that really shouldn't be in here.
3291 if (empty($CFG->messaging
)) {
3292 throw new moodle_exception('disabled', 'message');
3295 'userid' => $userid,
3296 'conversations' => $conversationids
3298 $params = self
::validate_parameters(self
::unset_favourite_conversations_parameters(), $params);
3299 $systemcontext = context_system
::instance();
3300 self
::validate_context($systemcontext);
3302 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3303 throw new moodle_exception('You do not have permission to perform this action.');
3306 foreach ($params['conversations'] as $conversationid) {
3307 \core_message\api
::unset_favourite_conversation($conversationid, $params['userid']);
3314 * Unset favourite conversations return description.
3316 * @return external_description
3318 public static function unset_favourite_conversations_returns() {
3319 return new external_warnings();
3323 * Returns description of method parameters for get_member_info() method.
3325 * @return external_function_parameters
3327 public static function get_member_info_parameters() {
3328 return new external_function_parameters(
3330 'referenceuserid' => new external_value(PARAM_INT
, 'id of the user'),
3331 'userids' => new external_multiple_structure(
3332 new external_value(PARAM_INT
, 'id of members to get')
3334 'includecontactrequests' => new external_value(PARAM_BOOL
, 'include contact requests in response', VALUE_DEFAULT
, false),
3335 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'include privacy info in response', VALUE_DEFAULT
, false)
3341 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid.
3343 * This is the basic structure used when returning members, and includes information about the relationship between each member
3344 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them.
3346 * @param int $referenceuserid the id of the user which check contact and blocked status.
3347 * @param array $userids
3348 * @return array the array of objects containing member info.
3349 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3351 public static function get_member_info(
3352 int $referenceuserid,
3354 bool $includecontactrequests = false,
3355 bool $includeprivacyinfo = false
3359 // All the business logic checks that really shouldn't be in here.
3360 if (empty($CFG->messaging
)) {
3361 throw new moodle_exception('disabled', 'message');
3364 'referenceuserid' => $referenceuserid,
3365 'userids' => $userids,
3366 'includecontactrequests' => $includecontactrequests,
3367 'includeprivacyinfo' => $includeprivacyinfo
3369 $params = self
::validate_parameters(self
::get_member_info_parameters(), $params);
3370 $systemcontext = context_system
::instance();
3371 self
::validate_context($systemcontext);
3373 if (($USER->id
!= $referenceuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3374 throw new moodle_exception('You do not have permission to perform this action.');
3377 return \core_message\helper
::get_member_info(
3378 $params['referenceuserid'],
3380 $params['includecontactrequests'],
3381 $params['includeprivacyinfo']
3386 * Get member info return description.
3388 * @return external_description
3390 public static function get_member_info_returns() {
3391 return new external_multiple_structure(
3392 self
::get_conversation_member_structure()
3397 * Returns description of method parameters for get_conversation_counts() method.
3399 * @return external_function_parameters
3401 public static function get_conversation_counts_parameters() {
3402 return new external_function_parameters(
3404 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3410 * Returns an array of conversation counts for the various types of conversations, including favourites.
3414 * 'favourites' => 0,
3416 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
3417 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
3421 * @param int $userid the id of the user whose counts we are fetching.
3422 * @return array the array of conversation counts, indexed by type.
3423 * @throws moodle_exception if the current user cannot perform this action.
3425 public static function get_conversation_counts(int $userid) {
3428 // All the business logic checks that really shouldn't be in here.
3429 if (empty($CFG->messaging
)) {
3430 throw new moodle_exception('disabled', 'message');
3433 if (empty($userid)) {
3434 $userid = $USER->id
;
3437 $params = ['userid' => $userid];
3438 $params = self
::validate_parameters(self
::get_conversation_counts_parameters(), $params);
3440 $systemcontext = context_system
::instance();
3441 self
::validate_context($systemcontext);
3443 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3444 throw new moodle_exception('You do not have permission to perform this action.');
3447 return \core_message\api
::get_conversation_counts($params['userid']);
3451 * Get conversation counts return description.
3453 * @return external_description
3455 public static function get_conversation_counts_returns() {
3456 return new external_single_structure(
3458 'favourites' => new external_value(PARAM_INT
, 'Total number of favourite conversations'),
3459 'types' => new external_single_structure(
3461 \core_message\api
::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL
=> new external_value(PARAM_INT
,
3462 'Total number of individual conversations'),
3463 \core_message\api
::MESSAGE_CONVERSATION_TYPE_GROUP
=> new external_value(PARAM_INT
,
3464 'Total number of group conversations'),
3465 \core_message\api
::MESSAGE_CONVERSATION_TYPE_SELF
=> new external_value(PARAM_INT
,
3466 'Total number of self conversations'),
3474 * Returns description of method parameters for get_unread_conversation_counts() method.
3476 * @return external_function_parameters
3478 public static function get_unread_conversation_counts_parameters() {
3479 return new external_function_parameters(
3481 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3487 * Returns an array of unread conversation counts for the various types of conversations, including favourites.
3491 * 'favourites' => 0,
3493 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
3494 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
3498 * @param int $userid the id of the user whose counts we are fetching.
3499 * @return array the array of unread conversation counts, indexed by type.
3500 * @throws moodle_exception if the current user cannot perform this action.
3502 public static function get_unread_conversation_counts(int $userid) {
3505 // All the business logic checks that really shouldn't be in here.
3506 if (empty($CFG->messaging
)) {
3507 throw new moodle_exception('disabled', 'message');
3510 if (empty($userid)) {
3511 $userid = $USER->id
;
3514 $params = ['userid' => $userid];
3515 $params = self
::validate_parameters(self
::get_unread_conversation_counts_parameters(), $params);
3517 $systemcontext = context_system
::instance();
3518 self
::validate_context($systemcontext);
3520 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3521 throw new moodle_exception('You do not have permission to perform this action.');
3524 return \core_message\api
::get_unread_conversation_counts($params['userid']);
3528 * Get unread conversation counts return description.
3530 * @return external_description
3532 public static function get_unread_conversation_counts_returns() {
3533 return new external_single_structure(
3535 'favourites' => new external_value(PARAM_INT
, 'Total number of unread favourite conversations'),
3536 'types' => new external_single_structure(
3538 \core_message\api
::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL
=> new external_value(PARAM_INT
,
3539 'Total number of unread individual conversations'),
3540 \core_message\api
::MESSAGE_CONVERSATION_TYPE_GROUP
=> new external_value(PARAM_INT
,
3541 'Total number of unread group conversations'),
3542 \core_message\api
::MESSAGE_CONVERSATION_TYPE_SELF
=> new external_value(PARAM_INT
,
3543 'Total number of unread self conversations'),
3551 * Returns description of method parameters
3553 * @return external_function_parameters
3556 public static function delete_message_for_all_users_parameters() {
3557 return new external_function_parameters(
3559 'messageid' => new external_value(PARAM_INT
, 'The message id'),
3560 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for all users')
3565 * Deletes a message for all users
3567 * @param int $messageid the message id
3568 * @param int $userid the user id of who we want to delete the message for all users
3569 * @return external_description
3570 * @throws moodle_exception
3573 public static function delete_message_for_all_users(int $messageid, int $userid) {
3576 // Check if private messaging between users is allowed.
3577 if (empty($CFG->messaging
)) {
3578 throw new moodle_exception('disabled', 'message');
3583 'messageid' => $messageid,
3586 $params = self
::validate_parameters(self
::delete_message_for_all_users_parameters(), $params);
3588 // Validate context.
3589 $context = context_system
::instance();
3590 self
::validate_context($context);
3592 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3593 core_user
::require_active_user($user);
3595 // Checks if a user can delete a message for all users.
3596 if (core_message\api
::can_delete_message_for_all_users($user->id
, $params['messageid'])) {
3597 \core_message\api
::delete_message_for_all_users($params['messageid']);
3599 throw new moodle_exception('You do not have permission to delete this message for everyone.');
3605 * Returns description of method result value
3607 * @return external_description
3610 public static function delete_message_for_all_users_returns() {
3611 return new external_warnings();