MDL-54687 core_message: added ability to view messages
[moodle.git] / message / externallib.php
CommitLineData
a623b6b8 1<?php
a623b6b8
JM
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/>.
16
4615817d 17
a623b6b8
JM
18/**
19 * External message API
20 *
6fbd60ef 21 * @package core_message
4615817d
JM
22 * @category external
23 * @copyright 2011 Jerome Mouneyrac
a623b6b8
JM
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
4615817d 26
a623b6b8 27require_once("$CFG->libdir/externallib.php");
705afe6f 28require_once($CFG->dirroot . "/message/lib.php");
a623b6b8 29
5d1017e1 30/**
4615817d 31 * Message external functions
6fbd60ef
AD
32 *
33 * @package core_message
4615817d
JM
34 * @category external
35 * @copyright 2011 Jerome Mouneyrac
75e4f98c 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4615817d 37 * @since Moodle 2.2
5d1017e1
JM
38 */
39class core_message_external extends external_api {
a623b6b8
JM
40
41 /**
42 * Returns description of method parameters
4615817d 43 *
a623b6b8 44 * @return external_function_parameters
4615817d 45 * @since Moodle 2.2
a623b6b8 46 */
5d1017e1 47 public static function send_instant_messages_parameters() {
a623b6b8
JM
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'),
93ce0e82
JM
54 'text' => new external_value(PARAM_RAW, 'the text of the message'),
55 'textformat' => new external_format_value('text', VALUE_DEFAULT),
a623b6b8
JM
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 }
63
64 /**
65 * Send private messages from the current USER to other users
66 *
4615817d
JM
67 * @param array $messages An array of message to send.
68 * @return array
69 * @since Moodle 2.2
a623b6b8 70 */
5d1017e1 71 public static function send_instant_messages($messages = array()) {
a623b6b8 72 global $CFG, $USER, $DB;
a623b6b8 73
436bbf89 74 // Check if messaging is enabled.
a623b6b8
JM
75 if (!$CFG->messaging) {
76 throw new moodle_exception('disabled', 'message');
77 }
78
79 // Ensure the current user is allowed to run this function
bf0f06b1 80 $context = context_system::instance();
a623b6b8
JM
81 self::validate_context($context);
82 require_capability('moodle/site:sendmessage', $context);
83
5d1017e1 84 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages));
a623b6b8
JM
85
86 //retrieve all tousers of the messages
4de00da7 87 $receivers = array();
a623b6b8 88 foreach($params['messages'] as $message) {
4de00da7 89 $receivers[] = $message['touserid'];
a623b6b8 90 }
4de00da7 91 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers, SQL_PARAMS_NAMED, 'userid_');
a623b6b8 92 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams);
4de00da7
DC
93 $blocklist = array();
94 $contactlist = array();
a623b6b8 95 $sqlparams['contactid'] = $USER->id;
4de00da7
DC
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();
a623b6b8
JM
110
111 $canreadallmessages = has_capability('moodle/site:readallmessages', $context);
112
113 $resultmessages = array();
114 foreach ($params['messages'] as $message) {
a623b6b8
JM
115 $resultmsg = array(); //the infos about the success of the operation
116
117 //we are going to do some checking
118 //code should match /messages/index.php checks
119 $success = true;
120
121 //check the user exists
122 if (empty($tousers[$message['touserid']])) {
123 $success = false;
124 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']);
125 }
126
127 //check that the touser is not blocking the current user
4de00da7 128 if ($success and !empty($blocklist[$message['touserid']]) and !$canreadallmessages) {
a623b6b8
JM
129 $success = false;
130 $errormessage = get_string('userisblockingyou', 'message');
131 }
132
78736e5d 133 // Check if the user is a contact
4615817d 134 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid
4de00da7
DC
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)) {
78736e5d
SH
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;
126a4bc4
CS
140 $errormessage = get_string('userisblockingyounoncontact', 'message',
141 fullname(core_user::get_user($message['touserid'])));
a623b6b8
JM
142 }
143
144 //now we can send the message (at least try)
145 if ($success) {
4615817d 146 //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object
93ce0e82
JM
147 $success = message_post_message($USER, $tousers[$message['touserid']],
148 $message['text'], external_validate_format($message['textformat']));
a623b6b8
JM
149 }
150
151 //build the resultmsg
152 if (isset($message['clientmsgid'])) {
78736e5d 153 $resultmsg['clientmsgid'] = $message['clientmsgid'];
a623b6b8
JM
154 }
155 if ($success) {
156 $resultmsg['msgid'] = $success;
157 } else {
93ce0e82
JM
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 .
a623b6b8
JM
161 $resultmsg['msgid'] = -1;
162 $resultmsg['errormessage'] = $errormessage;
163 }
164
165 $resultmessages[] = $resultmsg;
166 }
167
168 return $resultmessages;
169 }
170
171 /**
172 * Returns description of method result value
4615817d 173 *
a623b6b8 174 * @return external_description
4615817d 175 * @since Moodle 2.2
a623b6b8 176 */
5d1017e1 177 public static function send_instant_messages_returns() {
a623b6b8
JM
178 return new external_multiple_structure(
179 new external_single_structure(
180 array(
78736e5d 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'),
4de00da7 182 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL),
78736e5d 183 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL)
a623b6b8
JM
184 )
185 )
186 );
187 }
188
d6731600
FM
189 /**
190 * Create contacts parameters description.
191 *
192 * @return external_function_parameters
5bcfd504 193 * @since Moodle 2.5
d6731600
FM
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 )
203 );
204 }
205
206 /**
207 * Create contacts.
208 *
209 * @param array $userids array of user IDs.
210 * @return external_description
5bcfd504 211 * @since Moodle 2.5
d6731600
FM
212 */
213 public static function create_contacts($userids) {
436bbf89
DM
214 global $CFG;
215
216 // Check if messaging is enabled.
217 if (!$CFG->messaging) {
218 throw new moodle_exception('disabled', 'message');
219 }
220
d6731600
FM
221 $params = array('userids' => $userids);
222 $params = self::validate_parameters(self::create_contacts_parameters(), $params);
223
224 $warnings = array();
225 foreach ($params['userids'] as $id) {
226 if (!message_add_contact($id)) {
227 $warnings[] = array(
228 'item' => 'user',
229 'itemid' => $id,
230 'warningcode' => 'contactnotcreated',
231 'message' => 'The contact could not be created'
232 );
233 }
234 }
235 return $warnings;
236 }
237
238 /**
239 * Create contacts return description.
240 *
241 * @return external_description
5bcfd504 242 * @since Moodle 2.5
d6731600
FM
243 */
244 public static function create_contacts_returns() {
245 return new external_warnings();
246 }
247
248 /**
249 * Delete contacts parameters description.
250 *
251 * @return external_function_parameters
5bcfd504 252 * @since Moodle 2.5
d6731600
FM
253 */
254 public static function delete_contacts_parameters() {
255 return new external_function_parameters(
256 array(
257 'userids' => new external_multiple_structure(
258 new external_value(PARAM_INT, 'User ID'),
259 'List of user IDs'
260 )
261 )
262 );
263 }
264
265 /**
266 * Delete contacts.
267 *
268 * @param array $userids array of user IDs.
269 * @return null
5bcfd504 270 * @since Moodle 2.5
d6731600
FM
271 */
272 public static function delete_contacts($userids) {
436bbf89
DM
273 global $CFG;
274
275 // Check if messaging is enabled.
276 if (!$CFG->messaging) {
277 throw new moodle_exception('disabled', 'message');
278 }
279
d6731600
FM
280 $params = array('userids' => $userids);
281 $params = self::validate_parameters(self::delete_contacts_parameters(), $params);
282
283 foreach ($params['userids'] as $id) {
284 message_remove_contact($id);
285 }
286
287 return null;
288 }
289
290 /**
291 * Delete contacts return description.
292 *
293 * @return external_description
5bcfd504 294 * @since Moodle 2.5
d6731600
FM
295 */
296 public static function delete_contacts_returns() {
297 return null;
298 }
299
300 /**
301 * Block contacts parameters description.
302 *
303 * @return external_function_parameters
5bcfd504 304 * @since Moodle 2.5
d6731600
FM
305 */
306 public static function block_contacts_parameters() {
307 return new external_function_parameters(
308 array(
309 'userids' => new external_multiple_structure(
310 new external_value(PARAM_INT, 'User ID'),
311 'List of user IDs'
312 )
313 )
314 );
315 }
316
317 /**
318 * Block contacts.
319 *
320 * @param array $userids array of user IDs.
321 * @return external_description
5bcfd504 322 * @since Moodle 2.5
d6731600
FM
323 */
324 public static function block_contacts($userids) {
436bbf89
DM
325 global $CFG;
326
327 // Check if messaging is enabled.
328 if (!$CFG->messaging) {
329 throw new moodle_exception('disabled', 'message');
330 }
331
d6731600
FM
332 $params = array('userids' => $userids);
333 $params = self::validate_parameters(self::block_contacts_parameters(), $params);
334
335 $warnings = array();
336 foreach ($params['userids'] as $id) {
337 if (!message_block_contact($id)) {
338 $warnings[] = array(
339 'item' => 'user',
340 'itemid' => $id,
341 'warningcode' => 'contactnotblocked',
342 'message' => 'The contact could not be blocked'
343 );
344 }
345 }
346 return $warnings;
347 }
348
349 /**
350 * Block contacts return description.
351 *
352 * @return external_description
5bcfd504 353 * @since Moodle 2.5
d6731600
FM
354 */
355 public static function block_contacts_returns() {
356 return new external_warnings();
357 }
358
359 /**
360 * Unblock contacts parameters description.
361 *
362 * @return external_function_parameters
5bcfd504 363 * @since Moodle 2.5
d6731600
FM
364 */
365 public static function unblock_contacts_parameters() {
366 return new external_function_parameters(
367 array(
368 'userids' => new external_multiple_structure(
369 new external_value(PARAM_INT, 'User ID'),
370 'List of user IDs'
371 )
372 )
373 );
374 }
375
376 /**
377 * Unblock contacts.
378 *
379 * @param array $userids array of user IDs.
380 * @return null
5bcfd504 381 * @since Moodle 2.5
d6731600
FM
382 */
383 public static function unblock_contacts($userids) {
436bbf89
DM
384 global $CFG;
385
386 // Check if messaging is enabled.
387 if (!$CFG->messaging) {
388 throw new moodle_exception('disabled', 'message');
389 }
390
d6731600
FM
391 $params = array('userids' => $userids);
392 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params);
393
394 foreach ($params['userids'] as $id) {
395 message_unblock_contact($id);
396 }
397
398 return null;
399 }
400
401 /**
402 * Unblock contacts return description.
403 *
404 * @return external_description
5bcfd504 405 * @since Moodle 2.5
d6731600
FM
406 */
407 public static function unblock_contacts_returns() {
408 return null;
409 }
410
9aa012b5
MN
411 /**
412 * Get messagearea conversations parameters.
413 *
414 * @return external_function_parameters
415 */
416 public static function data_for_messagearea_conversations_parameters() {
417 return new external_function_parameters(
418 array(
419 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
420 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
421 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
422 )
423 );
424 }
425
426 /**
427 * Get messagearea conversations.
428 *
429 * @param int $userid The id of the user who we are viewing conversations for
430 * @param int $limitfrom
431 * @param int $limitnum
432 * @return external_function_parameters
433 */
434 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) {
435 global $CFG, $PAGE;
436
437 // Check if messaging is enabled.
438 if (!$CFG->messaging) {
439 throw new moodle_exception('disabled', 'message');
440 }
441
442 $params = array(
443 'userid' => $userid,
444 'limitfrom' => $limitfrom,
445 'limitnum' => $limitnum
446 );
447 self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params);
448
449 self::validate_context(context_user::instance($userid));
450
451 $contacts = \core_message\api::get_conversations($userid, 0, $limitfrom, $limitnum);
452
453 $renderer = $PAGE->get_renderer('core_message');
454 return $contacts->export_for_template($renderer);
455 }
456
457 /**
458 * Get messagearea conversations returns.
459 *
460 * @return external_function_parameters
461 */
462 public static function data_for_messagearea_conversations_returns() {
463 return new external_function_parameters(
464 array(
465 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'),
466 'conversationsselected' => new external_value(PARAM_BOOL, 'Determines if conversations were selected,
467 otherwise contacts were'),
468 'contacts' => new external_multiple_structure(
469 new external_single_structure(
470 array(
471 'userid' => new external_value(PARAM_INT, 'The user\'s id'),
472 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
473 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
474 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
475 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message', VALUE_OPTIONAL),
476 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status', VALUE_OPTIONAL)
477 )
478 )
479 )
480 )
481 );
482 }
483
484 /**
485 * Get messagearea contacts parameters.
486 *
487 * @return external_function_parameters
488 */
489 public static function data_for_messagearea_contacts_parameters() {
490 return self::data_for_messagearea_conversations_parameters();
491 }
492
493 /**
494 * Get messagearea contacts parameters.
495 *
496 * @param int $userid The id of the user who we are viewing conversations for
497 * @param int $limitfrom
498 * @param int $limitnum
499 * @return external_function_parameters
500 */
501 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) {
502 global $CFG, $PAGE;
503
504 // Check if messaging is enabled.
505 if (!$CFG->messaging) {
506 throw new moodle_exception('disabled', 'message');
507 }
508
509 $params = array(
510 'userid' => $userid,
511 'limitfrom' => $limitfrom,
512 'limitnum' => $limitnum
513 );
514 self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params);
515
516 self::validate_context(context_user::instance($userid));
517
518 $contacts = \core_message\api::get_contacts($userid, $limitfrom, $limitnum);
519
520 $renderer = $PAGE->get_renderer('core_message');
521 return $contacts->export_for_template($renderer);
522 }
523
524 /**
525 * Get messagearea contacts returns.
526 *
527 * @return external_function_parameters
528 */
529 public static function data_for_messagearea_contacts_returns() {
530 return self::data_for_messagearea_conversations_returns();
531 }
532
3cd13828
MN
533 /**
534 * Get messagearea messages parameters.
535 *
536 * @return external_function_parameters
537 */
538 public static function data_for_messagearea_messages_parameters() {
539 return new external_function_parameters(
540 array(
541 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
542 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
543 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0),
544 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0)
545 )
546 );
547 }
548
549 /**
550 * Get messagearea messages.
551 *
552 * @param int $currentuserid The current user's id
553 * @param int $otheruserid The other user's id
554 * @param int $limitfrom
555 * @param int $limitnum
556 * @return external_description
557 */
558 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0) {
559 global $CFG, $PAGE;
560
561 // Check if messaging is enabled.
562 if (!$CFG->messaging) {
563 throw new moodle_exception('disabled', 'message');
564 }
565
566 $params = array(
567 'currentuserid' => $currentuserid,
568 'otheruserid' => $otheruserid,
569 'limitfrom' => $limitfrom,
570 'limitnum' => $limitnum
571 );
572 self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params);
573
574 self::validate_context(context_user::instance($currentuserid));
575
576 $messages = \core_message\api::get_messages($currentuserid, $otheruserid, $limitfrom, $limitnum);
577
578 $renderer = $PAGE->get_renderer('core_message');
579 return $messages->export_for_template($renderer);
580 }
581
582 /**
583 * Get messagearea messages returns.
584 *
585 * @return external_description
586 */
587 public static function data_for_messagearea_messages_returns() {
588 return new external_function_parameters(
589 array(
590 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing the messages on behalf of?'),
591 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'),
592 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'),
593 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'),
594 'messages' => new external_multiple_structure(
595 new external_single_structure(
596 array(
597 'text' => new external_value(PARAM_RAW, 'The text of the message'),
598 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'),
599 'position' => new external_value(PARAM_ALPHA, 'The position of the text'),
600 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'),
601 )
602 )
603 )
604 )
605 );
606 }
607
d6731600
FM
608 /**
609 * Get contacts parameters description.
610 *
611 * @return external_function_parameters
5bcfd504 612 * @since Moodle 2.5
d6731600
FM
613 */
614 public static function get_contacts_parameters() {
615 return new external_function_parameters(array());
616 }
617
618 /**
619 * Get contacts.
620 *
621 * @param array $userids array of user IDs.
622 * @return external_description
5bcfd504 623 * @since Moodle 2.5
d6731600
FM
624 */
625 public static function get_contacts() {
d85bedf7 626 global $CFG, $PAGE;
436bbf89
DM
627
628 // Check if messaging is enabled.
629 if (!$CFG->messaging) {
630 throw new moodle_exception('disabled', 'message');
631 }
632
d6731600
FM
633 require_once($CFG->dirroot . '/user/lib.php');
634
635 list($online, $offline, $strangers) = message_get_contacts();
636 $allcontacts = array('online' => $online, 'offline' => $offline, 'strangers' => $strangers);
637 foreach ($allcontacts as $mode => $contacts) {
638 foreach ($contacts as $key => $contact) {
639 $newcontact = array(
640 'id' => $contact->id,
641 'fullname' => fullname($contact),
642 'unread' => $contact->messagecount
643 );
644
d85bedf7
JL
645 $userpicture = new user_picture($contact);
646 $userpicture->size = 1; // Size f1.
647 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
648 $userpicture->size = 0; // Size f2.
649 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
650
651 $allcontacts[$mode][$key] = $newcontact;
652 }
653 }
654 return $allcontacts;
655 }
656
657 /**
658 * Get contacts return description.
659 *
660 * @return external_description
5bcfd504 661 * @since Moodle 2.5
d6731600
FM
662 */
663 public static function get_contacts_returns() {
664 return new external_single_structure(
665 array(
666 'online' => new external_multiple_structure(
667 new external_single_structure(
668 array(
669 'id' => new external_value(PARAM_INT, 'User ID'),
670 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
671 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
672 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
673 'unread' => new external_value(PARAM_INT, 'Unread message count')
674 )
675 ),
676 'List of online contacts'
677 ),
678 'offline' => new external_multiple_structure(
679 new external_single_structure(
680 array(
681 'id' => new external_value(PARAM_INT, 'User ID'),
682 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
683 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
684 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
685 'unread' => new external_value(PARAM_INT, 'Unread message count')
686 )
687 ),
688 'List of offline contacts'
689 ),
690 'strangers' => new external_multiple_structure(
691 new external_single_structure(
692 array(
693 'id' => new external_value(PARAM_INT, 'User ID'),
694 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
695 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
696 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL),
697 'unread' => new external_value(PARAM_INT, 'Unread message count')
698 )
699 ),
700 'List of users that are not in the user\'s contact list but have sent a message'
701 )
702 )
703 );
704 }
705
706 /**
707 * Search contacts parameters description.
708 *
709 * @return external_function_parameters
5bcfd504 710 * @since Moodle 2.5
d6731600
FM
711 */
712 public static function search_contacts_parameters() {
713 return new external_function_parameters(
714 array(
715 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'),
716 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses',
717 VALUE_DEFAULT, false)
718 )
719 );
720 }
721
722 /**
723 * Search contacts.
724 *
725 * @param string $searchtext query string.
726 * @param bool $onlymycourses limit the search to the user's courses only.
727 * @return external_description
5bcfd504 728 * @since Moodle 2.5
d6731600
FM
729 */
730 public static function search_contacts($searchtext, $onlymycourses = false) {
d85bedf7 731 global $CFG, $USER, $PAGE;
11d83ab3 732 require_once($CFG->dirroot . '/user/lib.php');
436bbf89
DM
733
734 // Check if messaging is enabled.
735 if (!$CFG->messaging) {
736 throw new moodle_exception('disabled', 'message');
737 }
738
d6731600
FM
739 require_once($CFG->libdir . '/enrollib.php');
740
741 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses);
742 $params = self::validate_parameters(self::search_contacts_parameters(), $params);
743
744 // Extra validation, we do not allow empty queries.
745 if ($params['searchtext'] === '') {
746 throw new moodle_exception('querystringcannotbeempty');
747 }
748
749 $courseids = array();
750 if ($params['onlymycourses']) {
751 $mycourses = enrol_get_my_courses(array('id'));
752 foreach ($mycourses as $mycourse) {
753 $courseids[] = $mycourse->id;
754 }
755 } else {
756 $courseids[] = SITEID;
757 }
758
759 // Retrieving the users matching the query.
760 $users = message_search_users($courseids, $params['searchtext']);
761 $results = array();
762 foreach ($users as $user) {
763 $results[$user->id] = $user;
764 }
765
766 // Reorganising information.
767 foreach ($results as &$user) {
768 $newuser = array(
769 'id' => $user->id,
770 'fullname' => fullname($user)
771 );
772
773 // Avoid undefined property notice as phone not specified.
774 $user->phone1 = null;
775 $user->phone2 = null;
776
d85bedf7
JL
777 $userpicture = new user_picture($user);
778 $userpicture->size = 1; // Size f1.
779 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
780 $userpicture->size = 0; // Size f2.
781 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false);
d6731600
FM
782
783 $user = $newuser;
784 }
785
786 return $results;
787 }
788
789 /**
790 * Search contacts return description.
791 *
792 * @return external_description
5bcfd504 793 * @since Moodle 2.5
d6731600
FM
794 */
795 public static function search_contacts_returns() {
796 return new external_multiple_structure(
797 new external_single_structure(
798 array(
799 'id' => new external_value(PARAM_INT, 'User ID'),
800 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
801 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL),
802 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL)
803 )
804 ),
805 'List of contacts'
806 );
807 }
aff9da17
JL
808
809 /**
810 * Get messages parameters description.
811 *
812 * @return external_function_parameters
193edf7f 813 * @since 2.8
aff9da17
JL
814 */
815 public static function get_messages_parameters() {
816 return new external_function_parameters(
817 array(
6ff4464b 818 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED),
127ef540
SH
819 'useridfrom' => new external_value(
820 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user',
821 VALUE_DEFAULT, 0),
822 'type' => new external_value(
823 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both',
824 VALUE_DEFAULT, 'both'),
6ff4464b 825 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true),
127ef540
SH
826 'newestfirst' => new external_value(
827 PARAM_BOOL, 'true for ordering by newest first, false for oldest first',
828 VALUE_DEFAULT, true),
aff9da17 829 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0),
127ef540
SH
830 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0)
831 )
aff9da17
JL
832 );
833 }
834
835 /**
836 * Get messages function implementation.
127ef540
SH
837 *
838 * @since 2.8
839 * @throws invalid_parameter_exception
840 * @throws moodle_exception
6ff4464b
JL
841 * @param int $useridto the user id who received the message
842 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user
193edf7f 843 * @param string $type type of message to return, expected values: notifications, conversations and both
aff9da17 844 * @param bool $read true for retreiving read messages, false for unread
6ff4464b 845 * @param bool $newestfirst true for ordering by newest first, false for oldest first
aff9da17
JL
846 * @param int $limitfrom limit from
847 * @param int $limitnum limit num
848 * @return external_description
aff9da17 849 */
193edf7f 850 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
aff9da17 851 $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
127ef540 852 global $CFG, $USER;
aff9da17
JL
853
854 $warnings = array();
855
856 $params = array(
857 'useridto' => $useridto,
6ff4464b 858 'useridfrom' => $useridfrom,
aff9da17
JL
859 'type' => $type,
860 'read' => $read,
aff9da17
JL
861 'newestfirst' => $newestfirst,
862 'limitfrom' => $limitfrom,
863 'limitnum' => $limitnum
864 );
865
866 $params = self::validate_parameters(self::get_messages_parameters(), $params);
867
868 $context = context_system::instance();
869 self::validate_context($context);
870
871 $useridto = $params['useridto'];
6ff4464b 872 $useridfrom = $params['useridfrom'];
aff9da17
JL
873 $type = $params['type'];
874 $read = $params['read'];
aff9da17
JL
875 $newestfirst = $params['newestfirst'];
876 $limitfrom = $params['limitfrom'];
877 $limitnum = $params['limitnum'];
878
879 $allowedvalues = array('notifications', 'conversations', 'both');
880 if (!in_array($type, $allowedvalues)) {
881 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' .
882 'allowed values are: ' . implode(',', $allowedvalues));
883 }
884
885 // Check if private messaging between users is allowed.
886 if (empty($CFG->messaging)) {
887 // If we are retreiving only conversations, and messaging is disabled, throw an exception.
aff9da17
JL
888 if ($type == "conversations") {
889 throw new moodle_exception('disabled', 'message');
890 }
891 if ($type == "both") {
892 $warning = array();
893 $warning['item'] = 'message';
894 $warning['itemid'] = $USER->id;
895 $warning['warningcode'] = '1';
896 $warning['message'] = 'Private messages (conversations) are not enabled in this site.
897 Only notifications will be returned';
898 $warnings[] = $warning;
899 }
900 }
901
902 if (!empty($useridto)) {
6ff4464b
JL
903 if (core_user::is_real_user($useridto)) {
904 $userto = core_user::get_user($useridto, '*', MUST_EXIST);
905 } else {
906 throw new moodle_exception('invaliduser');
907 }
aff9da17
JL
908 }
909
910 if (!empty($useridfrom)) {
911 // We use get_user here because the from user can be the noreply or support user.
912 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST);
913 }
914
915 // Check if the current user is the sender/receiver or just a privileged user.
916 if ($useridto != $USER->id and $useridfrom != $USER->id and
917 !has_capability('moodle/site:readallmessages', $context)) {
918 throw new moodle_exception('accessdenied', 'admin');
919 }
920
127ef540 921 // Which type of messages to retrieve.
193edf7f 922 $notifications = -1;
aff9da17 923 if ($type != 'both') {
193edf7f 924 $notifications = ($type == 'notifications') ? 1 : 0;
aff9da17
JL
925 }
926
aff9da17 927 $orderdirection = $newestfirst ? 'DESC' : 'ASC';
193edf7f 928 $sort = "mr.timecreated $orderdirection";
aff9da17 929
193edf7f 930 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) {
aff9da17
JL
931 $canviewfullname = has_capability('moodle/site:viewfullnames', $context);
932
933 // In some cases, we don't need to get the to/from user objects from the sql query.
934 $userfromfullname = '';
935 $usertofullname = '';
936
937 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there.
938 if (!empty($useridto)) {
939 $usertofullname = fullname($userto, $canviewfullname);
940 // The user from may or may not be filled.
941 if (!empty($useridfrom)) {
942 $userfromfullname = fullname($userfrom, $canviewfullname);
943 }
944 } else {
945 // If the useridto field is empty, the useridfrom must be filled.
946 $userfromfullname = fullname($userfrom, $canviewfullname);
947 }
aff9da17
JL
948 foreach ($messages as $mid => $message) {
949
ea21d637
JL
950 // Do not return deleted messages.
951 if (($useridto == $USER->id and $message->timeusertodeleted) or
952 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) {
953
954 unset($messages[$mid]);
955 continue;
956 }
957
aff9da17
JL
958 // We need to get the user from the query.
959 if (empty($userfromfullname)) {
6ff4464b
JL
960 // Check for non-reply and support users.
961 if (core_user::is_real_user($message->useridfrom)) {
127ef540 962 $user = new stdClass();
6ff4464b
JL
963 $user = username_load_fields_from_object($user, $message, 'userfrom');
964 $message->userfromfullname = fullname($user, $canviewfullname);
965 } else {
966 $user = core_user::get_user($message->useridfrom);
967 $message->userfromfullname = fullname($user, $canviewfullname);
968 }
aff9da17
JL
969 } else {
970 $message->userfromfullname = $userfromfullname;
971 }
972
973 // We need to get the user from the query.
974 if (empty($usertofullname)) {
127ef540 975 $user = new stdClass();
aff9da17
JL
976 $user = username_load_fields_from_object($user, $message, 'userto');
977 $message->usertofullname = fullname($user, $canviewfullname);
978 } else {
979 $message->usertofullname = $usertofullname;
980 }
981
193edf7f 982 // This field is only available in the message_read table.
aff9da17
JL
983 if (!isset($message->timeread)) {
984 $message->timeread = 0;
985 }
986
aff9da17 987 $message->text = message_format_message_text($message);
aff9da17
JL
988 $messages[$mid] = (array) $message;
989 }
990 }
991
992 $results = array(
993 'messages' => $messages,
994 'warnings' => $warnings
995 );
996
997 return $results;
998 }
999
1000 /**
1001 * Get messages return description.
1002 *
6ff4464b 1003 * @return external_single_structure
193edf7f 1004 * @since 2.8
aff9da17
JL
1005 */
1006 public static function get_messages_returns() {
1007 return new external_single_structure(
1008 array(
1009 'messages' => new external_multiple_structure(
1010 new external_single_structure(
1011 array(
193edf7f 1012 'id' => new external_value(PARAM_INT, 'Message id'),
aff9da17
JL
1013 'useridfrom' => new external_value(PARAM_INT, 'User from id'),
1014 'useridto' => new external_value(PARAM_INT, 'User to id'),
1015 'subject' => new external_value(PARAM_TEXT, 'The message subject'),
1016 'text' => new external_value(PARAM_RAW, 'The message text formated'),
1017 'fullmessage' => new external_value(PARAM_RAW, 'The message'),
193edf7f 1018 'fullmessageformat' => new external_format_value('fullmessage'),
aff9da17
JL
1019 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'),
1020 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'),
1021 'notification' => new external_value(PARAM_INT, 'Is a notification?'),
1022 'contexturl' => new external_value(PARAM_RAW, 'Context URL'),
1023 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'),
1024 'timecreated' => new external_value(PARAM_INT, 'Time created'),
1025 'timeread' => new external_value(PARAM_INT, 'Time read'),
1026 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'),
1027 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name')
1028 ), 'message'
1029 )
1030 ),
1031 'warnings' => new external_warnings()
1032 )
1033 );
1034 }
1035
60ab2e1b
JL
1036 /**
1037 * Get blocked users parameters description.
1038 *
1039 * @return external_function_parameters
1040 * @since 2.9
1041 */
1042 public static function get_blocked_users_parameters() {
1043 return new external_function_parameters(
1044 array(
1045 'userid' => new external_value(PARAM_INT,
1046 'the user whose blocked users we want to retrieve',
1047 VALUE_REQUIRED),
1048 )
1049 );
1050 }
1051
1052 /**
1053 * Retrieve a list of users blocked
1054 *
1055 * @param int $userid the user whose blocked users we want to retrieve
1056 * @return external_description
1057 * @since 2.9
1058 */
1059 public static function get_blocked_users($userid) {
d85bedf7 1060 global $CFG, $USER, $PAGE;
60ab2e1b
JL
1061
1062 // Warnings array, it can be empty at the end but is mandatory.
1063 $warnings = array();
1064
1065 // Validate params.
1066 $params = array(
1067 'userid' => $userid
1068 );
1069 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params);
1070 $userid = $params['userid'];
1071
1072 // Validate context.
1073 $context = context_system::instance();
1074 self::validate_context($context);
1075
1076 // Check if private messaging between users is allowed.
1077 if (empty($CFG->messaging)) {
1078 throw new moodle_exception('disabled', 'message');
1079 }
1080
4485f7c5
JL
1081 $user = core_user::get_user($userid, '*', MUST_EXIST);
1082 core_user::require_active_user($user);
60ab2e1b
JL
1083
1084 // Check if we have permissions for retrieve the information.
1085 if ($userid != $USER->id and !has_capability('moodle/site:readallmessages', $context)) {
1086 throw new moodle_exception('accessdenied', 'admin');
1087 }
1088
1089 // Now, we can get safely all the blocked users.
1090 $users = message_get_blocked_users($user);
1091
1092 $blockedusers = array();
1093 foreach ($users as $user) {
1094 $newuser = array(
1095 'id' => $user->id,
1096 'fullname' => fullname($user),
1097 );
0b074e88 1098
d85bedf7
JL
1099 $userpicture = new user_picture($user);
1100 $userpicture->size = 1; // Size f1.
1101 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
60ab2e1b
JL
1102
1103 $blockedusers[] = $newuser;
1104 }
1105
1106 $results = array(
1107 'users' => $blockedusers,
1108 'warnings' => $warnings
1109 );
1110 return $results;
1111 }
1112
1113 /**
1114 * Get blocked users return description.
1115 *
1116 * @return external_single_structure
1117 * @since 2.9
1118 */
1119 public static function get_blocked_users_returns() {
1120 return new external_single_structure(
1121 array(
1122 'users' => new external_multiple_structure(
1123 new external_single_structure(
1124 array(
1125 'id' => new external_value(PARAM_INT, 'User ID'),
1126 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'),
1127 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL)
1128 )
1129 ),
1130 'List of blocked users'
1131 ),
1132 'warnings' => new external_warnings()
1133 )
1134 );
1135 }
1136
31c474da
JL
1137 /**
1138 * Returns description of method parameters
1139 *
1140 * @return external_function_parameters
1141 * @since 2.9
1142 */
1143 public static function mark_message_read_parameters() {
1144 return new external_function_parameters(
1145 array(
1146 'messageid' => new external_value(PARAM_INT, 'id of the message (in the message table)'),
1147 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read')
1148 )
1149 );
1150 }
1151
1152 /**
1153 * Mark a single message as read, trigger message_viewed event
1154 *
1155 * @param int $messageid id of the message (in the message table)
1156 * @param int $timeread timestamp for when the message should be marked read
1157 * @return external_description
1158 * @throws invalid_parameter_exception
1159 * @throws moodle_exception
1160 * @since 2.9
1161 */
1162 public static function mark_message_read($messageid, $timeread) {
1163 global $CFG, $DB, $USER;
31c474da
JL
1164
1165 // Check if private messaging between users is allowed.
1166 if (empty($CFG->messaging)) {
1167 throw new moodle_exception('disabled', 'message');
1168 }
1169
1170 // Warnings array, it can be empty at the end but is mandatory.
1171 $warnings = array();
1172
1173 // Validate params.
1174 $params = array(
1175 'messageid' => $messageid,
1176 'timeread' => $timeread
1177 );
1178 $params = self::validate_parameters(self::mark_message_read_parameters(), $params);
1179
1180 // Validate context.
1181 $context = context_system::instance();
1182 self::validate_context($context);
1183
1184 $message = $DB->get_record('message', array('id' => $params['messageid']), '*', MUST_EXIST);
1185
1186 if ($message->useridto != $USER->id) {
1187 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read');
1188 }
1189
1190 $messageid = message_mark_message_read($message, $params['timeread']);
1191
1192 $results = array(
1193 'messageid' => $messageid,
1194 'warnings' => $warnings
1195 );
1196 return $results;
1197 }
1198
1199 /**
1200 * Returns description of method result value
1201 *
1202 * @return external_description
1203 * @since 2.9
1204 */
1205 public static function mark_message_read_returns() {
1206 return new external_single_structure(
1207 array(
1208 'messageid' => new external_value(PARAM_INT, 'the id of the message in the message_read table'),
1209 'warnings' => new external_warnings()
1210 )
1211 );
1212 }
1213
419b1128
JL
1214 /**
1215 * Returns description of method parameters
1216 *
1217 * @return external_function_parameters
1218 * @since 3.1
1219 */
1220 public static function delete_message_parameters() {
1221 return new external_function_parameters(
1222 array(
1223 'messageid' => new external_value(PARAM_INT, 'The message id'),
1224 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
1225 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
1226 )
1227 );
1228 }
1229
1230 /**
1231 * Deletes a message
1232 *
1233 * @param int $messageid the message id
1234 * @param int $userid the user id of who we want to delete the message for
1235 * @param bool $read if is a message read (default to true)
1236 * @return external_description
1237 * @throws moodle_exception
1238 * @since 3.1
1239 */
1240 public static function delete_message($messageid, $userid, $read = true) {
1241 global $CFG, $DB;
419b1128
JL
1242
1243 // Check if private messaging between users is allowed.
1244 if (empty($CFG->messaging)) {
1245 throw new moodle_exception('disabled', 'message');
1246 }
1247
1248 // Warnings array, it can be empty at the end but is mandatory.
1249 $warnings = array();
1250
1251 // Validate params.
1252 $params = array(
1253 'messageid' => $messageid,
1254 'userid' => $userid,
1255 'read' => $read
1256 );
1257 $params = self::validate_parameters(self::delete_message_parameters(), $params);
1258
1259 // Validate context.
1260 $context = context_system::instance();
1261 self::validate_context($context);
1262
1263 $messagestable = $params['read'] ? 'message_read' : 'message';
1264 $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
1265
1266 $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
1267 core_user::require_active_user($user);
1268
1269 $status = false;
1270 if (message_can_delete_message($message, $user->id)) {
1271 $status = message_delete_message($message, $user->id);;
1272 } else {
1273 throw new moodle_exception('You do not have permission to delete this message');
1274 }
1275
1276 $results = array(
1277 'status' => $status,
1278 'warnings' => $warnings
1279 );
1280 return $results;
1281 }
1282
1283 /**
1284 * Returns description of method result value
1285 *
1286 * @return external_description
1287 * @since 3.1
1288 */
1289 public static function delete_message_returns() {
1290 return new external_single_structure(
1291 array(
1292 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
1293 'warnings' => new external_warnings()
1294 )
1295 );
1296 }
1297
a623b6b8 1298}