Automatically generated installer lang files
[moodle.git] / message / externallib.php
blob3fbff4d2a2c8131064003cfa5c61572694d4572b
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * External message API
21 * @package core_message
22 * @category external
23 * @copyright 2011 Jerome Mouneyrac
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') || die();
29 require_once("$CFG->libdir/externallib.php");
30 require_once($CFG->dirroot . "/message/lib.php");
32 /**
33 * Message external functions
35 * @package core_message
36 * @category external
37 * @copyright 2011 Jerome Mouneyrac
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 * @since Moodle 2.2
41 class core_message_external extends external_api {
42 /**
43 * Returns description of method parameters
45 * @return external_function_parameters
46 * @since Moodle 3.6
48 public static function send_messages_to_conversation_parameters() {
49 return new external_function_parameters(
50 array(
51 'conversationid' => new external_value(PARAM_INT, 'id of the conversation'),
52 'messages' => new external_multiple_structure(
53 new external_single_structure(
54 array(
55 'text' => new external_value(PARAM_RAW, 'the text of the message'),
56 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
64 /**
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).
72 * @since Moodle 3.6
74 public static function send_messages_to_conversation(int $conversationid, array $messages = []) {
75 global $CFG, $USER;
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
89 ]);
91 $messages = [];
92 foreach ($params['messages'] as $message) {
93 $createdmessage = \core_message\api::send_message_to_conversation($USER->id, $params['conversationid'], $message['text'],
94 $message['textformat']);
95 $createdmessage->text = message_format_message_text((object) [
96 'smallmessage' => $createdmessage->text,
97 'fullmessageformat' => external_validate_format($message['textformat']),
98 'fullmessagetrust' => $createdmessage->fullmessagetrust
99 ]);
100 $messages[] = $createdmessage;
103 return $messages;
107 * Returns description of method result value.
109 * @return external_description
110 * @since Moodle 3.6
112 public static function send_messages_to_conversation_returns() {
113 return new external_multiple_structure(
114 self::get_conversation_message_structure()
120 * Returns description of method parameters
122 * @return external_function_parameters
123 * @since Moodle 2.2
125 public static function send_instant_messages_parameters() {
126 return new external_function_parameters(
127 array(
128 'messages' => new external_multiple_structure(
129 new external_single_structure(
130 array(
131 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'),
132 'text' => new external_value(PARAM_RAW, 'the text of the message'),
133 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
134 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the message. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL),
143 * Send private messages from the current USER to other users
145 * @param array $messages An array of message to send.
146 * @return array
147 * @since Moodle 2.2
149 public static function send_instant_messages($messages = array()) {
150 global $CFG, $USER, $DB;
152 // Check if messaging is enabled.
153 if (empty($CFG->messaging)) {
154 throw new moodle_exception('disabled', 'message');
157 // Ensure the current user is allowed to run this function
158 $context = context_system::instance();
159 self::validate_context($context);
160 require_capability('moodle/site:sendmessage', $context);
162 // Ensure the current user is allowed to delete message for everyone.
163 $candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $context);
165 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
167 //retrieve all tousers of the messages
168 $receivers = array();
169 foreach($params['messages'] as $message) {
170 $receivers[] = $message['touserid'];
172 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
173 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
175 $resultmessages = array();
176 $messageids = array();
177 foreach ($params['messages'] as $message) {
178 $resultmsg = array(); //the infos about the success of the operation
180 // We are going to do some checking.
181 // Code should match /messages/index.php checks.
182 $success = true;
184 // Check the user exists.
185 if (empty($tousers[$message['touserid']])) {
186 $success = false;
187 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
190 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
191 // Check if the recipient can be messaged by the sender.
192 if ($success && !\core_message\api::can_send_message($tousers[$message['touserid']]->id, $USER->id)) {
193 $success = false;
194 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message['touserid'])));
197 // Now we can send the message (at least try).
198 if ($success) {
199 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
200 $success = message_post_message($USER, $tousers[$message['touserid']],
201 $message['text'], external_validate_format($message['textformat']));
204 // Build the resultmsg.
205 if (isset($message['clientmsgid'])) {
206 $resultmsg['clientmsgid'] = $message['clientmsgid'];
208 if ($success) {
209 $resultmsg['msgid'] = $success;
210 $resultmsg['timecreated'] = time();
211 $resultmsg['candeletemessagesforallusers'] = $candeletemessagesforallusers;
212 $messageids[] = $success;
213 } else {
214 // WARNINGS: for backward compatibility we return this errormessage.
215 // We should have thrown exceptions as these errors prevent results to be returned.
216 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
217 $resultmsg['msgid'] = -1;
218 $resultmsg['errormessage'] = $errormessage;
221 $resultmessages[] = $resultmsg;
224 if (!empty($messageids)) {
225 $messagerecords = $DB->get_records_list(
226 'messages',
227 'id',
228 $messageids,
230 'id, conversationid, smallmessage, fullmessageformat, fullmessagetrust');
231 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) {
232 $id = $resultmessage['msgid'];
233 $resultmessage['conversationid'] = isset($messagerecords[$id]) ? $messagerecords[$id]->conversationid : null;
234 $resultmessage['useridfrom'] = $USER->id;
235 $resultmessage['text'] = message_format_message_text((object) [
236 'smallmessage' => $messagerecords[$id]->smallmessage,
237 'fullmessageformat' => external_validate_format($messagerecords[$id]->fullmessageformat),
238 'fullmessagetrust' => $messagerecords[$id]->fullmessagetrust
240 return $resultmessage;
241 }, $resultmessages);
244 return $resultmessages;
248 * Returns description of method result value
250 * @return external_description
251 * @since Moodle 2.2
253 public static function send_instant_messages_returns() {
254 return new external_multiple_structure(
255 new external_single_structure(
256 array(
257 'msgid' => new external_value(PARAM_INT, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
258 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
259 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL),
260 'text' => new external_value(PARAM_RAW, 'The text of the message', VALUE_OPTIONAL),
261 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message', VALUE_OPTIONAL),
262 'conversationid' => new external_value(PARAM_INT, 'The conversation id for this message', VALUE_OPTIONAL),
263 'useridfrom' => new external_value(PARAM_INT, 'The user id who sent the message', VALUE_OPTIONAL),
264 'candeletemessagesforallusers' => new external_value(PARAM_BOOL,
265 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false),
272 * Create contacts parameters description.
274 * @deprecated since Moodle 3.6
275 * @return external_function_parameters
276 * @since Moodle 2.5
278 public static function create_contacts_parameters() {
279 return new external_function_parameters(
280 array(
281 'userids' => new external_multiple_structure(
282 new external_value(PARAM_INT, 'User ID'),
283 'List of user IDs'
285 'userid' => new external_value(PARAM_INT, 'The id of the user we are creating the contacts for, 0 for the
286 current user', VALUE_DEFAULT, 0)
292 * Create contacts.
294 * @deprecated since Moodle 3.6
295 * @param array $userids array of user IDs.
296 * @param int $userid The id of the user we are creating the contacts for
297 * @return external_description
298 * @since Moodle 2.5
300 public static function create_contacts($userids, $userid = 0) {
301 global $CFG, $USER;
303 // Check if messaging is enabled.
304 if (empty($CFG->messaging)) {
305 throw new moodle_exception('disabled', 'message');
308 if (empty($userid)) {
309 $userid = $USER->id;
312 // Validate context.
313 $context = context_system::instance();
314 self::validate_context($context);
316 $params = array('userids' => $userids, 'userid' => $userid);
317 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
319 $capability = 'moodle/site:manageallmessaging';
320 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
321 throw new required_capability_exception($context, $capability, 'nopermissions', '');
324 $warnings = array();
325 foreach ($params['userids'] as $id) {
326 if (!message_add_contact($id, 0, $params['userid'])) {
327 $warnings[] = array(
328 'item' => 'user',
329 'itemid' => $id,
330 'warningcode' => 'contactnotcreated',
331 'message' => 'The contact could not be created'
335 return $warnings;
339 * Create contacts return description.
341 * @deprecated since Moodle 3.6
342 * @return external_description
343 * @since Moodle 2.5
345 public static function create_contacts_returns() {
346 return new external_warnings();
350 * Marking the method as deprecated.
352 * @return bool
354 public static function create_contacts_is_deprecated() {
355 return true;
359 * Delete contacts parameters description.
361 * @return external_function_parameters
362 * @since Moodle 2.5
364 public static function delete_contacts_parameters() {
365 return new external_function_parameters(
366 array(
367 'userids' => new external_multiple_structure(
368 new external_value(PARAM_INT, 'User ID'),
369 'List of user IDs'
371 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the
372 current user', VALUE_DEFAULT, 0)
378 * Delete contacts.
380 * @param array $userids array of user IDs.
381 * @param int $userid The id of the user we are deleting the contacts for
382 * @return null
383 * @since Moodle 2.5
385 public static function delete_contacts($userids, $userid = 0) {
386 global $CFG, $USER;
388 // Check if messaging is enabled.
389 if (empty($CFG->messaging)) {
390 throw new moodle_exception('disabled', 'message');
393 if (empty($userid)) {
394 $userid = $USER->id;
397 // Validate context.
398 $context = context_system::instance();
399 self::validate_context($context);
401 $params = array('userids' => $userids, 'userid' => $userid);
402 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
404 $capability = 'moodle/site:manageallmessaging';
405 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
406 throw new required_capability_exception($context, $capability, 'nopermissions', '');
409 foreach ($params['userids'] as $id) {
410 \core_message\api::remove_contact($params['userid'], $id);
413 return null;
417 * Delete contacts return description.
419 * @return external_description
420 * @since Moodle 2.5
422 public static function delete_contacts_returns() {
423 return null;
427 * Mute conversations parameters description.
429 * @return external_function_parameters
431 public static function mute_conversations_parameters() {
432 return new external_function_parameters(
434 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
435 'conversationids' => new external_multiple_structure(
436 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED)
443 * Mutes conversations.
445 * @param int $userid The id of the user who is blocking
446 * @param array $conversationids The list of conversations being muted
447 * @return external_description
449 public static function mute_conversations(int $userid, array $conversationids) {
450 global $CFG, $USER;
452 // Check if messaging is enabled.
453 if (empty($CFG->messaging)) {
454 throw new moodle_exception('disabled', 'message');
457 // Validate context.
458 $context = context_system::instance();
459 self::validate_context($context);
461 $params = ['userid' => $userid, 'conversationids' => $conversationids];
462 $params = self::validate_parameters(self::mute_conversations_parameters(), $params);
464 $capability = 'moodle/site:manageallmessaging';
465 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
466 throw new required_capability_exception($context, $capability, 'nopermissions', '');
469 foreach ($params['conversationids'] as $conversationid) {
470 if (!\core_message\api::is_conversation_muted($params['userid'], $conversationid)) {
471 \core_message\api::mute_conversation($params['userid'], $conversationid);
475 return [];
479 * Mute conversations return description.
481 * @return external_description
483 public static function mute_conversations_returns() {
484 return new external_warnings();
488 * Unmute conversations parameters description.
490 * @return external_function_parameters
492 public static function unmute_conversations_parameters() {
493 return new external_function_parameters(
495 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
496 'conversationids' => new external_multiple_structure(
497 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED)
504 * Unmute conversations.
506 * @param int $userid The id of the user who is unblocking
507 * @param array $conversationids The list of conversations being muted
509 public static function unmute_conversations(int $userid, array $conversationids) {
510 global $CFG, $USER;
512 // Check if messaging is enabled.
513 if (empty($CFG->messaging)) {
514 throw new moodle_exception('disabled', 'message');
517 // Validate context.
518 $context = context_system::instance();
519 self::validate_context($context);
521 $params = ['userid' => $userid, 'conversationids' => $conversationids];
522 $params = self::validate_parameters(self::unmute_conversations_parameters(), $params);
524 $capability = 'moodle/site:manageallmessaging';
525 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
526 throw new required_capability_exception($context, $capability, 'nopermissions', '');
529 foreach ($params['conversationids'] as $conversationid) {
530 \core_message\api::unmute_conversation($params['userid'], $conversationid);
533 return [];
537 * Unmute conversations return description.
539 * @return external_description
541 public static function unmute_conversations_returns() {
542 return new external_warnings();
546 * Block user parameters description.
548 * @return external_function_parameters
550 public static function block_user_parameters() {
551 return new external_function_parameters(
553 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
554 'blockeduserid' => new external_value(PARAM_INT, 'The id of the user being blocked'),
560 * Blocks a user.
562 * @param int $userid The id of the user who is blocking
563 * @param int $blockeduserid The id of the user being blocked
564 * @return external_description
566 public static function block_user(int $userid, int $blockeduserid) {
567 global $CFG, $USER;
569 // Check if messaging is enabled.
570 if (empty($CFG->messaging)) {
571 throw new moodle_exception('disabled', 'message');
574 // Validate context.
575 $context = context_system::instance();
576 self::validate_context($context);
578 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
579 $params = self::validate_parameters(self::block_user_parameters(), $params);
581 $capability = 'moodle/site:manageallmessaging';
582 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
583 throw new required_capability_exception($context, $capability, 'nopermissions', '');
586 // If the blocking is going to be useless then don't do it.
587 if (\core_message\api::can_send_message($userid, $blockeduserid, true)) {
588 return [];
591 if (!\core_message\api::is_blocked($params['userid'], $params['blockeduserid'])) {
592 \core_message\api::block_user($params['userid'], $params['blockeduserid']);
595 return [];
599 * Block user return description.
601 * @return external_description
603 public static function block_user_returns() {
604 return new external_warnings();
608 * Unblock user parameters description.
610 * @return external_function_parameters
612 public static function unblock_user_parameters() {
613 return new external_function_parameters(
615 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
616 'unblockeduserid' => new external_value(PARAM_INT, 'The id of the user being unblocked'),
622 * Unblock user.
624 * @param int $userid The id of the user who is unblocking
625 * @param int $unblockeduserid The id of the user being unblocked
627 public static function unblock_user(int $userid, int $unblockeduserid) {
628 global $CFG, $USER;
630 // Check if messaging is enabled.
631 if (empty($CFG->messaging)) {
632 throw new moodle_exception('disabled', 'message');
635 // Validate context.
636 $context = context_system::instance();
637 self::validate_context($context);
639 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
640 $params = self::validate_parameters(self::unblock_user_parameters(), $params);
642 $capability = 'moodle/site:manageallmessaging';
643 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
644 throw new required_capability_exception($context, $capability, 'nopermissions', '');
647 \core_message\api::unblock_user($params['userid'], $params['unblockeduserid']);
649 return [];
653 * Unblock user return description.
655 * @return external_description
657 public static function unblock_user_returns() {
658 return new external_warnings();
662 * Block contacts parameters description.
664 * @deprecated since Moodle 3.6
665 * @return external_function_parameters
666 * @since Moodle 2.5
668 public static function block_contacts_parameters() {
669 return new external_function_parameters(
670 array(
671 'userids' => new external_multiple_structure(
672 new external_value(PARAM_INT, 'User ID'),
673 'List of user IDs'
675 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the
676 current user', VALUE_DEFAULT, 0)
682 * Block contacts.
684 * @deprecated since Moodle 3.6
685 * @param array $userids array of user IDs.
686 * @param int $userid The id of the user we are blocking the contacts for
687 * @return external_description
688 * @since Moodle 2.5
690 public static function block_contacts($userids, $userid = 0) {
691 global $CFG, $USER;
693 // Check if messaging is enabled.
694 if (empty($CFG->messaging)) {
695 throw new moodle_exception('disabled', 'message');
698 if (empty($userid)) {
699 $userid = $USER->id;
702 // Validate context.
703 $context = context_system::instance();
704 self::validate_context($context);
706 $params = array('userids' => $userids, 'userid' => $userid);
707 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
709 $capability = 'moodle/site:manageallmessaging';
710 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
711 throw new required_capability_exception($context, $capability, 'nopermissions', '');
714 $warnings = array();
715 foreach ($params['userids'] as $id) {
716 if (!message_block_contact($id, $params['userid'])) {
717 $warnings[] = array(
718 'item' => 'user',
719 'itemid' => $id,
720 'warningcode' => 'contactnotblocked',
721 'message' => 'The contact could not be blocked'
725 return $warnings;
729 * Block contacts return description.
731 * @deprecated since Moodle 3.6
732 * @return external_description
733 * @since Moodle 2.5
735 public static function block_contacts_returns() {
736 return new external_warnings();
740 * Marking the method as deprecated.
742 * @return bool
744 public static function block_contacts_is_deprecated() {
745 return true;
749 * Unblock contacts parameters description.
751 * @deprecated since Moodle 3.6
752 * @return external_function_parameters
753 * @since Moodle 2.5
755 public static function unblock_contacts_parameters() {
756 return new external_function_parameters(
757 array(
758 'userids' => new external_multiple_structure(
759 new external_value(PARAM_INT, 'User ID'),
760 'List of user IDs'
762 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the
763 current user', VALUE_DEFAULT, 0)
769 * Unblock contacts.
771 * @param array $userids array of user IDs.
772 * @param int $userid The id of the user we are unblocking the contacts for
773 * @return null
774 * @since Moodle 2.5
776 public static function unblock_contacts($userids, $userid = 0) {
777 global $CFG, $USER;
779 // Check if messaging is enabled.
780 if (empty($CFG->messaging)) {
781 throw new moodle_exception('disabled', 'message');
784 if (empty($userid)) {
785 $userid = $USER->id;
788 // Validate context.
789 $context = context_system::instance();
790 self::validate_context($context);
792 $params = array('userids' => $userids, 'userid' => $userid);
793 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
795 $capability = 'moodle/site:manageallmessaging';
796 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
797 throw new required_capability_exception($context, $capability, 'nopermissions', '');
800 foreach ($params['userids'] as $id) {
801 message_unblock_contact($id, $params['userid']);
804 return null;
808 * Unblock contacts return description.
810 * @deprecated since Moodle 3.6
811 * @return external_description
812 * @since Moodle 2.5
814 public static function unblock_contacts_returns() {
815 return null;
819 * Marking the method as deprecated.
821 * @return bool
823 public static function unblock_contacts_is_deprecated() {
824 return true;
828 * Returns contact requests parameters description.
830 * @return external_function_parameters
832 public static function get_contact_requests_parameters() {
833 return new external_function_parameters(
835 'userid' => new external_value(PARAM_INT, 'The id of the user we want the requests for'),
836 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
837 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
843 * Handles returning the contact requests for a user.
845 * This also includes the user data necessary to display information
846 * about the user.
848 * It will not include blocked users.
850 * @param int $userid The id of the user we want to get the contact requests for
851 * @param int $limitfrom
852 * @param int $limitnum
854 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) {
855 global $CFG, $USER;
857 // Check if messaging is enabled.
858 if (empty($CFG->messaging)) {
859 throw new moodle_exception('disabled', 'message');
862 // Validate context.
863 $context = context_system::instance();
864 self::validate_context($context);
866 $params = [
867 'userid' => $userid,
868 'limitfrom' => $limitfrom,
869 'limitnum' => $limitnum
871 $params = self::validate_parameters(self::get_contact_requests_parameters(), $params);
873 $capability = 'moodle/site:manageallmessaging';
874 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
875 throw new required_capability_exception($context, $capability, 'nopermissions', '');
878 return \core_message\api::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']);
882 * Returns the contact requests return description.
884 * @return external_description
886 public static function get_contact_requests_returns() {
887 return new external_multiple_structure(
888 self::get_conversation_member_structure()
893 * Returns the number of contact requests the user has received parameters description.
895 * @return external_function_parameters
897 public static function get_received_contact_requests_count_parameters() {
898 return new external_function_parameters(
899 array(
900 'userid' => new external_value(PARAM_INT, 'The id of the user we want to return the number of ' .
901 'received contact requests for', VALUE_REQUIRED),
907 * Returns the number of contact requests the user has received.
909 * @param int $userid The ID of the user we want to return the number of received contact requests for
910 * @return external_value
912 public static function get_received_contact_requests_count(int $userid) {
913 global $CFG, $USER;
915 // Check if messaging is enabled.
916 if (empty($CFG->messaging)) {
917 throw new moodle_exception('disabled', 'message');
920 // Validate context.
921 $context = context_system::instance();
922 self::validate_context($context);
924 $params = [
925 'userid' => $userid,
927 $params = self::validate_parameters(self::get_received_contact_requests_count_parameters(), $params);
929 $capability = 'moodle/site:manageallmessaging';
930 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
931 throw new required_capability_exception($context, $capability, 'nopermissions', '');
934 return \core_message\api::get_received_contact_requests_count($params['userid']);
938 * Returns the number of contact requests the user has received return description.
940 * @return external_value
942 public static function get_received_contact_requests_count_returns() {
943 return new external_value(PARAM_INT, 'The number of received contact requests');
947 * Returns get conversation members parameters description.
949 * @return external_function_parameters
951 public static function get_conversation_members_parameters() {
952 return new external_function_parameters(
954 'userid' => new external_value(PARAM_INT, 'The id of the user we are performing this action on behalf of'),
955 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation'),
956 'includecontactrequests' => new external_value(PARAM_BOOL, 'Do we want to include contact requests?',
957 VALUE_DEFAULT, false),
958 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Do we want to include privacy info?',
959 VALUE_DEFAULT, false),
960 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
961 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
967 * Returns a list of conversation members.
969 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
970 * @param int $conversationid The id of the conversation
971 * @param bool $includecontactrequests Do we want to include contact requests with this data?
972 * @param bool $includeprivacyinfo Do we want to include privacy info?
973 * @param int $limitfrom
974 * @param int $limitnum
975 * @return array
977 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
978 bool $includeprivacyinfo = false, int $limitfrom = 0, int $limitnum = 0) {
979 global $CFG, $USER;
981 // Check if messaging is enabled.
982 if (empty($CFG->messaging)) {
983 throw new moodle_exception('disabled', 'message');
986 // Validate context.
987 $context = context_system::instance();
988 self::validate_context($context);
990 $params = [
991 'userid' => $userid,
992 'conversationid' => $conversationid,
993 'includecontactrequests' => $includecontactrequests,
994 'includeprivacyinfo' => $includeprivacyinfo,
995 'limitfrom' => $limitfrom,
996 'limitnum' => $limitnum
998 $params = self::validate_parameters(self::get_conversation_members_parameters(), $params);
1000 $capability = 'moodle/site:manageallmessaging';
1001 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
1002 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1005 // The user needs to be a part of the conversation before querying who the members are.
1006 if (!\core_message\api::is_user_in_conversation($params['userid'], $params['conversationid'])) {
1007 throw new moodle_exception('You are not a member of this conversation.');
1010 return \core_message\api::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'],
1011 $params['includeprivacyinfo'], $params['limitfrom'], $params['limitnum']);
1015 * Returns the get conversation members return description.
1017 * @return external_description
1019 public static function get_conversation_members_returns() {
1020 return new external_multiple_structure(
1021 self::get_conversation_member_structure()
1026 * Creates a contact request parameters description.
1028 * @return external_function_parameters
1030 public static function create_contact_request_parameters() {
1031 return new external_function_parameters(
1033 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1034 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1040 * Creates a contact request.
1042 * @param int $userid The id of the user who is creating the contact request
1043 * @param int $requesteduserid The id of the user being requested
1045 public static function create_contact_request(int $userid, int $requesteduserid) {
1046 global $CFG, $USER;
1048 // Check if messaging is enabled.
1049 if (empty($CFG->messaging)) {
1050 throw new moodle_exception('disabled', 'message');
1053 // Validate context.
1054 $context = context_system::instance();
1055 self::validate_context($context);
1057 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1058 $params = self::validate_parameters(self::create_contact_request_parameters(), $params);
1060 $capability = 'moodle/site:manageallmessaging';
1061 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
1062 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1065 $result = [
1066 'warnings' => []
1069 if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) {
1070 $result['warnings'][] = [
1071 'item' => 'user',
1072 'itemid' => $params['requesteduserid'],
1073 'warningcode' => 'cannotcreatecontactrequest',
1074 'message' => 'You are unable to create a contact request for this user'
1076 } else {
1077 if ($requests = \core_message\api::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) {
1078 // There should only ever be one but just in case there are multiple then we can return the first.
1079 $result['request'] = array_shift($requests);
1080 } else {
1081 $result['request'] = \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']);
1085 return $result;
1089 * Creates a contact request return description.
1091 * @return external_description
1093 public static function create_contact_request_returns() {
1094 return new external_single_structure(
1095 array(
1096 'request' => new external_single_structure(
1097 array(
1098 'id' => new external_value(PARAM_INT, 'Message id'),
1099 'userid' => new external_value(PARAM_INT, 'User from id'),
1100 'requesteduserid' => new external_value(PARAM_INT, 'User to id'),
1101 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1103 'request record',
1104 VALUE_OPTIONAL
1106 'warnings' => new external_warnings()
1112 * Confirm a contact request parameters description.
1114 * @return external_function_parameters
1116 public static function confirm_contact_request_parameters() {
1117 return new external_function_parameters(
1119 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1120 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1126 * Confirm a contact request.
1128 * @param int $userid The id of the user who is creating the contact request
1129 * @param int $requesteduserid The id of the user being requested
1131 public static function confirm_contact_request(int $userid, int $requesteduserid) {
1132 global $CFG, $USER;
1134 // Check if messaging is enabled.
1135 if (empty($CFG->messaging)) {
1136 throw new moodle_exception('disabled', 'message');
1139 // Validate context.
1140 $context = context_system::instance();
1141 self::validate_context($context);
1143 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1144 $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params);
1146 $capability = 'moodle/site:manageallmessaging';
1147 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) {
1148 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1151 \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']);
1153 return [];
1157 * Confirm a contact request return description.
1159 * @return external_description
1161 public static function confirm_contact_request_returns() {
1162 return new external_warnings();
1166 * Declines a contact request parameters description.
1168 * @return external_function_parameters
1170 public static function decline_contact_request_parameters() {
1171 return new external_function_parameters(
1173 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1174 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1180 * Declines a contact request.
1182 * @param int $userid The id of the user who is creating the contact request
1183 * @param int $requesteduserid The id of the user being requested
1185 public static function decline_contact_request(int $userid, int $requesteduserid) {
1186 global $CFG, $USER;
1188 // Check if messaging is enabled.
1189 if (empty($CFG->messaging)) {
1190 throw new moodle_exception('disabled', 'message');
1193 // Validate context.
1194 $context = context_system::instance();
1195 self::validate_context($context);
1197 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1198 $params = self::validate_parameters(self::decline_contact_request_parameters(), $params);
1200 $capability = 'moodle/site:manageallmessaging';
1201 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) {
1202 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1205 \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']);
1207 return [];
1211 * Declines a contact request return description.
1213 * @return external_description
1215 public static function decline_contact_request_returns() {
1216 return new external_warnings();
1220 * Return the structure of a message area contact.
1222 * @return external_single_structure
1223 * @since Moodle 3.2
1225 private static function get_messagearea_contact_structure() {
1226 return new external_single_structure(
1227 array(
1228 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
1229 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1230 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1231 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1232 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
1233 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
1234 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
1235 'lastmessagedate' => new external_value(PARAM_INT, 'Timestamp for last message', VALUE_DEFAULT, null),
1236 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
1237 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1238 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1239 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
1240 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
1241 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1242 VALUE_DEFAULT, null),
1243 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation', VALUE_DEFAULT, null),
1249 * Return the structure of a conversation.
1251 * @return external_single_structure
1252 * @since Moodle 3.6
1254 private static function get_conversation_structure() {
1255 return new external_single_structure(
1256 array(
1257 'id' => new external_value(PARAM_INT, 'The conversation id'),
1258 'name' => new external_value(PARAM_TEXT, 'The conversation name, if set', VALUE_DEFAULT, null),
1259 'subname' => new external_value(PARAM_TEXT, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null),
1260 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null),
1261 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group,3=self)'),
1262 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'),
1263 'ismuted' => new external_value(PARAM_BOOL, 'If the user muted this conversation'),
1264 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked this conversation as a favourite'),
1265 'isread' => new external_value(PARAM_BOOL, 'If the user has read all messages in the conversation'),
1266 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1267 VALUE_DEFAULT, null),
1268 'members' => new external_multiple_structure(
1269 self::get_conversation_member_structure()
1271 'messages' => new external_multiple_structure(
1272 self::get_conversation_message_structure()
1274 'candeletemessagesforallusers' => new external_value(PARAM_BOOL,
1275 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false),
1281 * Return the structure of a conversation member.
1283 * @return external_single_structure
1284 * @since Moodle 3.6
1286 private static function get_conversation_member_structure() {
1287 $result = [
1288 'id' => new external_value(PARAM_INT, 'The user id'),
1289 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1290 'profileurl' => new external_value(PARAM_URL, 'The link to the user\'s profile page'),
1291 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1292 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1293 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1294 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1295 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
1296 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?'),
1297 'isdeleted' => new external_value(PARAM_BOOL, 'Is the user deleted?'),
1298 'canmessageevenifblocked' => new external_value(PARAM_BOOL,
1299 'If the user can still message even if they get blocked'),
1300 'canmessage' => new external_value(PARAM_BOOL, 'If the user can be messaged'),
1301 'requirescontact' => new external_value(PARAM_BOOL, 'If the user requires to be contacts'),
1304 $result['contactrequests'] = new external_multiple_structure(
1305 new external_single_structure(
1307 'id' => new external_value(PARAM_INT, 'The id of the contact request'),
1308 'userid' => new external_value(PARAM_INT, 'The id of the user who created the contact request'),
1309 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user confirming the request'),
1310 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the contact request'),
1312 ), 'The contact requests', VALUE_OPTIONAL
1315 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1316 array(
1317 'id' => new external_value(PARAM_INT, 'Conversations id'),
1318 'type' => new external_value(PARAM_INT, 'Conversation type: private or public'),
1319 'name' => new external_value(PARAM_TEXT, 'Multilang compatible conversation name'. VALUE_OPTIONAL),
1320 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the conversation'),
1321 ), 'information about conversation', VALUE_OPTIONAL),
1322 'Conversations between users', VALUE_OPTIONAL
1325 return new external_single_structure(
1326 $result
1331 * Return the structure of a message area message.
1333 * @return external_single_structure
1334 * @since Moodle 3.6
1336 private static function get_conversation_message_structure() {
1337 return new external_single_structure(
1338 array(
1339 'id' => new external_value(PARAM_INT, 'The id of the message'),
1340 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1341 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1342 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1348 * Return the structure of a message area message.
1350 * @return external_single_structure
1351 * @since Moodle 3.2
1353 private static function get_messagearea_message_structure() {
1354 return new external_single_structure(
1355 array(
1356 'id' => new external_value(PARAM_INT, 'The id of the message'),
1357 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1358 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
1359 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1360 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
1361 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
1362 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
1363 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
1364 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1365 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
1371 * Get messagearea search users in course parameters.
1373 * @deprecated since 3.6
1375 * @return external_function_parameters
1376 * @since 3.2
1378 public static function data_for_messagearea_search_users_in_course_parameters() {
1379 return new external_function_parameters(
1380 array(
1381 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1382 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
1383 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1384 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1385 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1391 * Get messagearea search users in course results.
1393 * @deprecated since 3.6
1395 * @param int $userid The id of the user who is performing the search
1396 * @param int $courseid The id of the course
1397 * @param string $search The string being searched
1398 * @param int $limitfrom
1399 * @param int $limitnum
1400 * @return stdClass
1401 * @throws moodle_exception
1402 * @since 3.2
1404 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
1405 $limitnum = 0) {
1406 global $CFG, $PAGE, $USER;
1408 // Check if messaging is enabled.
1409 if (empty($CFG->messaging)) {
1410 throw new moodle_exception('disabled', 'message');
1413 $systemcontext = context_system::instance();
1415 $params = array(
1416 'userid' => $userid,
1417 'courseid' => $courseid,
1418 'search' => $search,
1419 'limitfrom' => $limitfrom,
1420 'limitnum' => $limitnum
1422 $params = self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
1423 self::validate_context($systemcontext);
1425 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1426 throw new moodle_exception('You do not have permission to perform this action.');
1429 $users = \core_message\api::search_users_in_course(
1430 $params['userid'],
1431 $params['courseid'],
1432 $params['search'],
1433 $params['limitfrom'],
1434 $params['limitnum']
1436 $results = new \core_message\output\messagearea\user_search_results($users);
1438 $renderer = $PAGE->get_renderer('core_message');
1439 return $results->export_for_template($renderer);
1443 * Get messagearea search users in course returns.
1445 * @deprecated since 3.6
1447 * @return external_single_structure
1448 * @since 3.2
1450 public static function data_for_messagearea_search_users_in_course_returns() {
1451 return new external_single_structure(
1452 array(
1453 'contacts' => new external_multiple_structure(
1454 self::get_messagearea_contact_structure()
1461 * Marking the method as deprecated.
1463 * @return bool
1465 public static function data_for_messagearea_search_users_in_course_is_deprecated() {
1466 return true;
1470 * Get messagearea search users parameters.
1472 * @deprecated since 3.6
1474 * @return external_function_parameters
1475 * @since 3.2
1477 public static function data_for_messagearea_search_users_parameters() {
1478 return new external_function_parameters(
1479 array(
1480 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1481 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1482 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1488 * Get messagearea search users results.
1490 * @deprecated since 3.6
1492 * @param int $userid The id of the user who is performing the search
1493 * @param string $search The string being searched
1494 * @param int $limitnum
1495 * @return stdClass
1496 * @throws moodle_exception
1497 * @since 3.2
1499 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
1500 global $CFG, $PAGE, $USER;
1502 // Check if messaging is enabled.
1503 if (empty($CFG->messaging)) {
1504 throw new moodle_exception('disabled', 'message');
1507 $systemcontext = context_system::instance();
1509 $params = array(
1510 'userid' => $userid,
1511 'search' => $search,
1512 'limitnum' => $limitnum
1514 $params = self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
1515 self::validate_context($systemcontext);
1517 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1518 throw new moodle_exception('You do not have permission to perform this action.');
1521 list($contacts, $courses, $noncontacts) = \core_message\api::search_users(
1522 $params['userid'],
1523 $params['search'],
1524 $params['limitnum']
1527 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
1529 $renderer = $PAGE->get_renderer('core_message');
1530 return $search->export_for_template($renderer);
1534 * Get messagearea search users returns.
1536 * @deprecated since 3.6
1538 * @return external_single_structure
1539 * @since 3.2
1541 public static function data_for_messagearea_search_users_returns() {
1542 return new external_single_structure(
1543 array(
1544 'contacts' => new external_multiple_structure(
1545 self::get_messagearea_contact_structure()
1547 'courses' => new external_multiple_structure(
1548 new external_single_structure(
1549 array(
1550 'id' => new external_value(PARAM_INT, 'The course id'),
1551 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
1552 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
1556 'noncontacts' => new external_multiple_structure(
1557 self::get_messagearea_contact_structure()
1564 * Marking the method as deprecated.
1566 * @return bool
1568 public static function data_for_messagearea_search_users_is_deprecated() {
1569 return true;
1573 * Get messagearea message search users parameters.
1575 * @return external_function_parameters
1576 * @since 3.6
1578 public static function message_search_users_parameters() {
1579 return new external_function_parameters(
1580 array(
1581 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1582 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1583 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1584 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1590 * Get search users results.
1592 * @param int $userid The id of the user who is performing the search
1593 * @param string $search The string being searched
1594 * @param int $limitfrom
1595 * @param int $limitnum
1596 * @return array
1597 * @throws moodle_exception
1598 * @since 3.6
1600 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
1601 global $USER;
1603 $systemcontext = context_system::instance();
1605 $params = array(
1606 'userid' => $userid,
1607 'search' => $search,
1608 'limitfrom' => $limitfrom,
1609 'limitnum' => $limitnum
1611 $params = self::validate_parameters(self::message_search_users_parameters(), $params);
1612 self::validate_context($systemcontext);
1614 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1615 throw new moodle_exception('You do not have permission to perform this action.');
1618 list($contacts, $noncontacts) = \core_message\api::message_search_users(
1619 $params['userid'],
1620 $params['search'],
1621 $params['limitfrom'],
1622 $params['limitnum']);
1624 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1628 * Get messagearea message search users returns.
1630 * @return external_single_structure
1631 * @since 3.2
1633 public static function message_search_users_returns() {
1634 return new external_single_structure(
1635 array(
1636 'contacts' => new external_multiple_structure(
1637 self::get_conversation_member_structure()
1639 'noncontacts' => new external_multiple_structure(
1640 self::get_conversation_member_structure()
1647 * Get messagearea search messages parameters.
1649 * @return external_function_parameters
1650 * @since 3.2
1652 public static function data_for_messagearea_search_messages_parameters() {
1653 return new external_function_parameters(
1654 array(
1655 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1656 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1657 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1658 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1664 * Get messagearea search messages results.
1666 * @param int $userid The id of the user who is performing the search
1667 * @param string $search The string being searched
1668 * @param int $limitfrom
1669 * @param int $limitnum
1670 * @return stdClass
1671 * @throws moodle_exception
1672 * @since 3.2
1674 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1675 global $CFG, $USER;
1677 // Check if messaging is enabled.
1678 if (empty($CFG->messaging)) {
1679 throw new moodle_exception('disabled', 'message');
1682 $systemcontext = context_system::instance();
1684 $params = array(
1685 'userid' => $userid,
1686 'search' => $search,
1687 'limitfrom' => $limitfrom,
1688 'limitnum' => $limitnum
1691 $params = self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
1692 self::validate_context($systemcontext);
1694 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1695 throw new moodle_exception('You do not have permission to perform this action.');
1698 $messages = \core_message\api::search_messages(
1699 $params['userid'],
1700 $params['search'],
1701 $params['limitfrom'],
1702 $params['limitnum']
1705 $data = new \stdClass();
1706 $data->contacts = [];
1707 foreach ($messages as $message) {
1708 $contact = new \stdClass();
1709 $contact->userid = $message->userid;
1710 $contact->fullname = $message->fullname;
1711 $contact->profileimageurl = $message->profileimageurl;
1712 $contact->profileimageurlsmall = $message->profileimageurlsmall;
1713 $contact->messageid = $message->messageid;
1714 $contact->ismessaging = $message->ismessaging;
1715 $contact->sentfromcurrentuser = false;
1716 if ($message->lastmessage) {
1717 if ($message->userid !== $message->useridfrom) {
1718 $contact->sentfromcurrentuser = true;
1720 $contact->lastmessage = shorten_text($message->lastmessage, 60);
1721 } else {
1722 $contact->lastmessage = null;
1724 $contact->lastmessagedate = $message->lastmessagedate;
1725 $contact->showonlinestatus = is_null($message->isonline) ? false : true;
1726 $contact->isonline = $message->isonline;
1727 $contact->isblocked = $message->isblocked;
1728 $contact->isread = $message->isread;
1729 $contact->unreadcount = $message->unreadcount;
1730 $contact->conversationid = $message->conversationid;
1732 $data->contacts[] = $contact;
1735 return $data;
1739 * Get messagearea search messages returns.
1741 * @return external_single_structure
1742 * @since 3.2
1744 public static function data_for_messagearea_search_messages_returns() {
1745 return new external_single_structure(
1746 array(
1747 'contacts' => new external_multiple_structure(
1748 self::get_messagearea_contact_structure()
1755 * Get conversations parameters.
1757 * @return external_function_parameters
1758 * @since 3.6
1760 public static function get_conversations_parameters() {
1761 return new external_function_parameters(
1762 array(
1763 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1764 'limitfrom' => new external_value(PARAM_INT, 'The offset to start at', VALUE_DEFAULT, 0),
1765 'limitnum' => new external_value(PARAM_INT, 'Limit number of conversations to this', VALUE_DEFAULT, 0),
1766 'type' => new external_value(PARAM_INT, 'Filter by type', VALUE_DEFAULT, null),
1767 'favourites' => new external_value(PARAM_BOOL, 'Whether to restrict the results to contain NO favourite
1768 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1769 VALUE_DEFAULT, null),
1770 'mergeself' => new external_value(PARAM_BOOL, 'Whether to include self-conversations (true) or ONLY private
1771 conversations (false) when private conversations are requested.',
1772 VALUE_DEFAULT, false),
1778 * Get the list of conversations for the user.
1780 * @param int $userid The id of the user who is performing the search
1781 * @param int $limitfrom
1782 * @param int $limitnum
1783 * @param int|null $type
1784 * @param bool|null $favourites
1785 * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false)
1786 * when private conversations are requested.
1787 * @return stdClass
1788 * @throws \moodle_exception if the messaging feature is disabled on the site.
1789 * @since 3.2
1791 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null,
1792 bool $mergeself = false) {
1793 global $CFG, $USER;
1795 // All the standard BL checks.
1796 if (empty($CFG->messaging)) {
1797 throw new moodle_exception('disabled', 'message');
1800 $params = array(
1801 'userid' => $userid,
1802 'limitfrom' => $limitfrom,
1803 'limitnum' => $limitnum,
1804 'type' => $type,
1805 'favourites' => $favourites,
1806 'mergeself' => $mergeself
1808 $params = self::validate_parameters(self::get_conversations_parameters(), $params);
1810 $systemcontext = context_system::instance();
1811 self::validate_context($systemcontext);
1813 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1814 throw new moodle_exception('You do not have permission to perform this action.');
1817 $conversations = \core_message\api::get_conversations(
1818 $params['userid'],
1819 $params['limitfrom'],
1820 $params['limitnum'],
1821 $params['type'],
1822 $params['favourites'],
1823 $params['mergeself']
1826 return (object) ['conversations' => $conversations];
1830 * Get conversations returns.
1832 * @return external_single_structure
1833 * @since 3.6
1835 public static function get_conversations_returns() {
1836 return new external_single_structure(
1838 'conversations' => new external_multiple_structure(
1839 self::get_conversation_structure(true)
1846 * Get conversation parameters.
1848 * @return external_function_parameters
1850 public static function get_conversation_parameters() {
1851 return new external_function_parameters(
1852 array(
1853 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1854 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation to fetch'),
1855 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1856 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1857 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1858 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1859 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1860 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1861 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1867 * Get a single conversation.
1869 * @param int $userid The user id to get the conversation for
1870 * @param int $conversationid The id of the conversation to fetch
1871 * @param bool $includecontactrequests Should contact requests be included between members
1872 * @param bool $includeprivacyinfo Should privacy info be included between members
1873 * @param int $memberlimit Limit number of members to load
1874 * @param int $memberoffset Offset members by this amount
1875 * @param int $messagelimit Limit number of messages to load
1876 * @param int $messageoffset Offset the messages
1877 * @param bool $newestmessagesfirst Order messages by newest first
1878 * @return stdClass
1879 * @throws \moodle_exception if the messaging feature is disabled on the site.
1881 public static function get_conversation(
1882 int $userid,
1883 int $conversationid,
1884 bool $includecontactrequests = false,
1885 bool $includeprivacyinfo = false,
1886 int $memberlimit = 0,
1887 int $memberoffset = 0,
1888 int $messagelimit = 0,
1889 int $messageoffset = 0,
1890 bool $newestmessagesfirst = true
1892 global $CFG, $DB, $USER;
1894 // All the standard BL checks.
1895 if (empty($CFG->messaging)) {
1896 throw new moodle_exception('disabled', 'message');
1899 $params = [
1900 'userid' => $userid,
1901 'conversationid' => $conversationid,
1902 'includecontactrequests' => $includecontactrequests,
1903 'includeprivacyinfo' => $includeprivacyinfo,
1904 'memberlimit' => $memberlimit,
1905 'memberoffset' => $memberoffset,
1906 'messagelimit' => $messagelimit,
1907 'messageoffset' => $messageoffset,
1908 'newestmessagesfirst' => $newestmessagesfirst
1910 self::validate_parameters(self::get_conversation_parameters(), $params);
1912 $systemcontext = context_system::instance();
1913 self::validate_context($systemcontext);
1915 $conversation = \core_message\api::get_conversation(
1916 $params['userid'],
1917 $params['conversationid'],
1918 $params['includecontactrequests'],
1919 $params['includeprivacyinfo'],
1920 $params['memberlimit'],
1921 $params['memberoffset'],
1922 $params['messagelimit'],
1923 $params['messageoffset'],
1924 $params['newestmessagesfirst']
1927 if ($conversation) {
1928 return $conversation;
1929 } else {
1930 // We have to throw an exception here because the external functions annoyingly
1931 // don't accept null to be returned for a single structure.
1932 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
1937 * Get conversation returns.
1939 * @return external_single_structure
1941 public static function get_conversation_returns() {
1942 return self::get_conversation_structure();
1946 * Get conversation parameters.
1948 * @return external_function_parameters
1950 public static function get_conversation_between_users_parameters() {
1951 return new external_function_parameters(
1952 array(
1953 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1954 'otheruserid' => new external_value(PARAM_INT, 'The other user id'),
1955 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1956 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1957 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1958 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1959 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1960 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1961 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1967 * Get a single conversation between users.
1969 * @param int $userid The user id to get the conversation for
1970 * @param int $otheruserid The other user id
1971 * @param bool $includecontactrequests Should contact requests be included between members
1972 * @param bool $includeprivacyinfo Should privacy info be included between members
1973 * @param int $memberlimit Limit number of members to load
1974 * @param int $memberoffset Offset members by this amount
1975 * @param int $messagelimit Limit number of messages to load
1976 * @param int $messageoffset Offset the messages
1977 * @param bool $newestmessagesfirst Order messages by newest first
1978 * @return stdClass
1979 * @throws \moodle_exception if the messaging feature is disabled on the site.
1981 public static function get_conversation_between_users(
1982 int $userid,
1983 int $otheruserid,
1984 bool $includecontactrequests = false,
1985 bool $includeprivacyinfo = false,
1986 int $memberlimit = 0,
1987 int $memberoffset = 0,
1988 int $messagelimit = 0,
1989 int $messageoffset = 0,
1990 bool $newestmessagesfirst = true
1992 global $CFG, $DB, $USER;
1994 // All the standard BL checks.
1995 if (empty($CFG->messaging)) {
1996 throw new moodle_exception('disabled', 'message');
1999 $params = [
2000 'userid' => $userid,
2001 'otheruserid' => $otheruserid,
2002 'includecontactrequests' => $includecontactrequests,
2003 'includeprivacyinfo' => $includeprivacyinfo,
2004 'memberlimit' => $memberlimit,
2005 'memberoffset' => $memberoffset,
2006 'messagelimit' => $messagelimit,
2007 'messageoffset' => $messageoffset,
2008 'newestmessagesfirst' => $newestmessagesfirst
2010 self::validate_parameters(self::get_conversation_between_users_parameters(), $params);
2012 $systemcontext = context_system::instance();
2013 self::validate_context($systemcontext);
2015 $conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']]);
2016 $conversation = null;
2018 if ($conversationid) {
2019 $conversation = \core_message\api::get_conversation(
2020 $params['userid'],
2021 $conversationid,
2022 $params['includecontactrequests'],
2023 $params['includeprivacyinfo'],
2024 $params['memberlimit'],
2025 $params['memberoffset'],
2026 $params['messagelimit'],
2027 $params['messageoffset'],
2028 $params['newestmessagesfirst']
2032 if ($conversation) {
2033 return $conversation;
2034 } else {
2035 // We have to throw an exception here because the external functions annoyingly
2036 // don't accept null to be returned for a single structure.
2037 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
2042 * Get conversation returns.
2044 * @return external_single_structure
2046 public static function get_conversation_between_users_returns() {
2047 return self::get_conversation_structure(true);
2051 * Get self-conversation parameters.
2053 * @return external_function_parameters
2055 public static function get_self_conversation_parameters() {
2056 return new external_function_parameters(
2057 array(
2058 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing self-conversations for'),
2059 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
2060 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
2061 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
2067 * Get a single self-conversation.
2069 * @param int $userid The user id to get the self-conversation for
2070 * @param int $messagelimit Limit number of messages to load
2071 * @param int $messageoffset Offset the messages
2072 * @param bool $newestmessagesfirst Order messages by newest first
2073 * @return stdClass
2074 * @throws \moodle_exception if the messaging feature is disabled on the site.
2075 * @since Moodle 3.7
2077 public static function get_self_conversation(
2078 int $userid,
2079 int $messagelimit = 0,
2080 int $messageoffset = 0,
2081 bool $newestmessagesfirst = true
2083 global $CFG;
2085 // All the standard BL checks.
2086 if (empty($CFG->messaging)) {
2087 throw new moodle_exception('disabled', 'message');
2090 $params = [
2091 'userid' => $userid,
2092 'messagelimit' => $messagelimit,
2093 'messageoffset' => $messageoffset,
2094 'newestmessagesfirst' => $newestmessagesfirst
2096 self::validate_parameters(self::get_self_conversation_parameters(), $params);
2098 $systemcontext = context_system::instance();
2099 self::validate_context($systemcontext);
2101 $conversation = \core_message\api::get_self_conversation($params['userid']);
2103 if ($conversation) {
2104 $conversation = \core_message\api::get_conversation(
2105 $params['userid'],
2106 $conversation->id,
2107 false,
2108 false,
2111 $params['messagelimit'],
2112 $params['messageoffset'],
2113 $params['newestmessagesfirst']
2117 if ($conversation) {
2118 return $conversation;
2119 } else {
2120 // We have to throw an exception here because the external functions annoyingly
2121 // don't accept null to be returned for a single structure.
2122 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
2127 * Get conversation returns.
2129 * @return external_single_structure
2131 public static function get_self_conversation_returns() {
2132 return self::get_conversation_structure();
2136 * The messagearea conversations parameters.
2138 * @deprecated since 3.6
2139 * @return external_function_parameters
2140 * @since 3.2
2142 public static function data_for_messagearea_conversations_parameters() {
2143 return new external_function_parameters(
2144 array(
2145 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
2146 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2147 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
2153 * Get messagearea conversations.
2155 * NOTE FOR FINAL DEPRECATION:
2156 * When removing this method, please also consider removal of get_conversations_legacy_formatter()
2157 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data
2158 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be
2159 * removed.
2161 * @deprecated since 3.6
2162 * @param int $userid The id of the user who we are viewing conversations for
2163 * @param int $limitfrom
2164 * @param int $limitnum
2165 * @return stdClass
2166 * @throws moodle_exception
2167 * @since 3.2
2169 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
2170 global $CFG, $PAGE, $USER;
2172 // Check if messaging is enabled.
2173 if (empty($CFG->messaging)) {
2174 throw new moodle_exception('disabled', 'message');
2177 $systemcontext = context_system::instance();
2179 $params = array(
2180 'userid' => $userid,
2181 'limitfrom' => $limitfrom,
2182 'limitnum' => $limitnum
2184 $params = self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
2185 self::validate_context($systemcontext);
2187 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2188 throw new moodle_exception('You do not have permission to perform this action.');
2191 $conversations = \core_message\api::get_conversations($params['userid'], $params['limitfrom'], $params['limitnum']);
2193 // Format the conversations in the legacy style, as the get_conversations method has since been changed.
2194 $conversations = \core_message\helper::get_conversations_legacy_formatter($conversations);
2196 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
2198 $renderer = $PAGE->get_renderer('core_message');
2199 return $conversations->export_for_template($renderer);
2203 * The messagearea conversations return structure.
2205 * @deprecated since 3.6
2206 * @return external_single_structure
2207 * @since 3.2
2209 public static function data_for_messagearea_conversations_returns() {
2210 return new external_single_structure(
2211 array(
2212 'contacts' => new external_multiple_structure(
2213 self::get_messagearea_contact_structure()
2220 * Marking the method as deprecated.
2222 * @return bool
2224 public static function data_for_messagearea_conversations_is_deprecated() {
2225 return true;
2229 * The messagearea contacts return parameters.
2231 * @deprecated since 3.6
2232 * @return external_function_parameters
2233 * @since 3.2
2235 public static function data_for_messagearea_contacts_parameters() {
2236 return self::data_for_messagearea_conversations_parameters();
2240 * Get messagearea contacts parameters.
2242 * @deprecated since 3.6
2243 * @param int $userid The id of the user who we are viewing conversations for
2244 * @param int $limitfrom
2245 * @param int $limitnum
2246 * @return stdClass
2247 * @throws moodle_exception
2248 * @since 3.2
2250 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
2251 global $CFG, $PAGE, $USER;
2253 // Check if messaging is enabled.
2254 if (empty($CFG->messaging)) {
2255 throw new moodle_exception('disabled', 'message');
2258 $systemcontext = context_system::instance();
2260 $params = array(
2261 'userid' => $userid,
2262 'limitfrom' => $limitfrom,
2263 'limitnum' => $limitnum
2265 $params = self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
2266 self::validate_context($systemcontext);
2268 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2269 throw new moodle_exception('You do not have permission to perform this action.');
2272 $contacts = \core_message\api::get_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
2273 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
2275 $renderer = $PAGE->get_renderer('core_message');
2276 return $contacts->export_for_template($renderer);
2280 * The messagearea contacts return structure.
2282 * @deprecated since 3.6
2283 * @return external_single_structure
2284 * @since 3.2
2286 public static function data_for_messagearea_contacts_returns() {
2287 return self::data_for_messagearea_conversations_returns();
2291 * Marking the method as deprecated.
2293 * @return bool
2295 public static function data_for_messagearea_contacts_is_deprecated() {
2296 return true;
2300 * The messagearea messages parameters.
2302 * @deprecated since 3.6
2303 * @return external_function_parameters
2304 * @since 3.2
2306 public static function data_for_messagearea_messages_parameters() {
2307 return new external_function_parameters(
2308 array(
2309 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2310 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2311 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2312 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2313 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
2314 'timefrom' => new external_value(PARAM_INT,
2315 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
2321 * Get messagearea messages.
2323 * @deprecated since 3.6
2324 * @param int $currentuserid The current user's id
2325 * @param int $otheruserid The other user's id
2326 * @param int $limitfrom
2327 * @param int $limitnum
2328 * @param boolean $newest
2329 * @return stdClass
2330 * @throws moodle_exception
2331 * @since 3.2
2333 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
2334 $newest = false, $timefrom = 0) {
2335 global $CFG, $PAGE, $USER;
2337 // Check if messaging is enabled.
2338 if (empty($CFG->messaging)) {
2339 throw new moodle_exception('disabled', 'message');
2342 $systemcontext = context_system::instance();
2344 $params = array(
2345 'currentuserid' => $currentuserid,
2346 'otheruserid' => $otheruserid,
2347 'limitfrom' => $limitfrom,
2348 'limitnum' => $limitnum,
2349 'newest' => $newest,
2350 'timefrom' => $timefrom,
2352 $params = self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
2353 self::validate_context($systemcontext);
2355 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2356 throw new moodle_exception('You do not have permission to perform this action.');
2359 if ($params['newest']) {
2360 $sort = 'timecreated DESC';
2361 } else {
2362 $sort = 'timecreated ASC';
2365 // We need to enforce a one second delay on messages to avoid race conditions of current
2366 // messages still being sent.
2368 // There is a chance that we could request messages before the current time's
2369 // second has elapsed and while other messages are being sent in that same second. In which
2370 // case those messages will be lost.
2372 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
2373 if (!empty($params['timefrom'])) {
2374 $timeto = time() - 1;
2375 } else {
2376 $timeto = 0;
2379 // No requesting messages from the current time, as stated above.
2380 if ($params['timefrom'] == time()) {
2381 $messages = [];
2382 } else {
2383 $messages = \core_message\api::get_messages($params['currentuserid'], $params['otheruserid'], $params['limitfrom'],
2384 $params['limitnum'], $sort, $params['timefrom'], $timeto);
2387 $messages = new \core_message\output\messagearea\messages($params['currentuserid'], $params['otheruserid'], $messages);
2389 $renderer = $PAGE->get_renderer('core_message');
2390 return $messages->export_for_template($renderer);
2394 * The messagearea messages return structure.
2396 * @deprecated since 3.6
2397 * @return external_single_structure
2398 * @since 3.2
2400 public static function data_for_messagearea_messages_returns() {
2401 return new external_single_structure(
2402 array(
2403 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
2404 the messages on behalf of?'),
2405 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2406 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2407 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
2408 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
2409 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
2410 'messages' => new external_multiple_structure(
2411 self::get_messagearea_message_structure()
2413 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
2419 * Marking the method as deprecated.
2421 * @return bool
2423 public static function data_for_messagearea_messages_is_deprecated() {
2424 return true;
2428 * The conversation messages parameters.
2430 * @return external_function_parameters
2431 * @since 3.6
2433 public static function get_conversation_messages_parameters() {
2434 return new external_function_parameters(
2435 array(
2436 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2437 'convid' => new external_value(PARAM_INT, 'The conversation id'),
2438 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2439 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2440 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
2441 'timefrom' => new external_value(PARAM_INT,
2442 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
2448 * Get conversation messages.
2450 * @param int $currentuserid The current user's id.
2451 * @param int $convid The conversation id.
2452 * @param int $limitfrom Return a subset of records, starting at this point (optional).
2453 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
2454 * @param bool $newest True for getting first newest messages, false otherwise.
2455 * @param int $timefrom The time from the conversation messages to get.
2456 * @return array The messages and members who have sent some of these messages.
2457 * @throws moodle_exception
2458 * @since 3.6
2460 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
2461 bool $newest = false, int $timefrom = 0) {
2462 global $CFG, $USER;
2464 // Check if messaging is enabled.
2465 if (empty($CFG->messaging)) {
2466 throw new moodle_exception('disabled', 'message');
2469 $systemcontext = context_system::instance();
2471 $params = array(
2472 'currentuserid' => $currentuserid,
2473 'convid' => $convid,
2474 'limitfrom' => $limitfrom,
2475 'limitnum' => $limitnum,
2476 'newest' => $newest,
2477 'timefrom' => $timefrom,
2479 $params = self::validate_parameters(self::get_conversation_messages_parameters(), $params);
2480 self::validate_context($systemcontext);
2482 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2483 throw new moodle_exception('You do not have permission to perform this action.');
2486 // Check that the user belongs to the conversation.
2487 if (!\core_message\api::is_user_in_conversation($params['currentuserid'], $params['convid'])) {
2488 throw new moodle_exception('User is not part of conversation.');
2491 $sort = $newest ? 'timecreated DESC' : 'timecreated ASC';
2493 // We need to enforce a one second delay on messages to avoid race conditions of current
2494 // messages still being sent.
2496 // There is a chance that we could request messages before the current time's
2497 // second has elapsed and while other messages are being sent in that same second. In which
2498 // case those messages will be lost.
2500 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
2501 $timeto = empty($params['timefrom']) ? 0 : time() - 1;
2503 // No requesting messages from the current time, as stated above.
2504 if ($params['timefrom'] == time()) {
2505 $messages = [];
2506 } else {
2507 $messages = \core_message\api::get_conversation_messages(
2508 $params['currentuserid'],
2509 $params['convid'],
2510 $params['limitfrom'],
2511 $params['limitnum'],
2512 $sort,
2513 $params['timefrom'],
2514 $timeto);
2517 return $messages;
2521 * The messagearea messages return structure.
2523 * @return external_single_structure
2524 * @since 3.6
2526 public static function get_conversation_messages_returns() {
2527 return new external_single_structure(
2528 array(
2529 'id' => new external_value(PARAM_INT, 'The conversation id'),
2530 'members' => new external_multiple_structure(
2531 self::get_conversation_member_structure()
2533 'messages' => new external_multiple_structure(
2534 self::get_conversation_message_structure()
2541 * The user contacts return parameters.
2543 * @return external_function_parameters
2545 public static function get_user_contacts_parameters() {
2546 return new external_function_parameters(
2547 array(
2548 'userid' => new external_value(PARAM_INT, 'The id of the user who we retrieving the contacts for'),
2549 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2550 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
2556 * Get user contacts.
2558 * @param int $userid The id of the user who we are viewing conversations for
2559 * @param int $limitfrom
2560 * @param int $limitnum
2561 * @return array
2562 * @throws moodle_exception
2564 public static function get_user_contacts(int $userid, int $limitfrom = 0, int $limitnum = 0) {
2565 global $CFG, $USER;
2567 // Check if messaging is enabled.
2568 if (empty($CFG->messaging)) {
2569 throw new moodle_exception('disabled', 'message');
2572 $systemcontext = context_system::instance();
2574 $params = array(
2575 'userid' => $userid,
2576 'limitfrom' => $limitfrom,
2577 'limitnum' => $limitnum
2579 $params = self::validate_parameters(self::get_user_contacts_parameters(), $params);
2580 self::validate_context($systemcontext);
2582 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2583 throw new moodle_exception('You do not have permission to perform this action.');
2586 return \core_message\api::get_user_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
2590 * The user contacts return structure.
2592 * @return external_multiple_structure
2594 public static function get_user_contacts_returns() {
2595 return new external_multiple_structure(
2596 self::get_conversation_member_structure()
2601 * The get most recent message return parameters.
2603 * @deprecated since 3.6
2604 * @return external_function_parameters
2605 * @since 3.2
2607 public static function data_for_messagearea_get_most_recent_message_parameters() {
2608 return new external_function_parameters(
2609 array(
2610 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2611 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2617 * Get the most recent message in a conversation.
2619 * @deprecated since 3.6
2620 * @param int $currentuserid The current user's id
2621 * @param int $otheruserid The other user's id
2622 * @return stdClass
2623 * @throws moodle_exception
2624 * @since 3.2
2626 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
2627 global $CFG, $PAGE, $USER;
2629 // Check if messaging is enabled.
2630 if (empty($CFG->messaging)) {
2631 throw new moodle_exception('disabled', 'message');
2634 $systemcontext = context_system::instance();
2636 $params = array(
2637 'currentuserid' => $currentuserid,
2638 'otheruserid' => $otheruserid
2640 $params = self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
2641 self::validate_context($systemcontext);
2643 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2644 throw new moodle_exception('You do not have permission to perform this action.');
2647 $message = \core_message\api::get_most_recent_message($params['currentuserid'], $params['otheruserid']);
2648 $message = new \core_message\output\messagearea\message($message);
2650 $renderer = $PAGE->get_renderer('core_message');
2651 return $message->export_for_template($renderer);
2655 * The get most recent message return structure.
2657 * @deprecated since 3.6
2658 * @return external_single_structure
2659 * @since 3.2
2661 public static function data_for_messagearea_get_most_recent_message_returns() {
2662 return self::get_messagearea_message_structure();
2666 * Marking the method as deprecated.
2668 * @return bool
2670 public static function data_for_messagearea_get_most_recent_message_is_deprecated() {
2671 return true;
2675 * The get profile parameters.
2677 * @deprecated since 3.6
2678 * @return external_function_parameters
2679 * @since 3.2
2681 public static function data_for_messagearea_get_profile_parameters() {
2682 return new external_function_parameters(
2683 array(
2684 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2685 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
2691 * Get the profile information for a contact.
2693 * @deprecated since 3.6
2694 * @param int $currentuserid The current user's id
2695 * @param int $otheruserid The id of the user whose profile we are viewing
2696 * @return stdClass
2697 * @throws moodle_exception
2698 * @since 3.2
2700 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
2701 global $CFG, $PAGE, $USER;
2703 // Check if messaging is enabled.
2704 if (empty($CFG->messaging)) {
2705 throw new moodle_exception('disabled', 'message');
2708 $systemcontext = context_system::instance();
2710 $params = array(
2711 'currentuserid' => $currentuserid,
2712 'otheruserid' => $otheruserid
2714 $params = self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
2715 self::validate_context($systemcontext);
2717 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2718 throw new moodle_exception('You do not have permission to perform this action.');
2721 $profile = \core_message\api::get_profile($params['currentuserid'], $params['otheruserid']);
2722 $profile = new \core_message\output\messagearea\profile($profile);
2724 $renderer = $PAGE->get_renderer('core_message');
2725 return $profile->export_for_template($renderer);
2729 * The get profile return structure.
2731 * @deprecated since 3.6
2732 * @return external_single_structure
2733 * @since 3.2
2735 public static function data_for_messagearea_get_profile_returns() {
2736 return new external_single_structure(
2737 array(
2738 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
2739 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
2740 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
2741 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
2742 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
2743 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
2744 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
2745 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
2746 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
2747 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
2748 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
2754 * Marking the method as deprecated.
2756 * @return bool
2758 public static function data_for_messagearea_get_profile_is_deprecated() {
2759 return true;
2763 * Get contacts parameters description.
2765 * @deprecated since 3.6
2766 * @return external_function_parameters
2767 * @since Moodle 2.5
2769 public static function get_contacts_parameters() {
2770 return new external_function_parameters(array());
2774 * Get contacts.
2776 * @deprecated since 3.6
2777 * @return external_description
2778 * @since Moodle 2.5
2780 public static function get_contacts() {
2781 global $CFG, $PAGE, $USER;
2783 // Check if messaging is enabled.
2784 if (empty($CFG->messaging)) {
2785 throw new moodle_exception('disabled', 'message');
2788 require_once($CFG->dirroot . '/user/lib.php');
2790 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
2791 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id);
2792 foreach ($contacts as $contact) {
2793 // Set the mode.
2794 $mode = 'offline';
2795 if (\core_message\helper::is_online($contact->lastaccess)) {
2796 $mode = 'online';
2799 $newcontact = array(
2800 'id' => $contact->id,
2801 'fullname' => fullname($contact),
2802 'unread' => $contact->messagecount
2805 $userpicture = new user_picture($contact);
2806 $userpicture->size = 1; // Size f1.
2807 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2808 $userpicture->size = 0; // Size f2.
2809 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2811 $allcontacts[$mode][$contact->id] = $newcontact;
2814 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id);
2815 foreach ($strangers as $contact) {
2816 $newcontact = array(
2817 'id' => $contact->id,
2818 'fullname' => fullname($contact),
2819 'unread' => $contact->messagecount
2822 $userpicture = new user_picture($contact);
2823 $userpicture->size = 1; // Size f1.
2824 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2825 $userpicture->size = 0; // Size f2.
2826 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2828 $allcontacts['strangers'][$contact->id] = $newcontact;
2831 // Add noreply user and support user to the list, if they don't exist.
2832 $supportuser = core_user::get_support_user();
2833 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) {
2834 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
2835 if ($supportuser->messagecount > 0) {
2836 $supportuser->fullname = fullname($supportuser);
2837 $supportuser->unread = $supportuser->messagecount;
2838 $allcontacts['strangers'][$supportuser->id] = $supportuser;
2842 $noreplyuser = core_user::get_noreply_user();
2843 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) {
2844 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
2845 if ($noreplyuser->messagecount > 0) {
2846 $noreplyuser->fullname = fullname($noreplyuser);
2847 $noreplyuser->unread = $noreplyuser->messagecount;
2848 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser;
2852 return $allcontacts;
2856 * Get contacts return description.
2858 * @deprecated since 3.6
2859 * @return external_description
2860 * @since Moodle 2.5
2862 public static function get_contacts_returns() {
2863 return new external_single_structure(
2864 array(
2865 'online' => new external_multiple_structure(
2866 new external_single_structure(
2867 array(
2868 'id' => new external_value(PARAM_INT, 'User ID'),
2869 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2870 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2871 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2872 'unread' => new external_value(PARAM_INT, 'Unread message count')
2875 'List of online contacts'
2877 'offline' => new external_multiple_structure(
2878 new external_single_structure(
2879 array(
2880 'id' => new external_value(PARAM_INT, 'User ID'),
2881 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2882 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2883 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2884 'unread' => new external_value(PARAM_INT, 'Unread message count')
2887 'List of offline contacts'
2889 'strangers' => new external_multiple_structure(
2890 new external_single_structure(
2891 array(
2892 'id' => new external_value(PARAM_INT, 'User ID'),
2893 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2894 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2895 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2896 'unread' => new external_value(PARAM_INT, 'Unread message count')
2899 'List of users that are not in the user\'s contact list but have sent a message'
2906 * Marking the method as deprecated.
2908 * @return bool
2910 public static function get_contacts_is_deprecated() {
2911 return true;
2915 * Search contacts parameters description.
2917 * @return external_function_parameters
2918 * @since Moodle 2.5
2920 public static function search_contacts_parameters() {
2921 return new external_function_parameters(
2922 array(
2923 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
2924 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
2925 VALUE_DEFAULT, false)
2931 * Search contacts.
2933 * @param string $searchtext query string.
2934 * @param bool $onlymycourses limit the search to the user's courses only.
2935 * @return external_description
2936 * @since Moodle 2.5
2938 public static function search_contacts($searchtext, $onlymycourses = false) {
2939 global $CFG, $USER, $PAGE;
2940 require_once($CFG->dirroot . '/user/lib.php');
2942 // Check if messaging is enabled.
2943 if (empty($CFG->messaging)) {
2944 throw new moodle_exception('disabled', 'message');
2947 require_once($CFG->libdir . '/enrollib.php');
2949 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
2950 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
2952 // Extra validation, we do not allow empty queries.
2953 if ($params['searchtext'] === '') {
2954 throw new moodle_exception('querystringcannotbeempty');
2957 $courseids = array();
2958 if ($params['onlymycourses']) {
2959 $mycourses = enrol_get_my_courses(array('id'));
2960 foreach ($mycourses as $mycourse) {
2961 $courseids[] = $mycourse->id;
2963 } else {
2964 $courseids[] = SITEID;
2967 // Retrieving the users matching the query.
2968 $users = message_search_users($courseids, $params['searchtext']);
2969 $results = array();
2970 foreach ($users as $user) {
2971 $results[$user->id] = $user;
2974 // Reorganising information.
2975 foreach ($results as &$user) {
2976 $newuser = array(
2977 'id' => $user->id,
2978 'fullname' => fullname($user)
2981 // Avoid undefined property notice as phone not specified.
2982 $user->phone1 = null;
2983 $user->phone2 = null;
2985 $userpicture = new user_picture($user);
2986 $userpicture->size = 1; // Size f1.
2987 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2988 $userpicture->size = 0; // Size f2.
2989 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2991 $user = $newuser;
2994 return $results;
2998 * Search contacts return description.
3000 * @return external_description
3001 * @since Moodle 2.5
3003 public static function search_contacts_returns() {
3004 return new external_multiple_structure(
3005 new external_single_structure(
3006 array(
3007 'id' => new external_value(PARAM_INT, 'User ID'),
3008 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
3009 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
3010 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
3013 'List of contacts'
3018 * Get messages parameters description.
3020 * @return external_function_parameters
3021 * @since 2.8
3023 public static function get_messages_parameters() {
3024 return new external_function_parameters(
3025 array(
3026 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3027 'useridfrom' => new external_value(
3028 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3029 VALUE_DEFAULT, 0),
3030 'type' => new external_value(
3031 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
3032 VALUE_DEFAULT, 'both'),
3033 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
3034 'newestfirst' => new external_value(
3035 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
3036 VALUE_DEFAULT, true),
3037 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
3038 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
3044 * Get messages function implementation.
3046 * @since 2.8
3047 * @throws invalid_parameter_exception
3048 * @throws moodle_exception
3049 * @param int $useridto the user id who received the message
3050 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3051 * @param string $type type of message to return, expected values: notifications, conversations and both
3052 * @param bool $read true for retreiving read messages, false for unread
3053 * @param bool $newestfirst true for ordering by newest first, false for oldest first
3054 * @param int $limitfrom limit from
3055 * @param int $limitnum limit num
3056 * @return external_description
3058 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
3059 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
3060 global $CFG, $USER;
3062 $warnings = array();
3064 $params = array(
3065 'useridto' => $useridto,
3066 'useridfrom' => $useridfrom,
3067 'type' => $type,
3068 'read' => $read,
3069 'newestfirst' => $newestfirst,
3070 'limitfrom' => $limitfrom,
3071 'limitnum' => $limitnum
3074 $params = self::validate_parameters(self::get_messages_parameters(), $params);
3076 $context = context_system::instance();
3077 self::validate_context($context);
3079 $useridto = $params['useridto'];
3080 $useridfrom = $params['useridfrom'];
3081 $type = $params['type'];
3082 $read = $params['read'];
3083 $newestfirst = $params['newestfirst'];
3084 $limitfrom = $params['limitfrom'];
3085 $limitnum = $params['limitnum'];
3087 $allowedvalues = array('notifications', 'conversations', 'both');
3088 if (!in_array($type, $allowedvalues)) {
3089 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
3090 'allowed values are: ' . implode(',', $allowedvalues));
3093 // Check if private messaging between users is allowed.
3094 if (empty($CFG->messaging)) {
3095 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
3096 if ($type == "conversations") {
3097 throw new moodle_exception('disabled', 'message');
3099 if ($type == "both") {
3100 $warning = array();
3101 $warning['item'] = 'message';
3102 $warning['itemid'] = $USER->id;
3103 $warning['warningcode'] = '1';
3104 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
3105 Only notifications will be returned';
3106 $warnings[] = $warning;
3110 if (!empty($useridto)) {
3111 if (core_user::is_real_user($useridto)) {
3112 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3113 } else {
3114 throw new moodle_exception('invaliduser');
3118 if (!empty($useridfrom)) {
3119 // We use get_user here because the from user can be the noreply or support user.
3120 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3123 // Check if the current user is the sender/receiver or just a privileged user.
3124 if ($useridto != $USER->id and $useridfrom != $USER->id and
3125 !has_capability('moodle/site:readallmessages', $context)) {
3126 throw new moodle_exception('accessdenied', 'admin');
3129 // Which type of messages to retrieve.
3130 $notifications = -1;
3131 if ($type != 'both') {
3132 $notifications = ($type == 'notifications') ? 1 : 0;
3135 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
3136 $sort = "mr.timecreated $orderdirection";
3138 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
3139 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
3141 // In some cases, we don't need to get the to/from user objects from the sql query.
3142 $userfromfullname = '';
3143 $usertofullname = '';
3145 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
3146 if (!empty($useridto)) {
3147 $usertofullname = fullname($userto, $canviewfullname);
3148 // The user from may or may not be filled.
3149 if (!empty($useridfrom)) {
3150 $userfromfullname = fullname($userfrom, $canviewfullname);
3152 } else {
3153 // If the useridto field is empty, the useridfrom must be filled.
3154 $userfromfullname = fullname($userfrom, $canviewfullname);
3156 foreach ($messages as $mid => $message) {
3158 // Do not return deleted messages.
3159 if (!$message->notification) {
3160 if (($useridto == $USER->id and $message->timeusertodeleted) or
3161 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
3162 unset($messages[$mid]);
3163 continue;
3167 // We need to get the user from the query.
3168 if (empty($userfromfullname)) {
3169 // Check for non-reply and support users.
3170 if (core_user::is_real_user($message->useridfrom)) {
3171 $user = new stdClass();
3172 $user = username_load_fields_from_object($user, $message, 'userfrom');
3173 $message->userfromfullname = fullname($user, $canviewfullname);
3174 } else {
3175 $user = core_user::get_user($message->useridfrom);
3176 $message->userfromfullname = fullname($user, $canviewfullname);
3178 } else {
3179 $message->userfromfullname = $userfromfullname;
3182 // We need to get the user from the query.
3183 if (empty($usertofullname)) {
3184 $user = new stdClass();
3185 $user = username_load_fields_from_object($user, $message, 'userto');
3186 $message->usertofullname = fullname($user, $canviewfullname);
3187 } else {
3188 $message->usertofullname = $usertofullname;
3191 $message->text = message_format_message_text($message);
3192 $messages[$mid] = (array) $message;
3196 $results = array(
3197 'messages' => $messages,
3198 'warnings' => $warnings
3201 return $results;
3205 * Get messages return description.
3207 * @return external_single_structure
3208 * @since 2.8
3210 public static function get_messages_returns() {
3211 return new external_single_structure(
3212 array(
3213 'messages' => new external_multiple_structure(
3214 new external_single_structure(
3215 array(
3216 'id' => new external_value(PARAM_INT, 'Message id'),
3217 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
3218 'useridto' => new external_value(PARAM_INT, 'User to id'),
3219 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
3220 'text' => new external_value(PARAM_RAW, 'The message text formated'),
3221 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
3222 'fullmessageformat' => new external_format_value('fullmessage'),
3223 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
3224 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
3225 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
3226 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
3227 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
3228 'timecreated' => new external_value(PARAM_INT, 'Time created'),
3229 'timeread' => new external_value(PARAM_INT, 'Time read'),
3230 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
3231 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name'),
3232 'component' => new external_value(PARAM_TEXT, 'The component that generated the notification',
3233 VALUE_OPTIONAL),
3234 'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL),
3235 'customdata' => new external_value(PARAM_RAW, 'Custom data to be passed to the message processor.
3236 The data here is serialised using json_encode().', VALUE_OPTIONAL),
3237 ), 'message'
3240 'warnings' => new external_warnings()
3246 * Mark all notifications as read parameters description.
3248 * @return external_function_parameters
3249 * @since 3.2
3251 public static function mark_all_notifications_as_read_parameters() {
3252 return new external_function_parameters(
3253 array(
3254 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3255 'useridfrom' => new external_value(
3256 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3257 VALUE_DEFAULT, 0),
3263 * Mark all notifications as read function.
3265 * @since 3.2
3266 * @throws invalid_parameter_exception
3267 * @throws moodle_exception
3268 * @param int $useridto the user id who received the message
3269 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3270 * @return external_description
3272 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
3273 global $USER;
3275 $params = self::validate_parameters(
3276 self::mark_all_notifications_as_read_parameters(),
3277 array(
3278 'useridto' => $useridto,
3279 'useridfrom' => $useridfrom,
3283 $context = context_system::instance();
3284 self::validate_context($context);
3286 $useridto = $params['useridto'];
3287 $useridfrom = $params['useridfrom'];
3289 if (!empty($useridto)) {
3290 if (core_user::is_real_user($useridto)) {
3291 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3292 } else {
3293 throw new moodle_exception('invaliduser');
3297 if (!empty($useridfrom)) {
3298 // We use get_user here because the from user can be the noreply or support user.
3299 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3302 // Check if the current user is the sender/receiver or just a privileged user.
3303 if ($useridto != $USER->id and $useridfrom != $USER->id and
3304 // The deleteanymessage cap seems more reasonable here than readallmessages.
3305 !has_capability('moodle/site:deleteanymessage', $context)) {
3306 throw new moodle_exception('accessdenied', 'admin');
3309 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom);
3311 return true;
3315 * Mark all notifications as read return description.
3317 * @return external_single_structure
3318 * @since 3.2
3320 public static function mark_all_notifications_as_read_returns() {
3321 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
3325 * Get unread conversations count parameters description.
3327 * @return external_function_parameters
3328 * @since 3.2
3330 public static function get_unread_conversations_count_parameters() {
3331 return new external_function_parameters(
3332 array(
3333 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3339 * Get unread messages count function.
3341 * @since 3.2
3342 * @throws invalid_parameter_exception
3343 * @throws moodle_exception
3344 * @param int $useridto the user id who received the message
3345 * @return external_description
3347 public static function get_unread_conversations_count($useridto) {
3348 global $USER, $CFG;
3350 // Check if messaging is enabled.
3351 if (empty($CFG->messaging)) {
3352 throw new moodle_exception('disabled', 'message');
3355 $params = self::validate_parameters(
3356 self::get_unread_conversations_count_parameters(),
3357 array('useridto' => $useridto)
3360 $context = context_system::instance();
3361 self::validate_context($context);
3363 $useridto = $params['useridto'];
3365 if (!empty($useridto)) {
3366 if (core_user::is_real_user($useridto)) {
3367 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3368 } else {
3369 throw new moodle_exception('invaliduser');
3371 } else {
3372 $useridto = $USER->id;
3375 // Check if the current user is the receiver or just a privileged user.
3376 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
3377 throw new moodle_exception('accessdenied', 'admin');
3380 return \core_message\api::count_unread_conversations($userto);
3384 * Get unread conversations count return description.
3386 * @return external_single_structure
3387 * @since 3.2
3389 public static function get_unread_conversations_count_returns() {
3390 return new external_value(PARAM_INT, 'The count of unread messages for the user');
3394 * Get blocked users parameters description.
3396 * @return external_function_parameters
3397 * @since 2.9
3399 public static function get_blocked_users_parameters() {
3400 return new external_function_parameters(
3401 array(
3402 'userid' => new external_value(PARAM_INT,
3403 'the user whose blocked users we want to retrieve',
3404 VALUE_REQUIRED),
3410 * Retrieve a list of users blocked
3412 * @param int $userid the user whose blocked users we want to retrieve
3413 * @return external_description
3414 * @since 2.9
3416 public static function get_blocked_users($userid) {
3417 global $CFG, $USER, $PAGE;
3419 // Warnings array, it can be empty at the end but is mandatory.
3420 $warnings = array();
3422 // Validate params.
3423 $params = array(
3424 'userid' => $userid
3426 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
3427 $userid = $params['userid'];
3429 // Validate context.
3430 $context = context_system::instance();
3431 self::validate_context($context);
3433 // Check if private messaging between users is allowed.
3434 if (empty($CFG->messaging)) {
3435 throw new moodle_exception('disabled', 'message');
3438 $user = core_user::get_user($userid, '*', MUST_EXIST);
3439 core_user::require_active_user($user);
3441 // Check if we have permissions for retrieve the information.
3442 $capability = 'moodle/site:manageallmessaging';
3443 if (($USER->id != $userid) && !has_capability($capability, $context)) {
3444 throw new required_capability_exception($context, $capability, 'nopermissions', '');
3447 // Now, we can get safely all the blocked users.
3448 $users = \core_message\api::get_blocked_users($user->id);
3450 $blockedusers = array();
3451 foreach ($users as $user) {
3452 $newuser = array(
3453 'id' => $user->id,
3454 'fullname' => fullname($user),
3457 $userpicture = new user_picture($user);
3458 $userpicture->size = 1; // Size f1.
3459 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
3461 $blockedusers[] = $newuser;
3464 $results = array(
3465 'users' => $blockedusers,
3466 'warnings' => $warnings
3468 return $results;
3472 * Get blocked users return description.
3474 * @return external_single_structure
3475 * @since 2.9
3477 public static function get_blocked_users_returns() {
3478 return new external_single_structure(
3479 array(
3480 'users' => new external_multiple_structure(
3481 new external_single_structure(
3482 array(
3483 'id' => new external_value(PARAM_INT, 'User ID'),
3484 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
3485 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
3488 'List of blocked users'
3490 'warnings' => new external_warnings()
3496 * Returns description of method parameters
3498 * @return external_function_parameters
3499 * @since 2.9
3501 public static function mark_message_read_parameters() {
3502 return new external_function_parameters(
3503 array(
3504 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'),
3505 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
3506 VALUE_DEFAULT, 0)
3512 * Mark a single message as read, trigger message_viewed event
3514 * @param int $messageid id of the message (in the message table)
3515 * @param int $timeread timestamp for when the message should be marked read
3516 * @return external_description
3517 * @throws invalid_parameter_exception
3518 * @throws moodle_exception
3519 * @since 2.9
3521 public static function mark_message_read($messageid, $timeread) {
3522 global $CFG, $DB, $USER;
3524 // Check if private messaging between users is allowed.
3525 if (empty($CFG->messaging)) {
3526 throw new moodle_exception('disabled', 'message');
3529 // Warnings array, it can be empty at the end but is mandatory.
3530 $warnings = array();
3532 // Validate params.
3533 $params = array(
3534 'messageid' => $messageid,
3535 'timeread' => $timeread
3537 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
3539 if (empty($params['timeread'])) {
3540 $timeread = time();
3541 } else {
3542 $timeread = $params['timeread'];
3545 // Validate context.
3546 $context = context_system::instance();
3547 self::validate_context($context);
3549 $sql = "SELECT m.*, mcm.userid as useridto
3550 FROM {messages} m
3551 INNER JOIN {message_conversations} mc
3552 ON m.conversationid = mc.id
3553 INNER JOIN {message_conversation_members} mcm
3554 ON mcm.conversationid = mc.id
3555 LEFT JOIN {message_user_actions} mua
3556 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
3557 WHERE mua.id is NULL
3558 AND mcm.userid != m.useridfrom
3559 AND m.id = ?";
3560 $messageparams = [];
3561 $messageparams[] = $USER->id;
3562 $messageparams[] = \core_message\api::MESSAGE_ACTION_READ;
3563 $messageparams[] = $params['messageid'];
3564 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST);
3566 if ($message->useridto != $USER->id) {
3567 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
3570 \core_message\api::mark_message_as_read($USER->id, $message, $timeread);
3572 $results = array(
3573 'messageid' => $message->id,
3574 'warnings' => $warnings
3576 return $results;
3580 * Returns description of method result value
3582 * @return external_description
3583 * @since 2.9
3585 public static function mark_message_read_returns() {
3586 return new external_single_structure(
3587 array(
3588 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'),
3589 'warnings' => new external_warnings()
3595 * Returns description of method parameters
3597 * @return external_function_parameters
3599 public static function mark_notification_read_parameters() {
3600 return new external_function_parameters(
3601 array(
3602 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
3603 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read',
3604 VALUE_DEFAULT, 0)
3610 * Mark a single notification as read.
3612 * This will trigger a 'notification_viewed' event.
3614 * @param int $notificationid id of the notification
3615 * @param int $timeread timestamp for when the notification should be marked read
3616 * @return external_description
3617 * @throws invalid_parameter_exception
3618 * @throws moodle_exception
3620 public static function mark_notification_read($notificationid, $timeread) {
3621 global $CFG, $DB, $USER;
3623 // Check if private messaging between users is allowed.
3624 if (empty($CFG->messaging)) {
3625 throw new moodle_exception('disabled', 'message');
3628 // Warnings array, it can be empty at the end but is mandatory.
3629 $warnings = array();
3631 // Validate params.
3632 $params = array(
3633 'notificationid' => $notificationid,
3634 'timeread' => $timeread
3636 $params = self::validate_parameters(self::mark_notification_read_parameters(), $params);
3638 if (empty($params['timeread'])) {
3639 $timeread = time();
3640 } else {
3641 $timeread = $params['timeread'];
3644 // Validate context.
3645 $context = context_system::instance();
3646 self::validate_context($context);
3648 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST);
3650 if ($notification->useridto != $USER->id) {
3651 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
3652 'notification as read');
3655 \core_message\api::mark_notification_as_read($notification, $timeread);
3657 $results = array(
3658 'notificationid' => $notification->id,
3659 'warnings' => $warnings
3662 return $results;
3666 * Returns description of method result value
3668 * @return external_description
3670 public static function mark_notification_read_returns() {
3671 return new external_single_structure(
3672 array(
3673 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
3674 'warnings' => new external_warnings()
3680 * Mark all messages as read parameters description.
3682 * @deprecated since 3.6
3683 * @return external_function_parameters
3684 * @since 3.2
3686 public static function mark_all_messages_as_read_parameters() {
3687 return new external_function_parameters(
3688 array(
3689 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3690 'useridfrom' => new external_value(
3691 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3692 VALUE_DEFAULT, 0),
3698 * Mark all messages as read function.
3700 * @deprecated since 3.6
3701 * @throws invalid_parameter_exception
3702 * @throws moodle_exception
3703 * @param int $useridto the user id who received the message
3704 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3705 * @return external_description
3706 * @since 3.2
3708 public static function mark_all_messages_as_read($useridto, $useridfrom) {
3709 global $USER, $CFG;
3711 // Check if messaging is enabled.
3712 if (empty($CFG->messaging)) {
3713 throw new moodle_exception('disabled', 'message');
3716 $params = self::validate_parameters(
3717 self::mark_all_messages_as_read_parameters(),
3718 array(
3719 'useridto' => $useridto,
3720 'useridfrom' => $useridfrom,
3724 $context = context_system::instance();
3725 self::validate_context($context);
3727 $useridto = $params['useridto'];
3728 $useridfrom = $params['useridfrom'];
3730 if (!empty($useridto)) {
3731 if (core_user::is_real_user($useridto)) {
3732 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3733 } else {
3734 throw new moodle_exception('invaliduser');
3738 if (!empty($useridfrom)) {
3739 // We use get_user here because the from user can be the noreply or support user.
3740 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3743 // Check if the current user is the sender/receiver or just a privileged user.
3744 if ($useridto != $USER->id and $useridfrom != $USER->id and
3745 // The deleteanymessage cap seems more reasonable here than readallmessages.
3746 !has_capability('moodle/site:deleteanymessage', $context)) {
3747 throw new moodle_exception('accessdenied', 'admin');
3750 if ($useridfrom) {
3751 if ($conversationid = \core_message\api::get_conversation_between_users([$useridto, $useridfrom])) {
3752 \core_message\api::mark_all_messages_as_read($useridto, $conversationid);
3754 } else {
3755 \core_message\api::mark_all_messages_as_read($useridto);
3758 return true;
3762 * Mark all messages as read return description.
3764 * @deprecated since 3.6
3765 * @return external_single_structure
3766 * @since 3.2
3768 public static function mark_all_messages_as_read_returns() {
3769 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
3773 * Marking the method as deprecated.
3775 * @return bool
3777 public static function mark_all_messages_as_read_is_deprecated() {
3778 return true;
3782 * Mark all conversation messages as read parameters description.
3784 * @return external_function_parameters
3785 * @since 3.6
3787 public static function mark_all_conversation_messages_as_read_parameters() {
3788 return new external_function_parameters(
3789 array(
3790 'userid' => new external_value(PARAM_INT, 'The user id who who we are marking the messages as read for'),
3791 'conversationid' =>
3792 new external_value(PARAM_INT, 'The conversation id who who we are marking the messages as read for')
3798 * Mark all conversation messages as read function.
3800 * @param int $userid The user id of who we want to delete the conversation for
3801 * @param int $conversationid The id of the conversations
3802 * @since 3.6
3804 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
3805 global $CFG;
3807 // Check if messaging is enabled.
3808 if (empty($CFG->messaging)) {
3809 throw new moodle_exception('disabled', 'message');
3812 $params = array(
3813 'userid' => $userid,
3814 'conversationid' => $conversationid,
3816 $params = self::validate_parameters(self::mark_all_conversation_messages_as_read_parameters(), $params);
3818 $context = context_system::instance();
3819 self::validate_context($context);
3821 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3822 core_user::require_active_user($user);
3824 if (\core_message\api::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) {
3825 \core_message\api::mark_all_messages_as_read($params['userid'], $params['conversationid']);
3826 } else {
3827 throw new moodle_exception('accessdenied', 'admin');
3832 * Mark all conversation messages as read return description.
3834 * @return external_warnings
3835 * @since 3.6
3837 public static function mark_all_conversation_messages_as_read_returns() {
3838 return null;
3842 * Returns description of method parameters.
3844 * @deprecated since 3.6
3845 * @return external_function_parameters
3846 * @since 3.2
3848 public static function delete_conversation_parameters() {
3849 return new external_function_parameters(
3850 array(
3851 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
3852 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
3858 * Deletes a conversation.
3860 * @deprecated since 3.6
3861 * @param int $userid The user id of who we want to delete the conversation for
3862 * @param int $otheruserid The user id of the other user in the conversation
3863 * @return array
3864 * @throws moodle_exception
3865 * @since 3.2
3867 public static function delete_conversation($userid, $otheruserid) {
3868 global $CFG;
3870 // Check if private messaging between users is allowed.
3871 if (empty($CFG->messaging)) {
3872 throw new moodle_exception('disabled', 'message');
3875 // Warnings array, it can be empty at the end but is mandatory.
3876 $warnings = array();
3878 // Validate params.
3879 $params = array(
3880 'userid' => $userid,
3881 'otheruserid' => $otheruserid,
3883 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
3885 // Validate context.
3886 $context = context_system::instance();
3887 self::validate_context($context);
3889 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3890 core_user::require_active_user($user);
3892 if (!$conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']])) {
3893 return [];
3896 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) {
3897 \core_message\api::delete_conversation_by_id($user->id, $conversationid);
3898 $status = true;
3899 } else {
3900 throw new moodle_exception('You do not have permission to delete messages');
3903 $results = array(
3904 'status' => $status,
3905 'warnings' => $warnings
3908 return $results;
3912 * Returns description of method result value.
3914 * @deprecated since 3.6
3915 * @return external_description
3916 * @since 3.2
3918 public static function delete_conversation_returns() {
3919 return new external_single_structure(
3920 array(
3921 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
3922 'warnings' => new external_warnings()
3928 * Marking the method as deprecated.
3930 * @return bool
3932 public static function delete_conversation_is_deprecated() {
3933 return true;
3937 * Returns description of method parameters.
3939 * @return external_function_parameters
3940 * @since 3.6
3942 public static function delete_conversations_by_id_parameters() {
3943 return new external_function_parameters(
3944 array(
3945 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
3946 'conversationids' => new external_multiple_structure(
3947 new external_value(PARAM_INT, 'The id of the conversation'),
3948 'List of conversation IDs'
3955 * Deletes a conversation.
3957 * @param int $userid The user id of who we want to delete the conversation for
3958 * @param int[] $conversationids The ids of the conversations
3959 * @return array
3960 * @throws moodle_exception
3961 * @since 3.6
3963 public static function delete_conversations_by_id($userid, array $conversationids) {
3964 global $CFG;
3966 // Check if private messaging between users is allowed.
3967 if (empty($CFG->messaging)) {
3968 throw new moodle_exception('disabled', 'message');
3971 // Validate params.
3972 $params = [
3973 'userid' => $userid,
3974 'conversationids' => $conversationids,
3976 $params = self::validate_parameters(self::delete_conversations_by_id_parameters(), $params);
3978 // Validate context.
3979 $context = context_system::instance();
3980 self::validate_context($context);
3982 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3983 core_user::require_active_user($user);
3985 foreach ($params['conversationids'] as $conversationid) {
3986 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) {
3987 \core_message\api::delete_conversation_by_id($user->id, $conversationid);
3988 } else {
3989 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'");
3993 return [];
3997 * Returns description of method result value.
3999 * @return external_description
4000 * @since 3.6
4002 public static function delete_conversations_by_id_returns() {
4003 return new external_warnings();
4007 * Returns description of method parameters
4009 * @return external_function_parameters
4010 * @since 3.1
4012 public static function delete_message_parameters() {
4013 return new external_function_parameters(
4014 array(
4015 'messageid' => new external_value(PARAM_INT, 'The message id'),
4016 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
4017 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
4023 * Deletes a message
4025 * @param int $messageid the message id
4026 * @param int $userid the user id of who we want to delete the message for
4027 * @param bool $read if is a message read (default to true)
4028 * @return external_description
4029 * @throws moodle_exception
4030 * @since 3.1
4032 public static function delete_message($messageid, $userid, $read = true) {
4033 global $CFG;
4035 // Check if private messaging between users is allowed.
4036 if (empty($CFG->messaging)) {
4037 throw new moodle_exception('disabled', 'message');
4040 // Warnings array, it can be empty at the end but is mandatory.
4041 $warnings = array();
4043 // Validate params.
4044 $params = array(
4045 'messageid' => $messageid,
4046 'userid' => $userid,
4047 'read' => $read
4049 $params = self::validate_parameters(self::delete_message_parameters(), $params);
4051 // Validate context.
4052 $context = context_system::instance();
4053 self::validate_context($context);
4055 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4056 core_user::require_active_user($user);
4058 if (\core_message\api::can_delete_message($user->id, $params['messageid'])) {
4059 $status = \core_message\api::delete_message($user->id, $params['messageid']);
4060 } else {
4061 throw new moodle_exception('You do not have permission to delete this message');
4064 $results = array(
4065 'status' => $status,
4066 'warnings' => $warnings
4068 return $results;
4072 * Returns description of method result value
4074 * @return external_description
4075 * @since 3.1
4077 public static function delete_message_returns() {
4078 return new external_single_structure(
4079 array(
4080 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
4081 'warnings' => new external_warnings()
4087 * Returns description of method parameters
4089 * @return external_function_parameters
4090 * @since 3.2
4092 public static function message_processor_config_form_parameters() {
4093 return new external_function_parameters(
4094 array(
4095 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
4096 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
4097 'formvalues' => new external_multiple_structure(
4098 new external_single_structure(
4099 array(
4100 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
4101 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
4104 'Config form values',
4105 VALUE_REQUIRED
4112 * Processes a message processor config form.
4114 * @param int $userid the user id
4115 * @param string $name the name of the processor
4116 * @param array $formvalues the form values
4117 * @return external_description
4118 * @throws moodle_exception
4119 * @since 3.2
4121 public static function message_processor_config_form($userid, $name, $formvalues) {
4122 global $USER, $CFG;
4124 // Check if messaging is enabled.
4125 if (empty($CFG->messaging)) {
4126 throw new moodle_exception('disabled', 'message');
4129 $params = self::validate_parameters(
4130 self::message_processor_config_form_parameters(),
4131 array(
4132 'userid' => $userid,
4133 'name' => $name,
4134 'formvalues' => $formvalues,
4138 $user = self::validate_preferences_permissions($params['userid']);
4140 $processor = get_message_processor($params['name']);
4141 $preferences = [];
4142 $form = new stdClass();
4144 foreach ($params['formvalues'] as $formvalue) {
4145 // Curly braces to ensure interpretation is consistent between
4146 // php 5 and php 7.
4147 $form->{$formvalue['name']} = $formvalue['value'];
4150 $processor->process_form($form, $preferences);
4152 if (!empty($preferences)) {
4153 set_user_preferences($preferences, $params['userid']);
4158 * Returns description of method result value
4160 * @return external_description
4161 * @since 3.2
4163 public static function message_processor_config_form_returns() {
4164 return null;
4168 * Returns description of method parameters
4170 * @return external_function_parameters
4171 * @since 3.2
4173 public static function get_message_processor_parameters() {
4174 return new external_function_parameters(
4175 array(
4176 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
4177 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
4183 * Get a message processor.
4185 * @param int $userid
4186 * @param string $name the name of the processor
4187 * @return external_description
4188 * @throws moodle_exception
4189 * @since 3.2
4191 public static function get_message_processor($userid = 0, $name) {
4192 global $USER, $PAGE, $CFG;
4194 // Check if messaging is enabled.
4195 if (empty($CFG->messaging)) {
4196 throw new moodle_exception('disabled', 'message');
4199 $params = self::validate_parameters(
4200 self::get_message_processor_parameters(),
4201 array(
4202 'userid' => $userid,
4203 'name' => $name,
4207 if (empty($params['userid'])) {
4208 $params['userid'] = $USER->id;
4211 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4212 core_user::require_active_user($user);
4213 self::validate_context(context_user::instance($params['userid']));
4215 $processor = get_message_processor($params['name']);
4217 $processoroutput = new \core_message\output\processor($processor, $user);
4218 $renderer = $PAGE->get_renderer('core_message');
4220 return $processoroutput->export_for_template($renderer);
4224 * Returns description of method result value
4226 * @return external_description
4227 * @since 3.2
4229 public static function get_message_processor_returns() {
4230 return new external_function_parameters(
4231 array(
4232 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
4233 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
4239 * Check that the user has enough permission to retrieve message or notifications preferences.
4241 * @param int $userid the user id requesting the preferences
4242 * @return stdClass full user object
4243 * @throws moodle_exception
4244 * @since Moodle 3.2
4246 protected static function validate_preferences_permissions($userid) {
4247 global $USER;
4249 if (empty($userid)) {
4250 $user = $USER;
4251 } else {
4252 $user = core_user::get_user($userid, '*', MUST_EXIST);
4253 core_user::require_active_user($user);
4256 $systemcontext = context_system::instance();
4257 self::validate_context($systemcontext);
4259 // Check access control.
4260 if ($user->id == $USER->id) {
4261 // Editing own message profile.
4262 require_capability('moodle/user:editownmessageprofile', $systemcontext);
4263 } else {
4264 // Teachers, parents, etc.
4265 $personalcontext = context_user::instance($user->id);
4266 require_capability('moodle/user:editmessageprofile', $personalcontext);
4268 return $user;
4272 * Returns a notification or message preference structure.
4274 * @return external_single_structure the structure
4275 * @since Moodle 3.2
4277 protected static function get_preferences_structure() {
4278 return new external_single_structure(
4279 array(
4280 'userid' => new external_value(PARAM_INT, 'User id'),
4281 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
4282 'processors' => new external_multiple_structure(
4283 new external_single_structure(
4284 array(
4285 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4286 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
4287 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
4288 'contextid' => new external_value(PARAM_INT, 'Context id'),
4289 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
4292 'Config form values'
4294 'components' => new external_multiple_structure(
4295 new external_single_structure(
4296 array(
4297 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4298 'notifications' => new external_multiple_structure(
4299 new external_single_structure(
4300 array(
4301 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4302 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
4303 'processors' => new external_multiple_structure(
4304 new external_single_structure(
4305 array(
4306 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4307 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
4308 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
4309 'lockedmessage' => new external_value(PARAM_TEXT,
4310 'Text to display if locked', VALUE_OPTIONAL),
4311 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
4312 'loggedin' => new external_single_structure(
4313 array(
4314 'name' => new external_value(PARAM_NOTAGS, 'Name'),
4315 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4316 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
4319 'loggedoff' => new external_single_structure(
4320 array(
4321 'name' => new external_value(PARAM_NOTAGS, 'Name'),
4322 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4323 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
4328 'Processors values for this notification'
4332 'List of notificaitons for the component'
4336 'Available components'
4343 * Returns description of method parameters
4345 * @return external_function_parameters
4346 * @since 3.2
4348 public static function get_user_notification_preferences_parameters() {
4349 return new external_function_parameters(
4350 array(
4351 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4357 * Get the notification preferences for a given user.
4359 * @param int $userid id of the user, 0 for current user
4360 * @return external_description
4361 * @throws moodle_exception
4362 * @since 3.2
4364 public static function get_user_notification_preferences($userid = 0) {
4365 global $PAGE;
4367 $params = self::validate_parameters(
4368 self::get_user_notification_preferences_parameters(),
4369 array(
4370 'userid' => $userid,
4373 $user = self::validate_preferences_permissions($params['userid']);
4375 $processors = get_message_processors();
4376 $providers = message_get_providers_for_user($user->id);
4377 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
4378 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
4380 $renderer = $PAGE->get_renderer('core_message');
4382 $result = array(
4383 'warnings' => array(),
4384 'preferences' => $notificationlist->export_for_template($renderer)
4386 return $result;
4390 * Returns description of method result value
4392 * @return external_description
4393 * @since 3.2
4395 public static function get_user_notification_preferences_returns() {
4396 return new external_function_parameters(
4397 array(
4398 'preferences' => self::get_preferences_structure(),
4399 'warnings' => new external_warnings(),
4405 * Returns description of method parameters
4407 * @return external_function_parameters
4408 * @since 3.2
4410 public static function get_user_message_preferences_parameters() {
4411 return new external_function_parameters(
4412 array(
4413 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4419 * Get the notification preferences for a given user.
4421 * @param int $userid id of the user, 0 for current user
4422 * @return external_description
4423 * @throws moodle_exception
4424 * @since 3.2
4426 public static function get_user_message_preferences($userid = 0) {
4427 global $CFG, $PAGE;
4429 $params = self::validate_parameters(
4430 self::get_user_message_preferences_parameters(),
4431 array(
4432 'userid' => $userid,
4436 $user = self::validate_preferences_permissions($params['userid']);
4438 // Filter out enabled, available system_configured and user_configured processors only.
4439 $readyprocessors = array_filter(get_message_processors(), function($processor) {
4440 return $processor->enabled &&
4441 $processor->configured &&
4442 $processor->object->is_user_configured() &&
4443 // Filter out processors that don't have and message preferences to configure.
4444 $processor->object->has_message_preferences();
4447 $providers = array_filter(message_get_providers_for_user($user->id), function($provider) {
4448 return $provider->component === 'moodle';
4450 $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user);
4451 $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors,
4452 $providers, $preferences, $user);
4454 $renderer = $PAGE->get_renderer('core_message');
4456 $entertosend = get_user_preferences('message_entertosend', $CFG->messagingdefaultpressenter, $user);
4458 $result = array(
4459 'warnings' => array(),
4460 'preferences' => $notificationlistoutput->export_for_template($renderer),
4461 'blocknoncontacts' => \core_message\api::get_user_privacy_messaging_preference($user->id),
4462 'entertosend' => $entertosend
4464 return $result;
4468 * Returns description of method result value
4470 * @return external_description
4471 * @since 3.2
4473 public static function get_user_message_preferences_returns() {
4474 return new external_function_parameters(
4475 array(
4476 'preferences' => self::get_preferences_structure(),
4477 'blocknoncontacts' => new external_value(PARAM_INT, 'Privacy messaging setting to define who can message you'),
4478 'entertosend' => new external_value(PARAM_BOOL, 'User preference for using enter to send messages'),
4479 'warnings' => new external_warnings(),
4485 * Returns description of method parameters for the favourite_conversations() method.
4487 * @return external_function_parameters
4489 public static function set_favourite_conversations_parameters() {
4490 return new external_function_parameters(
4491 array(
4492 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0),
4493 'conversations' => new external_multiple_structure(
4494 new external_value(PARAM_INT, 'id of the conversation', VALUE_DEFAULT, 0)
4501 * Favourite a conversation, or list of conversations for a user.
4503 * @param int $userid the id of the user, or 0 for the current user.
4504 * @param array $conversationids the list of conversations ids to favourite.
4505 * @return array
4506 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4508 public static function set_favourite_conversations(int $userid, array $conversationids) {
4509 global $CFG, $USER;
4511 // All the business logic checks that really shouldn't be in here.
4512 if (empty($CFG->messaging)) {
4513 throw new moodle_exception('disabled', 'message');
4515 $params = [
4516 'userid' => $userid,
4517 'conversations' => $conversationids
4519 $params = self::validate_parameters(self::set_favourite_conversations_parameters(), $params);
4520 $systemcontext = context_system::instance();
4521 self::validate_context($systemcontext);
4523 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4524 throw new moodle_exception('You do not have permission to perform this action.');
4527 foreach ($params['conversations'] as $conversationid) {
4528 \core_message\api::set_favourite_conversation($conversationid, $params['userid']);
4531 return [];
4535 * Return a description of the returns for the create_user_favourite_conversations() method.
4537 * @return external_description
4539 public static function set_favourite_conversations_returns() {
4540 return new external_warnings();
4544 * Returns description of method parameters for unfavourite_conversations() method.
4546 * @return external_function_parameters
4548 public static function unset_favourite_conversations_parameters() {
4549 return new external_function_parameters(
4550 array(
4551 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0),
4552 'conversations' => new external_multiple_structure(
4553 new external_value(PARAM_INT, 'id of the conversation', VALUE_DEFAULT, 0)
4560 * Unfavourite a conversation, or list of conversations for a user.
4562 * @param int $userid the id of the user, or 0 for the current user.
4563 * @param array $conversationids the list of conversations ids unset as favourites.
4564 * @return array
4565 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4567 public static function unset_favourite_conversations(int $userid, array $conversationids) {
4568 global $CFG, $USER;
4570 // All the business logic checks that really shouldn't be in here.
4571 if (empty($CFG->messaging)) {
4572 throw new moodle_exception('disabled', 'message');
4574 $params = [
4575 'userid' => $userid,
4576 'conversations' => $conversationids
4578 $params = self::validate_parameters(self::unset_favourite_conversations_parameters(), $params);
4579 $systemcontext = context_system::instance();
4580 self::validate_context($systemcontext);
4582 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4583 throw new moodle_exception('You do not have permission to perform this action.');
4586 foreach ($params['conversations'] as $conversationid) {
4587 \core_message\api::unset_favourite_conversation($conversationid, $params['userid']);
4590 return [];
4594 * Unset favourite conversations return description.
4596 * @return external_description
4598 public static function unset_favourite_conversations_returns() {
4599 return new external_warnings();
4603 * Returns description of method parameters for get_member_info() method.
4605 * @return external_function_parameters
4607 public static function get_member_info_parameters() {
4608 return new external_function_parameters(
4609 array(
4610 'referenceuserid' => new external_value(PARAM_INT, 'id of the user'),
4611 'userids' => new external_multiple_structure(
4612 new external_value(PARAM_INT, 'id of members to get')
4614 'includecontactrequests' => new external_value(PARAM_BOOL, 'include contact requests in response', VALUE_DEFAULT, false),
4615 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'include privacy info in response', VALUE_DEFAULT, false)
4621 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid.
4623 * This is the basic structure used when returning members, and includes information about the relationship between each member
4624 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them.
4626 * @param int $referenceuserid the id of the user which check contact and blocked status.
4627 * @param array $userids
4628 * @return array the array of objects containing member info.
4629 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4631 public static function get_member_info(
4632 int $referenceuserid,
4633 array $userids,
4634 bool $includecontactrequests = false,
4635 bool $includeprivacyinfo = false
4637 global $CFG, $USER;
4639 // All the business logic checks that really shouldn't be in here.
4640 if (empty($CFG->messaging)) {
4641 throw new moodle_exception('disabled', 'message');
4643 $params = [
4644 'referenceuserid' => $referenceuserid,
4645 'userids' => $userids,
4646 'includecontactrequests' => $includecontactrequests,
4647 'includeprivacyinfo' => $includeprivacyinfo
4649 $params = self::validate_parameters(self::get_member_info_parameters(), $params);
4650 $systemcontext = context_system::instance();
4651 self::validate_context($systemcontext);
4653 if (($USER->id != $referenceuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4654 throw new moodle_exception('You do not have permission to perform this action.');
4657 return \core_message\helper::get_member_info(
4658 $params['referenceuserid'],
4659 $params['userids'],
4660 $params['includecontactrequests'],
4661 $params['includeprivacyinfo']
4666 * Get member info return description.
4668 * @return external_description
4670 public static function get_member_info_returns() {
4671 return new external_multiple_structure(
4672 self::get_conversation_member_structure()
4677 * Returns description of method parameters for get_conversation_counts() method.
4679 * @return external_function_parameters
4681 public static function get_conversation_counts_parameters() {
4682 return new external_function_parameters(
4684 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4690 * Returns an array of conversation counts for the various types of conversations, including favourites.
4692 * Return format:
4694 * 'favourites' => 0,
4695 * 'types' => [
4696 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
4697 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
4701 * @param int $userid the id of the user whose counts we are fetching.
4702 * @return array the array of conversation counts, indexed by type.
4703 * @throws moodle_exception if the current user cannot perform this action.
4705 public static function get_conversation_counts(int $userid) {
4706 global $CFG, $USER;
4708 // All the business logic checks that really shouldn't be in here.
4709 if (empty($CFG->messaging)) {
4710 throw new moodle_exception('disabled', 'message');
4713 if (empty($userid)) {
4714 $userid = $USER->id;
4717 $params = ['userid' => $userid];
4718 $params = self::validate_parameters(self::get_conversation_counts_parameters(), $params);
4720 $systemcontext = context_system::instance();
4721 self::validate_context($systemcontext);
4723 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4724 throw new moodle_exception('You do not have permission to perform this action.');
4727 return \core_message\api::get_conversation_counts($params['userid']);
4731 * Get conversation counts return description.
4733 * @return external_description
4735 public static function get_conversation_counts_returns() {
4736 return new external_single_structure(
4738 'favourites' => new external_value(PARAM_INT, 'Total number of favourite conversations'),
4739 'types' => new external_single_structure(
4741 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT,
4742 'Total number of individual conversations'),
4743 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT,
4744 'Total number of group conversations'),
4745 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT,
4746 'Total number of self conversations'),
4754 * Returns description of method parameters for get_unread_conversation_counts() method.
4756 * @return external_function_parameters
4758 public static function get_unread_conversation_counts_parameters() {
4759 return new external_function_parameters(
4761 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4767 * Returns an array of unread conversation counts for the various types of conversations, including favourites.
4769 * Return format:
4771 * 'favourites' => 0,
4772 * 'types' => [
4773 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
4774 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
4778 * @param int $userid the id of the user whose counts we are fetching.
4779 * @return array the array of unread conversation counts, indexed by type.
4780 * @throws moodle_exception if the current user cannot perform this action.
4782 public static function get_unread_conversation_counts(int $userid) {
4783 global $CFG, $USER;
4785 // All the business logic checks that really shouldn't be in here.
4786 if (empty($CFG->messaging)) {
4787 throw new moodle_exception('disabled', 'message');
4790 if (empty($userid)) {
4791 $userid = $USER->id;
4794 $params = ['userid' => $userid];
4795 $params = self::validate_parameters(self::get_unread_conversation_counts_parameters(), $params);
4797 $systemcontext = context_system::instance();
4798 self::validate_context($systemcontext);
4800 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4801 throw new moodle_exception('You do not have permission to perform this action.');
4804 return \core_message\api::get_unread_conversation_counts($params['userid']);
4808 * Get unread conversation counts return description.
4810 * @return external_description
4812 public static function get_unread_conversation_counts_returns() {
4813 return new external_single_structure(
4815 'favourites' => new external_value(PARAM_INT, 'Total number of unread favourite conversations'),
4816 'types' => new external_single_structure(
4818 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT,
4819 'Total number of unread individual conversations'),
4820 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT,
4821 'Total number of unread group conversations'),
4822 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT,
4823 'Total number of unread self conversations'),
4831 * Returns description of method parameters
4833 * @return external_function_parameters
4834 * @since 3.7
4836 public static function delete_message_for_all_users_parameters() {
4837 return new external_function_parameters(
4838 array(
4839 'messageid' => new external_value(PARAM_INT, 'The message id'),
4840 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for all users')
4845 * Deletes a message for all users
4847 * @param int $messageid the message id
4848 * @param int $userid the user id of who we want to delete the message for all users
4849 * @return external_description
4850 * @throws moodle_exception
4851 * @since 3.7
4853 public static function delete_message_for_all_users(int $messageid, int $userid) {
4854 global $CFG;
4856 // Check if private messaging between users is allowed.
4857 if (empty($CFG->messaging)) {
4858 throw new moodle_exception('disabled', 'message');
4861 // Validate params.
4862 $params = array(
4863 'messageid' => $messageid,
4864 'userid' => $userid
4866 $params = self::validate_parameters(self::delete_message_for_all_users_parameters(), $params);
4868 // Validate context.
4869 $context = context_system::instance();
4870 self::validate_context($context);
4872 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4873 core_user::require_active_user($user);
4875 // Checks if a user can delete a message for all users.
4876 if (core_message\api::can_delete_message_for_all_users($user->id, $params['messageid'])) {
4877 \core_message\api::delete_message_for_all_users($params['messageid']);
4878 } else {
4879 throw new moodle_exception('You do not have permission to delete this message for everyone.');
4882 return [];
4885 * Returns description of method result value
4887 * @return external_description
4888 * @since 3.7
4890 public static function delete_message_for_all_users_returns() {
4891 return new external_warnings();