MDL-50537 mod_chat: New WS mod_chat_get_chats_by_courses
[moodle.git] / mod / chat / classes / external.php
CommitLineData
1ca4cdf3
JL
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/>.
16
17/**
18 * Chat external API
19 *
20 * @package mod_chat
21 * @category external
22 * @copyright 2015 Juan Leyva <juan@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 * @since Moodle 3.0
25 */
26
27defined('MOODLE_INTERNAL') || die;
28
29require_once($CFG->libdir . '/externallib.php');
30require_once($CFG->dirroot . '/mod/chat/lib.php');
31
32/**
33 * Chat external functions
34 *
35 * @package mod_chat
36 * @category external
37 * @copyright 2015 Juan Leyva <juan@moodle.com>
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 * @since Moodle 3.0
40 */
41class mod_chat_external extends external_api {
42
43 /**
44 * Returns description of method parameters
45 *
46 * @return external_function_parameters
47 * @since Moodle 3.0
48 */
49 public static function login_user_parameters() {
50 return new external_function_parameters(
51 array(
52 'chatid' => new external_value(PARAM_INT, 'chat instance id'),
53 'groupid' => new external_value(PARAM_INT, 'group id, 0 means that the function will determine the user group',
54 VALUE_DEFAULT, 0),
55 )
56 );
57 }
58
59 /**
60 * Log the current user into a chat room in the given chat.
61 *
62 * @param int $chatid the chat instance id
63 * @param int $groupid the user group id
64 * @return array of warnings and the chat unique session id
65 * @since Moodle 3.0
66 * @throws moodle_exception
67 */
68 public static function login_user($chatid, $groupid = 0) {
69 global $DB;
70
71 $params = self::validate_parameters(self::login_user_parameters(),
72 array(
73 'chatid' => $chatid,
74 'groupid' => $groupid
75 ));
76 $warnings = array();
77
78 // Request and permission validation.
79 $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST);
80 list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
81
82 $context = context_module::instance($cm->id);
83 self::validate_context($context);
84
85 require_capability('mod/chat:chat', $context);
86
87 if (!empty($params['groupid'])) {
88 $groupid = $params['groupid'];
89 // Determine is the group is visible to user.
90 if (!groups_group_visible($groupid, $course, $cm)) {
91 throw new moodle_exception('notingroup');
92 }
93 } else {
94 // Check to see if groups are being used here.
95 if ($groupmode = groups_get_activity_groupmode($cm)) {
96 $groupid = groups_get_activity_group($cm);
97 // Determine is the group is visible to user (this is particullary for the group 0).
98 if (!groups_group_visible($groupid, $course, $cm)) {
99 throw new moodle_exception('notingroup');
100 }
101 } else {
102 $groupid = 0;
103 }
104 }
105
106 // Get the unique chat session id.
107 // Since we are going to use the chat via Web Service requests we set the ajax version (since it's the most similar).
108 if (!$chatsid = chat_login_user($chat->id, 'ajax', $groupid, $course)) {
109 throw moodle_exception('cantlogin', 'chat');
110 }
111
112 $result = array();
113 $result['chatsid'] = $chatsid;
114 $result['warnings'] = $warnings;
115 return $result;
116 }
117
118 /**
119 * Returns description of method result value
120 *
121 * @return external_description
122 * @since Moodle 3.0
123 */
124 public static function login_user_returns() {
125 return new external_single_structure(
126 array(
127 'chatsid' => new external_value(PARAM_ALPHANUM, 'unique chat session id'),
128 'warnings' => new external_warnings()
129 )
130 );
131 }
132
e4076a6e
JL
133 /**
134 * Returns description of method parameters
135 *
136 * @return external_function_parameters
137 * @since Moodle 3.0
138 */
139 public static function get_chat_users_parameters() {
140 return new external_function_parameters(
141 array(
142 'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)')
143 )
144 );
145 }
146
147 /**
148 * Get the list of users in the given chat session.
149 *
150 * @param int $chatsid the chat session id
151 * @return array of warnings and the user lists
152 * @since Moodle 3.0
153 * @throws moodle_exception
154 */
155 public static function get_chat_users($chatsid) {
156 global $DB;
157
158 $params = self::validate_parameters(self::get_chat_users_parameters(),
159 array(
160 'chatsid' => $chatsid
161 ));
162 $warnings = array();
163
164 // Request and permission validation.
165 if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) {
166 throw new moodle_exception('notlogged', 'chat');
167 }
168 $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST);
169 list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
170
171 $context = context_module::instance($cm->id);
172 self::validate_context($context);
173
174 require_capability('mod/chat:chat', $context);
175
176 // First, delete old users from the chats.
177 chat_delete_old_users();
178
179 $users = chat_get_users($chatuser->chatid, $chatuser->groupid, $cm->groupingid);
180 $returnedusers = array();
181
182 foreach ($users as $user) {
183 $usercontext = context_user::instance($user->id, IGNORE_MISSING);
184 $profileimageurl = '';
185
186 if ($usercontext) {
187 $profileimageurl = moodle_url::make_webservice_pluginfile_url(
188 $usercontext->id, 'user', 'icon', null, '/', 'f1')->out(false);
189 }
190
191 $returnedusers[] = array(
192 'id' => $user->id,
193 'fullname' => fullname($user),
194 'profileimageurl' => $profileimageurl
195 );
196 }
197
198 $result = array();
199 $result['users'] = $returnedusers;
200 $result['warnings'] = $warnings;
201 return $result;
202 }
203
204 /**
205 * Returns description of method result value
206 *
207 * @return external_description
208 * @since Moodle 3.0
209 */
210 public static function get_chat_users_returns() {
211 return new external_single_structure(
212 array(
213 'users' => new external_multiple_structure(
214 new external_single_structure(
215 array(
216 'id' => new external_value(PARAM_INT, 'user id'),
217 'fullname' => new external_value(PARAM_NOTAGS, 'user full name'),
218 'profileimageurl' => new external_value(PARAM_URL, 'user picture URL'),
219 )
220 ),
221 'list of users'
222 ),
223 'warnings' => new external_warnings()
224 )
225 );
226 }
227
874aa80f
JL
228 /**
229 * Returns description of method parameters
230 *
231 * @return external_function_parameters
232 * @since Moodle 3.0
233 */
234 public static function send_chat_message_parameters() {
235 return new external_function_parameters(
236 array(
237 'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)'),
238 'messagetext' => new external_value(PARAM_RAW, 'the message text'),
239 'beepid' => new external_value(PARAM_RAW, 'the beep id', VALUE_DEFAULT, ''),
240
241 )
242 );
243 }
244
245 /**
246 * Send a message on the given chat session.
247 *
248 * @param int $chatsid the chat session id
249 * @param string $messagetext the message text
250 * @param string $beepid the beep message id
251 * @return array of warnings and the new message id (0 if the message was empty)
252 * @since Moodle 3.0
253 * @throws moodle_exception
254 */
255 public static function send_chat_message($chatsid, $messagetext, $beepid = '') {
256 global $DB;
257
258 $params = self::validate_parameters(self::send_chat_message_parameters(),
259 array(
260 'chatsid' => $chatsid,
261 'messagetext' => $messagetext,
262 'beepid' => $beepid
263 ));
264 $warnings = array();
265
266 // Request and permission validation.
267 if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) {
268 throw new moodle_exception('notlogged', 'chat');
269 }
270 $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST);
271 list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
272
273 $context = context_module::instance($cm->id);
274 self::validate_context($context);
275
276 require_capability('mod/chat:chat', $context);
277
278 $chatmessage = clean_text($params['messagetext'], FORMAT_MOODLE);
279
280 if (!empty($params['beepid'])) {
281 $chatmessage = 'beep ' . $params['beepid'];
282 }
283
284 if (!empty($chatmessage)) {
285 // Send the message.
286 $messageid = chat_send_chatmessage($chatuser, $chatmessage, 0, $cm);
287 // Update ping time.
288 $chatuser->lastmessageping = time() - 2;
289 $DB->update_record('chat_users', $chatuser);
290 } else {
291 $messageid = 0;
292 }
293
294 $result = array();
295 $result['messageid'] = $messageid;
296 $result['warnings'] = $warnings;
297 return $result;
298 }
299
300 /**
301 * Returns description of method result value
302 *
303 * @return external_description
304 * @since Moodle 3.0
305 */
306 public static function send_chat_message_returns() {
307 return new external_single_structure(
308 array(
309 'messageid' => new external_value(PARAM_INT, 'message sent id'),
310 'warnings' => new external_warnings()
311 )
312 );
313 }
314
8380bc7f
JL
315 /**
316 * Returns description of method parameters
317 *
318 * @return external_function_parameters
319 * @since Moodle 3.0
320 */
321 public static function get_chat_latest_messages_parameters() {
322 return new external_function_parameters(
323 array(
324 'chatsid' => new external_value(PARAM_ALPHANUM, 'chat session id (obtained via mod_chat_login_user)'),
325 'chatlasttime' => new external_value(PARAM_INT, 'last time messages were retrieved (epoch time)', VALUE_DEFAULT, 0)
326 )
327 );
328 }
329
330 /**
331 * Get the latest messages from the given chat session.
332 *
333 * @param int $chatsid the chat session id
334 * @param int $chatlasttime last time messages were retrieved (epoch time)
335 * @return array of warnings and the new message id (0 if the message was empty)
336 * @since Moodle 3.0
337 * @throws moodle_exception
338 */
339 public static function get_chat_latest_messages($chatsid, $chatlasttime = 0) {
340 global $DB, $CFG;
341
342 $params = self::validate_parameters(self::get_chat_latest_messages_parameters(),
343 array(
344 'chatsid' => $chatsid,
345 'chatlasttime' => $chatlasttime
346 ));
347 $warnings = array();
348
349 // Request and permission validation.
350 if (!$chatuser = $DB->get_record('chat_users', array('sid' => $params['chatsid']))) {
351 throw new moodle_exception('notlogged', 'chat');
352 }
353 $chat = $DB->get_record('chat', array('id' => $chatuser->chatid), '*', MUST_EXIST);
354 list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
355
356 $context = context_module::instance($cm->id);
357 self::validate_context($context);
358
359 require_capability('mod/chat:chat', $context);
360
361 $chatlasttime = $params['chatlasttime'];
362 if ((time() - $chatlasttime) > $CFG->chat_old_ping) {
363 chat_delete_old_users();
364 }
365
366 // Set default chat last time (to not retrieve all the conversations).
367 if ($chatlasttime == 0) {
368 $chatlasttime = time() - $CFG->chat_old_ping;
369 }
370
371 if ($latestmessage = chat_get_latest_message($chatuser->chatid, $chatuser->groupid)) {
372 $chatnewlasttime = $latestmessage->timestamp;
373 } else {
374 $chatnewlasttime = 0;
375 }
376
377 $messages = chat_get_latest_messages($chatuser, $chatlasttime);
378 $returnedmessages = array();
379
380 foreach ($messages as $message) {
381
382 // FORMAT_MOODLE is mandatory in the chat plugin.
383 list($messageformatted, $format) = external_format_text($message->message, FORMAT_MOODLE, $context->id, 'mod_chat',
384 '', 0);
385
386 $returnedmessages[] = array(
387 'id' => $message->id,
388 'userid' => $message->userid,
389 'system' => (bool) $message->system,
390 'message' => $messageformatted,
391 'timestamp' => $message->timestamp,
392 );
393 }
394
395 // Update our status since we are active in the chat.
396 $DB->set_field('chat_users', 'lastping', time(), array('id' => $chatuser->id));
397
398 $result = array();
399 $result['messages'] = $returnedmessages;
400 $result['chatnewlasttime'] = $chatnewlasttime;
401 $result['warnings'] = $warnings;
402 return $result;
403 }
404
405 /**
406 * Returns description of method result value
407 *
408 * @return external_description
409 * @since Moodle 3.0
410 */
411 public static function get_chat_latest_messages_returns() {
412 return new external_single_structure(
413 array(
414 'messages' => new external_multiple_structure(
415 new external_single_structure(
416 array(
417 'id' => new external_value(PARAM_INT, 'message id'),
418 'userid' => new external_value(PARAM_INT, 'user id'),
419 'system' => new external_value(PARAM_BOOL, 'true if is a system message (like user joined)'),
420 'message' => new external_value(PARAM_RAW, 'message text'),
421 'timestamp' => new external_value(PARAM_INT, 'timestamp for the message'),
422 )
423 ),
424 'list of users'
425 ),
426 'chatnewlasttime' => new external_value(PARAM_INT, 'new last time'),
427 'warnings' => new external_warnings()
428 )
429 );
430 }
431
5841b9d5
JL
432 /**
433 * Returns description of method parameters
434 *
435 * @return external_function_parameters
436 * @since Moodle 3.0
437 */
438 public static function view_chat_parameters() {
439 return new external_function_parameters(
440 array(
441 'chatid' => new external_value(PARAM_INT, 'chat instance id')
442 )
443 );
444 }
445
446 /**
447 * Trigger the course module viewed event and update the module completion status.
448 *
449 * @param int $chatid the chat instance id
450 * @return array of warnings and status result
451 * @since Moodle 3.0
452 * @throws moodle_exception
453 */
454 public static function view_chat($chatid) {
455 global $DB, $CFG;
456
457 $params = self::validate_parameters(self::view_chat_parameters(),
458 array(
459 'chatid' => $chatid
460 ));
461 $warnings = array();
462
463 // Request and permission validation.
464 $chat = $DB->get_record('chat', array('id' => $params['chatid']), '*', MUST_EXIST);
465 list($course, $cm) = get_course_and_cm_from_instance($chat, 'chat');
466
467 $context = context_module::instance($cm->id);
468 self::validate_context($context);
469
470 require_capability('mod/chat:chat', $context);
471
472 // Call the url/lib API.
473 chat_view($chat, $course, $cm, $context);
474
475 $result = array();
476 $result['status'] = true;
477 $result['warnings'] = $warnings;
478 return $result;
479 }
480
481 /**
482 * Returns description of method result value
483 *
484 * @return external_description
485 * @since Moodle 3.0
486 */
487 public static function view_chat_returns() {
488 return new external_single_structure(
489 array(
490 'status' => new external_value(PARAM_BOOL, 'status: true if success'),
491 'warnings' => new external_warnings()
492 )
493 );
494 }
495
9f7de631
CC
496 /**
497 * Describes the parameters for get_chats_by_courses.
498 *
499 * @return external_external_function_parameters
500 * @since Moodle 3.0
501 */
502 public static function get_chats_by_courses_parameters() {
503 return new external_function_parameters (
504 array(
505 'courseids' => new external_multiple_structure(
506 new external_value(PARAM_INT, 'course id'),
507 'Array of course ids', VALUE_DEFAULT, array()
508 ),
509 )
510 );
511 }
512 /**
513 * Returns a list of chats in a provided list of courses,
514 * if no list is provided all chats that the user can view will be returned.
515 *
516 * @param array $courseids the course ids
517 * @return array of chats details
518 * @since Moodle 3.0
519 */
520 public static function get_chats_by_courses($courseids = array()) {
521 global $CFG;
522 $params = self::validate_parameters(self::get_chats_by_courses_parameters(), array('courseids' => $courseids));
523 $warnings = array();
524 if (!empty($params['courseids'])) {
525 $courses = array();
526 $courseids = $params['courseids'];
527 } else {
528 $courses = enrol_get_my_courses();
529 $courseids = array_keys($courses);
530 }
531 // Array to store the chats to return.
532 $arrchats = array();
533 // Ensure there are courseids to loop through.
534 if (!empty($courseids)) {
535 // Array of the courses we are going to retrieve the chats from.
536 $arraycourses = array();
537 // Go through the courseids.
538 foreach ($courseids as $cid) {
539 // Check the user can function in this context.
540 try {
541 $context = context_course::instance($cid);
542 self::validate_context($context);
543 // Check if this course was already loaded (by enrol_get_my_courses).
544 if (!isset($courses[$cid])) {
545 $courses[$cid] = get_course($cid);
546 }
547 $arraycourses[$cid] = $courses[$cid];
548 } catch (Exception $e) {
549 $warnings[] = array(
550 'item' => 'course',
551 'itemid' => $cid,
552 'warningcode' => '1',
553 'message' => 'No access rights in course context '.$e->getMessage()
554 );
555 }
556 }
557 // Get the chats in this course, this function checks users visibility permissions.
558 // We can avoid then additional validate_context calls.
559 $chats = get_all_instances_in_courses("chat", $arraycourses);
560 foreach ($chats as $chat) {
561 $chatcontext = context_module::instance($chat->coursemodule);
562 // Entry to return.
563 $chatdetails = array();
564 // First, we return information that any user can see in the web interface.
565 $chatdetails['id'] = $chat->id;
566 $chatdetails['coursemodule'] = $chat->coursemodule;
567 $chatdetails['course'] = $chat->course;
568 $chatdetails['name'] = $chat->name;
569 // Format intro.
570 list($chatdetails['intro'], $chatdetails['introformat']) =
571 external_format_text($chat->intro, $chat->introformat,
572 $chatcontext->id, 'mod_chat', 'intro', null);
573 if (has_capability('moodle/course:manageactivities', $chatcontext)) {
574 $chatdetails['keepdays'] = $chat->keepdays;
575 $chatdetails['studentlogs'] = $chat->studentlogs;
576 $chatdetails['chattime'] = $chat->chattime;
577 $chatdetails['schedule'] = $chat->schedule;
578 $chatdetails['timemodified'] = $chat->timemodified;
579 $chatdetails['section'] = $chat->section;
580 $chatdetails['visible'] = $chat->visible;
581 $chatdetails['groupmode'] = $chat->groupmode;
582 $chatdetails['groupingid'] = $chat->groupingid;
583 }
584 $arrchats[] = $chatdetails;
585 }
586 }
587 $result = array();
588 $result['chats'] = $arrchats;
589 $result['warnings'] = $warnings;
590 return $result;
591 }
592 /**
593 * Describes the get_chats_by_courses return value.
594 *
595 * @return external_single_structure
596 * @since Moodle 3.0
597 */
598 public static function get_chats_by_courses_returns() {
599 return new external_single_structure(
600 array(
601 'chats' => new external_multiple_structure(
602 new external_single_structure(
603 array(
604 'id' => new external_value(PARAM_INT, 'Chat id'),
605 'coursemodule' => new external_value(PARAM_INT, 'Course module id'),
606 'course' => new external_value(PARAM_TEXT, 'Course id'),
607 'name' => new external_value(PARAM_TEXT, 'Chat name'),
608 'intro' => new external_value(PARAM_RAW, 'The Chat intro'),
609 'introformat' => new external_format_value('intro'),
610 'keepdays' => new external_value(PARAM_INT, 'keep days', VALUE_OPTIONAL),
611 'studentlogs' => new external_value(PARAM_INT, 'student logs visible to everyone', VALUE_OPTIONAL),
612 'chattime' => new external_value(PARAM_RAW, 'chat time', VALUE_OPTIONAL),
613 'schedule' => new external_value(PARAM_INT, 'schedule type', VALUE_OPTIONAL),
614 'timemodified' => new external_value(PARAM_RAW, 'time of last modification', VALUE_OPTIONAL),
615 'section' => new external_value(PARAM_INT, 'course section id', VALUE_OPTIONAL),
616 'visible' => new external_value(PARAM_BOOL, 'visible', VALUE_OPTIONAL),
617 'groupmode' => new external_value(PARAM_INT, 'group mode', VALUE_OPTIONAL),
618 'groupingid' => new external_value(PARAM_INT, 'group id', VALUE_OPTIONAL),
619 ), 'Chats'
620 )
621 ),
622 'warnings' => new external_warnings(),
623 )
624 );
625 }
1ca4cdf3 626}