2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
19 * External message API
21 * @package core_message
23 * @copyright 2011 Jerome Mouneyrac
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 defined('MOODLE_INTERNAL') ||
die();
29 require_once("$CFG->libdir/externallib.php");
30 require_once($CFG->dirroot
. "/message/lib.php");
33 * Message external functions
35 * @package core_message
37 * @copyright 2011 Jerome Mouneyrac
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 class core_message_external
extends external_api
{
44 * Returns description of method parameters
46 * @return external_function_parameters
49 public static function send_instant_messages_parameters() {
50 return new external_function_parameters(
52 'messages' => new external_multiple_structure(
53 new external_single_structure(
55 'touserid' => new external_value(PARAM_INT
, 'id of the user to send the private message'),
56 'text' => new external_value(PARAM_RAW
, 'the text of the message'),
57 'textformat' => new external_format_value('text', VALUE_DEFAULT
, FORMAT_MOODLE
),
58 '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
),
67 * Send private messages from the current USER to other users
69 * @param array $messages An array of message to send.
73 public static function send_instant_messages($messages = array()) {
74 global $CFG, $USER, $DB;
76 // Check if messaging is enabled.
77 if (empty($CFG->messaging
)) {
78 throw new moodle_exception('disabled', 'message');
81 // Ensure the current user is allowed to run this function
82 $context = context_system
::instance();
83 self
::validate_context($context);
84 require_capability('moodle/site:sendmessage', $context);
86 $params = self
::validate_parameters(self
::send_instant_messages_parameters(), array('messages' => $messages));
88 //retrieve all tousers of the messages
90 foreach($params['messages'] as $message) {
91 $receivers[] = $message['touserid'];
93 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers);
94 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
96 $resultmessages = array();
97 foreach ($params['messages'] as $message) {
98 $resultmsg = array(); //the infos about the success of the operation
100 // We are going to do some checking.
101 // Code should match /messages/index.php checks.
104 // Check the user exists.
105 if (empty($tousers[$message['touserid']])) {
107 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
110 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
111 // Check if the recipient can be messaged by the sender.
112 if ($success && !\core_message\api
::can_post_message($tousers[$message['touserid']], $USER)) {
114 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user
::get_user($message['touserid'])));
117 // Now we can send the message (at least try).
119 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object.
120 $success = message_post_message($USER, $tousers[$message['touserid']],
121 $message['text'], external_validate_format($message['textformat']));
124 // Build the resultmsg.
125 if (isset($message['clientmsgid'])) {
126 $resultmsg['clientmsgid'] = $message['clientmsgid'];
129 $resultmsg['msgid'] = $success;
131 // WARNINGS: for backward compatibility we return this errormessage.
132 // We should have thrown exceptions as these errors prevent results to be returned.
133 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
134 $resultmsg['msgid'] = -1;
135 $resultmsg['errormessage'] = $errormessage;
138 $resultmessages[] = $resultmsg;
141 return $resultmessages;
145 * Returns description of method result value
147 * @return external_description
150 public static function send_instant_messages_returns() {
151 return new external_multiple_structure(
152 new external_single_structure(
154 'msgid' => new external_value(PARAM_INT
, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
155 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT
, 'your own id for the message', VALUE_OPTIONAL
),
156 'errormessage' => new external_value(PARAM_TEXT
, 'error message - if it failed', VALUE_OPTIONAL
)
163 * Create contacts parameters description.
165 * @deprecated since Moodle 3.6
166 * @return external_function_parameters
169 public static function create_contacts_parameters() {
170 return new external_function_parameters(
172 'userids' => new external_multiple_structure(
173 new external_value(PARAM_INT
, 'User ID'),
176 'userid' => new external_value(PARAM_INT
, 'The id of the user we are creating the contacts for, 0 for the
177 current user', VALUE_DEFAULT
, 0)
185 * @deprecated since Moodle 3.6
186 * @param array $userids array of user IDs.
187 * @param int $userid The id of the user we are creating the contacts for
188 * @return external_description
191 public static function create_contacts($userids, $userid = 0) {
194 // Check if messaging is enabled.
195 if (empty($CFG->messaging
)) {
196 throw new moodle_exception('disabled', 'message');
199 if (empty($userid)) {
204 $context = context_system
::instance();
205 self
::validate_context($context);
207 $capability = 'moodle/site:manageallmessaging';
208 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
209 throw new required_capability_exception($context, $capability, 'nopermissions', '');
212 $params = array('userids' => $userids, 'userid' => $userid);
213 $params = self
::validate_parameters(self
::create_contacts_parameters(), $params);
216 foreach ($params['userids'] as $id) {
217 if (!message_add_contact($id, 0, $userid)) {
221 'warningcode' => 'contactnotcreated',
222 'message' => 'The contact could not be created'
230 * Create contacts return description.
232 * @deprecated since Moodle 3.6
233 * @return external_description
236 public static function create_contacts_returns() {
237 return new external_warnings();
241 * Marking the method as deprecated.
245 public static function create_contacts_is_deprecated() {
250 * Delete contacts parameters description.
252 * @return external_function_parameters
255 public static function delete_contacts_parameters() {
256 return new external_function_parameters(
258 'userids' => new external_multiple_structure(
259 new external_value(PARAM_INT
, 'User ID'),
262 'userid' => new external_value(PARAM_INT
, 'The id of the user we are deleting the contacts for, 0 for the
263 current user', VALUE_DEFAULT
, 0)
271 * @param array $userids array of user IDs.
272 * @param int $userid The id of the user we are deleting the contacts for
276 public static function delete_contacts($userids, $userid = 0) {
279 // Check if messaging is enabled.
280 if (empty($CFG->messaging
)) {
281 throw new moodle_exception('disabled', 'message');
284 if (empty($userid)) {
289 $context = context_system
::instance();
290 self
::validate_context($context);
292 $capability = 'moodle/site:manageallmessaging';
293 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
294 throw new required_capability_exception($context, $capability, 'nopermissions', '');
297 $params = array('userids' => $userids, 'userid' => $userid);
298 $params = self
::validate_parameters(self
::delete_contacts_parameters(), $params);
300 foreach ($params['userids'] as $id) {
301 \core_message\api
::remove_contact($userid, $id);
308 * Delete contacts return description.
310 * @return external_description
313 public static function delete_contacts_returns() {
318 * Block user parameters description.
320 * @return external_function_parameters
322 public static function block_user_parameters() {
323 return new external_function_parameters(
325 'userid' => new external_value(PARAM_INT
, 'The id of the user who is blocking'),
326 'blockeduserid' => new external_value(PARAM_INT
, 'The id of the user being blocked'),
334 * @param int $userid The id of the user who is blocking
335 * @param int $blockeduserid The id of the user being blocked
336 * @return external_description
338 public static function block_user(int $userid, int $blockeduserid) {
341 // Check if messaging is enabled.
342 if (empty($CFG->messaging
)) {
343 throw new moodle_exception('disabled', 'message');
347 $context = context_system
::instance();
348 self
::validate_context($context);
350 $capability = 'moodle/site:manageallmessaging';
351 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
352 throw new required_capability_exception($context, $capability, 'nopermissions', '');
355 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid];
356 $params = self
::validate_parameters(self
::block_user_parameters(), $params);
358 if (!\core_message\api
::is_blocked($params['userid'], $params['blockeduserid'])) {
359 \core_message\api
::block_user($params['userid'], $params['blockeduserid']);
366 * Block user return description.
368 * @return external_description
370 public static function block_user_returns() {
371 return new external_warnings();
375 * Unblock user parameters description.
377 * @return external_function_parameters
379 public static function unblock_user_parameters() {
380 return new external_function_parameters(
382 'userid' => new external_value(PARAM_INT
, 'The id of the user who is unblocking'),
383 'unblockeduserid' => new external_value(PARAM_INT
, 'The id of the user being unblocked'),
391 * @param int $userid The id of the user who is unblocking
392 * @param int $unblockeduserid The id of the user being unblocked
394 public static function unblock_user(int $userid, int $unblockeduserid) {
397 // Check if messaging is enabled.
398 if (empty($CFG->messaging
)) {
399 throw new moodle_exception('disabled', 'message');
403 $context = context_system
::instance();
404 self
::validate_context($context);
406 $capability = 'moodle/site:manageallmessaging';
407 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
408 throw new required_capability_exception($context, $capability, 'nopermissions', '');
411 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid];
412 $params = self
::validate_parameters(self
::unblock_user_parameters(), $params);
414 \core_message\api
::unblock_user($params['userid'], $params['unblockeduserid']);
420 * Unblock user return description.
422 * @return external_description
424 public static function unblock_user_returns() {
425 return new external_warnings();
429 * Block contacts parameters description.
431 * @deprecated since Moodle 3.6
432 * @return external_function_parameters
435 public static function block_contacts_parameters() {
436 return new external_function_parameters(
438 'userids' => new external_multiple_structure(
439 new external_value(PARAM_INT
, 'User ID'),
442 'userid' => new external_value(PARAM_INT
, 'The id of the user we are blocking the contacts for, 0 for the
443 current user', VALUE_DEFAULT
, 0)
451 * @deprecated since Moodle 3.6
452 * @param array $userids array of user IDs.
453 * @param int $userid The id of the user we are blocking the contacts for
454 * @return external_description
457 public static function block_contacts($userids, $userid = 0) {
460 // Check if messaging is enabled.
461 if (empty($CFG->messaging
)) {
462 throw new moodle_exception('disabled', 'message');
465 if (empty($userid)) {
470 $context = context_system
::instance();
471 self
::validate_context($context);
473 $capability = 'moodle/site:manageallmessaging';
474 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
475 throw new required_capability_exception($context, $capability, 'nopermissions', '');
478 $params = array('userids' => $userids, 'userid' => $userid);
479 $params = self
::validate_parameters(self
::block_contacts_parameters(), $params);
482 foreach ($params['userids'] as $id) {
483 if (!message_block_contact($id, $userid)) {
487 'warningcode' => 'contactnotblocked',
488 'message' => 'The contact could not be blocked'
496 * Block contacts return description.
498 * @deprecated since Moodle 3.6
499 * @return external_description
502 public static function block_contacts_returns() {
503 return new external_warnings();
507 * Marking the method as deprecated.
511 public static function block_contacts_is_deprecated() {
516 * Unblock contacts parameters description.
518 * @deprecated since Moodle 3.6
519 * @return external_function_parameters
522 public static function unblock_contacts_parameters() {
523 return new external_function_parameters(
525 'userids' => new external_multiple_structure(
526 new external_value(PARAM_INT
, 'User ID'),
529 'userid' => new external_value(PARAM_INT
, 'The id of the user we are unblocking the contacts for, 0 for the
530 current user', VALUE_DEFAULT
, 0)
538 * @param array $userids array of user IDs.
539 * @param int $userid The id of the user we are unblocking the contacts for
543 public static function unblock_contacts($userids, $userid = 0) {
546 // Check if messaging is enabled.
547 if (empty($CFG->messaging
)) {
548 throw new moodle_exception('disabled', 'message');
551 if (empty($userid)) {
556 $context = context_system
::instance();
557 self
::validate_context($context);
559 $capability = 'moodle/site:manageallmessaging';
560 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
561 throw new required_capability_exception($context, $capability, 'nopermissions', '');
564 $params = array('userids' => $userids, 'userid' => $userid);
565 $params = self
::validate_parameters(self
::unblock_contacts_parameters(), $params);
567 foreach ($params['userids'] as $id) {
568 message_unblock_contact($id, $userid);
575 * Unblock contacts return description.
577 * @deprecated since Moodle 3.6
578 * @return external_description
581 public static function unblock_contacts_returns() {
586 * Marking the method as deprecated.
590 public static function unblock_contacts_is_deprecated() {
595 * Returns contact requests parameters description.
597 * @return external_function_parameters
599 public static function get_contact_requests_parameters() {
600 return new external_function_parameters(
602 'userid' => new external_value(PARAM_INT
, 'The id of the user we want the requests for')
608 * Handles returning the contact requests for a user.
610 * This also includes the user data necessary to display information
613 * It will not include blocked users.
615 * @param int $userid The id of the user we want to get the contact requests for
617 public static function get_contact_requests(int $userid) {
620 // Check if messaging is enabled.
621 if (empty($CFG->messaging
)) {
622 throw new moodle_exception('disabled', 'message');
626 $context = context_system
::instance();
627 self
::validate_context($context);
629 $capability = 'moodle/site:manageallmessaging';
630 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
631 throw new required_capability_exception($context, $capability, 'nopermissions', '');
634 $params = ['userid' => $userid];
635 $params = self
::validate_parameters(self
::get_contact_requests_parameters(), $params);
637 return \core_message\api
::get_contact_requests($params['userid']);
641 * Returns the contact requests return description.
643 * @return external_description
645 public static function get_contact_requests_returns() {
646 return new external_multiple_structure(
647 new external_single_structure(
649 'id' => new external_value(core_user
::get_property_type('id'), 'ID of the user'),
650 'contactrequestid' => new external_value(PARAM_INT
, 'The ID of the contact request'),
651 'picture' => new external_value(core_user
::get_property_type('picture'), 'The picture'),
652 'firstname' => new external_value(core_user
::get_property_type('firstname'),
653 'The first name(s) of the user'),
654 'lastname' => new external_value(core_user
::get_property_type('lastname'),
655 'The family name of the user'),
656 'firstnamephonetic' => new external_value(core_user
::get_property_type('firstnamephonetic'),
657 'The phonetic first name of the user'),
658 'lastnamephonetic' => new external_value(core_user
::get_property_type('lastnamephonetic'),
659 'The phonetic last name of the user'),
660 'middlename' => new external_value(core_user
::get_property_type('middlename'),
661 'The middle name of the user'),
662 'alternatename' => new external_value(core_user
::get_property_type('alternatename'),
663 'The alternate name of the user'),
664 'email' => new external_value(core_user
::get_property_type('email'), 'An email address')
671 * Returns get conversation members parameters description.
673 * @return external_function_parameters
675 public static function get_conversation_members_parameters() {
676 return new external_function_parameters(
678 'userid' => new external_value(PARAM_INT
, 'The id of the user we are performing this action on behalf of'),
679 'conversationid' => new external_value(PARAM_INT
, 'The id of the conversation'),
680 'includecontactrequests' => new external_value(PARAM_BOOL
, 'Do we want to include contact requests?',
681 VALUE_DEFAULT
, false),
682 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
683 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
689 * Returns a list of conversation members.
691 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info.
692 * @param int $conversationid The id of the conversation
693 * @param bool $includecontactrequests Do we want to include contact requests with this data?
694 * @param int $limitfrom
695 * @param int $limitnum
698 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false,
699 int $limitfrom = 0, int $limitnum = 0) {
702 // Check if messaging is enabled.
703 if (empty($CFG->messaging
)) {
704 throw new moodle_exception('disabled', 'message');
708 $context = context_system
::instance();
709 self
::validate_context($context);
711 $capability = 'moodle/site:manageallmessaging';
712 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
713 throw new required_capability_exception($context, $capability, 'nopermissions', '');
716 // The user needs to be a part of the conversation before querying who the members are.
717 if (!\core_message\api
::is_user_in_conversation($userid, $conversationid)) {
718 throw new moodle_exception('You are not a member of this conversation.');
723 'conversationid' => $conversationid,
724 'includecontactrequests' => $includecontactrequests,
725 'limitfrom' => $limitfrom,
726 'limitnum' => $limitnum
728 self
::validate_parameters(self
::get_conversation_members_parameters(), $params);
730 return \core_message\api
::get_conversation_members($userid, $conversationid, $includecontactrequests,
731 $limitfrom, $limitnum);
735 * Returns the get conversation members return description.
737 * @return external_description
739 public static function get_conversation_members_returns() {
740 return new external_multiple_structure(
741 self
::get_conversation_member_structure(true)
746 * Creates a contact request parameters description.
748 * @return external_function_parameters
750 public static function create_contact_request_parameters() {
751 return new external_function_parameters(
753 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
754 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
760 * Creates a contact request.
762 * @param int $userid The id of the user who is creating the contact request
763 * @param int $requesteduserid The id of the user being requested
765 public static function create_contact_request(int $userid, int $requesteduserid) {
768 // Check if messaging is enabled.
769 if (empty($CFG->messaging
)) {
770 throw new moodle_exception('disabled', 'message');
774 $context = context_system
::instance();
775 self
::validate_context($context);
777 $capability = 'moodle/site:manageallmessaging';
778 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
779 throw new required_capability_exception($context, $capability, 'nopermissions', '');
782 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
783 $params = self
::validate_parameters(self
::create_contact_request_parameters(), $params);
785 if (!\core_message\api
::can_create_contact($params['userid'], $params['requesteduserid'])) {
788 'itemid' => $params['requesteduserid'],
789 'warningcode' => 'cannotcreatecontactrequest',
790 'message' => 'You are unable to create a contact request for this user'
795 if (!\core_message\api
::does_contact_request_exist($params['userid'], $params['requesteduserid'])) {
796 \core_message\api
::create_contact_request($params['userid'], $params['requesteduserid']);
803 * Creates a contact request return description.
805 * @return external_description
807 public static function create_contact_request_returns() {
808 return new external_warnings();
812 * Confirm a contact request parameters description.
814 * @return external_function_parameters
816 public static function confirm_contact_request_parameters() {
817 return new external_function_parameters(
819 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
820 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
826 * Confirm a contact request.
828 * @param int $userid The id of the user who is creating the contact request
829 * @param int $requesteduserid The id of the user being requested
831 public static function confirm_contact_request(int $userid, int $requesteduserid) {
834 // Check if messaging is enabled.
835 if (empty($CFG->messaging
)) {
836 throw new moodle_exception('disabled', 'message');
840 $context = context_system
::instance();
841 self
::validate_context($context);
843 $capability = 'moodle/site:manageallmessaging';
844 if (($USER->id
!= $requesteduserid) && !has_capability($capability, $context)) {
845 throw new required_capability_exception($context, $capability, 'nopermissions', '');
848 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
849 $params = self
::validate_parameters(self
::confirm_contact_request_parameters(), $params);
851 \core_message\api
::confirm_contact_request($params['userid'], $params['requesteduserid']);
857 * Confirm a contact request return description.
859 * @return external_description
861 public static function confirm_contact_request_returns() {
862 return new external_warnings();
866 * Declines a contact request parameters description.
868 * @return external_function_parameters
870 public static function decline_contact_request_parameters() {
871 return new external_function_parameters(
873 'userid' => new external_value(PARAM_INT
, 'The id of the user making the request'),
874 'requesteduserid' => new external_value(PARAM_INT
, 'The id of the user being requested')
880 * Declines a contact request.
882 * @param int $userid The id of the user who is creating the contact request
883 * @param int $requesteduserid The id of the user being requested
885 public static function decline_contact_request(int $userid, int $requesteduserid) {
888 // Check if messaging is enabled.
889 if (empty($CFG->messaging
)) {
890 throw new moodle_exception('disabled', 'message');
894 $context = context_system
::instance();
895 self
::validate_context($context);
897 $capability = 'moodle/site:manageallmessaging';
898 if (($USER->id
!= $requesteduserid) && !has_capability($capability, $context)) {
899 throw new required_capability_exception($context, $capability, 'nopermissions', '');
902 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid];
903 $params = self
::validate_parameters(self
::decline_contact_request_parameters(), $params);
905 \core_message\api
::decline_contact_request($params['userid'], $params['requesteduserid']);
911 * Declines a contact request return description.
913 * @return external_description
915 public static function decline_contact_request_returns() {
916 return new external_warnings();
920 * Return the structure of a message area contact.
922 * @return external_single_structure
925 private static function get_messagearea_contact_structure() {
926 return new external_single_structure(
928 'userid' => new external_value(PARAM_INT
, 'The user\'s id'),
929 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
930 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
931 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
932 'ismessaging' => new external_value(PARAM_BOOL
, 'If we are messaging the user'),
933 'sentfromcurrentuser' => new external_value(PARAM_BOOL
, 'Was the last message sent from the current user?'),
934 'lastmessage' => new external_value(PARAM_NOTAGS
, 'The user\'s last message'),
935 'messageid' => new external_value(PARAM_INT
, 'The unique search message id', VALUE_DEFAULT
, null),
936 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
937 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
938 'isread' => new external_value(PARAM_BOOL
, 'If the user has read the message'),
939 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
940 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
941 VALUE_DEFAULT
, null),
947 * Return the structure of a conversation.
949 * @return external_single_structure
952 private static function get_conversation_structure() {
953 return new external_single_structure(
955 'id' => new external_value(PARAM_INT
, 'The conversation id'),
956 'name' => new external_value(PARAM_NOTAGS
, 'The conversation name, if set', VALUE_DEFAULT
, null),
957 'subname' => new external_value(PARAM_NOTAGS
, 'A subtitle for the conversation name, if set', VALUE_DEFAULT
, null),
958 'type' => new external_value(PARAM_INT
, 'The type of the conversation (1=individual,2=group)'),
959 'membercount' => new external_value(PARAM_INT
, 'Total number of conversation members'),
960 'isfavourite' => new external_value(PARAM_BOOL
, 'If the user marked conversation this conversation as a favourite'),
961 'isread' => new external_value(PARAM_BOOL
, 'If the user has read all messages in the conversation'),
962 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
963 VALUE_DEFAULT
, null),
964 'members' => new external_multiple_structure(
965 self
::get_conversation_member_structure()
967 'messages' => new external_multiple_structure(
968 self
::get_conversation_message_structure()
975 * Return the structure of a conversation member.
977 * @param bool $includecontactrequests Are we including contact requests?
978 * @return external_single_structure
981 private static function get_conversation_member_structure(bool $includecontactrequests = false) {
983 'id' => new external_value(PARAM_INT
, 'The user id'),
984 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
985 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
986 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
987 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
988 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
989 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
990 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?'),
993 if ($includecontactrequests) {
994 $result['contactrequests'] = new external_multiple_structure(
995 new external_single_structure(
997 'id' => new external_value(PARAM_INT
, 'The id of the message'),
998 'userid' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
999 'requesteduserid' => new external_value(PARAM_RAW
, 'The text of the message'),
1000 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1002 ), 'The contact requests', VALUE_OPTIONAL
1006 return new external_single_structure(
1012 * Return the structure of a message area message.
1014 * @return external_single_structure
1017 private static function get_conversation_message_structure() {
1018 return new external_single_structure(
1020 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1021 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1022 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
1023 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1029 * Return the structure of a message area message.
1031 * @return external_single_structure
1034 private static function get_messagearea_message_structure() {
1035 return new external_single_structure(
1037 'id' => new external_value(PARAM_INT
, 'The id of the message'),
1038 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
1039 'useridto' => new external_value(PARAM_INT
, 'The id of the user who received the message'),
1040 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
1041 'displayblocktime' => new external_value(PARAM_BOOL
, 'Should we display the block time?'),
1042 'blocktime' => new external_value(PARAM_NOTAGS
, 'The time to display above the message'),
1043 'position' => new external_value(PARAM_ALPHA
, 'The position of the text'),
1044 'timesent' => new external_value(PARAM_NOTAGS
, 'The time the message was sent'),
1045 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
1046 'isread' => new external_value(PARAM_INT
, 'Determines if the message was read or not'),
1052 * Get messagearea search users in course parameters.
1054 * @return external_function_parameters
1057 public static function data_for_messagearea_search_users_in_course_parameters() {
1058 return new external_function_parameters(
1060 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1061 'courseid' => new external_value(PARAM_INT
, 'The id of the course'),
1062 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1063 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1064 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1070 * Get messagearea search users in course results.
1072 * @param int $userid The id of the user who is performing the search
1073 * @param int $courseid The id of the course
1074 * @param string $search The string being searched
1075 * @param int $limitfrom
1076 * @param int $limitnum
1078 * @throws moodle_exception
1081 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
1083 global $CFG, $PAGE, $USER;
1085 // Check if messaging is enabled.
1086 if (empty($CFG->messaging
)) {
1087 throw new moodle_exception('disabled', 'message');
1090 $systemcontext = context_system
::instance();
1093 'userid' => $userid,
1094 'courseid' => $courseid,
1095 'search' => $search,
1096 'limitfrom' => $limitfrom,
1097 'limitnum' => $limitnum
1099 self
::validate_parameters(self
::data_for_messagearea_search_users_in_course_parameters(), $params);
1100 self
::validate_context($systemcontext);
1102 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1103 throw new moodle_exception('You do not have permission to perform this action.');
1106 $users = \core_message\api
::search_users_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
1107 $results = new \core_message\output\messagearea\
user_search_results($users);
1109 $renderer = $PAGE->get_renderer('core_message');
1110 return $results->export_for_template($renderer);
1114 * Get messagearea search users in course returns.
1116 * @return external_single_structure
1119 public static function data_for_messagearea_search_users_in_course_returns() {
1120 return new external_single_structure(
1122 'contacts' => new external_multiple_structure(
1123 self
::get_messagearea_contact_structure()
1130 * Get messagearea search users parameters.
1132 * @return external_function_parameters
1135 public static function data_for_messagearea_search_users_parameters() {
1136 return new external_function_parameters(
1138 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1139 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1140 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1146 * Get messagearea search users results.
1148 * @param int $userid The id of the user who is performing the search
1149 * @param string $search The string being searched
1150 * @param int $limitnum
1152 * @throws moodle_exception
1155 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
1156 global $CFG, $PAGE, $USER;
1158 // Check if messaging is enabled.
1159 if (empty($CFG->messaging
)) {
1160 throw new moodle_exception('disabled', 'message');
1163 $systemcontext = context_system
::instance();
1166 'userid' => $userid,
1167 'search' => $search,
1168 'limitnum' => $limitnum
1170 self
::validate_parameters(self
::data_for_messagearea_search_users_parameters(), $params);
1171 self
::validate_context($systemcontext);
1173 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1174 throw new moodle_exception('You do not have permission to perform this action.');
1177 list($contacts, $courses, $noncontacts) = \core_message\api
::search_users($userid, $search, $limitnum);
1178 $search = new \core_message\output\messagearea\
user_search_results($contacts, $courses, $noncontacts);
1180 $renderer = $PAGE->get_renderer('core_message');
1181 return $search->export_for_template($renderer);
1185 * Get messagearea search users returns.
1187 * @return external_single_structure
1190 public static function data_for_messagearea_search_users_returns() {
1191 return new external_single_structure(
1193 'contacts' => new external_multiple_structure(
1194 self
::get_messagearea_contact_structure()
1196 'courses' => new external_multiple_structure(
1197 new external_single_structure(
1199 'id' => new external_value(PARAM_INT
, 'The course id'),
1200 'shortname' => new external_value(PARAM_TEXT
, 'The course shortname'),
1201 'fullname' => new external_value(PARAM_TEXT
, 'The course fullname'),
1205 'noncontacts' => new external_multiple_structure(
1206 self
::get_messagearea_contact_structure()
1213 * Get messagearea search messages parameters.
1215 * @return external_function_parameters
1218 public static function data_for_messagearea_search_messages_parameters() {
1219 return new external_function_parameters(
1221 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
1222 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
1223 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1224 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1230 * Get messagearea search messages results.
1232 * @param int $userid The id of the user who is performing the search
1233 * @param string $search The string being searched
1234 * @param int $limitfrom
1235 * @param int $limitnum
1237 * @throws moodle_exception
1240 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
1241 global $CFG, $PAGE, $USER;
1243 // Check if messaging is enabled.
1244 if (empty($CFG->messaging
)) {
1245 throw new moodle_exception('disabled', 'message');
1248 $systemcontext = context_system
::instance();
1251 'userid' => $userid,
1252 'search' => $search,
1253 'limitfrom' => $limitfrom,
1254 'limitnum' => $limitnum
1257 self
::validate_parameters(self
::data_for_messagearea_search_messages_parameters(), $params);
1258 self
::validate_context($systemcontext);
1260 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1261 throw new moodle_exception('You do not have permission to perform this action.');
1264 $messages = \core_message\api
::search_messages($userid, $search, $limitfrom, $limitnum);
1265 $results = new \core_message\output\messagearea\
message_search_results($messages);
1267 $renderer = $PAGE->get_renderer('core_message');
1268 return $results->export_for_template($renderer);
1272 * Get messagearea search messages returns.
1274 * @return external_single_structure
1277 public static function data_for_messagearea_search_messages_returns() {
1278 return new external_single_structure(
1280 'contacts' => new external_multiple_structure(
1281 self
::get_messagearea_contact_structure()
1288 * Get conversations parameters.
1290 * @return external_function_parameters
1293 public static function get_conversations_parameters() {
1294 return new external_function_parameters(
1296 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1297 'limitfrom' => new external_value(PARAM_INT
, 'The offset to start at', VALUE_DEFAULT
, 0),
1298 'limitnum' => new external_value(PARAM_INT
, 'Limit number of conversations to this', VALUE_DEFAULT
, 0),
1299 'type' => new external_value(PARAM_INT
, 'Filter by type', VALUE_DEFAULT
, null),
1300 'favourites' => new external_value(PARAM_BOOL
, 'Whether to restrict the results to contain NO favourite
1301 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)',
1302 VALUE_DEFAULT
, null),
1309 * Get the list of conversations for the user.
1311 * @param int $userid The id of the user who is performing the search
1312 * @param int $limitfrom
1313 * @param int $limitnum
1314 * @param int|null $type
1315 * @param bool|null $favourites
1317 * @throws \moodle_exception if the messaging feature is disabled on the site.
1320 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null) {
1323 // All the standard BL checks.
1324 if (empty($CFG->messaging
)) {
1325 throw new moodle_exception('disabled', 'message');
1329 'userid' => $userid,
1330 'limitfrom' => $limitfrom,
1331 'limitnum' => $limitnum,
1333 'favourites' => $favourites
1335 self
::validate_parameters(self
::get_conversations_parameters(), $params);
1337 $systemcontext = context_system
::instance();
1338 self
::validate_context($systemcontext);
1340 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1341 throw new moodle_exception('You do not have permission to perform this action.');
1344 $conversations = \core_message\api
::get_conversations($userid, $limitfrom, $limitnum, $type, $favourites);
1345 return (object) ['conversations' => $conversations];
1349 * Get conversations returns.
1351 * @return external_single_structure
1354 public static function get_conversations_returns() {
1355 return new external_single_structure(
1357 'conversations' => new external_multiple_structure(
1358 self
::get_conversation_structure()
1365 * The messagearea conversations parameters.
1367 * @deprecated since 3.6
1368 * @return external_function_parameters
1371 public static function data_for_messagearea_conversations_parameters() {
1372 return new external_function_parameters(
1374 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
1375 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1376 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
1382 * Get messagearea conversations.
1384 * NOTE FOR FINAL DEPRECATION:
1385 * When removing this method, please also consider removal of get_conversations_legacy_formatter()
1386 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data
1387 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be
1390 * @deprecated since 3.6
1391 * @param int $userid The id of the user who we are viewing conversations for
1392 * @param int $limitfrom
1393 * @param int $limitnum
1395 * @throws moodle_exception
1398 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
1399 global $CFG, $PAGE, $USER;
1401 // Check if messaging is enabled.
1402 if (empty($CFG->messaging
)) {
1403 throw new moodle_exception('disabled', 'message');
1406 $systemcontext = context_system
::instance();
1409 'userid' => $userid,
1410 'limitfrom' => $limitfrom,
1411 'limitnum' => $limitnum
1413 self
::validate_parameters(self
::data_for_messagearea_conversations_parameters(), $params);
1414 self
::validate_context($systemcontext);
1416 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1417 throw new moodle_exception('You do not have permission to perform this action.');
1420 $conversations = \core_message\api
::get_conversations($userid, $limitfrom, $limitnum);
1422 // Format the conversations in the legacy style, as the get_conversations method has since been changed.
1423 $conversations = \core_message\helper
::get_conversations_legacy_formatter($conversations);
1425 $conversations = new \core_message\output\messagearea\
contacts(null, $conversations);
1427 $renderer = $PAGE->get_renderer('core_message');
1428 return $conversations->export_for_template($renderer);
1432 * The messagearea conversations return structure.
1434 * @deprecated since 3.6
1435 * @return external_single_structure
1438 public static function data_for_messagearea_conversations_returns() {
1439 return new external_single_structure(
1441 'contacts' => new external_multiple_structure(
1442 self
::get_messagearea_contact_structure()
1449 * Marking the method as deprecated.
1453 public static function data_for_messagearea_conversations_is_deprecated() {
1458 * The messagearea contacts return parameters.
1460 * @return external_function_parameters
1463 public static function data_for_messagearea_contacts_parameters() {
1464 return self
::data_for_messagearea_conversations_parameters();
1468 * Get messagearea contacts parameters.
1470 * @param int $userid The id of the user who we are viewing conversations for
1471 * @param int $limitfrom
1472 * @param int $limitnum
1474 * @throws moodle_exception
1477 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
1478 global $CFG, $PAGE, $USER;
1480 // Check if messaging is enabled.
1481 if (empty($CFG->messaging
)) {
1482 throw new moodle_exception('disabled', 'message');
1485 $systemcontext = context_system
::instance();
1488 'userid' => $userid,
1489 'limitfrom' => $limitfrom,
1490 'limitnum' => $limitnum
1492 self
::validate_parameters(self
::data_for_messagearea_contacts_parameters(), $params);
1493 self
::validate_context($systemcontext);
1495 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1496 throw new moodle_exception('You do not have permission to perform this action.');
1499 $contacts = \core_message\api
::get_contacts($userid, $limitfrom, $limitnum);
1500 $contacts = new \core_message\output\messagearea\
contacts(null, $contacts);
1502 $renderer = $PAGE->get_renderer('core_message');
1503 return $contacts->export_for_template($renderer);
1507 * The messagearea contacts return structure.
1509 * @return external_single_structure
1512 public static function data_for_messagearea_contacts_returns() {
1513 return self
::data_for_messagearea_conversations_returns();
1517 * The messagearea messages parameters.
1519 * @return external_function_parameters
1522 public static function data_for_messagearea_messages_parameters() {
1523 return new external_function_parameters(
1525 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1526 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
1527 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1528 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1529 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
1530 'timefrom' => new external_value(PARAM_INT
,
1531 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
1537 * Get messagearea messages.
1539 * @param int $currentuserid The current user's id
1540 * @param int $otheruserid The other user's id
1541 * @param int $limitfrom
1542 * @param int $limitnum
1543 * @param boolean $newest
1545 * @throws moodle_exception
1548 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
1549 $newest = false, $timefrom = 0) {
1550 global $CFG, $PAGE, $USER;
1552 // Check if messaging is enabled.
1553 if (empty($CFG->messaging
)) {
1554 throw new moodle_exception('disabled', 'message');
1557 $systemcontext = context_system
::instance();
1560 'currentuserid' => $currentuserid,
1561 'otheruserid' => $otheruserid,
1562 'limitfrom' => $limitfrom,
1563 'limitnum' => $limitnum,
1564 'newest' => $newest,
1565 'timefrom' => $timefrom,
1567 self
::validate_parameters(self
::data_for_messagearea_messages_parameters(), $params);
1568 self
::validate_context($systemcontext);
1570 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1571 throw new moodle_exception('You do not have permission to perform this action.');
1575 $sort = 'timecreated DESC';
1577 $sort = 'timecreated ASC';
1580 // We need to enforce a one second delay on messages to avoid race conditions of current
1581 // messages still being sent.
1583 // There is a chance that we could request messages before the current time's
1584 // second has elapsed and while other messages are being sent in that same second. In which
1585 // case those messages will be lost.
1587 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
1588 if (!empty($timefrom)) {
1589 $timeto = time() - 1;
1594 // No requesting messages from the current time, as stated above.
1595 if ($timefrom == time()) {
1598 $messages = \core_message\api
::get_messages($currentuserid, $otheruserid, $limitfrom,
1599 $limitnum, $sort, $timefrom, $timeto);
1602 $messages = new \core_message\output\messagearea\
messages($currentuserid, $otheruserid, $messages);
1604 $renderer = $PAGE->get_renderer('core_message');
1605 return $messages->export_for_template($renderer);
1609 * The messagearea messages return structure.
1611 * @return external_single_structure
1614 public static function data_for_messagearea_messages_returns() {
1615 return new external_single_structure(
1617 'iscurrentuser' => new external_value(PARAM_BOOL
, 'Is the currently logged in user the user we are viewing
1618 the messages on behalf of?'),
1619 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1620 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
1621 'otheruserfullname' => new external_value(PARAM_NOTAGS
, 'The other user\'s fullname'),
1622 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1623 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1624 'messages' => new external_multiple_structure(
1625 self
::get_messagearea_message_structure()
1627 'isblocked' => new external_value(PARAM_BOOL
, 'Is this user blocked by the current user?', VALUE_DEFAULT
, false),
1633 * The conversation messages parameters.
1635 * @return external_function_parameters
1638 public static function get_conversation_messages_parameters() {
1639 return new external_function_parameters(
1641 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1642 'convid' => new external_value(PARAM_INT
, 'The conversation id'),
1643 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
1644 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
1645 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
1646 'timefrom' => new external_value(PARAM_INT
,
1647 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
1653 * Get conversation messages.
1655 * @param int $currentuserid The current user's id.
1656 * @param int $convid The conversation id.
1657 * @param int $limitfrom Return a subset of records, starting at this point (optional).
1658 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set).
1659 * @param bool $newest True for getting first newest messages, false otherwise.
1660 * @param int $timefrom The time from the conversation messages to get.
1661 * @return stdClass The messages and members who have sent some of these messages.
1662 * @throws moodle_exception
1665 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0,
1666 bool $newest = false, int $timefrom = 0) {
1667 global $CFG, $PAGE, $USER;
1669 // Check if messaging is enabled.
1670 if (empty($CFG->messaging
)) {
1671 throw new moodle_exception('disabled', 'message');
1674 $systemcontext = context_system
::instance();
1677 'currentuserid' => $currentuserid,
1678 'convid' => $convid,
1679 'limitfrom' => $limitfrom,
1680 'limitnum' => $limitnum,
1681 'newest' => $newest,
1682 'timefrom' => $timefrom,
1684 self
::validate_parameters(self
::get_conversation_messages_parameters(), $params);
1685 self
::validate_context($systemcontext);
1687 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1688 throw new moodle_exception('You do not have permission to perform this action.');
1691 $sort = $newest ?
'timecreated DESC' : 'timecreated ASC';
1693 // We need to enforce a one second delay on messages to avoid race conditions of current
1694 // messages still being sent.
1696 // There is a chance that we could request messages before the current time's
1697 // second has elapsed and while other messages are being sent in that same second. In which
1698 // case those messages will be lost.
1700 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
1701 $timeto = empty($timefrom) ?
0 : time() - 1;
1703 // No requesting messages from the current time, as stated above.
1704 if ($timefrom == time()) {
1707 $messages = \core_message\api
::get_conversation_messages($currentuserid, $convid, $limitfrom,
1708 $limitnum, $sort, $timefrom, $timeto);
1715 * The messagearea messages return structure.
1717 * @return external_single_structure
1720 public static function get_conversation_messages_returns() {
1721 return new external_single_structure(
1723 'id' => new external_value(PARAM_INT
, 'The conversation id'),
1724 'members' => new external_multiple_structure(
1725 self
::get_conversation_member_structure()
1727 'messages' => new external_multiple_structure(
1728 self
::get_conversation_message_structure()
1735 * The get most recent message return parameters.
1737 * @return external_function_parameters
1740 public static function data_for_messagearea_get_most_recent_message_parameters() {
1741 return new external_function_parameters(
1743 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1744 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
1750 * Get the most recent message in a conversation.
1752 * @param int $currentuserid The current user's id
1753 * @param int $otheruserid The other user's id
1755 * @throws moodle_exception
1758 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
1759 global $CFG, $PAGE, $USER;
1761 // Check if messaging is enabled.
1762 if (empty($CFG->messaging
)) {
1763 throw new moodle_exception('disabled', 'message');
1766 $systemcontext = context_system
::instance();
1769 'currentuserid' => $currentuserid,
1770 'otheruserid' => $otheruserid
1772 self
::validate_parameters(self
::data_for_messagearea_get_most_recent_message_parameters(), $params);
1773 self
::validate_context($systemcontext);
1775 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1776 throw new moodle_exception('You do not have permission to perform this action.');
1779 $message = \core_message\api
::get_most_recent_message($currentuserid, $otheruserid);
1780 $message = new \core_message\output\messagearea\
message($message);
1782 $renderer = $PAGE->get_renderer('core_message');
1783 return $message->export_for_template($renderer);
1787 * The get most recent message return structure.
1789 * @return external_single_structure
1792 public static function data_for_messagearea_get_most_recent_message_returns() {
1793 return self
::get_messagearea_message_structure();
1797 * The get profile parameters.
1799 * @return external_function_parameters
1802 public static function data_for_messagearea_get_profile_parameters() {
1803 return new external_function_parameters(
1805 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1806 'otheruserid' => new external_value(PARAM_INT
, 'The id of the user whose profile we want to view'),
1812 * Get the profile information for a contact.
1814 * @param int $currentuserid The current user's id
1815 * @param int $otheruserid The id of the user whose profile we are viewing
1817 * @throws moodle_exception
1820 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
1821 global $CFG, $PAGE, $USER;
1823 // Check if messaging is enabled.
1824 if (empty($CFG->messaging
)) {
1825 throw new moodle_exception('disabled', 'message');
1828 $systemcontext = context_system
::instance();
1831 'currentuserid' => $currentuserid,
1832 'otheruserid' => $otheruserid
1834 self
::validate_parameters(self
::data_for_messagearea_get_profile_parameters(), $params);
1835 self
::validate_context($systemcontext);
1837 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1838 throw new moodle_exception('You do not have permission to perform this action.');
1841 $profile = \core_message\api
::get_profile($currentuserid, $otheruserid);
1842 $profile = new \core_message\output\messagearea\
profile($profile);
1844 $renderer = $PAGE->get_renderer('core_message');
1845 return $profile->export_for_template($renderer);
1849 * The get profile return structure.
1851 * @return external_single_structure
1854 public static function data_for_messagearea_get_profile_returns() {
1855 return new external_single_structure(
1857 'userid' => new external_value(PARAM_INT
, 'The id of the user whose profile we are viewing'),
1858 'email' => new external_value(core_user
::get_property_type('email'), 'An email address'),
1859 'country' => new external_value(PARAM_TEXT
, 'Home country of the user'),
1860 'city' => new external_value(core_user
::get_property_type('city'), 'Home city of the user'),
1861 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
1862 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
1863 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
1864 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1865 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1866 'isblocked' => new external_value(PARAM_BOOL
, 'Is the user blocked?'),
1867 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?')
1873 * Get contacts parameters description.
1875 * @return external_function_parameters
1878 public static function get_contacts_parameters() {
1879 return new external_function_parameters(array());
1885 * @return external_description
1888 public static function get_contacts() {
1889 global $CFG, $PAGE, $USER;
1891 // Check if messaging is enabled.
1892 if (empty($CFG->messaging
)) {
1893 throw new moodle_exception('disabled', 'message');
1896 require_once($CFG->dirroot
. '/user/lib.php');
1898 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []);
1899 $contacts = \core_message\api
::get_contacts_with_unread_message_count($USER->id
);
1900 foreach ($contacts as $contact) {
1903 if (\core_message\helper
::is_online($contact->lastaccess
)) {
1907 $newcontact = array(
1908 'id' => $contact->id
,
1909 'fullname' => fullname($contact),
1910 'unread' => $contact->messagecount
1913 $userpicture = new user_picture($contact);
1914 $userpicture->size
= 1; // Size f1.
1915 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1916 $userpicture->size
= 0; // Size f2.
1917 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1919 $allcontacts[$mode][$contact->id
] = $newcontact;
1922 $strangers = \core_message\api
::get_non_contacts_with_unread_message_count($USER->id
);
1923 foreach ($strangers as $contact) {
1924 $newcontact = array(
1925 'id' => $contact->id
,
1926 'fullname' => fullname($contact),
1927 'unread' => $contact->messagecount
1930 $userpicture = new user_picture($contact);
1931 $userpicture->size
= 1; // Size f1.
1932 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1933 $userpicture->size
= 0; // Size f2.
1934 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1936 $allcontacts['strangers'][$contact->id
] = $newcontact;
1939 // Add noreply user and support user to the list, if they don't exist.
1940 $supportuser = core_user
::get_support_user();
1941 if (!isset($strangers[$supportuser->id
]) && !$supportuser->deleted
) {
1942 $supportuser->messagecount
= message_count_unread_messages($USER, $supportuser);
1943 if ($supportuser->messagecount
> 0) {
1944 $supportuser->fullname
= fullname($supportuser);
1945 $supportuser->unread
= $supportuser->messagecount
;
1946 $allcontacts['strangers'][$supportuser->id
] = $supportuser;
1950 $noreplyuser = core_user
::get_noreply_user();
1951 if (!isset($strangers[$noreplyuser->id
]) && !$noreplyuser->deleted
) {
1952 $noreplyuser->messagecount
= message_count_unread_messages($USER, $noreplyuser);
1953 if ($noreplyuser->messagecount
> 0) {
1954 $noreplyuser->fullname
= fullname($noreplyuser);
1955 $noreplyuser->unread
= $noreplyuser->messagecount
;
1956 $allcontacts['strangers'][$noreplyuser->id
] = $noreplyuser;
1960 return $allcontacts;
1964 * Get contacts return description.
1966 * @return external_description
1969 public static function get_contacts_returns() {
1970 return new external_single_structure(
1972 'online' => new external_multiple_structure(
1973 new external_single_structure(
1975 'id' => new external_value(PARAM_INT
, 'User ID'),
1976 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1977 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1978 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
1979 'unread' => new external_value(PARAM_INT
, 'Unread message count')
1982 'List of online contacts'
1984 'offline' => new external_multiple_structure(
1985 new external_single_structure(
1987 'id' => new external_value(PARAM_INT
, 'User ID'),
1988 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1989 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1990 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
1991 'unread' => new external_value(PARAM_INT
, 'Unread message count')
1994 'List of offline contacts'
1996 'strangers' => new external_multiple_structure(
1997 new external_single_structure(
1999 'id' => new external_value(PARAM_INT
, 'User ID'),
2000 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2001 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
2002 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
2003 'unread' => new external_value(PARAM_INT
, 'Unread message count')
2006 'List of users that are not in the user\'s contact list but have sent a message'
2013 * Search contacts parameters description.
2015 * @return external_function_parameters
2018 public static function search_contacts_parameters() {
2019 return new external_function_parameters(
2021 'searchtext' => new external_value(PARAM_CLEAN
, 'String the user\'s fullname has to match to be found'),
2022 'onlymycourses' => new external_value(PARAM_BOOL
, 'Limit search to the user\'s courses',
2023 VALUE_DEFAULT
, false)
2031 * @param string $searchtext query string.
2032 * @param bool $onlymycourses limit the search to the user's courses only.
2033 * @return external_description
2036 public static function search_contacts($searchtext, $onlymycourses = false) {
2037 global $CFG, $USER, $PAGE;
2038 require_once($CFG->dirroot
. '/user/lib.php');
2040 // Check if messaging is enabled.
2041 if (empty($CFG->messaging
)) {
2042 throw new moodle_exception('disabled', 'message');
2045 require_once($CFG->libdir
. '/enrollib.php');
2047 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
2048 $params = self
::validate_parameters(self
::search_contacts_parameters(), $params);
2050 // Extra validation, we do not allow empty queries.
2051 if ($params['searchtext'] === '') {
2052 throw new moodle_exception('querystringcannotbeempty');
2055 $courseids = array();
2056 if ($params['onlymycourses']) {
2057 $mycourses = enrol_get_my_courses(array('id'));
2058 foreach ($mycourses as $mycourse) {
2059 $courseids[] = $mycourse->id
;
2062 $courseids[] = SITEID
;
2065 // Retrieving the users matching the query.
2066 $users = message_search_users($courseids, $params['searchtext']);
2068 foreach ($users as $user) {
2069 $results[$user->id
] = $user;
2072 // Reorganising information.
2073 foreach ($results as &$user) {
2076 'fullname' => fullname($user)
2079 // Avoid undefined property notice as phone not specified.
2080 $user->phone1
= null;
2081 $user->phone2
= null;
2083 $userpicture = new user_picture($user);
2084 $userpicture->size
= 1; // Size f1.
2085 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2086 $userpicture->size
= 0; // Size f2.
2087 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
2096 * Search contacts return description.
2098 * @return external_description
2101 public static function search_contacts_returns() {
2102 return new external_multiple_structure(
2103 new external_single_structure(
2105 'id' => new external_value(PARAM_INT
, 'User ID'),
2106 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2107 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
2108 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
)
2116 * Get messages parameters description.
2118 * @return external_function_parameters
2121 public static function get_messages_parameters() {
2122 return new external_function_parameters(
2124 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2125 'useridfrom' => new external_value(
2126 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2128 'type' => new external_value(
2129 PARAM_ALPHA
, 'type of message to return, expected values are: notifications, conversations and both',
2130 VALUE_DEFAULT
, 'both'),
2131 'read' => new external_value(PARAM_BOOL
, 'true for getting read messages, false for unread', VALUE_DEFAULT
, true),
2132 'newestfirst' => new external_value(
2133 PARAM_BOOL
, 'true for ordering by newest first, false for oldest first',
2134 VALUE_DEFAULT
, true),
2135 'limitfrom' => new external_value(PARAM_INT
, 'limit from', VALUE_DEFAULT
, 0),
2136 'limitnum' => new external_value(PARAM_INT
, 'limit number', VALUE_DEFAULT
, 0)
2142 * Get messages function implementation.
2145 * @throws invalid_parameter_exception
2146 * @throws moodle_exception
2147 * @param int $useridto the user id who received the message
2148 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2149 * @param string $type type of message to return, expected values: notifications, conversations and both
2150 * @param bool $read true for retreiving read messages, false for unread
2151 * @param bool $newestfirst true for ordering by newest first, false for oldest first
2152 * @param int $limitfrom limit from
2153 * @param int $limitnum limit num
2154 * @return external_description
2156 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
2157 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
2160 $warnings = array();
2163 'useridto' => $useridto,
2164 'useridfrom' => $useridfrom,
2167 'newestfirst' => $newestfirst,
2168 'limitfrom' => $limitfrom,
2169 'limitnum' => $limitnum
2172 $params = self
::validate_parameters(self
::get_messages_parameters(), $params);
2174 $context = context_system
::instance();
2175 self
::validate_context($context);
2177 $useridto = $params['useridto'];
2178 $useridfrom = $params['useridfrom'];
2179 $type = $params['type'];
2180 $read = $params['read'];
2181 $newestfirst = $params['newestfirst'];
2182 $limitfrom = $params['limitfrom'];
2183 $limitnum = $params['limitnum'];
2185 $allowedvalues = array('notifications', 'conversations', 'both');
2186 if (!in_array($type, $allowedvalues)) {
2187 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
2188 'allowed values are: ' . implode(',', $allowedvalues));
2191 // Check if private messaging between users is allowed.
2192 if (empty($CFG->messaging
)) {
2193 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
2194 if ($type == "conversations") {
2195 throw new moodle_exception('disabled', 'message');
2197 if ($type == "both") {
2199 $warning['item'] = 'message';
2200 $warning['itemid'] = $USER->id
;
2201 $warning['warningcode'] = '1';
2202 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
2203 Only notifications will be returned';
2204 $warnings[] = $warning;
2208 if (!empty($useridto)) {
2209 if (core_user
::is_real_user($useridto)) {
2210 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2212 throw new moodle_exception('invaliduser');
2216 if (!empty($useridfrom)) {
2217 // We use get_user here because the from user can be the noreply or support user.
2218 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2221 // Check if the current user is the sender/receiver or just a privileged user.
2222 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2223 !has_capability('moodle/site:readallmessages', $context)) {
2224 throw new moodle_exception('accessdenied', 'admin');
2227 // Which type of messages to retrieve.
2228 $notifications = -1;
2229 if ($type != 'both') {
2230 $notifications = ($type == 'notifications') ?
1 : 0;
2233 $orderdirection = $newestfirst ?
'DESC' : 'ASC';
2234 $sort = "mr.timecreated $orderdirection";
2236 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
2237 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
2239 // In some cases, we don't need to get the to/from user objects from the sql query.
2240 $userfromfullname = '';
2241 $usertofullname = '';
2243 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
2244 if (!empty($useridto)) {
2245 $usertofullname = fullname($userto, $canviewfullname);
2246 // The user from may or may not be filled.
2247 if (!empty($useridfrom)) {
2248 $userfromfullname = fullname($userfrom, $canviewfullname);
2251 // If the useridto field is empty, the useridfrom must be filled.
2252 $userfromfullname = fullname($userfrom, $canviewfullname);
2254 foreach ($messages as $mid => $message) {
2256 // Do not return deleted messages.
2257 if (!$message->notification
) {
2258 if (($useridto == $USER->id
and $message->timeusertodeleted
) or
2259 ($useridfrom == $USER->id
and $message->timeuserfromdeleted
)) {
2260 unset($messages[$mid]);
2265 // We need to get the user from the query.
2266 if (empty($userfromfullname)) {
2267 // Check for non-reply and support users.
2268 if (core_user
::is_real_user($message->useridfrom
)) {
2269 $user = new stdClass();
2270 $user = username_load_fields_from_object($user, $message, 'userfrom');
2271 $message->userfromfullname
= fullname($user, $canviewfullname);
2273 $user = core_user
::get_user($message->useridfrom
);
2274 $message->userfromfullname
= fullname($user, $canviewfullname);
2277 $message->userfromfullname
= $userfromfullname;
2280 // We need to get the user from the query.
2281 if (empty($usertofullname)) {
2282 $user = new stdClass();
2283 $user = username_load_fields_from_object($user, $message, 'userto');
2284 $message->usertofullname
= fullname($user, $canviewfullname);
2286 $message->usertofullname
= $usertofullname;
2289 $message->text
= message_format_message_text($message);
2290 $messages[$mid] = (array) $message;
2295 'messages' => $messages,
2296 'warnings' => $warnings
2303 * Get messages return description.
2305 * @return external_single_structure
2308 public static function get_messages_returns() {
2309 return new external_single_structure(
2311 'messages' => new external_multiple_structure(
2312 new external_single_structure(
2314 'id' => new external_value(PARAM_INT
, 'Message id'),
2315 'useridfrom' => new external_value(PARAM_INT
, 'User from id'),
2316 'useridto' => new external_value(PARAM_INT
, 'User to id'),
2317 'subject' => new external_value(PARAM_TEXT
, 'The message subject'),
2318 'text' => new external_value(PARAM_RAW
, 'The message text formated'),
2319 'fullmessage' => new external_value(PARAM_RAW
, 'The message'),
2320 'fullmessageformat' => new external_format_value('fullmessage'),
2321 'fullmessagehtml' => new external_value(PARAM_RAW
, 'The message in html'),
2322 'smallmessage' => new external_value(PARAM_RAW
, 'The shorten message'),
2323 'notification' => new external_value(PARAM_INT
, 'Is a notification?'),
2324 'contexturl' => new external_value(PARAM_RAW
, 'Context URL'),
2325 'contexturlname' => new external_value(PARAM_TEXT
, 'Context URL link name'),
2326 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
2327 'timeread' => new external_value(PARAM_INT
, 'Time read'),
2328 'usertofullname' => new external_value(PARAM_TEXT
, 'User to full name'),
2329 'userfromfullname' => new external_value(PARAM_TEXT
, 'User from full name')
2333 'warnings' => new external_warnings()
2339 * Mark all notifications as read parameters description.
2341 * @return external_function_parameters
2344 public static function mark_all_notifications_as_read_parameters() {
2345 return new external_function_parameters(
2347 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2348 'useridfrom' => new external_value(
2349 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2356 * Mark all notifications as read function.
2359 * @throws invalid_parameter_exception
2360 * @throws moodle_exception
2361 * @param int $useridto the user id who received the message
2362 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2363 * @return external_description
2365 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
2368 $params = self
::validate_parameters(
2369 self
::mark_all_notifications_as_read_parameters(),
2371 'useridto' => $useridto,
2372 'useridfrom' => $useridfrom,
2376 $context = context_system
::instance();
2377 self
::validate_context($context);
2379 $useridto = $params['useridto'];
2380 $useridfrom = $params['useridfrom'];
2382 if (!empty($useridto)) {
2383 if (core_user
::is_real_user($useridto)) {
2384 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2386 throw new moodle_exception('invaliduser');
2390 if (!empty($useridfrom)) {
2391 // We use get_user here because the from user can be the noreply or support user.
2392 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2395 // Check if the current user is the sender/receiver or just a privileged user.
2396 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2397 // The deleteanymessage cap seems more reasonable here than readallmessages.
2398 !has_capability('moodle/site:deleteanymessage', $context)) {
2399 throw new moodle_exception('accessdenied', 'admin');
2402 \core_message\api
::mark_all_notifications_as_read($useridto, $useridfrom);
2408 * Mark all notifications as read return description.
2410 * @return external_single_structure
2413 public static function mark_all_notifications_as_read_returns() {
2414 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
2418 * Get unread conversations count parameters description.
2420 * @return external_function_parameters
2423 public static function get_unread_conversations_count_parameters() {
2424 return new external_function_parameters(
2426 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2432 * Get unread messages count function.
2435 * @throws invalid_parameter_exception
2436 * @throws moodle_exception
2437 * @param int $useridto the user id who received the message
2438 * @return external_description
2440 public static function get_unread_conversations_count($useridto) {
2443 // Check if messaging is enabled.
2444 if (empty($CFG->messaging
)) {
2445 throw new moodle_exception('disabled', 'message');
2448 $params = self
::validate_parameters(
2449 self
::get_unread_conversations_count_parameters(),
2450 array('useridto' => $useridto)
2453 $context = context_system
::instance();
2454 self
::validate_context($context);
2456 $useridto = $params['useridto'];
2458 if (!empty($useridto)) {
2459 if (core_user
::is_real_user($useridto)) {
2460 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2462 throw new moodle_exception('invaliduser');
2465 $useridto = $USER->id
;
2468 // Check if the current user is the receiver or just a privileged user.
2469 if ($useridto != $USER->id
and !has_capability('moodle/site:readallmessages', $context)) {
2470 throw new moodle_exception('accessdenied', 'admin');
2473 return \core_message\api
::count_unread_conversations($userto);
2477 * Get unread conversations count return description.
2479 * @return external_single_structure
2482 public static function get_unread_conversations_count_returns() {
2483 return new external_value(PARAM_INT
, 'The count of unread messages for the user');
2487 * Get blocked users parameters description.
2489 * @return external_function_parameters
2492 public static function get_blocked_users_parameters() {
2493 return new external_function_parameters(
2495 'userid' => new external_value(PARAM_INT
,
2496 'the user whose blocked users we want to retrieve',
2503 * Retrieve a list of users blocked
2505 * @param int $userid the user whose blocked users we want to retrieve
2506 * @return external_description
2509 public static function get_blocked_users($userid) {
2510 global $CFG, $USER, $PAGE;
2512 // Warnings array, it can be empty at the end but is mandatory.
2513 $warnings = array();
2519 $params = self
::validate_parameters(self
::get_blocked_users_parameters(), $params);
2520 $userid = $params['userid'];
2522 // Validate context.
2523 $context = context_system
::instance();
2524 self
::validate_context($context);
2526 // Check if private messaging between users is allowed.
2527 if (empty($CFG->messaging
)) {
2528 throw new moodle_exception('disabled', 'message');
2531 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
2532 core_user
::require_active_user($user);
2534 // Check if we have permissions for retrieve the information.
2535 $capability = 'moodle/site:manageallmessaging';
2536 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
2537 throw new required_capability_exception($context, $capability, 'nopermissions', '');
2540 // Now, we can get safely all the blocked users.
2541 $users = \core_message\api
::get_blocked_users($user->id
);
2543 $blockedusers = array();
2544 foreach ($users as $user) {
2547 'fullname' => fullname($user),
2550 $userpicture = new user_picture($user);
2551 $userpicture->size
= 1; // Size f1.
2552 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
2554 $blockedusers[] = $newuser;
2558 'users' => $blockedusers,
2559 'warnings' => $warnings
2565 * Get blocked users return description.
2567 * @return external_single_structure
2570 public static function get_blocked_users_returns() {
2571 return new external_single_structure(
2573 'users' => new external_multiple_structure(
2574 new external_single_structure(
2576 'id' => new external_value(PARAM_INT
, 'User ID'),
2577 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
2578 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
)
2581 'List of blocked users'
2583 'warnings' => new external_warnings()
2589 * Returns description of method parameters
2591 * @return external_function_parameters
2594 public static function mark_message_read_parameters() {
2595 return new external_function_parameters(
2597 'messageid' => new external_value(PARAM_INT
, 'id of the message in the messages table'),
2598 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the message should be marked read',
2605 * Mark a single message as read, trigger message_viewed event
2607 * @param int $messageid id of the message (in the message table)
2608 * @param int $timeread timestamp for when the message should be marked read
2609 * @return external_description
2610 * @throws invalid_parameter_exception
2611 * @throws moodle_exception
2614 public static function mark_message_read($messageid, $timeread) {
2615 global $CFG, $DB, $USER;
2617 // Check if private messaging between users is allowed.
2618 if (empty($CFG->messaging
)) {
2619 throw new moodle_exception('disabled', 'message');
2622 // Warnings array, it can be empty at the end but is mandatory.
2623 $warnings = array();
2627 'messageid' => $messageid,
2628 'timeread' => $timeread
2630 $params = self
::validate_parameters(self
::mark_message_read_parameters(), $params);
2632 if (empty($params['timeread'])) {
2635 $timeread = $params['timeread'];
2638 // Validate context.
2639 $context = context_system
::instance();
2640 self
::validate_context($context);
2642 $sql = "SELECT m.*, mcm.userid as useridto
2644 INNER JOIN {message_conversations} mc
2645 ON m.conversationid = mc.id
2646 INNER JOIN {message_conversation_members} mcm
2647 ON mcm.conversationid = mc.id
2648 LEFT JOIN {message_user_actions} mua
2649 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?)
2650 WHERE mua.id is NULL
2651 AND mcm.userid != m.useridfrom
2653 $messageparams = [];
2654 $messageparams[] = $USER->id
;
2655 $messageparams[] = \core_message\api
::MESSAGE_ACTION_READ
;
2656 $messageparams[] = $params['messageid'];
2657 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST
);
2659 if ($message->useridto
!= $USER->id
) {
2660 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
2663 \core_message\api
::mark_message_as_read($USER->id
, $message, $timeread);
2666 'messageid' => $message->id
,
2667 'warnings' => $warnings
2673 * Returns description of method result value
2675 * @return external_description
2678 public static function mark_message_read_returns() {
2679 return new external_single_structure(
2681 'messageid' => new external_value(PARAM_INT
, 'the id of the message in the messages table'),
2682 'warnings' => new external_warnings()
2688 * Returns description of method parameters
2690 * @return external_function_parameters
2692 public static function mark_notification_read_parameters() {
2693 return new external_function_parameters(
2695 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
2696 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the notification should be marked read',
2703 * Mark a single notification as read.
2705 * This will trigger a 'notification_viewed' event.
2707 * @param int $notificationid id of the notification
2708 * @param int $timeread timestamp for when the notification should be marked read
2709 * @return external_description
2710 * @throws invalid_parameter_exception
2711 * @throws moodle_exception
2713 public static function mark_notification_read($notificationid, $timeread) {
2714 global $CFG, $DB, $USER;
2716 // Check if private messaging between users is allowed.
2717 if (empty($CFG->messaging
)) {
2718 throw new moodle_exception('disabled', 'message');
2721 // Warnings array, it can be empty at the end but is mandatory.
2722 $warnings = array();
2726 'notificationid' => $notificationid,
2727 'timeread' => $timeread
2729 $params = self
::validate_parameters(self
::mark_notification_read_parameters(), $params);
2731 if (empty($params['timeread'])) {
2734 $timeread = $params['timeread'];
2737 // Validate context.
2738 $context = context_system
::instance();
2739 self
::validate_context($context);
2741 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST
);
2743 if ($notification->useridto
!= $USER->id
) {
2744 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' .
2745 'notification as read');
2748 \core_message\api
::mark_notification_as_read($notification, $timeread);
2751 'notificationid' => $notification->id
,
2752 'warnings' => $warnings
2759 * Returns description of method result value
2761 * @return external_description
2763 public static function mark_notification_read_returns() {
2764 return new external_single_structure(
2766 'notificationid' => new external_value(PARAM_INT
, 'id of the notification'),
2767 'warnings' => new external_warnings()
2773 * Mark all messages as read parameters description.
2775 * @deprecated since 3.6
2776 * @return external_function_parameters
2779 public static function mark_all_messages_as_read_parameters() {
2780 return new external_function_parameters(
2782 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
2783 'useridfrom' => new external_value(
2784 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
2791 * Mark all messages as read function.
2793 * @deprecated since 3.6
2794 * @throws invalid_parameter_exception
2795 * @throws moodle_exception
2796 * @param int $useridto the user id who received the message
2797 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
2798 * @return external_description
2801 public static function mark_all_messages_as_read($useridto, $useridfrom) {
2804 // Check if messaging is enabled.
2805 if (empty($CFG->messaging
)) {
2806 throw new moodle_exception('disabled', 'message');
2809 $params = self
::validate_parameters(
2810 self
::mark_all_messages_as_read_parameters(),
2812 'useridto' => $useridto,
2813 'useridfrom' => $useridfrom,
2817 $context = context_system
::instance();
2818 self
::validate_context($context);
2820 $useridto = $params['useridto'];
2821 $useridfrom = $params['useridfrom'];
2823 if (!empty($useridto)) {
2824 if (core_user
::is_real_user($useridto)) {
2825 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
2827 throw new moodle_exception('invaliduser');
2831 if (!empty($useridfrom)) {
2832 // We use get_user here because the from user can be the noreply or support user.
2833 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
2836 // Check if the current user is the sender/receiver or just a privileged user.
2837 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
2838 // The deleteanymessage cap seems more reasonable here than readallmessages.
2839 !has_capability('moodle/site:deleteanymessage', $context)) {
2840 throw new moodle_exception('accessdenied', 'admin');
2844 if ($conversationid = \core_message\api
::get_conversation_between_users([$useridto, $useridfrom])) {
2845 \core_message\api
::mark_all_messages_as_read($useridto, $conversationid);
2848 \core_message\api
::mark_all_messages_as_read($useridto);
2855 * Mark all messages as read return description.
2857 * @deprecated since 3.6
2858 * @return external_single_structure
2861 public static function mark_all_messages_as_read_returns() {
2862 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
2866 * Marking the method as deprecated.
2870 public static function mark_all_messages_as_read_is_deprecated() {
2875 * Mark all conversation messages as read parameters description.
2877 * @return external_function_parameters
2880 public static function mark_all_conversation_messages_as_read_parameters() {
2881 return new external_function_parameters(
2883 'userid' => new external_value(PARAM_INT
, 'The user id who who we are marking the messages as read for'),
2885 new external_value(PARAM_INT
, 'The conversation id who who we are marking the messages as read for')
2891 * Mark all conversation messages as read function.
2893 * @param int $userid The user id of who we want to delete the conversation for
2894 * @param int $conversationid The id of the conversations
2897 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) {
2900 // Check if messaging is enabled.
2901 if (empty($CFG->messaging
)) {
2902 throw new moodle_exception('disabled', 'message');
2906 'userid' => $userid,
2907 'conversationid' => $conversationid,
2909 $params = self
::validate_parameters(self
::mark_all_conversation_messages_as_read_parameters(), $params);
2911 $context = context_system
::instance();
2912 self
::validate_context($context);
2914 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2915 core_user
::require_active_user($user);
2917 if (\core_message\api
::can_mark_all_messages_as_read($userid, $conversationid)) {
2918 \core_message\api
::mark_all_messages_as_read($userid, $conversationid);
2920 throw new moodle_exception('accessdenied', 'admin');
2925 * Mark all conversation messages as read return description.
2927 * @return external_warnings
2930 public static function mark_all_conversation_messages_as_read_returns() {
2931 return new external_warnings();
2935 * Returns description of method parameters.
2937 * @deprecated since 3.6
2938 * @return external_function_parameters
2941 public static function delete_conversation_parameters() {
2942 return new external_function_parameters(
2944 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
2945 'otheruserid' => new external_value(PARAM_INT
, 'The user id of the other user in the conversation'),
2951 * Deletes a conversation.
2953 * @deprecated since 3.6
2954 * @param int $userid The user id of who we want to delete the conversation for
2955 * @param int $otheruserid The user id of the other user in the conversation
2957 * @throws moodle_exception
2960 public static function delete_conversation($userid, $otheruserid) {
2963 // Check if private messaging between users is allowed.
2964 if (empty($CFG->messaging
)) {
2965 throw new moodle_exception('disabled', 'message');
2968 // Warnings array, it can be empty at the end but is mandatory.
2969 $warnings = array();
2973 'userid' => $userid,
2974 'otheruserid' => $otheruserid,
2976 $params = self
::validate_parameters(self
::delete_conversation_parameters(), $params);
2978 // Validate context.
2979 $context = context_system
::instance();
2980 self
::validate_context($context);
2982 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2983 core_user
::require_active_user($user);
2985 if (!$conversationid = \core_message\api
::get_conversation_between_users([$userid, $otheruserid])) {
2989 if (\core_message\api
::can_delete_conversation($user->id
, $conversationid)) {
2990 \core_message\api
::delete_conversation_by_id($user->id
, $conversationid);
2993 throw new moodle_exception('You do not have permission to delete messages');
2997 'status' => $status,
2998 'warnings' => $warnings
3005 * Returns description of method result value.
3007 * @deprecated since 3.6
3008 * @return external_description
3011 public static function delete_conversation_returns() {
3012 return new external_single_structure(
3014 'status' => new external_value(PARAM_BOOL
, 'True if the conversation was deleted, false otherwise'),
3015 'warnings' => new external_warnings()
3021 * Marking the method as deprecated.
3025 public static function delete_conversation_is_deprecated() {
3030 * Returns description of method parameters.
3032 * @return external_function_parameters
3035 public static function delete_conversations_by_id_parameters() {
3036 return new external_function_parameters(
3038 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
3039 'conversationids' => new external_multiple_structure(
3040 new external_value(PARAM_INT
, 'The id of the conversation'),
3041 'List of conversation IDs'
3048 * Deletes a conversation.
3050 * @param int $userid The user id of who we want to delete the conversation for
3051 * @param int[] $conversationids The ids of the conversations
3053 * @throws moodle_exception
3056 public static function delete_conversations_by_id($userid, array $conversationids) {
3059 // Check if private messaging between users is allowed.
3060 if (empty($CFG->messaging
)) {
3061 throw new moodle_exception('disabled', 'message');
3066 'userid' => $userid,
3067 'conversationids' => $conversationids,
3069 $params = self
::validate_parameters(self
::delete_conversations_by_id_parameters(), $params);
3071 // Validate context.
3072 $context = context_system
::instance();
3073 self
::validate_context($context);
3075 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3076 core_user
::require_active_user($user);
3078 foreach ($conversationids as $conversationid) {
3079 if (\core_message\api
::can_delete_conversation($user->id
, $conversationid)) {
3080 \core_message\api
::delete_conversation_by_id($user->id
, $conversationid);
3082 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'");
3090 * Returns description of method result value.
3092 * @return external_description
3095 public static function delete_conversations_by_id_returns() {
3096 return new external_warnings();
3100 * Returns description of method parameters
3102 * @return external_function_parameters
3105 public static function delete_message_parameters() {
3106 return new external_function_parameters(
3108 'messageid' => new external_value(PARAM_INT
, 'The message id'),
3109 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for'),
3110 'read' => new external_value(PARAM_BOOL
, 'If is a message read', VALUE_DEFAULT
, true)
3118 * @param int $messageid the message id
3119 * @param int $userid the user id of who we want to delete the message for
3120 * @param bool $read if is a message read (default to true)
3121 * @return external_description
3122 * @throws moodle_exception
3125 public static function delete_message($messageid, $userid, $read = true) {
3128 // Check if private messaging between users is allowed.
3129 if (empty($CFG->messaging
)) {
3130 throw new moodle_exception('disabled', 'message');
3133 // Warnings array, it can be empty at the end but is mandatory.
3134 $warnings = array();
3138 'messageid' => $messageid,
3139 'userid' => $userid,
3142 $params = self
::validate_parameters(self
::delete_message_parameters(), $params);
3144 // Validate context.
3145 $context = context_system
::instance();
3146 self
::validate_context($context);
3148 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3149 core_user
::require_active_user($user);
3151 if (\core_message\api
::can_delete_message($user->id
, $messageid)) {
3152 $status = \core_message\api
::delete_message($user->id
, $messageid);
3154 throw new moodle_exception('You do not have permission to delete this message');
3158 'status' => $status,
3159 'warnings' => $warnings
3165 * Returns description of method result value
3167 * @return external_description
3170 public static function delete_message_returns() {
3171 return new external_single_structure(
3173 'status' => new external_value(PARAM_BOOL
, 'True if the message was deleted, false otherwise'),
3174 'warnings' => new external_warnings()
3180 * Returns description of method parameters
3182 * @return external_function_parameters
3185 public static function message_processor_config_form_parameters() {
3186 return new external_function_parameters(
3188 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_REQUIRED
),
3189 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor'),
3190 'formvalues' => new external_multiple_structure(
3191 new external_single_structure(
3193 'name' => new external_value(PARAM_TEXT
, 'name of the form element', VALUE_REQUIRED
),
3194 'value' => new external_value(PARAM_RAW
, 'value of the form element', VALUE_REQUIRED
),
3197 'Config form values',
3205 * Processes a message processor config form.
3207 * @param int $userid the user id
3208 * @param string $name the name of the processor
3209 * @param array $formvalues the form values
3210 * @return external_description
3211 * @throws moodle_exception
3214 public static function message_processor_config_form($userid, $name, $formvalues) {
3217 // Check if messaging is enabled.
3218 if (empty($CFG->messaging
)) {
3219 throw new moodle_exception('disabled', 'message');
3222 $params = self
::validate_parameters(
3223 self
::message_processor_config_form_parameters(),
3225 'userid' => $userid,
3227 'formvalues' => $formvalues,
3231 $user = self
::validate_preferences_permissions($params['userid']);
3233 $processor = get_message_processor($name);
3235 $form = new stdClass();
3237 foreach ($formvalues as $formvalue) {
3238 // Curly braces to ensure interpretation is consistent between
3240 $form->{$formvalue['name']} = $formvalue['value'];
3243 $processor->process_form($form, $preferences);
3245 if (!empty($preferences)) {
3246 set_user_preferences($preferences, $userid);
3251 * Returns description of method result value
3253 * @return external_description
3256 public static function message_processor_config_form_returns() {
3261 * Returns description of method parameters
3263 * @return external_function_parameters
3266 public static function get_message_processor_parameters() {
3267 return new external_function_parameters(
3269 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user'),
3270 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor', VALUE_REQUIRED
),
3276 * Get a message processor.
3278 * @param int $userid
3279 * @param string $name the name of the processor
3280 * @return external_description
3281 * @throws moodle_exception
3284 public static function get_message_processor($userid = 0, $name) {
3285 global $USER, $PAGE, $CFG;
3287 // Check if messaging is enabled.
3288 if (empty($CFG->messaging
)) {
3289 throw new moodle_exception('disabled', 'message');
3292 $params = self
::validate_parameters(
3293 self
::get_message_processor_parameters(),
3295 'userid' => $userid,
3300 if (empty($params['userid'])) {
3301 $params['userid'] = $USER->id
;
3304 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
3305 core_user
::require_active_user($user);
3306 self
::validate_context(context_user
::instance($params['userid']));
3308 $processor = get_message_processor($name);
3310 $processoroutput = new \core_message\output\
processor($processor, $user);
3311 $renderer = $PAGE->get_renderer('core_message');
3313 return $processoroutput->export_for_template($renderer);
3317 * Returns description of method result value
3319 * @return external_description
3322 public static function get_message_processor_returns() {
3323 return new external_function_parameters(
3325 'systemconfigured' => new external_value(PARAM_BOOL
, 'Site configuration status'),
3326 'userconfigured' => new external_value(PARAM_BOOL
, 'The user configuration status'),
3332 * Check that the user has enough permission to retrieve message or notifications preferences.
3334 * @param int $userid the user id requesting the preferences
3335 * @return stdClass full user object
3336 * @throws moodle_exception
3339 protected static function validate_preferences_permissions($userid) {
3342 if (empty($userid)) {
3345 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
3346 core_user
::require_active_user($user);
3349 $systemcontext = context_system
::instance();
3350 self
::validate_context($systemcontext);
3352 // Check access control.
3353 if ($user->id
== $USER->id
) {
3354 // Editing own message profile.
3355 require_capability('moodle/user:editownmessageprofile', $systemcontext);
3357 // Teachers, parents, etc.
3358 $personalcontext = context_user
::instance($user->id
);
3359 require_capability('moodle/user:editmessageprofile', $personalcontext);
3365 * Returns a notification or message preference structure.
3367 * @return external_single_structure the structure
3370 protected static function get_preferences_structure() {
3371 return new external_single_structure(
3373 'userid' => new external_value(PARAM_INT
, 'User id'),
3374 'disableall' => new external_value(PARAM_INT
, 'Whether all the preferences are disabled'),
3375 'processors' => new external_multiple_structure(
3376 new external_single_structure(
3378 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3379 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3380 'hassettings' => new external_value(PARAM_BOOL
, 'Whether has settings'),
3381 'contextid' => new external_value(PARAM_INT
, 'Context id'),
3382 'userconfigured' => new external_value(PARAM_INT
, 'Whether is configured by the user'),
3385 'Config form values'
3387 'components' => new external_multiple_structure(
3388 new external_single_structure(
3390 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3391 'notifications' => new external_multiple_structure(
3392 new external_single_structure(
3394 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3395 'preferencekey' => new external_value(PARAM_ALPHANUMEXT
, 'Preference key'),
3396 'processors' => new external_multiple_structure(
3397 new external_single_structure(
3399 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3400 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
3401 'locked' => new external_value(PARAM_BOOL
, 'Is locked by admin?'),
3402 'userconfigured' => new external_value(PARAM_INT
, 'Is configured?'),
3403 'loggedin' => new external_single_structure(
3405 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3406 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3407 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3410 'loggedoff' => new external_single_structure(
3412 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
3413 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
3414 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
3419 'Processors values for this notification'
3423 'List of notificaitons for the component'
3427 'Available components'
3434 * Returns description of method parameters
3436 * @return external_function_parameters
3439 public static function get_user_notification_preferences_parameters() {
3440 return new external_function_parameters(
3442 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3448 * Get the notification preferences for a given user.
3450 * @param int $userid id of the user, 0 for current user
3451 * @return external_description
3452 * @throws moodle_exception
3455 public static function get_user_notification_preferences($userid = 0) {
3458 $params = self
::validate_parameters(
3459 self
::get_user_notification_preferences_parameters(),
3461 'userid' => $userid,
3464 $user = self
::validate_preferences_permissions($params['userid']);
3466 $processors = get_message_processors();
3467 $providers = message_get_providers_for_user($user->id
);
3468 $preferences = \core_message\api
::get_all_message_preferences($processors, $providers, $user);
3469 $notificationlist = new \core_message\output\preferences\notification_list
($processors, $providers, $preferences, $user);
3471 $renderer = $PAGE->get_renderer('core_message');
3474 'warnings' => array(),
3475 'preferences' => $notificationlist->export_for_template($renderer)
3481 * Returns description of method result value
3483 * @return external_description
3486 public static function get_user_notification_preferences_returns() {
3487 return new external_function_parameters(
3489 'preferences' => self
::get_preferences_structure(),
3490 'warnings' => new external_warnings(),
3496 * Returns description of method parameters
3498 * @return external_function_parameters
3501 public static function get_user_message_preferences_parameters() {
3502 return new external_function_parameters(
3504 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
3510 * Get the notification preferences for a given user.
3512 * @param int $userid id of the user, 0 for current user
3513 * @return external_description
3514 * @throws moodle_exception
3517 public static function get_user_message_preferences($userid = 0) {
3520 $params = self
::validate_parameters(
3521 self
::get_user_message_preferences_parameters(),
3523 'userid' => $userid,
3527 $user = self
::validate_preferences_permissions($params['userid']);
3529 // Filter out enabled, available system_configured and user_configured processors only.
3530 $readyprocessors = array_filter(get_message_processors(), function($processor) {
3531 return $processor->enabled
&&
3532 $processor->configured
&&
3533 $processor->object->is_user_configured() &&
3534 // Filter out processors that don't have and message preferences to configure.
3535 $processor->object->has_message_preferences();
3538 $providers = array_filter(message_get_providers_for_user($user->id
), function($provider) {
3539 return $provider->component
=== 'moodle';
3541 $preferences = \core_message\api
::get_all_message_preferences($readyprocessors, $providers, $user);
3542 $notificationlistoutput = new \core_message\output\preferences\
message_notification_list($readyprocessors,
3543 $providers, $preferences, $user);
3545 $renderer = $PAGE->get_renderer('core_message');
3548 'warnings' => array(),
3549 'preferences' => $notificationlistoutput->export_for_template($renderer),
3550 'blocknoncontacts' => \core_message\api
::get_user_privacy_messaging_preference($user->id
),
3556 * Returns description of method result value
3558 * @return external_description
3561 public static function get_user_message_preferences_returns() {
3562 return new external_function_parameters(
3564 'preferences' => self
::get_preferences_structure(),
3565 'blocknoncontacts' => new external_value(PARAM_INT
, 'Privacy messaging setting to define who can message you'),
3566 'warnings' => new external_warnings(),
3572 * Returns description of method parameters for the favourite_conversations() method.
3574 * @return external_function_parameters
3576 public static function set_favourite_conversations_parameters() {
3577 return new external_function_parameters(
3579 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
3580 'conversations' => new external_multiple_structure(
3581 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
3588 * Favourite a conversation, or list of conversations for a user.
3590 * @param int $userid the id of the user, or 0 for the current user.
3591 * @param array $conversationids the list of conversations ids to favourite.
3593 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3595 public static function set_favourite_conversations(int $userid, array $conversationids) {
3598 // All the business logic checks that really shouldn't be in here.
3599 if (empty($CFG->messaging
)) {
3600 throw new moodle_exception('disabled', 'message');
3603 'userid' => $userid,
3604 'conversations' => $conversationids
3606 $params = self
::validate_parameters(self
::set_favourite_conversations_parameters(), $params);
3607 $systemcontext = context_system
::instance();
3608 self
::validate_context($systemcontext);
3610 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3611 throw new moodle_exception('You do not have permission to perform this action.');
3614 foreach ($params['conversations'] as $conversationid) {
3615 \core_message\api
::set_favourite_conversation($conversationid, $params['userid']);
3622 * Return a description of the returns for the create_user_favourite_conversations() method.
3624 * @return external_description
3626 public static function set_favourite_conversations_returns() {
3627 return new external_warnings();
3631 * Returns description of method parameters for unfavourite_conversations() method.
3633 * @return external_function_parameters
3635 public static function unset_favourite_conversations_parameters() {
3636 return new external_function_parameters(
3638 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0),
3639 'conversations' => new external_multiple_structure(
3640 new external_value(PARAM_INT
, 'id of the conversation', VALUE_DEFAULT
, 0)
3647 * Unfavourite a conversation, or list of conversations for a user.
3649 * @param int $userid the id of the user, or 0 for the current user.
3650 * @param array $conversationids the list of conversations ids unset as favourites.
3652 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action.
3654 public static function unset_favourite_conversations(int $userid, array $conversationids) {
3657 // All the business logic checks that really shouldn't be in here.
3658 if (empty($CFG->messaging
)) {
3659 throw new moodle_exception('disabled', 'message');
3662 'userid' => $userid,
3663 'conversations' => $conversationids
3665 $params = self
::validate_parameters(self
::unset_favourite_conversations_parameters(), $params);
3666 $systemcontext = context_system
::instance();
3667 self
::validate_context($systemcontext);
3669 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
3670 throw new moodle_exception('You do not have permission to perform this action.');
3673 foreach ($params['conversations'] as $conversationid) {
3674 \core_message\api
::unset_favourite_conversation($conversationid, $params['userid']);
3681 * Unset favourite conversations return description.
3683 * @return external_description
3685 public static function unset_favourite_conversations_returns() {
3686 return new external_warnings();