- Совместимость
- не проверялся на совместимость
- Изменения в БД
- не требуются
- Автор
- _Xz_
- Общественное достояние
- да
Описание: добавляет логирование действий пользователей, их точное месторасположение на трекере.
- Инструкция по установке
-
PHP:
<? открыть config.php найти 'bb_login_err' => array('filecache', array()), после вставить 'buf_where' => array('db_sqlite', array('columns' => 'user_ip INT, username TEXT, user_id INT, user_rank INT, user_opt INT, forum_id INT, id INT, title TEXT, type TEXT, time INT')), найти конец файла перед вставить $bb_cfg['where_user'] = true; открыть functions.php найти if(!in_array($user_id, array('', ANONYMOUS, BOT_UID)) && $username) { $profile = '<a href="'. make_url(PROFILE_URL . $user_id) .'">'. $profile .'</a>'; } заменить на if(!in_array($user_id, array('', ANONYMOUS, BOT_UID)) && $username) { $profile = '<span class="nowrap"><a href="'. make_url(PROFILE_URL . $user_id) .'">'. $profile .'</a> <span onclick="user_popup('. $user_id .', \''. $username .'\');" title="Просмотр профиля" class="popup clickable"><span class="pad_6"></span></span></span>'; } function where_user($data) { global $bb_cfg, $lang, $userdata; if(!$bb_cfg['where_user']) return; $where_time = (TIMENOW - 300); $buf = CACHE('buf_where')->fetch_row(" SELECT time FROM buf_where WHERE type = '{$data['type']}' AND forum_id = {$data['forum_id']} AND user_ip = '". USER_IP ."' AND time > $where_time AND id = {$data['id']} ORDER BY time DESC"); $insert = true; if($buf) $insert = false; $sql['user_ip'] = USER_IP; $sql['username'] = $userdata['username']; /* if(IS_GUEST) { $user_browser = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'not browser'; foreach ($bb_cfg['bots'] as $bot => $name) { if(strstr($user_browser, $bot)) $sql['username'] = $name; } } */ $sql['user_id'] = $userdata['user_id']; $sql['user_rank'] = $userdata['user_rank']; $sql['user_opt'] = $userdata['user_opt']; $sql['time'] = TIMENOW; $sql['type'] = @$data['type']; $sql['forum_id'] = @$data['forum_id']; $sql['id'] = @$data['id']; $sql['title'] = @htmlCHR($data['title']); $sql_insert = DB()->build_array('INSERT', $sql); if($insert) CACHE('buf_where')->query("INSERT INTO buf_where $sql_insert"); } function where_user_url($data, $obrezka = true) { global $lang, $bb_cfg; if(!$bb_cfg['where_user']) return '---'; $title = html_ent_decode($data['title']); $old_title = $title; if($obrezka && $data['type'] != 'profile' && $title) $title = str_short($title, 60); switch($data['type']) { case 'index': return 'Просмотр главной страницы <a href="'. make_url('index.php') .'" target="_blank">'. $title .'</a>'; break; case 'topic': case 'post': $topic = ($data['type'] == 'post') ? '<a href="'. (POST_URL . $data['id'] .'#'. $data['id'], $old_title) .'" target="_blank">'. $title .'</a>' : '<a href="'. (TOPIC_URL . $data['id'], $old_title) .'" target="_blank">'. $title .'</a>'; return 'Просмотр темы '. $topic; break; case 'forum': $forum = '<a href="'. (FORUM_URL . $data['id'], $old_title) .'" target="_blank">'. $title .'</a>'; return 'Просмотр форума '. $forum; break; case 'profile': return 'Просмотр профиля '. $title; break; case 'search': return 'Использует поиск по форуму'; break; case 'tracker': return 'Использует поиск по трекеру'; break; case 'nya': return 'Смотрит цитаты с няша'; break; case 'torrent': return "Скачал торрент в <a href='$title'>этой</a> раздачи"; break; case 'online': return "Смотрит <a href='viewonline.php'>Кто онлайн</a>"; break; } } index.php // Init userdata $user->session_start(); if(!IS_GUEST) where_user(array('id' => 0, 'forum_id' => 0, 'type' => 'index', 'title' => $bb_cfg['sitename'])); открыть найти viewtopic.php if (!$t_data = DB()->fetch_row($sql)) { bb_die($lang['TOPIC_POST_NOT_EXIST']); } после вставить if(!IS_GUEST) { $where_type = ($post_id) ? 'post' : 'topic'; $where_id = ($post_id) ? $post_id : $t_data['topic_id']; where_user(array('id' => $where_id, 'forum_id' => $t_data['forum_id'], 'type' => $where_type, 'title' => $t_data['topic_title'])); } if($bb_cfg['where_user'] && !IS_GUEST) { $where_time = (TIMENOW - 300); $user_list = array(); $sql = CACHE('buf_where')->fetch_rowset(" SELECT * FROM buf_where WHERE (type = 'post' OR type = 'topic' OR type = 'posting') AND forum_id = {$t_data['forum_id']} AND time > $where_time GROUP BY ORDER BY time DESC"); $guest = $users = $hide_users = 0; foreach($sql as $row) { $profile = str_replace('title="', 'data="', profile_url($row)); $time = delta_time($row['time']); if(bf($row['user_opt'], 'user_opt', 'allow_viewonline')) { $hide_users++; if(IS_ADMIN) { $user_list[] = '<span title="'. $time .'" style="border-bottom: 1px dashed #000; padding-bottom: 2px;">'. $profile .'</span>'; } } else if($row['user_id'] == ANONYMOUS) { $guest++; $user_list[] = '<span title="'. $time .'">'. $profile .'</span>'; } else { $users++; $user_list[] = '<span title="'. $time .'">'. $profile .'</span>'; } } $text = ($users + $hide_users) ." человек читают эту тему: $users пользователей, $hide_users скрытых пользователей, $guest гостей"; $list = join(', ', $user_list); $template->assign_vars(array( 'USER_TEXT' => $text, 'USER_LIST' => $list, )); } открыть viewforum.php найти if($forums['forum'][$forum_id]['allow_porno_topic'] && bf($userdata['user_opt'], 'user_opt', 'hide_porn_forums')) bb_die($lang['ERROR_PORNO_FORUM']); после вставить if(!IS_GUEST) where_user(array('id' => $forum_id, 'forum_id' => $forum_id, 'type' => 'forum', 'title' => $forums['forum_name_html'][$forum_id])); if($bb_cfg['where_user'] && !IS_GUEST) { $where_time = (TIMENOW - 300); $user_list = array(); $sql = CACHE('buf_where')->fetch_rowset(" SELECT * FROM buf_where WHERE (type = 'forum' OR type = 'post' OR type = 'topic' OR type = 'posting') AND forum_id = $forum_id AND time > $where_time ORDER BY time DESC"); $guest = $users = $hide_users = 0; foreach($sql as $row) { $profile = str_replace('title="', 'data="', profile_url($row)); $time = delta_time($row['time']); if(bf($row['user_opt'], 'user_opt', 'allow_viewonline')) { $hide_users++; if(IS_ADMIN) { $user_list[] = '<span title="'. $time .'" style="border-bottom: 1px dashed #000; padding-bottom: 2px;">'. $profile .'</span>'; } } else if($row['user_id'] == ANONYMOUS) { $guest++; $user_list[] = '<span title="'. $time .'">'. $profile .'</span>'; } else { $users++; $user_list[] = '<span title="'. $time .'">'. $profile .'</span>'; } } $text = ($users + $hide_users) ." человек читают эту тему: $users пользователей, $hide_users скрытых пользователей, $guest гостей"; $list = join(', ', $user_list); $template->assign_vars(array( 'USER_TEXT' => $text, 'USER_LIST' => $list, )); } открыть index_data.php добавить case 'user_popup': $user_id = (int) $this->request['user_id']; $data = get_userdata($user_id); if ($data['user_id'] == ANONYMOUS || $data['user_id'] == BOT_UID || !$data) { $this->ajax_die('Пользователь не найден'); } $where_time = (TIMENOW - 300); $where = CACHE('buf_where')->fetch_row(" SELECT * FROM buf_where WHERE user_id = '". $data['user_id'] ."' AND time > $where_time ORDER BY time DESC"); $datastore->enqueue(array( 'ranks', )); $ranks = $datastore->get('ranks'); $rank_title = $lang['USER']; $rank_image = $rank_style = ''; if ($user_rank = $data['user_rank'] AND isset($ranks[$user_rank])) { $rank_image = $ranks[$user_rank]['rank_image']; $rank_title = $ranks[$user_rank]['rank_title']; $rank_style = $ranks[$user_rank]['rank_style']; } if(bf($data['user_opt'], 'user_opt', 'allow_viewonline') && !IS_ADMIN) { $lastvisit = '<div class="pad_2"><b>Последняя активность</b>: скрыто</div>'; } else { if($where >= (TIMENOW - 300)) { $text = where_user_url($where); $lastvisit = '<div class="pad_2"><b>Последняя активность</b>: '. bb_date($data['user_session_time']) .'</div>'; $lastvisit .= '<div class="pad_2"><b>Сейчас</b>: '. $text .'</div>'; } else { $lastvisit = '<div class="pad_2"><b>Сейчас</b>: Offline</div>'; } } $avatar = get_avatar($data['user_avatar'], $data['user_avatar_type'], !bf($data['user_opt'], 'user_opt', 'allow_avatar')); $html .= '<div class="pad_4"> '. str_replace('<img', '<img width="100" align="right"', $avatar) .' <div class="pad_2"><b>Звание</b>: <span class="'. $rank_style .'">'. $rank_title .'</span></div> <div class="pad_2"><b>Зарегистрирован</b>: '. bb_date($data['user_regdate']) .'</div> <div class="pad_2"><b>Всего сообщений</b>: '. $data['user_posts'] .'</div> '. $lastvisit .' <div class="clear pad_4"></div> <div class="hr pad_2"> <a href="'. PROFILE_URL . $user_id .'">[профиль]</a> <a href="'. PM_URL .'?mode=post&u='. $user_id .'">[Отправить ЛС]</a> </div> </div>'; break; открыть viewtopic.tpl найти <!-- IF QUICK_REPLY --> перед вставить <!-- IF $bb_cfg['where_user'] --> <div class="category row1 border bw_TRBL mrg_8 pad_4"> {USER_TEXT} <br /><br /> {USER_LIST} </div> <!-- ENDIF --> <script type="text/javascript" src="{#BB_ROOT}misc/js/ui/jquery.ui.js?v={$bb_cfg['js_ver']}"></script> <link rel="stylesheet" href="{#BB_ROOT}misc/js/ui/ui.css?v={$bb_cfg['css_ver']}" type="text/css"> <!--=================--> <!-- ELSEIF IN_ADMIN --> <!--=================--> <!--======--> <!-- ELSE --> <!--======--> <script type="text/javascript"> function user_popup(user_id, name) { $("#user_popup").dialog( "destroy" ); $("#user_popup").show().attr({title: 'Пользователь: '+name}).dialog({ height: 200, width: 400, }); ajax.exec({ action : 'index_data', mode : 'user_popup', user_id : user_id, }); ajax.callback.index_data = function(data) { $('#'+data.mode).html(data.html); }; } </script> <div id="user_popup" class="hidden med"></div> <!--page_container--> <div id="page_container">