848bb113 |
1 | <?php |
2 | |
3 | // This file is part of Moodle - http://moodle.org/ |
4 | // |
5 | // Moodle is free software: you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by |
7 | // the Free Software Foundation, either version 3 of the License, or |
8 | // (at your option) any later version. |
9 | // |
10 | // Moodle is distributed in the hope that it will be useful, |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | // GNU General Public License for more details. |
14 | // |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
1515a89e |
17 | |
848bb113 |
18 | /** |
19 | * Library of functions and constants for module chat |
20 | * |
b2d5a79a |
21 | * @package mod-chat |
848bb113 |
22 | * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
24 | */ |
25 | |
26 | /** Include portfoliolib.php */ |
214b1cf7 |
27 | require_once($CFG->libdir.'/portfoliolib.php'); |
c4d588cc |
28 | |
1d507186 |
29 | $CFG->chat_ajax_debug = false; |
30 | $CFG->chat_use_cache = false; |
31 | |
1515a89e |
32 | // The HTML head for the message window to start with (<!-- nix --> is used to get some browsers starting with output |
17da2e6f |
33 | global $CHAT_HTMLHEAD; |
1f8abb89 |
34 | $CHAT_HTMLHEAD = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head></head>\n<body>\n\n".padding(200); |
1515a89e |
35 | |
36 | // The HTML head for the message window to start with (with js scrolling) |
17da2e6f |
37 | global $CHAT_HTMLHEAD_JS; |
1f8abb89 |
38 | $CHAT_HTMLHEAD_JS = <<<EOD |
39 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> |
40 | <html><head><script type="text/javascript"> |
41 | //<![CDATA[ |
42 | function move(){ |
43 | if (scroll_active) |
44 | window.scroll(1,400000); |
45 | window.setTimeout("move()",100); |
46 | } |
47 | var scroll_active = true; |
48 | move(); |
49 | //]]> |
50 | </script> |
51 | </head> |
52 | <body onBlur="scroll_active = true" onFocus="scroll_active = false"> |
53 | EOD; |
17da2e6f |
54 | global $CHAT_HTMLHEAD_JS; |
1f8abb89 |
55 | $CHAT_HTMLHEAD_JS .= padding(200); |
1515a89e |
56 | |
57 | // The HTML code for standard empty pages (e.g. if a user was kicked out) |
17da2e6f |
58 | global $CHAT_HTMLHEAD_OUT; |
1f8abb89 |
59 | $CHAT_HTMLHEAD_OUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>You are out!</title></head><body></body></html>"; |
1515a89e |
60 | |
61 | // The HTML head for the message input page |
17da2e6f |
62 | global $CHAT_HTMLHEAD_MSGINPUT; |
1f8abb89 |
63 | $CHAT_HTMLHEAD_MSGINPUT = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\"><html><head><title>Message Input</title></head><body>"; |
1515a89e |
64 | |
65 | // The HTML code for the message input page, with JavaScript |
17da2e6f |
66 | global $CHAT_HTMLHEAD_MSGINPUT_JS; |
1d507186 |
67 | $CHAT_HTMLHEAD_MSGINPUT_JS = <<<EOD |
68 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> |
69 | <html> |
70 | <head><title>Message Input</title> |
71 | <script type="text/javascript"> |
72 | //<![CDATA[ |
73 | scroll_active = true; |
74 | function empty_field_and_submit(){ |
75 | document.fdummy.arsc_message.value=document.f.arsc_message.value; |
76 | document.fdummy.submit(); |
77 | document.f.arsc_message.focus(); |
78 | document.f.arsc_message.select(); |
79 | return false; |
80 | } |
81 | //]]> |
82 | </script> |
83 | </head><body OnLoad="document.f.arsc_message.focus();document.f.arsc_message.select();">; |
84 | EOD; |
1515a89e |
85 | |
fbabbd23 |
86 | // Dummy data that gets output to the browser as needed, in order to make it show output |
17da2e6f |
87 | global $CHAT_DUMMY_DATA; |
6e5f40ea |
88 | $CHAT_DUMMY_DATA = padding(200); |
5c2f6a7f |
89 | |
848bb113 |
90 | /** |
91 | * @param int $n |
92 | * @return string |
93 | */ |
6e5f40ea |
94 | function padding($n){ |
5c2f6a7f |
95 | $str = ''; |
633c3341 |
96 | for($i=0; $i<$n; $i++){ |
1f8abb89 |
97 | $str.="<!-- nix -->\n"; |
5c2f6a7f |
98 | } |
99 | return $str; |
100 | } |
1515a89e |
101 | |
848bb113 |
102 | /** |
103 | * Given an object containing all the necessary data, |
104 | * (defined by the form in mod_form.php) this function |
105 | * will create a new instance and return the id number |
106 | * of the new instance. |
107 | * |
108 | * @global object |
109 | * @param object $chat |
110 | * @return int |
111 | */ |
1515a89e |
112 | function chat_add_instance($chat) { |
c18269c7 |
113 | global $DB; |
1515a89e |
114 | |
115 | $chat->timemodified = time(); |
116 | |
c18269c7 |
117 | if ($returnid = $DB->insert_record("chat", $chat)) { |
8496c4af |
118 | |
119 | $event = NULL; |
120 | $event->name = $chat->name; |
9b010a10 |
121 | $event->description = format_module_intro('chat', $chat, $chat->coursemodule); |
8496c4af |
122 | $event->courseid = $chat->course; |
123 | $event->groupid = 0; |
124 | $event->userid = 0; |
125 | $event->modulename = 'chat'; |
126 | $event->instance = $returnid; |
127 | $event->eventtype = $chat->schedule; |
128 | $event->timestart = $chat->chattime; |
129 | $event->timeduration = 0; |
130 | |
131 | add_event($event); |
132 | } |
133 | |
134 | return $returnid; |
1515a89e |
135 | } |
136 | |
848bb113 |
137 | /** |
138 | * Given an object containing all the necessary data, |
139 | * (defined by the form in mod_form.php) this function |
140 | * will update an existing instance with new data. |
141 | * |
142 | * @global object |
143 | * @param object $chat |
144 | * @return int |
145 | */ |
1515a89e |
146 | function chat_update_instance($chat) { |
c18269c7 |
147 | global $DB; |
1515a89e |
148 | |
149 | $chat->timemodified = time(); |
150 | $chat->id = $chat->instance; |
151 | |
1515a89e |
152 | |
c18269c7 |
153 | if ($returnid = $DB->update_record("chat", $chat)) { |
8496c4af |
154 | |
264867fd |
155 | $event = new object(); |
8496c4af |
156 | |
c18269c7 |
157 | if ($event->id = $DB->get_field('event', 'id', array('modulename'=>'chat', 'instance'=>$chat->id))) { |
8496c4af |
158 | |
159 | $event->name = $chat->name; |
9b010a10 |
160 | $event->description = format_module_intro('chat', $chat, $chat->coursemodule); |
8496c4af |
161 | $event->timestart = $chat->chattime; |
162 | |
163 | update_event($event); |
164 | } |
165 | } |
166 | |
167 | return $returnid; |
1515a89e |
168 | } |
169 | |
848bb113 |
170 | /** |
171 | * Given an ID of an instance of this module, |
172 | * this function will permanently delete the instance |
173 | * and any data that depends on it. |
174 | * |
175 | * @global object |
176 | * @param int $id |
177 | * @return bool |
178 | */ |
1515a89e |
179 | function chat_delete_instance($id) { |
c18269c7 |
180 | global $DB; |
848bb113 |
181 | |
1515a89e |
182 | |
c18269c7 |
183 | if (! $chat = $DB->get_record('chat', array('id'=>$id))) { |
1515a89e |
184 | return false; |
185 | } |
186 | |
187 | $result = true; |
188 | |
189 | # Delete any dependent records here # |
190 | |
c18269c7 |
191 | if (! $DB->delete_records('chat', array('id'=>$chat->id))) { |
a71efae3 |
192 | $result = false; |
193 | } |
c18269c7 |
194 | if (! $DB->delete_records('chat_messages', array('chatid'=>$chat->id))) { |
a71efae3 |
195 | $result = false; |
196 | } |
6e5f40ea |
197 | if (! $DB->delete_records('chat_messages_current', array('chatid'=>$chat->id))) { |
198 | $result = false; |
199 | } |
c18269c7 |
200 | if (! $DB->delete_records('chat_users', array('chatid'=>$chat->id))) { |
1515a89e |
201 | $result = false; |
202 | } |
203 | |
c18269c7 |
204 | if (! $DB->delete_records('event', array('modulename'=>'chat', 'instance'=>$chat->id))) { |
36eb856f |
205 | $result = false; |
206 | } |
207 | |
1515a89e |
208 | return $result; |
209 | } |
210 | |
848bb113 |
211 | /** |
212 | * Return a small object with summary information about what a |
213 | * user has done with a given particular instance of this module |
214 | * Used for user activity reports. |
215 | * <code> |
216 | * $return->time = the time they did it |
217 | * $return->info = a short text description |
218 | * </code> |
219 | * |
220 | * @param object $course |
221 | * @param object $user |
222 | * @param object $mod |
223 | * @param object $chat |
224 | * @return void |
225 | */ |
1515a89e |
226 | function chat_user_outline($course, $user, $mod, $chat) { |
d3bf6f92 |
227 | return NULL; |
1515a89e |
228 | } |
229 | |
848bb113 |
230 | /** |
231 | * Print a detailed representation of what a user has done with |
232 | * a given particular instance of this module, for user activity reports. |
233 | * |
234 | * @param object $course |
235 | * @param object $user |
236 | * @param object $mod |
237 | * @param object $chat |
238 | * @return bool |
239 | */ |
1515a89e |
240 | function chat_user_complete($course, $user, $mod, $chat) { |
1515a89e |
241 | return true; |
242 | } |
243 | |
848bb113 |
244 | /** |
245 | * Given a course and a date, prints a summary of all chat rooms past and present |
246 | * This function is called from course/lib.php: print_recent_activity() |
247 | * |
248 | * @global object |
249 | * @global object |
250 | * @global object |
251 | * @param object $course |
252 | * @param array $viewfullnames |
253 | * @param int|string $timestart Timestamp |
254 | * @return bool |
255 | */ |
dd97c328 |
256 | function chat_print_recent_activity($course, $viewfullnames, $timestart) { |
e09fc68b |
257 | global $CFG, $USER, $DB, $OUTPUT; |
dd97c328 |
258 | |
259 | // this is approximate only, but it is really fast ;-) |
260 | $timeout = $CFG->chat_old_ping * 10; |
261 | |
d3bf6f92 |
262 | if (!$mcms = $DB->get_records_sql("SELECT cm.id, MAX(chm.timestamp) AS lasttime |
263 | FROM {course_modules} cm |
264 | JOIN {modules} md ON md.id = cm.module |
265 | JOIN {chat} ch ON ch.id = cm.instance |
266 | JOIN {chat_messages} chm ON chm.chatid = ch.id |
267 | WHERE chm.timestamp > ? AND ch.course = ? AND md.name = 'chat' |
268 | GROUP BY cm.id |
269 | ORDER BY lasttime ASC", array($timestart, $course->id))) { |
dd97c328 |
270 | return false; |
271 | } |
272 | |
273 | $past = array(); |
274 | $current = array(); |
275 | $modinfo =& get_fast_modinfo($course); // reference needed because we might load the groups |
276 | |
fd4d41c3 |
277 | foreach ($mcms as $cmid=>$mcm) { |
278 | if (!array_key_exists($cmid, $modinfo->cms)) { |
dd97c328 |
279 | continue; |
280 | } |
fd4d41c3 |
281 | $cm = $modinfo->cms[$cmid]; |
282 | $cm->lasttime = $mcm->lasttime; |
dd97c328 |
283 | if (!$modinfo->cms[$cm->id]->uservisible) { |
284 | continue; |
285 | } |
b7602a11 |
286 | |
dd97c328 |
287 | if (groups_get_activity_groupmode($cm) != SEPARATEGROUPS |
288 | or has_capability('moodle/site:accessallgroups', get_context_instance(CONTEXT_MODULE, $cm->id))) { |
289 | if ($timeout > time() - $cm->lasttime) { |
290 | $current[] = $cm; |
291 | } else { |
292 | $past[] = $cm; |
293 | } |
294 | |
295 | continue; |
296 | } |
297 | |
298 | if (is_null($modinfo->groups)) { |
299 | $modinfo->groups = groups_get_user_groups($course->id); // load all my groups and cache it in modinfo |
300 | } |
c5a05b95 |
301 | |
dd97c328 |
302 | // verify groups in separate mode |
303 | if (!$mygroupids = $modinfo->groups[$cm->groupingid]) { |
304 | continue; |
305 | } |
0469cccf |
306 | |
dd97c328 |
307 | // ok, last post was not for my group - we have to query db to get last message from one of my groups |
308 | // only minor problem is that the order will not be correct |
309 | $mygroupids = implode(',', $mygroupids); |
310 | $cm->mygroupids = $mygroupids; |
311 | |
d3bf6f92 |
312 | if (!$mcm = $DB->get_record_sql("SELECT cm.id, MAX(chm.timestamp) AS lasttime |
313 | FROM {course_modules} cm |
314 | JOIN {chat} ch ON ch.id = cm.instance |
6e5f40ea |
315 | JOIN {chat_messages_current} chm ON chm.chatid = ch.id |
d3bf6f92 |
316 | WHERE chm.timestamp > ? AND cm.id = ? AND |
317 | (chm.groupid IN ($mygroupids) OR chm.groupid = 0) |
318 | GROUP BY cm.id", array($timestart, $cm->id))) { |
dd97c328 |
319 | continue; |
320 | } |
fd4d41c3 |
321 | |
322 | $cm->lasttime = $mcm->lasttime; |
dd97c328 |
323 | if ($timeout > time() - $cm->lasttime) { |
324 | $current[] = $cm; |
325 | } else { |
326 | $past[] = $cm; |
327 | } |
328 | } |
329 | |
330 | if (!$past and !$current) { |
b7602a11 |
331 | return false; |
332 | } |
1515a89e |
333 | |
dd97c328 |
334 | $strftimerecent = get_string('strftimerecent'); |
335 | |
336 | if ($past) { |
e09fc68b |
337 | echo $OUTPUT->heading(get_string("pastchats", 'chat').':'); |
dd97c328 |
338 | |
339 | foreach ($past as $cm) { |
340 | $link = $CFG->wwwroot.'/mod/chat/view.php?id='.$cm->id; |
341 | $date = userdate($cm->lasttime, $strftimerecent); |
342 | echo '<div class="head"><div class="date">'.$date.'</div></div>'; |
343 | echo '<div class="info"><a href="'.$link.'">'.format_string($cm->name,true).'</a></div>'; |
b7602a11 |
344 | } |
8f7dc7f1 |
345 | } |
346 | |
347 | if ($current) { |
e09fc68b |
348 | echo $OUTPUT->heading(get_string("currentchats", 'chat').':'); |
dd97c328 |
349 | |
350 | $oldest = floor((time()-$CFG->chat_old_ping)/10)*10; // better db caching |
351 | |
352 | $timeold = time() - $CFG->chat_old_ping; |
353 | $timeold = floor($timeold/10)*10; // better db caching |
354 | $timeoldext = time() - ($CFG->chat_old_ping*10); // JSless gui_basic needs much longer timeouts |
355 | $timeoldext = floor($timeoldext/10)*10; // better db caching |
356 | |
d3bf6f92 |
357 | $params = array('timeold'=>$timeold, 'timeoldext'=>$timeoldext, 'cmid'=>$cm->id); |
358 | |
359 | $timeout = "AND (chu.version<>'basic' AND chu.lastping>:timeold) OR (chu.version='basic' AND chu.lastping>:timeoldext)"; |
dd97c328 |
360 | |
361 | foreach ($current as $cm) { |
362 | //count users first |
363 | if (isset($cm->mygroupids)) { |
364 | $groupselect = "AND (chu.groupid IN ({$cm->mygroupids}) OR chu.groupid = 0)"; |
365 | } else { |
366 | $groupselect = ""; |
367 | } |
fd4d41c3 |
368 | |
d3bf6f92 |
369 | if (!$users = $DB->get_records_sql("SELECT u.id, u.firstname, u.lastname, u.email, u.picture |
370 | FROM {course_modules} cm |
371 | JOIN {chat} ch ON ch.id = cm.instance |
372 | JOIN {chat_users} chu ON chu.chatid = ch.id |
373 | JOIN {user} u ON u.id = chu.userid |
374 | WHERE cm.id = :cmid $timeout $groupselect |
375 | GROUP BY u.id, u.firstname, u.lastname, u.email, u.picture", $params)) { |
dd97c328 |
376 | } |
377 | |
378 | $link = $CFG->wwwroot.'/mod/chat/view.php?id='.$cm->id; |
379 | $date = userdate($cm->lasttime, $strftimerecent); |
380 | |
381 | echo '<div class="head"><div class="date">'.$date.'</div></div>'; |
382 | echo '<div class="info"><a href="'.$link.'">'.format_string($cm->name,true).'</a></div>'; |
383 | echo '<div class="userlist">'; |
384 | if ($users) { |
385 | echo '<ul>'; |
386 | foreach ($users as $user) { |
387 | echo '<li>'.fullname($user, $viewfullnames).'</li>'; |
388 | } |
389 | echo '</ul>'; |
390 | } |
391 | echo '</div>'; |
392 | } |
b7602a11 |
393 | } |
394 | |
395 | return true; |
1515a89e |
396 | } |
397 | |
848bb113 |
398 | /** |
399 | * Function to be run periodically according to the moodle cron |
400 | * This function searches for things that need to be done, such |
401 | * as sending out mail, toggling flags etc ... |
402 | * |
403 | * @global object |
404 | * @return bool |
405 | */ |
1515a89e |
406 | function chat_cron () { |
d3bf6f92 |
407 | global $DB; |
1515a89e |
408 | |
fcd3a1ee |
409 | chat_update_chat_times(); |
410 | |
7d792369 |
411 | chat_delete_old_users(); |
412 | |
319038c3 |
413 | /// Delete old messages with a |
414 | /// single SQL query. |
415 | $subselect = "SELECT c.keepdays |
d3bf6f92 |
416 | FROM {chat} c |
417 | WHERE c.id = {chat_messages}.chatid"; |
4388027c |
418 | |
319038c3 |
419 | $sql = "DELETE |
d3bf6f92 |
420 | FROM {chat_messages} |
6e5f40ea |
421 | WHERE ($subselect) > 0 AND timestamp < ( ".time()." -($subselect) * 24 * 3600)"; |
422 | |
423 | $DB->execute($sql); |
424 | |
425 | $sql = "DELETE |
426 | FROM {chat_messages_current} |
427 | WHERE timestamp < ( ".time()." - 8 * 3600)"; |
4388027c |
428 | |
d3bf6f92 |
429 | $DB->execute($sql); |
22a4491a |
430 | |
1515a89e |
431 | return true; |
432 | } |
433 | |
848bb113 |
434 | /** |
435 | * Returns the users with data in one chat |
436 | * (users with records in chat_messages, students) |
437 | * |
438 | * @global object |
439 | * @param int $chatid |
440 | * @param int $groupid |
441 | * @return array |
442 | */ |
84a2fdd7 |
443 | function chat_get_participants($chatid, $groupid=0) { |
d3bf6f92 |
444 | global $DB; |
05855091 |
445 | |
d3bf6f92 |
446 | $params = array('groupid'=>$groupid, 'chatid'=>$chatid); |
05855091 |
447 | |
84a2fdd7 |
448 | if ($groupid) { |
d3bf6f92 |
449 | $groupselect = " AND (c.groupid=:groupid OR c.groupid='0')"; |
84a2fdd7 |
450 | } else { |
451 | $groupselect = ""; |
452 | } |
453 | |
05855091 |
454 | //Get students |
d3bf6f92 |
455 | $students = $DB->get_records_sql("SELECT DISTINCT u.id, u.id |
456 | FROM {user} u, {chat_messages} c |
457 | WHERE c.chatid = :chatid $groupselect |
458 | AND u.id = c.userid", $params); |
1515a89e |
459 | |
05855091 |
460 | //Return students array (it contains an array of unique users) |
461 | return ($students); |
462 | } |
1515a89e |
463 | |
848bb113 |
464 | /** |
465 | * This standard function will check all instances of this module |
466 | * and make sure there are up-to-date events created for each of them. |
467 | * If courseid = 0, then every chat event in the site is checked, else |
468 | * only chat events belonging to the course specified are checked. |
469 | * This function is used, in its new format, by restore_refresh_events() |
470 | * |
471 | * @global object |
472 | * @param int $courseid |
473 | * @return bool |
474 | */ |
8496c4af |
475 | function chat_refresh_events($courseid = 0) { |
d3bf6f92 |
476 | global $DB; |
8496c4af |
477 | |
478 | if ($courseid) { |
d3bf6f92 |
479 | if (! $chats = $DB->get_records("chat", array("course"=>$courseid))) { |
8496c4af |
480 | return true; |
481 | } |
482 | } else { |
d3bf6f92 |
483 | if (! $chats = $DB->get_records("chat")) { |
8496c4af |
484 | return true; |
485 | } |
486 | } |
d3bf6f92 |
487 | $moduleid = $DB->get_field('modules', 'id', array('name'=>'chat')); |
8496c4af |
488 | |
489 | foreach ($chats as $chat) { |
9b010a10 |
490 | $cm = get_coursemodule_from_id('chat', $chat->id); |
491 | $event = new object(); |
d3bf6f92 |
492 | $event->name = $chat->name; |
9b010a10 |
493 | $event->description = format_module_intro('chat', $chat, $cm->id); |
8496c4af |
494 | $event->timestart = $chat->chattime; |
495 | |
d3bf6f92 |
496 | if ($event->id = $DB->get_field('event', 'id', array('modulename'=>'chat', 'instance'=>$chat->id))) { |
8496c4af |
497 | update_event($event); |
498 | |
499 | } else { |
500 | $event->courseid = $chat->course; |
501 | $event->groupid = 0; |
502 | $event->userid = 0; |
503 | $event->modulename = 'chat'; |
504 | $event->instance = $chat->id; |
505 | $event->eventtype = $chat->schedule; |
506 | $event->timeduration = 0; |
d3bf6f92 |
507 | $event->visible = $DB->get_field('course_modules', 'visible', array('module'=>$moduleid, 'instance'=>$chat->id)); |
b5de723d |
508 | |
8496c4af |
509 | add_event($event); |
510 | } |
511 | } |
512 | return true; |
513 | } |
514 | |
516121bd |
515 | |
1515a89e |
516 | ////////////////////////////////////////////////////////////////////// |
517 | /// Functions that require some SQL |
518 | |
848bb113 |
519 | /** |
520 | * @global object |
521 | * @param int $chatid |
522 | * @param int $groupid |
523 | * @param int $groupingid |
524 | * @return array |
525 | */ |
a12e11c1 |
526 | function chat_get_users($chatid, $groupid=0, $groupingid=0) { |
d3bf6f92 |
527 | global $DB; |
1515a89e |
528 | |
d3bf6f92 |
529 | $params = array('chatid'=>$chatid, 'groupid'=>$groupid, 'groupingid'=>$groupingid); |
84a2fdd7 |
530 | |
531 | if ($groupid) { |
d3bf6f92 |
532 | $groupselect = " AND (c.groupid=:groupid OR c.groupid='0')"; |
84a2fdd7 |
533 | } else { |
534 | $groupselect = ""; |
535 | } |
6e5f40ea |
536 | |
a12e11c1 |
537 | if (!empty($CFG->enablegroupings) && !(empty($groupingid))) { |
d3bf6f92 |
538 | $groupingjoin = "JOIN {groups_members} gm ON u.id = gm.userid |
539 | JOIN {groupings_groups} gg ON gm.groupid = gg.groupid AND gg.groupingid = :groupingid "; |
6e5f40ea |
540 | |
a12e11c1 |
541 | } else { |
542 | $groupingjoin = ''; |
543 | } |
b5de723d |
544 | |
547ac664 |
545 | return $DB->get_records_sql("SELECT |
546 | DISTINCT u.id, u.firstname, u.lastname, u.picture, c.lastmessageping, c.firstping, u.imagealt |
547 | FROM {chat_users} c JOIN {user} u ON u.id = c.userid $groupingjoin |
548 | WHERE c.chatid = :chatid $groupselect |
549 | ORDER BY c.firstping ASC", $params); |
1515a89e |
550 | } |
551 | |
848bb113 |
552 | /** |
553 | * @global object |
554 | * @param int $chatid |
555 | * @param int $groupid |
556 | * @return array |
557 | */ |
84a2fdd7 |
558 | function chat_get_latest_message($chatid, $groupid=0) { |
f33e1ed4 |
559 | global $DB; |
1515a89e |
560 | |
d3bf6f92 |
561 | $params = array('chatid'=>$chatid, 'groupid'=>$groupid); |
1515a89e |
562 | |
84a2fdd7 |
563 | if ($groupid) { |
d3bf6f92 |
564 | $groupselect = "AND (groupid=:groupid OR groupid=0)"; |
84a2fdd7 |
565 | } else { |
566 | $groupselect = ""; |
567 | } |
568 | |
547ac664 |
569 | $sql = "SELECT * |
570 | FROM {chat_messages_current} WHERE chatid = :chatid $groupselect |
571 | ORDER BY timestamp DESC"; |
03cedd62 |
572 | |
547ac664 |
573 | // return the lastest one message |
f33e1ed4 |
574 | return $DB->get_record_sql($sql, $params, true); |
1515a89e |
575 | } |
576 | |
5a8625e4 |
577 | |
1515a89e |
578 | ////////////////////////////////////////////////////////////////////// |
516121bd |
579 | // login if not already logged in |
1515a89e |
580 | |
848bb113 |
581 | /** |
582 | * login if not already logged in |
583 | * |
584 | * @global object |
585 | * @global object |
586 | * @param int $chatid |
587 | * @param string $version |
588 | * @param int $groupid |
589 | * @param object $course |
590 | * @return bool|int Returns the chat users sid or false |
591 | */ |
a32c7772 |
592 | function chat_login_user($chatid, $version, $groupid, $course) { |
d3bf6f92 |
593 | global $USER, $DB; |
594 | |
595 | if (($version != 'sockets') and $chatuser = $DB->get_record('chat_users', array('chatid'=>$chatid, 'userid'=>$USER->id, 'groupid'=>$groupid))) { |
7f0483f6 |
596 | // this will update logged user information |
516121bd |
597 | $chatuser->version = $version; |
d96466d2 |
598 | $chatuser->ip = $USER->lastip; |
516121bd |
599 | $chatuser->lastping = time(); |
600 | $chatuser->lang = current_language(); |
1515a89e |
601 | |
d96466d2 |
602 | // Sometimes $USER->lastip is not setup properly |
d13ef2fb |
603 | // during login. Update with current value if possible |
f83edcb1 |
604 | // or provide a dummy value for the db |
d13ef2fb |
605 | if (empty($chatuser->ip)) { |
606 | $chatuser->ip = getremoteaddr(); |
607 | if (empty($chatuser->ip)) { |
f83edcb1 |
608 | $chatuser->ip = ''; |
d13ef2fb |
609 | } |
610 | } |
611 | |
7f0483f6 |
612 | if (($chatuser->course != $course->id) or ($chatuser->userid != $USER->id)) { |
516121bd |
613 | return false; |
614 | } |
a8c31db2 |
615 | $DB->update_record('chat_users', $chatuser); |
616 | |
516121bd |
617 | } else { |
6ee78cee |
618 | $chatuser = new object(); |
516121bd |
619 | $chatuser->chatid = $chatid; |
620 | $chatuser->userid = $USER->id; |
621 | $chatuser->groupid = $groupid; |
622 | $chatuser->version = $version; |
d96466d2 |
623 | $chatuser->ip = $USER->lastip; |
516121bd |
624 | $chatuser->lastping = $chatuser->firstping = $chatuser->lastmessageping = time(); |
625 | $chatuser->sid = random_string(32); |
3dfd307f |
626 | $chatuser->course = $course->id; //caching - needed for current_language too |
627 | $chatuser->lang = current_language(); //caching - to resource intensive to find out later |
516121bd |
628 | |
d96466d2 |
629 | // Sometimes $USER->lastip is not setup properly |
274f0091 |
630 | // during login. Update with current value if possible |
631 | // or provide a dummy value for the db |
632 | if (empty($chatuser->ip)) { |
633 | $chatuser->ip = getremoteaddr(); |
634 | if (empty($chatuser->ip)) { |
635 | $chatuser->ip = ''; |
636 | } |
637 | } |
638 | |
639 | |
a8c31db2 |
640 | $DB->insert_record('chat_users', $chatuser); |
516121bd |
641 | |
a32c7772 |
642 | if ($version == 'sockets') { |
643 | // do not send 'enter' message, chatd will do it |
644 | } else { |
6ee78cee |
645 | $message = new object(); |
2ac0d13b |
646 | $message->chatid = $chatuser->chatid; |
647 | $message->userid = $chatuser->userid; |
648 | $message->groupid = $groupid; |
649 | $message->message = 'enter'; |
650 | $message->system = 1; |
651 | $message->timestamp = time(); |
652 | |
7826abc7 |
653 | $DB->insert_record('chat_messages', $message); |
654 | $DB->insert_record('chat_messages_current', $message); |
516121bd |
655 | } |
1515a89e |
656 | } |
657 | |
658 | return $chatuser->sid; |
659 | } |
660 | |
848bb113 |
661 | /** |
662 | * Delete the old and in the way |
663 | * |
664 | * @global object |
665 | * @global object |
666 | */ |
7d792369 |
667 | function chat_delete_old_users() { |
668 | // Delete the old and in the way |
d3bf6f92 |
669 | global $CFG, $DB; |
b5012f3e |
670 | |
e7fbd0b3 |
671 | $timeold = time() - $CFG->chat_old_ping; |
953eb6f3 |
672 | $timeoldext = time() - ($CFG->chat_old_ping*10); // JSless gui_basic needs much longer timeouts |
a32c7772 |
673 | |
d3bf6f92 |
674 | $query = "(version<>'basic' AND lastping<?) OR (version='basic' AND lastping<?)"; |
675 | $params = array($timeold, $timeoldext); |
7d792369 |
676 | |
d3bf6f92 |
677 | if ($oldusers = $DB->get_records_select('chat_users', $query, $params) ) { |
678 | $DB->delete_records_select('chat_users', $query, $params); |
7d792369 |
679 | foreach ($oldusers as $olduser) { |
6ee78cee |
680 | $message = new object(); |
516121bd |
681 | $message->chatid = $olduser->chatid; |
682 | $message->userid = $olduser->userid; |
683 | $message->groupid = $olduser->groupid; |
684 | $message->message = 'exit'; |
685 | $message->system = 1; |
7d792369 |
686 | $message->timestamp = time(); |
b5de723d |
687 | |
7826abc7 |
688 | $DB->insert_record('chat_messages', $message); |
689 | $DB->insert_record('chat_messages_current', $message); |
7d792369 |
690 | } |
691 | } |
692 | } |
1515a89e |
693 | |
848bb113 |
694 | /** |
695 | * Updates chat records so that the next chat time is correct |
696 | * |
697 | * @global object |
698 | * @param int $chatid |
699 | * @return void |
700 | */ |
fcd3a1ee |
701 | function chat_update_chat_times($chatid=0) { |
702 | /// Updates chat records so that the next chat time is correct |
d3bf6f92 |
703 | global $DB; |
fcd3a1ee |
704 | |
705 | $timenow = time(); |
d3bf6f92 |
706 | |
707 | $params = array('timenow'=>$timenow, 'chatid'=>$chatid); |
708 | |
fcd3a1ee |
709 | if ($chatid) { |
d3bf6f92 |
710 | if (!$chats[] = $DB->get_record_select("chat", "id = :chatid AND chattime <= :timenow AND schedule > 0", $params)) { |
fcd3a1ee |
711 | return; |
712 | } |
713 | } else { |
d3bf6f92 |
714 | if (!$chats = $DB->get_records_select("chat", "chattime <= :timenow AND schedule > 0", $params)) { |
fcd3a1ee |
715 | return; |
716 | } |
717 | } |
718 | |
719 | foreach ($chats as $chat) { |
720 | switch ($chat->schedule) { |
721 | case 1: // Single event - turn off schedule and disable |
722 | $chat->chattime = 0; |
723 | $chat->schedule = 0; |
724 | break; |
725 | case 2: // Repeat daily |
f0d3bb9e |
726 | while ($chat->chattime <= $timenow) { |
727 | $chat->chattime += 24 * 3600; |
728 | } |
fcd3a1ee |
729 | break; |
730 | case 3: // Repeat weekly |
f0d3bb9e |
731 | while ($chat->chattime <= $timenow) { |
732 | $chat->chattime += 7 * 24 * 3600; |
733 | } |
fcd3a1ee |
734 | break; |
735 | } |
d3bf6f92 |
736 | $DB->update_record("chat", $chat); |
737 | |
738 | $event = new object(); // Update calendar too |
8496c4af |
739 | |
d3bf6f92 |
740 | $cond = "modulename='chat' AND instance = :chatid AND timestart <> :chattime"; |
741 | $params = array('chattime'=>$chat->chattime, 'chatid'=>$chatid); |
742 | |
743 | if ($event->id = $DB->get_field_select('event', 'id', $cond, $params)) { |
8496c4af |
744 | $event->timestart = $chat->chattime; |
745 | update_event($event); |
746 | } |
fcd3a1ee |
747 | } |
748 | } |
749 | |
848bb113 |
750 | /** |
751 | * @global object |
752 | * @global object |
753 | * @param object $message |
754 | * @param int $courseid |
755 | * @param object $sender |
756 | * @param object $currentuser |
757 | * @param string $chat_lastrow |
758 | * @return bool|string Returns HTML or false |
759 | */ |
aa5c32fd |
760 | function chat_format_message_manually($message, $courseid, $sender, $currentuser, $chat_lastrow=NULL) { |
af7bad79 |
761 | global $CFG, $USER, $OUTPUT; |
1515a89e |
762 | |
6ee78cee |
763 | $output = new object(); |
516121bd |
764 | $output->beep = false; // by default |
765 | $output->refreshusers = false; // by default |
7d792369 |
766 | |
72989350 |
767 | // Use get_user_timezone() to find the correct timezone for displaying this message: |
768 | // It's either the current user's timezone or else decided by some Moodle config setting |
970f144e |
769 | // First, "reset" $USER->timezone (which could have been set by a previous call to here) |
770 | // because otherwise the value for the previous $currentuser will take precedence over $CFG->timezone |
771 | $USER->timezone = 99; |
72989350 |
772 | $tz = get_user_timezone($currentuser->timezone); |
b5de723d |
773 | |
72989350 |
774 | // Before formatting the message time string, set $USER->timezone to the above. |
775 | // This will allow dst_offset_on (called by userdate) to work correctly, otherwise the |
776 | // message times appear off because DST is not taken into account when it should be. |
777 | $USER->timezone = $tz; |
b5de723d |
778 | $message->strtime = userdate($message->timestamp, get_string('strftimemessage', 'chat'), $tz); |
779 | |
af7bad79 |
780 | $message->picture = $OUTPUT->user_picture(moodle_user_picture::make($sender, $courseid)); |
582de679 |
781 | if ($courseid) { |
d3981e38 |
782 | $message->picture = "<a onclick=\"window.open('$CFG->wwwroot/user/view.php?id=$sender->id&course=$courseid')\" href=\"$CFG->wwwroot/user/view.php?id=$sender->id&course=$courseid\">$message->picture</a>"; |
582de679 |
783 | } |
1515a89e |
784 | |
aa5c32fd |
785 | //Calculate the row class |
786 | if ($chat_lastrow !== NULL) { |
787 | $rowclass = ' class="r'.$chat_lastrow.'" '; |
788 | } else { |
789 | $rowclass = ''; |
790 | } |
791 | |
b5de723d |
792 | // Start processing the message |
1515a89e |
793 | |
b5de723d |
794 | if(!empty($message->system)) { |
795 | // System event |
796 | $output->text = $message->strtime.': '.get_string('message'.$message->message, 'chat', fullname($sender)); |
aa5c32fd |
797 | $output->html = '<table class="chat-event"><tr'.$rowclass.'><td class="picture">'.$message->picture.'</td><td class="text">'; |
798 | $output->html .= '<span class="event">'.$output->text.'</span></td></tr></table>'; |
6e5f40ea |
799 | $output->basic = '<dl><dt class="event">'.$message->strtime.': '.get_string('message'.$message->message, 'chat', fullname($sender)).'</dt></dl>'; |
7d792369 |
800 | |
516121bd |
801 | if($message->message == 'exit' or $message->message == 'enter') { |
802 | $output->refreshusers = true; //force user panel refresh ASAP |
803 | } |
1515a89e |
804 | return $output; |
805 | } |
806 | |
82a524ef |
807 | // It's not a system event |
b5de723d |
808 | |
809 | $text = $message->message; |
82a524ef |
810 | |
811 | /// Parse the text to clean and filter it |
812 | |
6ee78cee |
813 | $options = new object(); |
82a524ef |
814 | $options->para = false; |
815 | $text = format_text($text, FORMAT_MOODLE, $options, $courseid); |
927a7808 |
816 | |
b5de723d |
817 | // And now check for special cases |
927a7808 |
818 | $special = false; |
819 | |
b5de723d |
820 | if (substr($text, 0, 5) == 'beep ') { |
6e5f40ea |
821 | /// It's a beep! |
927a7808 |
822 | $special = true; |
7d792369 |
823 | $beepwho = trim(substr($text, 5)); |
9f85bed4 |
824 | |
b5de723d |
825 | if ($beepwho == 'all') { // everyone |
826 | $outinfo = $message->strtime.': '.get_string('messagebeepseveryone', 'chat', fullname($sender)); |
827 | $outmain = ''; |
828 | $output->beep = true; // (eventually this should be set to |
7d792369 |
829 | // to a filename uploaded by the user) |
830 | |
82a524ef |
831 | } else if ($beepwho == $currentuser->id) { // current user |
b5de723d |
832 | $outinfo = $message->strtime.': '.get_string('messagebeepsyou', 'chat', fullname($sender)); |
833 | $outmain = ''; |
7d792369 |
834 | $output->beep = true; |
264867fd |
835 | |
0eda0a46 |
836 | } else { //something is not caught? |
7d792369 |
837 | return false; |
838 | } |
b5de723d |
839 | } else if (substr($text, 0, 1) == '/') { /// It's a user command |
1d507186 |
840 | // support some IRC commands |
841 | $pattern = '#(^\/)(\w+).*#'; |
842 | preg_match($pattern, trim($text), $matches); |
843 | $command = $matches[2]; |
844 | switch ($command){ |
845 | case 'me': |
927a7808 |
846 | $special = true; |
b5de723d |
847 | $outinfo = $message->strtime; |
1d507186 |
848 | $outmain = '*** <b>'.$sender->firstname.' '.substr($text, 4).'</b>'; |
849 | break; |
1515a89e |
850 | } |
7f0483f6 |
851 | } elseif (substr($text, 0, 2) == 'To') { |
852 | $pattern = '#To[[:space:]](.*):(.*)#'; |
853 | preg_match($pattern, trim($text), $matches); |
854 | $special = true; |
855 | $outinfo = $message->strtime; |
856 | $outmain = $sender->firstname.' '.get_string('saidto', 'chat').' <i>'.$matches[1].'</i>: '.$matches[2]; |
927a7808 |
857 | } |
9f85bed4 |
858 | |
927a7808 |
859 | if(!$special) { |
b5de723d |
860 | $outinfo = $message->strtime.' '.$sender->firstname; |
7d792369 |
861 | $outmain = $text; |
1515a89e |
862 | } |
264867fd |
863 | |
9f85bed4 |
864 | /// Format the message as a small table |
1515a89e |
865 | |
b5de723d |
866 | $output->text = strip_tags($outinfo.': '.$outmain); |
7d792369 |
867 | |
5379d249 |
868 | $output->html = "<table class=\"chat-message\"><tr$rowclass><td class=\"picture\" valign=\"top\">$message->picture</td><td class=\"text\">"; |
aa5c32fd |
869 | $output->html .= "<span class=\"title\">$outinfo</span>"; |
7d792369 |
870 | if ($outmain) { |
871 | $output->html .= ": $outmain"; |
6e5f40ea |
872 | $output->basic = '<dl><dt class="title">'.$outinfo.':</dt><dd class="text">'.$outmain.'</dd></dl>'; |
6ee78cee |
873 | } else { |
6e5f40ea |
874 | $output->basic = '<dl><dt class="title">'.$outinfo.'</dt></dl>'; |
7d792369 |
875 | } |
aa5c32fd |
876 | $output->html .= "</td></tr></table>"; |
7d792369 |
877 | return $output; |
b5de723d |
878 | } |
879 | |
848bb113 |
880 | /** |
881 | * @global object |
882 | * @param object $message |
883 | * @param int $courseid |
884 | * @param object $currentuser |
885 | * @param string $chat_lastrow |
886 | * @return bool|string Returns HTML or false |
887 | */ |
aa5c32fd |
888 | function chat_format_message($message, $courseid, $currentuser, $chat_lastrow=NULL) { |
b5de723d |
889 | /// Given a message object full of information, this function |
890 | /// formats it appropriately into text and html, then |
891 | /// returns the formatted data. |
d3bf6f92 |
892 | global $DB; |
b5de723d |
893 | |
78c98892 |
894 | static $users; // Cache user lookups |
895 | |
896 | if (isset($users[$message->userid])) { |
897 | $user = $users[$message->userid]; |
d3bf6f92 |
898 | } else if ($user = $DB->get_record('user', array('id'=>$message->userid), 'id,picture,firstname,lastname')) { |
78c98892 |
899 | $users[$message->userid] = $user; |
900 | } else { |
901 | return NULL; |
b5de723d |
902 | } |
aa5c32fd |
903 | return chat_format_message_manually($message, $courseid, $user, $currentuser, $chat_lastrow); |
1515a89e |
904 | } |
905 | |
848bb113 |
906 | /** |
907 | * @return array |
908 | */ |
f3221af9 |
909 | function chat_get_view_actions() { |
910 | return array('view','view all','report'); |
911 | } |
912 | |
848bb113 |
913 | /** |
914 | * @return array |
915 | */ |
f3221af9 |
916 | function chat_get_post_actions() { |
917 | return array('talk'); |
918 | } |
919 | |
848bb113 |
920 | /** |
921 | * @global object |
922 | * @global object |
923 | * @param array $courses |
924 | * @param array $htmlarray Passed by reference |
925 | */ |
9ca0187e |
926 | function chat_print_overview($courses, &$htmlarray) { |
927 | global $USER, $CFG; |
928 | |
929 | if (empty($courses) || !is_array($courses) || count($courses) == 0) { |
930 | return array(); |
931 | } |
932 | |
933 | if (!$chats = get_all_instances_in_courses('chat',$courses)) { |
934 | return; |
935 | } |
936 | |
937 | $strchat = get_string('modulename', 'chat'); |
938 | $strnextsession = get_string('nextsession', 'chat'); |
9ca0187e |
939 | |
940 | foreach ($chats as $chat) { |
9ca0187e |
941 | if ($chat->chattime and $chat->schedule) { // A chat is scheduled |
a2a37336 |
942 | $str = '<div class="chat overview"><div class="name">'. |
943 | $strchat.': <a '.($chat->visible?'':' class="dimmed"'). |
944 | ' href="'.$CFG->wwwroot.'/mod/chat/view.php?id='.$chat->coursemodule.'">'. |
945 | $chat->name.'</a></div>'; |
946 | $str .= '<div class="info">'.$strnextsession.': '.userdate($chat->chattime).'</div></div>'; |
947 | |
948 | if (empty($htmlarray[$chat->course]['chat'])) { |
949 | $htmlarray[$chat->course]['chat'] = $str; |
950 | } else { |
951 | $htmlarray[$chat->course]['chat'] .= $str; |
952 | } |
9ca0187e |
953 | } |
9ca0187e |
954 | } |
955 | } |
956 | |
0b5a80a1 |
957 | |
958 | /** |
959 | * Implementation of the function for printing the form elements that control |
960 | * whether the course reset functionality affects the chat. |
848bb113 |
961 | * |
962 | * @param object $mform form passed by reference |
0b5a80a1 |
963 | */ |
964 | function chat_reset_course_form_definition(&$mform) { |
965 | $mform->addElement('header', 'chatheader', get_string('modulenameplural', 'chat')); |
966 | $mform->addElement('advcheckbox', 'reset_chat', get_string('removemessages','chat')); |
967 | } |
968 | |
969 | /** |
970 | * Course reset form defaults. |
848bb113 |
971 | * |
972 | * @param object $course |
973 | * @return array |
0b5a80a1 |
974 | */ |
975 | function chat_reset_course_form_defaults($course) { |
976 | return array('reset_chat'=>1); |
977 | } |
978 | |
979 | /** |
980 | * Actual implementation of the rest coures functionality, delete all the |
981 | * chat messages for course $data->courseid. |
848bb113 |
982 | * |
983 | * @global object |
984 | * @global object |
985 | * @param object $data the data submitted from the reset course. |
0b5a80a1 |
986 | * @return array status array |
987 | */ |
988 | function chat_reset_userdata($data) { |
d3bf6f92 |
989 | global $CFG, $DB; |
0b5a80a1 |
990 | |
991 | $componentstr = get_string('modulenameplural', 'chat'); |
992 | $status = array(); |
993 | |
994 | if (!empty($data->reset_chat)) { |
995 | $chatessql = "SELECT ch.id |
d3bf6f92 |
996 | FROM {chat} ch |
997 | WHERE ch.course=?"; |
998 | $params = array($data->courseid); |
0b5a80a1 |
999 | |
d3bf6f92 |
1000 | $DB->delete_records_select('chat_messages', "chatid IN ($chatessql)", $params); |
6e5f40ea |
1001 | $DB->delete_records_select('chat_messages_current', "chatid IN ($chatessql)", $params); |
d3bf6f92 |
1002 | $DB->delete_records_select('chat_users', "chatid IN ($chatessql)", $params); |
0b5a80a1 |
1003 | $status[] = array('component'=>$componentstr, 'item'=>get_string('removemessages', 'chat'), 'error'=>false); |
1004 | } |
1005 | |
1006 | /// updating dates - shift may be negative too |
1007 | if ($data->timeshift) { |
1008 | shift_course_mod_dates('chat', array('chattime'), $data->timeshift, $data->courseid); |
1009 | $status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false); |
1010 | } |
1011 | |
1012 | return $status; |
1013 | } |
1014 | |
f432bebf |
1015 | /** |
1016 | * Returns all other caps used in module |
848bb113 |
1017 | * |
1018 | * @return array |
f432bebf |
1019 | */ |
1020 | function chat_get_extra_capabilities() { |
1021 | return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames'); |
1022 | } |
1023 | |
848bb113 |
1024 | /** |
b2d5a79a |
1025 | * @package mod-chat |
848bb113 |
1026 | * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} |
1027 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
1028 | */ |
47cfd331 |
1029 | class chat_portfolio_caller extends portfolio_module_caller_base { |
848bb113 |
1030 | /** @var object */ |
47cfd331 |
1031 | private $chat; |
848bb113 |
1032 | /** @var int Timestamp */ |
0d06b6fd |
1033 | protected $start; |
848bb113 |
1034 | /** @var int Timestamp */ |
0d06b6fd |
1035 | protected $end; |
848bb113 |
1036 | /** |
1037 | * @return array |
1038 | */ |
0d06b6fd |
1039 | public static function expected_callbackargs() { |
1040 | return array( |
1041 | 'id' => true, |
1042 | 'start' => false, |
1043 | 'end' => false, |
1044 | ); |
1045 | } |
848bb113 |
1046 | /** |
1047 | * @global object |
1048 | */ |
0d06b6fd |
1049 | public function load_data() { |
1050 | global $DB; |
47cfd331 |
1051 | |
0d06b6fd |
1052 | if (!$this->cm = get_coursemodule_from_id('chat', $this->id)) { |
34035201 |
1053 | throw new portfolio_caller_exception('invalidid', 'chat'); |
47cfd331 |
1054 | } |
1055 | $this->chat = $DB->get_record('chat', array('id' => $this->cm->instance)); |
1056 | $select = 'chatid = ?'; |
1057 | $params = array($this->chat->id); |
0d06b6fd |
1058 | if ($this->start && $this->end) { |
47cfd331 |
1059 | $select .= ' AND timestamp >= ? AND timestamp <= ?'; |
0d06b6fd |
1060 | $params[] = $this->start; |
1061 | $params[] = $this->end; |
47cfd331 |
1062 | } |
1063 | $this->messages = $DB->get_records_select( |
1064 | 'chat_messages', |
1065 | $select, |
1066 | $params, |
1067 | 'timestamp ASC' |
1068 | ); |
1069 | $select .= ' AND userid = ?'; |
0d06b6fd |
1070 | $params[] = $this->user->id; |
47cfd331 |
1071 | $this->participated = $DB->record_exists_select( |
1072 | 'chat_messages', |
1073 | $select, |
1074 | $params |
1075 | ); |
0d06b6fd |
1076 | } |
848bb113 |
1077 | /** |
1078 | * @return array |
1079 | */ |
a7d90683 |
1080 | public static function supported_formats() { |
6be1dcae |
1081 | return array(PORTFOLIO_FORMAT_PLAINHTML); |
47cfd331 |
1082 | } |
848bb113 |
1083 | /** |
1084 | * |
1085 | */ |
47cfd331 |
1086 | public function expected_time() { |
d8606b20 |
1087 | return portfolio_expected_time_db(count($this->messages)); |
47cfd331 |
1088 | } |
848bb113 |
1089 | /** |
1090 | * @return string |
1091 | */ |
47cfd331 |
1092 | public function get_sha1() { |
1093 | $str = ''; |
1094 | ksort($this->messages); |
1095 | foreach ($this->messages as $m) { |
1096 | $str .= implode('', (array)$m); |
1097 | } |
1098 | return sha1($str); |
1099 | } |
1100 | |
848bb113 |
1101 | /** |
1102 | * @return bool |
1103 | */ |
47cfd331 |
1104 | public function check_permissions() { |
1105 | $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); |
1106 | return has_capability('mod/chat:exportsession', $context) |
1107 | || ($this->participated |
1108 | && has_capability('mod/chat:exportparticipatedsession', $context)); |
1109 | } |
848bb113 |
1110 | |
1111 | /** |
1112 | * @todo Document this function |
1113 | */ |
47cfd331 |
1114 | public function prepare_package() { |
1115 | $content = ''; |
5a04379a |
1116 | $lasttime = 0; |
1117 | $sessiongap = 5 * 60; // 5 minutes silence means a new session |
47cfd331 |
1118 | foreach ($this->messages as $message) { // We are walking FORWARDS through messages |
5a04379a |
1119 | $m = clone $message; // grrrrrr - this causes the sha1 to change as chat_format_message changes what it's passed. |
47cfd331 |
1120 | $formatmessage = chat_format_message($m, null, $this->user); |
1121 | if (!isset($formatmessage->html)) { |
1122 | continue; |
1123 | } |
5a04379a |
1124 | if (empty($lasttime) || (($message->timestamp - $lasttime) > $sessiongap)) { |
1125 | $content .= '<hr />'; |
1126 | $content .= userdate($message->timestamp); |
1127 | } |
47cfd331 |
1128 | $content .= $formatmessage->html; |
5a04379a |
1129 | $lasttime = $message->timestamp; |
47cfd331 |
1130 | } |
1131 | $content = preg_replace('/\<img[^>]*\>/', '', $content); |
1132 | |
6be1dcae |
1133 | $this->exporter->write_new_file($content, clean_filename($this->cm->name . '-session.html'), false); |
47cfd331 |
1134 | } |
1135 | |
848bb113 |
1136 | /** |
1137 | * @return string |
1138 | */ |
47cfd331 |
1139 | public static function display_name() { |
1140 | return get_string('modulename', 'chat'); |
1141 | } |
1142 | |
848bb113 |
1143 | /** |
1144 | * @global object |
1145 | * @return string |
1146 | */ |
47cfd331 |
1147 | public function get_return_url() { |
1148 | global $CFG; |
1149 | |
1150 | return $CFG->wwwroot . '/mod/chat/report.php?id=' |
1151 | . $this->cm->id . ((isset($this->start)) |
1152 | ? '&start=' . $this->start . '&end=' . $this->end |
1153 | : ''); |
1154 | } |
1155 | } |
1156 | |
42f103be |
1157 | /** |
1158 | * @param string $feature FEATURE_xx constant for requested feature |
1159 | * @return mixed True if module supports feature, null if doesn't know |
1160 | */ |
1161 | function chat_supports($feature) { |
1162 | switch($feature) { |
1163 | case FEATURE_GROUPS: return true; |
1164 | case FEATURE_GROUPINGS: return true; |
1165 | case FEATURE_GROUPMEMBERSONLY: return true; |
dc5c2bd9 |
1166 | case FEATURE_MOD_INTRO: return true; |
42f103be |
1167 | case FEATURE_COMPLETION_TRACKS_VIEWS: return false; |
1168 | case FEATURE_GRADE_HAS_GRADE: return false; |
1169 | case FEATURE_GRADE_OUTCOMES: return true; |
1170 | |
1171 | default: return null; |
1172 | } |
1173 | } |