Приветствую.
Вот понадобилось сделать для форума портала PHP.SU нечто более, чем текущий бан.
К примеру временная блокировка и указание причины бана. Так же нужен список забаненных товарищей с информацией кого, когда, на сколько и кто забанил. Так же кто разбанил, Модератор или сам скрипт по истечению (авторазбан работает, когда забаненный юзер пытается зайти по истечению срока бана. Возможно лучшее решение это крон раз в сутки).
Бан ставится минимум на 1 день. Возможно разбанить и раньше - обычной кнопкой "Разбанить"
Я слышал, что в новой версии будет улучшен этот алгоритм, но сегодня появилось время и решил сделать - может кому еще пригодится.
1. Для начала создаем в папке data папку banned_users и сразу ставим права 777 (rwxrwxrwx). В этой папке будут храниться файлы ИДюзера.php
2. в файле profile.php после строки
CODE:if ($is_moder && !$to_moder) {
коменируем
CODE:// $moders_ban= '<a href="..........';
и добавляем код
Спойлер (Отобразить)
CODE:
$moders_ban= '';
if($user['status'] == 'banned' AND file_exists('data/banned_users/'.$user_id.'.php')) {
$usrban = $fm->_Read('data/banned_users/'.$user_id.'.php');
$moders_ban.= '<br />'.$fm->LANG['BanReason'].': <b>'.$usrban['reason'].'</b> '.$fm->LANG['BanDays'].' <b>'.$usrban['days'].'</b> '.$fm->LANG['BanDateEnd'].': <b>'.$fm->_DateFormat($usrban['end']).'</b>';
}
$moders_ban.= '<hr/><form action="profile.php?action=show&member='.$user_id.'&ban=yes" method="POST">';
if($user['status'] == 'banned') {
$moders_ban.= '<input type="hidden" name="unban" value="1">';
}else {
$moders_ban.= $fm->LANG['BanDays'].': <input type="text" size="5" name="days"> ';
$moders_ban.= $fm->LANG['BanReason'].': <input type="text" size="70" name="reason">';
}
$moders_ban.= '<input type="submit" value="'.(($user['status'] == 'banned') ? $fm->LANG['BanUnSet'] : $fm->LANG['BanSet']).'">';
$moders_ban.= '</form>';
if ($fm->_Boolean1('ban') AND ($user['status'] == 'me' OR $user['status'] == 'banned')) {
$days = isset($fm->input['days']) ? abs(intval($fm->input['days'])) : 0;
$reason = isset($fm->input['reason']) ? $fm->_String('reason') : '';
$unban = isset($fm->input['unban']) ? intval($fm->input['unban']) : 0;
if($reason!='' OR $unban==1) {
if($days>0 OR $unban==1) {
$days = $unban==1 ? 0 : $days;
$user_ban = $fm->_Read2Write($fp_ban, 'data/banned_users/'.$user_id.'.php');
$user_ban['user_id'] = $user_id;
$user_ban['user_name'] = $user['name'];
$user_ban['days'] = $days;
$user_ban['date'] = time();
$user_ban['end'] = mktime(0,0,0,date('m'),date('d')+$days,date('Y'));
$user_ban['reason'] = $unban==1 ? $user_ban['reason'] : ($reason ? $reason : '');
$user_ban['who_id'] = $fm->user['id'];
$user_ban['who_name'] = (isset($fm->LANG['Pun'.$fm->user['status']]) ? $fm->LANG['Pun'.$fm->user['status']].' ' : '').$fm->user['name'];
if($unban==1) {
$user_ban['whounban_id'] = $fm->user['id'];
$user_ban['whounban_name'] = (isset($fm->LANG['Pun'.$fm->user['status']]) ? $fm->LANG['Pun'.$fm->user['status']].' ' : '').$fm->user['name'];
}
$fm->_Write($fp_ban, $user_ban);
}else{
$fm->_Message($fm->LANG['MainMsg'], $fm->LANG['BanErrorDays']);
}
}else{
$fm->_Message($fm->LANG['MainMsg'], $fm->LANG['BanErrorReason']);
}
}
3. в файле tools.php после строк
CODE: case 'members':
memberslist();
break;
добавиляем
CODE:
case 'banmembers':
banmemberslist();
break;
там же перед строкой
CODE:function memberslist() {
добавляем
CODE:
function banmemberslist() {
global $fm;
$users = $fm->_Read(FM_USERS);
$userskeys = array_keys($users);
$banmembers_data = '';
$time_end = time();
$is_moder = ($fm->user['status'] == 'ad' || $fm->user['status'] == 'sm') ? 1 : 0;
foreach ($userskeys AS $key => $user_id) {
$user = $fm->_GetBanMember($user_id);
if(!$user){continue;}
if($user['end'] < $time_end AND $is_moder==0) {continue;}
$user['user_name'] = ($user['end'] < time() OR $user['days']==0) ? $user['user_name'] : '<font color=\'red\'>'.$user['user_name'].'</font>';
$user['date'] = $fm->_DateFormat($user['date']);
$user['end'] = $user['days']>=999 ? 'никогда' : $fm->_DateFormat($user['end']);
$user['days'] = $user['days']>0 ? ($user['days']>=999 ? '-' : $user['days']) : $fm->LANG['BanUnSeted'];
$user['whounban'] = (isset($user['whounban_id']) AND $user['whounban_id']>0) ? '<a href="profile.php?action=show&member='.$user['whounban_id'].'" title="'.$fm->LANG['UserProfile'].' '.$user['whounban_name'].'">'.$user['whounban_name'].'</a>' : ($user['days']==0 ? 'Auto' : '');
include('./templates/'.DEF_SKIN.'/banmemblist_data.tpl');
unset($user);
}
4. в файле loginout.php после строк
CODE:$fm->_Fclose($fp_user);
$fm->_WriteLog($fm->LANG['BannedLoged']);
добавляем
CODE:if($text_ban = $fm->_AutoUnBan($user, TRUE)) {
$fm->_Message($fm->LANG['ErrorLogin'],$fm->LANG['LoginDeniedBan'].'<br />'.$text_ban);
}
5. в файле include/fm.class.php
перед
CODE:/*
_Locale установка локальных настроек форума для пользователя и гостя
*/
function _Locale() {
добавляем
CODE:
/*
_AutoUnBan разбанивание по окончании времени действия бана
*/
function _AutoUnBan($user, $msg=FALSE){
$usrban = $this->_Read('data/banned_users/'.$user['id'].'.php');
if($usrban['end'] < time()) {
$user_ban = $this->_Read2Write($fp_ban, 'data/banned_users/'.$user['id'].'.php');
$user_ban['whounban_id'] = 0;
$user_ban['whounban_name'] = 'auto';
$user_ban['days'] = 0;
$this->_Write($fp_ban, $user_ban);
$user_unban = $this->_Read2Write($fp_user_unban, 'members/'.$user['id'].'.php');
$user_unban['status'] = 'me';
$this->_Write($fp_user_unban, $user_unban);
$this->_Mail($this->exbb['boardname'],$this->exbb['adminemail'],$this->exbb['adminemail'], 'AutoUnBanned User (PHP.SU)', 'AutoUnBan '.$user['name']);
$this->_WriteLog(sprintf('AutoUnBan', 'Auto', '<b>'.$user['name'].'</b>'), 2); // Запись в лог
return false;
}
if($msg) {
return '<br />Причина: '.$usrban['reason'].'<br /> Дней: '.$usrban['days'].'<br /> Дата окончания: '.$this->_DateFormat($usrban['end']);
}
return true;
}
после
CODE:if ($this->user['id'] == 0) {
$this->user['name'] = $this->LANG['Guest'];
}elseif ($this->user['status'] == 'banned') {
добавляем
CODE:
if($text_ban =$this->_AutoUnBan($this->user,TRUE)) {
$this->_Message($this->LANG['MainMsg'],$this->LANG['LoginDeniedBan'].$text_ban,'',1);
}
7. в файле language/russian/lang_front_all.php перед строкой
добаляем
CODE:
$this->LANG['BanUnSeted'] = 'Разбанен';
$this->LANG['BanReason'] = 'Причина';
$this->LANG['BanDays'] = 'Дней';
$this->LANG['BanDate'] = 'Дата бана';
$this->LANG['BanDateEnd'] = 'Дата окончания';
$this->LANG['BanUser'] = 'Пользователь';
$this->LANG['BanWho'] = 'Кто забанил';
$this->LANG['BanWhoUnban'] = 'Кто разбанил';
8. в файле language/russian/lang_front_register.php перед строкой
добавляем
CODE:
$this->LANG['Punad'] = 'Администратор';
$this->LANG['Punsm'] = 'Супермодератор';
/*
Ban/UnBan
*/
$this->LANG['BanReason'] = 'Причина';
$this->LANG['BanDays'] = 'Дней';
$this->LANG['BanDate'] = 'Дата';
$this->LANG['BanDateEnd'] = 'Дата окончания';
$this->LANG['BanSet'] = 'Забанить';
$this->LANG['BanUnSet'] = 'Разбанить';
$this->LANG['BanErrorReason'] = 'Укажите причину бана';
$this->LANG['BanErrorDays'] = 'Укажите количество дней бана (целое число от 1)';
9. в файле templates/InvisionBB/logos.tpl
за строкой
CODE:<a href="tools.php?action=members" title="{$fm->LANG['Users']}"><img src="./templates/InvisionExBB/im/members.gif" border="0" alt="{$fm->LANG['Users']}" /> <b>{$fm->LANG['Users']}</b></a>
добавляем
CODE:
<a href="tools.php?action=banmembers" title="{$fm->LANG['BanUsers']}"><img src="./templates/InvisionExBB/im/banmembers.gif" border="0" alt="{$fm->LANG['BanUsers']}" /> <b>{$fm->LANG['BanUsers']}</b></a>
10. создаем файл templates/InvisionBB/banmemblist.tpl с таким содержанием :
CODE:
<?php
echo <<<MEMBERS
<br/>
<div id="navstrip" align="left">
<img src="./templates/InvisionExBB/im/nav.gif" border="0" alt=">" /> <a href="index.php">{$fm->exbb['boardname']}</a> » <a href="tools.php?action=banmembers">{$fm->LANG['BanMemberlist']}</a>
</div>
<table width="100%" cellpadding="0" cellspacing="1" class="tableborder">
<tr>
<td class="maintitle" colspan="8"><img src="./templates/InvisionExBB/im/nav_m.gif" border="0" alt=">" width="8" height="8" /> {$fm->LANG['BanMemberlist']}</td>
</tr>
<tr class="postlinksbar" align="center">
<td width="15%" height="29">{$fm->LANG['BanUser']}</td>
<td width="33%">{$fm->LANG['BanReason']}</td>
<td width="15%">{$fm->LANG['BanDate']}</td>
<td width="2%">{$fm->LANG['BanDays']}</td>
<td width="15%">{$fm->LANG['BanDateEnd']}</td>
<td width="15%">{$fm->LANG['BanWho']}</td>
<td width="15%">{$fm->LANG['BanWhoUnban']}</td>
</tr>
{$banmembers_data}
<tr>
<td class="activeuserstrip" align="center" colspan="8"> </td>
</tr>
</table>
MEMBERS;
?>
11. создаем файл templates/InvisionBB/banmemblist_data.tpl с таким содержанием :
CODE:
<?php
$banmembers_data .= <<<DATA
<tr align="center">
<td class="row2"><b><a href="profile.php?action=show&member={$user_id}" title="{$fm->LANG['UserProfile']} {$user['user_name']}">{$user['user_name']}</a></b</td>
<td class="row2">{$user['reason']}</td>
<td class="row2">{$user['date']}</td>
<td class="row2">{$user['days']}</td>
<td class="row2">{$user['end']}</td>
<td class="row2"><b><a href="profile.php?action=show&member={$user['who_id']}" title="{$fm->LANG['UserProfile']} {$user['who_name']}">{$user['who_name']}</a></b</td>
<td class="row2">{$user['whounban']}</td>
</tr>
DATA;
?>
пара моментов которые зацепил походу:
1. в файле modules/punish/profile.php
строку
CODE:$whoadd = $fm->LANG['Pun'.$status].$moder;
заменить на
CODE:$whoadd = (isset($fm->LANG['Pun'.$status]) ? $fm->LANG['Pun'.$status].' - ' : '').$moder;
2. в файле language/russian/lang_front_all.php
(необходимо так как забаненному выскакивает предупреждение из шаблона админки) добавляем
CODE:$this->LANG['Administrating'] = 'Администрирование ExBB FM';
Конечно, много нюансов и вопросов остается, но сделал за несколько часов, и в будущем буду модифицировать и выкладывать
Как это выглядит:
1. В профиле юзера модераторы видят форму с полями для бана
2. http://forum.php.su/tools.php?action=banmembers
Модераторы так же видят кого разбанили.
Возможно лучшее решение это удалять разбаненого пользователя из папки data/banned_users/. Отредактировано администратором: Александр Михалицын, 21 февраля 2010 — 12:47 |