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
91 // Validate messages content before posting them.
92 foreach ($params['messages'] as $message) {
93 // Check message length.
94 if (strlen($message['text']) > \core_message\api
::MESSAGE_MAX_LENGTH
) {
95 throw new moodle_exception('errormessagetoolong', 'message');
100 foreach ($params['messages'] as $message) {
101 $createdmessage = \core_message\api
::send_message_to_conversation($USER->id
, $params['conversationid'], $message['text'],
102 $message['textformat']);
103 $createdmessage->text
= message_format_message_text((object) [
104 'smallmessage' => $createdmessage->text
,
105 'fullmessageformat' => external_validate_format($message['textformat']),
106 'fullmessagetrust' => $createdmessage->fullmessagetrust
108 $messages[] = $createdmessage;
115 * Returns description of method result value.
117 * @return external_description
120 public static function send_messages_to_conversation_returns() {
121 return new external_multiple_structure(
122 self
::get_conversation_message_structure()
128 * Returns description of method parameters
130 * @return external_function_parameters
133 public static function send_instant_messages_parameters() {
134 return new external_function_parameters(
136 'messages' => new external_multiple_structure(
137 new external_single_structure(
139 'touserid' => new external_value(PARAM_INT
, 'id of the user to send the private message'),
140 'text' => new external_value(PARAM_RAW
, 'the text of the message'),
141 'textformat' => new external_format_value('text', VALUE_DEFAULT
, FORMAT_MOODLE
),
142 '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
),
151 * Send private messages from the current USER to other users
153 * @param array $messages An array of message to send.
157 public static function send_instant_messages($messages = array()) {
158 global $CFG, $USER, $DB;
160 // Check if messaging is enabled.
161 if (empty($CFG->messaging
)) {
162 throw new moodle_exception('disabled', 'message');
165 // Ensure the current user is allowed to run this function
166 $context = context_system
::instance();
167 self
::validate_context($context);
168 require_capability('moodle/site:sendmessage', $context);
170 // Ensure the current user is allowed to delete message for everyone.
171 $candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $context);
173 $params = self
::validate_parameters(self
::send_instant_messages_parameters(), array('messages' => $messages));
175 //retrieve all tousers of the messages
176 $receivers = array();
177 foreach($params['messages'] as $message) {
178 $receivers[] = $message['touserid'];
180 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
181 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
183 $resultmessages = array();
184 $messageids = array();
185 foreach ($params['messages'] as $message) {
186 $resultmsg = array(); //the infos about the success of the operation
188 // We are going to do some checking.
189 // Code should match /messages/index.php checks.
192 // Check the user exists.
193 if (empty($tousers[$message['touserid']])) {
195 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
198 // Check message length.
199 if ($success && strlen($message['text']) > \core_message\api
::MESSAGE_MAX_LENGTH
) {
201 $errormessage = get_string('errormessagetoolong', 'message');
204 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
205 // Check if the recipient can be messaged by the sender.
206 if ($success && !\core_message\api
::can_send_message($tousers[$message['touserid']]->id
, $USER->id
)) {
208 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user
::get_user($message['touserid'])));
211 // Now we can send the message (at least try).
213 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
214 $success = message_post_message($USER, $tousers[$message['touserid']],
215 $message['text'], external_validate_format($message['textformat']));
218 // Build the resultmsg.
219 if (isset($message['clientmsgid'])) {
220 $resultmsg['clientmsgid'] = $message['clientmsgid'];
223 $resultmsg['msgid'] = $success;
224 $resultmsg['timecreated'] = time();
225 $resultmsg['candeletemessagesforallusers'] = $candeletemessagesforallusers;
226 $messageids[] = $success;
228 // WARNINGS: for backward compatibility we return this errormessage.
229 // We should have thrown exceptions as these errors prevent results to be returned.
230 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
231 $resultmsg['msgid'] = -1;
232 if (!isset($errormessage)) { // Nobody has set a message error or thrown an exception, let's set it.
233 $errormessage = get_string('messageundeliveredbynotificationsettings', 'error');
235 $resultmsg['errormessage'] = $errormessage;
238 $resultmessages[] = $resultmsg;
241 if (!empty($messageids)) {
242 $messagerecords = $DB->get_records_list(
247 'id, conversationid, smallmessage, fullmessageformat, fullmessagetrust');
248 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) {
249 $id = $resultmessage['msgid'];
250 $resultmessage['conversationid'] = isset($messagerecords[$id]) ?
$messagerecords[$id]->conversationid
: null;
251 $resultmessage['useridfrom'] = $USER->id
;
252 $resultmessage['text'] = message_format_message_text((object) [
253 'smallmessage' => $messagerecords[$id]->smallmessage
,
254 'fullmessageformat' => external_validate_format($messagerecords[$id]->fullmessageformat
),
255 'fullmessagetrust' => $messagerecords[$id]->fullmessagetrust
257 return $resultmessage;
261 return $resultmessages;
265 * Returns description of method result value
267 * @return external_description
270 public static function send_instant_messages_returns() {
271 return new external_multiple_structure(
272 new external_single_structure(
274 'msgid' => new external_value(PARAM_INT
, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
275 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT
, 'your own id for the message', VALUE_OPTIONAL
),
276 'errormessage' => new external_value(PARAM_TEXT
, 'error message - if it failed', VALUE_OPTIONAL
),
277 'text' => new external_value(PARAM_RAW
, 'The text of the message', VALUE_OPTIONAL
),
278 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message', VALUE_OPTIONAL
),
279 'conversationid' => new external_value(PARAM_INT
, 'The conversation id for this message', VALUE_OPTIONAL
),
280 'useridfrom' => new external_value(PARAM_INT
, 'The user id who sent the message', VALUE_OPTIONAL
),
281 'candeletemessagesforallusers' => new external_value(PARAM_BOOL
,
282 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT
, false),
289 * Delete contacts parameters description.
291 * @return external_function_parameters
294 public static function delete_contacts_parameters() {
295 return new external_function_parameters(
297 'userids' => new external_multiple_structure(
298 new external_value(PARAM_INT
, 'User ID'),
301 'userid' => new external_value(PARAM_INT
, 'The id of the user we are deleting the contacts for, 0 for the
302 current user', VALUE_DEFAULT
, 0)
310 * @param array $userids array of user IDs.
311 * @param int $userid The id of the user we are deleting the contacts for
315 public static function delete_contacts($userids, $userid = 0) {
318 // Check if messaging is enabled.
319 if (empty($CFG->messaging
)) {
320 throw new moodle_exception('disabled', 'message');
323 if (empty($userid)) {
328 $context = context_system
::instance();
329 self
::validate_context($context);
331 $params = array('userids' => $userids, 'userid' => $userid);
332 $params = self
::validate_parameters(self
::delete_contacts_parameters(), $params);
334 $capability = 'moodle/site:manageallmessaging';
335 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
336 throw new required_capability_exception($context, $capability, 'nopermissions', '');
339 foreach ($params['userids'] as $id) {
340 \core_message\api
::remove_contact($params['userid'], $id);
347 * Delete contacts return description.
349 * @return external_description
352 public static function delete_contacts_returns() {
357 * Mute conversations parameters description.
359 * @return external_function_parameters
361 public static function mute_conversations_parameters() {
362 return new external_function_parameters(
364 'userid' => new external_value(PARAM_INT
, 'The id of the user who is blocking'),
365 'conversationids' => new external_multiple_structure(
366 new external_value(PARAM_INT
, 'id of the conversation', VALUE_REQUIRED
)
373 * Mutes conversations.
375 * @param int $userid The id of the user who is blocking
376 * @param array $conversationids The list of conversations being muted
377 * @return external_description
379 public static function mute_conversations(int $userid, array $conversationids) {
382 // Check if messaging is enabled.
383 if (empty($CFG->messaging
)) {
384 throw new moodle_exception('disabled', 'message');
388 $context = context_system
::instance();
389 self
::validate_context($context);
391 $params = ['userid' => $userid, 'conversationids' => $conversationids];
392 $params = self
::validate_parameters(self
::mute_conversations_parameters(), $params);
394 $capability = 'moodle/site:manageallmessaging';
395 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
396 throw new required_capability_exception($context, $capability, 'nopermissions', '');
399 foreach ($params['conversationids'] as $conversationid) {
400 if (!\core_message\api
::is_conversation_muted($params['userid'], $conversationid)) {
401 \core_message\api
::mute_conversation($params['userid'], $conversationid);
409 * Mute conversations return description.
411 * @return external_description
413 public static function mute_conversations_returns() {
414 return new external_warnings();
418 * Unmute conversations parameters description.
420 * @return external_function_parameters
422 public static function unmute_conversations_parameters() {
423 return new external_function_parameters(
425 'userid' => new external_value(PARAM_INT
, 'The id of the user who is unblocking'),
426 'conversationids' => new external_multiple_structure(
427 new external_value(PARAM_INT
, 'id of the conversation', VALUE_REQUIRED
)
434 * Unmute conversations.
436 * @param int $userid The id of the user who is unblocking
437 * @param array $conversationids The list of conversations being muted
439 public static function unmute_conversations(int $userid, array $conversationids) {
442 // Check if messaging is enabled.
443 if (empty($CFG->messaging
)) {
444 throw new moodle_exception('disabled', 'message');
448 $context = context_system
::instance();
449 self
::validate_context($context);
451 $params = ['userid' => $userid, 'conversationids' => $conversationids];
452 $params = self
::validate_parameters(self
::unmute_conversations_parameters(), $params);
454 $capability = 'moodle/site:manageallmessaging';
455 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
456 throw new required_capability_exception($context, $capability, 'nopermissions', '');
459 foreach ($params['conversationids'] as $conversationid) {
460 \core_message\api
::unmute_conversation($params['userid'], $conversationid);
467 * Unmute conversations return description.
469 * @return external_description
471 public static function unmute_conversations_returns() {
472 return new external_warnings();
476 * Block user parameters description.
478 * @return external_function_parameters
480 public static function block_user_parameters() {
481 return new external_function_parameters(
483 'userid' => new external_value(PARAM_INT
, 'The id of the user who is blocking'),
484 'blockeduserid' => new external_value(PARAM_INT
, 'The id of the user being blocked'),
492 * @param int $userid The id of the user who is blocking
493 * @param int $blockeduserid The id of the user being blocked
494 * @return external_description
496 public static function block_user(int $userid, int $blockeduserid) {
499 // Check if messaging is enabled.
500 if (empty($CFG->messaging
)) {
501 throw new moodle_exception('disabled', 'message');
505 $context = context_system
::instance();
506 self
::validate_context($context);
508 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
509 $params = self
::validate_parameters(self
::block_user_parameters(), $params);
511 $capability = 'moodle/site:manageallmessaging';
512 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
513 throw new required_capability_exception($context, $capability, 'nopermissions', '');
516 // If the blocking is going to be useless then don't do it.
517 if (\core_message\api
::can_send_message($userid, $blockeduserid, true)) {
521 if (!\core_message\api
::is_blocked($params['userid'], $params['blockeduserid'])) {
522 \core_message\api
::block_user($params['userid'], $params['blockeduserid']);
529 * Block user return description.
531 * @return external_description
533 public static function block_user_returns() {
534 return new external_warnings();
538 * Unblock user parameters description.
540 * @return external_function_parameters
542 public static function unblock_user_parameters() {
543 return new external_function_parameters(
545 'userid' => new external_value(PARAM_INT
, 'The id of the user who is unblocking'),
546 'unblockeduserid' => new external_value(PARAM_INT
, 'The id of the user being unblocked'),
554 * @param int $userid The id of the user who is unblocking
555 * @param int $unblockeduserid The id of the user being unblocked
557 public static function unblock_user(int $userid, int $unblockeduserid) {
560 // Check if messaging is enabled.
561 if (empty($CFG->messaging
)) {
562 throw new moodle_exception('disabled', 'message');
566 $context = context_system
::instance();
567 self
::validate_context($context);
569 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
570 $params = self
::validate_parameters(self
::unblock_user_parameters(), $params);
572 $capability = 'moodle/site:manageallmessaging';
573 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
574 throw new required_capability_exception($context, $capability, 'nopermissions', '');
577 \core_message\api
::unblock_user($params['userid'], $params['unblockeduserid']);
583 * Unblock user return description.
585 * @return external_description
587 public static function unblock_user_returns() {
588 return new external_warnings();
592 * Returns contact requests parameters description.
594 * @return external_function_parameters
596 public static function get_contact_requests_parameters() {
597 return new external_function_parameters(
599 'userid' => new external_value(PARAM_INT
, 'The id of the user we want the requests for'),
600 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
601 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
607 * Handles returning the contact requests for a user.
609 * This also includes the user data necessary to display information
612 * It will not include blocked users.
614 * @param int $userid The id of the user we want to get the contact requests for
615 * @param int $limitfrom
616 * @param int $limitnum
618 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) {
621 // Check if messaging is enabled.
622 if (empty($CFG->messaging
)) {
623 throw new moodle_exception('disabled', 'message');
627 $context = context_system
::instance();
628 self
::validate_context($context);
632 'limitfrom' => $limitfrom,
633 'limitnum' => $limitnum
635 $params = self
::validate_parameters(self
::get_contact_requests_parameters(), $params);
637 $capability = 'moodle/site:manageallmessaging';
638 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
639 throw new required_capability_exception($context, $capability, 'nopermissions', '');
642 return \core_message\api
::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']);
646 * Returns the contact requests return description.
648 * @return external_description
650 public static function get_contact_requests_returns() {
651 return new external_multiple_structure(
652 self
::get_conversation_member_structure()
657 * Returns the number of contact requests the user has received parameters description.
659 * @return external_function_parameters
661 public static function get_received_contact_requests_count_parameters() {
662 return new external_function_parameters(
664 'userid' => new external_value(PARAM_INT
, 'The id of the user we want to return the number of ' .
665 'received contact requests for', VALUE_REQUIRED
),
671 * Returns the number of contact requests the user has received.
673 * @param int $userid The ID of the user we want to return the number of received contact requests for
674 * @return external_value
676 public static function get_received_contact_requests_count(int $userid) {
679 // Check if messaging is enabled.
680 if (empty($CFG->messaging
)) {
681 throw new moodle_exception('disabled', 'message');
685 $context = context_system
::instance();
686 self
::validate_context($context);
691 $params = self
::validate_parameters(self
::get_received_contact_requests_count_parameters(), $params);
693 $capability = 'moodle/site:manageallmessaging';
694 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
695 throw new required_capability_exception($context, $capability, 'nopermissions', '');
698 return \core_message\api
::get_received_contact_requests_count($params['userid']);
702 * Returns the number of contact requests the user has received return description.
704 * @return external_value
706 public static function get_received_contact_requests_count_returns() {
707 return new external_value(PARAM_INT
, 'The number of received contact requests');
711 * Returns get conversation members parameters description.
713 * @return external_function_parameters
715 public static function get_conversation_members_parameters() {
716 return new external_function_parameters(
718 'userid' => new external_value(PARAM_INT
, 'The id of the user we are performing this action on behalf of'),
719 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation'),
720 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Do we want to include contact requests?',
721 VALUE_DEFAULT
, false),
722 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Do we want to include privacy info?',
723 VALUE_DEFAULT
, false),
724 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
725 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
731 * Returns a list of conversation members.
733 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
734 * @param int $conversationid The id of the conversation
735 * @param bool $includecontactrequests Do we want to include contact requests with this data?
736 * @param bool $includeprivacyinfo Do we want to include privacy info?
737 * @param int $limitfrom
738 * @param int $limitnum
741 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
742 bool $includeprivacyinfo = false, int $limitfrom = 0, int $limitnum = 0) {
745 // Check if messaging is enabled.
746 if (empty($CFG->messaging
)) {
747 throw new moodle_exception('disabled', 'message');
751 $context = context_system
::instance();
752 self
::validate_context($context);
756 'conversationid' => $conversationid,
757 'includecontactrequests' => $includecontactrequests,
758 'includeprivacyinfo' => $includeprivacyinfo,
759 'limitfrom' => $limitfrom,
760 'limitnum' => $limitnum
762 $params = self
::validate_parameters(self
::get_conversation_members_parameters(), $params);
764 $capability = 'moodle/site:manageallmessaging';
765 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
766 throw new required_capability_exception($context, $capability, 'nopermissions', '');
769 // The user needs to be a part of the conversation before querying who the members are.
770 if (!\core_message\api
::is_user_in_conversation($params['userid'], $params['conversationid'])) {
771 throw new moodle_exception('You are not a member of this conversation.');
774 return \core_message\api
::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'],
775 $params['includeprivacyinfo'], $params['limitfrom'], $params['limitnum']);
779 * Returns the get conversation members return description.
781 * @return external_description
783 public static function get_conversation_members_returns() {
784 return new external_multiple_structure(
785 self
::get_conversation_member_structure()
790 * Creates a contact request parameters description.
792 * @return external_function_parameters
794 public static function create_contact_request_parameters() {
795 return new external_function_parameters(
797 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
798 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
804 * Creates a contact request.
806 * @param int $userid The id of the user who is creating the contact request
807 * @param int $requesteduserid The id of the user being requested
809 public static function create_contact_request(int $userid, int $requesteduserid) {
812 // Check if messaging is enabled.
813 if (empty($CFG->messaging
)) {
814 throw new moodle_exception('disabled', 'message');
818 $context = context_system
::instance();
819 self
::validate_context($context);
821 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
822 $params = self
::validate_parameters(self
::create_contact_request_parameters(), $params);
824 $capability = 'moodle/site:manageallmessaging';
825 if (($USER->id
!= $params['userid']) && !has_capability($capability, $context)) {
826 throw new required_capability_exception($context, $capability, 'nopermissions', '');
833 if (!\core_message\api
::can_create_contact($params['userid'], $params['requesteduserid'])) {
834 $result['warnings'][] = [
836 'itemid' => $params['requesteduserid'],
837 'warningcode' => 'cannotcreatecontactrequest',
838 'message' => 'You are unable to create a contact request for this user'
841 if ($requests = \core_message\api
::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) {
842 // There should only ever be one but just in case there are multiple then we can return the first.
843 $result['request'] = array_shift($requests);
845 $result['request'] = \core_message\api
::create_contact_request($params['userid'], $params['requesteduserid']);
853 * Creates a contact request return description.
855 * @return external_description
857 public static function create_contact_request_returns() {
858 return new external_single_structure(
860 'request' => new external_single_structure(
862 'id' => new external_value(PARAM_INT
, 'Message id'),
863 'userid' => new external_value(PARAM_INT
, 'User from id'),
864 'requesteduserid' => new external_value(PARAM_INT
, 'User to id'),
865 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
870 'warnings' => new external_warnings()
876 * Confirm a contact request parameters description.
878 * @return external_function_parameters
880 public static function confirm_contact_request_parameters() {
881 return new external_function_parameters(
883 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
884 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
890 * Confirm a contact request.
892 * @param int $userid The id of the user who is creating the contact request
893 * @param int $requesteduserid The id of the user being requested
895 public static function confirm_contact_request(int $userid, int $requesteduserid) {
898 // Check if messaging is enabled.
899 if (empty($CFG->messaging
)) {
900 throw new moodle_exception('disabled', 'message');
904 $context = context_system
::instance();
905 self
::validate_context($context);
907 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
908 $params = self
::validate_parameters(self
::confirm_contact_request_parameters(), $params);
910 $capability = 'moodle/site:manageallmessaging';
911 if (($USER->id
!= $params['requesteduserid']) && !has_capability($capability, $context)) {
912 throw new required_capability_exception($context, $capability, 'nopermissions', '');
915 \core_message\api
::confirm_contact_request($params['userid'], $params['requesteduserid']);
921 * Confirm a contact request return description.
923 * @return external_description
925 public static function confirm_contact_request_returns() {
926 return new external_warnings();
930 * Declines a contact request parameters description.
932 * @return external_function_parameters
934 public static function decline_contact_request_parameters() {
935 return new external_function_parameters(
937 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
938 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
944 * Declines a contact request.
946 * @param int $userid The id of the user who is creating the contact request
947 * @param int $requesteduserid The id of the user being requested
949 public static function decline_contact_request(int $userid, int $requesteduserid) {
952 // Check if messaging is enabled.
953 if (empty($CFG->messaging
)) {
954 throw new moodle_exception('disabled', 'message');
958 $context = context_system
::instance();
959 self
::validate_context($context);
961 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
962 $params = self
::validate_parameters(self
::decline_contact_request_parameters(), $params);
964 $capability = 'moodle/site:manageallmessaging';
965 if (($USER->id
!= $params['requesteduserid']) && !has_capability($capability, $context)) {
966 throw new required_capability_exception($context, $capability, 'nopermissions', '');
969 \core_message\api
::decline_contact_request($params['userid'], $params['requesteduserid']);
975 * Declines a contact request return description.
977 * @return external_description
979 public static function decline_contact_request_returns() {
980 return new external_warnings();
984 * Return the structure of a message area contact.
986 * @return external_single_structure
989 private static function get_messagearea_contact_structure() {
990 return new external_single_structure(
992 'userid' => new external_value(PARAM_INT
, 'The user\'s id'),
993 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
994 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
995 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
996 'ismessaging' => new external_value(PARAM_BOOL
, 'If we are messaging the user'),
997 'sentfromcurrentuser' => new external_value(PARAM_BOOL
, 'Was the last message sent from the current user?'),
998 'lastmessage' => new external_value(PARAM_NOTAGS
, 'The user\'s last message'),
999 'lastmessagedate' => new external_value(PARAM_INT
, 'Timestamp for last message', VALUE_DEFAULT
, null),
1000 'messageid' => new external_value(PARAM_INT
, 'The unique search message id', VALUE_DEFAULT
, null),
1001 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1002 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1003 'isread' => new external_value(PARAM_BOOL
, 'If the user has read the message'),
1004 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
1005 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
1006 VALUE_DEFAULT
, null),
1007 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation', VALUE_DEFAULT
, null),
1013 * Return the structure of a conversation.
1015 * @return external_single_structure
1018 private static function get_conversation_structure() {
1019 return new external_single_structure(
1021 'id' => new external_value(PARAM_INT
, 'The conversation id'),
1022 'name' => new external_value(PARAM_RAW
, 'The conversation name, if set', VALUE_DEFAULT
, null),
1023 'subname' => new external_value(PARAM_RAW
, 'A subtitle for the conversation name, if set', VALUE_DEFAULT
, null),
1024 'imageurl' => new external_value(PARAM_URL
, 'A link to the conversation picture, if set', VALUE_DEFAULT
, null),
1025 'type' => new external_value(PARAM_INT
, 'The type of the conversation (1=individual,2=group,3=self)'),
1026 'membercount' => new external_value(PARAM_INT
, 'Total number of conversation members'),
1027 'ismuted' => new external_value(PARAM_BOOL
, 'If the user muted this conversation'),
1028 'isfavourite' => new external_value(PARAM_BOOL
, 'If the user marked this conversation as a favourite'),
1029 'isread' => new external_value(PARAM_BOOL
, 'If the user has read all messages in the conversation'),
1030 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
1031 VALUE_DEFAULT
, null),
1032 'members' => new external_multiple_structure(
1033 self
::get_conversation_member_structure()
1035 'messages' => new external_multiple_structure(
1036 self
::get_conversation_message_structure()
1038 'candeletemessagesforallusers' => new external_value(PARAM_BOOL
,
1039 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT
, false),
1045 * Return the structure of a conversation member.
1047 * @return external_single_structure
1050 private static function get_conversation_member_structure() {
1052 'id' => new external_value(PARAM_INT
, 'The user id'),
1053 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
1054 'profileurl' => new external_value(PARAM_URL
, 'The link to the user\'s profile page'),
1055 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
1056 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
1057 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1058 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1059 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
1060 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?'),
1061 'isdeleted' => new external_value(PARAM_BOOL
, 'Is the user deleted?'),
1062 'canmessageevenifblocked' => new external_value(PARAM_BOOL
,
1063 'If the user can still message even if they get blocked'),
1064 'canmessage' => new external_value(PARAM_BOOL
, 'If the user can be messaged'),
1065 'requirescontact' => new external_value(PARAM_BOOL
, 'If the user requires to be contacts'),
1068 $result['contactrequests'] = new external_multiple_structure(
1069 new external_single_structure(
1071 'id' => new external_value(PARAM_INT
, 'The id of the contact request'),
1072 'userid' => new external_value(PARAM_INT
, 'The id of the user who created the contact request'),
1073 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user confirming the request'),
1074 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the contact request'),
1076 ), 'The contact requests', VALUE_OPTIONAL
1079 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1081 'id' => new external_value(PARAM_INT
, 'Conversations id'),
1082 'type' => new external_value(PARAM_INT
, 'Conversation type: private or public'),
1083 'name' => new external_value(PARAM_RAW
, 'Multilang compatible conversation name'. VALUE_OPTIONAL
),
1084 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the conversation'),
1085 ), 'information about conversation', VALUE_OPTIONAL
),
1086 'Conversations between users', VALUE_OPTIONAL
1089 return new external_single_structure(
1095 * Return the structure of a message area message.
1097 * @return external_single_structure
1100 private static function get_conversation_message_structure() {
1101 return new external_single_structure(
1103 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1104 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1105 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
1106 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1112 * Get messagearea message search users parameters.
1114 * @return external_function_parameters
1117 public static function message_search_users_parameters() {
1118 return new external_function_parameters(
1120 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1121 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1122 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1123 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1129 * Get search users results.
1131 * @param int $userid The id of the user who is performing the search
1132 * @param string $search The string being searched
1133 * @param int $limitfrom
1134 * @param int $limitnum
1136 * @throws moodle_exception
1139 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
1142 $systemcontext = context_system
::instance();
1145 'userid' => $userid,
1146 'search' => $search,
1147 'limitfrom' => $limitfrom,
1148 'limitnum' => $limitnum
1150 $params = self
::validate_parameters(self
::message_search_users_parameters(), $params);
1151 self
::validate_context($systemcontext);
1153 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1154 throw new moodle_exception('You do not have permission to perform this action.');
1157 list($contacts, $noncontacts) = \core_message\api
::message_search_users(
1160 $params['limitfrom'],
1161 $params['limitnum']);
1163 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1167 * Get messagearea message search users returns.
1169 * @return external_single_structure
1172 public static function message_search_users_returns() {
1173 return new external_single_structure(
1175 'contacts' => new external_multiple_structure(
1176 self
::get_conversation_member_structure()
1178 'noncontacts' => new external_multiple_structure(
1179 self
::get_conversation_member_structure()
1186 * Get messagearea search messages parameters.
1188 * @return external_function_parameters
1191 public static function data_for_messagearea_search_messages_parameters() {
1192 return new external_function_parameters(
1194 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1195 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1196 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1197 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1203 * Get messagearea search messages results.
1205 * @param int $userid The id of the user who is performing the search
1206 * @param string $search The string being searched
1207 * @param int $limitfrom
1208 * @param int $limitnum
1210 * @throws moodle_exception
1213 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1216 // Check if messaging is enabled.
1217 if (empty($CFG->messaging
)) {
1218 throw new moodle_exception('disabled', 'message');
1221 $systemcontext = context_system
::instance();
1224 'userid' => $userid,
1225 'search' => $search,
1226 'limitfrom' => $limitfrom,
1227 'limitnum' => $limitnum
1230 $params = self
::validate_parameters(self
::data_for_messagearea_search_messages_parameters(), $params);
1231 self
::validate_context($systemcontext);
1233 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1234 throw new moodle_exception('You do not have permission to perform this action.');
1237 $messages = \core_message\api
::search_messages(
1240 $params['limitfrom'],
1244 $data = new \
stdClass();
1245 $data->contacts
= [];
1246 foreach ($messages as $message) {
1247 $contact = new \
stdClass();
1248 $contact->userid
= $message->userid
;
1249 $contact->fullname
= $message->fullname
;
1250 $contact->profileimageurl
= $message->profileimageurl
;
1251 $contact->profileimageurlsmall
= $message->profileimageurlsmall
;
1252 $contact->messageid
= $message->messageid
;
1253 $contact->ismessaging
= $message->ismessaging
;
1254 $contact->sentfromcurrentuser
= false;
1255 if ($message->lastmessage
) {
1256 if ($message->userid
!== $message->useridfrom
) {
1257 $contact->sentfromcurrentuser
= true;
1259 $contact->lastmessage
= shorten_text($message->lastmessage
, 60);
1261 $contact->lastmessage
= null;
1263 $contact->lastmessagedate
= $message->lastmessagedate
;
1264 $contact->showonlinestatus
= is_null($message->isonline
) ?
false : true;
1265 $contact->isonline
= $message->isonline
;
1266 $contact->isblocked
= $message->isblocked
;
1267 $contact->isread
= $message->isread
;
1268 $contact->unreadcount
= $message->unreadcount
;
1269 $contact->conversationid
= $message->conversationid
;
1271 $data->contacts
[] = $contact;
1278 * Get messagearea search messages returns.
1280 * @return external_single_structure
1283 public static function data_for_messagearea_search_messages_returns() {
1284 return new external_single_structure(
1286 'contacts' => new external_multiple_structure(
1287 self
::get_messagearea_contact_structure()
1294 * Get conversations parameters.
1296 * @return external_function_parameters
1299 public static function get_conversations_parameters() {
1300 return new external_function_parameters(
1302 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1303 'limitfrom' => new external_value(PARAM_INT
, 'The offset to start at', VALUE_DEFAULT
, 0),
1304 'limitnum' => new external_value(PARAM_INT
, 'Limit number of conversations to this', VALUE_DEFAULT
, 0),
1305 'type' => new external_value(PARAM_INT
, 'Filter by type', VALUE_DEFAULT
, null),
1306 'favourites' => new external_value(PARAM_BOOL
, 'Whether to restrict the results to contain NO favourite
1307 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1308 VALUE_DEFAULT
, null),
1309 'mergeself' => new external_value(PARAM_BOOL
, 'Whether to include self-conversations (true) or ONLY private
1310 conversations (false) when private conversations are requested.',
1311 VALUE_DEFAULT
, false),
1317 * Get the list of conversations for the user.
1319 * @param int $userid The id of the user who is performing the search
1320 * @param int $limitfrom
1321 * @param int $limitnum
1322 * @param int|null $type
1323 * @param bool|null $favourites
1324 * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false)
1325 * when private conversations are requested.
1327 * @throws \moodle_exception if the messaging feature is disabled on the site.
1330 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null,
1331 bool $mergeself = false) {
1334 // All the standard BL checks.
1335 if (empty($CFG->messaging
)) {
1336 throw new moodle_exception('disabled', 'message');
1340 'userid' => $userid,
1341 'limitfrom' => $limitfrom,
1342 'limitnum' => $limitnum,
1344 'favourites' => $favourites,
1345 'mergeself' => $mergeself
1347 $params = self
::validate_parameters(self
::get_conversations_parameters(), $params);
1349 $systemcontext = context_system
::instance();
1350 self
::validate_context($systemcontext);
1352 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1353 throw new moodle_exception('You do not have permission to perform this action.');
1356 $conversations = \core_message\api
::get_conversations(
1358 $params['limitfrom'],
1359 $params['limitnum'],
1361 $params['favourites'],
1362 $params['mergeself']
1365 return (object) ['conversations' => $conversations];
1369 * Get conversations returns.
1371 * @return external_single_structure
1374 public static function get_conversations_returns() {
1375 return new external_single_structure(
1377 'conversations' => new external_multiple_structure(
1378 self
::get_conversation_structure(true)
1385 * Get conversation parameters.
1387 * @return external_function_parameters
1389 public static function get_conversation_parameters() {
1390 return new external_function_parameters(
1392 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1393 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation to fetch'),
1394 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Include contact requests in the members'),
1395 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Include privacy info in the members'),
1396 'memberlimit' => new external_value(PARAM_INT
, 'Limit for number of members', VALUE_DEFAULT
, 0),
1397 'memberoffset' => new external_value(PARAM_INT
, 'Offset for member list', VALUE_DEFAULT
, 0),
1398 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1399 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1400 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1406 * Get a single conversation.
1408 * @param int $userid The user id to get the conversation for
1409 * @param int $conversationid The id of the conversation to fetch
1410 * @param bool $includecontactrequests Should contact requests be included between members
1411 * @param bool $includeprivacyinfo Should privacy info be included between members
1412 * @param int $memberlimit Limit number of members to load
1413 * @param int $memberoffset Offset members by this amount
1414 * @param int $messagelimit Limit number of messages to load
1415 * @param int $messageoffset Offset the messages
1416 * @param bool $newestmessagesfirst Order messages by newest first
1418 * @throws \moodle_exception if the messaging feature is disabled on the site.
1420 public static function get_conversation(
1422 int $conversationid,
1423 bool $includecontactrequests = false,
1424 bool $includeprivacyinfo = false,
1425 int $memberlimit = 0,
1426 int $memberoffset = 0,
1427 int $messagelimit = 0,
1428 int $messageoffset = 0,
1429 bool $newestmessagesfirst = true
1431 global $CFG, $DB, $USER;
1433 // All the standard BL checks.
1434 if (empty($CFG->messaging
)) {
1435 throw new moodle_exception('disabled', 'message');
1439 'userid' => $userid,
1440 'conversationid' => $conversationid,
1441 'includecontactrequests' => $includecontactrequests,
1442 'includeprivacyinfo' => $includeprivacyinfo,
1443 'memberlimit' => $memberlimit,
1444 'memberoffset' => $memberoffset,
1445 'messagelimit' => $messagelimit,
1446 'messageoffset' => $messageoffset,
1447 'newestmessagesfirst' => $newestmessagesfirst
1449 self
::validate_parameters(self
::get_conversation_parameters(), $params);
1451 $systemcontext = context_system
::instance();
1452 self
::validate_context($systemcontext);
1454 $conversation = \core_message\api
::get_conversation(
1456 $params['conversationid'],
1457 $params['includecontactrequests'],
1458 $params['includeprivacyinfo'],
1459 $params['memberlimit'],
1460 $params['memberoffset'],
1461 $params['messagelimit'],
1462 $params['messageoffset'],
1463 $params['newestmessagesfirst']
1466 if ($conversation) {
1467 return $conversation;
1469 // We have to throw an exception here because the external functions annoyingly
1470 // don't accept null to be returned for a single structure.
1471 throw new \
moodle_exception('errorconversationdoesnotexist', 'message');
1476 * Get conversation returns.
1478 * @return external_single_structure
1480 public static function get_conversation_returns() {
1481 return self
::get_conversation_structure();
1485 * Get conversation parameters.
1487 * @return external_function_parameters
1489 public static function get_conversation_between_users_parameters() {
1490 return new external_function_parameters(
1492 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1493 'otheruserid' => new external_value(PARAM_INT
, 'The other user id'),
1494 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Include contact requests in the members'),
1495 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'Include privacy info in the members'),
1496 'memberlimit' => new external_value(PARAM_INT
, 'Limit for number of members', VALUE_DEFAULT
, 0),
1497 'memberoffset' => new external_value(PARAM_INT
, 'Offset for member list', VALUE_DEFAULT
, 0),
1498 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1499 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1500 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1506 * Get a single conversation between users.
1508 * @param int $userid The user id to get the conversation for
1509 * @param int $otheruserid The other user id
1510 * @param bool $includecontactrequests Should contact requests be included between members
1511 * @param bool $includeprivacyinfo Should privacy info be included between members
1512 * @param int $memberlimit Limit number of members to load
1513 * @param int $memberoffset Offset members by this amount
1514 * @param int $messagelimit Limit number of messages to load
1515 * @param int $messageoffset Offset the messages
1516 * @param bool $newestmessagesfirst Order messages by newest first
1518 * @throws \moodle_exception if the messaging feature is disabled on the site.
1520 public static function get_conversation_between_users(
1523 bool $includecontactrequests = false,
1524 bool $includeprivacyinfo = false,
1525 int $memberlimit = 0,
1526 int $memberoffset = 0,
1527 int $messagelimit = 0,
1528 int $messageoffset = 0,
1529 bool $newestmessagesfirst = true
1531 global $CFG, $DB, $USER;
1533 // All the standard BL checks.
1534 if (empty($CFG->messaging
)) {
1535 throw new moodle_exception('disabled', 'message');
1539 'userid' => $userid,
1540 'otheruserid' => $otheruserid,
1541 'includecontactrequests' => $includecontactrequests,
1542 'includeprivacyinfo' => $includeprivacyinfo,
1543 'memberlimit' => $memberlimit,
1544 'memberoffset' => $memberoffset,
1545 'messagelimit' => $messagelimit,
1546 'messageoffset' => $messageoffset,
1547 'newestmessagesfirst' => $newestmessagesfirst
1549 self
::validate_parameters(self
::get_conversation_between_users_parameters(), $params);
1551 $systemcontext = context_system
::instance();
1552 self
::validate_context($systemcontext);
1554 $conversationid = \core_message\api
::get_conversation_between_users([$params['userid'], $params['otheruserid']]);
1555 $conversation = null;
1557 if ($conversationid) {
1558 $conversation = \core_message\api
::get_conversation(
1561 $params['includecontactrequests'],
1562 $params['includeprivacyinfo'],
1563 $params['memberlimit'],
1564 $params['memberoffset'],
1565 $params['messagelimit'],
1566 $params['messageoffset'],
1567 $params['newestmessagesfirst']
1571 if ($conversation) {
1572 return $conversation;
1574 // We have to throw an exception here because the external functions annoyingly
1575 // don't accept null to be returned for a single structure.
1576 throw new \
moodle_exception('errorconversationdoesnotexist', 'message');
1581 * Get conversation returns.
1583 * @return external_single_structure
1585 public static function get_conversation_between_users_returns() {
1586 return self
::get_conversation_structure(true);
1590 * Get self-conversation parameters.
1592 * @return external_function_parameters
1594 public static function get_self_conversation_parameters() {
1595 return new external_function_parameters(
1597 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing self-conversations for'),
1598 'messagelimit' => new external_value(PARAM_INT
, 'Limit for number of messages', VALUE_DEFAULT
, 100),
1599 'messageoffset' => new external_value(PARAM_INT
, 'Offset for messages list', VALUE_DEFAULT
, 0),
1600 'newestmessagesfirst' => new external_value(PARAM_BOOL
, 'Order messages by newest first', VALUE_DEFAULT
, true)
1606 * Get a single self-conversation.
1608 * @param int $userid The user id to get the self-conversation for
1609 * @param int $messagelimit Limit number of messages to load
1610 * @param int $messageoffset Offset the messages
1611 * @param bool $newestmessagesfirst Order messages by newest first
1613 * @throws \moodle_exception if the messaging feature is disabled on the site.
1616 public static function get_self_conversation(
1618 int $messagelimit = 0,
1619 int $messageoffset = 0,
1620 bool $newestmessagesfirst = true
1624 // All the standard BL checks.
1625 if (empty($CFG->messaging
)) {
1626 throw new moodle_exception('disabled', 'message');
1630 'userid' => $userid,
1631 'messagelimit' => $messagelimit,
1632 'messageoffset' => $messageoffset,
1633 'newestmessagesfirst' => $newestmessagesfirst
1635 self
::validate_parameters(self
::get_self_conversation_parameters(), $params);
1637 $systemcontext = context_system
::instance();
1638 self
::validate_context($systemcontext);
1640 $conversation = \core_message\api
::get_self_conversation($params['userid']);
1642 if ($conversation) {
1643 $conversation = \core_message\api
::get_conversation(
1650 $params['messagelimit'],
1651 $params['messageoffset'],
1652 $params['newestmessagesfirst']
1656 if ($conversation) {
1657 return $conversation;
1659 // We have to throw an exception here because the external functions annoyingly
1660 // don't accept null to be returned for a single structure.
1661 throw new \
moodle_exception('errorconversationdoesnotexist', 'message');
1666 * Get conversation returns.
1668 * @return external_single_structure
1670 public static function get_self_conversation_returns() {
1671 return self
::get_conversation_structure();
1675 * The conversation messages parameters.
1677 * @return external_function_parameters
1680 public static function get_conversation_messages_parameters() {
1681 return new external_function_parameters(
1683 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1684 'convid' => new external_value(PARAM_INT
, 'The conversation id'),
1685 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1686 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1687 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
1688 'timefrom' => new external_value(PARAM_INT
,
1689 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
1695 * Get conversation messages.
1697 * @param int $currentuserid The current user's id.
1698 * @param int $convid The conversation id.
1699 * @param int $limitfrom Return a subset of records, starting at this point (optional).
1700 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
1701 * @param bool $newest True for getting first newest messages, false otherwise.
1702 * @param int $timefrom The time from the conversation messages to get.
1703 * @return array The messages and members who have sent some of these messages.
1704 * @throws moodle_exception
1707 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
1708 bool $newest = false, int $timefrom = 0) {
1711 // Check if messaging is enabled.
1712 if (empty($CFG->messaging
)) {
1713 throw new moodle_exception('disabled', 'message');
1716 $systemcontext = context_system
::instance();
1719 'currentuserid' => $currentuserid,
1720 'convid' => $convid,
1721 'limitfrom' => $limitfrom,
1722 'limitnum' => $limitnum,
1723 'newest' => $newest,
1724 'timefrom' => $timefrom,
1726 $params = self
::validate_parameters(self
::get_conversation_messages_parameters(), $params);
1727 self
::validate_context($systemcontext);
1729 if (($USER->id
!= $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1730 throw new moodle_exception('You do not have permission to perform this action.');
1733 // Check that the user belongs to the conversation.
1734 if (!\core_message\api
::is_user_in_conversation($params['currentuserid'], $params['convid'])) {
1735 throw new moodle_exception('User is not part of conversation.');
1738 $sort = $newest ?
'timecreated DESC' : 'timecreated ASC';
1740 // We need to enforce a one second delay on messages to avoid race conditions of current
1741 // messages still being sent.
1743 // There is a chance that we could request messages before the current time's
1744 // second has elapsed and while other messages are being sent in that same second. In which
1745 // case those messages will be lost.
1747 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
1748 $timeto = empty($params['timefrom']) ?
0 : time() - 1;
1750 // No requesting messages from the current time, as stated above.
1751 if ($params['timefrom'] == time()) {
1754 $messages = \core_message\api
::get_conversation_messages(
1755 $params['currentuserid'],
1757 $params['limitfrom'],
1758 $params['limitnum'],
1760 $params['timefrom'],
1768 * The messagearea messages return structure.
1770 * @return external_single_structure
1773 public static function get_conversation_messages_returns() {
1774 return new external_single_structure(
1776 'id' => new external_value(PARAM_INT
, 'The conversation id'),
1777 'members' => new external_multiple_structure(
1778 self
::get_conversation_member_structure()
1780 'messages' => new external_multiple_structure(
1781 self
::get_conversation_message_structure()
1788 * The user contacts return parameters.
1790 * @return external_function_parameters
1792 public static function get_user_contacts_parameters() {
1793 return new external_function_parameters(
1795 'userid' => new external_value(PARAM_INT
, 'The id of the user who we retrieving the contacts for'),
1796 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1797 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1803 * Get user contacts.
1805 * @param int $userid The id of the user who we are viewing conversations for
1806 * @param int $limitfrom
1807 * @param int $limitnum
1809 * @throws moodle_exception
1811 public static function get_user_contacts(int $userid, int $limitfrom = 0, int $limitnum = 0) {
1814 // Check if messaging is enabled.
1815 if (empty($CFG->messaging
)) {
1816 throw new moodle_exception('disabled', 'message');
1819 $systemcontext = context_system
::instance();
1822 'userid' => $userid,
1823 'limitfrom' => $limitfrom,
1824 'limitnum' => $limitnum
1826 $params = self
::validate_parameters(self
::get_user_contacts_parameters(), $params);
1827 self
::validate_context($systemcontext);
1829 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1830 throw new moodle_exception('You do not have permission to perform this action.');
1833 return \core_message\api
::get_user_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
1837 * The user contacts return structure.
1839 * @return external_multiple_structure
1841 public static function get_user_contacts_returns() {
1842 return new external_multiple_structure(
1843 self
::get_conversation_member_structure()
1848 * Search contacts parameters description.
1850 * @return external_function_parameters
1853 public static function search_contacts_parameters() {
1854 return new external_function_parameters(
1856 'searchtext' => new external_value(PARAM_CLEAN
, 'String the user\'s fullname has to match to be found'),
1857 'onlymycourses' => new external_value(PARAM_BOOL
, 'Limit search to the user\'s courses',
1858 VALUE_DEFAULT
, false)
1866 * @param string $searchtext query string.
1867 * @param bool $onlymycourses limit the search to the user's courses only.
1868 * @return external_description
1871 public static function search_contacts($searchtext, $onlymycourses = false) {
1872 global $CFG, $USER, $PAGE;
1873 require_once($CFG->dirroot
. '/user/lib.php');
1875 // Check if messaging is enabled.
1876 if (empty($CFG->messaging
)) {
1877 throw new moodle_exception('disabled', 'message');
1880 require_once($CFG->libdir
. '/enrollib.php');
1882 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1883 $params = self
::validate_parameters(self
::search_contacts_parameters(), $params);
1885 // Extra validation, we do not allow empty queries.
1886 if ($params['searchtext'] === '') {
1887 throw new moodle_exception('querystringcannotbeempty');
1890 $courseids = array();
1891 if ($params['onlymycourses']) {
1892 $mycourses = enrol_get_my_courses(array('id'));
1893 foreach ($mycourses as $mycourse) {
1894 $courseids[] = $mycourse->id
;
1897 $courseids[] = SITEID
;
1900 // Retrieving the users matching the query.
1901 $users = message_search_users($courseids, $params['searchtext']);
1903 foreach ($users as $user) {
1904 $results[$user->id
] = $user;
1907 // Reorganising information.
1908 foreach ($results as &$user) {
1911 'fullname' => fullname($user)
1914 // Avoid undefined property notice as phone not specified.
1915 $user->phone1
= null;
1916 $user->phone2
= null;
1918 $userpicture = new user_picture($user);
1919 $userpicture->size
= 1; // Size f1.
1920 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1921 $userpicture->size
= 0; // Size f2.
1922 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1931 * Search contacts return description.
1933 * @return external_description
1936 public static function search_contacts_returns() {
1937 return new external_multiple_structure(
1938 new external_single_structure(
1940 'id' => new external_value(PARAM_INT
, 'User ID'),
1941 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1942 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1943 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
)
1951 * Get messages parameters description.
1953 * @return external_function_parameters
1956 public static function get_messages_parameters() {
1957 return new external_function_parameters(
1959 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
1960 'useridfrom' => new external_value(
1961 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1963 'type' => new external_value(
1964 PARAM_ALPHA
, 'type of message to return, expected values are: notifications, conversations and both',
1965 VALUE_DEFAULT
, 'both'),
1966 'read' => new external_value(PARAM_INT
, '1 for getting read messages, 0 for unread, 2 for both',
1968 'newestfirst' => new external_value(
1969 PARAM_BOOL
, 'true for ordering by newest first, false for oldest first',
1970 VALUE_DEFAULT
, true),
1971 'limitfrom' => new external_value(PARAM_INT
, 'limit from', VALUE_DEFAULT
, 0),
1972 'limitnum' => new external_value(PARAM_INT
, 'limit number', VALUE_DEFAULT
, 0)
1978 * Get messages function implementation.
1981 * @throws invalid_parameter_exception
1982 * @throws moodle_exception
1983 * @param int $useridto the user id who received the message
1984 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1985 * @param string $type type of message to return, expected values: notifications, conversations and both
1986 * @param int $read 1 for getting read messages, 0 for unread, 2 for both
1987 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1988 * @param int $limitfrom limit from
1989 * @param int $limitnum limit num
1990 * @return external_description
1992 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = MESSAGE_GET_READ
,
1993 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
1994 global $CFG, $USER, $PAGE;
1996 $warnings = array();
1999 'useridto' => $useridto,
2000 'useridfrom' => $useridfrom,
2003 'newestfirst' => $newestfirst,
2004 'limitfrom' => $limitfrom,
2005 'limitnum' => $limitnum
2008 $params = self
::validate_parameters(self
::get_messages_parameters(), $params);
2010 $context = context_system
::instance();
2011 self
::validate_context($context);
2013 $useridto = $params['useridto'];
2014 $useridfrom = $params['useridfrom'];
2015 $type = $params['type'];
2016 $read = $params['read'];
2017 $newestfirst = $params['newestfirst'];
2018 $limitfrom = $params['limitfrom'];
2019 $limitnum = $params['limitnum'];
2021 $allowedvalues = array('notifications', 'conversations', 'both');
2022 if (!in_array($type, $allowedvalues)) {
2023 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
2024 'allowed values are: ' . implode(',', $allowedvalues));
2027 // Check if private messaging between users is allowed.
2028 if (empty($CFG->messaging
)) {
2029 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
2030 if ($type == "conversations") {
2031 throw new moodle_exception('disabled', 'message');
2033 if ($type == "both") {
2035 $warning['item'] = 'message';
2036 $warning['itemid'] = $USER->id
;
2037 $warning['warningcode'] = '1';
2038 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
2039 Only notifications will be returned';
2040 $warnings[] = $warning;
2044 if (!empty($useridto)) {
2045 if (core_user
::is_real_user($useridto)) {
2046 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2048 throw new moodle_exception('invaliduser');
2052 if (!empty($useridfrom)) {
2053 // We use get_user here because the from user can be the noreply or support user.
2054 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2057 // Check if the current user is the sender/receiver or just a privileged user.
2058 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2059 !has_capability('moodle/site:readallmessages', $context)) {
2060 throw new moodle_exception('accessdenied', 'admin');
2063 // Which type of messages to retrieve.
2064 $notifications = -1;
2065 if ($type != 'both') {
2066 $notifications = ($type == 'notifications') ?
1 : 0;
2069 $orderdirection = $newestfirst ?
'DESC' : 'ASC';
2070 $sort = "mr.timecreated $orderdirection";
2072 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
2073 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
2075 // In some cases, we don't need to get the to/from user objects from the sql query.
2076 $userfromfullname = '';
2077 $usertofullname = '';
2079 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
2080 if (!empty($useridto)) {
2081 $usertofullname = fullname($userto, $canviewfullname);
2082 // The user from may or may not be filled.
2083 if (!empty($useridfrom)) {
2084 $userfromfullname = fullname($userfrom, $canviewfullname);
2087 // If the useridto field is empty, the useridfrom must be filled.
2088 $userfromfullname = fullname($userfrom, $canviewfullname);
2090 foreach ($messages as $mid => $message) {
2092 if (!$message->notification
) {
2093 // Do not return deleted messages.
2094 if (($useridto == $USER->id
and $message->timeusertodeleted
) or
2095 ($useridfrom == $USER->id
and $message->timeuserfromdeleted
)) {
2096 unset($messages[$mid]);
2100 // Return iconurl for notifications.
2101 if (!isset($output)) {
2102 $output = $PAGE->get_renderer('core');
2105 if (!empty($message->component
) && substr($message->component
, 0, 4) == 'mod_') {
2106 $iconurl = $output->image_url('icon', $message->component
);
2108 $iconurl = $output->image_url('i/marker', 'core');
2111 $message->iconurl
= clean_param($iconurl->out(), PARAM_URL
);
2114 // We need to get the user from the query.
2115 if (empty($userfromfullname)) {
2116 // Check for non-reply and support users.
2117 if (core_user
::is_real_user($message->useridfrom
)) {
2118 $user = new stdClass();
2119 $user = username_load_fields_from_object($user, $message, 'userfrom');
2120 $message->userfromfullname
= fullname($user, $canviewfullname);
2122 $user = core_user
::get_user($message->useridfrom
);
2123 $message->userfromfullname
= fullname($user, $canviewfullname);
2126 $message->userfromfullname
= $userfromfullname;
2129 // We need to get the user from the query.
2130 if (empty($usertofullname)) {
2131 $user = new stdClass();
2132 $user = username_load_fields_from_object($user, $message, 'userto');
2133 $message->usertofullname
= fullname($user, $canviewfullname);
2135 $message->usertofullname
= $usertofullname;
2138 $message->text
= message_format_message_text($message);
2139 $messages[$mid] = (array) $message;
2144 'messages' => $messages,
2145 'warnings' => $warnings
2152 * Get messages return description.
2154 * @return external_single_structure
2157 public static function get_messages_returns() {
2158 return new external_single_structure(
2160 'messages' => new external_multiple_structure(
2161 new external_single_structure(
2163 'id' => new external_value(PARAM_INT
, 'Message id'),
2164 'useridfrom' => new external_value(PARAM_INT
, 'User from id'),
2165 'useridto' => new external_value(PARAM_INT
, 'User to id'),
2166 'subject' => new external_value(PARAM_TEXT
, 'The message subject'),
2167 'text' => new external_value(PARAM_RAW
, 'The message text formated'),
2168 'fullmessage' => new external_value(PARAM_RAW
, 'The message'),
2169 'fullmessageformat' => new external_format_value('fullmessage'),
2170 'fullmessagehtml' => new external_value(PARAM_RAW
, 'The message in html'),
2171 'smallmessage' => new external_value(PARAM_RAW
, 'The shorten message'),
2172 'notification' => new external_value(PARAM_INT
, 'Is a notification?'),
2173 'contexturl' => new external_value(PARAM_RAW
, 'Context URL'),
2174 'contexturlname' => new external_value(PARAM_TEXT
, 'Context URL link name'),
2175 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
2176 'timeread' => new external_value(PARAM_INT
, 'Time read'),
2177 'usertofullname' => new external_value(PARAM_TEXT
, 'User to full name'),
2178 'userfromfullname' => new external_value(PARAM_TEXT
, 'User from full name'),
2179 'component' => new external_value(PARAM_TEXT
, 'The component that generated the notification',
2181 'eventtype' => new external_value(PARAM_TEXT
, 'The type of notification', VALUE_OPTIONAL
),
2182 'customdata' => new external_value(PARAM_RAW
, 'Custom data to be passed to the message processor.
2183 The data here is serialised using json_encode().', VALUE_OPTIONAL
),
2184 'iconurl' => new external_value(PARAM_URL
, 'URL for icon, only for notifications.', VALUE_OPTIONAL
),
2188 'warnings' => new external_warnings()
2194 * Mark all notifications as read parameters description.
2196 * @return external_function_parameters
2199 public static function mark_all_notifications_as_read_parameters() {
2200 return new external_function_parameters(
2202 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2203 'useridfrom' => new external_value(
2204 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2206 'timecreatedto' => new external_value(
2207 PARAM_INT
, 'mark messages created before this time as read, 0 for all messages',
2214 * Mark all notifications as read function.
2217 * @throws invalid_parameter_exception
2218 * @throws moodle_exception
2219 * @param int $useridto the user id who received the message
2220 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2221 * @param int $timecreatedto mark message created before this time as read, 0 for all messages
2222 * @return external_description
2224 public static function mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto = 0) {
2227 $params = self
::validate_parameters(
2228 self
::mark_all_notifications_as_read_parameters(),
2230 'useridto' => $useridto,
2231 'useridfrom' => $useridfrom,
2232 'timecreatedto' => $timecreatedto,
2236 $context = context_system
::instance();
2237 self
::validate_context($context);
2239 $useridto = $params['useridto'];
2240 $useridfrom = $params['useridfrom'];
2241 $timecreatedto = $params['timecreatedto'];
2243 if (!empty($useridto)) {
2244 if (core_user
::is_real_user($useridto)) {
2245 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2247 throw new moodle_exception('invaliduser');
2251 if (!empty($useridfrom)) {
2252 // We use get_user here because the from user can be the noreply or support user.
2253 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2256 // Check if the current user is the sender/receiver or just a privileged user.
2257 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2258 // The deleteanymessage cap seems more reasonable here than readallmessages.
2259 !has_capability('moodle/site:deleteanymessage', $context)) {
2260 throw new moodle_exception('accessdenied', 'admin');
2263 \core_message\api
::mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto);
2269 * Mark all notifications as read return description.
2271 * @return external_single_structure
2274 public static function mark_all_notifications_as_read_returns() {
2275 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
2279 * Get unread conversations count parameters description.
2281 * @return external_function_parameters
2284 public static function get_unread_conversations_count_parameters() {
2285 return new external_function_parameters(
2287 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2293 * Get unread messages count function.
2296 * @throws invalid_parameter_exception
2297 * @throws moodle_exception
2298 * @param int $useridto the user id who received the message
2299 * @return external_description
2301 public static function get_unread_conversations_count($useridto) {
2304 // Check if messaging is enabled.
2305 if (empty($CFG->messaging
)) {
2306 throw new moodle_exception('disabled', 'message');
2309 $params = self
::validate_parameters(
2310 self
::get_unread_conversations_count_parameters(),
2311 array('useridto' => $useridto)
2314 $context = context_system
::instance();
2315 self
::validate_context($context);
2317 $useridto = $params['useridto'];
2319 if (!empty($useridto)) {
2320 if (core_user
::is_real_user($useridto)) {
2321 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2323 throw new moodle_exception('invaliduser');
2326 $useridto = $USER->id
;
2329 // Check if the current user is the receiver or just a privileged user.
2330 if ($useridto != $USER->id
and !has_capability('moodle/site:readallmessages', $context)) {
2331 throw new moodle_exception('accessdenied', 'admin');
2334 return \core_message\api
::count_unread_conversations($userto);
2338 * Get unread conversations count return description.
2340 * @return external_single_structure
2343 public static function get_unread_conversations_count_returns() {
2344 return new external_value(PARAM_INT
, 'The count of unread messages for the user');
2348 * Get blocked users parameters description.
2350 * @return external_function_parameters
2353 public static function get_blocked_users_parameters() {
2354 return new external_function_parameters(
2356 'userid' => new external_value(PARAM_INT
,
2357 'the user whose blocked users we want to retrieve',
2364 * Retrieve a list of users blocked
2366 * @param int $userid the user whose blocked users we want to retrieve
2367 * @return external_description
2370 public static function get_blocked_users($userid) {
2371 global $CFG, $USER, $PAGE;
2373 // Warnings array, it can be empty at the end but is mandatory.
2374 $warnings = array();
2380 $params = self
::validate_parameters(self
::get_blocked_users_parameters(), $params);
2381 $userid = $params['userid'];
2383 // Validate context.
2384 $context = context_system
::instance();
2385 self
::validate_context($context);
2387 // Check if private messaging between users is allowed.
2388 if (empty($CFG->messaging
)) {
2389 throw new moodle_exception('disabled', 'message');
2392 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
2393 core_user
::require_active_user($user);
2395 // Check if we have permissions for retrieve the information.
2396 $capability = 'moodle/site:manageallmessaging';
2397 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
2398 throw new required_capability_exception($context, $capability, 'nopermissions', '');
2401 // Now, we can get safely all the blocked users.
2402 $users = \core_message\api
::get_blocked_users($user->id
);
2404 $blockedusers = array();
2405 foreach ($users as $user) {
2408 'fullname' => fullname($user),
2411 $userpicture = new user_picture($user);
2412 $userpicture->size
= 1; // Size f1.
2413 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2415 $blockedusers[] = $newuser;
2419 'users' => $blockedusers,
2420 'warnings' => $warnings
2426 * Get blocked users return description.
2428 * @return external_single_structure
2431 public static function get_blocked_users_returns() {
2432 return new external_single_structure(
2434 'users' => new external_multiple_structure(
2435 new external_single_structure(
2437 'id' => new external_value(PARAM_INT
, 'User ID'),
2438 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2439 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
)
2442 'List of blocked users'
2444 'warnings' => new external_warnings()
2450 * Returns description of method parameters
2452 * @return external_function_parameters
2455 public static function mark_message_read_parameters() {
2456 return new external_function_parameters(
2458 'messageid' => new external_value(PARAM_INT
, 'id of the message in the messages table'),
2459 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the message should be marked read',
2466 * Mark a single message as read, trigger message_viewed event
2468 * @param int $messageid id of the message (in the message table)
2469 * @param int $timeread timestamp for when the message should be marked read
2470 * @return external_description
2471 * @throws invalid_parameter_exception
2472 * @throws moodle_exception
2475 public static function mark_message_read($messageid, $timeread) {
2476 global $CFG, $DB, $USER;
2478 // Check if private messaging between users is allowed.
2479 if (empty($CFG->messaging
)) {
2480 throw new moodle_exception('disabled', 'message');
2483 // Warnings array, it can be empty at the end but is mandatory.
2484 $warnings = array();
2488 'messageid' => $messageid,
2489 'timeread' => $timeread
2491 $params = self
::validate_parameters(self
::mark_message_read_parameters(), $params);
2493 if (empty($params['timeread'])) {
2496 $timeread = $params['timeread'];
2499 // Validate context.
2500 $context = context_system
::instance();
2501 self
::validate_context($context);
2503 $sql = "SELECT m.*, mcm.userid as useridto
2505 INNER JOIN {message_conversations} mc
2506 ON m.conversationid = mc.id
2507 INNER JOIN {message_conversation_members} mcm
2508 ON mcm.conversationid = mc.id
2509 LEFT JOIN {message_user_actions} mua
2510 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
2511 WHERE mua.id is NULL
2512 AND mcm.userid != m.useridfrom
2514 $messageparams = [];
2515 $messageparams[] = $USER->id
;
2516 $messageparams[] = \core_message\api
::MESSAGE_ACTION_READ
;
2517 $messageparams[] = $params['messageid'];
2518 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST
);
2520 if ($message->useridto
!= $USER->id
) {
2521 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2524 \core_message\api
::mark_message_as_read($USER->id
, $message, $timeread);
2527 'messageid' => $message->id
,
2528 'warnings' => $warnings
2534 * Returns description of method result value
2536 * @return external_description
2539 public static function mark_message_read_returns() {
2540 return new external_single_structure(
2542 'messageid' => new external_value(PARAM_INT
, 'the id of the message in the messages table'),
2543 'warnings' => new external_warnings()
2549 * Returns description of method parameters
2551 * @return external_function_parameters
2553 public static function mark_notification_read_parameters() {
2554 return new external_function_parameters(
2556 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
2557 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the notification should be marked read',
2564 * Mark a single notification as read.
2566 * This will trigger a 'notification_viewed' event.
2568 * @param int $notificationid id of the notification
2569 * @param int $timeread timestamp for when the notification should be marked read
2570 * @return external_description
2571 * @throws invalid_parameter_exception
2572 * @throws moodle_exception
2574 public static function mark_notification_read($notificationid, $timeread) {
2575 global $CFG, $DB, $USER;
2577 // Warnings array, it can be empty at the end but is mandatory.
2578 $warnings = array();
2582 'notificationid' => $notificationid,
2583 'timeread' => $timeread
2585 $params = self
::validate_parameters(self
::mark_notification_read_parameters(), $params);
2587 if (empty($params['timeread'])) {
2590 $timeread = $params['timeread'];
2593 // Validate context.
2594 $context = context_system
::instance();
2595 self
::validate_context($context);
2597 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST
);
2599 if ($notification->useridto
!= $USER->id
) {
2600 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
2601 'notification as read');
2604 \core_message\api
::mark_notification_as_read($notification, $timeread);
2607 'notificationid' => $notification->id
,
2608 'warnings' => $warnings
2615 * Returns description of method result value
2617 * @return external_description
2619 public static function mark_notification_read_returns() {
2620 return new external_single_structure(
2622 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
2623 'warnings' => new external_warnings()
2629 * Mark all conversation messages as read parameters description.
2631 * @return external_function_parameters
2634 public static function mark_all_conversation_messages_as_read_parameters() {
2635 return new external_function_parameters(
2637 'userid' => new external_value(PARAM_INT
, 'The user id who who we are marking the messages as read for'),
2639 new external_value(PARAM_INT
, 'The conversation id who who we are marking the messages as read for')
2645 * Mark all conversation messages as read function.
2647 * @param int $userid The user id of who we want to delete the conversation for
2648 * @param int $conversationid The id of the conversations
2651 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
2654 // Check if messaging is enabled.
2655 if (empty($CFG->messaging
)) {
2656 throw new moodle_exception('disabled', 'message');
2660 'userid' => $userid,
2661 'conversationid' => $conversationid,
2663 $params = self
::validate_parameters(self
::mark_all_conversation_messages_as_read_parameters(), $params);
2665 $context = context_system
::instance();
2666 self
::validate_context($context);
2668 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2669 core_user
::require_active_user($user);
2671 if (\core_message\api
::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) {
2672 \core_message\api
::mark_all_messages_as_read($params['userid'], $params['conversationid']);
2674 throw new moodle_exception('accessdenied', 'admin');
2679 * Mark all conversation messages as read return description.
2681 * @return external_warnings
2684 public static function mark_all_conversation_messages_as_read_returns() {
2689 * Returns description of method parameters.
2691 * @return external_function_parameters
2694 public static function delete_conversations_by_id_parameters() {
2695 return new external_function_parameters(
2697 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
2698 'conversationids' => new external_multiple_structure(
2699 new external_value(PARAM_INT
, 'The id of the conversation'),
2700 'List of conversation IDs'
2707 * Deletes a conversation.
2709 * @param int $userid The user id of who we want to delete the conversation for
2710 * @param int[] $conversationids The ids of the conversations
2712 * @throws moodle_exception
2715 public static function delete_conversations_by_id($userid, array $conversationids) {
2718 // Check if private messaging between users is allowed.
2719 if (empty($CFG->messaging
)) {
2720 throw new moodle_exception('disabled', 'message');
2725 'userid' => $userid,
2726 'conversationids' => $conversationids,
2728 $params = self
::validate_parameters(self
::delete_conversations_by_id_parameters(), $params);
2730 // Validate context.
2731 $context = context_system
::instance();
2732 self
::validate_context($context);
2734 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2735 core_user
::require_active_user($user);
2737 foreach ($params['conversationids'] as $conversationid) {
2738 if (\core_message\api
::can_delete_conversation($user->id
, $conversationid)) {
2739 \core_message\api
::delete_conversation_by_id($user->id
, $conversationid);
2741 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'");
2749 * Returns description of method result value.
2751 * @return external_description
2754 public static function delete_conversations_by_id_returns() {
2755 return new external_warnings();
2759 * Returns description of method parameters
2761 * @return external_function_parameters
2764 public static function delete_message_parameters() {
2765 return new external_function_parameters(
2767 'messageid' => new external_value(PARAM_INT
, 'The message id'),
2768 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for'),
2769 'read' => new external_value(PARAM_BOOL
, 'If is a message read', VALUE_DEFAULT
, true)
2777 * @param int $messageid the message id
2778 * @param int $userid the user id of who we want to delete the message for
2779 * @param bool $read if is a message read (default to true)
2780 * @return external_description
2781 * @throws moodle_exception
2784 public static function delete_message($messageid, $userid, $read = true) {
2787 // Check if private messaging between users is allowed.
2788 if (empty($CFG->messaging
)) {
2789 throw new moodle_exception('disabled', 'message');
2792 // Warnings array, it can be empty at the end but is mandatory.
2793 $warnings = array();
2797 'messageid' => $messageid,
2798 'userid' => $userid,
2801 $params = self
::validate_parameters(self
::delete_message_parameters(), $params);
2803 // Validate context.
2804 $context = context_system
::instance();
2805 self
::validate_context($context);
2807 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2808 core_user
::require_active_user($user);
2810 if (\core_message\api
::can_delete_message($user->id
, $params['messageid'])) {
2811 $status = \core_message\api
::delete_message($user->id
, $params['messageid']);
2813 throw new moodle_exception('You do not have permission to delete this message');
2817 'status' => $status,
2818 'warnings' => $warnings
2824 * Returns description of method result value
2826 * @return external_description
2829 public static function delete_message_returns() {
2830 return new external_single_structure(
2832 'status' => new external_value(PARAM_BOOL
, 'True if the message was deleted, false otherwise'),
2833 'warnings' => new external_warnings()
2839 * Returns description of method parameters
2841 * @return external_function_parameters
2844 public static function message_processor_config_form_parameters() {
2845 return new external_function_parameters(
2847 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_REQUIRED
),
2848 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor'),
2849 'formvalues' => new external_multiple_structure(
2850 new external_single_structure(
2852 'name' => new external_value(PARAM_TEXT
, 'name of the form element', VALUE_REQUIRED
),
2853 'value' => new external_value(PARAM_RAW
, 'value of the form element', VALUE_REQUIRED
),
2856 'Config form values',
2864 * Processes a message processor config form.
2866 * @param int $userid the user id
2867 * @param string $name the name of the processor
2868 * @param array $formvalues the form values
2869 * @return external_description
2870 * @throws moodle_exception
2873 public static function message_processor_config_form($userid, $name, $formvalues) {
2876 $params = self
::validate_parameters(
2877 self
::message_processor_config_form_parameters(),
2879 'userid' => $userid,
2881 'formvalues' => $formvalues,
2885 $user = self
::validate_preferences_permissions($params['userid']);
2887 $processor = get_message_processor($params['name']);
2889 $form = new stdClass();
2891 foreach ($params['formvalues'] as $formvalue) {
2892 // Curly braces to ensure interpretation is consistent between
2894 $form->{$formvalue['name']} = $formvalue['value'];
2897 $processor->process_form($form, $preferences);
2899 if (!empty($preferences)) {
2900 set_user_preferences($preferences, $params['userid']);
2905 * Returns description of method result value
2907 * @return external_description
2910 public static function message_processor_config_form_returns() {
2915 * Returns description of method parameters
2917 * @return external_function_parameters
2920 public static function get_message_processor_parameters() {
2921 return new external_function_parameters(
2923 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user'),
2924 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor', VALUE_REQUIRED
),
2930 * Get a message processor.
2932 * @param int $userid
2933 * @param string $name the name of the processor
2934 * @return external_description
2935 * @throws moodle_exception
2938 public static function get_message_processor($userid, $name) {
2939 global $USER, $PAGE, $CFG;
2941 // Check if messaging is enabled.
2942 if (empty($CFG->messaging
)) {
2943 throw new moodle_exception('disabled', 'message');
2946 $params = self
::validate_parameters(
2947 self
::get_message_processor_parameters(),
2949 'userid' => $userid,
2954 if (empty($params['userid'])) {
2955 $params['userid'] = $USER->id
;
2958 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2959 core_user
::require_active_user($user);
2960 self
::validate_context(context_user
::instance($params['userid']));
2962 $processor = get_message_processor($params['name']);
2964 $processoroutput = new \core_message\output\
processor($processor, $user);
2965 $renderer = $PAGE->get_renderer('core_message');
2967 return $processoroutput->export_for_template($renderer);
2971 * Returns description of method result value
2973 * @return external_description
2976 public static function get_message_processor_returns() {
2977 return new external_function_parameters(
2979 'systemconfigured' => new external_value(PARAM_BOOL
, 'Site configuration status'),
2980 'userconfigured' => new external_value(PARAM_BOOL
, 'The user configuration status'),
2986 * Check that the user has enough permission to retrieve message or notifications preferences.
2988 * @param int $userid the user id requesting the preferences
2989 * @return stdClass full user object
2990 * @throws moodle_exception
2993 protected static function validate_preferences_permissions($userid) {
2996 if (empty($userid)) {
2999 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
3000 core_user
::require_active_user($user);
3003 $systemcontext = context_system
::instance();
3004 self
::validate_context($systemcontext);
3006 // Check access control.
3007 if ($user->id
== $USER->id
) {
3008 // Editing own message profile.
3009 require_capability('moodle/user:editownmessageprofile', $systemcontext);
3011 // Teachers, parents, etc.
3012 $personalcontext = context_user
::instance($user->id
);
3013 require_capability('moodle/user:editmessageprofile', $personalcontext);
3019 * Returns a notification or message preference structure.
3021 * @return external_single_structure the structure
3023 * @todo Remove loggedin and loggedoff from processors structure on MDL-73284.
3025 protected static function get_preferences_structure() {
3026 return new external_single_structure(
3028 'userid' => new external_value(PARAM_INT
, 'User id'),
3029 'disableall' => new external_value(PARAM_INT
, 'Whether all the preferences are disabled'),
3030 'processors' => new external_multiple_structure(
3031 new external_single_structure(
3033 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3034 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3035 'hassettings' => new external_value(PARAM_BOOL
, 'Whether has settings'),
3036 'contextid' => new external_value(PARAM_INT
, 'Context id'),
3037 'userconfigured' => new external_value(PARAM_INT
, 'Whether is configured by the user'),
3040 'Config form values'
3042 'components' => new external_multiple_structure(
3043 new external_single_structure(
3045 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3046 'notifications' => new external_multiple_structure(
3047 new external_single_structure(
3049 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3050 'preferencekey' => new external_value(PARAM_ALPHANUMEXT
, 'Preference key'),
3051 'processors' => new external_multiple_structure(
3052 new external_single_structure(
3054 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3055 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3056 'locked' => new external_value(PARAM_BOOL
, 'Is locked by admin?'),
3057 'lockedmessage' => new external_value(PARAM_TEXT
,
3058 'Text to display if locked', VALUE_OPTIONAL
),
3059 'userconfigured' => new external_value(PARAM_INT
, 'Is configured?'),
3060 'loggedin' => new external_single_structure(
3062 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3063 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3064 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3066 'DEPRECATED ATTRIBUTE -
3067 Kept for backward compatibility, use enabled instead.',
3069 'loggedoff' => new external_single_structure(
3071 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3072 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3073 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3075 'DEPRECATED ATTRIBUTE -
3076 Kept for backward compatibility, use enabled instead.',
3078 'enabled' => new external_value(PARAM_BOOL
, 'Is enabled?'),
3081 'Processors values for this notification'
3085 'List of notificaitons for the component'
3089 'Available components'
3096 * Returns description of method parameters
3098 * @return external_function_parameters
3101 public static function get_user_notification_preferences_parameters() {
3102 return new external_function_parameters(
3104 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3110 * Get the notification preferences for a given user.
3112 * @param int $userid id of the user, 0 for current user
3113 * @return external_description
3114 * @throws moodle_exception
3117 public static function get_user_notification_preferences($userid = 0) {
3120 $params = self
::validate_parameters(
3121 self
::get_user_notification_preferences_parameters(),
3123 'userid' => $userid,
3126 $user = self
::validate_preferences_permissions($params['userid']);
3128 $processors = get_message_processors();
3129 $providers = message_get_providers_for_user($user->id
);
3130 $preferences = \core_message\api
::get_all_message_preferences($processors, $providers, $user);
3131 $notificationlist = new \core_message\output\preferences\notification_list
($processors, $providers, $preferences, $user);
3133 $renderer = $PAGE->get_renderer('core_message');
3136 'warnings' => array(),
3137 'preferences' => $notificationlist->export_for_template($renderer)
3143 * Returns description of method result value
3145 * @return external_description
3148 public static function get_user_notification_preferences_returns() {
3149 return new external_function_parameters(
3151 'preferences' => self
::get_preferences_structure(),
3152 'warnings' => new external_warnings(),
3158 * Returns description of method parameters
3160 * @return external_function_parameters
3163 public static function get_user_message_preferences_parameters() {
3164 return new external_function_parameters(
3166 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3172 * Get the notification preferences for a given user.
3174 * @param int $userid id of the user, 0 for current user
3175 * @return external_description
3176 * @throws moodle_exception
3179 public static function get_user_message_preferences($userid = 0) {
3182 $params = self
::validate_parameters(
3183 self
::get_user_message_preferences_parameters(),
3185 'userid' => $userid,
3189 $user = self
::validate_preferences_permissions($params['userid']);
3191 // Filter out enabled, available system_configured and user_configured processors only.
3192 $readyprocessors = array_filter(get_message_processors(), function($processor) {
3193 return $processor->enabled
&&
3194 $processor->configured
&&
3195 $processor->object->is_user_configured() &&
3196 // Filter out processors that don't have and message preferences to configure.
3197 $processor->object->has_message_preferences();
3200 $providers = array_filter(message_get_providers_for_user($user->id
), function($provider) {
3201 return $provider->component
=== 'moodle';
3203 $preferences = \core_message\api
::get_all_message_preferences($readyprocessors, $providers, $user);
3204 $notificationlistoutput = new \core_message\output\preferences\
message_notification_list($readyprocessors,
3205 $providers, $preferences, $user);
3207 $renderer = $PAGE->get_renderer('core_message');
3209 $entertosend = get_user_preferences('message_entertosend', $CFG->messagingdefaultpressenter
, $user);
3212 'warnings' => array(),
3213 'preferences' => $notificationlistoutput->export_for_template($renderer),
3214 'blocknoncontacts' => \core_message\api
::get_user_privacy_messaging_preference($user->id
),
3215 'entertosend' => $entertosend
3221 * Returns description of method result value
3223 * @return external_description
3226 public static function get_user_message_preferences_returns() {
3227 return new external_function_parameters(
3229 'preferences' => self
::get_preferences_structure(),
3230 'blocknoncontacts' => new external_value(PARAM_INT
, 'Privacy messaging setting to define who can message you'),
3231 'entertosend' => new external_value(PARAM_BOOL
, 'User preference for using enter to send messages'),
3232 'warnings' => new external_warnings(),
3238 * Returns description of method parameters for the favourite_conversations() method.
3240 * @return external_function_parameters
3242 public static function set_favourite_conversations_parameters() {
3243 return new external_function_parameters(
3245 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
3246 'conversations' => new external_multiple_structure(
3247 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
3254 * Favourite a conversation, or list of conversations for a user.
3256 * @param int $userid the id of the user, or 0 for the current user.
3257 * @param array $conversationids the list of conversations ids to favourite.
3259 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3261 public static function set_favourite_conversations(int $userid, array $conversationids) {
3264 // All the business logic checks that really shouldn't be in here.
3265 if (empty($CFG->messaging
)) {
3266 throw new moodle_exception('disabled', 'message');
3269 'userid' => $userid,
3270 'conversations' => $conversationids
3272 $params = self
::validate_parameters(self
::set_favourite_conversations_parameters(), $params);
3273 $systemcontext = context_system
::instance();
3274 self
::validate_context($systemcontext);
3276 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3277 throw new moodle_exception('You do not have permission to perform this action.');
3280 foreach ($params['conversations'] as $conversationid) {
3281 \core_message\api
::set_favourite_conversation($conversationid, $params['userid']);
3288 * Return a description of the returns for the create_user_favourite_conversations() method.
3290 * @return external_description
3292 public static function set_favourite_conversations_returns() {
3293 return new external_warnings();
3297 * Returns description of method parameters for unfavourite_conversations() method.
3299 * @return external_function_parameters
3301 public static function unset_favourite_conversations_parameters() {
3302 return new external_function_parameters(
3304 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
3305 'conversations' => new external_multiple_structure(
3306 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
3313 * Unfavourite a conversation, or list of conversations for a user.
3315 * @param int $userid the id of the user, or 0 for the current user.
3316 * @param array $conversationids the list of conversations ids unset as favourites.
3318 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3320 public static function unset_favourite_conversations(int $userid, array $conversationids) {
3323 // All the business logic checks that really shouldn't be in here.
3324 if (empty($CFG->messaging
)) {
3325 throw new moodle_exception('disabled', 'message');
3328 'userid' => $userid,
3329 'conversations' => $conversationids
3331 $params = self
::validate_parameters(self
::unset_favourite_conversations_parameters(), $params);
3332 $systemcontext = context_system
::instance();
3333 self
::validate_context($systemcontext);
3335 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3336 throw new moodle_exception('You do not have permission to perform this action.');
3339 foreach ($params['conversations'] as $conversationid) {
3340 \core_message\api
::unset_favourite_conversation($conversationid, $params['userid']);
3347 * Unset favourite conversations return description.
3349 * @return external_description
3351 public static function unset_favourite_conversations_returns() {
3352 return new external_warnings();
3356 * Returns description of method parameters for get_member_info() method.
3358 * @return external_function_parameters
3360 public static function get_member_info_parameters() {
3361 return new external_function_parameters(
3363 'referenceuserid' => new external_value(PARAM_INT
, 'id of the user'),
3364 'userids' => new external_multiple_structure(
3365 new external_value(PARAM_INT
, 'id of members to get')
3367 'includecontactrequests' => new external_value(PARAM_BOOL
, 'include contact requests in response', VALUE_DEFAULT
, false),
3368 'includeprivacyinfo' => new external_value(PARAM_BOOL
, 'include privacy info in response', VALUE_DEFAULT
, false)
3374 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid.
3376 * This is the basic structure used when returning members, and includes information about the relationship between each member
3377 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them.
3379 * @param int $referenceuserid the id of the user which check contact and blocked status.
3380 * @param array $userids
3381 * @return array the array of objects containing member info.
3382 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3384 public static function get_member_info(
3385 int $referenceuserid,
3387 bool $includecontactrequests = false,
3388 bool $includeprivacyinfo = false
3392 // All the business logic checks that really shouldn't be in here.
3393 if (empty($CFG->messaging
)) {
3394 throw new moodle_exception('disabled', 'message');
3397 'referenceuserid' => $referenceuserid,
3398 'userids' => $userids,
3399 'includecontactrequests' => $includecontactrequests,
3400 'includeprivacyinfo' => $includeprivacyinfo
3402 $params = self
::validate_parameters(self
::get_member_info_parameters(), $params);
3403 $systemcontext = context_system
::instance();
3404 self
::validate_context($systemcontext);
3406 if (($USER->id
!= $referenceuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3407 throw new moodle_exception('You do not have permission to perform this action.');
3410 return \core_message\helper
::get_member_info(
3411 $params['referenceuserid'],
3413 $params['includecontactrequests'],
3414 $params['includeprivacyinfo']
3419 * Get member info return description.
3421 * @return external_description
3423 public static function get_member_info_returns() {
3424 return new external_multiple_structure(
3425 self
::get_conversation_member_structure()
3430 * Returns description of method parameters for get_conversation_counts() method.
3432 * @return external_function_parameters
3434 public static function get_conversation_counts_parameters() {
3435 return new external_function_parameters(
3437 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3443 * Returns an array of conversation counts for the various types of conversations, including favourites.
3447 * 'favourites' => 0,
3449 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
3450 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
3454 * @param int $userid the id of the user whose counts we are fetching.
3455 * @return array the array of conversation counts, indexed by type.
3456 * @throws moodle_exception if the current user cannot perform this action.
3458 public static function get_conversation_counts(int $userid) {
3461 // All the business logic checks that really shouldn't be in here.
3462 if (empty($CFG->messaging
)) {
3463 throw new moodle_exception('disabled', 'message');
3466 if (empty($userid)) {
3467 $userid = $USER->id
;
3470 $params = ['userid' => $userid];
3471 $params = self
::validate_parameters(self
::get_conversation_counts_parameters(), $params);
3473 $systemcontext = context_system
::instance();
3474 self
::validate_context($systemcontext);
3476 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3477 throw new moodle_exception('You do not have permission to perform this action.');
3480 return \core_message\api
::get_conversation_counts($params['userid']);
3484 * Get conversation counts return description.
3486 * @return external_description
3488 public static function get_conversation_counts_returns() {
3489 return new external_single_structure(
3491 'favourites' => new external_value(PARAM_INT
, 'Total number of favourite conversations'),
3492 'types' => new external_single_structure(
3494 \core_message\api
::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL
=> new external_value(PARAM_INT
,
3495 'Total number of individual conversations'),
3496 \core_message\api
::MESSAGE_CONVERSATION_TYPE_GROUP
=> new external_value(PARAM_INT
,
3497 'Total number of group conversations'),
3498 \core_message\api
::MESSAGE_CONVERSATION_TYPE_SELF
=> new external_value(PARAM_INT
,
3499 'Total number of self conversations'),
3507 * Returns description of method parameters for get_unread_conversation_counts() method.
3509 * @return external_function_parameters
3511 public static function get_unread_conversation_counts_parameters() {
3512 return new external_function_parameters(
3514 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3520 * Returns an array of unread conversation counts for the various types of conversations, including favourites.
3524 * 'favourites' => 0,
3526 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
3527 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
3531 * @param int $userid the id of the user whose counts we are fetching.
3532 * @return array the array of unread conversation counts, indexed by type.
3533 * @throws moodle_exception if the current user cannot perform this action.
3535 public static function get_unread_conversation_counts(int $userid) {
3538 // All the business logic checks that really shouldn't be in here.
3539 if (empty($CFG->messaging
)) {
3540 throw new moodle_exception('disabled', 'message');
3543 if (empty($userid)) {
3544 $userid = $USER->id
;
3547 $params = ['userid' => $userid];
3548 $params = self
::validate_parameters(self
::get_unread_conversation_counts_parameters(), $params);
3550 $systemcontext = context_system
::instance();
3551 self
::validate_context($systemcontext);
3553 if (($USER->id
!= $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3554 throw new moodle_exception('You do not have permission to perform this action.');
3557 return \core_message\api
::get_unread_conversation_counts($params['userid']);
3561 * Get unread conversation counts return description.
3563 * @return external_description
3565 public static function get_unread_conversation_counts_returns() {
3566 return new external_single_structure(
3568 'favourites' => new external_value(PARAM_INT
, 'Total number of unread favourite conversations'),
3569 'types' => new external_single_structure(
3571 \core_message\api
::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL
=> new external_value(PARAM_INT
,
3572 'Total number of unread individual conversations'),
3573 \core_message\api
::MESSAGE_CONVERSATION_TYPE_GROUP
=> new external_value(PARAM_INT
,
3574 'Total number of unread group conversations'),
3575 \core_message\api
::MESSAGE_CONVERSATION_TYPE_SELF
=> new external_value(PARAM_INT
,
3576 'Total number of unread self conversations'),
3584 * Returns description of method parameters
3586 * @return external_function_parameters
3589 public static function delete_message_for_all_users_parameters() {
3590 return new external_function_parameters(
3592 'messageid' => new external_value(PARAM_INT
, 'The message id'),
3593 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for all users')
3598 * Deletes a message for all users
3600 * @param int $messageid the message id
3601 * @param int $userid the user id of who we want to delete the message for all users, is no longer used.
3602 * @return external_description
3603 * @throws moodle_exception
3606 public static function delete_message_for_all_users(int $messageid, int $userid) {
3609 // Check if private messaging between users is allowed.
3610 if (empty($CFG->messaging
)) {
3611 throw new moodle_exception('disabled', 'message');
3616 'messageid' => $messageid,
3619 $params = self
::validate_parameters(self
::delete_message_for_all_users_parameters(), $params);
3621 // Validate context.
3622 $context = context_system
::instance();
3623 self
::validate_context($context);
3625 core_user
::require_active_user($USER);
3627 // Checks if a user can delete a message for all users.
3628 if (core_message\api
::can_delete_message_for_all_users($USER->id
, $params['messageid'])) {
3629 \core_message\api
::delete_message_for_all_users($params['messageid']);
3631 throw new moodle_exception('You do not have permission to delete this message for everyone.');
3637 * Returns description of method result value
3639 * @return external_description
3642 public static function delete_message_for_all_users_returns() {
3643 return new external_warnings();