Merge branch 'MDL-67119-39' of git://github.com/aanabit/moodle into MOODLE_39_STABLE
[moodle.git] / message / externallib.php
blob7235cbdafcc3b5998cf34430f0338ca86d07e4f2
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 // Validate messages content before posting them.
92 foreach ($params['messages'] as $message) {
93 // Check message length.
94 if (strlen($message['text']) > \core_message\api::MESSAGE_MAX_LENGTH) {
95 throw new moodle_exception('errormessagetoolong', 'message');
99 $messages = [];
100 foreach ($params['messages'] as $message) {
101 $createdmessage = \core_message\api::send_message_to_conversation($USER->id, $params['conversationid'], $message['text'],
102 $message['textformat']);
103 $createdmessage->text = message_format_message_text((object) [
104 'smallmessage' => $createdmessage->text,
105 'fullmessageformat' => external_validate_format($message['textformat']),
106 'fullmessagetrust' => $createdmessage->fullmessagetrust
108 $messages[] = $createdmessage;
111 return $messages;
115 * Returns description of method result value.
117 * @return external_description
118 * @since Moodle 3.6
120 public static function send_messages_to_conversation_returns() {
121 return new external_multiple_structure(
122 self::get_conversation_message_structure()
128 * Returns description of method parameters
130 * @return external_function_parameters
131 * @since Moodle 2.2
133 public static function send_instant_messages_parameters() {
134 return new external_function_parameters(
135 array(
136 'messages' => new external_multiple_structure(
137 new external_single_structure(
138 array(
139 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'),
140 'text' => new external_value(PARAM_RAW, 'the text of the message'),
141 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE),
142 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the message. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL),
151 * Send private messages from the current USER to other users
153 * @param array $messages An array of message to send.
154 * @return array
155 * @since Moodle 2.2
157 public static function send_instant_messages($messages = array()) {
158 global $CFG, $USER, $DB;
160 // Check if messaging is enabled.
161 if (empty($CFG->messaging)) {
162 throw new moodle_exception('disabled', 'message');
165 // Ensure the current user is allowed to run this function
166 $context = context_system::instance();
167 self::validate_context($context);
168 require_capability('moodle/site:sendmessage', $context);
170 // Ensure the current user is allowed to delete message for everyone.
171 $candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $context);
173 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
175 //retrieve all tousers of the messages
176 $receivers = array();
177 foreach($params['messages'] as $message) {
178 $receivers[] = $message['touserid'];
180 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
181 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
183 $resultmessages = array();
184 $messageids = array();
185 foreach ($params['messages'] as $message) {
186 $resultmsg = array(); //the infos about the success of the operation
188 // We are going to do some checking.
189 // Code should match /messages/index.php checks.
190 $success = true;
192 // Check the user exists.
193 if (empty($tousers[$message['touserid']])) {
194 $success = false;
195 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
198 // Check message length.
199 if ($success && strlen($message['text']) > \core_message\api::MESSAGE_MAX_LENGTH) {
200 $success = false;
201 $errormessage = get_string('errormessagetoolong', 'message');
204 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
205 // Check if the recipient can be messaged by the sender.
206 if ($success && !\core_message\api::can_send_message($tousers[$message['touserid']]->id, $USER->id)) {
207 $success = false;
208 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message['touserid'])));
211 // Now we can send the message (at least try).
212 if ($success) {
213 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
214 $success = message_post_message($USER, $tousers[$message['touserid']],
215 $message['text'], external_validate_format($message['textformat']));
218 // Build the resultmsg.
219 if (isset($message['clientmsgid'])) {
220 $resultmsg['clientmsgid'] = $message['clientmsgid'];
222 if ($success) {
223 $resultmsg['msgid'] = $success;
224 $resultmsg['timecreated'] = time();
225 $resultmsg['candeletemessagesforallusers'] = $candeletemessagesforallusers;
226 $messageids[] = $success;
227 } else {
228 // WARNINGS: for backward compatibility we return this errormessage.
229 // We should have thrown exceptions as these errors prevent results to be returned.
230 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
231 $resultmsg['msgid'] = -1;
232 if (!isset($errormessage)) { // Nobody has set a message error or thrown an exception, let's set it.
233 $errormessage = get_string('messageundeliveredbynotificationsettings', 'error');
235 $resultmsg['errormessage'] = $errormessage;
238 $resultmessages[] = $resultmsg;
241 if (!empty($messageids)) {
242 $messagerecords = $DB->get_records_list(
243 'messages',
244 'id',
245 $messageids,
247 'id, conversationid, smallmessage, fullmessageformat, fullmessagetrust');
248 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) {
249 $id = $resultmessage['msgid'];
250 $resultmessage['conversationid'] = isset($messagerecords[$id]) ? $messagerecords[$id]->conversationid : null;
251 $resultmessage['useridfrom'] = $USER->id;
252 $resultmessage['text'] = message_format_message_text((object) [
253 'smallmessage' => $messagerecords[$id]->smallmessage,
254 'fullmessageformat' => external_validate_format($messagerecords[$id]->fullmessageformat),
255 'fullmessagetrust' => $messagerecords[$id]->fullmessagetrust
257 return $resultmessage;
258 }, $resultmessages);
261 return $resultmessages;
265 * Returns description of method result value
267 * @return external_description
268 * @since Moodle 2.2
270 public static function send_instant_messages_returns() {
271 return new external_multiple_structure(
272 new external_single_structure(
273 array(
274 'msgid' => new external_value(PARAM_INT, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
275 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
276 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL),
277 'text' => new external_value(PARAM_RAW, 'The text of the message', VALUE_OPTIONAL),
278 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message', VALUE_OPTIONAL),
279 'conversationid' => new external_value(PARAM_INT, 'The conversation id for this message', VALUE_OPTIONAL),
280 'useridfrom' => new external_value(PARAM_INT, 'The user id who sent the message', VALUE_OPTIONAL),
281 'candeletemessagesforallusers' => new external_value(PARAM_BOOL,
282 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false),
289 * Create contacts parameters description.
291 * @deprecated since Moodle 3.6
292 * @return external_function_parameters
293 * @since Moodle 2.5
295 public static function create_contacts_parameters() {
296 return new external_function_parameters(
297 array(
298 'userids' => new external_multiple_structure(
299 new external_value(PARAM_INT, 'User ID'),
300 'List of user IDs'
302 'userid' => new external_value(PARAM_INT, 'The id of the user we are creating the contacts for, 0 for the
303 current user', VALUE_DEFAULT, 0)
309 * Create contacts.
311 * @deprecated since Moodle 3.6
312 * @param array $userids array of user IDs.
313 * @param int $userid The id of the user we are creating the contacts for
314 * @return external_description
315 * @since Moodle 2.5
317 public static function create_contacts($userids, $userid = 0) {
318 global $CFG, $USER;
320 // Check if messaging is enabled.
321 if (empty($CFG->messaging)) {
322 throw new moodle_exception('disabled', 'message');
325 if (empty($userid)) {
326 $userid = $USER->id;
329 // Validate context.
330 $context = context_system::instance();
331 self::validate_context($context);
333 $params = array('userids' => $userids, 'userid' => $userid);
334 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
336 $capability = 'moodle/site:manageallmessaging';
337 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
338 throw new required_capability_exception($context, $capability, 'nopermissions', '');
341 $warnings = array();
342 foreach ($params['userids'] as $id) {
343 if (!message_add_contact($id, 0, $params['userid'])) {
344 $warnings[] = array(
345 'item' => 'user',
346 'itemid' => $id,
347 'warningcode' => 'contactnotcreated',
348 'message' => 'The contact could not be created'
352 return $warnings;
356 * Create contacts return description.
358 * @deprecated since Moodle 3.6
359 * @return external_description
360 * @since Moodle 2.5
362 public static function create_contacts_returns() {
363 return new external_warnings();
367 * Marking the method as deprecated.
369 * @return bool
371 public static function create_contacts_is_deprecated() {
372 return true;
376 * Delete contacts parameters description.
378 * @return external_function_parameters
379 * @since Moodle 2.5
381 public static function delete_contacts_parameters() {
382 return new external_function_parameters(
383 array(
384 'userids' => new external_multiple_structure(
385 new external_value(PARAM_INT, 'User ID'),
386 'List of user IDs'
388 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the
389 current user', VALUE_DEFAULT, 0)
395 * Delete contacts.
397 * @param array $userids array of user IDs.
398 * @param int $userid The id of the user we are deleting the contacts for
399 * @return null
400 * @since Moodle 2.5
402 public static function delete_contacts($userids, $userid = 0) {
403 global $CFG, $USER;
405 // Check if messaging is enabled.
406 if (empty($CFG->messaging)) {
407 throw new moodle_exception('disabled', 'message');
410 if (empty($userid)) {
411 $userid = $USER->id;
414 // Validate context.
415 $context = context_system::instance();
416 self::validate_context($context);
418 $params = array('userids' => $userids, 'userid' => $userid);
419 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
421 $capability = 'moodle/site:manageallmessaging';
422 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
423 throw new required_capability_exception($context, $capability, 'nopermissions', '');
426 foreach ($params['userids'] as $id) {
427 \core_message\api::remove_contact($params['userid'], $id);
430 return null;
434 * Delete contacts return description.
436 * @return external_description
437 * @since Moodle 2.5
439 public static function delete_contacts_returns() {
440 return null;
444 * Mute conversations parameters description.
446 * @return external_function_parameters
448 public static function mute_conversations_parameters() {
449 return new external_function_parameters(
451 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
452 'conversationids' => new external_multiple_structure(
453 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED)
460 * Mutes conversations.
462 * @param int $userid The id of the user who is blocking
463 * @param array $conversationids The list of conversations being muted
464 * @return external_description
466 public static function mute_conversations(int $userid, array $conversationids) {
467 global $CFG, $USER;
469 // Check if messaging is enabled.
470 if (empty($CFG->messaging)) {
471 throw new moodle_exception('disabled', 'message');
474 // Validate context.
475 $context = context_system::instance();
476 self::validate_context($context);
478 $params = ['userid' => $userid, 'conversationids' => $conversationids];
479 $params = self::validate_parameters(self::mute_conversations_parameters(), $params);
481 $capability = 'moodle/site:manageallmessaging';
482 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
483 throw new required_capability_exception($context, $capability, 'nopermissions', '');
486 foreach ($params['conversationids'] as $conversationid) {
487 if (!\core_message\api::is_conversation_muted($params['userid'], $conversationid)) {
488 \core_message\api::mute_conversation($params['userid'], $conversationid);
492 return [];
496 * Mute conversations return description.
498 * @return external_description
500 public static function mute_conversations_returns() {
501 return new external_warnings();
505 * Unmute conversations parameters description.
507 * @return external_function_parameters
509 public static function unmute_conversations_parameters() {
510 return new external_function_parameters(
512 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
513 'conversationids' => new external_multiple_structure(
514 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED)
521 * Unmute conversations.
523 * @param int $userid The id of the user who is unblocking
524 * @param array $conversationids The list of conversations being muted
526 public static function unmute_conversations(int $userid, array $conversationids) {
527 global $CFG, $USER;
529 // Check if messaging is enabled.
530 if (empty($CFG->messaging)) {
531 throw new moodle_exception('disabled', 'message');
534 // Validate context.
535 $context = context_system::instance();
536 self::validate_context($context);
538 $params = ['userid' => $userid, 'conversationids' => $conversationids];
539 $params = self::validate_parameters(self::unmute_conversations_parameters(), $params);
541 $capability = 'moodle/site:manageallmessaging';
542 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
543 throw new required_capability_exception($context, $capability, 'nopermissions', '');
546 foreach ($params['conversationids'] as $conversationid) {
547 \core_message\api::unmute_conversation($params['userid'], $conversationid);
550 return [];
554 * Unmute conversations return description.
556 * @return external_description
558 public static function unmute_conversations_returns() {
559 return new external_warnings();
563 * Block user parameters description.
565 * @return external_function_parameters
567 public static function block_user_parameters() {
568 return new external_function_parameters(
570 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'),
571 'blockeduserid' => new external_value(PARAM_INT, 'The id of the user being blocked'),
577 * Blocks a user.
579 * @param int $userid The id of the user who is blocking
580 * @param int $blockeduserid The id of the user being blocked
581 * @return external_description
583 public static function block_user(int $userid, int $blockeduserid) {
584 global $CFG, $USER;
586 // Check if messaging is enabled.
587 if (empty($CFG->messaging)) {
588 throw new moodle_exception('disabled', 'message');
591 // Validate context.
592 $context = context_system::instance();
593 self::validate_context($context);
595 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
596 $params = self::validate_parameters(self::block_user_parameters(), $params);
598 $capability = 'moodle/site:manageallmessaging';
599 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
600 throw new required_capability_exception($context, $capability, 'nopermissions', '');
603 // If the blocking is going to be useless then don't do it.
604 if (\core_message\api::can_send_message($userid, $blockeduserid, true)) {
605 return [];
608 if (!\core_message\api::is_blocked($params['userid'], $params['blockeduserid'])) {
609 \core_message\api::block_user($params['userid'], $params['blockeduserid']);
612 return [];
616 * Block user return description.
618 * @return external_description
620 public static function block_user_returns() {
621 return new external_warnings();
625 * Unblock user parameters description.
627 * @return external_function_parameters
629 public static function unblock_user_parameters() {
630 return new external_function_parameters(
632 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'),
633 'unblockeduserid' => new external_value(PARAM_INT, 'The id of the user being unblocked'),
639 * Unblock user.
641 * @param int $userid The id of the user who is unblocking
642 * @param int $unblockeduserid The id of the user being unblocked
644 public static function unblock_user(int $userid, int $unblockeduserid) {
645 global $CFG, $USER;
647 // Check if messaging is enabled.
648 if (empty($CFG->messaging)) {
649 throw new moodle_exception('disabled', 'message');
652 // Validate context.
653 $context = context_system::instance();
654 self::validate_context($context);
656 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
657 $params = self::validate_parameters(self::unblock_user_parameters(), $params);
659 $capability = 'moodle/site:manageallmessaging';
660 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
661 throw new required_capability_exception($context, $capability, 'nopermissions', '');
664 \core_message\api::unblock_user($params['userid'], $params['unblockeduserid']);
666 return [];
670 * Unblock user return description.
672 * @return external_description
674 public static function unblock_user_returns() {
675 return new external_warnings();
679 * Block contacts parameters description.
681 * @deprecated since Moodle 3.6
682 * @return external_function_parameters
683 * @since Moodle 2.5
685 public static function block_contacts_parameters() {
686 return new external_function_parameters(
687 array(
688 'userids' => new external_multiple_structure(
689 new external_value(PARAM_INT, 'User ID'),
690 'List of user IDs'
692 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the
693 current user', VALUE_DEFAULT, 0)
699 * Block contacts.
701 * @deprecated since Moodle 3.6
702 * @param array $userids array of user IDs.
703 * @param int $userid The id of the user we are blocking the contacts for
704 * @return external_description
705 * @since Moodle 2.5
707 public static function block_contacts($userids, $userid = 0) {
708 global $CFG, $USER;
710 // Check if messaging is enabled.
711 if (empty($CFG->messaging)) {
712 throw new moodle_exception('disabled', 'message');
715 if (empty($userid)) {
716 $userid = $USER->id;
719 // Validate context.
720 $context = context_system::instance();
721 self::validate_context($context);
723 $params = array('userids' => $userids, 'userid' => $userid);
724 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
726 $capability = 'moodle/site:manageallmessaging';
727 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
728 throw new required_capability_exception($context, $capability, 'nopermissions', '');
731 $warnings = array();
732 foreach ($params['userids'] as $id) {
733 if (!message_block_contact($id, $params['userid'])) {
734 $warnings[] = array(
735 'item' => 'user',
736 'itemid' => $id,
737 'warningcode' => 'contactnotblocked',
738 'message' => 'The contact could not be blocked'
742 return $warnings;
746 * Block contacts return description.
748 * @deprecated since Moodle 3.6
749 * @return external_description
750 * @since Moodle 2.5
752 public static function block_contacts_returns() {
753 return new external_warnings();
757 * Marking the method as deprecated.
759 * @return bool
761 public static function block_contacts_is_deprecated() {
762 return true;
766 * Unblock contacts parameters description.
768 * @deprecated since Moodle 3.6
769 * @return external_function_parameters
770 * @since Moodle 2.5
772 public static function unblock_contacts_parameters() {
773 return new external_function_parameters(
774 array(
775 'userids' => new external_multiple_structure(
776 new external_value(PARAM_INT, 'User ID'),
777 'List of user IDs'
779 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the
780 current user', VALUE_DEFAULT, 0)
786 * Unblock contacts.
788 * @param array $userids array of user IDs.
789 * @param int $userid The id of the user we are unblocking the contacts for
790 * @return null
791 * @since Moodle 2.5
793 public static function unblock_contacts($userids, $userid = 0) {
794 global $CFG, $USER;
796 // Check if messaging is enabled.
797 if (empty($CFG->messaging)) {
798 throw new moodle_exception('disabled', 'message');
801 if (empty($userid)) {
802 $userid = $USER->id;
805 // Validate context.
806 $context = context_system::instance();
807 self::validate_context($context);
809 $params = array('userids' => $userids, 'userid' => $userid);
810 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
812 $capability = 'moodle/site:manageallmessaging';
813 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
814 throw new required_capability_exception($context, $capability, 'nopermissions', '');
817 foreach ($params['userids'] as $id) {
818 message_unblock_contact($id, $params['userid']);
821 return null;
825 * Unblock contacts return description.
827 * @deprecated since Moodle 3.6
828 * @return external_description
829 * @since Moodle 2.5
831 public static function unblock_contacts_returns() {
832 return null;
836 * Marking the method as deprecated.
838 * @return bool
840 public static function unblock_contacts_is_deprecated() {
841 return true;
845 * Returns contact requests parameters description.
847 * @return external_function_parameters
849 public static function get_contact_requests_parameters() {
850 return new external_function_parameters(
852 'userid' => new external_value(PARAM_INT, 'The id of the user we want the requests for'),
853 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
854 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
860 * Handles returning the contact requests for a user.
862 * This also includes the user data necessary to display information
863 * about the user.
865 * It will not include blocked users.
867 * @param int $userid The id of the user we want to get the contact requests for
868 * @param int $limitfrom
869 * @param int $limitnum
871 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) {
872 global $CFG, $USER;
874 // Check if messaging is enabled.
875 if (empty($CFG->messaging)) {
876 throw new moodle_exception('disabled', 'message');
879 // Validate context.
880 $context = context_system::instance();
881 self::validate_context($context);
883 $params = [
884 'userid' => $userid,
885 'limitfrom' => $limitfrom,
886 'limitnum' => $limitnum
888 $params = self::validate_parameters(self::get_contact_requests_parameters(), $params);
890 $capability = 'moodle/site:manageallmessaging';
891 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
892 throw new required_capability_exception($context, $capability, 'nopermissions', '');
895 return \core_message\api::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']);
899 * Returns the contact requests return description.
901 * @return external_description
903 public static function get_contact_requests_returns() {
904 return new external_multiple_structure(
905 self::get_conversation_member_structure()
910 * Returns the number of contact requests the user has received parameters description.
912 * @return external_function_parameters
914 public static function get_received_contact_requests_count_parameters() {
915 return new external_function_parameters(
916 array(
917 'userid' => new external_value(PARAM_INT, 'The id of the user we want to return the number of ' .
918 'received contact requests for', VALUE_REQUIRED),
924 * Returns the number of contact requests the user has received.
926 * @param int $userid The ID of the user we want to return the number of received contact requests for
927 * @return external_value
929 public static function get_received_contact_requests_count(int $userid) {
930 global $CFG, $USER;
932 // Check if messaging is enabled.
933 if (empty($CFG->messaging)) {
934 throw new moodle_exception('disabled', 'message');
937 // Validate context.
938 $context = context_system::instance();
939 self::validate_context($context);
941 $params = [
942 'userid' => $userid,
944 $params = self::validate_parameters(self::get_received_contact_requests_count_parameters(), $params);
946 $capability = 'moodle/site:manageallmessaging';
947 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
948 throw new required_capability_exception($context, $capability, 'nopermissions', '');
951 return \core_message\api::get_received_contact_requests_count($params['userid']);
955 * Returns the number of contact requests the user has received return description.
957 * @return external_value
959 public static function get_received_contact_requests_count_returns() {
960 return new external_value(PARAM_INT, 'The number of received contact requests');
964 * Returns get conversation members parameters description.
966 * @return external_function_parameters
968 public static function get_conversation_members_parameters() {
969 return new external_function_parameters(
971 'userid' => new external_value(PARAM_INT, 'The id of the user we are performing this action on behalf of'),
972 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation'),
973 'includecontactrequests' => new external_value(PARAM_BOOL, 'Do we want to include contact requests?',
974 VALUE_DEFAULT, false),
975 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Do we want to include privacy info?',
976 VALUE_DEFAULT, false),
977 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
978 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
984 * Returns a list of conversation members.
986 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
987 * @param int $conversationid The id of the conversation
988 * @param bool $includecontactrequests Do we want to include contact requests with this data?
989 * @param bool $includeprivacyinfo Do we want to include privacy info?
990 * @param int $limitfrom
991 * @param int $limitnum
992 * @return array
994 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
995 bool $includeprivacyinfo = false, int $limitfrom = 0, int $limitnum = 0) {
996 global $CFG, $USER;
998 // Check if messaging is enabled.
999 if (empty($CFG->messaging)) {
1000 throw new moodle_exception('disabled', 'message');
1003 // Validate context.
1004 $context = context_system::instance();
1005 self::validate_context($context);
1007 $params = [
1008 'userid' => $userid,
1009 'conversationid' => $conversationid,
1010 'includecontactrequests' => $includecontactrequests,
1011 'includeprivacyinfo' => $includeprivacyinfo,
1012 'limitfrom' => $limitfrom,
1013 'limitnum' => $limitnum
1015 $params = self::validate_parameters(self::get_conversation_members_parameters(), $params);
1017 $capability = 'moodle/site:manageallmessaging';
1018 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
1019 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1022 // The user needs to be a part of the conversation before querying who the members are.
1023 if (!\core_message\api::is_user_in_conversation($params['userid'], $params['conversationid'])) {
1024 throw new moodle_exception('You are not a member of this conversation.');
1027 return \core_message\api::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'],
1028 $params['includeprivacyinfo'], $params['limitfrom'], $params['limitnum']);
1032 * Returns the get conversation members return description.
1034 * @return external_description
1036 public static function get_conversation_members_returns() {
1037 return new external_multiple_structure(
1038 self::get_conversation_member_structure()
1043 * Creates a contact request parameters description.
1045 * @return external_function_parameters
1047 public static function create_contact_request_parameters() {
1048 return new external_function_parameters(
1050 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1051 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1057 * Creates a contact request.
1059 * @param int $userid The id of the user who is creating the contact request
1060 * @param int $requesteduserid The id of the user being requested
1062 public static function create_contact_request(int $userid, int $requesteduserid) {
1063 global $CFG, $USER;
1065 // Check if messaging is enabled.
1066 if (empty($CFG->messaging)) {
1067 throw new moodle_exception('disabled', 'message');
1070 // Validate context.
1071 $context = context_system::instance();
1072 self::validate_context($context);
1074 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1075 $params = self::validate_parameters(self::create_contact_request_parameters(), $params);
1077 $capability = 'moodle/site:manageallmessaging';
1078 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) {
1079 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1082 $result = [
1083 'warnings' => []
1086 if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) {
1087 $result['warnings'][] = [
1088 'item' => 'user',
1089 'itemid' => $params['requesteduserid'],
1090 'warningcode' => 'cannotcreatecontactrequest',
1091 'message' => 'You are unable to create a contact request for this user'
1093 } else {
1094 if ($requests = \core_message\api::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) {
1095 // There should only ever be one but just in case there are multiple then we can return the first.
1096 $result['request'] = array_shift($requests);
1097 } else {
1098 $result['request'] = \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']);
1102 return $result;
1106 * Creates a contact request return description.
1108 * @return external_description
1110 public static function create_contact_request_returns() {
1111 return new external_single_structure(
1112 array(
1113 'request' => new external_single_structure(
1114 array(
1115 'id' => new external_value(PARAM_INT, 'Message id'),
1116 'userid' => new external_value(PARAM_INT, 'User from id'),
1117 'requesteduserid' => new external_value(PARAM_INT, 'User to id'),
1118 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1120 'request record',
1121 VALUE_OPTIONAL
1123 'warnings' => new external_warnings()
1129 * Confirm a contact request parameters description.
1131 * @return external_function_parameters
1133 public static function confirm_contact_request_parameters() {
1134 return new external_function_parameters(
1136 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1137 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1143 * Confirm a contact request.
1145 * @param int $userid The id of the user who is creating the contact request
1146 * @param int $requesteduserid The id of the user being requested
1148 public static function confirm_contact_request(int $userid, int $requesteduserid) {
1149 global $CFG, $USER;
1151 // Check if messaging is enabled.
1152 if (empty($CFG->messaging)) {
1153 throw new moodle_exception('disabled', 'message');
1156 // Validate context.
1157 $context = context_system::instance();
1158 self::validate_context($context);
1160 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1161 $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params);
1163 $capability = 'moodle/site:manageallmessaging';
1164 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) {
1165 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1168 \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']);
1170 return [];
1174 * Confirm a contact request return description.
1176 * @return external_description
1178 public static function confirm_contact_request_returns() {
1179 return new external_warnings();
1183 * Declines a contact request parameters description.
1185 * @return external_function_parameters
1187 public static function decline_contact_request_parameters() {
1188 return new external_function_parameters(
1190 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'),
1191 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested')
1197 * Declines a contact request.
1199 * @param int $userid The id of the user who is creating the contact request
1200 * @param int $requesteduserid The id of the user being requested
1202 public static function decline_contact_request(int $userid, int $requesteduserid) {
1203 global $CFG, $USER;
1205 // Check if messaging is enabled.
1206 if (empty($CFG->messaging)) {
1207 throw new moodle_exception('disabled', 'message');
1210 // Validate context.
1211 $context = context_system::instance();
1212 self::validate_context($context);
1214 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
1215 $params = self::validate_parameters(self::decline_contact_request_parameters(), $params);
1217 $capability = 'moodle/site:manageallmessaging';
1218 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) {
1219 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1222 \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']);
1224 return [];
1228 * Declines a contact request return description.
1230 * @return external_description
1232 public static function decline_contact_request_returns() {
1233 return new external_warnings();
1237 * Return the structure of a message area contact.
1239 * @return external_single_structure
1240 * @since Moodle 3.2
1242 private static function get_messagearea_contact_structure() {
1243 return new external_single_structure(
1244 array(
1245 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
1246 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1247 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1248 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1249 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
1250 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'),
1251 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'),
1252 'lastmessagedate' => new external_value(PARAM_INT, 'Timestamp for last message', VALUE_DEFAULT, null),
1253 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null),
1254 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1255 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1256 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
1257 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
1258 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1259 VALUE_DEFAULT, null),
1260 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation', VALUE_DEFAULT, null),
1266 * Return the structure of a conversation.
1268 * @return external_single_structure
1269 * @since Moodle 3.6
1271 private static function get_conversation_structure() {
1272 return new external_single_structure(
1273 array(
1274 'id' => new external_value(PARAM_INT, 'The conversation id'),
1275 'name' => new external_value(PARAM_RAW, 'The conversation name, if set', VALUE_DEFAULT, null),
1276 'subname' => new external_value(PARAM_RAW, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null),
1277 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null),
1278 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group,3=self)'),
1279 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'),
1280 'ismuted' => new external_value(PARAM_BOOL, 'If the user muted this conversation'),
1281 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked this conversation as a favourite'),
1282 'isread' => new external_value(PARAM_BOOL, 'If the user has read all messages in the conversation'),
1283 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
1284 VALUE_DEFAULT, null),
1285 'members' => new external_multiple_structure(
1286 self::get_conversation_member_structure()
1288 'messages' => new external_multiple_structure(
1289 self::get_conversation_message_structure()
1291 'candeletemessagesforallusers' => new external_value(PARAM_BOOL,
1292 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false),
1298 * Return the structure of a conversation member.
1300 * @return external_single_structure
1301 * @since Moodle 3.6
1303 private static function get_conversation_member_structure() {
1304 $result = [
1305 'id' => new external_value(PARAM_INT, 'The user id'),
1306 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1307 'profileurl' => new external_value(PARAM_URL, 'The link to the user\'s profile page'),
1308 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1309 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1310 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1311 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
1312 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
1313 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?'),
1314 'isdeleted' => new external_value(PARAM_BOOL, 'Is the user deleted?'),
1315 'canmessageevenifblocked' => new external_value(PARAM_BOOL,
1316 'If the user can still message even if they get blocked'),
1317 'canmessage' => new external_value(PARAM_BOOL, 'If the user can be messaged'),
1318 'requirescontact' => new external_value(PARAM_BOOL, 'If the user requires to be contacts'),
1321 $result['contactrequests'] = new external_multiple_structure(
1322 new external_single_structure(
1324 'id' => new external_value(PARAM_INT, 'The id of the contact request'),
1325 'userid' => new external_value(PARAM_INT, 'The id of the user who created the contact request'),
1326 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user confirming the request'),
1327 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the contact request'),
1329 ), 'The contact requests', VALUE_OPTIONAL
1332 $result['conversations'] = new external_multiple_structure(new external_single_structure(
1333 array(
1334 'id' => new external_value(PARAM_INT, 'Conversations id'),
1335 'type' => new external_value(PARAM_INT, 'Conversation type: private or public'),
1336 'name' => new external_value(PARAM_RAW, 'Multilang compatible conversation name'. VALUE_OPTIONAL),
1337 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the conversation'),
1338 ), 'information about conversation', VALUE_OPTIONAL),
1339 'Conversations between users', VALUE_OPTIONAL
1342 return new external_single_structure(
1343 $result
1348 * Return the structure of a message area message.
1350 * @return external_single_structure
1351 * @since Moodle 3.6
1353 private static function get_conversation_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 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1359 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1365 * Return the structure of a message area message.
1367 * @return external_single_structure
1368 * @since Moodle 3.2
1370 private static function get_messagearea_message_structure() {
1371 return new external_single_structure(
1372 array(
1373 'id' => new external_value(PARAM_INT, 'The id of the message'),
1374 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
1375 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
1376 'text' => new external_value(PARAM_RAW, 'The text of the message'),
1377 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
1378 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
1379 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
1380 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
1381 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'),
1382 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
1388 * Get messagearea search users in course parameters.
1390 * @deprecated since 3.6
1392 * @return external_function_parameters
1393 * @since 3.2
1395 public static function data_for_messagearea_search_users_in_course_parameters() {
1396 return new external_function_parameters(
1397 array(
1398 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1399 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
1400 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1401 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1402 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1408 * Get messagearea search users in course results.
1410 * @deprecated since 3.6
1412 * @param int $userid The id of the user who is performing the search
1413 * @param int $courseid The id of the course
1414 * @param string $search The string being searched
1415 * @param int $limitfrom
1416 * @param int $limitnum
1417 * @return stdClass
1418 * @throws moodle_exception
1419 * @since 3.2
1421 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
1422 $limitnum = 0) {
1423 global $CFG, $PAGE, $USER;
1425 // Check if messaging is enabled.
1426 if (empty($CFG->messaging)) {
1427 throw new moodle_exception('disabled', 'message');
1430 $systemcontext = context_system::instance();
1432 $params = array(
1433 'userid' => $userid,
1434 'courseid' => $courseid,
1435 'search' => $search,
1436 'limitfrom' => $limitfrom,
1437 'limitnum' => $limitnum
1439 $params = self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
1440 self::validate_context($systemcontext);
1442 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1443 throw new moodle_exception('You do not have permission to perform this action.');
1446 $users = \core_message\api::search_users_in_course(
1447 $params['userid'],
1448 $params['courseid'],
1449 $params['search'],
1450 $params['limitfrom'],
1451 $params['limitnum']
1453 $results = new \core_message\output\messagearea\user_search_results($users);
1455 $renderer = $PAGE->get_renderer('core_message');
1456 return $results->export_for_template($renderer);
1460 * Get messagearea search users in course returns.
1462 * @deprecated since 3.6
1464 * @return external_single_structure
1465 * @since 3.2
1467 public static function data_for_messagearea_search_users_in_course_returns() {
1468 return new external_single_structure(
1469 array(
1470 'contacts' => new external_multiple_structure(
1471 self::get_messagearea_contact_structure()
1478 * Marking the method as deprecated.
1480 * @return bool
1482 public static function data_for_messagearea_search_users_in_course_is_deprecated() {
1483 return true;
1487 * Get messagearea search users parameters.
1489 * @deprecated since 3.6
1491 * @return external_function_parameters
1492 * @since 3.2
1494 public static function data_for_messagearea_search_users_parameters() {
1495 return new external_function_parameters(
1496 array(
1497 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1498 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1499 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1505 * Get messagearea search users results.
1507 * @deprecated since 3.6
1509 * @param int $userid The id of the user who is performing the search
1510 * @param string $search The string being searched
1511 * @param int $limitnum
1512 * @return stdClass
1513 * @throws moodle_exception
1514 * @since 3.2
1516 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
1517 global $CFG, $PAGE, $USER;
1519 // Check if messaging is enabled.
1520 if (empty($CFG->messaging)) {
1521 throw new moodle_exception('disabled', 'message');
1524 $systemcontext = context_system::instance();
1526 $params = array(
1527 'userid' => $userid,
1528 'search' => $search,
1529 'limitnum' => $limitnum
1531 $params = self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
1532 self::validate_context($systemcontext);
1534 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1535 throw new moodle_exception('You do not have permission to perform this action.');
1538 list($contacts, $courses, $noncontacts) = \core_message\api::search_users(
1539 $params['userid'],
1540 $params['search'],
1541 $params['limitnum']
1544 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
1546 $renderer = $PAGE->get_renderer('core_message');
1547 return $search->export_for_template($renderer);
1551 * Get messagearea search users returns.
1553 * @deprecated since 3.6
1555 * @return external_single_structure
1556 * @since 3.2
1558 public static function data_for_messagearea_search_users_returns() {
1559 return new external_single_structure(
1560 array(
1561 'contacts' => new external_multiple_structure(
1562 self::get_messagearea_contact_structure()
1564 'courses' => new external_multiple_structure(
1565 new external_single_structure(
1566 array(
1567 'id' => new external_value(PARAM_INT, 'The course id'),
1568 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'),
1569 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'),
1573 'noncontacts' => new external_multiple_structure(
1574 self::get_messagearea_contact_structure()
1581 * Marking the method as deprecated.
1583 * @return bool
1585 public static function data_for_messagearea_search_users_is_deprecated() {
1586 return true;
1590 * Get messagearea message search users parameters.
1592 * @return external_function_parameters
1593 * @since 3.6
1595 public static function message_search_users_parameters() {
1596 return new external_function_parameters(
1597 array(
1598 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1599 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1600 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1601 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
1607 * Get search users results.
1609 * @param int $userid The id of the user who is performing the search
1610 * @param string $search The string being searched
1611 * @param int $limitfrom
1612 * @param int $limitnum
1613 * @return array
1614 * @throws moodle_exception
1615 * @since 3.6
1617 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) {
1618 global $USER;
1620 $systemcontext = context_system::instance();
1622 $params = array(
1623 'userid' => $userid,
1624 'search' => $search,
1625 'limitfrom' => $limitfrom,
1626 'limitnum' => $limitnum
1628 $params = self::validate_parameters(self::message_search_users_parameters(), $params);
1629 self::validate_context($systemcontext);
1631 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1632 throw new moodle_exception('You do not have permission to perform this action.');
1635 list($contacts, $noncontacts) = \core_message\api::message_search_users(
1636 $params['userid'],
1637 $params['search'],
1638 $params['limitfrom'],
1639 $params['limitnum']);
1641 return array('contacts' => $contacts, 'noncontacts' => $noncontacts);
1645 * Get messagearea message search users returns.
1647 * @return external_single_structure
1648 * @since 3.2
1650 public static function message_search_users_returns() {
1651 return new external_single_structure(
1652 array(
1653 'contacts' => new external_multiple_structure(
1654 self::get_conversation_member_structure()
1656 'noncontacts' => new external_multiple_structure(
1657 self::get_conversation_member_structure()
1664 * Get messagearea search messages parameters.
1666 * @return external_function_parameters
1667 * @since 3.2
1669 public static function data_for_messagearea_search_messages_parameters() {
1670 return new external_function_parameters(
1671 array(
1672 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
1673 'search' => new external_value(PARAM_RAW, 'The string being searched'),
1674 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
1675 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
1681 * Get messagearea search messages results.
1683 * @param int $userid The id of the user who is performing the search
1684 * @param string $search The string being searched
1685 * @param int $limitfrom
1686 * @param int $limitnum
1687 * @return stdClass
1688 * @throws moodle_exception
1689 * @since 3.2
1691 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1692 global $CFG, $USER;
1694 // Check if messaging is enabled.
1695 if (empty($CFG->messaging)) {
1696 throw new moodle_exception('disabled', 'message');
1699 $systemcontext = context_system::instance();
1701 $params = array(
1702 'userid' => $userid,
1703 'search' => $search,
1704 'limitfrom' => $limitfrom,
1705 'limitnum' => $limitnum
1708 $params = self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
1709 self::validate_context($systemcontext);
1711 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1712 throw new moodle_exception('You do not have permission to perform this action.');
1715 $messages = \core_message\api::search_messages(
1716 $params['userid'],
1717 $params['search'],
1718 $params['limitfrom'],
1719 $params['limitnum']
1722 $data = new \stdClass();
1723 $data->contacts = [];
1724 foreach ($messages as $message) {
1725 $contact = new \stdClass();
1726 $contact->userid = $message->userid;
1727 $contact->fullname = $message->fullname;
1728 $contact->profileimageurl = $message->profileimageurl;
1729 $contact->profileimageurlsmall = $message->profileimageurlsmall;
1730 $contact->messageid = $message->messageid;
1731 $contact->ismessaging = $message->ismessaging;
1732 $contact->sentfromcurrentuser = false;
1733 if ($message->lastmessage) {
1734 if ($message->userid !== $message->useridfrom) {
1735 $contact->sentfromcurrentuser = true;
1737 $contact->lastmessage = shorten_text($message->lastmessage, 60);
1738 } else {
1739 $contact->lastmessage = null;
1741 $contact->lastmessagedate = $message->lastmessagedate;
1742 $contact->showonlinestatus = is_null($message->isonline) ? false : true;
1743 $contact->isonline = $message->isonline;
1744 $contact->isblocked = $message->isblocked;
1745 $contact->isread = $message->isread;
1746 $contact->unreadcount = $message->unreadcount;
1747 $contact->conversationid = $message->conversationid;
1749 $data->contacts[] = $contact;
1752 return $data;
1756 * Get messagearea search messages returns.
1758 * @return external_single_structure
1759 * @since 3.2
1761 public static function data_for_messagearea_search_messages_returns() {
1762 return new external_single_structure(
1763 array(
1764 'contacts' => new external_multiple_structure(
1765 self::get_messagearea_contact_structure()
1772 * Get conversations parameters.
1774 * @return external_function_parameters
1775 * @since 3.6
1777 public static function get_conversations_parameters() {
1778 return new external_function_parameters(
1779 array(
1780 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1781 'limitfrom' => new external_value(PARAM_INT, 'The offset to start at', VALUE_DEFAULT, 0),
1782 'limitnum' => new external_value(PARAM_INT, 'Limit number of conversations to this', VALUE_DEFAULT, 0),
1783 'type' => new external_value(PARAM_INT, 'Filter by type', VALUE_DEFAULT, null),
1784 'favourites' => new external_value(PARAM_BOOL, 'Whether to restrict the results to contain NO favourite
1785 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1786 VALUE_DEFAULT, null),
1787 'mergeself' => new external_value(PARAM_BOOL, 'Whether to include self-conversations (true) or ONLY private
1788 conversations (false) when private conversations are requested.',
1789 VALUE_DEFAULT, false),
1795 * Get the list of conversations for the user.
1797 * @param int $userid The id of the user who is performing the search
1798 * @param int $limitfrom
1799 * @param int $limitnum
1800 * @param int|null $type
1801 * @param bool|null $favourites
1802 * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false)
1803 * when private conversations are requested.
1804 * @return stdClass
1805 * @throws \moodle_exception if the messaging feature is disabled on the site.
1806 * @since 3.2
1808 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null,
1809 bool $mergeself = false) {
1810 global $CFG, $USER;
1812 // All the standard BL checks.
1813 if (empty($CFG->messaging)) {
1814 throw new moodle_exception('disabled', 'message');
1817 $params = array(
1818 'userid' => $userid,
1819 'limitfrom' => $limitfrom,
1820 'limitnum' => $limitnum,
1821 'type' => $type,
1822 'favourites' => $favourites,
1823 'mergeself' => $mergeself
1825 $params = self::validate_parameters(self::get_conversations_parameters(), $params);
1827 $systemcontext = context_system::instance();
1828 self::validate_context($systemcontext);
1830 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1831 throw new moodle_exception('You do not have permission to perform this action.');
1834 $conversations = \core_message\api::get_conversations(
1835 $params['userid'],
1836 $params['limitfrom'],
1837 $params['limitnum'],
1838 $params['type'],
1839 $params['favourites'],
1840 $params['mergeself']
1843 return (object) ['conversations' => $conversations];
1847 * Get conversations returns.
1849 * @return external_single_structure
1850 * @since 3.6
1852 public static function get_conversations_returns() {
1853 return new external_single_structure(
1855 'conversations' => new external_multiple_structure(
1856 self::get_conversation_structure(true)
1863 * Get conversation parameters.
1865 * @return external_function_parameters
1867 public static function get_conversation_parameters() {
1868 return new external_function_parameters(
1869 array(
1870 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1871 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation to fetch'),
1872 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1873 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1874 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1875 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1876 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1877 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1878 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1884 * Get a single conversation.
1886 * @param int $userid The user id to get the conversation for
1887 * @param int $conversationid The id of the conversation to fetch
1888 * @param bool $includecontactrequests Should contact requests be included between members
1889 * @param bool $includeprivacyinfo Should privacy info be included between members
1890 * @param int $memberlimit Limit number of members to load
1891 * @param int $memberoffset Offset members by this amount
1892 * @param int $messagelimit Limit number of messages to load
1893 * @param int $messageoffset Offset the messages
1894 * @param bool $newestmessagesfirst Order messages by newest first
1895 * @return stdClass
1896 * @throws \moodle_exception if the messaging feature is disabled on the site.
1898 public static function get_conversation(
1899 int $userid,
1900 int $conversationid,
1901 bool $includecontactrequests = false,
1902 bool $includeprivacyinfo = false,
1903 int $memberlimit = 0,
1904 int $memberoffset = 0,
1905 int $messagelimit = 0,
1906 int $messageoffset = 0,
1907 bool $newestmessagesfirst = true
1909 global $CFG, $DB, $USER;
1911 // All the standard BL checks.
1912 if (empty($CFG->messaging)) {
1913 throw new moodle_exception('disabled', 'message');
1916 $params = [
1917 'userid' => $userid,
1918 'conversationid' => $conversationid,
1919 'includecontactrequests' => $includecontactrequests,
1920 'includeprivacyinfo' => $includeprivacyinfo,
1921 'memberlimit' => $memberlimit,
1922 'memberoffset' => $memberoffset,
1923 'messagelimit' => $messagelimit,
1924 'messageoffset' => $messageoffset,
1925 'newestmessagesfirst' => $newestmessagesfirst
1927 self::validate_parameters(self::get_conversation_parameters(), $params);
1929 $systemcontext = context_system::instance();
1930 self::validate_context($systemcontext);
1932 $conversation = \core_message\api::get_conversation(
1933 $params['userid'],
1934 $params['conversationid'],
1935 $params['includecontactrequests'],
1936 $params['includeprivacyinfo'],
1937 $params['memberlimit'],
1938 $params['memberoffset'],
1939 $params['messagelimit'],
1940 $params['messageoffset'],
1941 $params['newestmessagesfirst']
1944 if ($conversation) {
1945 return $conversation;
1946 } else {
1947 // We have to throw an exception here because the external functions annoyingly
1948 // don't accept null to be returned for a single structure.
1949 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
1954 * Get conversation returns.
1956 * @return external_single_structure
1958 public static function get_conversation_returns() {
1959 return self::get_conversation_structure();
1963 * Get conversation parameters.
1965 * @return external_function_parameters
1967 public static function get_conversation_between_users_parameters() {
1968 return new external_function_parameters(
1969 array(
1970 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
1971 'otheruserid' => new external_value(PARAM_INT, 'The other user id'),
1972 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'),
1973 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'),
1974 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0),
1975 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0),
1976 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
1977 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
1978 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
1984 * Get a single conversation between users.
1986 * @param int $userid The user id to get the conversation for
1987 * @param int $otheruserid The other user id
1988 * @param bool $includecontactrequests Should contact requests be included between members
1989 * @param bool $includeprivacyinfo Should privacy info be included between members
1990 * @param int $memberlimit Limit number of members to load
1991 * @param int $memberoffset Offset members by this amount
1992 * @param int $messagelimit Limit number of messages to load
1993 * @param int $messageoffset Offset the messages
1994 * @param bool $newestmessagesfirst Order messages by newest first
1995 * @return stdClass
1996 * @throws \moodle_exception if the messaging feature is disabled on the site.
1998 public static function get_conversation_between_users(
1999 int $userid,
2000 int $otheruserid,
2001 bool $includecontactrequests = false,
2002 bool $includeprivacyinfo = false,
2003 int $memberlimit = 0,
2004 int $memberoffset = 0,
2005 int $messagelimit = 0,
2006 int $messageoffset = 0,
2007 bool $newestmessagesfirst = true
2009 global $CFG, $DB, $USER;
2011 // All the standard BL checks.
2012 if (empty($CFG->messaging)) {
2013 throw new moodle_exception('disabled', 'message');
2016 $params = [
2017 'userid' => $userid,
2018 'otheruserid' => $otheruserid,
2019 'includecontactrequests' => $includecontactrequests,
2020 'includeprivacyinfo' => $includeprivacyinfo,
2021 'memberlimit' => $memberlimit,
2022 'memberoffset' => $memberoffset,
2023 'messagelimit' => $messagelimit,
2024 'messageoffset' => $messageoffset,
2025 'newestmessagesfirst' => $newestmessagesfirst
2027 self::validate_parameters(self::get_conversation_between_users_parameters(), $params);
2029 $systemcontext = context_system::instance();
2030 self::validate_context($systemcontext);
2032 $conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']]);
2033 $conversation = null;
2035 if ($conversationid) {
2036 $conversation = \core_message\api::get_conversation(
2037 $params['userid'],
2038 $conversationid,
2039 $params['includecontactrequests'],
2040 $params['includeprivacyinfo'],
2041 $params['memberlimit'],
2042 $params['memberoffset'],
2043 $params['messagelimit'],
2044 $params['messageoffset'],
2045 $params['newestmessagesfirst']
2049 if ($conversation) {
2050 return $conversation;
2051 } else {
2052 // We have to throw an exception here because the external functions annoyingly
2053 // don't accept null to be returned for a single structure.
2054 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
2059 * Get conversation returns.
2061 * @return external_single_structure
2063 public static function get_conversation_between_users_returns() {
2064 return self::get_conversation_structure(true);
2068 * Get self-conversation parameters.
2070 * @return external_function_parameters
2072 public static function get_self_conversation_parameters() {
2073 return new external_function_parameters(
2074 array(
2075 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing self-conversations for'),
2076 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100),
2077 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0),
2078 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true)
2084 * Get a single self-conversation.
2086 * @param int $userid The user id to get the self-conversation for
2087 * @param int $messagelimit Limit number of messages to load
2088 * @param int $messageoffset Offset the messages
2089 * @param bool $newestmessagesfirst Order messages by newest first
2090 * @return stdClass
2091 * @throws \moodle_exception if the messaging feature is disabled on the site.
2092 * @since Moodle 3.7
2094 public static function get_self_conversation(
2095 int $userid,
2096 int $messagelimit = 0,
2097 int $messageoffset = 0,
2098 bool $newestmessagesfirst = true
2100 global $CFG;
2102 // All the standard BL checks.
2103 if (empty($CFG->messaging)) {
2104 throw new moodle_exception('disabled', 'message');
2107 $params = [
2108 'userid' => $userid,
2109 'messagelimit' => $messagelimit,
2110 'messageoffset' => $messageoffset,
2111 'newestmessagesfirst' => $newestmessagesfirst
2113 self::validate_parameters(self::get_self_conversation_parameters(), $params);
2115 $systemcontext = context_system::instance();
2116 self::validate_context($systemcontext);
2118 $conversation = \core_message\api::get_self_conversation($params['userid']);
2120 if ($conversation) {
2121 $conversation = \core_message\api::get_conversation(
2122 $params['userid'],
2123 $conversation->id,
2124 false,
2125 false,
2128 $params['messagelimit'],
2129 $params['messageoffset'],
2130 $params['newestmessagesfirst']
2134 if ($conversation) {
2135 return $conversation;
2136 } else {
2137 // We have to throw an exception here because the external functions annoyingly
2138 // don't accept null to be returned for a single structure.
2139 throw new \moodle_exception('errorconversationdoesnotexist', 'message');
2144 * Get conversation returns.
2146 * @return external_single_structure
2148 public static function get_self_conversation_returns() {
2149 return self::get_conversation_structure();
2153 * The messagearea conversations parameters.
2155 * @deprecated since 3.6
2156 * @return external_function_parameters
2157 * @since 3.2
2159 public static function data_for_messagearea_conversations_parameters() {
2160 return new external_function_parameters(
2161 array(
2162 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
2163 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2164 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
2170 * Get messagearea conversations.
2172 * NOTE FOR FINAL DEPRECATION:
2173 * When removing this method, please also consider removal of get_conversations_legacy_formatter()
2174 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data
2175 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be
2176 * removed.
2178 * @deprecated since 3.6
2179 * @param int $userid The id of the user who we are viewing conversations for
2180 * @param int $limitfrom
2181 * @param int $limitnum
2182 * @return stdClass
2183 * @throws moodle_exception
2184 * @since 3.2
2186 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
2187 global $CFG, $PAGE, $USER;
2189 // Check if messaging is enabled.
2190 if (empty($CFG->messaging)) {
2191 throw new moodle_exception('disabled', 'message');
2194 $systemcontext = context_system::instance();
2196 $params = array(
2197 'userid' => $userid,
2198 'limitfrom' => $limitfrom,
2199 'limitnum' => $limitnum
2201 $params = self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
2202 self::validate_context($systemcontext);
2204 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2205 throw new moodle_exception('You do not have permission to perform this action.');
2208 $conversations = \core_message\api::get_conversations($params['userid'], $params['limitfrom'], $params['limitnum']);
2210 // Format the conversations in the legacy style, as the get_conversations method has since been changed.
2211 $conversations = \core_message\helper::get_conversations_legacy_formatter($conversations);
2213 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
2215 $renderer = $PAGE->get_renderer('core_message');
2216 return $conversations->export_for_template($renderer);
2220 * The messagearea conversations return structure.
2222 * @deprecated since 3.6
2223 * @return external_single_structure
2224 * @since 3.2
2226 public static function data_for_messagearea_conversations_returns() {
2227 return new external_single_structure(
2228 array(
2229 'contacts' => new external_multiple_structure(
2230 self::get_messagearea_contact_structure()
2237 * Marking the method as deprecated.
2239 * @return bool
2241 public static function data_for_messagearea_conversations_is_deprecated() {
2242 return true;
2246 * The messagearea contacts return parameters.
2248 * @deprecated since 3.6
2249 * @return external_function_parameters
2250 * @since 3.2
2252 public static function data_for_messagearea_contacts_parameters() {
2253 return self::data_for_messagearea_conversations_parameters();
2257 * Get messagearea contacts parameters.
2259 * @deprecated since 3.6
2260 * @param int $userid The id of the user who we are viewing conversations for
2261 * @param int $limitfrom
2262 * @param int $limitnum
2263 * @return stdClass
2264 * @throws moodle_exception
2265 * @since 3.2
2267 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
2268 global $CFG, $PAGE, $USER;
2270 // Check if messaging is enabled.
2271 if (empty($CFG->messaging)) {
2272 throw new moodle_exception('disabled', 'message');
2275 $systemcontext = context_system::instance();
2277 $params = array(
2278 'userid' => $userid,
2279 'limitfrom' => $limitfrom,
2280 'limitnum' => $limitnum
2282 $params = self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
2283 self::validate_context($systemcontext);
2285 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2286 throw new moodle_exception('You do not have permission to perform this action.');
2289 $contacts = \core_message\api::get_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
2290 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
2292 $renderer = $PAGE->get_renderer('core_message');
2293 return $contacts->export_for_template($renderer);
2297 * The messagearea contacts return structure.
2299 * @deprecated since 3.6
2300 * @return external_single_structure
2301 * @since 3.2
2303 public static function data_for_messagearea_contacts_returns() {
2304 return self::data_for_messagearea_conversations_returns();
2308 * Marking the method as deprecated.
2310 * @return bool
2312 public static function data_for_messagearea_contacts_is_deprecated() {
2313 return true;
2317 * The messagearea messages parameters.
2319 * @deprecated since 3.6
2320 * @return external_function_parameters
2321 * @since 3.2
2323 public static function data_for_messagearea_messages_parameters() {
2324 return new external_function_parameters(
2325 array(
2326 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2327 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2328 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2329 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2330 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
2331 'timefrom' => new external_value(PARAM_INT,
2332 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
2338 * Get messagearea messages.
2340 * @deprecated since 3.6
2341 * @param int $currentuserid The current user's id
2342 * @param int $otheruserid The other user's id
2343 * @param int $limitfrom
2344 * @param int $limitnum
2345 * @param boolean $newest
2346 * @return stdClass
2347 * @throws moodle_exception
2348 * @since 3.2
2350 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
2351 $newest = false, $timefrom = 0) {
2352 global $CFG, $PAGE, $USER;
2354 // Check if messaging is enabled.
2355 if (empty($CFG->messaging)) {
2356 throw new moodle_exception('disabled', 'message');
2359 $systemcontext = context_system::instance();
2361 $params = array(
2362 'currentuserid' => $currentuserid,
2363 'otheruserid' => $otheruserid,
2364 'limitfrom' => $limitfrom,
2365 'limitnum' => $limitnum,
2366 'newest' => $newest,
2367 'timefrom' => $timefrom,
2369 $params = self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
2370 self::validate_context($systemcontext);
2372 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2373 throw new moodle_exception('You do not have permission to perform this action.');
2376 if ($params['newest']) {
2377 $sort = 'timecreated DESC';
2378 } else {
2379 $sort = 'timecreated ASC';
2382 // We need to enforce a one second delay on messages to avoid race conditions of current
2383 // messages still being sent.
2385 // There is a chance that we could request messages before the current time's
2386 // second has elapsed and while other messages are being sent in that same second. In which
2387 // case those messages will be lost.
2389 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
2390 if (!empty($params['timefrom'])) {
2391 $timeto = time() - 1;
2392 } else {
2393 $timeto = 0;
2396 // No requesting messages from the current time, as stated above.
2397 if ($params['timefrom'] == time()) {
2398 $messages = [];
2399 } else {
2400 $messages = \core_message\api::get_messages($params['currentuserid'], $params['otheruserid'], $params['limitfrom'],
2401 $params['limitnum'], $sort, $params['timefrom'], $timeto);
2404 $messages = new \core_message\output\messagearea\messages($params['currentuserid'], $params['otheruserid'], $messages);
2406 $renderer = $PAGE->get_renderer('core_message');
2407 return $messages->export_for_template($renderer);
2411 * The messagearea messages return structure.
2413 * @deprecated since 3.6
2414 * @return external_single_structure
2415 * @since 3.2
2417 public static function data_for_messagearea_messages_returns() {
2418 return new external_single_structure(
2419 array(
2420 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
2421 the messages on behalf of?'),
2422 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2423 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2424 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
2425 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
2426 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
2427 'messages' => new external_multiple_structure(
2428 self::get_messagearea_message_structure()
2430 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false),
2436 * Marking the method as deprecated.
2438 * @return bool
2440 public static function data_for_messagearea_messages_is_deprecated() {
2441 return true;
2445 * The conversation messages parameters.
2447 * @return external_function_parameters
2448 * @since 3.6
2450 public static function get_conversation_messages_parameters() {
2451 return new external_function_parameters(
2452 array(
2453 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2454 'convid' => new external_value(PARAM_INT, 'The conversation id'),
2455 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2456 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
2457 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
2458 'timefrom' => new external_value(PARAM_INT,
2459 'The timestamp from which the messages were created', VALUE_DEFAULT, 0),
2465 * Get conversation messages.
2467 * @param int $currentuserid The current user's id.
2468 * @param int $convid The conversation id.
2469 * @param int $limitfrom Return a subset of records, starting at this point (optional).
2470 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
2471 * @param bool $newest True for getting first newest messages, false otherwise.
2472 * @param int $timefrom The time from the conversation messages to get.
2473 * @return array The messages and members who have sent some of these messages.
2474 * @throws moodle_exception
2475 * @since 3.6
2477 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
2478 bool $newest = false, int $timefrom = 0) {
2479 global $CFG, $USER;
2481 // Check if messaging is enabled.
2482 if (empty($CFG->messaging)) {
2483 throw new moodle_exception('disabled', 'message');
2486 $systemcontext = context_system::instance();
2488 $params = array(
2489 'currentuserid' => $currentuserid,
2490 'convid' => $convid,
2491 'limitfrom' => $limitfrom,
2492 'limitnum' => $limitnum,
2493 'newest' => $newest,
2494 'timefrom' => $timefrom,
2496 $params = self::validate_parameters(self::get_conversation_messages_parameters(), $params);
2497 self::validate_context($systemcontext);
2499 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2500 throw new moodle_exception('You do not have permission to perform this action.');
2503 // Check that the user belongs to the conversation.
2504 if (!\core_message\api::is_user_in_conversation($params['currentuserid'], $params['convid'])) {
2505 throw new moodle_exception('User is not part of conversation.');
2508 $sort = $newest ? 'timecreated DESC' : 'timecreated ASC';
2510 // We need to enforce a one second delay on messages to avoid race conditions of current
2511 // messages still being sent.
2513 // There is a chance that we could request messages before the current time's
2514 // second has elapsed and while other messages are being sent in that same second. In which
2515 // case those messages will be lost.
2517 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
2518 $timeto = empty($params['timefrom']) ? 0 : time() - 1;
2520 // No requesting messages from the current time, as stated above.
2521 if ($params['timefrom'] == time()) {
2522 $messages = [];
2523 } else {
2524 $messages = \core_message\api::get_conversation_messages(
2525 $params['currentuserid'],
2526 $params['convid'],
2527 $params['limitfrom'],
2528 $params['limitnum'],
2529 $sort,
2530 $params['timefrom'],
2531 $timeto);
2534 return $messages;
2538 * The messagearea messages return structure.
2540 * @return external_single_structure
2541 * @since 3.6
2543 public static function get_conversation_messages_returns() {
2544 return new external_single_structure(
2545 array(
2546 'id' => new external_value(PARAM_INT, 'The conversation id'),
2547 'members' => new external_multiple_structure(
2548 self::get_conversation_member_structure()
2550 'messages' => new external_multiple_structure(
2551 self::get_conversation_message_structure()
2558 * The user contacts return parameters.
2560 * @return external_function_parameters
2562 public static function get_user_contacts_parameters() {
2563 return new external_function_parameters(
2564 array(
2565 'userid' => new external_value(PARAM_INT, 'The id of the user who we retrieving the contacts for'),
2566 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
2567 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
2573 * Get user contacts.
2575 * @param int $userid The id of the user who we are viewing conversations for
2576 * @param int $limitfrom
2577 * @param int $limitnum
2578 * @return array
2579 * @throws moodle_exception
2581 public static function get_user_contacts(int $userid, int $limitfrom = 0, int $limitnum = 0) {
2582 global $CFG, $USER;
2584 // Check if messaging is enabled.
2585 if (empty($CFG->messaging)) {
2586 throw new moodle_exception('disabled', 'message');
2589 $systemcontext = context_system::instance();
2591 $params = array(
2592 'userid' => $userid,
2593 'limitfrom' => $limitfrom,
2594 'limitnum' => $limitnum
2596 $params = self::validate_parameters(self::get_user_contacts_parameters(), $params);
2597 self::validate_context($systemcontext);
2599 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2600 throw new moodle_exception('You do not have permission to perform this action.');
2603 return \core_message\api::get_user_contacts($params['userid'], $params['limitfrom'], $params['limitnum']);
2607 * The user contacts return structure.
2609 * @return external_multiple_structure
2611 public static function get_user_contacts_returns() {
2612 return new external_multiple_structure(
2613 self::get_conversation_member_structure()
2618 * The get most recent message return parameters.
2620 * @deprecated since 3.6
2621 * @return external_function_parameters
2622 * @since 3.2
2624 public static function data_for_messagearea_get_most_recent_message_parameters() {
2625 return new external_function_parameters(
2626 array(
2627 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2628 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
2634 * Get the most recent message in a conversation.
2636 * @deprecated since 3.6
2637 * @param int $currentuserid The current user's id
2638 * @param int $otheruserid The other user's id
2639 * @return stdClass
2640 * @throws moodle_exception
2641 * @since 3.2
2643 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
2644 global $CFG, $PAGE, $USER;
2646 // Check if messaging is enabled.
2647 if (empty($CFG->messaging)) {
2648 throw new moodle_exception('disabled', 'message');
2651 $systemcontext = context_system::instance();
2653 $params = array(
2654 'currentuserid' => $currentuserid,
2655 'otheruserid' => $otheruserid
2657 $params = self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
2658 self::validate_context($systemcontext);
2660 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2661 throw new moodle_exception('You do not have permission to perform this action.');
2664 $message = \core_message\api::get_most_recent_message($params['currentuserid'], $params['otheruserid']);
2665 $message = new \core_message\output\messagearea\message($message);
2667 $renderer = $PAGE->get_renderer('core_message');
2668 return $message->export_for_template($renderer);
2672 * The get most recent message return structure.
2674 * @deprecated since 3.6
2675 * @return external_single_structure
2676 * @since 3.2
2678 public static function data_for_messagearea_get_most_recent_message_returns() {
2679 return self::get_messagearea_message_structure();
2683 * Marking the method as deprecated.
2685 * @return bool
2687 public static function data_for_messagearea_get_most_recent_message_is_deprecated() {
2688 return true;
2692 * The get profile parameters.
2694 * @deprecated since 3.6
2695 * @return external_function_parameters
2696 * @since 3.2
2698 public static function data_for_messagearea_get_profile_parameters() {
2699 return new external_function_parameters(
2700 array(
2701 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
2702 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
2708 * Get the profile information for a contact.
2710 * @deprecated since 3.6
2711 * @param int $currentuserid The current user's id
2712 * @param int $otheruserid The id of the user whose profile we are viewing
2713 * @return stdClass
2714 * @throws moodle_exception
2715 * @since 3.2
2717 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
2718 global $CFG, $PAGE, $USER;
2720 // Check if messaging is enabled.
2721 if (empty($CFG->messaging)) {
2722 throw new moodle_exception('disabled', 'message');
2725 $systemcontext = context_system::instance();
2727 $params = array(
2728 'currentuserid' => $currentuserid,
2729 'otheruserid' => $otheruserid
2731 $params = self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
2732 self::validate_context($systemcontext);
2734 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
2735 throw new moodle_exception('You do not have permission to perform this action.');
2738 $profile = \core_message\api::get_profile($params['currentuserid'], $params['otheruserid']);
2739 $profile = new \core_message\output\messagearea\profile($profile);
2741 $renderer = $PAGE->get_renderer('core_message');
2742 return $profile->export_for_template($renderer);
2746 * The get profile return structure.
2748 * @deprecated since 3.6
2749 * @return external_single_structure
2750 * @since 3.2
2752 public static function data_for_messagearea_get_profile_returns() {
2753 return new external_single_structure(
2754 array(
2755 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
2756 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
2757 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
2758 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
2759 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
2760 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
2761 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
2762 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'),
2763 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
2764 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
2765 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
2771 * Marking the method as deprecated.
2773 * @return bool
2775 public static function data_for_messagearea_get_profile_is_deprecated() {
2776 return true;
2780 * Get contacts parameters description.
2782 * @deprecated since 3.6
2783 * @return external_function_parameters
2784 * @since Moodle 2.5
2786 public static function get_contacts_parameters() {
2787 return new external_function_parameters(array());
2791 * Get contacts.
2793 * @deprecated since 3.6
2794 * @return external_description
2795 * @since Moodle 2.5
2797 public static function get_contacts() {
2798 global $CFG, $PAGE, $USER;
2800 // Check if messaging is enabled.
2801 if (empty($CFG->messaging)) {
2802 throw new moodle_exception('disabled', 'message');
2805 require_once($CFG->dirroot . '/user/lib.php');
2807 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
2808 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id);
2809 foreach ($contacts as $contact) {
2810 // Set the mode.
2811 $mode = 'offline';
2812 if (\core_message\helper::is_online($contact->lastaccess)) {
2813 $mode = 'online';
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[$mode][$contact->id] = $newcontact;
2831 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id);
2832 foreach ($strangers as $contact) {
2833 $newcontact = array(
2834 'id' => $contact->id,
2835 'fullname' => fullname($contact),
2836 'unread' => $contact->messagecount
2839 $userpicture = new user_picture($contact);
2840 $userpicture->size = 1; // Size f1.
2841 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2842 $userpicture->size = 0; // Size f2.
2843 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2845 $allcontacts['strangers'][$contact->id] = $newcontact;
2848 // Add noreply user and support user to the list, if they don't exist.
2849 $supportuser = core_user::get_support_user();
2850 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) {
2851 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser);
2852 if ($supportuser->messagecount > 0) {
2853 $supportuser->fullname = fullname($supportuser);
2854 $supportuser->unread = $supportuser->messagecount;
2855 $allcontacts['strangers'][$supportuser->id] = $supportuser;
2859 $noreplyuser = core_user::get_noreply_user();
2860 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) {
2861 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser);
2862 if ($noreplyuser->messagecount > 0) {
2863 $noreplyuser->fullname = fullname($noreplyuser);
2864 $noreplyuser->unread = $noreplyuser->messagecount;
2865 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser;
2869 return $allcontacts;
2873 * Get contacts return description.
2875 * @deprecated since 3.6
2876 * @return external_description
2877 * @since Moodle 2.5
2879 public static function get_contacts_returns() {
2880 return new external_single_structure(
2881 array(
2882 'online' => new external_multiple_structure(
2883 new external_single_structure(
2884 array(
2885 'id' => new external_value(PARAM_INT, 'User ID'),
2886 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2887 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2888 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2889 'unread' => new external_value(PARAM_INT, 'Unread message count')
2892 'List of online contacts'
2894 'offline' => new external_multiple_structure(
2895 new external_single_structure(
2896 array(
2897 'id' => new external_value(PARAM_INT, 'User ID'),
2898 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2899 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2900 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2901 'unread' => new external_value(PARAM_INT, 'Unread message count')
2904 'List of offline contacts'
2906 'strangers' => new external_multiple_structure(
2907 new external_single_structure(
2908 array(
2909 'id' => new external_value(PARAM_INT, 'User ID'),
2910 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
2911 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
2912 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
2913 'unread' => new external_value(PARAM_INT, 'Unread message count')
2916 'List of users that are not in the user\'s contact list but have sent a message'
2923 * Marking the method as deprecated.
2925 * @return bool
2927 public static function get_contacts_is_deprecated() {
2928 return true;
2932 * Search contacts parameters description.
2934 * @return external_function_parameters
2935 * @since Moodle 2.5
2937 public static function search_contacts_parameters() {
2938 return new external_function_parameters(
2939 array(
2940 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
2941 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
2942 VALUE_DEFAULT, false)
2948 * Search contacts.
2950 * @param string $searchtext query string.
2951 * @param bool $onlymycourses limit the search to the user's courses only.
2952 * @return external_description
2953 * @since Moodle 2.5
2955 public static function search_contacts($searchtext, $onlymycourses = false) {
2956 global $CFG, $USER, $PAGE;
2957 require_once($CFG->dirroot . '/user/lib.php');
2959 // Check if messaging is enabled.
2960 if (empty($CFG->messaging)) {
2961 throw new moodle_exception('disabled', 'message');
2964 require_once($CFG->libdir . '/enrollib.php');
2966 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
2967 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
2969 // Extra validation, we do not allow empty queries.
2970 if ($params['searchtext'] === '') {
2971 throw new moodle_exception('querystringcannotbeempty');
2974 $courseids = array();
2975 if ($params['onlymycourses']) {
2976 $mycourses = enrol_get_my_courses(array('id'));
2977 foreach ($mycourses as $mycourse) {
2978 $courseids[] = $mycourse->id;
2980 } else {
2981 $courseids[] = SITEID;
2984 // Retrieving the users matching the query.
2985 $users = message_search_users($courseids, $params['searchtext']);
2986 $results = array();
2987 foreach ($users as $user) {
2988 $results[$user->id] = $user;
2991 // Reorganising information.
2992 foreach ($results as &$user) {
2993 $newuser = array(
2994 'id' => $user->id,
2995 'fullname' => fullname($user)
2998 // Avoid undefined property notice as phone not specified.
2999 $user->phone1 = null;
3000 $user->phone2 = null;
3002 $userpicture = new user_picture($user);
3003 $userpicture->size = 1; // Size f1.
3004 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
3005 $userpicture->size = 0; // Size f2.
3006 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
3008 $user = $newuser;
3011 return $results;
3015 * Search contacts return description.
3017 * @return external_description
3018 * @since Moodle 2.5
3020 public static function search_contacts_returns() {
3021 return new external_multiple_structure(
3022 new external_single_structure(
3023 array(
3024 'id' => new external_value(PARAM_INT, 'User ID'),
3025 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
3026 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
3027 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
3030 'List of contacts'
3035 * Get messages parameters description.
3037 * @return external_function_parameters
3038 * @since 2.8
3040 public static function get_messages_parameters() {
3041 return new external_function_parameters(
3042 array(
3043 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3044 'useridfrom' => new external_value(
3045 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3046 VALUE_DEFAULT, 0),
3047 'type' => new external_value(
3048 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
3049 VALUE_DEFAULT, 'both'),
3050 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
3051 'newestfirst' => new external_value(
3052 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
3053 VALUE_DEFAULT, true),
3054 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
3055 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
3061 * Get messages function implementation.
3063 * @since 2.8
3064 * @throws invalid_parameter_exception
3065 * @throws moodle_exception
3066 * @param int $useridto the user id who received the message
3067 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3068 * @param string $type type of message to return, expected values: notifications, conversations and both
3069 * @param bool $read true for retreiving read messages, false for unread
3070 * @param bool $newestfirst true for ordering by newest first, false for oldest first
3071 * @param int $limitfrom limit from
3072 * @param int $limitnum limit num
3073 * @return external_description
3075 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
3076 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
3077 global $CFG, $USER;
3079 $warnings = array();
3081 $params = array(
3082 'useridto' => $useridto,
3083 'useridfrom' => $useridfrom,
3084 'type' => $type,
3085 'read' => $read,
3086 'newestfirst' => $newestfirst,
3087 'limitfrom' => $limitfrom,
3088 'limitnum' => $limitnum
3091 $params = self::validate_parameters(self::get_messages_parameters(), $params);
3093 $context = context_system::instance();
3094 self::validate_context($context);
3096 $useridto = $params['useridto'];
3097 $useridfrom = $params['useridfrom'];
3098 $type = $params['type'];
3099 $read = $params['read'];
3100 $newestfirst = $params['newestfirst'];
3101 $limitfrom = $params['limitfrom'];
3102 $limitnum = $params['limitnum'];
3104 $allowedvalues = array('notifications', 'conversations', 'both');
3105 if (!in_array($type, $allowedvalues)) {
3106 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
3107 'allowed values are: ' . implode(',', $allowedvalues));
3110 // Check if private messaging between users is allowed.
3111 if (empty($CFG->messaging)) {
3112 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
3113 if ($type == "conversations") {
3114 throw new moodle_exception('disabled', 'message');
3116 if ($type == "both") {
3117 $warning = array();
3118 $warning['item'] = 'message';
3119 $warning['itemid'] = $USER->id;
3120 $warning['warningcode'] = '1';
3121 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
3122 Only notifications will be returned';
3123 $warnings[] = $warning;
3127 if (!empty($useridto)) {
3128 if (core_user::is_real_user($useridto)) {
3129 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3130 } else {
3131 throw new moodle_exception('invaliduser');
3135 if (!empty($useridfrom)) {
3136 // We use get_user here because the from user can be the noreply or support user.
3137 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3140 // Check if the current user is the sender/receiver or just a privileged user.
3141 if ($useridto != $USER->id and $useridfrom != $USER->id and
3142 !has_capability('moodle/site:readallmessages', $context)) {
3143 throw new moodle_exception('accessdenied', 'admin');
3146 // Which type of messages to retrieve.
3147 $notifications = -1;
3148 if ($type != 'both') {
3149 $notifications = ($type == 'notifications') ? 1 : 0;
3152 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
3153 $sort = "mr.timecreated $orderdirection";
3155 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
3156 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
3158 // In some cases, we don't need to get the to/from user objects from the sql query.
3159 $userfromfullname = '';
3160 $usertofullname = '';
3162 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
3163 if (!empty($useridto)) {
3164 $usertofullname = fullname($userto, $canviewfullname);
3165 // The user from may or may not be filled.
3166 if (!empty($useridfrom)) {
3167 $userfromfullname = fullname($userfrom, $canviewfullname);
3169 } else {
3170 // If the useridto field is empty, the useridfrom must be filled.
3171 $userfromfullname = fullname($userfrom, $canviewfullname);
3173 foreach ($messages as $mid => $message) {
3175 // Do not return deleted messages.
3176 if (!$message->notification) {
3177 if (($useridto == $USER->id and $message->timeusertodeleted) or
3178 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
3179 unset($messages[$mid]);
3180 continue;
3184 // We need to get the user from the query.
3185 if (empty($userfromfullname)) {
3186 // Check for non-reply and support users.
3187 if (core_user::is_real_user($message->useridfrom)) {
3188 $user = new stdClass();
3189 $user = username_load_fields_from_object($user, $message, 'userfrom');
3190 $message->userfromfullname = fullname($user, $canviewfullname);
3191 } else {
3192 $user = core_user::get_user($message->useridfrom);
3193 $message->userfromfullname = fullname($user, $canviewfullname);
3195 } else {
3196 $message->userfromfullname = $userfromfullname;
3199 // We need to get the user from the query.
3200 if (empty($usertofullname)) {
3201 $user = new stdClass();
3202 $user = username_load_fields_from_object($user, $message, 'userto');
3203 $message->usertofullname = fullname($user, $canviewfullname);
3204 } else {
3205 $message->usertofullname = $usertofullname;
3208 $message->text = message_format_message_text($message);
3209 $messages[$mid] = (array) $message;
3213 $results = array(
3214 'messages' => $messages,
3215 'warnings' => $warnings
3218 return $results;
3222 * Get messages return description.
3224 * @return external_single_structure
3225 * @since 2.8
3227 public static function get_messages_returns() {
3228 return new external_single_structure(
3229 array(
3230 'messages' => new external_multiple_structure(
3231 new external_single_structure(
3232 array(
3233 'id' => new external_value(PARAM_INT, 'Message id'),
3234 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
3235 'useridto' => new external_value(PARAM_INT, 'User to id'),
3236 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
3237 'text' => new external_value(PARAM_RAW, 'The message text formated'),
3238 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
3239 'fullmessageformat' => new external_format_value('fullmessage'),
3240 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
3241 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
3242 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
3243 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
3244 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
3245 'timecreated' => new external_value(PARAM_INT, 'Time created'),
3246 'timeread' => new external_value(PARAM_INT, 'Time read'),
3247 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
3248 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name'),
3249 'component' => new external_value(PARAM_TEXT, 'The component that generated the notification',
3250 VALUE_OPTIONAL),
3251 'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL),
3252 'customdata' => new external_value(PARAM_RAW, 'Custom data to be passed to the message processor.
3253 The data here is serialised using json_encode().', VALUE_OPTIONAL),
3254 ), 'message'
3257 'warnings' => new external_warnings()
3263 * Mark all notifications as read parameters description.
3265 * @return external_function_parameters
3266 * @since 3.2
3268 public static function mark_all_notifications_as_read_parameters() {
3269 return new external_function_parameters(
3270 array(
3271 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3272 'useridfrom' => new external_value(
3273 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3274 VALUE_DEFAULT, 0),
3275 'timecreatedto' => new external_value(
3276 PARAM_INT, 'mark messages created before this time as read, 0 for all messages',
3277 VALUE_DEFAULT, 0),
3283 * Mark all notifications as read function.
3285 * @since 3.2
3286 * @throws invalid_parameter_exception
3287 * @throws moodle_exception
3288 * @param int $useridto the user id who received the message
3289 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3290 * @param int $timecreatedto mark message created before this time as read, 0 for all messages
3291 * @return external_description
3293 public static function mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto = 0) {
3294 global $USER;
3296 $params = self::validate_parameters(
3297 self::mark_all_notifications_as_read_parameters(),
3298 array(
3299 'useridto' => $useridto,
3300 'useridfrom' => $useridfrom,
3301 'timecreatedto' => $timecreatedto,
3305 $context = context_system::instance();
3306 self::validate_context($context);
3308 $useridto = $params['useridto'];
3309 $useridfrom = $params['useridfrom'];
3310 $timecreatedto = $params['timecreatedto'];
3312 if (!empty($useridto)) {
3313 if (core_user::is_real_user($useridto)) {
3314 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3315 } else {
3316 throw new moodle_exception('invaliduser');
3320 if (!empty($useridfrom)) {
3321 // We use get_user here because the from user can be the noreply or support user.
3322 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3325 // Check if the current user is the sender/receiver or just a privileged user.
3326 if ($useridto != $USER->id and $useridfrom != $USER->id and
3327 // The deleteanymessage cap seems more reasonable here than readallmessages.
3328 !has_capability('moodle/site:deleteanymessage', $context)) {
3329 throw new moodle_exception('accessdenied', 'admin');
3332 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto);
3334 return true;
3338 * Mark all notifications as read return description.
3340 * @return external_single_structure
3341 * @since 3.2
3343 public static function mark_all_notifications_as_read_returns() {
3344 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
3348 * Get unread conversations count parameters description.
3350 * @return external_function_parameters
3351 * @since 3.2
3353 public static function get_unread_conversations_count_parameters() {
3354 return new external_function_parameters(
3355 array(
3356 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3362 * Get unread messages count function.
3364 * @since 3.2
3365 * @throws invalid_parameter_exception
3366 * @throws moodle_exception
3367 * @param int $useridto the user id who received the message
3368 * @return external_description
3370 public static function get_unread_conversations_count($useridto) {
3371 global $USER, $CFG;
3373 // Check if messaging is enabled.
3374 if (empty($CFG->messaging)) {
3375 throw new moodle_exception('disabled', 'message');
3378 $params = self::validate_parameters(
3379 self::get_unread_conversations_count_parameters(),
3380 array('useridto' => $useridto)
3383 $context = context_system::instance();
3384 self::validate_context($context);
3386 $useridto = $params['useridto'];
3388 if (!empty($useridto)) {
3389 if (core_user::is_real_user($useridto)) {
3390 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3391 } else {
3392 throw new moodle_exception('invaliduser');
3394 } else {
3395 $useridto = $USER->id;
3398 // Check if the current user is the receiver or just a privileged user.
3399 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
3400 throw new moodle_exception('accessdenied', 'admin');
3403 return \core_message\api::count_unread_conversations($userto);
3407 * Get unread conversations count return description.
3409 * @return external_single_structure
3410 * @since 3.2
3412 public static function get_unread_conversations_count_returns() {
3413 return new external_value(PARAM_INT, 'The count of unread messages for the user');
3417 * Get blocked users parameters description.
3419 * @return external_function_parameters
3420 * @since 2.9
3422 public static function get_blocked_users_parameters() {
3423 return new external_function_parameters(
3424 array(
3425 'userid' => new external_value(PARAM_INT,
3426 'the user whose blocked users we want to retrieve',
3427 VALUE_REQUIRED),
3433 * Retrieve a list of users blocked
3435 * @param int $userid the user whose blocked users we want to retrieve
3436 * @return external_description
3437 * @since 2.9
3439 public static function get_blocked_users($userid) {
3440 global $CFG, $USER, $PAGE;
3442 // Warnings array, it can be empty at the end but is mandatory.
3443 $warnings = array();
3445 // Validate params.
3446 $params = array(
3447 'userid' => $userid
3449 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
3450 $userid = $params['userid'];
3452 // Validate context.
3453 $context = context_system::instance();
3454 self::validate_context($context);
3456 // Check if private messaging between users is allowed.
3457 if (empty($CFG->messaging)) {
3458 throw new moodle_exception('disabled', 'message');
3461 $user = core_user::get_user($userid, '*', MUST_EXIST);
3462 core_user::require_active_user($user);
3464 // Check if we have permissions for retrieve the information.
3465 $capability = 'moodle/site:manageallmessaging';
3466 if (($USER->id != $userid) && !has_capability($capability, $context)) {
3467 throw new required_capability_exception($context, $capability, 'nopermissions', '');
3470 // Now, we can get safely all the blocked users.
3471 $users = \core_message\api::get_blocked_users($user->id);
3473 $blockedusers = array();
3474 foreach ($users as $user) {
3475 $newuser = array(
3476 'id' => $user->id,
3477 'fullname' => fullname($user),
3480 $userpicture = new user_picture($user);
3481 $userpicture->size = 1; // Size f1.
3482 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
3484 $blockedusers[] = $newuser;
3487 $results = array(
3488 'users' => $blockedusers,
3489 'warnings' => $warnings
3491 return $results;
3495 * Get blocked users return description.
3497 * @return external_single_structure
3498 * @since 2.9
3500 public static function get_blocked_users_returns() {
3501 return new external_single_structure(
3502 array(
3503 'users' => new external_multiple_structure(
3504 new external_single_structure(
3505 array(
3506 'id' => new external_value(PARAM_INT, 'User ID'),
3507 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
3508 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
3511 'List of blocked users'
3513 'warnings' => new external_warnings()
3519 * Returns description of method parameters
3521 * @return external_function_parameters
3522 * @since 2.9
3524 public static function mark_message_read_parameters() {
3525 return new external_function_parameters(
3526 array(
3527 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'),
3528 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
3529 VALUE_DEFAULT, 0)
3535 * Mark a single message as read, trigger message_viewed event
3537 * @param int $messageid id of the message (in the message table)
3538 * @param int $timeread timestamp for when the message should be marked read
3539 * @return external_description
3540 * @throws invalid_parameter_exception
3541 * @throws moodle_exception
3542 * @since 2.9
3544 public static function mark_message_read($messageid, $timeread) {
3545 global $CFG, $DB, $USER;
3547 // Check if private messaging between users is allowed.
3548 if (empty($CFG->messaging)) {
3549 throw new moodle_exception('disabled', 'message');
3552 // Warnings array, it can be empty at the end but is mandatory.
3553 $warnings = array();
3555 // Validate params.
3556 $params = array(
3557 'messageid' => $messageid,
3558 'timeread' => $timeread
3560 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
3562 if (empty($params['timeread'])) {
3563 $timeread = time();
3564 } else {
3565 $timeread = $params['timeread'];
3568 // Validate context.
3569 $context = context_system::instance();
3570 self::validate_context($context);
3572 $sql = "SELECT m.*, mcm.userid as useridto
3573 FROM {messages} m
3574 INNER JOIN {message_conversations} mc
3575 ON m.conversationid = mc.id
3576 INNER JOIN {message_conversation_members} mcm
3577 ON mcm.conversationid = mc.id
3578 LEFT JOIN {message_user_actions} mua
3579 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
3580 WHERE mua.id is NULL
3581 AND mcm.userid != m.useridfrom
3582 AND m.id = ?";
3583 $messageparams = [];
3584 $messageparams[] = $USER->id;
3585 $messageparams[] = \core_message\api::MESSAGE_ACTION_READ;
3586 $messageparams[] = $params['messageid'];
3587 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST);
3589 if ($message->useridto != $USER->id) {
3590 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
3593 \core_message\api::mark_message_as_read($USER->id, $message, $timeread);
3595 $results = array(
3596 'messageid' => $message->id,
3597 'warnings' => $warnings
3599 return $results;
3603 * Returns description of method result value
3605 * @return external_description
3606 * @since 2.9
3608 public static function mark_message_read_returns() {
3609 return new external_single_structure(
3610 array(
3611 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'),
3612 'warnings' => new external_warnings()
3618 * Returns description of method parameters
3620 * @return external_function_parameters
3622 public static function mark_notification_read_parameters() {
3623 return new external_function_parameters(
3624 array(
3625 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
3626 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read',
3627 VALUE_DEFAULT, 0)
3633 * Mark a single notification as read.
3635 * This will trigger a 'notification_viewed' event.
3637 * @param int $notificationid id of the notification
3638 * @param int $timeread timestamp for when the notification should be marked read
3639 * @return external_description
3640 * @throws invalid_parameter_exception
3641 * @throws moodle_exception
3643 public static function mark_notification_read($notificationid, $timeread) {
3644 global $CFG, $DB, $USER;
3646 // Warnings array, it can be empty at the end but is mandatory.
3647 $warnings = array();
3649 // Validate params.
3650 $params = array(
3651 'notificationid' => $notificationid,
3652 'timeread' => $timeread
3654 $params = self::validate_parameters(self::mark_notification_read_parameters(), $params);
3656 if (empty($params['timeread'])) {
3657 $timeread = time();
3658 } else {
3659 $timeread = $params['timeread'];
3662 // Validate context.
3663 $context = context_system::instance();
3664 self::validate_context($context);
3666 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST);
3668 if ($notification->useridto != $USER->id) {
3669 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
3670 'notification as read');
3673 \core_message\api::mark_notification_as_read($notification, $timeread);
3675 $results = array(
3676 'notificationid' => $notification->id,
3677 'warnings' => $warnings
3680 return $results;
3684 * Returns description of method result value
3686 * @return external_description
3688 public static function mark_notification_read_returns() {
3689 return new external_single_structure(
3690 array(
3691 'notificationid' => new external_value(PARAM_INT, 'id of the notification'),
3692 'warnings' => new external_warnings()
3698 * Mark all messages as read parameters description.
3700 * @deprecated since 3.6
3701 * @return external_function_parameters
3702 * @since 3.2
3704 public static function mark_all_messages_as_read_parameters() {
3705 return new external_function_parameters(
3706 array(
3707 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
3708 'useridfrom' => new external_value(
3709 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
3710 VALUE_DEFAULT, 0),
3716 * Mark all messages as read function.
3718 * @deprecated since 3.6
3719 * @throws invalid_parameter_exception
3720 * @throws moodle_exception
3721 * @param int $useridto the user id who received the message
3722 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
3723 * @return external_description
3724 * @since 3.2
3726 public static function mark_all_messages_as_read($useridto, $useridfrom) {
3727 global $USER, $CFG;
3729 // Check if messaging is enabled.
3730 if (empty($CFG->messaging)) {
3731 throw new moodle_exception('disabled', 'message');
3734 $params = self::validate_parameters(
3735 self::mark_all_messages_as_read_parameters(),
3736 array(
3737 'useridto' => $useridto,
3738 'useridfrom' => $useridfrom,
3742 $context = context_system::instance();
3743 self::validate_context($context);
3745 $useridto = $params['useridto'];
3746 $useridfrom = $params['useridfrom'];
3748 if (!empty($useridto)) {
3749 if (core_user::is_real_user($useridto)) {
3750 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
3751 } else {
3752 throw new moodle_exception('invaliduser');
3756 if (!empty($useridfrom)) {
3757 // We use get_user here because the from user can be the noreply or support user.
3758 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
3761 // Check if the current user is the sender/receiver or just a privileged user.
3762 if ($useridto != $USER->id and $useridfrom != $USER->id and
3763 // The deleteanymessage cap seems more reasonable here than readallmessages.
3764 !has_capability('moodle/site:deleteanymessage', $context)) {
3765 throw new moodle_exception('accessdenied', 'admin');
3768 if ($useridfrom) {
3769 if ($conversationid = \core_message\api::get_conversation_between_users([$useridto, $useridfrom])) {
3770 \core_message\api::mark_all_messages_as_read($useridto, $conversationid);
3772 } else {
3773 \core_message\api::mark_all_messages_as_read($useridto);
3776 return true;
3780 * Mark all messages as read return description.
3782 * @deprecated since 3.6
3783 * @return external_single_structure
3784 * @since 3.2
3786 public static function mark_all_messages_as_read_returns() {
3787 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
3791 * Marking the method as deprecated.
3793 * @return bool
3795 public static function mark_all_messages_as_read_is_deprecated() {
3796 return true;
3800 * Mark all conversation messages as read parameters description.
3802 * @return external_function_parameters
3803 * @since 3.6
3805 public static function mark_all_conversation_messages_as_read_parameters() {
3806 return new external_function_parameters(
3807 array(
3808 'userid' => new external_value(PARAM_INT, 'The user id who who we are marking the messages as read for'),
3809 'conversationid' =>
3810 new external_value(PARAM_INT, 'The conversation id who who we are marking the messages as read for')
3816 * Mark all conversation messages as read function.
3818 * @param int $userid The user id of who we want to delete the conversation for
3819 * @param int $conversationid The id of the conversations
3820 * @since 3.6
3822 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
3823 global $CFG;
3825 // Check if messaging is enabled.
3826 if (empty($CFG->messaging)) {
3827 throw new moodle_exception('disabled', 'message');
3830 $params = array(
3831 'userid' => $userid,
3832 'conversationid' => $conversationid,
3834 $params = self::validate_parameters(self::mark_all_conversation_messages_as_read_parameters(), $params);
3836 $context = context_system::instance();
3837 self::validate_context($context);
3839 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3840 core_user::require_active_user($user);
3842 if (\core_message\api::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) {
3843 \core_message\api::mark_all_messages_as_read($params['userid'], $params['conversationid']);
3844 } else {
3845 throw new moodle_exception('accessdenied', 'admin');
3850 * Mark all conversation messages as read return description.
3852 * @return external_warnings
3853 * @since 3.6
3855 public static function mark_all_conversation_messages_as_read_returns() {
3856 return null;
3860 * Returns description of method parameters.
3862 * @deprecated since 3.6
3863 * @return external_function_parameters
3864 * @since 3.2
3866 public static function delete_conversation_parameters() {
3867 return new external_function_parameters(
3868 array(
3869 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
3870 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
3876 * Deletes a conversation.
3878 * @deprecated since 3.6
3879 * @param int $userid The user id of who we want to delete the conversation for
3880 * @param int $otheruserid The user id of the other user in the conversation
3881 * @return array
3882 * @throws moodle_exception
3883 * @since 3.2
3885 public static function delete_conversation($userid, $otheruserid) {
3886 global $CFG;
3888 // Check if private messaging between users is allowed.
3889 if (empty($CFG->messaging)) {
3890 throw new moodle_exception('disabled', 'message');
3893 // Warnings array, it can be empty at the end but is mandatory.
3894 $warnings = array();
3896 // Validate params.
3897 $params = array(
3898 'userid' => $userid,
3899 'otheruserid' => $otheruserid,
3901 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
3903 // Validate context.
3904 $context = context_system::instance();
3905 self::validate_context($context);
3907 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
3908 core_user::require_active_user($user);
3910 if (!$conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']])) {
3911 return [];
3914 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) {
3915 \core_message\api::delete_conversation_by_id($user->id, $conversationid);
3916 $status = true;
3917 } else {
3918 throw new moodle_exception('You do not have permission to delete messages');
3921 $results = array(
3922 'status' => $status,
3923 'warnings' => $warnings
3926 return $results;
3930 * Returns description of method result value.
3932 * @deprecated since 3.6
3933 * @return external_description
3934 * @since 3.2
3936 public static function delete_conversation_returns() {
3937 return new external_single_structure(
3938 array(
3939 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
3940 'warnings' => new external_warnings()
3946 * Marking the method as deprecated.
3948 * @return bool
3950 public static function delete_conversation_is_deprecated() {
3951 return true;
3955 * Returns description of method parameters.
3957 * @return external_function_parameters
3958 * @since 3.6
3960 public static function delete_conversations_by_id_parameters() {
3961 return new external_function_parameters(
3962 array(
3963 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
3964 'conversationids' => new external_multiple_structure(
3965 new external_value(PARAM_INT, 'The id of the conversation'),
3966 'List of conversation IDs'
3973 * Deletes a conversation.
3975 * @param int $userid The user id of who we want to delete the conversation for
3976 * @param int[] $conversationids The ids of the conversations
3977 * @return array
3978 * @throws moodle_exception
3979 * @since 3.6
3981 public static function delete_conversations_by_id($userid, array $conversationids) {
3982 global $CFG;
3984 // Check if private messaging between users is allowed.
3985 if (empty($CFG->messaging)) {
3986 throw new moodle_exception('disabled', 'message');
3989 // Validate params.
3990 $params = [
3991 'userid' => $userid,
3992 'conversationids' => $conversationids,
3994 $params = self::validate_parameters(self::delete_conversations_by_id_parameters(), $params);
3996 // Validate context.
3997 $context = context_system::instance();
3998 self::validate_context($context);
4000 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4001 core_user::require_active_user($user);
4003 foreach ($params['conversationids'] as $conversationid) {
4004 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) {
4005 \core_message\api::delete_conversation_by_id($user->id, $conversationid);
4006 } else {
4007 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'");
4011 return [];
4015 * Returns description of method result value.
4017 * @return external_description
4018 * @since 3.6
4020 public static function delete_conversations_by_id_returns() {
4021 return new external_warnings();
4025 * Returns description of method parameters
4027 * @return external_function_parameters
4028 * @since 3.1
4030 public static function delete_message_parameters() {
4031 return new external_function_parameters(
4032 array(
4033 'messageid' => new external_value(PARAM_INT, 'The message id'),
4034 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
4035 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
4041 * Deletes a message
4043 * @param int $messageid the message id
4044 * @param int $userid the user id of who we want to delete the message for
4045 * @param bool $read if is a message read (default to true)
4046 * @return external_description
4047 * @throws moodle_exception
4048 * @since 3.1
4050 public static function delete_message($messageid, $userid, $read = true) {
4051 global $CFG;
4053 // Check if private messaging between users is allowed.
4054 if (empty($CFG->messaging)) {
4055 throw new moodle_exception('disabled', 'message');
4058 // Warnings array, it can be empty at the end but is mandatory.
4059 $warnings = array();
4061 // Validate params.
4062 $params = array(
4063 'messageid' => $messageid,
4064 'userid' => $userid,
4065 'read' => $read
4067 $params = self::validate_parameters(self::delete_message_parameters(), $params);
4069 // Validate context.
4070 $context = context_system::instance();
4071 self::validate_context($context);
4073 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4074 core_user::require_active_user($user);
4076 if (\core_message\api::can_delete_message($user->id, $params['messageid'])) {
4077 $status = \core_message\api::delete_message($user->id, $params['messageid']);
4078 } else {
4079 throw new moodle_exception('You do not have permission to delete this message');
4082 $results = array(
4083 'status' => $status,
4084 'warnings' => $warnings
4086 return $results;
4090 * Returns description of method result value
4092 * @return external_description
4093 * @since 3.1
4095 public static function delete_message_returns() {
4096 return new external_single_structure(
4097 array(
4098 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
4099 'warnings' => new external_warnings()
4105 * Returns description of method parameters
4107 * @return external_function_parameters
4108 * @since 3.2
4110 public static function message_processor_config_form_parameters() {
4111 return new external_function_parameters(
4112 array(
4113 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
4114 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
4115 'formvalues' => new external_multiple_structure(
4116 new external_single_structure(
4117 array(
4118 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
4119 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
4122 'Config form values',
4123 VALUE_REQUIRED
4130 * Processes a message processor config form.
4132 * @param int $userid the user id
4133 * @param string $name the name of the processor
4134 * @param array $formvalues the form values
4135 * @return external_description
4136 * @throws moodle_exception
4137 * @since 3.2
4139 public static function message_processor_config_form($userid, $name, $formvalues) {
4140 global $USER, $CFG;
4142 $params = self::validate_parameters(
4143 self::message_processor_config_form_parameters(),
4144 array(
4145 'userid' => $userid,
4146 'name' => $name,
4147 'formvalues' => $formvalues,
4151 $user = self::validate_preferences_permissions($params['userid']);
4153 $processor = get_message_processor($params['name']);
4154 $preferences = [];
4155 $form = new stdClass();
4157 foreach ($params['formvalues'] as $formvalue) {
4158 // Curly braces to ensure interpretation is consistent between
4159 // php 5 and php 7.
4160 $form->{$formvalue['name']} = $formvalue['value'];
4163 $processor->process_form($form, $preferences);
4165 if (!empty($preferences)) {
4166 set_user_preferences($preferences, $params['userid']);
4171 * Returns description of method result value
4173 * @return external_description
4174 * @since 3.2
4176 public static function message_processor_config_form_returns() {
4177 return null;
4181 * Returns description of method parameters
4183 * @return external_function_parameters
4184 * @since 3.2
4186 public static function get_message_processor_parameters() {
4187 return new external_function_parameters(
4188 array(
4189 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
4190 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
4196 * Get a message processor.
4198 * @param int $userid
4199 * @param string $name the name of the processor
4200 * @return external_description
4201 * @throws moodle_exception
4202 * @since 3.2
4204 public static function get_message_processor($userid = 0, $name) {
4205 global $USER, $PAGE, $CFG;
4207 // Check if messaging is enabled.
4208 if (empty($CFG->messaging)) {
4209 throw new moodle_exception('disabled', 'message');
4212 $params = self::validate_parameters(
4213 self::get_message_processor_parameters(),
4214 array(
4215 'userid' => $userid,
4216 'name' => $name,
4220 if (empty($params['userid'])) {
4221 $params['userid'] = $USER->id;
4224 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4225 core_user::require_active_user($user);
4226 self::validate_context(context_user::instance($params['userid']));
4228 $processor = get_message_processor($params['name']);
4230 $processoroutput = new \core_message\output\processor($processor, $user);
4231 $renderer = $PAGE->get_renderer('core_message');
4233 return $processoroutput->export_for_template($renderer);
4237 * Returns description of method result value
4239 * @return external_description
4240 * @since 3.2
4242 public static function get_message_processor_returns() {
4243 return new external_function_parameters(
4244 array(
4245 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
4246 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
4252 * Check that the user has enough permission to retrieve message or notifications preferences.
4254 * @param int $userid the user id requesting the preferences
4255 * @return stdClass full user object
4256 * @throws moodle_exception
4257 * @since Moodle 3.2
4259 protected static function validate_preferences_permissions($userid) {
4260 global $USER;
4262 if (empty($userid)) {
4263 $user = $USER;
4264 } else {
4265 $user = core_user::get_user($userid, '*', MUST_EXIST);
4266 core_user::require_active_user($user);
4269 $systemcontext = context_system::instance();
4270 self::validate_context($systemcontext);
4272 // Check access control.
4273 if ($user->id == $USER->id) {
4274 // Editing own message profile.
4275 require_capability('moodle/user:editownmessageprofile', $systemcontext);
4276 } else {
4277 // Teachers, parents, etc.
4278 $personalcontext = context_user::instance($user->id);
4279 require_capability('moodle/user:editmessageprofile', $personalcontext);
4281 return $user;
4285 * Returns a notification or message preference structure.
4287 * @return external_single_structure the structure
4288 * @since Moodle 3.2
4290 protected static function get_preferences_structure() {
4291 return new external_single_structure(
4292 array(
4293 'userid' => new external_value(PARAM_INT, 'User id'),
4294 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
4295 'processors' => new external_multiple_structure(
4296 new external_single_structure(
4297 array(
4298 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4299 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
4300 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
4301 'contextid' => new external_value(PARAM_INT, 'Context id'),
4302 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
4305 'Config form values'
4307 'components' => new external_multiple_structure(
4308 new external_single_structure(
4309 array(
4310 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4311 'notifications' => new external_multiple_structure(
4312 new external_single_structure(
4313 array(
4314 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4315 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
4316 'processors' => new external_multiple_structure(
4317 new external_single_structure(
4318 array(
4319 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4320 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
4321 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
4322 'lockedmessage' => new external_value(PARAM_TEXT,
4323 'Text to display if locked', VALUE_OPTIONAL),
4324 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
4325 'loggedin' => new external_single_structure(
4326 array(
4327 'name' => new external_value(PARAM_NOTAGS, 'Name'),
4328 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4329 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
4332 'loggedoff' => new external_single_structure(
4333 array(
4334 'name' => new external_value(PARAM_NOTAGS, 'Name'),
4335 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
4336 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
4341 'Processors values for this notification'
4345 'List of notificaitons for the component'
4349 'Available components'
4356 * Returns description of method parameters
4358 * @return external_function_parameters
4359 * @since 3.2
4361 public static function get_user_notification_preferences_parameters() {
4362 return new external_function_parameters(
4363 array(
4364 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4370 * Get the notification preferences for a given user.
4372 * @param int $userid id of the user, 0 for current user
4373 * @return external_description
4374 * @throws moodle_exception
4375 * @since 3.2
4377 public static function get_user_notification_preferences($userid = 0) {
4378 global $PAGE;
4380 $params = self::validate_parameters(
4381 self::get_user_notification_preferences_parameters(),
4382 array(
4383 'userid' => $userid,
4386 $user = self::validate_preferences_permissions($params['userid']);
4388 $processors = get_message_processors();
4389 $providers = message_get_providers_for_user($user->id);
4390 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
4391 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
4393 $renderer = $PAGE->get_renderer('core_message');
4395 $result = array(
4396 'warnings' => array(),
4397 'preferences' => $notificationlist->export_for_template($renderer)
4399 return $result;
4403 * Returns description of method result value
4405 * @return external_description
4406 * @since 3.2
4408 public static function get_user_notification_preferences_returns() {
4409 return new external_function_parameters(
4410 array(
4411 'preferences' => self::get_preferences_structure(),
4412 'warnings' => new external_warnings(),
4418 * Returns description of method parameters
4420 * @return external_function_parameters
4421 * @since 3.2
4423 public static function get_user_message_preferences_parameters() {
4424 return new external_function_parameters(
4425 array(
4426 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4432 * Get the notification preferences for a given user.
4434 * @param int $userid id of the user, 0 for current user
4435 * @return external_description
4436 * @throws moodle_exception
4437 * @since 3.2
4439 public static function get_user_message_preferences($userid = 0) {
4440 global $CFG, $PAGE;
4442 $params = self::validate_parameters(
4443 self::get_user_message_preferences_parameters(),
4444 array(
4445 'userid' => $userid,
4449 $user = self::validate_preferences_permissions($params['userid']);
4451 // Filter out enabled, available system_configured and user_configured processors only.
4452 $readyprocessors = array_filter(get_message_processors(), function($processor) {
4453 return $processor->enabled &&
4454 $processor->configured &&
4455 $processor->object->is_user_configured() &&
4456 // Filter out processors that don't have and message preferences to configure.
4457 $processor->object->has_message_preferences();
4460 $providers = array_filter(message_get_providers_for_user($user->id), function($provider) {
4461 return $provider->component === 'moodle';
4463 $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user);
4464 $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors,
4465 $providers, $preferences, $user);
4467 $renderer = $PAGE->get_renderer('core_message');
4469 $entertosend = get_user_preferences('message_entertosend', $CFG->messagingdefaultpressenter, $user);
4471 $result = array(
4472 'warnings' => array(),
4473 'preferences' => $notificationlistoutput->export_for_template($renderer),
4474 'blocknoncontacts' => \core_message\api::get_user_privacy_messaging_preference($user->id),
4475 'entertosend' => $entertosend
4477 return $result;
4481 * Returns description of method result value
4483 * @return external_description
4484 * @since 3.2
4486 public static function get_user_message_preferences_returns() {
4487 return new external_function_parameters(
4488 array(
4489 'preferences' => self::get_preferences_structure(),
4490 'blocknoncontacts' => new external_value(PARAM_INT, 'Privacy messaging setting to define who can message you'),
4491 'entertosend' => new external_value(PARAM_BOOL, 'User preference for using enter to send messages'),
4492 'warnings' => new external_warnings(),
4498 * Returns description of method parameters for the favourite_conversations() method.
4500 * @return external_function_parameters
4502 public static function set_favourite_conversations_parameters() {
4503 return new external_function_parameters(
4504 array(
4505 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0),
4506 'conversations' => new external_multiple_structure(
4507 new external_value(PARAM_INT, 'id of the conversation', VALUE_DEFAULT, 0)
4514 * Favourite a conversation, or list of conversations for a user.
4516 * @param int $userid the id of the user, or 0 for the current user.
4517 * @param array $conversationids the list of conversations ids to favourite.
4518 * @return array
4519 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4521 public static function set_favourite_conversations(int $userid, array $conversationids) {
4522 global $CFG, $USER;
4524 // All the business logic checks that really shouldn't be in here.
4525 if (empty($CFG->messaging)) {
4526 throw new moodle_exception('disabled', 'message');
4528 $params = [
4529 'userid' => $userid,
4530 'conversations' => $conversationids
4532 $params = self::validate_parameters(self::set_favourite_conversations_parameters(), $params);
4533 $systemcontext = context_system::instance();
4534 self::validate_context($systemcontext);
4536 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4537 throw new moodle_exception('You do not have permission to perform this action.');
4540 foreach ($params['conversations'] as $conversationid) {
4541 \core_message\api::set_favourite_conversation($conversationid, $params['userid']);
4544 return [];
4548 * Return a description of the returns for the create_user_favourite_conversations() method.
4550 * @return external_description
4552 public static function set_favourite_conversations_returns() {
4553 return new external_warnings();
4557 * Returns description of method parameters for unfavourite_conversations() method.
4559 * @return external_function_parameters
4561 public static function unset_favourite_conversations_parameters() {
4562 return new external_function_parameters(
4563 array(
4564 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0),
4565 'conversations' => new external_multiple_structure(
4566 new external_value(PARAM_INT, 'id of the conversation', VALUE_DEFAULT, 0)
4573 * Unfavourite a conversation, or list of conversations for a user.
4575 * @param int $userid the id of the user, or 0 for the current user.
4576 * @param array $conversationids the list of conversations ids unset as favourites.
4577 * @return array
4578 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4580 public static function unset_favourite_conversations(int $userid, array $conversationids) {
4581 global $CFG, $USER;
4583 // All the business logic checks that really shouldn't be in here.
4584 if (empty($CFG->messaging)) {
4585 throw new moodle_exception('disabled', 'message');
4587 $params = [
4588 'userid' => $userid,
4589 'conversations' => $conversationids
4591 $params = self::validate_parameters(self::unset_favourite_conversations_parameters(), $params);
4592 $systemcontext = context_system::instance();
4593 self::validate_context($systemcontext);
4595 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4596 throw new moodle_exception('You do not have permission to perform this action.');
4599 foreach ($params['conversations'] as $conversationid) {
4600 \core_message\api::unset_favourite_conversation($conversationid, $params['userid']);
4603 return [];
4607 * Unset favourite conversations return description.
4609 * @return external_description
4611 public static function unset_favourite_conversations_returns() {
4612 return new external_warnings();
4616 * Returns description of method parameters for get_member_info() method.
4618 * @return external_function_parameters
4620 public static function get_member_info_parameters() {
4621 return new external_function_parameters(
4622 array(
4623 'referenceuserid' => new external_value(PARAM_INT, 'id of the user'),
4624 'userids' => new external_multiple_structure(
4625 new external_value(PARAM_INT, 'id of members to get')
4627 'includecontactrequests' => new external_value(PARAM_BOOL, 'include contact requests in response', VALUE_DEFAULT, false),
4628 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'include privacy info in response', VALUE_DEFAULT, false)
4634 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid.
4636 * This is the basic structure used when returning members, and includes information about the relationship between each member
4637 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them.
4639 * @param int $referenceuserid the id of the user which check contact and blocked status.
4640 * @param array $userids
4641 * @return array the array of objects containing member info.
4642 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
4644 public static function get_member_info(
4645 int $referenceuserid,
4646 array $userids,
4647 bool $includecontactrequests = false,
4648 bool $includeprivacyinfo = false
4650 global $CFG, $USER;
4652 // All the business logic checks that really shouldn't be in here.
4653 if (empty($CFG->messaging)) {
4654 throw new moodle_exception('disabled', 'message');
4656 $params = [
4657 'referenceuserid' => $referenceuserid,
4658 'userids' => $userids,
4659 'includecontactrequests' => $includecontactrequests,
4660 'includeprivacyinfo' => $includeprivacyinfo
4662 $params = self::validate_parameters(self::get_member_info_parameters(), $params);
4663 $systemcontext = context_system::instance();
4664 self::validate_context($systemcontext);
4666 if (($USER->id != $referenceuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4667 throw new moodle_exception('You do not have permission to perform this action.');
4670 return \core_message\helper::get_member_info(
4671 $params['referenceuserid'],
4672 $params['userids'],
4673 $params['includecontactrequests'],
4674 $params['includeprivacyinfo']
4679 * Get member info return description.
4681 * @return external_description
4683 public static function get_member_info_returns() {
4684 return new external_multiple_structure(
4685 self::get_conversation_member_structure()
4690 * Returns description of method parameters for get_conversation_counts() method.
4692 * @return external_function_parameters
4694 public static function get_conversation_counts_parameters() {
4695 return new external_function_parameters(
4697 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4703 * Returns an array of conversation counts for the various types of conversations, including favourites.
4705 * Return format:
4707 * 'favourites' => 0,
4708 * 'types' => [
4709 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
4710 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
4714 * @param int $userid the id of the user whose counts we are fetching.
4715 * @return array the array of conversation counts, indexed by type.
4716 * @throws moodle_exception if the current user cannot perform this action.
4718 public static function get_conversation_counts(int $userid) {
4719 global $CFG, $USER;
4721 // All the business logic checks that really shouldn't be in here.
4722 if (empty($CFG->messaging)) {
4723 throw new moodle_exception('disabled', 'message');
4726 if (empty($userid)) {
4727 $userid = $USER->id;
4730 $params = ['userid' => $userid];
4731 $params = self::validate_parameters(self::get_conversation_counts_parameters(), $params);
4733 $systemcontext = context_system::instance();
4734 self::validate_context($systemcontext);
4736 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4737 throw new moodle_exception('You do not have permission to perform this action.');
4740 return \core_message\api::get_conversation_counts($params['userid']);
4744 * Get conversation counts return description.
4746 * @return external_description
4748 public static function get_conversation_counts_returns() {
4749 return new external_single_structure(
4751 'favourites' => new external_value(PARAM_INT, 'Total number of favourite conversations'),
4752 'types' => new external_single_structure(
4754 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT,
4755 'Total number of individual conversations'),
4756 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT,
4757 'Total number of group conversations'),
4758 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT,
4759 'Total number of self conversations'),
4767 * Returns description of method parameters for get_unread_conversation_counts() method.
4769 * @return external_function_parameters
4771 public static function get_unread_conversation_counts_parameters() {
4772 return new external_function_parameters(
4774 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
4780 * Returns an array of unread conversation counts for the various types of conversations, including favourites.
4782 * Return format:
4784 * 'favourites' => 0,
4785 * 'types' => [
4786 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
4787 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
4791 * @param int $userid the id of the user whose counts we are fetching.
4792 * @return array the array of unread conversation counts, indexed by type.
4793 * @throws moodle_exception if the current user cannot perform this action.
4795 public static function get_unread_conversation_counts(int $userid) {
4796 global $CFG, $USER;
4798 // All the business logic checks that really shouldn't be in here.
4799 if (empty($CFG->messaging)) {
4800 throw new moodle_exception('disabled', 'message');
4803 if (empty($userid)) {
4804 $userid = $USER->id;
4807 $params = ['userid' => $userid];
4808 $params = self::validate_parameters(self::get_unread_conversation_counts_parameters(), $params);
4810 $systemcontext = context_system::instance();
4811 self::validate_context($systemcontext);
4813 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
4814 throw new moodle_exception('You do not have permission to perform this action.');
4817 return \core_message\api::get_unread_conversation_counts($params['userid']);
4821 * Get unread conversation counts return description.
4823 * @return external_description
4825 public static function get_unread_conversation_counts_returns() {
4826 return new external_single_structure(
4828 'favourites' => new external_value(PARAM_INT, 'Total number of unread favourite conversations'),
4829 'types' => new external_single_structure(
4831 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT,
4832 'Total number of unread individual conversations'),
4833 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT,
4834 'Total number of unread group conversations'),
4835 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT,
4836 'Total number of unread self conversations'),
4844 * Returns description of method parameters
4846 * @return external_function_parameters
4847 * @since 3.7
4849 public static function delete_message_for_all_users_parameters() {
4850 return new external_function_parameters(
4851 array(
4852 'messageid' => new external_value(PARAM_INT, 'The message id'),
4853 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for all users')
4858 * Deletes a message for all users
4860 * @param int $messageid the message id
4861 * @param int $userid the user id of who we want to delete the message for all users
4862 * @return external_description
4863 * @throws moodle_exception
4864 * @since 3.7
4866 public static function delete_message_for_all_users(int $messageid, int $userid) {
4867 global $CFG;
4869 // Check if private messaging between users is allowed.
4870 if (empty($CFG->messaging)) {
4871 throw new moodle_exception('disabled', 'message');
4874 // Validate params.
4875 $params = array(
4876 'messageid' => $messageid,
4877 'userid' => $userid
4879 $params = self::validate_parameters(self::delete_message_for_all_users_parameters(), $params);
4881 // Validate context.
4882 $context = context_system::instance();
4883 self::validate_context($context);
4885 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
4886 core_user::require_active_user($user);
4888 // Checks if a user can delete a message for all users.
4889 if (core_message\api::can_delete_message_for_all_users($user->id, $params['messageid'])) {
4890 \core_message\api::delete_message_for_all_users($params['messageid']);
4891 } else {
4892 throw new moodle_exception('You do not have permission to delete this message for everyone.');
4895 return [];
4898 * Returns description of method result value
4900 * @return external_description
4901 * @since 3.7
4903 public static function delete_message_for_all_users_returns() {
4904 return new external_warnings();