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