Browse Source

various improvements

pull/40/head
Michael Save 12 years ago
parent
commit
ad55a634bf
  1. 41
      inc/mod/ban.php
  2. 105
      inc/mod/pages.php
  3. 4
      mod.php
  4. 15
      stylesheets/style.css
  5. 74
      templates/mod/ban_list.html
  6. 4
      templates/mod/new_pm.html
  7. 41
      templates/mod/pm.html

41
inc/mod/ban.php

@ -16,44 +16,45 @@ function parse_time($str) {
if (($time = @strtotime($str)) !== false) if (($time = @strtotime($str)) !== false)
return $time; return $time;
if (!preg_match('/^((\d+)\s*ye?a?r?s?)?\s*+((\d+)\s*mon?t?h?s?)?\s*((\d+)\s*we?e?k?s?)?\s*((\d+)\s*da?y?s?)?((\d+)\s*ho?u?r?s?)?\s*((\d+)\s*mi?n?u?t?e?s?)?\s*+((\d+)\s*se?c?o?n?d?s?)?$/', $str, $matches)) if (!preg_match('/^((\d+)\s?ye?a?r?s?)?\s?+((\d+)\s?mon?t?h?s?)?\s?+((\d+)\s?we?e?k?s?)?\s?+((\d+)\s?da?y?s?)?((\d+)\s?ho?u?r?s?)?\s?+((\d+)\s?mi?n?u?t?e?s?)?\s?+((\d+)\s?se?c?o?n?d?s?)?$/', $str, $matches))
return false; return false;
$expire = time();
if (isset($m[2])) { $expire = 0;
if (isset($matches[2])) {
// Years // Years
$expire += $m[2]*60*60*24*365; $expire += $matches[2]*60*60*24*365;
} }
if (isset($m[4])) { if (isset($matches[4])) {
// Months // Months
$expire += $m[4]*60*60*24*30; $expire += $matches[4]*60*60*24*30;
} }
if (isset($m[6])) { if (isset($matches[6])) {
// Weeks // Weeks
$expire += $m[6]*60*60*24*7; $expire += $matches[6]*60*60*24*7;
} }
if (isset($m[8])) { if (isset($matches[8])) {
// Days // Days
$expire += $m[8]*60*60*24; $expire += $matches[8]*60*60*24;
} }
if (isset($m[10])) { if (isset($matches[10])) {
// Hours // Hours
$expire += $m[10]*60*60; $expire += $matches[10]*60*60;
} }
if (isset($m[12])) { if (isset($matches[12])) {
// Minutes // Minutes
$expire += $m[12]*60; $expire += $matches[12]*60;
} }
if (isset($m[14])) { if (isset($matches[14])) {
// Seconds // Seconds
$expire += $m[14]; $expire += $matches[14];
} }
return $expire; return time() + $expire;
} }
function ban($mask, $reason, $length, $board) { function ban($mask, $reason, $length, $board) {
global $mod; global $mod, $pdo;
// TODO: permissions // TODO: permissions
@ -78,6 +79,8 @@ function ban($mask, $reason, $length, $board) {
$query->bindValue(':board', null, PDO::PARAM_NULL); $query->bindValue(':board', null, PDO::PARAM_NULL);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
modLog('Created a new ban (<small>#' . $pdo->lastInsertId() . '</small>) for <strong>' . utf8tohtml($mask) . '</strong> with ' . ($reason ? 'reason: <small>' . $reason . '</small>' : 'no reason'));
} }
function unban($id) { function unban($id) {
@ -86,5 +89,7 @@ function unban($id) {
$query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query = prepare("DELETE FROM `bans` WHERE `id` = :id");
$query->bindValue(':id', $id); $query->bindValue(':id', $id);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
modLog("Removed ban #{$id}");
} }

105
inc/mod/pages.php

@ -39,7 +39,7 @@ function mod_login() {
$args['error'] = $config['error']['invalid']; $args['error'] = $config['error']['invalid'];
} else { } else {
modLog("Logged in."); modLog('Logged in');
// Login successful // Login successful
// Set cookies // Set cookies
@ -101,6 +101,7 @@ function mod_view_board($boardName, $page_no = 1) {
$page['btn'] = getPageButtons($page['pages'], true); $page['btn'] = getPageButtons($page['pages'], true);
$page['mod'] = true; $page['mod'] = true;
$page['config'] = $config; $page['config'] = $config;
echo Element('index.html', $page); echo Element('index.html', $page);
} }
@ -128,6 +129,8 @@ function mod_ip_remove_note($ip, $id) {
$query->bindValue(':id', $id); $query->bindValue(':id', $id);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
modLog("Removed a note for <a href=\"?/IP/{$ip}\">{$ip}</a>");
header('Location: ?/IP/' . $ip, true, $config['redirect_http']); header('Location: ?/IP/' . $ip, true, $config['redirect_http']);
} }
@ -160,6 +163,8 @@ function mod_page_ip($ip) {
$query->bindValue(':body', $_POST['note']); $query->bindValue(':body', $_POST['note']);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
modLog("Added a note for <a href=\"?/IP/{$ip}\">{$ip}</a>");
header('Location: ?/IP/' . $ip, true, $config['redirect_http']); header('Location: ?/IP/' . $ip, true, $config['redirect_http']);
return; return;
} }
@ -177,8 +182,9 @@ function mod_page_ip($ip) {
$query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT); $query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
while ($post = $query->fetch()) { while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
if (!$post['thread']) { if (!$post['thread']) {
// TODO: There is no reason why this should be such a fucking mess.
$po = new Thread( $po = new Thread(
$post['id'], $post['subject'], $post['email'], $post['name'], $post['trip'], $post['capcode'], $post['body'], $post['id'], $post['subject'], $post['email'], $post['name'], $post['trip'], $post['capcode'], $post['body'],
$post['time'], $post['thumb'], $post['thumbwidth'], $post['thumbheight'], $post['file'], $post['filewidth'], $post['time'], $post['thumb'], $post['thumbwidth'], $post['thumbheight'], $post['file'], $post['filewidth'],
@ -230,13 +236,6 @@ function mod_ban() {
return; return;
} }
$query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip");
$query->bindValue(':ip', $ip);
$query->execute() or error(db_error($query));
$args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC);
$ip = $_POST['ip'];
require_once 'inc/mod/ban.php'; require_once 'inc/mod/ban.php';
ban($_POST['ip'], $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']); ban($_POST['ip'], $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']);
@ -247,6 +246,51 @@ function mod_ban() {
header('Location: ?/', true, $config['redirect_http']); header('Location: ?/', true, $config['redirect_http']);
} }
function mod_bans() {
global $config;
if (!hasPermission($config['mod']['view_banlist']))
error($config['error']['noaccess']);
if (isset($_POST['unban'])) {
if (!hasPermission($config['mod']['unban']))
error($config['error']['noaccess']);
$unban = array();
foreach ($_POST as $name => $unused) {
if (preg_match('/^ban_(\d+)$/', $name, $match))
$unban[] = $match[1];
}
query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error());
foreach ($unban as $id) {
modLog("Removed ban #{$id}");
}
header('Location: ?/bans', true, $config['redirect_http']);
}
if ($config['mod']['view_banexpired']) {
$query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY (`expires` IS NOT NULL AND `expires` < :time), `set` DESC");
$query->bindValue(':time', time(), PDO::PARAM_INT);
$query->execute() or error(db_error($query));
} else {
// Filter out expired bans
$query = prepare("SELECT `bans`.*, `username` FROM `bans` INNER JOIN `mods` ON `mod` = `mods`.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC");
$query->bindValue(':time', time(), PDO::PARAM_INT);
$query->execute() or error(db_error($query));
}
$bans = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($bans as &$ban) {
if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false)
$ban['real_ip'] = true;
}
mod_page('Ban list', 'mod/ban_list.html', array('bans' => $bans));
}
function mod_delete($board, $post) { function mod_delete($board, $post) {
global $config, $mod; global $config, $mod;
@ -290,9 +334,48 @@ function mod_user_promote($uid, $action) {
$query->bindValue(':id', $uid); $query->bindValue(':id', $uid);
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
modLog(($action == 'promote' ? 'Promoted' : 'Demoted') . " user #{$uid}");
header('Location: ?/users', true, $config['redirect_http']); header('Location: ?/users', true, $config['redirect_http']);
} }
function mod_pm($id, $reply = false) {
global $mod, $config;
$query = prepare("SELECT `mods`.`username`, `mods_to`.`username` AS `to_username`, `pms`.* FROM `pms` LEFT JOIN `mods` ON `mods`.`id` = `sender` LEFT JOIN `mods` AS `mods_to` ON `mods_to`.`id` = `to` WHERE `pms`.`id` = :id");
$query->bindValue(':id', $id);
$query->execute() or error(db_error($query));
if ((!$pm = $query->fetch(PDO::FETCH_ASSOC)) || ($pm['to'] != $mod['id'] && !hasPermission($config['mod']['master_pm'])))
error($config['error']['404']);
if (isset($_POST['delete'])) {
$query = prepare("DELETE FROM `pms` WHERE `id` = :id");
$query->bindValue(':id', $id);
$query->execute() or error(db_error($query));
header('Location: ?/', true, $config['redirect_http']);
return;
}
if ($pm['unread'] && $pm['to'] == $mod['id']) {
$query = prepare("UPDATE `pms` SET `unread` = 0 WHERE `id` = :id");
$query->bindValue(':id', $id);
$query->execute() or error(db_error($query));
modLog('Read a PM');
}
if ($reply) {
if (!$pm['to_username'])
error($config['error']['404']); // deleted?
mod_page("New PM for {$pm['to_username']}", 'mod/new_pm.html', array('username' => $pm['to_username'], 'id' => $pm['to'], 'message' => quote($pm['message'])));
} else {
mod_page("Private message &ndash; #$id", 'mod/pm.html', $pm);
}
}
function mod_new_pm($username) { function mod_new_pm($username) {
global $config, $mod; global $config, $mod;
@ -323,6 +406,8 @@ function mod_new_pm($username) {
$query->bindValue(':time', time()); $query->bindValue(':time', time());
$query->execute() or error(db_error($query)); $query->execute() or error(db_error($query));
modLog('Sent a PM to ' . utf8tohtml($username));
header('Location: ?/', true, $config['redirect_http']); header('Location: ?/', true, $config['redirect_http']);
} }
@ -371,7 +456,7 @@ function mod_rebuild() {
} }
$query = query(sprintf("SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); $query = query(sprintf("SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error());
while($post = $query->fetch()) { while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
$log[] = '<strong>' . sprintf($config['board_abbreviation'], $board['uri']) . '</strong>: Rebuilding thread #' . $post['id']; $log[] = '<strong>' . sprintf($config['board_abbreviation'], $board['uri']) . '</strong>: Rebuilding thread #' . $post['id'];
buildThread($post['id']); buildThread($post['id']);
} }

4
mod.php

@ -26,16 +26,18 @@ $pages = array(
'!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work)
'!^/log$!' => 'log', // modlog '!^/log$!' => 'log', // modlog
'!^/log/(\d+)$!' => 'log', // modlog '!^/log/(\d+)$!' => 'log', // modlog
'!^/users$!' => 'users', // manage users '!^/users$!' => 'users', // manage users
'!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user
'!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm
'!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm
'!^/rebuild$!' => 'rebuild', // rebuild static files '!^/rebuild$!' => 'rebuild', // rebuild static files
'!^/ban$!' => 'ban', // new ban '!^/ban$!' => 'ban', // new ban
'!^/IP/([\w.:]+)$!' => 'ip', // view ip address '!^/IP/([\w.:]+)$!' => 'ip', // view ip address
'!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address '!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address
'!^/bans$!' => 'bans', // ban list
'!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post

15
stylesheets/style.css

@ -68,15 +68,18 @@ form table input {
} }
input[type="text"], input[type="password"], textarea { input[type="text"], input[type="password"], textarea {
border: 1px solid #a9a9a9; border: 1px solid #a9a9a9;
text-indent: 0px; text-indent: 0;
text-shadow: none; text-shadow: none;
text-transform: none; text-transform: none;
word-spacing: normal; word-spacing: normal;
} }
form table tr td { form table tr td {
text-align: left; text-align: left;
margin: 0px; margin: 0;
padding: 0px; padding: 0;
}
form table.mod tr td {
padding: 2px;
} }
form table tr th { form table tr th {
text-align: left; text-align: left;
@ -102,7 +105,7 @@ form table tr td div label {
} }
p.fileinfo { p.fileinfo {
display: block; display: block;
margin: 0px; margin: 0;
padding-right: 7em; padding-right: 7em;
} }
div.banner { div.banner {
@ -326,7 +329,7 @@ div.pages form input {
hr { hr {
border: none; border: none;
border-top: 1px solid #B7C5D9; border-top: 1px solid #B7C5D9;
height: 0px; height: 0;
clear: left; clear: left;
} }
div.boardlist { div.boardlist {
@ -349,7 +352,7 @@ table.modlog {
} }
table.modlog tr td { table.modlog tr td {
text-align: left; text-align: left;
margin: 0px; margin: 0;
padding: 4px 15px 0 0; padding: 4px 15px 0 0;
} }
table.modlog tr th { table.modlog tr th {

74
templates/mod/ban_list.html

@ -0,0 +1,74 @@
{% if bans|count == 0 %}
<p style="text-align:center" class="unimportant">(There are no active bans.)</p>
{% else %}
<form action="" method="post">
<table class="mod">
<tr>
<th>{% trans %}IP address{% endtrans %}</th>
<th>{% trans %}Reason{% endtrans %}</th>
<th>{% trans %}Board{% endtrans %}</th>
<th>{% trans %}Set{% endtrans %}</th>
<th>{% trans %}Expires{% endtrans %}</th>
<th>{% trans %}Staff{% endtrans %}</th>
</tr>
{% for ban in bans %}
<tr{% if ban.expires != 0 and ban.expires < time() %} style="text-decoration:line-through"{% endif %}>
<td style="white-space: nowrap">
<input type="checkbox" name="ban_{{ ban.id }}">
{% if ban.real_ip %}
<a href="?/IP/{{ ban.ip }}">{{ ban.ip }}</a>
{% else %}
{{ ban.ip|e }}
{% endif %}
</td>
<td>
{% if ban.reason %}
{{ ban.reason }}
{% else %}
-
{% endif %}
</td>
<td style="white-space: nowrap">
{% if ban.board %}
{{ config.board_abbreviation|sprintf(ban.board) }}
{% else %}
<em>{% trans %}all boards{% endtrans %}
{% endif %}
</td>
<td style="white-space: nowrap">
{{ ban.set|date(config.post_date) }}
</td>
<td style="white-space: nowrap">
{% if ban.expires == 0 %}
<em>never</em>
{% else %}
{{ ban.expires|date(config.post_date) }}
{% if ban.expires > time() %}
<small>({{ ban.expires|until }})</small>
{% endif %}
{% endif %}
</td>
<td>
{% if ban.username %}
{% if mod|hasPermission(config.mod.view_banstaff) %}
<a href="?/new_PM/{{ ban.username|e }}">{{ ban.username|e }}</a>
{% else %}
{% if mod|hasPermission(config.mod.view_banquestionmark) %}
<em>?</em>
{% else %}
{% endif %}
{% endif %}
{% else %}
<em>deleted?</em>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<p style="text-align:center">
<input type="submit" name="unban" value="Unban selected">
</p>
</form>
{% endif %}

4
templates/mod/new_pm.html

@ -2,7 +2,7 @@
{% set username = 'me' %} {% set username = 'me' %}
{% endif %}#} {% endif %}#}
<form action="" method="post"> <form action="?/new_PM/{{ username|e }}" method="post">
<table> <table>
<tr> <tr>
<th>To</th> <th>To</th>
@ -14,7 +14,7 @@
</tr> </tr>
<tr> <tr>
<th>Message</th> <th>Message</th>
<td><textarea name="message" rows="10" cols="40"></textarea></td> <td><textarea name="message" rows="10" cols="40">{{ message }}</textarea></td>
</tr> </tr>
</table> </table>

41
templates/mod/pm.html

@ -0,0 +1,41 @@
<form action="" method="post">
<table>
<tr>
<th>From</th>
{% if username %}
<td><a href="?/new_PM/{{ username|e }}">{{ username|e }}</a></td>
{% else %}
<td><em>deleted?</em></td>
{% endif %}
</tr>
{% if to != mod.id %}
<tr>
<th>To</th>
{% if to_username %}
<td><a href="?/new_PM/{{ to_username|e }}">{{ to_username|e }}</a></td>
{% else %}
<td><em>deleted?</em></td>
{% endif %}
</tr>
{% endif %}
<tr>
<th>Date</th>
<td>{{ time|date(config.post_date) }}</td>
</tr>
<tr>
<th>Message</th>
<td>{{ message }}</td>
</tr>
</table>
<ul style="list-style:none;text-align:center;padding:0">
<li style="padding:5px 0">
<input type="submit" name="delete" value="Delete forever">
</li>
<li style="padding:5px 0">
<a href="?/PM/{{ id }}/reply">
Reply with quote
</a>
</li>
</ul>
</form>
Loading…
Cancel
Save