diff --git a/inc/bans.php b/inc/bans.php
index ed81c6e4..154094e5 100644
--- a/inc/bans.php
+++ b/inc/bans.php
@@ -148,49 +148,86 @@ class Bans {
return $ban_list;
}
-
- static public function list_all($offset = 0, $limit = 9001) {
- $offset = (int)$offset;
- $limit = (int)$limit;
-
+
+ static public function stream_json($out = false, $filter_ips = false, $filter_staff = false, $board_access = false) {
$query = query("SELECT ``bans``.*, `username` FROM ``bans``
LEFT JOIN ``mods`` ON ``mods``.`id` = `creator`
- ORDER BY `created` DESC LIMIT $offset, $limit") or error(db_error());
- $bans = $query->fetchAll(PDO::FETCH_ASSOC);
-
- foreach ($bans as &$ban) {
- $ban['mask'] = self::range_to_string(array($ban['ipstart'], $ban['ipend']));
+ ORDER BY `created` DESC") or error(db_error());
+ $bans = $query->fetchAll(PDO::FETCH_ASSOC);
+
+ if ($board_access && $board_access[0] == '*') $board_access = false;
+
+ $out ? fputs($out, "[") : print("[");
+
+ $end = end($bans);
+
+ foreach ($bans as &$ban) {
+ $ban['mask'] = self::range_to_string(array($ban['ipstart'], $ban['ipend']));
+
+ if ($ban['post']) {
+ $post = json_decode($ban['post']);
+ $ban['message'] = $post->body;
+ }
+ unset($ban['ipstart'], $ban['ipend'], $ban['post'], $ban['creator']);
+
+ if ($board_access === false || in_array ($ban['board'], $board_access)) {
+ $ban['access'] = true;
+ }
+
+ if (filter_var($ban['mask'], FILTER_VALIDATE_IP) !== false) {
+ $ban['single_addr'] = true;
+ }
+ if ($filter_staff || ($board_access !== false && !in_array($ban['board'], $board_access))) {
+ $ban['username'] = '?';
+ }
+ if ($filter_ips || ($board_access !== false && !in_array($ban['board'], $board_access))) {
+ list($ban['mask'], $subnet) = explode("/", $ban['mask']);
+ $ban['mask'] = preg_split("/[\.:]/", $ban['mask']);
+ $ban['mask'] = array_slice($ban['mask'], 0, 2);
+ $ban['mask'] = implode(".", $ban['mask']);
+ $ban['mask'] .= ".*";
+ if (isset ($subnet)) {
+ $ban['mask'] .= "/$subnet";
+ }
+ $ban['masked'] = true;
+ }
+
+ $json = json_encode($ban);
+ $out ? fputs($out, $json) : print($json);
+
+ if ($ban['id'] != $end['id']) {
+ $out ? fputs($out, ",") : print(",");
+ }
}
-
- return $bans;
- }
-
- static public function count($board = false) {
- if (!$board) {
- $query = prepare("SELECT COUNT(*) FROM ``bans``");
- } else {
- $query = prepare("SELECT COUNT(*) FROM ``bans`` WHERE `board` = :board");
- }
- $query->bindValue(':board', $board);
- $query->execute() or error(db_error());
- return (int)$query->fetchColumn();
+
+ $out ? fputs($out, "]") : print("]");
+
}
static public function seen($ban_id) {
$query = query("UPDATE ``bans`` SET `seen` = 1 WHERE `id` = " . (int)$ban_id) or error(db_error());
+ rebuildThemes('bans');
}
static public function purge() {
$query = query("DELETE FROM ``bans`` WHERE `expires` IS NOT NULL AND `expires` < " . time() . " AND `seen` = 1") or error(db_error());
+ rebuildThemes('bans');
}
- static public function delete($ban_id, $modlog = false) {
+ static public function delete($ban_id, $modlog = false, $boards = false, $dont_rebuild = false) {
+ global $config;
+
+ if ($boards && $boards[0] == '*') $boards = false;
+
if ($modlog) {
$query = query("SELECT `ipstart`, `ipend` FROM ``bans`` WHERE `id` = " . (int)$ban_id) or error(db_error());
if (!$ban = $query->fetch(PDO::FETCH_ASSOC)) {
// Ban doesn't exist
return false;
}
+
+ if ($boards !== false && !in_array($ban['board'], $boards))
+ error($config['error']['noaccess']);
$mask = self::range_to_string(array($ban['ipstart'], $ban['ipend']));
@@ -199,6 +236,8 @@ class Bans {
}
query("DELETE FROM ``bans`` WHERE `id` = " . (int)$ban_id) or error(db_error());
+
+ if (!$dont_rebuild) rebuildThemes('bans');
return true;
}
@@ -265,6 +304,9 @@ class Bans {
' (#' . $pdo->lastInsertId() . ')' .
' with ' . ($reason ? 'reason: ' . utf8tohtml($reason) . '' : 'no reason'));
}
+
+ rebuildThemes('bans');
+
return $pdo->lastInsertId();
}
}
diff --git a/inc/mod/pages.php b/inc/mod/pages.php
index ab2fb2d3..c7722763 100644
--- a/inc/mod/pages.php
+++ b/inc/mod/pages.php
@@ -766,7 +766,7 @@ function mod_page_ip($ip) {
if (!hasPermission($config['mod']['unban']))
error($config['error']['noaccess']);
- Bans::delete($_POST['ban_id'], true);
+ Bans::delete($_POST['ban_id'], true, $mod['boards']);
header('Location: ?/IP/' . $ip . '#bans', true, $config['redirect_http']);
return;
@@ -863,18 +863,16 @@ function mod_ban() {
require_once 'inc/mod/ban.php';
Bans::new_ban($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'] == '*' ? false : $_POST['board']);
-
+
if (isset($_POST['redirect']))
header('Location: ' . $_POST['redirect'], true, $config['redirect_http']);
else
header('Location: ?/', true, $config['redirect_http']);
}
-function mod_bans($page_no = 1) {
+function mod_bans() {
global $config;
-
- if ($page_no < 1)
- error($config['error']['404']);
+ global $mod;
if (!hasPermission($config['mod']['view_banlist']))
error($config['error']['noaccess']);
@@ -892,29 +890,33 @@ function mod_bans($page_no = 1) {
error(sprintf($config['error']['toomanyunban'], $config['mod']['unban_limit'], count($unban)));
foreach ($unban as $id) {
- Bans::delete($id, true);
+ Bans::delete($id, true, $mod['boards'], true);
}
+ rebuildThemes('bans');
header('Location: ?/bans', true, $config['redirect_http']);
return;
}
- $bans = Bans::list_all(($page_no - 1) * $config['mod']['banlist_page'], $config['mod']['banlist_page']);
-
- if (empty($bans) && $page_no > 1)
- error($config['error']['404']);
-
- foreach ($bans as &$ban) {
- if (filter_var($ban['mask'], FILTER_VALIDATE_IP) !== false)
- $ban['single_addr'] = true;
- }
-
mod_page(_('Ban list'), 'mod/ban_list.html', array(
- 'bans' => $bans,
- 'count' => Bans::count(),
- 'token' => make_secure_link_token('bans')
+ 'mod' => $mod,
+ 'boards' => json_encode($mod['boards']),
+ 'token' => make_secure_link_token('bans'),
+ 'token_json' => make_secure_link_token('bans.json')
));
}
+function mod_bans_json() {
+ global $config, $mod;
+
+ if (!hasPermission($config['mod']['ban']))
+ error($config['error']['noaccess']);
+
+ // Compress the json for faster loads
+ if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler");
+
+ Bans::stream_json(false, false, !hasPermission($config['mod']['view_banstaff']), $mod['boards']);
+}
+
function mod_ban_appeals() {
global $config, $board;
diff --git a/js/local-time.js b/js/local-time.js
index e6b3495d..a4e25d6d 100644
--- a/js/local-time.js
+++ b/js/local-time.js
@@ -25,16 +25,6 @@ onready(function(){
return [Math.pow(10, count - num.toString().length), num].join('').substr(1);
};
- var datelocale =
- { days: [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')]
- , shortDays: [_("Sun"), _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat")]
- , months: [_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December')]
- , shortMonths: [_('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'), _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')]
- , AM: _('AM')
- , PM: _('PM')
- , am: _('am')
- , pm: _('pm')
- };
var dateformat = (typeof strftime === 'undefined') ? function(t) {
return zeropad(t.getMonth() + 1, 2) + "/" + zeropad(t.getDate(), 2) + "/" + t.getFullYear().toString().substring(2) +
" (" + [_("Sun"), _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun")][t.getDay()] + ") " +
diff --git a/js/mod/ban-list.js b/js/mod/ban-list.js
new file mode 100644
index 00000000..30529044
--- /dev/null
+++ b/js/mod/ban-list.js
@@ -0,0 +1,157 @@
+var banlist_init = function(token, my_boards, inMod) {
+ inMod = !inMod;
+
+ var lt;
+
+ var selected = {};
+
+ var time = function() { return Date.now()/1000|0; }
+
+ $.getJSON(inMod ? ("?/bans.json/"+token) : token, function(t) {
+ $("#banlist").on("new-row", function(e, drow, el) {
+ var sel = selected[drow.id];
+ if (sel) {
+ $(el).find('input.unban').prop("checked", true);
+ }
+ $(el).find('input.unban').on("click", function() {
+ selected[drow.id] = $(this).prop("checked");
+ });
+
+
+ if (drow.expires && drow.expires != 0 && drow.expires < time()) {
+ $(el).find("td").css("text-decoration", "line-through");
+ }
+ });
+
+ var selall = "";
+
+ lt = $("#banlist").longtable({
+ mask: {name: selall+_("IP address"), width: "220px", fmt: function(f) {
+ var pre = "";
+ if (inMod && f.access) {
+ pre = "";
+ }
+
+ if (inMod && f.single_addr && !f.masked) {
+ return pre+""+f.mask+"";
+ }
+ return pre+f.mask;
+ } },
+ reason: {name: _("Reason"), width: "calc(100% - 715px - 6 * 4px)", fmt: function(f) {
+ var add = "", suf = '';
+ if (f.seen == 1) add += "";
+ if (f.message) {
+ add += "";
+ suf = "
"+_("Message:")+"
"+f.message;
+ }
+
+ if (add) { add = "
({% trans 'There are no active bans.' %})
-{% else %} -