/[drupal]/contributions/modules/chatroom/chatroom.module
ViewVC logotype

Contents of /contributions/modules/chatroom/chatroom.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.66 - (show annotations) (download) (as text)
Thu Oct 29 21:41:18 2009 UTC (4 weeks, 2 days ago) by justinrandell
Branch: MAIN
Changes since 1.65: +518 -743 lines
File MIME type: text/x-php
pulling in changes from dev branch to head
1 <?php
2 // $Id: chatroom.module,v 1.63.2.18 2009/10/29 21:13:48 justinrandell Exp $
3
4 require_once dirname(__FILE__) . '/chatroom.forms.inc';
5 require_once dirname(__FILE__) . '/chatroom.theme.inc';
6
7 /**
8 * @file
9 * Enable chat room support in Drupal.
10 */
11
12 /**
13 * Implementation of hook_help().
14 */
15 function chatroom_help($path, $arg) {
16 switch ($path) {
17 case 'admin/help#chatroom':
18 return '<p />';
19 }
20 }
21
22 /**
23 * Implementation of hook_access().
24 */
25 function chatroom_access($op, $node, $account) {
26 $type = is_object($node) ? $node->type : $node;
27 if ($type == 'chatroom') {
28 if (user_access('administer chat rooms', $account)) {
29 return TRUE;
30 }
31 if ($op == 'create') {
32 return user_access('create chat rooms', $account);
33 }
34 if ($op == 'update' || $op == 'delete') {
35 if (user_access('edit own chat rooms', $account) && ($account->uid == $node->uid)) {
36 return TRUE;
37 }
38 }
39 }
40 else if ($type == 'chat') {
41 if (user_access('administer chats', $account)) {
42 return TRUE;
43 }
44 if ($op == 'create') {
45 return user_access('create chats', $account);
46 }
47 if ($op == 'update' || $op == 'delete') {
48 if (user_access('edit own chats', $account) && ($account->uid == $node->uid)) {
49 return TRUE;
50 }
51 }
52 }
53 return FALSE;
54 }
55
56 /**
57 * Implementation of hook_perm().
58 */
59 function chatroom_perm() {
60 return array('access chat rooms', 'create chat rooms', 'edit own chat rooms', 'administer chats', 'administer chat rooms', 'create chats');
61 }
62
63 /**
64 * Implementation of hook_menu().
65 */
66 function chatroom_menu() {
67 $items['admin/settings/chatroom'] = array(
68 'title' => 'Chat room',
69 'description' => t('Configure global settings for chat rooms and chats.'),
70 'page callback' => 'drupal_get_form',
71 'page arguments' => array('chatroom_admin_settings'),
72 'access arguments' => array('administer chat rooms'),
73 );
74 $items['chatroom/kicked'] = array(
75 'type' => MENU_CALLBACK,
76 'page callback' => 'chatroom_chat_kicked_user',
77 'page arguments' => array(2),
78 'access arguments' => array('access chat rooms'),
79 );
80 $items['chatroom/chat/post/message/%node/%'] = array(
81 'page callback' => 'chatroom_chat_post_message',
82 'page arguments' => array(4, 5),
83 'access arguments' => array('access chat rooms'),
84 'type' => MENU_CALLBACK,
85 );
86 $items['chatroom/chat/get/latest/messages/%node/%'] = array(
87 'page callback' => 'chatroom_chat_get_latest_messages',
88 'page arguments' => array(5, 6),
89 'access arguments' => array('access chat rooms'),
90 'type' => MENU_CALLBACK,
91 );
92 return $items;
93 }
94
95 /**
96 * Implementation of hook_node_info().
97 */
98 function chatroom_node_info() {
99 return array(
100 'chatroom' => array(
101 'name' => t('Chat room'),
102 'module' => 'chatroom',
103 'description' => t('A chat room provides access to chats and chat archives.'),
104 ),
105 'chat' => array(
106 'name' => t('Chat'),
107 'module' => 'chatroom_chat',
108 'description' => t('A chat provides the chat interface.'),
109 ),
110 );
111 }
112
113 /**
114 * Implementation of hook_insert().
115 */
116 function chatroom_insert($node) {
117 $chatroom = array(
118 'nid' => $node->nid,
119 'poll_freq' => $node->poll_freq,
120 'idle_freq' => $node->idle_freq,
121 'kicked_out_message' => $node->kicked_out_message,
122 'banned_message' => $node->banned_message,
123 'module' => isset($node->module) ? $node->module : 'chatroom',
124 'previous_messages_display_count' => $node->previous_messages_display_count,
125 'popout' => $node->popout,
126 'profile_picture' => $node->profile_picture,
127 );
128 drupal_write_record('chatroom', $chatroom);
129 }
130
131 /**
132 * Implementation of hook_update().
133 */
134 function chatroom_update($node) {
135 $chatroom = array(
136 'nid' => $node->nid,
137 'poll_freq' => $node->poll_freq,
138 'idle_freq' => $node->idle_freq,
139 'kicked_out_message' => $node->kicked_out_message,
140 'banned_message' => $node->banned_message,
141 'module' => isset($node->module) ? $node->module : 'chatroom',
142 'previous_messages_display_count' => $node->previous_messages_display_count,
143 'popout' => $node->popout,
144 'profile_picture' => $node->profile_picture,
145 );
146 drupal_write_record('chatroom', $chatroom, 'nid');
147 }
148
149 /**
150 * Implementation of hook_delete().
151 */
152 function chatroom_delete(&$node) {
153 db_query('DELETE FROM {chatroom} WHERE nid = %d', $node->nid);
154 db_query("DELETE FROM {chatroom_chat} WHERE crid = %d", $node->nid);
155 db_query('DELETE FROM {chatroom_ban_list} WHERE nid = %d', $node->nid);
156 if (!empty($node->chats)) {
157 $ccids = implode(',', array_keys($node->chats));
158 db_query('DELETE FROM {chatroom_msg} WHERE ccid IN (%s)', $ccids);
159 db_query('DELETE FROM {chatroom_online_list} WHERE ccid IN (%s)', $ccids);
160 }
161 }
162
163 /**
164 * Implementation of hook_load().
165 */
166 function chatroom_load($node) {
167 $room = new StdClass();
168 if ($room->chatroom = db_fetch_object(db_query('SELECT * FROM {chatroom} WHERE nid = %d', $node->nid))) {
169 $room->chatroom->banned_users = chatroom_get_banned_users($node);
170 // If the user is banned, don't load chats.
171 if (chatroom_is_banned_user($node)) {
172 return $chatroom;
173 }
174 $room->chatroom->chats = chatroom_load_chats($node->nid);
175 }
176 return $room;
177 }
178
179 /**
180 * Load chats for a given chatroom.
181 *
182 * @param mixed $nid
183 * @return array - a list of chats.
184 */
185 function chatroom_load_chats($nid) {
186 $chats = array();
187 $cmids = array();
188
189 $sql = "SELECT cc.*, n.title, 0 last_cmid, 0 msg_count, NULL last_msg
190 FROM {chatroom_chat} cc
191 INNER JOIN {node} n ON n.nid = cc.nid
192 WHERE cc.crid = %d";
193 $result = db_query($sql, $nid);
194 while ($chat = db_fetch_object($result)) {
195 $chats[$chat->nid] = $chat;
196 }
197
198 // Load the message count info.
199 if (!empty($chats)) {
200 $ccids = array_keys($chats);
201 $sql = "SELECT ccid, COUNT(*) msg_count, MAX(cmid) last_cmid
202 FROM {chatroom_msg}
203 WHERE ccid IN (" . db_placeholders($ccids) . ")
204 GROUP BY ccid";
205 $result = db_query($sql, $ccids);
206 while ($count = db_fetch_object($result)) {
207 $chats[$count->ccid]->msg_count = $count->msg_count;
208 $chats[$count->ccid]->last_cmid = $count->last_cmid;
209 $cmids[] = $count->last_cmid;
210 }
211 }
212
213 // Fetch the last message if there is one.
214 if (!empty($cmids)) {
215 // Note we join on the session not the uid, because anon users all have
216 // the same uid.
217 $sql = "SELECT cm.*, u.name, col.guest_id
218 FROM {chatroom_msg} cm
219 INNER JOIN {chatroom_chat_online_list} col ON col.sid = cm.sid
220 INNER JOIN {users} u ON u.uid = col.uid
221 WHERE cm.cmid IN (" . db_placeholders($cmids) . ")";
222 $result = db_query($sql, $cmids);
223 while ($message = db_fetch_object($result)) {
224 $chats[$message->ccid]->last_msg = $message;
225 }
226 }
227 return $chats;
228 }
229
230 /**
231 * Chatroom chat node hook functions.
232 */
233 /**
234 * Implementation of hook_insert().
235 */
236 function chatroom_chat_insert($node) {
237 $chat = array(
238 'nid' => $node->nid,
239 'crid' => isset($node->crid) ? $node->crid : 0,
240 'poll_freq' => $node->poll_freq,
241 'idle_freq' => $node->idle_freq,
242 'kicked_out_message' => $node->kicked_out_message,
243 'banned_message' => $node->banned_message,
244 'module' => isset($node->module) ? $node->module : 'chatroom',
245 'previous_messages_display_count' => $node->previous_messages_display_count,
246 'popout' => $node->popout,
247 'profile_picture' => $node->profile_picture,
248 );
249 drupal_write_record('chatroom_chat', $chat);
250 }
251
252 /**
253 * Implementation of hook_update().
254 */
255 function chatroom_chat_update($node) {
256 $chat = array(
257 'nid' => $node->nid,
258 'crid' => isset($node->crid) ? $node->crid : 0,
259 'poll_freq' => $node->poll_freq,
260 'idle_freq' => $node->idle_freq,
261 'kicked_out_message' => $node->kicked_out_message,
262 'banned_message' => $node->banned_message,
263 'module' => isset($node->module) ? $node->module : 'chatroom',
264 'previous_messages_display_count' => $node->previous_messages_display_count,
265 'popout' => $node->popout,
266 'profile_picture' => $node->profile_picture,
267 );
268 drupal_write_record('chatroom_chat', $chat, 'nid');
269 }
270
271 /**
272 * Implementation of hook_delete().
273 */
274 function chatroom_chat_delete(&$node) {
275 db_query('DELETE FROM {chatroom_chat} WHERE nid = %d', $node->nid);
276 db_query('DELETE FROM {chatroom_chat_online_list} WHERE ccid = %d', $node->nid);
277 }
278
279 /**
280 * Implementation of hook_load().
281 */
282 function chatroom_chat_load($node) {
283 $chat = new StdClass();
284 if ($chat->chat = db_fetch_object(db_query("SELECT * FROM {chatroom_chat} WHERE nid = %d", $node->nid))) {
285 $chat->chat->chatroom = node_load($chat->chat->crid);
286 $chat->chat->latest_msg = chatroom_chat_get_latest_message($node->nid);
287 $chat->chat->msg_count = chatroom_chat_get_message_count($node->nid);
288 return $chat;
289 }
290 }
291
292 /**
293 * Get the latest message id for a given chat.
294 *
295 * @param mixed $chat_id
296 */
297 function chatroom_chat_get_latest_message($chat_id) {
298 $sql = "SELECT cm.*, u.name
299 FROM {chatroom_msg} cm
300 INNER JOIN {users} u ON u.uid = cm.uid
301 WHERE ccid = %d
302 ORDER BY cmid
303 DESC LIMIT 1";
304 return db_fetch_object(db_query($sql, $chat_id));
305 }
306
307 /**
308 * Get the message count for a chat.
309 */
310 function chatroom_chat_get_message_count($chat_id) {
311 $sql = "SELECT COUNT(*) FROM {chatroom_msg} WHERE ccid = %d";
312 return db_result(db_query($sql, $chat_id));
313 }
314
315 /**
316 * Implementation of hook_view().
317 */
318 function chatroom_view($node, $teaser = FALSE, $page = FALSE) {
319 $node = node_prepare($node);
320 if (!$teaser && $page) {
321 // if the user is banned, just tell them why
322 if (chatroom_is_banned_user($node)) {
323 $node->content['body']['#value'] = !empty($node->banned_message) ? $node->banned_message : t('You have been banned from %chatroom.', array('%chatroom' => $node->title));
324 }
325 else {
326 // if the user can create chats, show the form
327 if (user_access('create chats')) {
328 $node->content['add_chat'] = array(
329 '#value' => drupal_get_form('chatroom_create_chat_form', $node),
330 '#weight' => 1,
331 );
332 }
333
334 // if there are some chats, build some tables to display them
335 if (!empty($node->chatroom->chats)) {
336 foreach ($node->chatroom->chats as $chat) {
337 if ($chat->when_archived) {
338 $rows['archived'][] = array(
339 array('data' => l($chat->title, "node/$chat->nid")),
340 array('data' => isset($chat->msg_count) ? $chat->msg_count : 0),
341 array('data' => t('Archived on !date.', array('!date' => format_date($chat->when_archived, 'medium')))),
342 );
343 }
344 else {
345 $rows['open'][] = array(
346 array('data' => l($chat->title, "node/$chat->nid")),
347 array('data' => isset($chat->msg_count) ? $chat->msg_count : 0),
348 array('data' => $chat->last_msg ? theme('chatroom_latest_message', $chat->last_msg) : ('No messages.')),
349 );
350 }
351 }
352 if (!empty($rows['open'])) {
353 $node->content['open_chats']['#weight'] = 2;
354 $node->content['open_chats']['title'] = array(
355 '#value' => '<h2>'. t('Open chats in this room') .'</h2>',
356 '#weight' => 0,
357 );
358 $node->content['open_chats']['table'] = array(
359 '#value' => theme('table', array(t('Chat name'), t('Message count'), t('Last message')), $rows['open']),
360 '#weight' => 1,
361 );
362 }
363 if (!empty($rows['archived'])) {
364 $node->content['archived_chats']['#weight'] = 3;
365 $node->content['archived_chats']['header'] = array(
366 '#value' => '<h2>'. t('Archived chats in this room') .'</h2>',
367 '#weight' => 0,
368 );
369 $node->content['archived_chats']['table'] = array(
370 '#value' => theme('table', array(t('Chat name'), t('Message count'), t('When archived')), $rows['archived']),
371 '#weight' => 1,
372 );
373 }
374 }
375 }
376 }
377 else {
378 $node->content['teaser'] = array('#value' => theme('chatroom_teaser', $node));
379 }
380 return $node;
381 }
382
383 /**
384 * Implementation of hook_view().
385 */
386 function chatroom_chat_view($node, $teaser = FALSE, $page = FALSE) {
387 $node = node_prepare($node);
388 if (!$teaser && $page) {
389 drupal_add_css(drupal_get_path('module', 'chatroom') .'/chatroom.css');
390
391 $bc = drupal_get_breadcrumb();
392 if ($node->chat->chatroom) {
393 $bc[] = l($node->chat->chatroom->title, "node/{$node->chat->chatroom->nid}");
394 }
395 $bc[] = l($node->title, "node/$node->nid");
396 drupal_set_breadcrumb($bc);
397
398 // Display a message if the user is banned.
399 if (chatroom_is_banned_user($node)) {
400 $content = theme('chatroom_chat_banned_user', $node);
401 }
402 elseif (!isset($node->chat->when_archived)) {
403 if (!chatroom_chat_register_user($node)) {
404 chatroom_update_last_seen_time($node, session_id());
405 }
406 $node->chat->users = chatroom_load_online_users($node);
407 chatroom_add_js($node);
408 $content = theme('chatroom_chat', $node);
409 }
410 else {
411 $content = theme('chatroom_chat_archive', $node);
412 if (user_access('administer chat rooms')) {
413 $content .= drupal_get_form('chatroom_unarchive_chat_form', $node->nid);
414 }
415 }
416 $node->content['chatroom_chat_interface'] = array('#value' => $content);
417 }
418 else {
419 $node->content['teaser'] = array('#value' => theme('chatroom_chat_teaser', $node));
420 }
421 return $node;
422 }
423
424 /**
425 * Gets a list of banned users for a given chat room.
426 */
427 function chatroom_get_banned_users($room) {
428 $banned_users = array();
429 $result = db_query("
430 SELECT bl.uid, u.name FROM {chatroom_ban_list} bl
431 INNER JOIN {users} u ON u.uid = bl.uid
432 WHERE bl.nid = %d
433 ", $room->nid);
434 while ($user = db_fetch_object($result)) {
435 $banned_users[$user->uid] = $user;
436 }
437 return $banned_users;
438 }
439
440 /**
441 * Unarchive old chat.
442 */
443 function chatroom_unarchive_chat($chat_id) {
444 $result = db_query('UPDATE {chatroom_chat} SET when_archived = NULL WHERE nid = %d', $chat_id);
445 return $result;
446 }
447
448 /**
449 * Archive a chat.
450 */
451 function chatroom_archive_chat($chat_id) {
452 $result = db_query('UPDATE {chatroom_chat} SET when_archived = %d WHERE nid = %d', time(), $chat_id);
453 return $result;
454 }
455
456 /**
457 * Implementation of hook_block().
458 */
459 function chatroom_block($op = 'list', $delta = 0, $edit = array()) {
460 $types = array('chats', 'rooms', 'chat_users', 'site_users');
461
462 switch ($op) {
463 case 'list':
464 $blocks[0] = array(
465 'info' => t('Chat room: active chats'),
466 'cache' => BLOCK_CACHE_GLOBAL,
467 'visibility' => 0,
468 'pages' => 'chatroom',
469 );
470 $blocks[1] = array(
471 'info' => t('Chat room: active chat rooms'),
472 'cache' => BLOCK_CACHE_GLOBAL,
473 'visibility' => 0,
474 'pages' => 'chatroom',
475 );
476 $blocks[2] = array(
477 'info' => t('Chat room: chat user list'),
478 'cache' => BLOCK_CACHE_PER_PAGE,
479 'visibility' => 1,
480 'pages' => 'chatroom/chat/*',
481 );
482 $blocks[3] = array(
483 'info' => t('Chat room: site-wide user list'),
484 'cache' => BLOCK_CACHE_GLOBAL,
485 );
486 return $blocks;
487
488 case 'configure':
489 switch ($types[$delta]) {
490 case 'chats':
491 $items = t('chats');
492 break;
493 case 'chat_rooms':
494 $items = t('chat rooms');
495 }
496 if (isset($items)) {
497 $form["chatroom_block_{$types[$delta]}"] = array(
498 '#type' => 'select',
499 '#title' => t('Number of !items to display', array('!items' => $items)),
500 '#default_value' => variable_get("chatroom_block_{$types[$delta]}", 5),
501 '#options' => drupal_map_assoc(range(1, 15))
502 );
503 return $form;
504 }
505 break;
506
507 case 'save':
508 variable_set("chatroom_block_{$types[$delta]}", $edit["chatroom_block_{$types[$delta]}"]);
509 break;
510
511 case 'view':
512 if (user_access('access chat rooms')) {
513 switch ($types[$delta]) {
514 case 'chat_users':
515 return theme('chatroom_block_chat_users', chatroom_load_chat(arg(2)));
516
517 default:
518 return theme("chatroom_block_{$types[$delta]}");
519 }
520 }
521 }
522 }
523
524 /**
525 * Get a list of active chats.
526 */
527 function chatroom_get_active_chats($start = NULL, $end = NULL, $save_query = TRUE) {
528 global $user;
529 $sql = "
530 SELECT cc.*, nr.title AS room_name, cr.nid
531 FROM {chatroom_chat} cc
532 INNER JOIN {chatroom} cr ON cr.nid = cc.crid
533 INNER JOIN {node_revisions} nr ON nr.nid = cr.nid
534 INNER JOIN {node} n ON n.nid = nr.nid
535 WHERE cc.when_archived IS NULL
536 ORDER BY cc.modified DESC
537 ";
538 if ($save_query) {
539 $sql = db_rewrite_sql($sql);
540 variable_set("chatroom_get_active_chats_query_{$user->uid}", $sql);
541 }
542 else {
543 $sql = variable_get("chatroom_get_active_chats_query_{$user->uid}", $sql);
544 }
545 if (isset($start) && isset($end)) {
546 $result = db_query_range($sql, $start, $end);
547 }
548 else {
549 $result = db_query($sql);
550 }
551 $chats = array();
552 while ($chat = db_fetch_object($result)) {
553 $chats[] = $chat;
554 }
555 if (!empty($chats)) {
556 return $chats;
557 }
558 return FALSE;
559 }
560
561 /**
562 * tells a kicked out user not to be a knob
563 */
564 function chatroom_chat_kicked_user($chat_id = FALSE) {
565 if ($chat = node_load($chat_id)) {
566 if (isset($chat->when_archived)) {
567 drupal_goto("chatrooms/chat/$chat_id", NULL, NULL, 301);
568 }
569 else {
570 if (chatroom_is_banned_user($chat)) {
571 $content = theme('chatroom_chat_banned_user', $chat);
572 }
573 else {
574 $content = theme('chatroom_chat_kicked_user', $chat);
575 }
576 return $content;
577 }
578 }
579 else {
580 drupal_not_found();
581 }
582 }
583
584 /**
585 * Move old messages to archive.
586 */
587 function chatroom_archive_old_msgs($chat_id) {
588 db_query("UPDATE {chatroom_msg} set archived = 1 WHERE ccid = %d", $chat_id);
589 }
590
591 /**
592 * Register a user in a chat.
593 */
594 function chatroom_chat_register_user($node) {
595 global $user;
596
597 $session_id = session_id();
598 if (!db_result(db_query("SELECT sid FROM {chatroom_chat_online_list} WHERE ccid = %d AND sid = '%s'", $node->nid, $session_id))) {
599 $params = array($node->nid, $user->uid, $session_id, time());
600 if ($user->uid) {
601 $sql = "INSERT INTO {chatroom_chat_online_list} (ccid, uid, sid, last_seen_time) VALUES (%d, %d, '%s', %d)";
602 }
603 else {
604 $sql = "INSERT INTO {chatroom_chat_online_list} (ccid, uid, sid, guest_id, last_seen_time)
605 SELECT %d, %d, '%s', COALESCE(MAX(guest_id) + 1, 1), %d
606 FROM {chatroom_chat_online_list}
607 WHERE ccid = %d";
608 $params[] = $node->nid;
609 }
610 return db_query($sql, $params);
611 }
612 return FALSE;
613 }
614
615 /**
616 * Add settings to chat page.
617 */
618 function chatroom_add_js($node) {
619 global $user;
620 $js = array(
621 'pollInterval' => (int) isset($node->chat) ? $node->chat->poll_freq : 1,
622 'idleInterval' => (int) $node->chat->idle_freq,
623 'chatId' => (int) $node->nid,
624 'cacheDirectory' => variable_get('chatroom_cache_directory', '/tmp'),
625 'postMessagePath' => 'chatroom/chat/post/message',
626 'chatPath' => 'node/' . $node->nid,
627 'successiveCacheHits' => 0,
628 'skipCacheCheckCount' => 5,
629 'latestMsgId' => $node->chat->latest_msg ? $node->chat->latest_msg->cmid : 0,
630 );
631
632 if (variable_get('configurable_timezones', 1) && $user->uid && drupal_strlen($user->timezone)) {
633 $js['timezone'] = $user->timezone;
634 }
635 else {
636 $js['timezone'] = variable_get('date_default_timezone', 0);
637 }
638 if (isset($node->chat, $node->chat->latest_msg_id)) {
639 $js['latestMsgId'] = $node->chat->latest_msg_id;
640 }
641
642 // Allow modules to alter the js settings sent down for a chat.
643 drupal_alter('chatroom_js_settings', $js);
644
645 drupal_add_js(drupal_get_path('module', 'chatroom') . '/chatroom.js');
646 drupal_add_js(array('chatroom' => $js), 'setting');
647 }
648
649 /**
650 * Get messages for a given chat.
651 *
652 * @param $chat_id
653 * The chat id.
654 * @param $last_cmid
655 * Only load messages with cmids greater than this value.
656 * @param $limit
657 * Default: FALSE.
658 * @return array $messages
659 */
660 function chatroom_chat_load_messages($chat_id, $last_cmid = 0, $limit = FALSE) {
661 global $user;
662
663 $sql = "SELECT cm.*
664 FROM {chatroom_msg} cm
665 WHERE cm.ccid = %d
666 AND cm.cmid > %d
667 ORDER BY cm.cmid ASC";
668 $args = array($chat_id, $last_cmid);
669
670 if ($limit) {
671 $sql .= ' LIMIT %d';
672 $args[] = $limit;
673 }
674
675 // Give modules a chance to modify query.
676 $result = db_query(db_rewrite_sql($sql, 'cm', 'cmid', array('chatroom_msg' => TRUE)), $args);
677
678 $messages = array();
679 $uids = array();
680 $guest_sids = array();
681 while ($message = db_fetch_object($result)) {
682 $message->guest_id = 0;
683 $message->name = '';
684 $messages[$message->cmid] = $message;
685 if ($message->uid > 0 && !in_array($message->uid, $uids)) {
686 $uids[] = $message->uid;
687 }
688 if ($message->uid == 0 && !in_array($message->sid, $guest_sids)) {
689 $guest_sids[] = $message->sid;
690 }
691 }
692
693 if (!empty($uids)) {
694 $sql = "SELECT uid, name FROM {users} WHERE uid IN (" . db_placeholders($uids) . ")";
695 $result = db_query($sql, $uids);
696 while ($chat_user = db_fetch_object($result)) {
697 foreach ($messages as $message) {
698 if ($message->uid == $chat_user->uid) {
699 $messages[$message->cmid]->name = $chat_user->name;
700 }
701 }
702 }
703 }
704 if (!empty($guest_sids)) {
705 $sql = "SELECT sid, guest_id FROM {chatroom_chat_online_list} WHERE sid IN (" . db_placeholders($guest_sids, 'varchar') . ")";
706 $result = db_query($sql, $guest_sids);
707 while ($guest = db_fetch_object($result)) {
708 foreach ($messages as $message) {
709 if ($message->sid == $guest->sid) {
710 $messages[$message->cmid]->guest_id = $guest->guest_id;
711 $messages[$message->cmid]->name = variable_get('chatroom_guest_user_prefix', 'guest-') . $guest->guest_id;
712 }
713 }
714 }
715 }
716 return $messages;
717 }
718
719 /**
720 * Load online users for the given chat.
721 */
722 function chatroom_load_online_users($chat) {
723 global $user;
724
725 $sql = "SELECT col.*, u.name, u.picture
726 FROM {chatroom_chat_online_list} col
727 LEFT JOIN {users} u ON u.uid = col.uid
728 WHERE col.ccid = %d
729 AND col.last_seen_time >= %d
730 ORDER BY u.name ASC";
731 $sql = db_rewrite_sql($sql, 'col', 'sid', array('chatroom_chat_online_list' => TRUE));
732 $result = db_query($sql, $chat->nid, time() - variable_get('chatroom_online_list_timeout', 10));
733 $users = array();
734 while ($u = db_fetch_object($result)) {
735 if ($u->uid == 0) {
736 $u->name = variable_get('chatroom_guest_user_prefix', 'guest-') . $u->guest_id;
737 }
738 $users[$u->sid] = $u;
739 }
740 return $users;
741 }
742
743 /**
744 * updates chat's cache file modified time
745 */
746 function chatroom_chat_update_cache($chat_id, $latest_msg_id) {
747 $cache_file = variable_get('chatroom_cache_directory', '/tmp') . '/chatroom.chat.' . $chat_id . '.cache';
748 file_put_contents($cache_file, "$latest_msg_id\n");
749 }
750
751 /**
752 * gets a list of online users, not including the current user
753 */
754 function chatroom_get_site_online_list($uid) {
755 $users = array();
756 $result = db_query("SELECT uid, name FROM {users} WHERE access >= %d AND uid <> 0", time() - variable_get('session_write_interval', 180));
757 while ($user = db_fetch_object($result)) {
758 if ($uid != $user->uid) {
759 $users[] = $user;
760 }
761 }
762 return $users;
763 }
764
765 /**
766 * Check if the current user is banned from the chat room.
767 */
768 function chatroom_is_banned_user($room) {
769 global $user;
770 // If the node is already loaded, check the ban list. Otherwise, query the
771 // database.
772 if (isset($room->banned_list) && is_array($room->banned_list)) {
773 return in_array($user->uid, array_keys($room->banned_list));
774 }
775 else {
776 return db_result(db_query("SELECT nid FROM {chatroom_ban_list} WHERE nid = %d AND uid = %d", $room->nid, $user->uid));
777 }
778 }
779
780 /**
781 * Get the latest messages for a chat, and send back to the client.
782 */
783 function chatroom_chat_get_latest_messages($node, $last_msg_id) {
784 global $user;
785
786 $response['messages'] = array();
787 if ($node->chat->when_archived) {
788 $response['archived'] = $node->chat->when_archived;
789 drupal_set_message(t('This chat has been archived.'));
790 }
791 else {
792 chatroom_update_last_seen_time($node, session_id());
793
794 foreach (chatroom_chat_load_messages($node->nid, $last_msg_id) as $message) {
795 $msg = new StdClass();
796 $msg->html = theme('chatroom_message', $message);
797 $msg->text = strip_tags($message->msg);
798 $msg->name = $message->name;
799 $msg->cmid = $message->cmid;
800 $response['messages'][] = $msg;
801 $latest_msg_id = $message->cmid;
802 }
803 if (isset($latest_msg_id)) {
804 chatroom_chat_update_cache($node->nid, $latest_msg_id);
805 }
806
807 $response['usersHtml'] = theme('chatroom_user_list', chatroom_load_online_users($node), $node);
808 }
809 print drupal_to_js(array('data' => $response));
810 }
811
812 /**
813 * Posted messages are handled here.
814 *
815 * @return void
816 */
817 function chatroom_chat_post_message($node, $last_msg_id) {
818 global $user;
819
820 // Check we have a message posted.
821 if (!isset($_POST['message'])) {
822 exit;
823 }
824
825 // Write the message to the chat.
826 $message = array(
827 'ccid' => $node->chat->nid,
828 'uid' => $user->uid,
829 'msg' => $_POST['message'],
830 'sid' => session_id(),
831 'type' => chatroom_chat_get_message_type($_POST['message']),
832 'recipient_uid' => isset($_POST['recipient_uid']) ? $_POST['recipient_uid'] : 0,
833 );
834 if ($msg_id = chatroom_chat_save_message($message, $node)) {
835 chatroom_chat_get_latest_messages($node, $msg_id - 1);
836 }
837 }
838
839 /**
840 * Write a message into a chat, and allow any interested modules to react.
841 *
842 * @param array $message
843 * @param StdClass $node
844 * @return boolean
845 */
846 function chatroom_chat_save_message($message, $node) {
847 drupal_alter('chatroom_chat_msg', $message);
848 if (drupal_write_record('chatroom_msg', $message)) {
849 $node->chat->latest_msg_id = $message['cmid'];
850 if ($message['type'] == 'command') {
851 chatroom_chat_call_command($message, $node);
852 }
853 else {
854 foreach (module_implements('chat_msg_saved') as $module) {
855 $function = $module . '_chat_msg_saved';
856 $function($message, $node);
857 }
858 }
859 return $message['cmid'];
860 }
861 return FALSE;
862 }
863
864 /**
865 * Try to invoke a command.
866 *
867 * @param mixed $message
868 * @param mixed $node
869 */
870 function chatroom_chat_call_command($message, $node) {
871 $commands = module_invoke_all('chat_commands');
872 $command = chatroom_chat_parse_command($message['message']);
873 if ($command && isset($commands[$command->name])) {
874 call_user_func_array($callback, array($command, $node));
875 }
876 foreach (module_implements('chat_command_api') as $module) {
877 $function = $module . '_chat_command_api';
878 $function($command, $node);
879 }
880 }
881
882 /**
883 * Parse out the command name and any arguments from a chat message.
884 *
885 * @param mixed $message
886 * @return array
887 */
888 function chatroom_chat_parse_command($message) {
889 $command = new StdClass();
890 $command->args = array();
891 $command->name = FALSE;
892 $command_regex = variable_get('chatroom_chat_command_prefix', '/') . '([^a-z_0-9]+)(.*)';
893 if (preg_match("#^$command_regex$#", $message, $matches)) {
894 $command->name = $matches[1];
895 if (isset($matches[2])) {
896 $command->args = explode(' ', $matches[2]);
897 }
898 }
899 return $command->name ? $command : FALSE;
900 }
901
902 /**
903 * Figure out what sort of message this is.
904 *
905 * @param mixed $message
906 * @return void
907 */
908 function chatroom_chat_get_message_type($message) {
909 if (preg_match('#^' . variable_get('chatroom_chat_command_prefix', '/') . '#', $message)) {
910 return 'command';
911 }
912 return 'message';
913 }
914
915 /**
916 * Update the last seen time for a the given session id in the given chat.
917 *
918 * @param mixed $node
919 * @param mixed $session_id
920 * @return void
921 */
922 function chatroom_update_last_seen_time($node, $session_id) {
923
924 $sql = "UPDATE {chatroom_chat_online_list}
925 SET last_seen_time = %d
926 WHERE ccid = %d AND sid = '%s'";
927 db_query($sql, time(), $node->nid, $session_id);
928 }
929

  ViewVC Help
Powered by ViewVC 1.1.2