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 require_once("$CFG->libdir/externallib.php");
28 require_once($CFG->dirroot
. "/message/lib.php");
31 * Message external functions
33 * @package core_message
35 * @copyright 2011 Jerome Mouneyrac
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 class core_message_external
extends external_api
{
42 * Returns description of method parameters
44 * @return external_function_parameters
47 public static function send_instant_messages_parameters() {
48 return new external_function_parameters(
50 'messages' => new external_multiple_structure(
51 new external_single_structure(
53 'touserid' => new external_value(PARAM_INT
, 'id of the user to send the private message'),
54 'text' => new external_value(PARAM_RAW
, 'the text of the message'),
55 'textformat' => new external_format_value('text', VALUE_DEFAULT
, FORMAT_MOODLE
),
56 '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
),
65 * Send private messages from the current USER to other users
67 * @param array $messages An array of message to send.
71 public static function send_instant_messages($messages = array()) {
72 global $CFG, $USER, $DB;
74 // Check if messaging is enabled.
75 if (empty($CFG->messaging
)) {
76 throw new moodle_exception('disabled', 'message');
79 // Ensure the current user is allowed to run this function
80 $context = context_system
::instance();
81 self
::validate_context($context);
82 require_capability('moodle/site:sendmessage', $context);
84 $params = self
::validate_parameters(self
::send_instant_messages_parameters(), array('messages' => $messages));
86 //retrieve all tousers of the messages
88 foreach($params['messages'] as $message) {
89 $receivers[] = $message['touserid'];
91 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers, SQL_PARAMS_NAMED
, 'userid_');
92 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
94 $contactlist = array();
95 $sqlparams['contactid'] = $USER->id
;
96 $rs = $DB->get_recordset_sql("SELECT *
97 FROM {message_contacts}
98 WHERE userid $sqluserids
99 AND contactid = :contactid", $sqlparams);
100 foreach ($rs as $record) {
101 if ($record->blocked
) {
102 // $record->userid is blocking current user
103 $blocklist[$record->userid
] = true;
105 // $record->userid have current user as contact
106 $contactlist[$record->userid
] = true;
111 $canreadallmessages = has_capability('moodle/site:readallmessages', $context);
113 $resultmessages = array();
114 foreach ($params['messages'] as $message) {
115 $resultmsg = array(); //the infos about the success of the operation
117 //we are going to do some checking
118 //code should match /messages/index.php checks
121 //check the user exists
122 if (empty($tousers[$message['touserid']])) {
124 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
127 //check that the touser is not blocking the current user
128 if ($success and !empty($blocklist[$message['touserid']]) and !$canreadallmessages) {
130 $errormessage = get_string('userisblockingyou', 'message');
133 // Check if the user is a contact
134 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
135 $blocknoncontacts = get_user_preferences('message_blocknoncontacts', NULL, $message['touserid']);
136 // message_blocknoncontacts option is on and current user is not in contact list
137 if ($success && empty($contactlist[$message['touserid']]) && !empty($blocknoncontacts)) {
138 // The user isn't a contact and they have selected to block non contacts so this message won't be sent.
140 $errormessage = get_string('userisblockingyounoncontact', 'message',
141 fullname(core_user
::get_user($message['touserid'])));
144 //now we can send the message (at least try)
146 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object
147 $success = message_post_message($USER, $tousers[$message['touserid']],
148 $message['text'], external_validate_format($message['textformat']));
151 //build the resultmsg
152 if (isset($message['clientmsgid'])) {
153 $resultmsg['clientmsgid'] = $message['clientmsgid'];
156 $resultmsg['msgid'] = $success;
158 // WARNINGS: for backward compatibility we return this errormessage.
159 // We should have thrown exceptions as these errors prevent results to be returned.
160 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side .
161 $resultmsg['msgid'] = -1;
162 $resultmsg['errormessage'] = $errormessage;
165 $resultmessages[] = $resultmsg;
168 return $resultmessages;
172 * Returns description of method result value
174 * @return external_description
177 public static function send_instant_messages_returns() {
178 return new external_multiple_structure(
179 new external_single_structure(
181 'msgid' => new external_value(PARAM_INT
, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'),
182 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT
, 'your own id for the message', VALUE_OPTIONAL
),
183 'errormessage' => new external_value(PARAM_TEXT
, 'error message - if it failed', VALUE_OPTIONAL
)
190 * Create contacts parameters description.
192 * @return external_function_parameters
195 public static function create_contacts_parameters() {
196 return new external_function_parameters(
198 'userids' => new external_multiple_structure(
199 new external_value(PARAM_INT
, 'User ID'),
202 'userid' => new external_value(PARAM_INT
, 'The id of the user we are creating the contacts for, 0 for the
203 current user', VALUE_DEFAULT
, 0)
211 * @param array $userids array of user IDs.
212 * @param int $userid The id of the user we are creating the contacts for
213 * @return external_description
216 public static function create_contacts($userids, $userid = 0) {
219 // Check if messaging is enabled.
220 if (empty($CFG->messaging
)) {
221 throw new moodle_exception('disabled', 'message');
224 if (empty($userid)) {
229 $context = context_system
::instance();
230 self
::validate_context($context);
232 $capability = 'moodle/site:manageallmessaging';
233 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
234 throw new required_capability_exception($context, $capability, 'nopermissions', '');
237 $params = array('userids' => $userids, 'userid' => $userid);
238 $params = self
::validate_parameters(self
::create_contacts_parameters(), $params);
241 foreach ($params['userids'] as $id) {
242 if (!message_add_contact($id, 0, $userid)) {
246 'warningcode' => 'contactnotcreated',
247 'message' => 'The contact could not be created'
255 * Create contacts return description.
257 * @return external_description
260 public static function create_contacts_returns() {
261 return new external_warnings();
265 * Delete contacts parameters description.
267 * @return external_function_parameters
270 public static function delete_contacts_parameters() {
271 return new external_function_parameters(
273 'userids' => new external_multiple_structure(
274 new external_value(PARAM_INT
, 'User ID'),
277 'userid' => new external_value(PARAM_INT
, 'The id of the user we are deleting the contacts for, 0 for the
278 current user', VALUE_DEFAULT
, 0)
286 * @param array $userids array of user IDs.
287 * @param int $userid The id of the user we are deleting the contacts for
291 public static function delete_contacts($userids, $userid = 0) {
294 // Check if messaging is enabled.
295 if (empty($CFG->messaging
)) {
296 throw new moodle_exception('disabled', 'message');
299 if (empty($userid)) {
304 $context = context_system
::instance();
305 self
::validate_context($context);
307 $capability = 'moodle/site:manageallmessaging';
308 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
309 throw new required_capability_exception($context, $capability, 'nopermissions', '');
312 $params = array('userids' => $userids, 'userid' => $userid);
313 $params = self
::validate_parameters(self
::delete_contacts_parameters(), $params);
315 foreach ($params['userids'] as $id) {
316 message_remove_contact($id, $userid);
323 * Delete contacts return description.
325 * @return external_description
328 public static function delete_contacts_returns() {
333 * Block contacts parameters description.
335 * @return external_function_parameters
338 public static function block_contacts_parameters() {
339 return new external_function_parameters(
341 'userids' => new external_multiple_structure(
342 new external_value(PARAM_INT
, 'User ID'),
345 'userid' => new external_value(PARAM_INT
, 'The id of the user we are blocking the contacts for, 0 for the
346 current user', VALUE_DEFAULT
, 0)
354 * @param array $userids array of user IDs.
355 * @param int $userid The id of the user we are blocking the contacts for
356 * @return external_description
359 public static function block_contacts($userids, $userid = 0) {
362 // Check if messaging is enabled.
363 if (empty($CFG->messaging
)) {
364 throw new moodle_exception('disabled', 'message');
367 if (empty($userid)) {
372 $context = context_system
::instance();
373 self
::validate_context($context);
375 $capability = 'moodle/site:manageallmessaging';
376 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
377 throw new required_capability_exception($context, $capability, 'nopermissions', '');
380 $params = array('userids' => $userids, 'userid' => $userid);
381 $params = self
::validate_parameters(self
::block_contacts_parameters(), $params);
384 foreach ($params['userids'] as $id) {
385 if (!message_block_contact($id, $userid)) {
389 'warningcode' => 'contactnotblocked',
390 'message' => 'The contact could not be blocked'
398 * Block contacts return description.
400 * @return external_description
403 public static function block_contacts_returns() {
404 return new external_warnings();
408 * Unblock contacts parameters description.
410 * @return external_function_parameters
413 public static function unblock_contacts_parameters() {
414 return new external_function_parameters(
416 'userids' => new external_multiple_structure(
417 new external_value(PARAM_INT
, 'User ID'),
420 'userid' => new external_value(PARAM_INT
, 'The id of the user we are unblocking the contacts for, 0 for the
421 current user', VALUE_DEFAULT
, 0)
429 * @param array $userids array of user IDs.
430 * @param int $userid The id of the user we are unblocking the contacts for
434 public static function unblock_contacts($userids, $userid = 0) {
437 // Check if messaging is enabled.
438 if (empty($CFG->messaging
)) {
439 throw new moodle_exception('disabled', 'message');
442 if (empty($userid)) {
447 $context = context_system
::instance();
448 self
::validate_context($context);
450 $capability = 'moodle/site:manageallmessaging';
451 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
452 throw new required_capability_exception($context, $capability, 'nopermissions', '');
455 $params = array('userids' => $userids, 'userid' => $userid);
456 $params = self
::validate_parameters(self
::unblock_contacts_parameters(), $params);
458 foreach ($params['userids'] as $id) {
459 message_unblock_contact($id, $userid);
466 * Unblock contacts return description.
468 * @return external_description
471 public static function unblock_contacts_returns() {
476 * Return the structure of a message area contact.
478 * @return external_single_structure
481 private static function get_messagearea_contact_structure() {
482 return new external_single_structure(
484 'userid' => new external_value(PARAM_INT
, 'The user\'s id'),
485 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
486 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
487 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
488 'ismessaging' => new external_value(PARAM_BOOL
, 'If we are messaging the user'),
489 'sentfromcurrentuser' => new external_value(PARAM_BOOL
, 'Was the last message sent from the current user?'),
490 'lastmessage' => new external_value(PARAM_NOTAGS
, 'The user\'s last message'),
491 'messageid' => new external_value(PARAM_INT
, 'The unique search message id', VALUE_DEFAULT
, null),
492 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
493 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
494 'isread' => new external_value(PARAM_BOOL
, 'If the user has read the message'),
495 'isblocked' => new external_value(PARAM_BOOL
, 'If the user has been blocked'),
496 'unreadcount' => new external_value(PARAM_INT
, 'The number of unread messages in this conversation',
497 VALUE_DEFAULT
, null),
503 * Return the structure of a message area message.
505 * @return external_single_structure
508 private static function get_messagearea_message_structure() {
509 return new external_single_structure(
511 'id' => new external_value(PARAM_INT
, 'The id of the message'),
512 'useridfrom' => new external_value(PARAM_INT
, 'The id of the user who sent the message'),
513 'useridto' => new external_value(PARAM_INT
, 'The id of the user who received the message'),
514 'text' => new external_value(PARAM_RAW
, 'The text of the message'),
515 'displayblocktime' => new external_value(PARAM_BOOL
, 'Should we display the block time?'),
516 'blocktime' => new external_value(PARAM_NOTAGS
, 'The time to display above the message'),
517 'position' => new external_value(PARAM_ALPHA
, 'The position of the text'),
518 'timesent' => new external_value(PARAM_NOTAGS
, 'The time the message was sent'),
519 'timecreated' => new external_value(PARAM_INT
, 'The timecreated timestamp for the message'),
520 'isread' => new external_value(PARAM_INT
, 'Determines if the message was read or not'),
526 * Get messagearea search users in course parameters.
528 * @return external_function_parameters
531 public static function data_for_messagearea_search_users_in_course_parameters() {
532 return new external_function_parameters(
534 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
535 'courseid' => new external_value(PARAM_INT
, 'The id of the course'),
536 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
537 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
538 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
544 * Get messagearea search users in course results.
546 * @param int $userid The id of the user who is performing the search
547 * @param int $courseid The id of the course
548 * @param string $search The string being searched
549 * @param int $limitfrom
550 * @param int $limitnum
552 * @throws moodle_exception
555 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
557 global $CFG, $PAGE, $USER;
559 // Check if messaging is enabled.
560 if (empty($CFG->messaging
)) {
561 throw new moodle_exception('disabled', 'message');
564 $systemcontext = context_system
::instance();
568 'courseid' => $courseid,
570 'limitfrom' => $limitfrom,
571 'limitnum' => $limitnum
573 self
::validate_parameters(self
::data_for_messagearea_search_users_in_course_parameters(), $params);
574 self
::validate_context($systemcontext);
576 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
577 throw new moodle_exception('You do not have permission to perform this action.');
580 $users = \core_message\api
::search_users_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
581 $results = new \core_message\output\messagearea\
user_search_results($users);
583 $renderer = $PAGE->get_renderer('core_message');
584 return $results->export_for_template($renderer);
588 * Get messagearea search users in course returns.
590 * @return external_single_structure
593 public static function data_for_messagearea_search_users_in_course_returns() {
594 return new external_single_structure(
596 'contacts' => new external_multiple_structure(
597 self
::get_messagearea_contact_structure()
604 * Get messagearea search users parameters.
606 * @return external_function_parameters
609 public static function data_for_messagearea_search_users_parameters() {
610 return new external_function_parameters(
612 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
613 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
614 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
620 * Get messagearea search users results.
622 * @param int $userid The id of the user who is performing the search
623 * @param string $search The string being searched
624 * @param int $limitnum
626 * @throws moodle_exception
629 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
630 global $CFG, $PAGE, $USER;
632 // Check if messaging is enabled.
633 if (empty($CFG->messaging
)) {
634 throw new moodle_exception('disabled', 'message');
637 $systemcontext = context_system
::instance();
642 'limitnum' => $limitnum
644 self
::validate_parameters(self
::data_for_messagearea_search_users_parameters(), $params);
645 self
::validate_context($systemcontext);
647 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
648 throw new moodle_exception('You do not have permission to perform this action.');
651 list($contacts, $courses, $noncontacts) = \core_message\api
::search_users($userid, $search, $limitnum);
652 $search = new \core_message\output\messagearea\
user_search_results($contacts, $courses, $noncontacts);
654 $renderer = $PAGE->get_renderer('core_message');
655 return $search->export_for_template($renderer);
659 * Get messagearea search users returns.
661 * @return external_single_structure
664 public static function data_for_messagearea_search_users_returns() {
665 return new external_single_structure(
667 'contacts' => new external_multiple_structure(
668 self
::get_messagearea_contact_structure()
670 'courses' => new external_multiple_structure(
671 new external_single_structure(
673 'id' => new external_value(PARAM_INT
, 'The course id'),
674 'shortname' => new external_value(PARAM_TEXT
, 'The course shortname'),
675 'fullname' => new external_value(PARAM_TEXT
, 'The course fullname'),
679 'noncontacts' => new external_multiple_structure(
680 self
::get_messagearea_contact_structure()
687 * Get messagearea search messages parameters.
689 * @return external_function_parameters
692 public static function data_for_messagearea_search_messages_parameters() {
693 return new external_function_parameters(
695 'userid' => new external_value(PARAM_INT
, 'The id of the user who is performing the search'),
696 'search' => new external_value(PARAM_RAW
, 'The string being searched'),
697 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
698 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
704 * Get messagearea search messages results.
706 * @param int $userid The id of the user who is performing the search
707 * @param string $search The string being searched
708 * @param int $limitfrom
709 * @param int $limitnum
711 * @throws moodle_exception
714 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
715 global $CFG, $PAGE, $USER;
717 // Check if messaging is enabled.
718 if (empty($CFG->messaging
)) {
719 throw new moodle_exception('disabled', 'message');
722 $systemcontext = context_system
::instance();
727 'limitfrom' => $limitfrom,
728 'limitnum' => $limitnum
731 self
::validate_parameters(self
::data_for_messagearea_search_messages_parameters(), $params);
732 self
::validate_context($systemcontext);
734 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
735 throw new moodle_exception('You do not have permission to perform this action.');
738 $messages = \core_message\api
::search_messages($userid, $search, $limitfrom, $limitnum);
739 $results = new \core_message\output\messagearea\
message_search_results($messages);
741 $renderer = $PAGE->get_renderer('core_message');
742 return $results->export_for_template($renderer);
746 * Get messagearea search messages returns.
748 * @return external_single_structure
751 public static function data_for_messagearea_search_messages_returns() {
752 return new external_single_structure(
754 'contacts' => new external_multiple_structure(
755 self
::get_messagearea_contact_structure()
762 * The messagearea conversations parameters.
764 * @return external_function_parameters
767 public static function data_for_messagearea_conversations_parameters() {
768 return new external_function_parameters(
770 'userid' => new external_value(PARAM_INT
, 'The id of the user who we are viewing conversations for'),
771 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
772 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0)
778 * Get messagearea conversations.
780 * @param int $userid The id of the user who we are viewing conversations for
781 * @param int $limitfrom
782 * @param int $limitnum
784 * @throws moodle_exception
787 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
788 global $CFG, $PAGE, $USER;
790 // Check if messaging is enabled.
791 if (empty($CFG->messaging
)) {
792 throw new moodle_exception('disabled', 'message');
795 $systemcontext = context_system
::instance();
799 'limitfrom' => $limitfrom,
800 'limitnum' => $limitnum
802 self
::validate_parameters(self
::data_for_messagearea_conversations_parameters(), $params);
803 self
::validate_context($systemcontext);
805 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
806 throw new moodle_exception('You do not have permission to perform this action.');
809 $conversations = \core_message\api
::get_conversations($userid, $limitfrom, $limitnum);
810 $conversations = new \core_message\output\messagearea\
contacts(null, $conversations);
812 $renderer = $PAGE->get_renderer('core_message');
813 return $conversations->export_for_template($renderer);
817 * The messagearea conversations return structure.
819 * @return external_single_structure
822 public static function data_for_messagearea_conversations_returns() {
823 return new external_single_structure(
825 'contacts' => new external_multiple_structure(
826 self
::get_messagearea_contact_structure()
833 * The messagearea contacts return parameters.
835 * @return external_function_parameters
838 public static function data_for_messagearea_contacts_parameters() {
839 return self
::data_for_messagearea_conversations_parameters();
843 * Get messagearea contacts parameters.
845 * @param int $userid The id of the user who we are viewing conversations for
846 * @param int $limitfrom
847 * @param int $limitnum
849 * @throws moodle_exception
852 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
853 global $CFG, $PAGE, $USER;
855 // Check if messaging is enabled.
856 if (empty($CFG->messaging
)) {
857 throw new moodle_exception('disabled', 'message');
860 $systemcontext = context_system
::instance();
864 'limitfrom' => $limitfrom,
865 'limitnum' => $limitnum
867 self
::validate_parameters(self
::data_for_messagearea_contacts_parameters(), $params);
868 self
::validate_context($systemcontext);
870 if (($USER->id
!= $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
871 throw new moodle_exception('You do not have permission to perform this action.');
874 $contacts = \core_message\api
::get_contacts($userid, $limitfrom, $limitnum);
875 $contacts = new \core_message\output\messagearea\
contacts(null, $contacts);
877 $renderer = $PAGE->get_renderer('core_message');
878 return $contacts->export_for_template($renderer);
882 * The messagearea contacts return structure.
884 * @return external_single_structure
887 public static function data_for_messagearea_contacts_returns() {
888 return self
::data_for_messagearea_conversations_returns();
892 * The messagearea messages parameters.
894 * @return external_function_parameters
897 public static function data_for_messagearea_messages_parameters() {
898 return new external_function_parameters(
900 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
901 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
902 'limitfrom' => new external_value(PARAM_INT
, 'Limit from', VALUE_DEFAULT
, 0),
903 'limitnum' => new external_value(PARAM_INT
, 'Limit number', VALUE_DEFAULT
, 0),
904 'newest' => new external_value(PARAM_BOOL
, 'Newest first?', VALUE_DEFAULT
, false),
905 'timefrom' => new external_value(PARAM_INT
,
906 'The timestamp from which the messages were created', VALUE_DEFAULT
, 0),
912 * Get messagearea messages.
914 * @param int $currentuserid The current user's id
915 * @param int $otheruserid The other user's id
916 * @param int $limitfrom
917 * @param int $limitnum
918 * @param boolean $newest
920 * @throws moodle_exception
923 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
924 $newest = false, $timefrom = 0) {
925 global $CFG, $PAGE, $USER;
927 // Check if messaging is enabled.
928 if (empty($CFG->messaging
)) {
929 throw new moodle_exception('disabled', 'message');
932 $systemcontext = context_system
::instance();
935 'currentuserid' => $currentuserid,
936 'otheruserid' => $otheruserid,
937 'limitfrom' => $limitfrom,
938 'limitnum' => $limitnum,
940 'timefrom' => $timefrom,
942 self
::validate_parameters(self
::data_for_messagearea_messages_parameters(), $params);
943 self
::validate_context($systemcontext);
945 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
946 throw new moodle_exception('You do not have permission to perform this action.');
950 $sort = 'timecreated DESC';
952 $sort = 'timecreated ASC';
955 // We need to enforce a one second delay on messages to avoid race conditions of current
956 // messages still being sent.
958 // There is a chance that we could request messages before the current time's
959 // second has elapsed and while other messages are being sent in that same second. In which
960 // case those messages will be lost.
962 // Instead we ignore the current time in the result set to ensure that second is allowed to finish.
963 if (!empty($timefrom)) {
964 $timeto = time() - 1;
969 // No requesting messages from the current time, as stated above.
970 if ($timefrom == time()) {
973 $messages = \core_message\api
::get_messages($currentuserid, $otheruserid, $limitfrom,
974 $limitnum, $sort, $timefrom, $timeto);
977 $messages = new \core_message\output\messagearea\
messages($currentuserid, $otheruserid, $messages);
979 $renderer = $PAGE->get_renderer('core_message');
980 return $messages->export_for_template($renderer);
984 * The messagearea messages return structure.
986 * @return external_single_structure
989 public static function data_for_messagearea_messages_returns() {
990 return new external_single_structure(
992 'iscurrentuser' => new external_value(PARAM_BOOL
, 'Is the currently logged in user the user we are viewing
993 the messages on behalf of?'),
994 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
995 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
996 'otheruserfullname' => new external_value(PARAM_NOTAGS
, 'The other user\'s fullname'),
997 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
998 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
999 'messages' => new external_multiple_structure(
1000 self
::get_messagearea_message_structure()
1002 'isblocked' => new external_value(PARAM_BOOL
, 'Is this user blocked by the current user?', VALUE_DEFAULT
, false),
1008 * The get most recent message return parameters.
1010 * @return external_function_parameters
1013 public static function data_for_messagearea_get_most_recent_message_parameters() {
1014 return new external_function_parameters(
1016 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1017 'otheruserid' => new external_value(PARAM_INT
, 'The other user\'s id'),
1023 * Get the most recent message in a conversation.
1025 * @param int $currentuserid The current user's id
1026 * @param int $otheruserid The other user's id
1028 * @throws moodle_exception
1031 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
1032 global $CFG, $PAGE, $USER;
1034 // Check if messaging is enabled.
1035 if (empty($CFG->messaging
)) {
1036 throw new moodle_exception('disabled', 'message');
1039 $systemcontext = context_system
::instance();
1042 'currentuserid' => $currentuserid,
1043 'otheruserid' => $otheruserid
1045 self
::validate_parameters(self
::data_for_messagearea_get_most_recent_message_parameters(), $params);
1046 self
::validate_context($systemcontext);
1048 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1049 throw new moodle_exception('You do not have permission to perform this action.');
1052 $message = \core_message\api
::get_most_recent_message($currentuserid, $otheruserid);
1053 $message = new \core_message\output\messagearea\
message($message);
1055 $renderer = $PAGE->get_renderer('core_message');
1056 return $message->export_for_template($renderer);
1060 * The get most recent message return structure.
1062 * @return external_single_structure
1065 public static function data_for_messagearea_get_most_recent_message_returns() {
1066 return self
::get_messagearea_message_structure();
1070 * The get profile parameters.
1072 * @return external_function_parameters
1075 public static function data_for_messagearea_get_profile_parameters() {
1076 return new external_function_parameters(
1078 'currentuserid' => new external_value(PARAM_INT
, 'The current user\'s id'),
1079 'otheruserid' => new external_value(PARAM_INT
, 'The id of the user whose profile we want to view'),
1085 * Get the profile information for a contact.
1087 * @param int $currentuserid The current user's id
1088 * @param int $otheruserid The id of the user whose profile we are viewing
1090 * @throws moodle_exception
1093 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
1094 global $CFG, $PAGE, $USER;
1096 // Check if messaging is enabled.
1097 if (empty($CFG->messaging
)) {
1098 throw new moodle_exception('disabled', 'message');
1101 $systemcontext = context_system
::instance();
1104 'currentuserid' => $currentuserid,
1105 'otheruserid' => $otheruserid
1107 self
::validate_parameters(self
::data_for_messagearea_get_profile_parameters(), $params);
1108 self
::validate_context($systemcontext);
1110 if (($USER->id
!= $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1111 throw new moodle_exception('You do not have permission to perform this action.');
1114 $profile = \core_message\api
::get_profile($currentuserid, $otheruserid);
1115 $profile = new \core_message\output\messagearea\
profile($profile);
1117 $renderer = $PAGE->get_renderer('core_message');
1118 return $profile->export_for_template($renderer);
1122 * The get profile return structure.
1124 * @return external_single_structure
1127 public static function data_for_messagearea_get_profile_returns() {
1128 return new external_single_structure(
1130 'userid' => new external_value(PARAM_INT
, 'The id of the user whose profile we are viewing'),
1131 'email' => new external_value(core_user
::get_property_type('email'), 'An email address'),
1132 'country' => new external_value(PARAM_TEXT
, 'Home country of the user'),
1133 'city' => new external_value(core_user
::get_property_type('city'), 'Home city of the user'),
1134 'fullname' => new external_value(PARAM_NOTAGS
, 'The user\'s name'),
1135 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL'),
1136 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL'),
1137 'showonlinestatus' => new external_value(PARAM_BOOL
, 'Show the user\'s online status?'),
1138 'isonline' => new external_value(PARAM_BOOL
, 'The user\'s online status'),
1139 'isblocked' => new external_value(PARAM_BOOL
, 'Is the user blocked?'),
1140 'iscontact' => new external_value(PARAM_BOOL
, 'Is the user a contact?')
1146 * Get contacts parameters description.
1148 * @return external_function_parameters
1151 public static function get_contacts_parameters() {
1152 return new external_function_parameters(array());
1158 * @return external_description
1161 public static function get_contacts() {
1164 // Check if messaging is enabled.
1165 if (empty($CFG->messaging
)) {
1166 throw new moodle_exception('disabled', 'message');
1169 require_once($CFG->dirroot
. '/user/lib.php');
1171 list($online, $offline, $strangers) = message_get_contacts();
1172 $allcontacts = array('online' => $online, 'offline' => $offline, 'strangers' => $strangers);
1173 foreach ($allcontacts as $mode => $contacts) {
1174 foreach ($contacts as $key => $contact) {
1175 $newcontact = array(
1176 'id' => $contact->id
,
1177 'fullname' => fullname($contact),
1178 'unread' => $contact->messagecount
1181 $userpicture = new user_picture($contact);
1182 $userpicture->size
= 1; // Size f1.
1183 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1184 $userpicture->size
= 0; // Size f2.
1185 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1187 $allcontacts[$mode][$key] = $newcontact;
1190 return $allcontacts;
1194 * Get contacts return description.
1196 * @return external_description
1199 public static function get_contacts_returns() {
1200 return new external_single_structure(
1202 'online' => new external_multiple_structure(
1203 new external_single_structure(
1205 'id' => new external_value(PARAM_INT
, 'User ID'),
1206 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1207 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1208 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
1209 'unread' => new external_value(PARAM_INT
, 'Unread message count')
1212 'List of online contacts'
1214 'offline' => new external_multiple_structure(
1215 new external_single_structure(
1217 'id' => new external_value(PARAM_INT
, 'User ID'),
1218 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1219 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1220 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
1221 'unread' => new external_value(PARAM_INT
, 'Unread message count')
1224 'List of offline contacts'
1226 'strangers' => new external_multiple_structure(
1227 new external_single_structure(
1229 'id' => new external_value(PARAM_INT
, 'User ID'),
1230 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1231 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1232 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
),
1233 'unread' => new external_value(PARAM_INT
, 'Unread message count')
1236 'List of users that are not in the user\'s contact list but have sent a message'
1243 * Search contacts parameters description.
1245 * @return external_function_parameters
1248 public static function search_contacts_parameters() {
1249 return new external_function_parameters(
1251 'searchtext' => new external_value(PARAM_CLEAN
, 'String the user\'s fullname has to match to be found'),
1252 'onlymycourses' => new external_value(PARAM_BOOL
, 'Limit search to the user\'s courses',
1253 VALUE_DEFAULT
, false)
1261 * @param string $searchtext query string.
1262 * @param bool $onlymycourses limit the search to the user's courses only.
1263 * @return external_description
1266 public static function search_contacts($searchtext, $onlymycourses = false) {
1267 global $CFG, $USER, $PAGE;
1268 require_once($CFG->dirroot
. '/user/lib.php');
1270 // Check if messaging is enabled.
1271 if (empty($CFG->messaging
)) {
1272 throw new moodle_exception('disabled', 'message');
1275 require_once($CFG->libdir
. '/enrollib.php');
1277 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1278 $params = self
::validate_parameters(self
::search_contacts_parameters(), $params);
1280 // Extra validation, we do not allow empty queries.
1281 if ($params['searchtext'] === '') {
1282 throw new moodle_exception('querystringcannotbeempty');
1285 $courseids = array();
1286 if ($params['onlymycourses']) {
1287 $mycourses = enrol_get_my_courses(array('id'));
1288 foreach ($mycourses as $mycourse) {
1289 $courseids[] = $mycourse->id
;
1292 $courseids[] = SITEID
;
1295 // Retrieving the users matching the query.
1296 $users = message_search_users($courseids, $params['searchtext']);
1298 foreach ($users as $user) {
1299 $results[$user->id
] = $user;
1302 // Reorganising information.
1303 foreach ($results as &$user) {
1306 'fullname' => fullname($user)
1309 // Avoid undefined property notice as phone not specified.
1310 $user->phone1
= null;
1311 $user->phone2
= null;
1313 $userpicture = new user_picture($user);
1314 $userpicture->size
= 1; // Size f1.
1315 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1316 $userpicture->size
= 0; // Size f2.
1317 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1326 * Search contacts return description.
1328 * @return external_description
1331 public static function search_contacts_returns() {
1332 return new external_multiple_structure(
1333 new external_single_structure(
1335 'id' => new external_value(PARAM_INT
, 'User ID'),
1336 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1337 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
),
1338 'profileimageurlsmall' => new external_value(PARAM_URL
, 'Small user picture URL', VALUE_OPTIONAL
)
1346 * Get messages parameters description.
1348 * @return external_function_parameters
1351 public static function get_messages_parameters() {
1352 return new external_function_parameters(
1354 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
1355 'useridfrom' => new external_value(
1356 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1358 'type' => new external_value(
1359 PARAM_ALPHA
, 'type of message to return, expected values are: notifications, conversations and both',
1360 VALUE_DEFAULT
, 'both'),
1361 'read' => new external_value(PARAM_BOOL
, 'true for getting read messages, false for unread', VALUE_DEFAULT
, true),
1362 'newestfirst' => new external_value(
1363 PARAM_BOOL
, 'true for ordering by newest first, false for oldest first',
1364 VALUE_DEFAULT
, true),
1365 'limitfrom' => new external_value(PARAM_INT
, 'limit from', VALUE_DEFAULT
, 0),
1366 'limitnum' => new external_value(PARAM_INT
, 'limit number', VALUE_DEFAULT
, 0)
1372 * Get messages function implementation.
1375 * @throws invalid_parameter_exception
1376 * @throws moodle_exception
1377 * @param int $useridto the user id who received the message
1378 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1379 * @param string $type type of message to return, expected values: notifications, conversations and both
1380 * @param bool $read true for retreiving read messages, false for unread
1381 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1382 * @param int $limitfrom limit from
1383 * @param int $limitnum limit num
1384 * @return external_description
1386 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
1387 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
1390 $warnings = array();
1393 'useridto' => $useridto,
1394 'useridfrom' => $useridfrom,
1397 'newestfirst' => $newestfirst,
1398 'limitfrom' => $limitfrom,
1399 'limitnum' => $limitnum
1402 $params = self
::validate_parameters(self
::get_messages_parameters(), $params);
1404 $context = context_system
::instance();
1405 self
::validate_context($context);
1407 $useridto = $params['useridto'];
1408 $useridfrom = $params['useridfrom'];
1409 $type = $params['type'];
1410 $read = $params['read'];
1411 $newestfirst = $params['newestfirst'];
1412 $limitfrom = $params['limitfrom'];
1413 $limitnum = $params['limitnum'];
1415 $allowedvalues = array('notifications', 'conversations', 'both');
1416 if (!in_array($type, $allowedvalues)) {
1417 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1418 'allowed values are: ' . implode(',', $allowedvalues));
1421 // Check if private messaging between users is allowed.
1422 if (empty($CFG->messaging
)) {
1423 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
1424 if ($type == "conversations") {
1425 throw new moodle_exception('disabled', 'message');
1427 if ($type == "both") {
1429 $warning['item'] = 'message';
1430 $warning['itemid'] = $USER->id
;
1431 $warning['warningcode'] = '1';
1432 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1433 Only notifications will be returned';
1434 $warnings[] = $warning;
1438 if (!empty($useridto)) {
1439 if (core_user
::is_real_user($useridto)) {
1440 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
1442 throw new moodle_exception('invaliduser');
1446 if (!empty($useridfrom)) {
1447 // We use get_user here because the from user can be the noreply or support user.
1448 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
1451 // Check if the current user is the sender/receiver or just a privileged user.
1452 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
1453 !has_capability('moodle/site:readallmessages', $context)) {
1454 throw new moodle_exception('accessdenied', 'admin');
1457 // Which type of messages to retrieve.
1458 $notifications = -1;
1459 if ($type != 'both') {
1460 $notifications = ($type == 'notifications') ?
1 : 0;
1463 $orderdirection = $newestfirst ?
'DESC' : 'ASC';
1464 $sort = "mr.timecreated $orderdirection";
1466 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
1467 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1469 // In some cases, we don't need to get the to/from user objects from the sql query.
1470 $userfromfullname = '';
1471 $usertofullname = '';
1473 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1474 if (!empty($useridto)) {
1475 $usertofullname = fullname($userto, $canviewfullname);
1476 // The user from may or may not be filled.
1477 if (!empty($useridfrom)) {
1478 $userfromfullname = fullname($userfrom, $canviewfullname);
1481 // If the useridto field is empty, the useridfrom must be filled.
1482 $userfromfullname = fullname($userfrom, $canviewfullname);
1484 foreach ($messages as $mid => $message) {
1486 // Do not return deleted messages.
1487 if (($useridto == $USER->id
and $message->timeusertodeleted
) or
1488 ($useridfrom == $USER->id
and $message->timeuserfromdeleted
)) {
1490 unset($messages[$mid]);
1494 // We need to get the user from the query.
1495 if (empty($userfromfullname)) {
1496 // Check for non-reply and support users.
1497 if (core_user
::is_real_user($message->useridfrom
)) {
1498 $user = new stdClass();
1499 $user = username_load_fields_from_object($user, $message, 'userfrom');
1500 $message->userfromfullname
= fullname($user, $canviewfullname);
1502 $user = core_user
::get_user($message->useridfrom
);
1503 $message->userfromfullname
= fullname($user, $canviewfullname);
1506 $message->userfromfullname
= $userfromfullname;
1509 // We need to get the user from the query.
1510 if (empty($usertofullname)) {
1511 $user = new stdClass();
1512 $user = username_load_fields_from_object($user, $message, 'userto');
1513 $message->usertofullname
= fullname($user, $canviewfullname);
1515 $message->usertofullname
= $usertofullname;
1518 // This field is only available in the message_read table.
1519 if (!isset($message->timeread
)) {
1520 $message->timeread
= 0;
1523 $message->text
= message_format_message_text($message);
1524 $messages[$mid] = (array) $message;
1529 'messages' => $messages,
1530 'warnings' => $warnings
1537 * Get messages return description.
1539 * @return external_single_structure
1542 public static function get_messages_returns() {
1543 return new external_single_structure(
1545 'messages' => new external_multiple_structure(
1546 new external_single_structure(
1548 'id' => new external_value(PARAM_INT
, 'Message id'),
1549 'useridfrom' => new external_value(PARAM_INT
, 'User from id'),
1550 'useridto' => new external_value(PARAM_INT
, 'User to id'),
1551 'subject' => new external_value(PARAM_TEXT
, 'The message subject'),
1552 'text' => new external_value(PARAM_RAW
, 'The message text formated'),
1553 'fullmessage' => new external_value(PARAM_RAW
, 'The message'),
1554 'fullmessageformat' => new external_format_value('fullmessage'),
1555 'fullmessagehtml' => new external_value(PARAM_RAW
, 'The message in html'),
1556 'smallmessage' => new external_value(PARAM_RAW
, 'The shorten message'),
1557 'notification' => new external_value(PARAM_INT
, 'Is a notification?'),
1558 'contexturl' => new external_value(PARAM_RAW
, 'Context URL'),
1559 'contexturlname' => new external_value(PARAM_TEXT
, 'Context URL link name'),
1560 'timecreated' => new external_value(PARAM_INT
, 'Time created'),
1561 'timeread' => new external_value(PARAM_INT
, 'Time read'),
1562 'usertofullname' => new external_value(PARAM_TEXT
, 'User to full name'),
1563 'userfromfullname' => new external_value(PARAM_TEXT
, 'User from full name')
1567 'warnings' => new external_warnings()
1573 * Mark all notifications as read parameters description.
1575 * @return external_function_parameters
1578 public static function mark_all_notifications_as_read_parameters() {
1579 return new external_function_parameters(
1581 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
1582 'useridfrom' => new external_value(
1583 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1590 * Mark all notifications as read function.
1593 * @throws invalid_parameter_exception
1594 * @throws moodle_exception
1595 * @param int $useridto the user id who received the message
1596 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1597 * @return external_description
1599 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
1602 $params = self
::validate_parameters(
1603 self
::mark_all_notifications_as_read_parameters(),
1605 'useridto' => $useridto,
1606 'useridfrom' => $useridfrom,
1610 $context = context_system
::instance();
1611 self
::validate_context($context);
1613 $useridto = $params['useridto'];
1614 $useridfrom = $params['useridfrom'];
1616 if (!empty($useridto)) {
1617 if (core_user
::is_real_user($useridto)) {
1618 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
1620 throw new moodle_exception('invaliduser');
1624 if (!empty($useridfrom)) {
1625 // We use get_user here because the from user can be the noreply or support user.
1626 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
1629 // Check if the current user is the sender/receiver or just a privileged user.
1630 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
1631 // The deleteanymessage cap seems more reasonable here than readallmessages.
1632 !has_capability('moodle/site:deleteanymessage', $context)) {
1633 throw new moodle_exception('accessdenied', 'admin');
1636 \core_message\api
::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_NOTIFICATION
);
1642 * Mark all notifications as read return description.
1644 * @return external_single_structure
1647 public static function mark_all_notifications_as_read_returns() {
1648 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
1652 * Get unread conversations count parameters description.
1654 * @return external_function_parameters
1657 public static function get_unread_conversations_count_parameters() {
1658 return new external_function_parameters(
1660 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
1666 * Get unread messages count function.
1669 * @throws invalid_parameter_exception
1670 * @throws moodle_exception
1671 * @param int $useridto the user id who received the message
1672 * @return external_description
1674 public static function get_unread_conversations_count($useridto) {
1677 // Check if messaging is enabled.
1678 if (empty($CFG->messaging
)) {
1679 throw new moodle_exception('disabled', 'message');
1682 $params = self
::validate_parameters(
1683 self
::get_unread_conversations_count_parameters(),
1684 array('useridto' => $useridto)
1687 $context = context_system
::instance();
1688 self
::validate_context($context);
1690 $useridto = $params['useridto'];
1692 if (!empty($useridto)) {
1693 if (core_user
::is_real_user($useridto)) {
1694 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
1696 throw new moodle_exception('invaliduser');
1699 $useridto = $USER->id
;
1702 // Check if the current user is the receiver or just a privileged user.
1703 if ($useridto != $USER->id
and !has_capability('moodle/site:readallmessages', $context)) {
1704 throw new moodle_exception('accessdenied', 'admin');
1707 return \core_message\api
::count_unread_conversations($userto);
1711 * Get unread conversations count return description.
1713 * @return external_single_structure
1716 public static function get_unread_conversations_count_returns() {
1717 return new external_value(PARAM_INT
, 'The count of unread messages for the user');
1721 * Get blocked users parameters description.
1723 * @return external_function_parameters
1726 public static function get_blocked_users_parameters() {
1727 return new external_function_parameters(
1729 'userid' => new external_value(PARAM_INT
,
1730 'the user whose blocked users we want to retrieve',
1737 * Retrieve a list of users blocked
1739 * @param int $userid the user whose blocked users we want to retrieve
1740 * @return external_description
1743 public static function get_blocked_users($userid) {
1744 global $CFG, $USER, $PAGE;
1746 // Warnings array, it can be empty at the end but is mandatory.
1747 $warnings = array();
1753 $params = self
::validate_parameters(self
::get_blocked_users_parameters(), $params);
1754 $userid = $params['userid'];
1756 // Validate context.
1757 $context = context_system
::instance();
1758 self
::validate_context($context);
1760 // Check if private messaging between users is allowed.
1761 if (empty($CFG->messaging
)) {
1762 throw new moodle_exception('disabled', 'message');
1765 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
1766 core_user
::require_active_user($user);
1768 // Check if we have permissions for retrieve the information.
1769 $capability = 'moodle/site:manageallmessaging';
1770 if (($USER->id
!= $userid) && !has_capability($capability, $context)) {
1771 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1774 // Now, we can get safely all the blocked users.
1775 $users = message_get_blocked_users($user);
1777 $blockedusers = array();
1778 foreach ($users as $user) {
1781 'fullname' => fullname($user),
1784 $userpicture = new user_picture($user);
1785 $userpicture->size
= 1; // Size f1.
1786 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1788 $blockedusers[] = $newuser;
1792 'users' => $blockedusers,
1793 'warnings' => $warnings
1799 * Get blocked users return description.
1801 * @return external_single_structure
1804 public static function get_blocked_users_returns() {
1805 return new external_single_structure(
1807 'users' => new external_multiple_structure(
1808 new external_single_structure(
1810 'id' => new external_value(PARAM_INT
, 'User ID'),
1811 'fullname' => new external_value(PARAM_NOTAGS
, 'User full name'),
1812 'profileimageurl' => new external_value(PARAM_URL
, 'User picture URL', VALUE_OPTIONAL
)
1815 'List of blocked users'
1817 'warnings' => new external_warnings()
1823 * Returns description of method parameters
1825 * @return external_function_parameters
1828 public static function mark_message_read_parameters() {
1829 return new external_function_parameters(
1831 'messageid' => new external_value(PARAM_INT
, 'id of the message (in the message table)'),
1832 'timeread' => new external_value(PARAM_INT
, 'timestamp for when the message should be marked read',
1839 * Mark a single message as read, trigger message_viewed event
1841 * @param int $messageid id of the message (in the message table)
1842 * @param int $timeread timestamp for when the message should be marked read
1843 * @return external_description
1844 * @throws invalid_parameter_exception
1845 * @throws moodle_exception
1848 public static function mark_message_read($messageid, $timeread) {
1849 global $CFG, $DB, $USER;
1851 // Check if private messaging between users is allowed.
1852 if (empty($CFG->messaging
)) {
1853 throw new moodle_exception('disabled', 'message');
1856 // Warnings array, it can be empty at the end but is mandatory.
1857 $warnings = array();
1861 'messageid' => $messageid,
1862 'timeread' => $timeread
1864 $params = self
::validate_parameters(self
::mark_message_read_parameters(), $params);
1866 if (empty($params['timeread'])) {
1869 $timeread = $params['timeread'];
1872 // Validate context.
1873 $context = context_system
::instance();
1874 self
::validate_context($context);
1876 $message = $DB->get_record('message', array('id' => $params['messageid']), '*', MUST_EXIST
);
1878 if ($message->useridto
!= $USER->id
) {
1879 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
1882 $messageid = message_mark_message_read($message, $timeread);
1885 'messageid' => $messageid,
1886 'warnings' => $warnings
1892 * Returns description of method result value
1894 * @return external_description
1897 public static function mark_message_read_returns() {
1898 return new external_single_structure(
1900 'messageid' => new external_value(PARAM_INT
, 'the id of the message in the message_read table'),
1901 'warnings' => new external_warnings()
1907 * Mark all messages as read parameters description.
1909 * @return external_function_parameters
1912 public static function mark_all_messages_as_read_parameters() {
1913 return new external_function_parameters(
1915 'useridto' => new external_value(PARAM_INT
, 'the user id who received the message, 0 for any user', VALUE_REQUIRED
),
1916 'useridfrom' => new external_value(
1917 PARAM_INT
, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1924 * Mark all notifications as read function.
1927 * @throws invalid_parameter_exception
1928 * @throws moodle_exception
1929 * @param int $useridto the user id who received the message
1930 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1931 * @return external_description
1933 public static function mark_all_messages_as_read($useridto, $useridfrom) {
1936 // Check if messaging is enabled.
1937 if (empty($CFG->messaging
)) {
1938 throw new moodle_exception('disabled', 'message');
1941 $params = self
::validate_parameters(
1942 self
::mark_all_messages_as_read_parameters(),
1944 'useridto' => $useridto,
1945 'useridfrom' => $useridfrom,
1949 $context = context_system
::instance();
1950 self
::validate_context($context);
1952 $useridto = $params['useridto'];
1953 $useridfrom = $params['useridfrom'];
1955 if (!empty($useridto)) {
1956 if (core_user
::is_real_user($useridto)) {
1957 $userto = core_user
::get_user($useridto, '*', MUST_EXIST
);
1959 throw new moodle_exception('invaliduser');
1963 if (!empty($useridfrom)) {
1964 // We use get_user here because the from user can be the noreply or support user.
1965 $userfrom = core_user
::get_user($useridfrom, '*', MUST_EXIST
);
1968 // Check if the current user is the sender/receiver or just a privileged user.
1969 if ($useridto != $USER->id
and $useridfrom != $USER->id
and
1970 // The deleteanymessage cap seems more reasonable here than readallmessages.
1971 !has_capability('moodle/site:deleteanymessage', $context)) {
1972 throw new moodle_exception('accessdenied', 'admin');
1975 \core_message\api
::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_MESSAGE
);
1981 * Mark all notifications as read return description.
1983 * @return external_single_structure
1986 public static function mark_all_messages_as_read_returns() {
1987 return new external_value(PARAM_BOOL
, 'True if the messages were marked read, false otherwise');
1991 * Returns description of method parameters.
1993 * @return external_function_parameters
1996 public static function delete_conversation_parameters() {
1997 return new external_function_parameters(
1999 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the conversation for'),
2000 'otheruserid' => new external_value(PARAM_INT
, 'The user id of the other user in the conversation'),
2006 * Deletes a conversation.
2008 * @param int $userid The user id of who we want to delete the conversation for
2009 * @param int $otheruserid The user id of the other user in the conversation
2011 * @throws moodle_exception
2014 public static function delete_conversation($userid, $otheruserid) {
2017 // Check if private messaging between users is allowed.
2018 if (empty($CFG->messaging
)) {
2019 throw new moodle_exception('disabled', 'message');
2022 // Warnings array, it can be empty at the end but is mandatory.
2023 $warnings = array();
2027 'userid' => $userid,
2028 'otheruserid' => $otheruserid,
2030 $params = self
::validate_parameters(self
::delete_conversation_parameters(), $params);
2032 // Validate context.
2033 $context = context_system
::instance();
2034 self
::validate_context($context);
2036 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2037 core_user
::require_active_user($user);
2039 if (\core_message\api
::can_delete_conversation($user->id
)) {
2040 $status = \core_message\api
::delete_conversation($user->id
, $otheruserid);
2042 throw new moodle_exception('You do not have permission to delete messages');
2046 'status' => $status,
2047 'warnings' => $warnings
2054 * Returns description of method result value.
2056 * @return external_description
2059 public static function delete_conversation_returns() {
2060 return new external_single_structure(
2062 'status' => new external_value(PARAM_BOOL
, 'True if the conversation was deleted, false otherwise'),
2063 'warnings' => new external_warnings()
2069 * Returns description of method parameters
2071 * @return external_function_parameters
2074 public static function delete_message_parameters() {
2075 return new external_function_parameters(
2077 'messageid' => new external_value(PARAM_INT
, 'The message id'),
2078 'userid' => new external_value(PARAM_INT
, 'The user id of who we want to delete the message for'),
2079 'read' => new external_value(PARAM_BOOL
, 'If is a message read', VALUE_DEFAULT
, true)
2087 * @param int $messageid the message id
2088 * @param int $userid the user id of who we want to delete the message for
2089 * @param bool $read if is a message read (default to true)
2090 * @return external_description
2091 * @throws moodle_exception
2094 public static function delete_message($messageid, $userid, $read = true) {
2097 // Check if private messaging between users is allowed.
2098 if (empty($CFG->messaging
)) {
2099 throw new moodle_exception('disabled', 'message');
2102 // Warnings array, it can be empty at the end but is mandatory.
2103 $warnings = array();
2107 'messageid' => $messageid,
2108 'userid' => $userid,
2111 $params = self
::validate_parameters(self
::delete_message_parameters(), $params);
2113 // Validate context.
2114 $context = context_system
::instance();
2115 self
::validate_context($context);
2117 $messagestable = $params['read'] ?
'message_read' : 'message';
2118 $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST
);
2120 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2121 core_user
::require_active_user($user);
2124 if (message_can_delete_message($message, $user->id
)) {
2125 $status = message_delete_message($message, $user->id
);;
2127 throw new moodle_exception('You do not have permission to delete this message');
2131 'status' => $status,
2132 'warnings' => $warnings
2138 * Returns description of method result value
2140 * @return external_description
2143 public static function delete_message_returns() {
2144 return new external_single_structure(
2146 'status' => new external_value(PARAM_BOOL
, 'True if the message was deleted, false otherwise'),
2147 'warnings' => new external_warnings()
2153 * Returns description of method parameters
2155 * @return external_function_parameters
2158 public static function message_processor_config_form_parameters() {
2159 return new external_function_parameters(
2161 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_REQUIRED
),
2162 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor'),
2163 'formvalues' => new external_multiple_structure(
2164 new external_single_structure(
2166 'name' => new external_value(PARAM_TEXT
, 'name of the form element', VALUE_REQUIRED
),
2167 'value' => new external_value(PARAM_RAW
, 'value of the form element', VALUE_REQUIRED
),
2170 'Config form values',
2178 * Processes a message processor config form.
2180 * @param int $userid the user id
2181 * @param string $name the name of the processor
2182 * @param array $formvalues the form values
2183 * @return external_description
2184 * @throws moodle_exception
2187 public static function message_processor_config_form($userid, $name, $formvalues) {
2190 // Check if messaging is enabled.
2191 if (empty($CFG->messaging
)) {
2192 throw new moodle_exception('disabled', 'message');
2195 $params = self
::validate_parameters(
2196 self
::message_processor_config_form_parameters(),
2198 'userid' => $userid,
2200 'formvalues' => $formvalues,
2204 $user = self
::validate_preferences_permissions($params['userid']);
2206 $processor = get_message_processor($name);
2208 $form = new stdClass();
2210 foreach ($formvalues as $formvalue) {
2211 // Curly braces to ensure interpretation is consistent between
2213 $form->{$formvalue['name']} = $formvalue['value'];
2216 $processor->process_form($form, $preferences);
2218 if (!empty($preferences)) {
2219 set_user_preferences($preferences, $userid);
2224 * Returns description of method result value
2226 * @return external_description
2229 public static function message_processor_config_form_returns() {
2234 * Returns description of method parameters
2236 * @return external_function_parameters
2239 public static function get_message_processor_parameters() {
2240 return new external_function_parameters(
2242 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user'),
2243 'name' => new external_value(PARAM_TEXT
, 'The name of the message processor', VALUE_REQUIRED
),
2249 * Get a message processor.
2251 * @param int $userid
2252 * @param string $name the name of the processor
2253 * @return external_description
2254 * @throws moodle_exception
2257 public static function get_message_processor($userid = 0, $name) {
2258 global $USER, $PAGE, $CFG;
2260 // Check if messaging is enabled.
2261 if (empty($CFG->messaging
)) {
2262 throw new moodle_exception('disabled', 'message');
2265 $params = self
::validate_parameters(
2266 self
::get_message_processor_parameters(),
2268 'userid' => $userid,
2273 if (empty($params['userid'])) {
2274 $params['userid'] = $USER->id
;
2277 $user = core_user
::get_user($params['userid'], '*', MUST_EXIST
);
2278 core_user
::require_active_user($user);
2279 self
::validate_context(context_user
::instance($params['userid']));
2281 $processor = get_message_processor($name);
2283 $processoroutput = new \core_message\output\
processor($processor, $user);
2284 $renderer = $PAGE->get_renderer('core_message');
2286 return $processoroutput->export_for_template($renderer);
2290 * Returns description of method result value
2292 * @return external_description
2295 public static function get_message_processor_returns() {
2296 return new external_function_parameters(
2298 'systemconfigured' => new external_value(PARAM_BOOL
, 'Site configuration status'),
2299 'userconfigured' => new external_value(PARAM_BOOL
, 'The user configuration status'),
2305 * Check that the user has enough permission to retrieve message or notifications preferences.
2307 * @param int $userid the user id requesting the preferences
2308 * @return stdClass full user object
2309 * @throws moodle_exception
2312 protected static function validate_preferences_permissions($userid) {
2315 if (empty($userid)) {
2318 $user = core_user
::get_user($userid, '*', MUST_EXIST
);
2319 core_user
::require_active_user($user);
2322 $systemcontext = context_system
::instance();
2323 self
::validate_context($systemcontext);
2325 // Check access control.
2326 if ($user->id
== $USER->id
) {
2327 // Editing own message profile.
2328 require_capability('moodle/user:editownmessageprofile', $systemcontext);
2330 // Teachers, parents, etc.
2331 $personalcontext = context_user
::instance($user->id
);
2332 require_capability('moodle/user:editmessageprofile', $personalcontext);
2338 * Returns a notification or message preference structure.
2340 * @return external_single_structure the structure
2343 protected static function get_preferences_structure() {
2344 return new external_single_structure(
2346 'userid' => new external_value(PARAM_INT
, 'User id'),
2347 'disableall' => new external_value(PARAM_INT
, 'Whether all the preferences are disabled'),
2348 'processors' => new external_multiple_structure(
2349 new external_single_structure(
2351 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
2352 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
2353 'hassettings' => new external_value(PARAM_BOOL
, 'Whether has settings'),
2354 'contextid' => new external_value(PARAM_INT
, 'Context id'),
2355 'userconfigured' => new external_value(PARAM_INT
, 'Whether is configured by the user'),
2358 'Config form values'
2360 'components' => new external_multiple_structure(
2361 new external_single_structure(
2363 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
2364 'notifications' => new external_multiple_structure(
2365 new external_single_structure(
2367 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
2368 'preferencekey' => new external_value(PARAM_ALPHANUMEXT
, 'Preference key'),
2369 'processors' => new external_multiple_structure(
2370 new external_single_structure(
2372 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
2373 'name' => new external_value(PARAM_PLUGIN
, 'Processor name'),
2374 'locked' => new external_value(PARAM_BOOL
, 'Is locked by admin?'),
2375 'userconfigured' => new external_value(PARAM_INT
, 'Is configured?'),
2376 'loggedin' => new external_single_structure(
2378 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
2379 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
2380 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
2383 'loggedoff' => new external_single_structure(
2385 'name' => new external_value(PARAM_NOTAGS
, 'Name'),
2386 'displayname' => new external_value(PARAM_TEXT
, 'Display name'),
2387 'checked' => new external_value(PARAM_BOOL
, 'Is checked?'),
2392 'Processors values for this notification'
2396 'List of notificaitons for the component'
2400 'Available components'
2407 * Returns description of method parameters
2409 * @return external_function_parameters
2412 public static function get_user_notification_preferences_parameters() {
2413 return new external_function_parameters(
2415 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
2421 * Get the notification preferences for a given user.
2423 * @param int $userid id of the user, 0 for current user
2424 * @return external_description
2425 * @throws moodle_exception
2428 public static function get_user_notification_preferences($userid = 0) {
2431 $params = self
::validate_parameters(
2432 self
::get_user_notification_preferences_parameters(),
2434 'userid' => $userid,
2437 $user = self
::validate_preferences_permissions($params['userid']);
2439 $processors = get_message_processors();
2440 $providers = message_get_providers_for_user($user->id
);
2441 $preferences = \core_message\api
::get_all_message_preferences($processors, $providers, $user);
2442 $notificationlist = new \core_message\output\preferences\notification_list
($processors, $providers, $preferences, $user);
2444 $renderer = $PAGE->get_renderer('core_message');
2447 'warnings' => array(),
2448 'preferences' => $notificationlist->export_for_template($renderer)
2454 * Returns description of method result value
2456 * @return external_description
2459 public static function get_user_notification_preferences_returns() {
2460 return new external_function_parameters(
2462 'preferences' => self
::get_preferences_structure(),
2463 'warnings' => new external_warnings(),
2470 * Returns description of method parameters
2472 * @return external_function_parameters
2475 public static function get_user_message_preferences_parameters() {
2476 return new external_function_parameters(
2478 'userid' => new external_value(PARAM_INT
, 'id of the user, 0 for current user', VALUE_DEFAULT
, 0)
2484 * Get the notification preferences for a given user.
2486 * @param int $userid id of the user, 0 for current user
2487 * @return external_description
2488 * @throws moodle_exception
2491 public static function get_user_message_preferences($userid = 0) {
2494 $params = self
::validate_parameters(
2495 self
::get_user_message_preferences_parameters(),
2497 'userid' => $userid,
2501 $user = self
::validate_preferences_permissions($params['userid']);
2503 // Filter out enabled, available system_configured and user_configured processors only.
2504 $readyprocessors = array_filter(get_message_processors(), function($processor) {
2505 return $processor->enabled
&&
2506 $processor->configured
&&
2507 $processor->object->is_user_configured() &&
2508 // Filter out processors that don't have and message preferences to configure.
2509 $processor->object->has_message_preferences();
2512 $providers = array_filter(message_get_providers_for_user($user->id
), function($provider) {
2513 return $provider->component
=== 'moodle';
2515 $preferences = \core_message\api
::get_all_message_preferences($readyprocessors, $providers, $user);
2516 $notificationlistoutput = new \core_message\output\preferences\
message_notification_list($readyprocessors,
2517 $providers, $preferences, $user);
2519 $renderer = $PAGE->get_renderer('core_message');
2522 'warnings' => array(),
2523 'preferences' => $notificationlistoutput->export_for_template($renderer),
2524 'blocknoncontacts' => get_user_preferences('message_blocknoncontacts', '', $user->id
) ?
true : false,
2530 * Returns description of method result value
2532 * @return external_description
2535 public static function get_user_message_preferences_returns() {
2536 return new external_function_parameters(
2538 'preferences' => self
::get_preferences_structure(),
2539 'blocknoncontacts' => new external_value(PARAM_BOOL
, 'Whether to block or not messages from non contacts'),
2540 'warnings' => new external_warnings(),