/** * Standard modular run function for realtime-rain hooks. * * @param TIME Start of time range. * @param TIME End of time range. * @return array A list of template parameter sets for rendering a 'drop'. */ function run($from, $to) { $drops = array(); if (has_actual_page_access(get_member(), 'chat')) { require_code('chat'); $rows = $GLOBALS['SITE_DB']->query('SELECT ip_address,the_message,user_id AS member_id,date_and_time AS timestamp,room_id FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'chat_messages WHERE system_message=0 AND date_and_time BETWEEN ' . strval($from) . ' AND ' . strval($to)); foreach ($rows as $row) { if (!check_chatroom_access($row['room_id'], true)) { continue; } $timestamp = $row['timestamp']; $member_id = $row['member_id']; $message = get_translated_text($row['the_message']); if (strpos($message, '[private') !== false) { continue; } $message = strip_comcode($message); if ($message == '') { continue; } $drops[] = rain_get_special_icons($row['ip_address'], $timestamp, NULL, $message) + array('TYPE' => 'chat', 'FROM_MEMBER_ID' => strval($member_id), 'TO_MEMBER_ID' => NULL, 'TITLE' => rain_truncate_for_title($message), 'IMAGE' => is_guest($member_id) ? rain_get_country_image($row['ip_address']) : $GLOBALS['FORUM_DRIVER']->get_member_avatar_url($member_id), 'TIMESTAMP' => strval($timestamp), 'RELATIVE_TIMESTAMP' => strval($timestamp - $from), 'TICKER_TEXT' => $message, 'URL' => build_url(array('page' => 'points', 'type' => 'member', 'id' => $member_id), '_SEARCH'), 'IS_POSITIVE' => false, 'IS_NEGATIVE' => false, 'FROM_ID' => 'member_' . strval($member_id), 'TO_ID' => NULL, 'GROUP_ID' => 'room_' . strval($row['room_id'])); } } return $drops; }
/** * Standard modular run function. * * @param array A map of parameters. * @return tempcode The result of execution. */ function run($map) { require_lang('chat'); require_css('side_blocks'); $room_id = array_key_exists('param', $map) ? intval($map['param']) : NULL; $num_messages = array_key_exists('max', $map) ? intval($map['max']) : 5; if (is_null($room_id)) { $room_id = $GLOBALS['SITE_DB']->query_value_null_ok('chat_rooms', 'MIN(id)', array('is_im' => 0)); if (is_null($room_id)) { return new ocp_tempcode(); } } $room_check = $GLOBALS['SITE_DB']->query_select('chat_rooms', array('*'), array('id' => $room_id), '', 1); if (!array_key_exists(0, $room_check)) { return new ocp_tempcode(); } require_code('chat'); if (!check_chatroom_access($room_check[0], true)) { global $DO_NOT_CACHE_THIS; // We don't cache against access, so we have a problem and can't cache $DO_NOT_CACHE_THIS = true; return new ocp_tempcode(); } $content = NULL; if (get_value('no_frames') === '1') { $content = shoutbox_script(true, $room_id, $num_messages); } return do_template('BLOCK_SIDE_SHOUTBOX_IFRAME', array('CONTENT' => $content, 'ROOM_ID' => strval($room_id), 'NUM_MESSAGES' => strval($num_messages))); }
/** * Standard modular run function for RSS hooks. * * @param string A list of categories we accept from * @param TIME Cutoff time, before which we do not show results from * @param string Prefix that represents the template set we use * @set RSS_ ATOM_ * @param string The standard format of date to use for the syndication type represented in the prefix * @param integer The maximum number of entries to return, ordering by date * @return ?array A pair: The main syndication section, and a title (NULL: error) */ function run($_filters, $cutoff, $prefix, $date_string, $max) { if (!addon_installed('chat')) { return NULL; } if (!has_actual_page_access(get_member(), 'chat')) { return NULL; } $filters = ocfilter_to_sqlfragment($_filters, 'room_id', 'chat_rooms', NULL, 'room_id', 'id'); // Note that the parameters are fiddled here so that category-set and record-set are the same, yet SQL is returned to deal in an entirely different record-set (entries' record-set) require_code('chat'); $rows = $GLOBALS['SITE_DB']->query('SELECT m.* FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'chat_messages m LEFT JOIN ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'chat_rooms r ON r.id=m.room_id WHERE r.is_im=0 AND date_and_time>' . strval(time() - $cutoff) . ' AND ' . $filters . ' ORDER BY date_and_time DESC', $max); $count = $GLOBALS['SITE_DB']->query_value('chat_rooms', 'COUNT(*)', array('is_im' => 0)); $categories = array(); if ($count < 100) { $_categories = $GLOBALS['SITE_DB']->query_select('chat_rooms', array('*'), array('is_im' => 0)); foreach ($_categories as $category) { $categories[$category['id']] = $category; } } $content = new ocp_tempcode(); foreach ($rows as $row) { if (!array_key_exists($row['room_id'], $categories) && $count >= 100) { $_categories = $GLOBALS['SITE_DB']->query_select('chat_rooms', array('*'), array('id' => $row['room_id']), '', 1); if (array_key_exists(0, $_categories)) { $categories[$row['room_id']] = $_categories[0]; } } if (!array_key_exists($row['room_id'], $categories)) { continue; } // Message is in deleted room (although should not exist in DB anymore!) if (check_chatroom_access($categories[$row['room_id']], true)) { $id = strval($row['id']); $author = $GLOBALS['FORUM_DRIVER']->get_username($row['user_id']); if (is_null($author)) { $author = ''; } $news_date = date($date_string, $row['date_and_time']); $edit_date = ''; $_title = get_translated_tempcode($row['the_message']); $news_title = xmlentities($_title->evaluate()); $summary = ''; $news = ''; $category = $categories[$row['room_id']]['room_name']; $category_raw = strval($row['room_id']); $view_url = build_url(array('page' => 'chat', 'type' => 'room', 'id' => $row['room_id']), get_module_zone('chat'), NULL, false, false, true); $if_comments = new ocp_tempcode(); $content->attach(do_template($prefix . 'ENTRY', array('VIEW_URL' => $view_url, 'SUMMARY' => $summary, 'EDIT_DATE' => $edit_date, 'IF_COMMENTS' => $if_comments, 'TITLE' => $news_title, 'CATEGORY_RAW' => $category_raw, 'CATEGORY' => $category, 'AUTHOR' => $author, 'ID' => $id, 'NEWS' => $news, 'DATE' => $news_date))); } } require_lang('chat'); return array($content, do_lang('MESSAGES')); }
/** * Standard function to create the standardised category tree * * @param ID_TEXT Notification code * @param ?ID_TEXT The ID of where we're looking under (NULL: N/A) * @return array Tree structure */ function create_category_tree($notification_code, $id) { $pagelinks = array(); require_code('chat'); $types = $GLOBALS['SITE_DB']->query_select('chat_rooms', array('*'), array('is_im' => 0)); foreach ($types as $type) { if (check_chatroom_access($type, true)) { $pagelinks[] = array('id' => $type['id'], 'title' => $type['room_name']); } } global $M_SORT_KEY; $M_SORT_KEY = 'title'; usort($pagelinks, 'multi_sort'); return $pagelinks; }
/** * The actualiser for deleting all the ticked messages in a room. * * @return tempcode The UI. */ function _chat_delete_many_messages() { breadcrumb_set_self(do_lang_tempcode('DONE')); $title = get_page_title('DELETE_SOME_MESSAGES'); $room_id = get_param_integer('room_id'); check_chatroom_access($room_id); $room_details = $GLOBALS['SITE_DB']->query_select('chat_rooms', array('*'), array('id' => $room_id), '', 1); if (!array_key_exists(0, $room_details)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $row = $room_details[0]; $has_mod_access = has_specific_permission(get_member(), 'edit_lowrange_content', 'cms_chat', array('chat', $room_id)) || $row['room_owner'] == get_member() && has_specific_permission(get_member(), 'moderate_my_private_rooms'); if (!$has_mod_access) { access_denied('SPECIFIC_PERMISSION', 'edit_lowrange_content'); } // Actualiser $count = 0; foreach (array_keys($_REQUEST) as $key) { if (substr($key, 0, 4) == 'del_') { delete_chat_messages(array('room_id' => $room_id, 'id' => intval(substr($key, 4)))); $count++; } } if ($count == 0) { warn_exit(do_lang_tempcode('NOTHING_SELECTED')); } decache('side_shoutbox'); $num_remaining = $GLOBALS['SITE_DB']->query_value('chat_messages', 'COUNT(*)', array('room_id' => $room_id)); if ($num_remaining == 0) { $url = build_url(array('page' => '_SELF', 'type' => 'misc'), '_SELF'); } else { $url = build_url(array('page' => '_SELF', 'type' => 'room', 'id' => $room_id, 'start' => get_param_integer('start'), 'max' => get_param_integer('max')), '_SELF'); } // Redirect return redirect_screen($title, $url, do_lang_tempcode('SUCCESS')); }
/** * The UI for a chat room. * * @return tempcode The UI */ function chat_room() { require_javascript('javascript_yahoo_2'); require_javascript('javascript_colour_picker'); require_javascript('javascript_posting'); require_css('colour_picker'); $prefs = @$_COOKIE['ocp_chat_prefs']; $prefs = @explode(';', $prefs); //$mode=get_param('mode',''); $room_id = get_param_integer('id', 1); $GLOBALS['FEED_URL'] = find_script('backend') . '?mode=chat&filter=' . strval($room_id); $room_check = $GLOBALS['SITE_DB']->query_select('chat_rooms', array('id', 'is_im', 'allow_list', 'allow_list_groups', 'disallow_list', 'disallow_list_groups', 'room_owner'), array('id' => $room_id), '', 1); if (!array_key_exists(0, $room_check)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } check_chatroom_access($room_check[0]); $posting_name = do_lang_tempcode('SEND_MESSAGE'); $keep = symbol_tempcode('KEEP'); $posting_url = find_script('messages') . '?mode=2&room_id=' . strval($room_id) . $keep->evaluate(); $messages_link = find_script('messages') . '?room_id=' . strval($room_id) . '&zone=' . get_zone_name() . $keep->evaluate(); $comcode_help = build_url(array('page' => 'userguide_comcode'), get_comcode_zone('userguide_comcode')); $chatcode_help = build_url(array('page' => 'userguide_chatcode'), get_comcode_zone('userguide_chatcode')); $buttons = new ocp_tempcode(); $_buttons = array('url', 'thumb', 'email', 'code', 'hide'); if (has_specific_permission(get_member(), 'comcode_dangerous')) { $_buttons[] = 'html'; } foreach ($_buttons as $button) { $buttons->attach(do_template('COMCODE_EDITOR_BUTTON', array('_GUID' => '4fd75edb2d091b1c78a71c653efb18f0', 'DIVIDER' => false, 'FIELD_NAME' => 'post', 'TITLE' => do_lang_tempcode('INPUT_COMCODE_' . $button), 'B' => $button))); } if (!is_guest()) { $_buttons = array('private_message', 'invite'); if (has_specific_permission(get_member(), 'create_private_room')) { $_buttons[] = 'new_room'; } foreach ($_buttons as $button) { $buttons->attach(do_template('CHATCODE_EDITOR_BUTTON', array('_GUID' => 'f1c3ccc2b6f0b68d71b7d256b3817cf3', 'TITLE' => do_lang_tempcode('INPUT_CHATCODE_' . $button), 'B' => $button))); } } $micro_buttons = new ocp_tempcode(); $_micro_buttons = array('b', 'i'); foreach ($_micro_buttons as $button) { $micro_buttons->attach(do_template('COMCODE_EDITOR_MICRO_BUTTON', array('_GUID' => '3ced1e569e0c6feaeadbc09f7f89e7ee', 'FIELD_NAME' => 'post', 'TITLE' => do_lang_tempcode('INPUT_COMCODE_' . $button), 'B' => $button))); } $user_colour = array_key_exists(0, $prefs) && $prefs[0] != '' ? $prefs[0] : get_option('chat_default_post_colour'); $line_contents = array_key_exists(1, $prefs) && $prefs[1] != '' ? $prefs[1] : get_option('chat_default_post_font'); $cs_post_url = build_url(array('page' => '_SELF', 'type' => 'options', 'id' => $room_id), '_SELF'); $yourname = $GLOBALS['FORUM_DRIVER']->get_username(get_member()); if (is_guest()) { $yourname .= '-' . substr(md5(get_ip_address()), 0, 5); } $messages_php = find_script('messages'); $debug = get_param_integer('debug', 0) == 1 ? 'block' : 'none'; $title = get_page_title('ROOM'); if (has_actual_page_access(get_member(), 'cms_chat', NULL, array('chat', strval($room_id)), array('edit_lowrange_content', $room_check[0]['room_owner'] == get_member() ? 'moderate_my_private_rooms' : NULL))) { $link = build_url(array('page' => 'cms_chat', 'type' => 'room', 'id' => $room_id), get_module_zone('cms_chat')); $modlink = hyperlink($link, do_lang_tempcode('CHAT_MOD_PANEL'), true); } else { $modlink = new ocp_tempcode(); } if (has_actual_page_access(get_member(), 'admin_chat')) { // The user is staff, so let him have the admin link $link = build_url(array('page' => 'admin_chat', 'type' => '_ed', 'id' => $room_id), 'adminzone'); $adminlink = hyperlink($link, do_lang_tempcode('EDIT_CHATROOM'), true); } else { $adminlink = new ocp_tempcode(); } $link = build_url(array('page' => '_SELF', 'type' => 'room', 'id' => $room_id), '_SELF'); $refreshlink = hyperlink($link, do_lang_tempcode('CHAT_REFRESH')); $link = build_url(array('page' => '_SELF', 'type' => 'download_logs'), '_SELF'); $downloadlink = hyperlink(build_url(array('page' => '_SELF', 'type' => 'download_logs', 'id' => $room_id), '_SELF'), do_lang_tempcode('CHAT_DOWNLOAD_LOGS'), true); $seteffectslink = hyperlink(build_url(array('page' => '_SELF', 'type' => 'set_effects'), '_SELF'), do_lang_tempcode('CHAT_SET_EFFECTS'), true); $links = array($adminlink, $modlink, $refreshlink, $downloadlink, $seteffectslink); breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('CHAT_LOBBY_END_CHAT')))); return do_template('CHAT_SCREEN', array('_GUID' => '867a0b050c050c81d33482d131783eb0', 'CHATTERS' => get_chatters_in_room_tpl(get_chatters_in_room($room_id)), 'CHAT_SOUND' => get_chat_sound_tpl(), 'ROOM_ID' => strval($room_id), 'DEBUG' => $debug, 'MESSAGES_PHP' => $messages_php, 'TEXT_COLOUR_DEFAULT' => $user_colour, 'FONT_NAME_DEFAULT' => $line_contents, 'OPTIONS_URL' => $cs_post_url, 'COMCODE_HELP' => $comcode_help, 'CHATCODE_HELP' => $chatcode_help, 'ROOM_NAME' => get_chatroom_name(get_param_integer('id', 1)), 'MICRO_BUTTONS' => $micro_buttons, 'BUTTONS' => $buttons, 'YOUR_NAME' => $yourname, 'MESSAGES_LINK' => $messages_link, 'POSTING_URL' => $posting_url, 'SUBMIT_VALUE' => $posting_name, 'INTRODUCTION' => '', 'TITLE' => $title, 'LINKS' => $links)); }
/** * Get a multidimensional array of the content of the specified chatroom. It automatically parses for comcode, chatcode, banned words, smilies, and uses complex logic to decide whether or not to show each message; based upon who the member is, the message content, and other such inputs. * If you set the $dereference flag, all the messages will be dereferenced for you, and if you set the $downloading flag, the array is returned in a format appropriate for things like downloading the chat logs. * $start and $finish are used to cutoff the number of messages returned, based on their posting date and time, and the $uptoid variable is used to make the function only return the messages newer than the id specified. * * @param AUTO_LINK The room ID (-1 for IM) * @param array Rooms database rows that we'll need * @param ?integer The maximum number of messages to be returned (NULL: no maximum) * @param boolean Whether to dereference the returned messages * @param boolean Whether to return the messages in a downloadeable format (using the templates for log downloading) * @param ?integer The datetime stamp to start gathering messages from (NULL: all) * @param ?integer The datetime stamp to stop gathering messages at (NULL: current time) * @param ?integer The lowest message ID to return (NULL: no special lowest number) * @param ?ID_TEXT The zone the chat module is in (NULL: find it) * @param ?AUTO_LINK The language ID for the "entering room" message (NULL: not entering the room) * @param boolean Return the current user's messages? * @param boolean Return system messages * @return array An array of all the messages collected according to the search criteria */ function chat_get_room_content($room_id, $_rooms, $cutoff = NULL, $dereference = false, $downloading = false, $start = NULL, $finish = NULL, $uptoid = NULL, $zone = NULL, $entering_room = NULL, $return_my_messages = true, $return_system_messages = true) { if (is_null($zone)) { $zone = get_module_zone('chat'); } $rooms = list_to_map('id', $_rooms); if (!is_null($entering_room)) { $their_username = $GLOBALS['FORUM_DRIVER']->get_username(get_member()); $_entering_room = get_translated_text($entering_room); if ($_entering_room != '') { require_code('comcode'); $_message_parsed = insert_lang_comcode('[private="' . $their_username . '"]' . $_entering_room . '[/private]', 4); $message_id = $GLOBALS['SITE_DB']->query_insert('chat_messages', array('system_message' => 0, 'ip_address' => get_ip_address(), 'room_id' => $room_id, 'user_id' => get_member(), 'date_and_time' => time(), 'the_message' => $_message_parsed, 'text_colour' => get_option('chat_default_post_colour'), 'font_name' => get_option('chat_default_post_font')), true); $myfile = @fopen(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat', 'wb') or intelligent_write_error(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat'); fwrite($myfile, strval($message_id)); fclose($myfile); sync_file(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat'); } $enter_room_msg = do_lang('ENTERED_THE_ROOM', $their_username); if ($enter_room_msg != '') { require_code('comcode'); $_message_parsed = insert_lang_comcode($enter_room_msg, 4); $message_id = $GLOBALS['SITE_DB']->query_insert('chat_messages', array('system_message' => 1, 'ip_address' => get_ip_address(), 'room_id' => $room_id, 'user_id' => get_member(), 'date_and_time' => time(), 'the_message' => $_message_parsed, 'text_colour' => get_option('chat_default_post_colour'), 'font_name' => get_option('chat_default_post_font')), true); $myfile = @fopen(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat', 'wb') or intelligent_write_error(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat'); fwrite($myfile, strval($message_id)); fclose($myfile); sync_file(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat'); } $room_name = $GLOBALS['SITE_DB']->query_value('chat_rooms', 'room_name', array('id' => $room_id)); $room_language = $GLOBALS['SITE_DB']->query_value('chat_rooms', 'room_language', array('id' => $room_id)); require_code('notifications'); $subject = do_lang('MEC_NOTIFICATION_MAIL_SUBJECT', get_site_name(), $their_username, $room_name, $room_language); $room_url = build_url(array('page' => 'chat', 'type' => 'room', 'id' => $room_id), $zone, NULL, false, false, true); $mail = do_lang('MEC_NOTIFICATION_MAIL', comcode_escape(get_site_name()), comcode_escape($their_username), array(comcode_escape($room_name), $room_url->evaluate()), $room_language); dispatch_notification('member_entered_chatroom', strval($room_id), $subject, $mail); } // Load all the room content from the db for one room and replace smilies and banned words etc. if ($downloading || !is_null($uptoid) || !$return_my_messages) { $query = 'SELECT main.* FROM ' . get_table_prefix() . 'chat_messages main '; $where = ''; if ($room_id != -1) { $where .= 'room_id=' . strval((int) $room_id); } if ($downloading) { if ($where != '') { $where .= ' AND '; } $where .= 'date_and_time>=' . strval((int) $start) . ' AND date_and_time<=' . strval((int) $finish); } if (!is_null($uptoid) && $uptoid != -1) { if (get_db_type() == 'xml') { $timestamp = $GLOBALS['SITE_DB']->query_value_null_ok('chat_messages', 'date_and_time', array('id' => $uptoid)); if (is_null($timestamp)) { $timestamp = 0; } if ($where != '') { $where .= ' AND '; } $where .= 'main.date_and_time>' . strval((int) $timestamp); } else { if ($where != '') { $where .= ' AND '; } $where .= 'main.id>' . strval((int) $uptoid); } } if (!$return_my_messages) { if ($where != '') { $where .= ' AND '; } $where .= 'user_id!=' . strval((int) get_member()); } if (!$return_system_messages) { if ($where != '') { $where .= ' AND '; } $where .= 'system_message=0'; } $query .= ($where == '' ? '' : ' WHERE ' . $where) . ' ORDER BY date_and_time DESC,id DESC'; global $TABLE_LANG_FIELDS; $rows = $GLOBALS['SITE_DB']->query($query, $cutoff, NULL, false, false, array_key_exists('chat_messages', $TABLE_LANG_FIELDS) ? $TABLE_LANG_FIELDS['chat_messages'] : array()); } else { $where_array = array('room_id' => $room_id); if (!$return_system_messages) { $where_array['system_message'] = 0; } $rows = $GLOBALS['SITE_DB']->query_select('chat_messages', array('*'), $where_array, 'ORDER BY date_and_time DESC,id DESC', $cutoff); } $rows = array_reverse($rows); $deleted_message_list = array(); foreach (array_keys($rows) as $i) { // Compose what we ultimately need to know about our message $rows[$i]['member_id'] = $rows[$i]['user_id']; // unfortunately the table schema was designed before our coding standards solidified $rows[$i]['username'] = $GLOBALS['FORUM_DRIVER']->get_username($rows[$i]['member_id']); if (is_null($rows[$i]['username'])) { $rows[$i]['username'] = do_lang('UNKNOWN'); } $rows[$i]['date_and_time_nice'] = get_timezoned_date($rows[$i]['date_and_time']); $message = get_translated_tempcode($rows[$i]['the_message']); // Extra access check if ($room_id == -1) { $pm_message_deleted = !array_key_exists($rows[$i]['room_id'], $rooms) || $rooms[$rows[$i]['room_id']]['is_im'] == 0 && !check_chatroom_access($rooms[$rows[$i]['room_id']], true); } else { $pm_message_deleted = false; } // Right... let's scan for chat tags in our tempcode, such as [private="Philip"]text[/private] $chatcode_tags = array('private', 'invite', 'newroom'); $text = $message->evaluate(); if (!$pm_message_deleted) { foreach ($chatcode_tags as $tag) { $pm_matches = array(); if (preg_match_all('#\\[' . $tag . '="([^&]*)"\\]([^\\[]*)\\[/' . $tag . '\\]#', $text, $pm_matches) != 0) { foreach (array_keys($pm_matches[0]) as $key) { $returns = _deal_with_chatcode_tags($text, $tag, $pm_matches[1][$key], $pm_matches[2][$key], $rows[$i]['username'], $cutoff, $zone, $rows[$i]['room_id'], $rows[$i]['system_message']); $pm_message_deleted = $returns['pm_message_deleted']; if ($pm_message_deleted) { break; } $text = $returns['text']; } if ($pm_message_deleted) { break; } } } } if (!$pm_message_deleted) { $message = make_string_tempcode($text); $rows[$i]['the_message'] = $dereference ? $message->evaluate() : $message; } else { $deleted_message_list[] = $i; } } $rows = _remove_empty_messages($rows, $deleted_message_list); return $rows; }