e86f581500f14c917f173f772afa67d144a3db48
[moodle.git] / message / externallib.php
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.
13 //
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
20  *
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
25  */
27 require_once("$CFG->libdir/externallib.php");
28 require_once($CFG->dirroot . "/message/lib.php");
30 /**
31  * Message external functions
32  *
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
38  */
39 class core_message_external extends external_api {
41     /**
42      * Returns description of method parameters
43      *
44      * @return external_function_parameters
45      * @since Moodle 2.2
46      */
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),
57                         )
58                     )
59                 )
60             )
61         );
62     }
64     /**
65      * Send private messages from the current USER to other users
66      *
67      * @param array $messages An array of message to send.
68      * @return array
69      * @since Moodle 2.2
70      */
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');
77         }
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'];
90         }
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;
107             }
108         }
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']);
125             }
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');
131             }
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'])));
142             }
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']));
149             }
151             //build the resultmsg
152             if (isset($message['clientmsgid'])) {
153                 $resultmsg['clientmsgid'] = $message['clientmsgid'];
154             }
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;
163             }
165             $resultmessages[] = $resultmsg;
166         }
168         return $resultmessages;
169     }
171     /**
172      * Returns description of method result value
173      *
174      * @return external_description
175      * @since Moodle 2.2
176      */
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)
184                 )
185             )
186         );
187     }
189     /**
190      * Create contacts parameters description.
191      *
192      * @return external_function_parameters
193      * @since Moodle 2.5
194      */
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'
201                 ),
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)
204             )
205         );
206     }
208     /**
209      * Create contacts.
210      *
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
215      */
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');
222         }
224         if (empty($userid)) {
225             $userid = $USER->id;
226         }
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', '');
235         }
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'
248                 );
249             }
250         }
251         return $warnings;
252     }
254     /**
255      * Create contacts return description.
256      *
257      * @return external_description
258      * @since Moodle 2.5
259      */
260     public static function create_contacts_returns() {
261         return new external_warnings();
262     }
264     /**
265      * Delete contacts parameters description.
266      *
267      * @return external_function_parameters
268      * @since Moodle 2.5
269      */
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'
276                 ),
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)
279             )
280         );
281     }
283     /**
284      * Delete contacts.
285      *
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
290      */
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');
297         }
299         if (empty($userid)) {
300             $userid = $USER->id;
301         }
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', '');
310         }
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);
317         }
319         return null;
320     }
322     /**
323      * Delete contacts return description.
324      *
325      * @return external_description
326      * @since Moodle 2.5
327      */
328     public static function delete_contacts_returns() {
329         return null;
330     }
332     /**
333      * Block contacts parameters description.
334      *
335      * @return external_function_parameters
336      * @since Moodle 2.5
337      */
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'
344                 ),
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)
347             )
348         );
349     }
351     /**
352      * Block contacts.
353      *
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
358      */
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');
365         }
367         if (empty($userid)) {
368             $userid = $USER->id;
369         }
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', '');
378         }
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'
391                 );
392             }
393         }
394         return $warnings;
395     }
397     /**
398      * Block contacts return description.
399      *
400      * @return external_description
401      * @since Moodle 2.5
402      */
403     public static function block_contacts_returns() {
404         return new external_warnings();
405     }
407     /**
408      * Unblock contacts parameters description.
409      *
410      * @return external_function_parameters
411      * @since Moodle 2.5
412      */
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'
419                 ),
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)
422             )
423         );
424     }
426     /**
427      * Unblock contacts.
428      *
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
433      */
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');
440         }
442         if (empty($userid)) {
443             $userid = $USER->id;
444         }
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', '');
453         }
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);
460         }
462         return null;
463     }
465     /**
466      * Unblock contacts return description.
467      *
468      * @return external_description
469      * @since Moodle 2.5
470      */
471     public static function unblock_contacts_returns() {
472         return null;
473     }
475     /**
476      * Return the structure of a message area contact.
477      *
478      * @return external_single_structure
479      * @since Moodle 3.2
480      */
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),
497             )
498         );
499     }
501     /**
502      * Return the structure of a message area message.
503      *
504      * @return external_single_structure
505      * @since Moodle 3.2
506      */
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'),
519             )
520         );
521     }
523     /**
524      * Get messagearea search users in course parameters.
525      *
526      * @return external_function_parameters
527      * @since 3.2
528      */
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)
537             )
538         );
539     }
541     /**
542      * Get messagearea search users in course results.
543      *
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
552      */
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');
560         }
562         $systemcontext = context_system::instance();
564         $params = array(
565             'userid' => $userid,
566             'courseid' => $courseid,
567             'search' => $search,
568             'limitfrom' => $limitfrom,
569             'limitnum' => $limitnum
570         );
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.');
576         }
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);
583     }
585     /**
586      * Get messagearea search users in course returns.
587      *
588      * @return external_single_structure
589      * @since 3.2
590      */
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()
596                 ),
597             )
598         );
599     }
601     /**
602      * Get messagearea search users parameters.
603      *
604      * @return external_function_parameters
605      * @since 3.2
606      */
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)
613             )
614         );
615     }
617     /**
618      * Get messagearea search users results.
619      *
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
626      */
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');
633         }
635         $systemcontext = context_system::instance();
637         $params = array(
638             'userid' => $userid,
639             'search' => $search,
640             'limitnum' => $limitnum
641         );
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.');
647         }
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);
654     }
656     /**
657      * Get messagearea search users returns.
658      *
659      * @return external_single_structure
660      * @since 3.2
661      */
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()
667                 ),
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'),
674                         )
675                     )
676                 ),
677                 'noncontacts' => new external_multiple_structure(
678                     self::get_messagearea_contact_structure()
679                 )
680             )
681         );
682     }
684     /**
685      * Get messagearea search messages parameters.
686      *
687      * @return external_function_parameters
688      * @since 3.2
689      */
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)
697             )
698         );
699     }
701     /**
702      * Get messagearea search messages results.
703      *
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
711      */
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');
718         }
720         $systemcontext = context_system::instance();
722         $params = array(
723             'userid' => $userid,
724             'search' => $search,
725             'limitfrom' => $limitfrom,
726             'limitnum' => $limitnum
728         );
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.');
734         }
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);
741     }
743     /**
744      * Get messagearea search messages returns.
745      *
746      * @return external_single_structure
747      * @since 3.2
748      */
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()
754                 )
755             )
756         );
757     }
759     /**
760      * The messagearea conversations parameters.
761      *
762      * @return external_function_parameters
763      * @since 3.2
764      */
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)
771             )
772         );
773     }
775     /**
776      * Get messagearea conversations.
777      *
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
784      */
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');
791         }
793         $systemcontext = context_system::instance();
795         $params = array(
796             'userid' => $userid,
797             'limitfrom' => $limitfrom,
798             'limitnum' => $limitnum
799         );
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.');
805         }
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);
812     }
814     /**
815      * The messagearea conversations return structure.
816      *
817      * @return external_single_structure
818      * @since 3.2
819      */
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()
825                 )
826             )
827         );
828     }
830     /**
831      * The messagearea contacts return parameters.
832      *
833      * @return external_function_parameters
834      * @since 3.2
835      */
836     public static function data_for_messagearea_contacts_parameters() {
837         return self::data_for_messagearea_conversations_parameters();
838     }
840     /**
841      * Get messagearea contacts parameters.
842      *
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
849      */
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');
856         }
858         $systemcontext = context_system::instance();
860         $params = array(
861             'userid' => $userid,
862             'limitfrom' => $limitfrom,
863             'limitnum' => $limitnum
864         );
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.');
870         }
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);
877     }
879     /**
880      * The messagearea contacts return structure.
881      *
882      * @return external_single_structure
883      * @since 3.2
884      */
885     public static function data_for_messagearea_contacts_returns() {
886         return self::data_for_messagearea_conversations_returns();
887     }
889     /**
890      * The messagearea messages parameters.
891      *
892      * @return external_function_parameters
893      * @since 3.2
894      */
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),
903             )
904         );
905     }
907     /**
908      * Get messagearea messages.
909      *
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
918      */
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');
926         }
928         $systemcontext = context_system::instance();
930         $params = array(
931             'currentuserid' => $currentuserid,
932             'otheruserid' => $otheruserid,
933             'limitfrom' => $limitfrom,
934             'limitnum' => $limitnum,
935             'newest' => $newest
936         );
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.');
942         }
944         if ($newest) {
945             $sort = 'timecreated DESC';
946         } else {
947             $sort = 'timecreated ASC';
948         }
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);
954     }
956     /**
957      * The messagearea messages return structure.
958      *
959      * @return external_single_structure
960      * @since 3.2
961      */
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()
973                 )
974             )
975         );
976     }
978     /**
979      * The get most recent message return parameters.
980      *
981      * @return external_function_parameters
982      * @since 3.2
983      */
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'),
989             )
990         );
991     }
993     /**
994      * Get the most recent message in a conversation.
995      *
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
1001      */
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');
1008         }
1010         $systemcontext = context_system::instance();
1012         $params = array(
1013             'currentuserid' => $currentuserid,
1014             'otheruserid' => $otheruserid
1015         );
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.');
1021         }
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);
1028     }
1030     /**
1031      * The get most recent message return structure.
1032      *
1033      * @return external_single_structure
1034      * @since 3.2
1035      */
1036     public static function data_for_messagearea_get_most_recent_message_returns() {
1037         return self::get_messagearea_message_structure();
1038     }
1040     /**
1041      * The get profile parameters.
1042      *
1043      * @return external_function_parameters
1044      * @since 3.2
1045      */
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'),
1051             )
1052         );
1053     }
1055     /**
1056      * Get the profile information for a contact.
1057      *
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
1063      */
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');
1070         }
1072         $systemcontext = context_system::instance();
1074         $params = array(
1075             'currentuserid' => $currentuserid,
1076             'otheruserid' => $otheruserid
1077         );
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.');
1083         }
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);
1090     }
1092     /**
1093      * The get profile return structure.
1094      *
1095      * @return external_single_structure
1096      * @since 3.2
1097      */
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?')
1111             )
1112         );
1113     }
1115     /**
1116      * Get contacts parameters description.
1117      *
1118      * @return external_function_parameters
1119      * @since Moodle 2.5
1120      */
1121     public static function get_contacts_parameters() {
1122         return new external_function_parameters(array());
1123     }
1125     /**
1126      * Get contacts.
1127      *
1128      * @return external_description
1129      * @since Moodle 2.5
1130      */
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');
1137         }
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
1149                 );
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;
1158             }
1159         }
1160         return $allcontacts;
1161     }
1163     /**
1164      * Get contacts return description.
1165      *
1166      * @return external_description
1167      * @since Moodle 2.5
1168      */
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')
1180                         )
1181                     ),
1182                     'List of online contacts'
1183                 ),
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')
1192                         )
1193                     ),
1194                     'List of offline contacts'
1195                 ),
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')
1204                         )
1205                     ),
1206                     'List of users that are not in the user\'s contact list but have sent a message'
1207                 )
1208             )
1209         );
1210     }
1212     /**
1213      * Search contacts parameters description.
1214      *
1215      * @return external_function_parameters
1216      * @since Moodle 2.5
1217      */
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)
1224             )
1225         );
1226     }
1228     /**
1229      * Search contacts.
1230      *
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
1235      */
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');
1243         }
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');
1253         }
1255         $courseids = array();
1256         if ($params['onlymycourses']) {
1257             $mycourses = enrol_get_my_courses(array('id'));
1258             foreach ($mycourses as $mycourse) {
1259                 $courseids[] = $mycourse->id;
1260             }
1261         } else {
1262             $courseids[] = SITEID;
1263         }
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;
1270         }
1272         // Reorganising information.
1273         foreach ($results as &$user) {
1274             $newuser = array(
1275                 'id' => $user->id,
1276                 'fullname' => fullname($user)
1277             );
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;
1290         }
1292         return $results;
1293     }
1295     /**
1296      * Search contacts return description.
1297      *
1298      * @return external_description
1299      * @since Moodle 2.5
1300      */
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)
1309                 )
1310             ),
1311             'List of contacts'
1312         );
1313     }
1315     /**
1316      * Get messages parameters description.
1317      *
1318      * @return external_function_parameters
1319      * @since 2.8
1320      */
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)
1337             )
1338         );
1339     }
1341     /**
1342      * Get messages function implementation.
1343      *
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
1355      */
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
1370         );
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));
1389         }
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');
1396             }
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;
1405             }
1406         }
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');
1413             }
1414         }
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);
1419         }
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');
1425         }
1427         // Which type of messages to retrieve.
1428         $notifications = -1;
1429         if ($type != 'both') {
1430             $notifications = ($type == 'notifications') ? 1 : 0;
1431         }
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);
1449                 }
1450             } else {
1451                 // If the useridto field is empty, the useridfrom must be filled.
1452                 $userfromfullname = fullname($userfrom, $canviewfullname);
1453             }
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;
1462                 }
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);
1474                     }
1475                 } else {
1476                     $message->userfromfullname = $userfromfullname;
1477                 }
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;
1486                 }
1488                 // This field is only available in the message_read table.
1489                 if (!isset($message->timeread)) {
1490                     $message->timeread = 0;
1491                 }
1493                 $message->text = message_format_message_text($message);
1494                 $messages[$mid] = (array) $message;
1495             }
1496         }
1498         $results = array(
1499             'messages' => $messages,
1500             'warnings' => $warnings
1501         );
1503         return $results;
1504     }
1506     /**
1507      * Get messages return description.
1508      *
1509      * @return external_single_structure
1510      * @since 2.8
1511      */
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'
1535                     )
1536                 ),
1537                 'warnings' => new external_warnings()
1538             )
1539         );
1540     }
1542     /**
1543      * Mark all notifications as read parameters description.
1544      *
1545      * @return external_function_parameters
1546      * @since 3.2
1547      */
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),
1555             )
1556         );
1557     }
1559     /**
1560      * Mark all notifications as read function.
1561      *
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
1568      */
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,
1577             )
1578         );
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');
1591             }
1592         }
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);
1597         }
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');
1604         }
1606         \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_NOTIFICATION);
1608         return true;
1609     }
1611     /**
1612      * Mark all notifications as read return description.
1613      *
1614      * @return external_single_structure
1615      * @since 3.2
1616      */
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');
1619     }
1621     /**
1622      * Get unread conversations count parameters description.
1623      *
1624      * @return external_function_parameters
1625      * @since 3.2
1626      */
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),
1631             )
1632         );
1633     }
1635     /**
1636      * Get unread messages count function.
1637      *
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
1643      */
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');
1650         }
1652         $params = self::validate_parameters(
1653             self::get_unread_conversations_count_parameters(),
1654             array('useridto' => $useridto)
1655         );
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');
1667             }
1668         } else {
1669             $useridto = $USER->id;
1670         }
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');
1675         }
1677         return \core_message\api::count_unread_conversations($userto);
1678     }
1680     /**
1681      * Get unread conversations count return description.
1682      *
1683      * @return external_single_structure
1684      * @since 3.2
1685      */
1686     public static function get_unread_conversations_count_returns() {
1687         return new external_value(PARAM_INT, 'The count of unread messages for the user');
1688     }
1690     /**
1691      * Get blocked users parameters description.
1692      *
1693      * @return external_function_parameters
1694      * @since 2.9
1695      */
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),
1702             )
1703         );
1704     }
1706     /**
1707      * Retrieve a list of users blocked
1708      *
1709      * @param  int $userid the user whose blocked users we want to retrieve
1710      * @return external_description
1711      * @since 2.9
1712      */
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');
1719         }
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
1727         );
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');
1738         }
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', '');
1747         }
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),
1757             );
1759             $userpicture = new user_picture($user);
1760             $userpicture->size = 1; // Size f1.
1761             $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
1763             $blockedusers[] = $newuser;
1764         }
1766         $results = array(
1767             'users' => $blockedusers,
1768             'warnings' => $warnings
1769         );
1770         return $results;
1771     }
1773     /**
1774      * Get blocked users return description.
1775      *
1776      * @return external_single_structure
1777      * @since 2.9
1778      */
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)
1788                         )
1789                     ),
1790                     'List of blocked users'
1791                 ),
1792                 'warnings' => new external_warnings()
1793             )
1794         );
1795     }
1797     /**
1798      * Returns description of method parameters
1799      *
1800      * @return external_function_parameters
1801      * @since 2.9
1802      */
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)
1809             )
1810         );
1811     }
1813     /**
1814      * Mark a single message as read, trigger message_viewed event
1815      *
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
1822      */
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');
1829         }
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
1838         );
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'];
1845         }
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');
1855         }
1857         $messageid = message_mark_message_read($message, $timeread);
1859         $results = array(
1860             'messageid' => $messageid,
1861             'warnings' => $warnings
1862         );
1863         return $results;
1864     }
1866     /**
1867      * Returns description of method result value
1868      *
1869      * @return external_description
1870      * @since 2.9
1871      */
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()
1877             )
1878         );
1879     }
1881     /**
1882      * Mark all messages as read parameters description.
1883      *
1884      * @return external_function_parameters
1885      * @since 3.2
1886      */
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),
1894             )
1895         );
1896     }
1898     /**
1899      * Mark all notifications as read function.
1900      *
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
1907      */
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');
1914         }
1916         $params = self::validate_parameters(
1917             self::mark_all_messages_as_read_parameters(),
1918             array(
1919                 'useridto' => $useridto,
1920                 'useridfrom' => $useridfrom,
1921             )
1922         );
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');
1935             }
1936         }
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);
1941         }
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');
1948         }
1950         \core_message\api::mark_all_read_for_user($useridto, $useridfrom, MESSAGE_TYPE_MESSAGE);
1952         return true;
1953     }
1955     /**
1956      * Mark all notifications as read return description.
1957      *
1958      * @return external_single_structure
1959      * @since 3.2
1960      */
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');
1963     }
1965     /**
1966      * Returns description of method parameters.
1967      *
1968      * @return external_function_parameters
1969      * @since 3.2
1970      */
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'),
1976             )
1977         );
1978     }
1980     /**
1981      * Deletes a conversation.
1982      *
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
1988      */
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');
1995         }
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,
2004         );
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');
2018         }
2020         $results = array(
2021             'status' => $status,
2022             'warnings' => $warnings
2023         );
2025         return $results;
2026     }
2028     /**
2029      * Returns description of method result value.
2030      *
2031      * @return external_description
2032      * @since 3.2
2033      */
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()
2039             )
2040         );
2041     }
2043     /**
2044      * Returns description of method parameters
2045      *
2046      * @return external_function_parameters
2047      * @since 3.1
2048      */
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)
2055             )
2056         );
2057     }
2059     /**
2060      * Deletes a message
2061      *
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
2068      */
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');
2075         }
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
2085         );
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');
2103         }
2105         $results = array(
2106             'status' => $status,
2107             'warnings' => $warnings
2108         );
2109         return $results;
2110     }
2112     /**
2113      * Returns description of method result value
2114      *
2115      * @return external_description
2116      * @since 3.1
2117      */
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()
2123             )
2124         );
2125     }
2127     /**
2128      * Returns description of method parameters
2129      *
2130      * @return external_function_parameters
2131      * @since 3.2
2132      */
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),
2143                         )
2144                     ),
2145                     'Config form values',
2146                     VALUE_REQUIRED
2147                 ),
2148             )
2149         );
2150     }
2152     /**
2153      * Processes a message processor config form.
2154      *
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
2161      */
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');
2168         }
2170         $params = self::validate_parameters(
2171             self::message_processor_config_form_parameters(),
2172             array(
2173                 'userid' => $userid,
2174                 'name' => $name,
2175                 'formvalues' => $formvalues,
2176             )
2177         );
2179         if (empty($params['userid'])) {
2180             $params['userid'] = $USER->id;
2181         }
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'];
2194         }
2196         $processor->process_form($form, $preferences);
2198         if (!empty($preferences)) {
2199             set_user_preferences($preferences, $userid);
2200         }
2201     }
2203     /**
2204      * Returns description of method result value
2205      *
2206      * @return external_description
2207      * @since 3.2
2208      */
2209     public static function message_processor_config_form_returns() {
2210         return null;
2211     }
2213     /**
2214      * Returns description of method parameters
2215      *
2216      * @return external_function_parameters
2217      * @since 3.2
2218      */
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),
2224             )
2225         );
2226     }
2228     /**
2229      * Get a message processor.
2230      *
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
2236      */
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');
2243         }
2245         $params = self::validate_parameters(
2246             self::get_message_processor_parameters(),
2247             array(
2248                 'userid' => $userid,
2249                 'name' => $name,
2250             )
2251         );
2253         if (empty($params['userid'])) {
2254             $params['userid'] = $USER->id;
2255         }
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);
2267     }
2269     /**
2270      * Returns description of method result value
2271      *
2272      * @return external_description
2273      * @since 3.2
2274      */
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'),
2280             )
2281         );
2282     }
2284     /**
2285      * Returns description of method parameters
2286      *
2287      * @return external_function_parameters
2288      * @since 3.2
2289      */
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)
2294             )
2295         );
2296     }
2298     /**
2299      * Get the notification preferences for a given user.
2300      *
2301      * @param int $userid id of the user, 0 for current user
2302      * @return external_description
2303      * @throws moodle_exception
2304      * @since 3.2
2305      */
2306     public static function get_user_notification_preferences($userid = 0) {
2307         global $USER, $PAGE, $CFG;
2309         // Check if messaging is enabled.
2310         if (empty($CFG->messaging)) {
2311             throw new moodle_exception('disabled', 'message');
2312         }
2314         $params = self::validate_parameters(
2315             self::get_user_notification_preferences_parameters(),
2316             array(
2317                 'userid' => $userid,
2318             )
2319         );
2321         if (empty($params['userid'])) {
2322             $user = $USER;
2323         } else {
2324             $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
2325             core_user::require_active_user($user);
2326         }
2328         $systemcontext = context_system::instance();
2329         self::validate_context($systemcontext);
2331         // Check access control.
2332         if ($user->id == $USER->id) {
2333             // Editing own message profile.
2334             require_capability('moodle/user:editownmessageprofile', $systemcontext);
2335         } else {
2336             // Teachers, parents, etc.
2337             $personalcontext = context_user::instance($user->id);
2338             require_capability('moodle/user:editmessageprofile', $personalcontext);
2339         }
2341         $processors = get_message_processors();
2342         $providers = message_get_providers_for_user($user->id);
2343         $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2344         $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user);
2346         $renderer = $PAGE->get_renderer('core_message');
2348         $result = array(
2349             'warnings' => array(),
2350             'preferences' => $notificationlist->export_for_template($renderer)
2351         );
2352         return $result;
2353     }
2355     /**
2356      * Returns description of method result value
2357      *
2358      * @return external_description
2359      * @since 3.2
2360      */
2361     public static function get_user_notification_preferences_returns() {
2362         return new external_function_parameters(
2363             array(
2364                 'preferences' => new external_single_structure(
2365                     array(
2366                         'userid' => new external_value(PARAM_INT, 'User id'),
2367                         'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'),
2368                         'processors' => new external_multiple_structure(
2369                             new external_single_structure(
2370                                 array(
2371                                     'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2372                                     'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2373                                     'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'),
2374                                     'contextid' => new external_value(PARAM_INT, 'Context id'),
2375                                     'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'),
2376                                 )
2377                             ),
2378                             'Config form values'
2379                         ),
2380                         'components' => new external_multiple_structure(
2381                             new external_single_structure(
2382                                 array(
2383                                     'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2384                                     'notifications' => new external_multiple_structure(
2385                                         new external_single_structure(
2386                                             array(
2387                                                 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2388                                                 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'),
2389                                                 'processors' => new external_multiple_structure(
2390                                                     new external_single_structure(
2391                                                         array(
2392                                                             'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2393                                                             'name' => new external_value(PARAM_PLUGIN, 'Processor name'),
2394                                                             'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'),
2395                                                             'userconfigured' => new external_value(PARAM_INT, 'Is configured?'),
2396                                                             'loggedin' => new external_single_structure(
2397                                                                 array(
2398                                                                     'name' => new external_value(PARAM_NOTAGS, 'Name'),
2399                                                                     'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2400                                                                     'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2401                                                                 )
2402                                                             ),
2403                                                             'loggedoff' => new external_single_structure(
2404                                                                 array(
2405                                                                     'name' => new external_value(PARAM_NOTAGS, 'Name'),
2406                                                                     'displayname' => new external_value(PARAM_TEXT, 'Display name'),
2407                                                                     'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
2408                                                                 )
2409                                                             ),
2410                                                         )
2411                                                     ),
2412                                                     'Processors values for this notification'
2413                                                 ),
2414                                             )
2415                                         ),
2416                                         'List of notificaitons for the component'
2417                                     ),
2418                                 )
2419                             ),
2420                             'Available components'
2421                         ),
2422                     )
2423                 ),
2424                 'warnings' => new external_warnings(),
2425             )
2426         );
2427     }