Merge branch 'MDL-56433-master' of git://github.com/damyon/moodle
[moodle.git] / message / externallib.php
blob6e81c4f8bf46810d3bf23187570c9ff928b3f800
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * External message API
21 * @package core_message
22 * @category external
23 * @copyright 2011 Jerome Mouneyrac
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 require_once("$CFG->libdir/externallib.php");
28 require_once($CFG->dirroot . "/message/lib.php");
30 /**
31 * Message external functions
33 * @package core_message
34 * @category external
35 * @copyright 2011 Jerome Mouneyrac
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 * @since Moodle 2.2
39 class core_message_external extends external_api {
41 /**
42 * Returns description of method parameters
44 * @return external_function_parameters
45 * @since Moodle 2.2
47 public static function send_instant_messages_parameters() {
48 return new external_function_parameters(
49 array(
50 'messages' => new external_multiple_structure(
51 new external_single_structure(
52 array(
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),
64 /**
65 * Send private messages from the current USER to other users
67 * @param array $messages An array of message to send.
68 * @return array
69 * @since Moodle 2.2
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
87 $receivers = array();
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);
93 $blocklist = array();
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;
104 } else {
105 // $record->userid have current user as contact
106 $contactlist[$record->userid] = true;
109 $rs->close();
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
119 $success = true;
121 //check the user exists
122 if (empty($tousers[$message['touserid']])) {
123 $success = false;
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) {
129 $success = false;
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.
139 $success = false;
140 $errormessage = get_string('userisblockingyounoncontact', 'message',
141 fullname(core_user::get_user($message['touserid'])));
144 //now we can send the message (at least try)
145 if ($success) {
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'];
155 if ($success) {
156 $resultmsg['msgid'] = $success;
157 } else {
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
175 * @since Moodle 2.2
177 public static function send_instant_messages_returns() {
178 return new external_multiple_structure(
179 new external_single_structure(
180 array(
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
193 * @since Moodle 2.5
195 public static function create_contacts_parameters() {
196 return new external_function_parameters(
197 array(
198 'userids' => new external_multiple_structure(
199 new external_value(PARAM_INT, 'User ID'),
200 'List of user IDs'
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)
209 * Create contacts.
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
214 * @since Moodle 2.5
216 public static function create_contacts($userids, $userid = 0) {
217 global $CFG, $USER;
219 // Check if messaging is enabled.
220 if (empty($CFG->messaging)) {
221 throw new moodle_exception('disabled', 'message');
224 if (empty($userid)) {
225 $userid = $USER->id;
228 // Validate context.
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);
240 $warnings = array();
241 foreach ($params['userids'] as $id) {
242 if (!message_add_contact($id, 0, $userid)) {
243 $warnings[] = array(
244 'item' => 'user',
245 'itemid' => $id,
246 'warningcode' => 'contactnotcreated',
247 'message' => 'The contact could not be created'
251 return $warnings;
255 * Create contacts return description.
257 * @return external_description
258 * @since Moodle 2.5
260 public static function create_contacts_returns() {
261 return new external_warnings();
265 * Delete contacts parameters description.
267 * @return external_function_parameters
268 * @since Moodle 2.5
270 public static function delete_contacts_parameters() {
271 return new external_function_parameters(
272 array(
273 'userids' => new external_multiple_structure(
274 new external_value(PARAM_INT, 'User ID'),
275 'List of user IDs'
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)
284 * Delete contacts.
286 * @param array $userids array of user IDs.
287 * @param int $userid The id of the user we are deleting the contacts for
288 * @return null
289 * @since Moodle 2.5
291 public static function delete_contacts($userids, $userid = 0) {
292 global $CFG, $USER;
294 // Check if messaging is enabled.
295 if (empty($CFG->messaging)) {
296 throw new moodle_exception('disabled', 'message');
299 if (empty($userid)) {
300 $userid = $USER->id;
303 // Validate context.
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);
319 return null;
323 * Delete contacts return description.
325 * @return external_description
326 * @since Moodle 2.5
328 public static function delete_contacts_returns() {
329 return null;
333 * Block contacts parameters description.
335 * @return external_function_parameters
336 * @since Moodle 2.5
338 public static function block_contacts_parameters() {
339 return new external_function_parameters(
340 array(
341 'userids' => new external_multiple_structure(
342 new external_value(PARAM_INT, 'User ID'),
343 'List of user IDs'
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)
352 * Block contacts.
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
357 * @since Moodle 2.5
359 public static function block_contacts($userids, $userid = 0) {
360 global $CFG, $USER;
362 // Check if messaging is enabled.
363 if (empty($CFG->messaging)) {
364 throw new moodle_exception('disabled', 'message');
367 if (empty($userid)) {
368 $userid = $USER->id;
371 // Validate context.
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);
383 $warnings = array();
384 foreach ($params['userids'] as $id) {
385 if (!message_block_contact($id, $userid)) {
386 $warnings[] = array(
387 'item' => 'user',
388 'itemid' => $id,
389 'warningcode' => 'contactnotblocked',
390 'message' => 'The contact could not be blocked'
394 return $warnings;
398 * Block contacts return description.
400 * @return external_description
401 * @since Moodle 2.5
403 public static function block_contacts_returns() {
404 return new external_warnings();
408 * Unblock contacts parameters description.
410 * @return external_function_parameters
411 * @since Moodle 2.5
413 public static function unblock_contacts_parameters() {
414 return new external_function_parameters(
415 array(
416 'userids' => new external_multiple_structure(
417 new external_value(PARAM_INT, 'User ID'),
418 'List of user IDs'
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)
427 * Unblock contacts.
429 * @param array $userids array of user IDs.
430 * @param int $userid The id of the user we are unblocking the contacts for
431 * @return null
432 * @since Moodle 2.5
434 public static function unblock_contacts($userids, $userid = 0) {
435 global $CFG, $USER;
437 // Check if messaging is enabled.
438 if (empty($CFG->messaging)) {
439 throw new moodle_exception('disabled', 'message');
442 if (empty($userid)) {
443 $userid = $USER->id;
446 // Validate context.
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);
462 return null;
466 * Unblock contacts return description.
468 * @return external_description
469 * @since Moodle 2.5
471 public static function unblock_contacts_returns() {
472 return null;
476 * Return the structure of a message area contact.
478 * @return external_single_structure
479 * @since Moodle 3.2
481 private static function get_messagearea_contact_structure() {
482 return new external_single_structure(
483 array(
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 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
493 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'),
494 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'),
495 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation',
496 VALUE_DEFAULT, null),
502 * Return the structure of a message area message.
504 * @return external_single_structure
505 * @since Moodle 3.2
507 private static function get_messagearea_message_structure() {
508 return new external_single_structure(
509 array(
510 'id' => new external_value(PARAM_INT, 'The id of the message'),
511 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'),
512 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'),
513 'text' => new external_value(PARAM_RAW, 'The text of the message'),
514 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'),
515 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
516 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
517 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
518 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'),
524 * Get messagearea search users in course parameters.
526 * @return external_function_parameters
527 * @since 3.2
529 public static function data_for_messagearea_search_users_in_course_parameters() {
530 return new external_function_parameters(
531 array(
532 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
533 'courseid' => new external_value(PARAM_INT, 'The id of the course'),
534 'search' => new external_value(PARAM_RAW, 'The string being searched'),
535 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
536 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
542 * Get messagearea search users in course results.
544 * @param int $userid The id of the user who is performing the search
545 * @param int $courseid The id of the course
546 * @param string $search The string being searched
547 * @param int $limitfrom
548 * @param int $limitnum
549 * @return stdClass
550 * @throws moodle_exception
551 * @since 3.2
553 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0,
554 $limitnum = 0) {
555 global $CFG, $PAGE, $USER;
557 // Check if messaging is enabled.
558 if (empty($CFG->messaging)) {
559 throw new moodle_exception('disabled', 'message');
562 $systemcontext = context_system::instance();
564 $params = array(
565 'userid' => $userid,
566 'courseid' => $courseid,
567 'search' => $search,
568 'limitfrom' => $limitfrom,
569 'limitnum' => $limitnum
571 self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params);
572 self::validate_context($systemcontext);
574 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
575 throw new moodle_exception('You do not have permission to perform this action.');
578 $users = \core_message\api::search_users_in_course($userid, $courseid, $search, $limitfrom, $limitnum);
579 $results = new \core_message\output\messagearea\user_search_results($users);
581 $renderer = $PAGE->get_renderer('core_message');
582 return $results->export_for_template($renderer);
586 * Get messagearea search users in course returns.
588 * @return external_single_structure
589 * @since 3.2
591 public static function data_for_messagearea_search_users_in_course_returns() {
592 return new external_single_structure(
593 array(
594 'contacts' => new external_multiple_structure(
595 self::get_messagearea_contact_structure()
602 * Get messagearea search users parameters.
604 * @return external_function_parameters
605 * @since 3.2
607 public static function data_for_messagearea_search_users_parameters() {
608 return new external_function_parameters(
609 array(
610 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
611 'search' => new external_value(PARAM_RAW, 'The string being searched'),
612 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
618 * Get messagearea search users results.
620 * @param int $userid The id of the user who is performing the search
621 * @param string $search The string being searched
622 * @param int $limitnum
623 * @return stdClass
624 * @throws moodle_exception
625 * @since 3.2
627 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) {
628 global $CFG, $PAGE, $USER;
630 // Check if messaging is enabled.
631 if (empty($CFG->messaging)) {
632 throw new moodle_exception('disabled', 'message');
635 $systemcontext = context_system::instance();
637 $params = array(
638 'userid' => $userid,
639 'search' => $search,
640 'limitnum' => $limitnum
642 self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params);
643 self::validate_context($systemcontext);
645 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
646 throw new moodle_exception('You do not have permission to perform this action.');
649 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($userid, $search, $limitnum);
650 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts);
652 $renderer = $PAGE->get_renderer('core_message');
653 return $search->export_for_template($renderer);
657 * Get messagearea search users returns.
659 * @return external_single_structure
660 * @since 3.2
662 public static function data_for_messagearea_search_users_returns() {
663 return new external_single_structure(
664 array(
665 'contacts' => new external_multiple_structure(
666 self::get_messagearea_contact_structure()
668 'courses' => new external_multiple_structure(
669 new external_single_structure(
670 array(
671 'id' => new external_value(PARAM_INT, 'The course id'),
672 'shortname' => new external_value(PARAM_NOTAGS, 'The course shortname'),
673 'fullname' => new external_value(PARAM_NOTAGS, 'The course fullname'),
677 'noncontacts' => new external_multiple_structure(
678 self::get_messagearea_contact_structure()
685 * Get messagearea search messages parameters.
687 * @return external_function_parameters
688 * @since 3.2
690 public static function data_for_messagearea_search_messages_parameters() {
691 return new external_function_parameters(
692 array(
693 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'),
694 'search' => new external_value(PARAM_RAW, 'The string being searched'),
695 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
696 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
702 * Get messagearea search messages results.
704 * @param int $userid The id of the user who is performing the search
705 * @param string $search The string being searched
706 * @param int $limitfrom
707 * @param int $limitnum
708 * @return stdClass
709 * @throws moodle_exception
710 * @since 3.2
712 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) {
713 global $CFG, $PAGE, $USER;
715 // Check if messaging is enabled.
716 if (empty($CFG->messaging)) {
717 throw new moodle_exception('disabled', 'message');
720 $systemcontext = context_system::instance();
722 $params = array(
723 'userid' => $userid,
724 'search' => $search,
725 'limitfrom' => $limitfrom,
726 'limitnum' => $limitnum
729 self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params);
730 self::validate_context($systemcontext);
732 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
733 throw new moodle_exception('You do not have permission to perform this action.');
736 $messages = \core_message\api::search_messages($userid, $search, $limitfrom, $limitnum);
737 $results = new \core_message\output\messagearea\message_search_results($messages);
739 $renderer = $PAGE->get_renderer('core_message');
740 return $results->export_for_template($renderer);
744 * Get messagearea search messages returns.
746 * @return external_single_structure
747 * @since 3.2
749 public static function data_for_messagearea_search_messages_returns() {
750 return new external_single_structure(
751 array(
752 'contacts' => new external_multiple_structure(
753 self::get_messagearea_contact_structure()
760 * The messagearea conversations parameters.
762 * @return external_function_parameters
763 * @since 3.2
765 public static function data_for_messagearea_conversations_parameters() {
766 return new external_function_parameters(
767 array(
768 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
769 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
770 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
776 * Get messagearea conversations.
778 * @param int $userid The id of the user who we are viewing conversations for
779 * @param int $limitfrom
780 * @param int $limitnum
781 * @return stdClass
782 * @throws moodle_exception
783 * @since 3.2
785 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
786 global $CFG, $PAGE, $USER;
788 // Check if messaging is enabled.
789 if (empty($CFG->messaging)) {
790 throw new moodle_exception('disabled', 'message');
793 $systemcontext = context_system::instance();
795 $params = array(
796 'userid' => $userid,
797 'limitfrom' => $limitfrom,
798 'limitnum' => $limitnum
800 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
801 self::validate_context($systemcontext);
803 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
804 throw new moodle_exception('You do not have permission to perform this action.');
807 $conversations = \core_message\api::get_conversations($userid, $limitfrom, $limitnum);
808 $conversations = new \core_message\output\messagearea\contacts(null, $conversations);
810 $renderer = $PAGE->get_renderer('core_message');
811 return $conversations->export_for_template($renderer);
815 * The messagearea conversations return structure.
817 * @return external_single_structure
818 * @since 3.2
820 public static function data_for_messagearea_conversations_returns() {
821 return new external_single_structure(
822 array(
823 'contacts' => new external_multiple_structure(
824 self::get_messagearea_contact_structure()
831 * The messagearea contacts return parameters.
833 * @return external_function_parameters
834 * @since 3.2
836 public static function data_for_messagearea_contacts_parameters() {
837 return self::data_for_messagearea_conversations_parameters();
841 * Get messagearea contacts parameters.
843 * @param int $userid The id of the user who we are viewing conversations for
844 * @param int $limitfrom
845 * @param int $limitnum
846 * @return stdClass
847 * @throws moodle_exception
848 * @since 3.2
850 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
851 global $CFG, $PAGE, $USER;
853 // Check if messaging is enabled.
854 if (empty($CFG->messaging)) {
855 throw new moodle_exception('disabled', 'message');
858 $systemcontext = context_system::instance();
860 $params = array(
861 'userid' => $userid,
862 'limitfrom' => $limitfrom,
863 'limitnum' => $limitnum
865 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
866 self::validate_context($systemcontext);
868 if (($USER->id != $userid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
869 throw new moodle_exception('You do not have permission to perform this action.');
872 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
873 $contacts = new \core_message\output\messagearea\contacts(null, $contacts);
875 $renderer = $PAGE->get_renderer('core_message');
876 return $contacts->export_for_template($renderer);
880 * The messagearea contacts return structure.
882 * @return external_single_structure
883 * @since 3.2
885 public static function data_for_messagearea_contacts_returns() {
886 return self::data_for_messagearea_conversations_returns();
890 * The messagearea messages parameters.
892 * @return external_function_parameters
893 * @since 3.2
895 public static function data_for_messagearea_messages_parameters() {
896 return new external_function_parameters(
897 array(
898 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
899 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
900 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
901 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0),
902 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false),
908 * Get messagearea messages.
910 * @param int $currentuserid The current user's id
911 * @param int $otheruserid The other user's id
912 * @param int $limitfrom
913 * @param int $limitnum
914 * @param boolean $newest
915 * @return stdClass
916 * @throws moodle_exception
917 * @since 3.2
919 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0,
920 $newest = false) {
921 global $CFG, $PAGE, $USER;
923 // Check if messaging is enabled.
924 if (empty($CFG->messaging)) {
925 throw new moodle_exception('disabled', 'message');
928 $systemcontext = context_system::instance();
930 $params = array(
931 'currentuserid' => $currentuserid,
932 'otheruserid' => $otheruserid,
933 'limitfrom' => $limitfrom,
934 'limitnum' => $limitnum,
935 'newest' => $newest
937 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
938 self::validate_context($systemcontext);
940 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
941 throw new moodle_exception('You do not have permission to perform this action.');
944 if ($newest) {
945 $sort = 'timecreated DESC';
946 } else {
947 $sort = 'timecreated ASC';
949 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom, $limitnum, $sort);
950 $messages = new \core_message\output\messagearea\messages($currentuserid, $otheruserid, $messages);
952 $renderer = $PAGE->get_renderer('core_message');
953 return $messages->export_for_template($renderer);
957 * The messagearea messages return structure.
959 * @return external_single_structure
960 * @since 3.2
962 public static function data_for_messagearea_messages_returns() {
963 return new external_single_structure(
964 array(
965 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing
966 the messages on behalf of?'),
967 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
968 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
969 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
970 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
971 'messages' => new external_multiple_structure(
972 self::get_messagearea_message_structure()
979 * The get most recent message return parameters.
981 * @return external_function_parameters
982 * @since 3.2
984 public static function data_for_messagearea_get_most_recent_message_parameters() {
985 return new external_function_parameters(
986 array(
987 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
988 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
994 * Get the most recent message in a conversation.
996 * @param int $currentuserid The current user's id
997 * @param int $otheruserid The other user's id
998 * @return stdClass
999 * @throws moodle_exception
1000 * @since 3.2
1002 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) {
1003 global $CFG, $PAGE, $USER;
1005 // Check if messaging is enabled.
1006 if (empty($CFG->messaging)) {
1007 throw new moodle_exception('disabled', 'message');
1010 $systemcontext = context_system::instance();
1012 $params = array(
1013 'currentuserid' => $currentuserid,
1014 'otheruserid' => $otheruserid
1016 self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params);
1017 self::validate_context($systemcontext);
1019 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1020 throw new moodle_exception('You do not have permission to perform this action.');
1023 $message = \core_message\api::get_most_recent_message($currentuserid, $otheruserid);
1024 $message = new \core_message\output\messagearea\message($message);
1026 $renderer = $PAGE->get_renderer('core_message');
1027 return $message->export_for_template($renderer);
1031 * The get most recent message return structure.
1033 * @return external_single_structure
1034 * @since 3.2
1036 public static function data_for_messagearea_get_most_recent_message_returns() {
1037 return self::get_messagearea_message_structure();
1041 * The get profile parameters.
1043 * @return external_function_parameters
1044 * @since 3.2
1046 public static function data_for_messagearea_get_profile_parameters() {
1047 return new external_function_parameters(
1048 array(
1049 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
1050 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'),
1056 * Get the profile information for a contact.
1058 * @param int $currentuserid The current user's id
1059 * @param int $otheruserid The id of the user whose profile we are viewing
1060 * @return stdClass
1061 * @throws moodle_exception
1062 * @since 3.2
1064 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) {
1065 global $CFG, $PAGE, $USER;
1067 // Check if messaging is enabled.
1068 if (empty($CFG->messaging)) {
1069 throw new moodle_exception('disabled', 'message');
1072 $systemcontext = context_system::instance();
1074 $params = array(
1075 'currentuserid' => $currentuserid,
1076 'otheruserid' => $otheruserid
1078 self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params);
1079 self::validate_context($systemcontext);
1081 if (($USER->id != $currentuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
1082 throw new moodle_exception('You do not have permission to perform this action.');
1085 $profile = \core_message\api::get_profile($currentuserid, $otheruserid);
1086 $profile = new \core_message\output\messagearea\profile($profile);
1088 $renderer = $PAGE->get_renderer('core_message');
1089 return $profile->export_for_template($renderer);
1093 * The get profile return structure.
1095 * @return external_single_structure
1096 * @since 3.2
1098 public static function data_for_messagearea_get_profile_returns() {
1099 return new external_single_structure(
1100 array(
1101 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'),
1102 'email' => new external_value(core_user::get_property_type('email'), 'An email address'),
1103 'country' => new external_value(PARAM_TEXT, 'Home country of the user'),
1104 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'),
1105 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
1106 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
1107 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
1108 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'),
1109 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'),
1110 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?')
1116 * Get contacts parameters description.
1118 * @return external_function_parameters
1119 * @since Moodle 2.5
1121 public static function get_contacts_parameters() {
1122 return new external_function_parameters(array());
1126 * Get contacts.
1128 * @return external_description
1129 * @since Moodle 2.5
1131 public static function get_contacts() {
1132 global $CFG, $PAGE;
1134 // Check if messaging is enabled.
1135 if (empty($CFG->messaging)) {
1136 throw new moodle_exception('disabled', 'message');
1139 require_once($CFG->dirroot . '/user/lib.php');
1141 list($online, $offline, $strangers) = message_get_contacts();
1142 $allcontacts = array('online' => $online, 'offline' => $offline, 'strangers' => $strangers);
1143 foreach ($allcontacts as $mode => $contacts) {
1144 foreach ($contacts as $key => $contact) {
1145 $newcontact = array(
1146 'id' => $contact->id,
1147 'fullname' => fullname($contact),
1148 'unread' => $contact->messagecount
1151 $userpicture = new user_picture($contact);
1152 $userpicture->size = 1; // Size f1.
1153 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1154 $userpicture->size = 0; // Size f2.
1155 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1157 $allcontacts[$mode][$key] = $newcontact;
1160 return $allcontacts;
1164 * Get contacts return description.
1166 * @return external_description
1167 * @since Moodle 2.5
1169 public static function get_contacts_returns() {
1170 return new external_single_structure(
1171 array(
1172 'online' => new external_multiple_structure(
1173 new external_single_structure(
1174 array(
1175 'id' => new external_value(PARAM_INT, 'User ID'),
1176 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1177 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1178 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1179 'unread' => new external_value(PARAM_INT, 'Unread message count')
1182 'List of online contacts'
1184 'offline' => new external_multiple_structure(
1185 new external_single_structure(
1186 array(
1187 'id' => new external_value(PARAM_INT, 'User ID'),
1188 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1189 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1190 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1191 'unread' => new external_value(PARAM_INT, 'Unread message count')
1194 'List of offline contacts'
1196 'strangers' => new external_multiple_structure(
1197 new external_single_structure(
1198 array(
1199 'id' => new external_value(PARAM_INT, 'User ID'),
1200 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1201 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1202 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
1203 'unread' => new external_value(PARAM_INT, 'Unread message count')
1206 'List of users that are not in the user\'s contact list but have sent a message'
1213 * Search contacts parameters description.
1215 * @return external_function_parameters
1216 * @since Moodle 2.5
1218 public static function search_contacts_parameters() {
1219 return new external_function_parameters(
1220 array(
1221 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
1222 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
1223 VALUE_DEFAULT, false)
1229 * Search contacts.
1231 * @param string $searchtext query string.
1232 * @param bool $onlymycourses limit the search to the user's courses only.
1233 * @return external_description
1234 * @since Moodle 2.5
1236 public static function search_contacts($searchtext, $onlymycourses = false) {
1237 global $CFG, $USER, $PAGE;
1238 require_once($CFG->dirroot . '/user/lib.php');
1240 // Check if messaging is enabled.
1241 if (empty($CFG->messaging)) {
1242 throw new moodle_exception('disabled', 'message');
1245 require_once($CFG->libdir . '/enrollib.php');
1247 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
1248 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
1250 // Extra validation, we do not allow empty queries.
1251 if ($params['searchtext'] === '') {
1252 throw new moodle_exception('querystringcannotbeempty');
1255 $courseids = array();
1256 if ($params['onlymycourses']) {
1257 $mycourses = enrol_get_my_courses(array('id'));
1258 foreach ($mycourses as $mycourse) {
1259 $courseids[] = $mycourse->id;
1261 } else {
1262 $courseids[] = SITEID;
1265 // Retrieving the users matching the query.
1266 $users = message_search_users($courseids, $params['searchtext']);
1267 $results = array();
1268 foreach ($users as $user) {
1269 $results[$user->id] = $user;
1272 // Reorganising information.
1273 foreach ($results as &$user) {
1274 $newuser = array(
1275 'id' => $user->id,
1276 'fullname' => fullname($user)
1279 // Avoid undefined property notice as phone not specified.
1280 $user->phone1 = null;
1281 $user->phone2 = null;
1283 $userpicture = new user_picture($user);
1284 $userpicture->size = 1; // Size f1.
1285 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1286 $userpicture->size = 0; // Size f2.
1287 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
1289 $user = $newuser;
1292 return $results;
1296 * Search contacts return description.
1298 * @return external_description
1299 * @since Moodle 2.5
1301 public static function search_contacts_returns() {
1302 return new external_multiple_structure(
1303 new external_single_structure(
1304 array(
1305 'id' => new external_value(PARAM_INT, 'User ID'),
1306 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1307 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
1308 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
1311 'List of contacts'
1316 * Get messages parameters description.
1318 * @return external_function_parameters
1319 * @since 2.8
1321 public static function get_messages_parameters() {
1322 return new external_function_parameters(
1323 array(
1324 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1325 'useridfrom' => new external_value(
1326 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1327 VALUE_DEFAULT, 0),
1328 'type' => new external_value(
1329 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
1330 VALUE_DEFAULT, 'both'),
1331 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
1332 'newestfirst' => new external_value(
1333 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
1334 VALUE_DEFAULT, true),
1335 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
1336 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
1342 * Get messages function implementation.
1344 * @since 2.8
1345 * @throws invalid_parameter_exception
1346 * @throws moodle_exception
1347 * @param int $useridto the user id who received the message
1348 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1349 * @param string $type type of message to return, expected values: notifications, conversations and both
1350 * @param bool $read true for retreiving read messages, false for unread
1351 * @param bool $newestfirst true for ordering by newest first, false for oldest first
1352 * @param int $limitfrom limit from
1353 * @param int $limitnum limit num
1354 * @return external_description
1356 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
1357 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
1358 global $CFG, $USER;
1360 $warnings = array();
1362 $params = array(
1363 'useridto' => $useridto,
1364 'useridfrom' => $useridfrom,
1365 'type' => $type,
1366 'read' => $read,
1367 'newestfirst' => $newestfirst,
1368 'limitfrom' => $limitfrom,
1369 'limitnum' => $limitnum
1372 $params = self::validate_parameters(self::get_messages_parameters(), $params);
1374 $context = context_system::instance();
1375 self::validate_context($context);
1377 $useridto = $params['useridto'];
1378 $useridfrom = $params['useridfrom'];
1379 $type = $params['type'];
1380 $read = $params['read'];
1381 $newestfirst = $params['newestfirst'];
1382 $limitfrom = $params['limitfrom'];
1383 $limitnum = $params['limitnum'];
1385 $allowedvalues = array('notifications', 'conversations', 'both');
1386 if (!in_array($type, $allowedvalues)) {
1387 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
1388 'allowed values are: ' . implode(',', $allowedvalues));
1391 // Check if private messaging between users is allowed.
1392 if (empty($CFG->messaging)) {
1393 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
1394 if ($type == "conversations") {
1395 throw new moodle_exception('disabled', 'message');
1397 if ($type == "both") {
1398 $warning = array();
1399 $warning['item'] = 'message';
1400 $warning['itemid'] = $USER->id;
1401 $warning['warningcode'] = '1';
1402 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
1403 Only notifications will be returned';
1404 $warnings[] = $warning;
1408 if (!empty($useridto)) {
1409 if (core_user::is_real_user($useridto)) {
1410 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1411 } else {
1412 throw new moodle_exception('invaliduser');
1416 if (!empty($useridfrom)) {
1417 // We use get_user here because the from user can be the noreply or support user.
1418 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1421 // Check if the current user is the sender/receiver or just a privileged user.
1422 if ($useridto != $USER->id and $useridfrom != $USER->id and
1423 !has_capability('moodle/site:readallmessages', $context)) {
1424 throw new moodle_exception('accessdenied', 'admin');
1427 // Which type of messages to retrieve.
1428 $notifications = -1;
1429 if ($type != 'both') {
1430 $notifications = ($type == 'notifications') ? 1 : 0;
1433 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
1434 $sort = "mr.timecreated $orderdirection";
1436 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
1437 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
1439 // In some cases, we don't need to get the to/from user objects from the sql query.
1440 $userfromfullname = '';
1441 $usertofullname = '';
1443 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
1444 if (!empty($useridto)) {
1445 $usertofullname = fullname($userto, $canviewfullname);
1446 // The user from may or may not be filled.
1447 if (!empty($useridfrom)) {
1448 $userfromfullname = fullname($userfrom, $canviewfullname);
1450 } else {
1451 // If the useridto field is empty, the useridfrom must be filled.
1452 $userfromfullname = fullname($userfrom, $canviewfullname);
1454 foreach ($messages as $mid => $message) {
1456 // Do not return deleted messages.
1457 if (($useridto == $USER->id and $message->timeusertodeleted) or
1458 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
1460 unset($messages[$mid]);
1461 continue;
1464 // We need to get the user from the query.
1465 if (empty($userfromfullname)) {
1466 // Check for non-reply and support users.
1467 if (core_user::is_real_user($message->useridfrom)) {
1468 $user = new stdClass();
1469 $user = username_load_fields_from_object($user, $message, 'userfrom');
1470 $message->userfromfullname = fullname($user, $canviewfullname);
1471 } else {
1472 $user = core_user::get_user($message->useridfrom);
1473 $message->userfromfullname = fullname($user, $canviewfullname);
1475 } else {
1476 $message->userfromfullname = $userfromfullname;
1479 // We need to get the user from the query.
1480 if (empty($usertofullname)) {
1481 $user = new stdClass();
1482 $user = username_load_fields_from_object($user, $message, 'userto');
1483 $message->usertofullname = fullname($user, $canviewfullname);
1484 } else {
1485 $message->usertofullname = $usertofullname;
1488 // This field is only available in the message_read table.
1489 if (!isset($message->timeread)) {
1490 $message->timeread = 0;
1493 $message->text = message_format_message_text($message);
1494 $messages[$mid] = (array) $message;
1498 $results = array(
1499 'messages' => $messages,
1500 'warnings' => $warnings
1503 return $results;
1507 * Get messages return description.
1509 * @return external_single_structure
1510 * @since 2.8
1512 public static function get_messages_returns() {
1513 return new external_single_structure(
1514 array(
1515 'messages' => new external_multiple_structure(
1516 new external_single_structure(
1517 array(
1518 'id' => new external_value(PARAM_INT, 'Message id'),
1519 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1520 'useridto' => new external_value(PARAM_INT, 'User to id'),
1521 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1522 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1523 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
1524 'fullmessageformat' => new external_format_value('fullmessage'),
1525 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1526 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1527 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
1528 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1529 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1530 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1531 'timeread' => new external_value(PARAM_INT, 'Time read'),
1532 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
1533 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
1534 ), 'message'
1537 'warnings' => new external_warnings()
1543 * Mark all notifications as read parameters description.
1545 * @return external_function_parameters
1546 * @since 3.2
1548 public static function mark_all_notifications_as_read_parameters() {
1549 return new external_function_parameters(
1550 array(
1551 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1552 'useridfrom' => new external_value(
1553 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1554 VALUE_DEFAULT, 0),
1560 * Mark all notifications as read function.
1562 * @since 3.2
1563 * @throws invalid_parameter_exception
1564 * @throws moodle_exception
1565 * @param int $useridto the user id who received the message
1566 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1567 * @return external_description
1569 public static function mark_all_notifications_as_read($useridto, $useridfrom) {
1570 global $USER;
1572 $params = self::validate_parameters(
1573 self::mark_all_notifications_as_read_parameters(),
1574 array(
1575 'useridto' => $useridto,
1576 'useridfrom' => $useridfrom,
1580 $context = context_system::instance();
1581 self::validate_context($context);
1583 $useridto = $params['useridto'];
1584 $useridfrom = $params['useridfrom'];
1586 if (!empty($useridto)) {
1587 if (core_user::is_real_user($useridto)) {
1588 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1589 } else {
1590 throw new moodle_exception('invaliduser');
1594 if (!empty($useridfrom)) {
1595 // We use get_user here because the from user can be the noreply or support user.
1596 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1599 // Check if the current user is the sender/receiver or just a privileged user.
1600 if ($useridto != $USER->id and $useridfrom != $USER->id and
1601 // The deleteanymessage cap seems more reasonable here than readallmessages.
1602 !has_capability('moodle/site:deleteanymessage', $context)) {
1603 throw new moodle_exception('accessdenied', 'admin');
1606 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_NOTIFICATION);
1608 return true;
1612 * Mark all notifications as read return description.
1614 * @return external_single_structure
1615 * @since 3.2
1617 public static function mark_all_notifications_as_read_returns() {
1618 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
1622 * Get unread conversations count parameters description.
1624 * @return external_function_parameters
1625 * @since 3.2
1627 public static function get_unread_conversations_count_parameters() {
1628 return new external_function_parameters(
1629 array(
1630 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1636 * Get unread messages count function.
1638 * @since 3.2
1639 * @throws invalid_parameter_exception
1640 * @throws moodle_exception
1641 * @param int $useridto the user id who received the message
1642 * @return external_description
1644 public static function get_unread_conversations_count($useridto) {
1645 global $USER, $CFG;
1647 // Check if messaging is enabled.
1648 if (empty($CFG->messaging)) {
1649 throw new moodle_exception('disabled', 'message');
1652 $params = self::validate_parameters(
1653 self::get_unread_conversations_count_parameters(),
1654 array('useridto' => $useridto)
1657 $context = context_system::instance();
1658 self::validate_context($context);
1660 $useridto = $params['useridto'];
1662 if (!empty($useridto)) {
1663 if (core_user::is_real_user($useridto)) {
1664 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1665 } else {
1666 throw new moodle_exception('invaliduser');
1668 } else {
1669 $useridto = $USER->id;
1672 // Check if the current user is the receiver or just a privileged user.
1673 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1674 throw new moodle_exception('accessdenied', 'admin');
1677 return \core_message\api::count_unread_conversations($userto);
1681 * Get unread conversations count return description.
1683 * @return external_single_structure
1684 * @since 3.2
1686 public static function get_unread_conversations_count_returns() {
1687 return new external_value(PARAM_INT, 'The count of unread messages for the user');
1691 * Get blocked users parameters description.
1693 * @return external_function_parameters
1694 * @since 2.9
1696 public static function get_blocked_users_parameters() {
1697 return new external_function_parameters(
1698 array(
1699 'userid' => new external_value(PARAM_INT,
1700 'the user whose blocked users we want to retrieve',
1701 VALUE_REQUIRED),
1707 * Retrieve a list of users blocked
1709 * @param int $userid the user whose blocked users we want to retrieve
1710 * @return external_description
1711 * @since 2.9
1713 public static function get_blocked_users($userid) {
1714 global $CFG, $USER, $PAGE;
1716 // Check if messaging is enabled.
1717 if (empty($CFG->messaging)) {
1718 throw new moodle_exception('disabled', 'message');
1721 // Warnings array, it can be empty at the end but is mandatory.
1722 $warnings = array();
1724 // Validate params.
1725 $params = array(
1726 'userid' => $userid
1728 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
1729 $userid = $params['userid'];
1731 // Validate context.
1732 $context = context_system::instance();
1733 self::validate_context($context);
1735 // Check if private messaging between users is allowed.
1736 if (empty($CFG->messaging)) {
1737 throw new moodle_exception('disabled', 'message');
1740 $user = core_user::get_user($userid, '*', MUST_EXIST);
1741 core_user::require_active_user($user);
1743 // Check if we have permissions for retrieve the information.
1744 $capability = 'moodle/site:manageallmessaging';
1745 if (($USER->id != $userid) && !has_capability($capability, $context)) {
1746 throw new required_capability_exception($context, $capability, 'nopermissions', '');
1749 // Now, we can get safely all the blocked users.
1750 $users = message_get_blocked_users($user);
1752 $blockedusers = array();
1753 foreach ($users as $user) {
1754 $newuser = array(
1755 'id' => $user->id,
1756 'fullname' => fullname($user),
1759 $userpicture = new user_picture($user);
1760 $userpicture->size = 1; // Size f1.
1761 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1763 $blockedusers[] = $newuser;
1766 $results = array(
1767 'users' => $blockedusers,
1768 'warnings' => $warnings
1770 return $results;
1774 * Get blocked users return description.
1776 * @return external_single_structure
1777 * @since 2.9
1779 public static function get_blocked_users_returns() {
1780 return new external_single_structure(
1781 array(
1782 'users' => new external_multiple_structure(
1783 new external_single_structure(
1784 array(
1785 'id' => new external_value(PARAM_INT, 'User ID'),
1786 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1787 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
1790 'List of blocked users'
1792 'warnings' => new external_warnings()
1798 * Returns description of method parameters
1800 * @return external_function_parameters
1801 * @since 2.9
1803 public static function mark_message_read_parameters() {
1804 return new external_function_parameters(
1805 array(
1806 'messageid' => new external_value(PARAM_INT, 'id of the message (in the message table)'),
1807 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read',
1808 VALUE_DEFAULT, 0)
1814 * Mark a single message as read, trigger message_viewed event
1816 * @param int $messageid id of the message (in the message table)
1817 * @param int $timeread timestamp for when the message should be marked read
1818 * @return external_description
1819 * @throws invalid_parameter_exception
1820 * @throws moodle_exception
1821 * @since 2.9
1823 public static function mark_message_read($messageid, $timeread) {
1824 global $CFG, $DB, $USER;
1826 // Check if private messaging between users is allowed.
1827 if (empty($CFG->messaging)) {
1828 throw new moodle_exception('disabled', 'message');
1831 // Warnings array, it can be empty at the end but is mandatory.
1832 $warnings = array();
1834 // Validate params.
1835 $params = array(
1836 'messageid' => $messageid,
1837 'timeread' => $timeread
1839 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
1841 if (empty($params['timeread'])) {
1842 $timeread = time();
1843 } else {
1844 $timeread = $params['timeread'];
1847 // Validate context.
1848 $context = context_system::instance();
1849 self::validate_context($context);
1851 $message = $DB->get_record('message', array('id' => $params['messageid']), '*', MUST_EXIST);
1853 if ($message->useridto != $USER->id) {
1854 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
1857 $messageid = message_mark_message_read($message, $timeread);
1859 $results = array(
1860 'messageid' => $messageid,
1861 'warnings' => $warnings
1863 return $results;
1867 * Returns description of method result value
1869 * @return external_description
1870 * @since 2.9
1872 public static function mark_message_read_returns() {
1873 return new external_single_structure(
1874 array(
1875 'messageid' => new external_value(PARAM_INT, 'the id of the message in the message_read table'),
1876 'warnings' => new external_warnings()
1882 * Mark all messages as read parameters description.
1884 * @return external_function_parameters
1885 * @since 3.2
1887 public static function mark_all_messages_as_read_parameters() {
1888 return new external_function_parameters(
1889 array(
1890 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
1891 'useridfrom' => new external_value(
1892 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
1893 VALUE_DEFAULT, 0),
1899 * Mark all notifications as read function.
1901 * @since 3.2
1902 * @throws invalid_parameter_exception
1903 * @throws moodle_exception
1904 * @param int $useridto the user id who received the message
1905 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
1906 * @return external_description
1908 public static function mark_all_messages_as_read($useridto, $useridfrom) {
1909 global $USER, $CFG;
1911 // Check if messaging is enabled.
1912 if (empty($CFG->messaging)) {
1913 throw new moodle_exception('disabled', 'message');
1916 $params = self::validate_parameters(
1917 self::mark_all_messages_as_read_parameters(),
1918 array(
1919 'useridto' => $useridto,
1920 'useridfrom' => $useridfrom,
1924 $context = context_system::instance();
1925 self::validate_context($context);
1927 $useridto = $params['useridto'];
1928 $useridfrom = $params['useridfrom'];
1930 if (!empty($useridto)) {
1931 if (core_user::is_real_user($useridto)) {
1932 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
1933 } else {
1934 throw new moodle_exception('invaliduser');
1938 if (!empty($useridfrom)) {
1939 // We use get_user here because the from user can be the noreply or support user.
1940 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
1943 // Check if the current user is the sender/receiver or just a privileged user.
1944 if ($useridto != $USER->id and $useridfrom != $USER->id and
1945 // The deleteanymessage cap seems more reasonable here than readallmessages.
1946 !has_capability('moodle/site:deleteanymessage', $context)) {
1947 throw new moodle_exception('accessdenied', 'admin');
1950 \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_MESSAGE);
1952 return true;
1956 * Mark all notifications as read return description.
1958 * @return external_single_structure
1959 * @since 3.2
1961 public static function mark_all_messages_as_read_returns() {
1962 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise');
1966 * Returns description of method parameters.
1968 * @return external_function_parameters
1969 * @since 3.2
1971 public static function delete_conversation_parameters() {
1972 return new external_function_parameters(
1973 array(
1974 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'),
1975 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'),
1981 * Deletes a conversation.
1983 * @param int $userid The user id of who we want to delete the conversation for
1984 * @param int $otheruserid The user id of the other user in the conversation
1985 * @return array
1986 * @throws moodle_exception
1987 * @since 3.2
1989 public static function delete_conversation($userid, $otheruserid) {
1990 global $CFG;
1992 // Check if private messaging between users is allowed.
1993 if (empty($CFG->messaging)) {
1994 throw new moodle_exception('disabled', 'message');
1997 // Warnings array, it can be empty at the end but is mandatory.
1998 $warnings = array();
2000 // Validate params.
2001 $params = array(
2002 'userid' => $userid,
2003 'otheruserid' => $otheruserid,
2005 $params = self::validate_parameters(self::delete_conversation_parameters(), $params);
2007 // Validate context.
2008 $context = context_system::instance();
2009 self::validate_context($context);
2011 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2012 core_user::require_active_user($user);
2014 if (\core_message\api::can_delete_conversation($user->id)) {
2015 $status = \core_message\api::delete_conversation($user->id, $otheruserid);
2016 } else {
2017 throw new moodle_exception('You do not have permission to delete messages');
2020 $results = array(
2021 'status' => $status,
2022 'warnings' => $warnings
2025 return $results;
2029 * Returns description of method result value.
2031 * @return external_description
2032 * @since 3.2
2034 public static function delete_conversation_returns() {
2035 return new external_single_structure(
2036 array(
2037 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'),
2038 'warnings' => new external_warnings()
2044 * Returns description of method parameters
2046 * @return external_function_parameters
2047 * @since 3.1
2049 public static function delete_message_parameters() {
2050 return new external_function_parameters(
2051 array(
2052 'messageid' => new external_value(PARAM_INT, 'The message id'),
2053 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
2054 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
2060 * Deletes a message
2062 * @param int $messageid the message id
2063 * @param int $userid the user id of who we want to delete the message for
2064 * @param bool $read if is a message read (default to true)
2065 * @return external_description
2066 * @throws moodle_exception
2067 * @since 3.1
2069 public static function delete_message($messageid, $userid, $read = true) {
2070 global $CFG, $DB;
2072 // Check if private messaging between users is allowed.
2073 if (empty($CFG->messaging)) {
2074 throw new moodle_exception('disabled', 'message');
2077 // Warnings array, it can be empty at the end but is mandatory.
2078 $warnings = array();
2080 // Validate params.
2081 $params = array(
2082 'messageid' => $messageid,
2083 'userid' => $userid,
2084 'read' => $read
2086 $params = self::validate_parameters(self::delete_message_parameters(), $params);
2088 // Validate context.
2089 $context = context_system::instance();
2090 self::validate_context($context);
2092 $messagestable = $params['read'] ? 'message_read' : 'message';
2093 $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
2095 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2096 core_user::require_active_user($user);
2098 $status = false;
2099 if (message_can_delete_message($message, $user->id)) {
2100 $status = message_delete_message($message, $user->id);;
2101 } else {
2102 throw new moodle_exception('You do not have permission to delete this message');
2105 $results = array(
2106 'status' => $status,
2107 'warnings' => $warnings
2109 return $results;
2113 * Returns description of method result value
2115 * @return external_description
2116 * @since 3.1
2118 public static function delete_message_returns() {
2119 return new external_single_structure(
2120 array(
2121 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
2122 'warnings' => new external_warnings()
2128 * Returns description of method parameters
2130 * @return external_function_parameters
2131 * @since 3.2
2133 public static function message_processor_config_form_parameters() {
2134 return new external_function_parameters(
2135 array(
2136 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
2137 'name' => new external_value(PARAM_TEXT, 'The name of the message processor'),
2138 'formvalues' => new external_multiple_structure(
2139 new external_single_structure(
2140 array(
2141 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED),
2142 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED),
2145 'Config form values',
2146 VALUE_REQUIRED
2153 * Processes a message processor config form.
2155 * @param int $userid the user id
2156 * @param string $name the name of the processor
2157 * @param array $formvalues the form values
2158 * @return external_description
2159 * @throws moodle_exception
2160 * @since 3.2
2162 public static function message_processor_config_form($userid, $name, $formvalues) {
2163 global $USER, $CFG;
2165 // Check if messaging is enabled.
2166 if (empty($CFG->messaging)) {
2167 throw new moodle_exception('disabled', 'message');
2170 $params = self::validate_parameters(
2171 self::message_processor_config_form_parameters(),
2172 array(
2173 'userid' => $userid,
2174 'name' => $name,
2175 'formvalues' => $formvalues,
2179 if (empty($params['userid'])) {
2180 $params['userid'] = $USER->id;
2183 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2184 core_user::require_active_user($user);
2186 $processor = get_message_processor($name);
2187 $preferences = [];
2188 $form = new stdClass();
2190 foreach ($formvalues as $formvalue) {
2191 // Curly braces to ensure interpretation is consistent between
2192 // php 5 and php 7.
2193 $form->{$formvalue['name']} = $formvalue['value'];
2196 $processor->process_form($form, $preferences);
2198 if (!empty($preferences)) {
2199 set_user_preferences($preferences, $userid);
2204 * Returns description of method result value
2206 * @return external_description
2207 * @since 3.2
2209 public static function message_processor_config_form_returns() {
2210 return null;
2214 * Returns description of method parameters
2216 * @return external_function_parameters
2217 * @since 3.2
2219 public static function get_message_processor_parameters() {
2220 return new external_function_parameters(
2221 array(
2222 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'),
2223 'name' => new external_value(PARAM_TEXT, 'The name of the message processor', VALUE_REQUIRED),
2229 * Get a message processor.
2231 * @param int $userid
2232 * @param string $name the name of the processor
2233 * @return external_description
2234 * @throws moodle_exception
2235 * @since 3.2
2237 public static function get_message_processor($userid = 0, $name) {
2238 global $USER, $PAGE, $CFG;
2240 // Check if messaging is enabled.
2241 if (empty($CFG->messaging)) {
2242 throw new moodle_exception('disabled', 'message');
2245 $params = self::validate_parameters(
2246 self::get_message_processor_parameters(),
2247 array(
2248 'userid' => $userid,
2249 'name' => $name,
2253 if (empty($params['userid'])) {
2254 $params['userid'] = $USER->id;
2257 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2258 core_user::require_active_user($user);
2259 self::validate_context(context_user::instance($params['userid']));
2261 $processor = get_message_processor($name);
2263 $processoroutput = new \core_message\output\processor($processor, $user);
2264 $renderer = $PAGE->get_renderer('core_message');
2266 return $processoroutput->export_for_template($renderer);
2270 * Returns description of method result value
2272 * @return external_description
2273 * @since 3.2
2275 public static function get_message_processor_returns() {
2276 return new external_function_parameters(
2277 array(
2278 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'),
2279 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'),
2285 * Returns description of method parameters
2287 * @return external_function_parameters
2288 * @since 3.2
2290 public static function get_user_notification_preferences_parameters() {
2291 return new external_function_parameters(
2292 array(
2293 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
2299 * Get the notification preferences for a given user.
2301 * @param int $userid id of the user, 0 for current user
2302 * @return external_description
2303 * @throws moodle_exception
2304 * @since 3.2
2306 public static function get_user_notification_preferences($userid = 0) {
2307 global $USER, $PAGE, $CFG;
2309 $params = self::validate_parameters(
2310 self::get_user_notification_preferences_parameters(),
2311 array(
2312 'userid' => $userid,
2316 if (empty($params['userid'])) {
2317 $user = $USER;
2318 } else {
2319 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2320 core_user::require_active_user($user);
2323 $systemcontext = context_system::instance();
2324 self::validate_context($systemcontext);
2326 // Check access control.
2327 if ($user->id == $USER->id) {
2328 // Editing own message profile.
2329 require_capability('moodle/user:editownmessageprofile', $systemcontext);
2330 } else {
2331 // Teachers, parents, etc.
2332 $personalcontext = context_user::instance($user->id);
2333 require_capability('moodle/user:editmessageprofile', $personalcontext);
2336 $processors = get_message_processors();
2337 $providers = message_get_providers_for_user($user->id);
2338 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2339 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
2341 $renderer = $PAGE->get_renderer('core_message');
2343 $result = array(
2344 'warnings' => array(),
2345 'preferences' => $notificationlist->export_for_template($renderer)
2347 return $result;
2351 * Returns description of method result value
2353 * @return external_description
2354 * @since 3.2
2356 public static function get_user_notification_preferences_returns() {
2357 return new external_function_parameters(
2358 array(
2359 'preferences' => new external_single_structure(
2360 array(
2361 'userid' => new external_value(PARAM_INT, 'User id'),
2362 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
2363 'processors' => new external_multiple_structure(
2364 new external_single_structure(
2365 array(
2366 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2367 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2368 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
2369 'contextid' => new external_value(PARAM_INT, 'Context id'),
2370 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
2373 'Config form values'
2375 'components' => new external_multiple_structure(
2376 new external_single_structure(
2377 array(
2378 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2379 'notifications' => new external_multiple_structure(
2380 new external_single_structure(
2381 array(
2382 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2383 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
2384 'processors' => new external_multiple_structure(
2385 new external_single_structure(
2386 array(
2387 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2388 'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2389 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
2390 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
2391 'loggedin' => new external_single_structure(
2392 array(
2393 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2394 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2395 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2398 'loggedoff' => new external_single_structure(
2399 array(
2400 'name' => new external_value(PARAM_NOTAGS, 'Name'),
2401 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2402 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2407 'Processors values for this notification'
2411 'List of notificaitons for the component'
2415 'Available components'
2419 'warnings' => new external_warnings(),