From 96495504631d6a4d466b93a835d7d66853e2e12b Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 02:11:41 +1000 Subject: start on mod interface rewrite --- templates/index.html | 6 +++--- templates/login.html | 27 --------------------------- templates/thread.html | 6 +++--- 3 files changed, 6 insertions(+), 33 deletions(-) delete mode 100644 templates/login.html (limited to 'templates') diff --git a/templates/index.html b/templates/index.html index f89199aa..f12e2517 100644 --- a/templates/index.html +++ b/templates/index.html @@ -35,10 +35,10 @@ {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} {% if config.url_banner %}{% endif %}
-

{{ board.url }} - {{ board.name }}

+

{{ board.url }} - {{ board.title }}

- {% if board.title %} - {{ board.title }} + {% if board.subtitle %} + {{ board.subtitle }} {% endif %} {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %}
diff --git a/templates/login.html b/templates/login.html deleted file mode 100644 index 709bad86..00000000 --- a/templates/login.html +++ /dev/null @@ -1,27 +0,0 @@ -{% if error %}

{{ error }}

{% endif %} -
-{% if redirect %}{% endif %} - - - - - - - - - - - - -
- {% trans %}Username{% endtrans %} - - -
- {% trans %}Password{% endtrans %} - - -
- -
-
diff --git a/templates/thread.html b/templates/thread.html index 2708b04d..9a56a50f 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -36,10 +36,10 @@ {% if pm %}
You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

{% endif %} {% if config.url_banner %}{% endif %}
-

{{ board.url }} - {{ board.name }}

+

{{ board.url }} - {{ board.title }}

- {% if board.title %} - {{ board.title }} + {% if board.subtitle %} + {{ board.subtitle }} {% endif %} {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %}
-- cgit v1.3 From 78f3ea783394dba14b51b27f7f2db3974ce8b8b3 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 09:29:08 +1000 Subject: View IP adress page, ban form. --- inc/mod/ban.php | 77 +++++++++++++++++++++++++++++++++++++++++ inc/mod/pages.php | 28 +++++++++++++-- mod.php | 3 +- templates/mod/ban_form.html | 59 ++++++++++++++++++++++++++++++++ templates/mod/dashboard.html | 81 ++++++++++++++++++++++++++++++++++++++++++++ templates/mod/login.html | 26 ++++++++++++++ templates/mod/view_ip.html | 18 ++++++++++ 7 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 inc/mod/ban.php create mode 100644 templates/mod/ban_form.html create mode 100644 templates/mod/dashboard.html create mode 100644 templates/mod/login.html create mode 100644 templates/mod/view_ip.html (limited to 'templates') diff --git a/inc/mod/ban.php b/inc/mod/ban.php new file mode 100644 index 00000000..236b2b14 --- /dev/null +++ b/inc/mod/ban.php @@ -0,0 +1,77 @@ +bindValue(':ip', $mask); + $query->bindValue(':mod', $mod['id']); + if ($reason !== '') + $query->bindValue(':reason', $reason); + else + $query->bindValue(':reason', null, PDO::PARAM_NULL); + + if ($length > 0) + $query->bindValue(':expires', time() + $length); + else + $query->bindValue(':expires', null, PDO::PARAM_NULL); + + if ($board) + $query->bindValue(':board', $board); + else + $query->bindValue(':board', null, PDO::PARAM_NULL); + + $query->execute() or error(db_error($query)); +} diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 9d154181..c00cd672 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -94,12 +94,17 @@ function mod_view_thread($boardName, $thread) { function mod_page_ip($ip) { global $config, $mod; + if(filter_var($ip, FILTER_VALIDATE_IP) === false) + error("Invalid IP address."); + $args = array(); $args['ip'] = $ip; $args['posts'] = array(); $boards = listBoards(); foreach ($boards as $board) { + openBoard($board['uri']); + $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit', $board['uri'])); $query->bindValue(':ip', $ip); $query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT); @@ -122,11 +127,30 @@ function mod_page_ip($ip) { } if (!isset($args['posts'][$board['uri']])) - $args['posts'][$board['uri']] = array(); - $args['posts'][$board['uri']][] = $po->build(true); + $args['posts'][$board['uri']] = array('board' => $board, 'posts' => array()); + $args['posts'][$board['uri']]['posts'][] = $po->build(true); } } + $args['boards'] = $boards; + mod_page("IP: $ip", 'mod/view_ip.html', $args); } +function mod_page_ban() { + if(!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) + error($config['error']['missedafield']); + + $ip = $_POST['ip']; + + require_once 'inc/mod/ban.php'; + + ban($_POST['ip'], $_POST['reason'], parse_time($_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']); +} + diff --git a/mod.php b/mod.php index 0ac83f46..5f2cad56 100644 --- a/mod.php +++ b/mod.php @@ -25,10 +25,11 @@ $pages = array( '!^/$!' => 'dashboard', // dashboard '!^/IP/(.+)$!' => 'ip', // view ip address + '!^/ban$!' => 'ban', // new ban // This should always be at the end: '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '?$!' => 'view_board', - '!^/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!/' => 'view_board', + '!^/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_board', '!^/(\w+)/' . preg_quote($config['dir']['res'], '!') . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_thread', ); diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html new file mode 100644 index 00000000..1b94e725 --- /dev/null +++ b/templates/mod/ban_form.html @@ -0,0 +1,59 @@ +
+ {% if redirect %} + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + + (eg. "2d1h30m" or "2 days")
Board +
    +
  • + + +
  • + + {% for board in boards %} +
  • + + +
  • + {% endfor %} +
+
+
+ diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html new file mode 100644 index 00000000..2a90d709 --- /dev/null +++ b/templates/mod/dashboard.html @@ -0,0 +1,81 @@ +
+ Boards + + +
+ +{% if mod|hasPermission(config.mod.noticeboard) %} +
+ Noticeboard + + {# TODO #} +
+{% endif %} + +
+ Administration + +
    + {% if mod|hasPermission(config.mod.reports) %} +
  • Report queue
  • + {% endif %} + + {% if mod|hasPermission(config.mod.view_banlist) %} +
  • Ban list
  • + {% endif %} + + {% if mod|hasPermission(config.mod.manageusers) %} +
  • Manage users
  • + {% elseif mod|hasPermission(config.mod.change_password) %} +
  • Change password
  • + {% endif %} + + {% if mod|hasPermission(config.mod.modlog) %} +
  • Moderation log
  • + {% endif %} + + {% if mod|hasPermission(config.mod.rebuild) %} +
  • Rebuild
  • + {% if config.cache.enabled %} +
  • Clear cache
  • + {% endif %} + {% endif %} + + {% if mod|hasPermission(config.mod.show_config) %} +
  • Configuration
  • + {% endif %} +
+
+ +{% if mod|hasPermission(config.mod.themes) %} +
+ Themes + + {# TODO #} +
+{% endif %} + +
+ Search + + {# TODO #} +
diff --git a/templates/mod/login.html b/templates/mod/login.html new file mode 100644 index 00000000..5ac308a3 --- /dev/null +++ b/templates/mod/login.html @@ -0,0 +1,26 @@ +{% if error %}

{{ error }}

{% endif %} +
+ + + + + + + + + + + + +
+ {% trans %}Username{% endtrans %} + + +
+ {% trans %}Password{% endtrans %} + + +
+ +
+
diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html new file mode 100644 index 00000000..3b558e4b --- /dev/null +++ b/templates/mod/view_ip.html @@ -0,0 +1,18 @@ +{% for board_posts in posts %} +
+ + {{ config.board_abbreviation|sprintf(board_posts.board.uri) }} + - + {{ board_posts.board.title }} + + {{ board_posts.posts|join('
') }} +
+{% endfor %} + +{% set redirect = '?/IP/' ~ ip %} + +
+ New ban + {% include 'mod/ban_form.html' %} +
+ -- cgit v1.3 From 2843ddc4826f250a8af6203cff437929ab807a41 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 09:47:27 +1000 Subject: view bans / unban --- inc/mod/ban.php | 19 ++++++++---- inc/mod/pages.php | 18 ++++++++++-- inc/template.php | 2 +- templates/mod/view_ip.html | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 9 deletions(-) (limited to 'templates') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 236b2b14..33b64975 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -10,7 +10,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { } function parse_time($str) { - if(empty($str)) + if (empty($str)) return false; if (($time = @strtotime($str)) !== false) @@ -55,16 +55,18 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod; - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, UNIX_TIMESTAMP(), :expires, :reason, :board)"); + $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); - if ($reason !== '') + $query->bindValue(':time', time()); + if ($reason !== '') { + markup($reason); $query->bindValue(':reason', $reason); - else + } else $query->bindValue(':reason', null, PDO::PARAM_NULL); if ($length > 0) - $query->bindValue(':expires', time() + $length); + $query->bindValue(':expires', $length); else $query->bindValue(':expires', null, PDO::PARAM_NULL); @@ -75,3 +77,10 @@ function ban($mask, $reason, $length, $board) { $query->execute() or error(db_error($query)); } + +function unban($id) { + $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); +} + diff --git a/inc/mod/pages.php b/inc/mod/pages.php index c00cd672..e7e4f065 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -94,9 +94,17 @@ function mod_view_thread($boardName, $thread) { function mod_page_ip($ip) { global $config, $mod; - if(filter_var($ip, FILTER_VALIDATE_IP) === false) + if (filter_var($ip, FILTER_VALIDATE_IP) === false) error("Invalid IP address."); + if (isset($_POST['ban_id'], $_POST['unban'])) { + require_once 'inc/mod/ban.php'; + + unban($_POST['ban_id']); + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + return; + } + $args = array(); $args['ip'] = $ip; $args['posts'] = array(); @@ -134,6 +142,11 @@ function mod_page_ip($ip) { $args['boards'] = $boards; + $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); + mod_page("IP: $ip", 'mod/view_ip.html', $args); } @@ -147,8 +160,7 @@ function mod_page_ban() { ban($_POST['ip'], $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']); - - if(isset($_POST['redirect'])) + if (isset($_POST['redirect'])) header('Location: ' . $_POST['redirect'], true, $config['redirect_http']); else header('Location: ?/', true, $config['redirect_http']); diff --git a/inc/template.php b/inc/template.php index 8d679d25..ab220454 100644 --- a/inc/template.php +++ b/inc/template.php @@ -26,7 +26,7 @@ function load_twig() { $loader->setPaths($config['dir']['template']); $twig = new Twig_Environment($loader, array( 'autoescape' => false, - 'cache' => "{$config['dir']['template']}/cache", + //'cache' => "{$config['dir']['template']}/cache", 'debug' => ($config['debug'] ? true : false), )); $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index 3b558e4b..a9676dd7 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -11,6 +11,79 @@ {% set redirect = '?/IP/' ~ ip %} +{% if bans|count > 0 %} +
+ Ban{% if bans|count != 1 %}s{% endif %} on record + + {% for ban in bans %} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Status + {% if config.mod.view_banexpired and ban.expires != 0 and ban.expires < time() %} + Expired + {% else %} + Active + {% endif %} +
IP{{ ban.ip }}
Reason + {% if ban.reason %} + {{ ban.reason }} + {% else %} + no reason + {% endif %} +
Board + {% if ban.board %} + {{ config.board_abbreviation|sprintf(ban.board) }} + {% else %} + all boards + {% endif %} +
Set{{ ban.set|date(config.post_date) }}
Expires + {% if ban.expires %} + {{ ban.expires|date(config.post_date) }} + {% else %} + never + {% endif %} +
Staff + {% if ban.username %} + {{ ban.username }} + {% else %} + deleted? + {% endif %} +
+ + +
+ {% endfor %} +
+{% endif %} +
New ban {% include 'mod/ban_form.html' %} -- cgit v1.3 From 7f6f836bf85350fe92d3975d2fb3973343923aeb Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 10:41:30 +1000 Subject: IP notes --- inc/mod/ban.php | 4 +++ inc/mod/pages.php | 90 +++++++++++++++++++++++++++++++++++++++++++--- mod.php | 15 +++++--- templates/mod/confirm.html | 7 ++++ templates/mod/log.html | 11 ++++++ templates/mod/view_ip.html | 80 +++++++++++++++++++++++++++++++++++++---- 6 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 templates/mod/confirm.html create mode 100644 templates/mod/log.html (limited to 'templates') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 33b64975..8d86cbcd 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -55,6 +55,8 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod; + // TODO: permissions + $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); @@ -79,6 +81,8 @@ function ban($mask, $reason, $length, $board) { } function unban($id) { + // TODO: permissions + $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); diff --git a/inc/mod/pages.php b/inc/mod/pages.php index e7e4f065..73015cf9 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -52,7 +52,11 @@ function mod_login() { if (isset($_POST['username'])) $args['username'] = $_POST['username']; - mod_page('Dashboard', 'mod/login.html', $args); + mod_page('Login', 'mod/login.html', $args); +} + +function mod_confirm($request) { + mod_page('Confirm action', 'mod/confirm.html', array('request' => $request)); } function mod_dashboard() { @@ -63,6 +67,21 @@ function mod_dashboard() { mod_page('Dashboard', 'mod/dashboard.html', $args); } +function mod_log($page_no = 1) { + global $config; + + if (!hasPermission($config['mod']['modlog'])) + error($config['error']['noaccess']); + + $query = prepare("SELECT `username`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); + $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $logs = $query->fetchAll(PDO::FETCH_ASSOC); + + mod_page('Moderation log', 'mod/log.html', array('logs' => $logs)); +} + function mod_view_board($boardName, $page_no = 1) { global $config, $mod; @@ -91,6 +110,20 @@ function mod_view_thread($boardName, $thread) { echo $page; } +function mod_ip_remove_note($ip, $id) { + global $config, $mod; + + if (filter_var($ip, FILTER_VALIDATE_IP) === false) + error("Invalid IP address."); + + $query = prepare('DELETE FROM `ip_notes` WHERE `ip` = :ip AND `id` = :id'); + $query->bindValue(':ip', $ip); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); +} + function mod_page_ip($ip) { global $config, $mod; @@ -105,6 +138,21 @@ function mod_page_ip($ip) { return; } + if (isset($_POST['note'])) { + // TODO: permissions + + markup($_POST['note']); + $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); + $query->bindValue(':ip', $ip); + $query->bindValue(':mod', $mod['id']); + $query->bindValue(':time', time()); + $query->bindValue(':body', $_POST['note']); + $query->execute() or error(db_error($query)); + + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + return; + } + $args = array(); $args['ip'] = $ip; $args['posts'] = array(); @@ -145,14 +193,26 @@ function mod_page_ip($ip) { $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); + $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); + + $query = prepare("SELECT `ip_notes`.*, `username` FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query->bindValue(':ip', $ip); + $query->execute() or error(db_error($query)); + $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); mod_page("IP: $ip", 'mod/view_ip.html', $args); } -function mod_page_ban() { - if(!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) - error($config['error']['missedafield']); +function mod_ban() { + if (!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) { + mod_page("New ban", 'mod/ban_form.html', array()); + 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']; @@ -166,3 +226,23 @@ function mod_page_ban() { header('Location: ?/', true, $config['redirect_http']); } +function mod_delete($board, $post) { + global $config, $mod; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['delete'], $board)) + error($config['error']['noaccess']); + + // Delete post + deletePost($post); + // Record the action + modLog("Deleted post #{$post}"); + // Rebuild board + buildIndex(); + + // Redirect + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + diff --git a/mod.php b/mod.php index 5f2cad56..c89c2f01 100644 --- a/mod.php +++ b/mod.php @@ -21,11 +21,18 @@ if (get_magic_quotes_gpc()) { $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $pages = array( - '!^$!' => ':?/', // redirect to dashboard - '!^/$!' => 'dashboard', // dashboard + '!^$!' => ':?/', // redirect to dashboard + '!^/$!' => 'dashboard', // dashboard + '!^/log$!' => 'log', // modlog + '!^/log/(\d+)/$!' => 'log', // modlog - '!^/IP/(.+)$!' => 'ip', // view ip address - '!^/ban$!' => 'ban', // new ban + '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) + + '!^/ban$!' => 'ban', // new ban + '!^/IP/([\w.:]+)$!' => 'ip', // view ip address + '!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address + + '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post // This should always be at the end: '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '?$!' => 'view_board', diff --git a/templates/mod/confirm.html b/templates/mod/confirm.html new file mode 100644 index 00000000..7509ce3c --- /dev/null +++ b/templates/mod/confirm.html @@ -0,0 +1,7 @@ +

+ Are you sure you want to do that? Click to proceed to ?/{{ request }}. +

+

+ You are seeing this message because we were unable to serve a confirmation dialog, probably due to Javascript being disabled. +

+ diff --git a/templates/mod/log.html b/templates/mod/log.html new file mode 100644 index 00000000..2aa0ea0a --- /dev/null +++ b/templates/mod/log.html @@ -0,0 +1,11 @@ + + + + + {% for log in logs %} + + {% endfor %} +
+ +
+ diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index a9676dd7..3bc9654c 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -9,9 +9,73 @@
{% endfor %} -{% set redirect = '?/IP/' ~ ip %} +{% if mod|hasPermission(config.mod.view_notes) %} +
+ + {{ notes|count }} note{% if notes|count != 1 %}s{% endif %} on record + + + {% if notes|count > 0 %} + + + + + + {% if mod|hasPermission(config.mod.remove_notes) %} + + {% endif %} + + {% for note in notes %} + + + + + {% if mod|hasPermission(config.mod.remove_notes) %} + + {% endif %} + + {% endfor %} +
StaffNoteDateActions
+ {% if note.username %} + {{ note.username }} + {% else %} + deleted? + {% endif %} + + {{ note.body }} + + {{ note.time|date(config.post_date) }} + + [remove] +
+ {% endif %} + + {% if mod|hasPermission(config.mod.create_notes) %} +
+ + + + + + + + + + + + + +
Staff{{ mod.username }}
+ + + +
+
+ {% endif %} +
+{% endif %} -{% if bans|count > 0 %} +{% if bans|count > 0 and mod|hasPermission(config.mod.view_ban) %}
Ban{% if bans|count != 1 %}s{% endif %} on record @@ -84,8 +148,10 @@
{% endif %} -
- New ban - {% include 'mod/ban_form.html' %} -
- +{% if mod|hasPermission(config.mod.ban) %} +
+ New ban + {% set redirect = '?/IP/' ~ ip %} + {% include 'mod/ban_form.html' %} +
+{% endif %} -- cgit v1.3 From e92ee2b4879d110f4076c17c0033267dfbbc9197 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 20:48:37 +1000 Subject: moderation log --- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 1 + templates/mod/log.html | 30 +++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'templates') diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index cbb2e752..4111fc3c 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -21,6 +21,7 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension 'poster_id' => new Twig_Filter_Function('poster_id', array('needs_environment' => false)), 'remove_whitespace' => new Twig_Filter_Function('twig_remove_whitespace_filter', array('needs_environment' => false)), 'count' => new Twig_Filter_Function('count', array('needs_environment' => false)), + 'ago' => new Twig_Filter_Function('ago', array('needs_environment' => false)), 'until' => new Twig_Filter_Function('until', array('needs_environment' => false)) ); } diff --git a/templates/mod/log.html b/templates/mod/log.html index 2aa0ea0a..4f2beb40 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -1,11 +1,33 @@ - + + + + + {% for log in logs %} - + + + + + + + {% endfor %}
- - StaffIP addressAgoBoardAction
+ {{ log.username }} + + {{ log.ip }} + + {{ log.time|ago }} + + {% if log.board %} + {{ config.board_abbreviation|sprintf(log.board) }} + {% else %} + - + {% endif %} + + {{ log.text }} +
-- cgit v1.3 From d1876a0dd66422570409787bae40aad371011b89 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 20:57:59 +1000 Subject: paginate moderation log --- inc/mod/pages.php | 6 +++++- mod.php | 2 +- templates/mod/log.html | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 73015cf9..942cfd50 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -79,7 +79,11 @@ function mod_log($page_no = 1) { $query->execute() or error(db_error($query)); $logs = $query->fetchAll(PDO::FETCH_ASSOC); - mod_page('Moderation log', 'mod/log.html', array('logs' => $logs)); + $query = prepare("SELECT COUNT(*) AS `count` FROM `modlogs`"); + $query->execute() or error(db_error($query)); + $count = $query->fetchColumn(0); + + mod_page('Moderation log', 'mod/log.html', array('logs' => $logs, 'count' => $count)); } function mod_view_board($boardName, $page_no = 1) { diff --git a/mod.php b/mod.php index c89c2f01..3aba6fe4 100644 --- a/mod.php +++ b/mod.php @@ -24,7 +24,7 @@ $pages = array( '!^$!' => ':?/', // redirect to dashboard '!^/$!' => 'dashboard', // dashboard '!^/log$!' => 'log', // modlog - '!^/log/(\d+)/$!' => 'log', // modlog + '!^/log/(\d+)$!' => 'log', // modlog '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) diff --git a/templates/mod/log.html b/templates/mod/log.html index 4f2beb40..fe1c5c1f 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -31,3 +31,9 @@ {% endfor %} +

+ {% for i in range(0, count / config.mod.modlog_page) %} + [{{ i + 1 }}] + {% endfor %} +

+ -- cgit v1.3 From 761cb4feab1a052e2e611a1d09d0a3513e011c06 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 21:43:01 +1000 Subject: ?/users (user list) --- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 45 +++++++++++++++---------- inc/mod/pages.php | 12 +++++++ mod.php | 4 ++- templates/mod/log.html | 12 ++++--- 4 files changed, 50 insertions(+), 23 deletions(-) (limited to 'templates') diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index 4111fc3c..2691cc55 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -10,19 +10,21 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension public function getFilters() { return Array( - 'filesize' => new Twig_Filter_Function('format_bytes', Array('needs_environment' => false)), - 'truncate' => new Twig_Filter_Function('twig_truncate_filter', array('needs_environment' => false)), - 'truncate_body' => new Twig_Filter_Function('truncate', array('needs_environment' => false)), - 'extension' => new Twig_Filter_Function('twig_extension_filter', array('needs_environment' => false)), - 'sprintf' => new Twig_Filter_Function('sprintf', array('needs_environment' => false)), - 'capcode' => new Twig_Filter_Function('capcode', array('needs_environment' => false)), - 'hasPermission' => new Twig_Filter_Function('twig_hasPermission_filter', array('needs_environment' => false)), - 'date' => new Twig_Filter_Function('twig_date_filter', array('needs_environment' => false)), - 'poster_id' => new Twig_Filter_Function('poster_id', array('needs_environment' => false)), - 'remove_whitespace' => new Twig_Filter_Function('twig_remove_whitespace_filter', array('needs_environment' => false)), - 'count' => new Twig_Filter_Function('count', array('needs_environment' => false)), - 'ago' => new Twig_Filter_Function('ago', array('needs_environment' => false)), - 'until' => new Twig_Filter_Function('until', array('needs_environment' => false)) + 'filesize' => new Twig_Filter_Function('format_bytes'), + 'truncate' => new Twig_Filter_Function('twig_truncate_filter'), + 'truncate_body' => new Twig_Filter_Function('truncate'), + 'extension' => new Twig_Filter_Function('twig_extension_filter'), + 'sprintf' => new Twig_Filter_Function('sprintf'), + 'capcode' => new Twig_Filter_Function('capcode'), + 'hasPermission' => new Twig_Filter_Function('twig_hasPermission_filter'), + 'date' => new Twig_Filter_Function('twig_date_filter'), + 'poster_id' => new Twig_Filter_Function('poster_id'), + 'remove_whitespace' => new Twig_Filter_Function('twig_remove_whitespace_filter'), + 'count' => new Twig_Filter_Function('count'), + 'ago' => new Twig_Filter_Function('ago'), + 'until' => new Twig_Filter_Function('until'), + 'split' => new Twig_Filter_Function('twig_split_filter'), + 'push' => new Twig_Filter_Function('twig_push_filter'), ); } @@ -34,10 +36,10 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension public function getFunctions() { return Array( - 'time' => new Twig_Filter_Function('time', array('needs_environment' => false)), - 'timezone' => new Twig_Filter_Function('twig_timezone_function', array('needs_environment' => false)), - 'hiddenInputs' => new Twig_Filter_Function('hiddenInputs', array('needs_environment' => false)), - 'hiddenInputsHash' => new Twig_Filter_Function('hiddenInputsHash', array('needs_environment' => false)) + 'time' => new Twig_Filter_Function('time'), + 'timezone' => new Twig_Filter_Function('twig_timezone_function'), + 'hiddenInputs' => new Twig_Filter_Function('hiddenInputs'), + 'hiddenInputsHash' => new Twig_Filter_Function('hiddenInputsHash'), ); } @@ -57,6 +59,15 @@ function twig_timezone_function() { return sprintf("%s%02d", ($hr = (int)floor(($tz = date('Z')) / 3600)) > 0 ? '+' : '-', abs($hr)) . ':' . sprintf("%02d", (($tz / 3600) - $hr) * 60); } +function twig_split_filter($str, $delim) { + return explode($delim, $str); +} + +function twig_push_filter($array, $value) { + array_push($array, $value); + return $array; +} + function twig_remove_whitespace_filter($data) { return preg_replace('/[\t\r\n]/', '', $data); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 942cfd50..2b5487fd 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -250,3 +250,15 @@ function mod_delete($board, $post) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } +function mod_users() { + global $config; + if(!hasPermission($config['mod']['manageusers'])) + error($config['error']['noaccess']); + + $args = array(); + $query = query("SELECT *, (SELECT `time` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM `mods` ORDER BY `type` DESC,`id`") or error(db_error()); + $args['users'] = $query->fetchAll(PDO::FETCH_ASSOC); + + mod_page("Manage users", 'mod/users.html', $args); +} + diff --git a/mod.php b/mod.php index 3aba6fe4..d95f9552 100644 --- a/mod.php +++ b/mod.php @@ -23,10 +23,12 @@ $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $pages = array( '!^$!' => ':?/', // redirect to dashboard '!^/$!' => 'dashboard', // dashboard + '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) '!^/log$!' => 'log', // modlog '!^/log/(\d+)$!' => 'log', // modlog + + '!^/users$!' => 'users', // manage users - '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) '!^/ban$!' => 'ban', // new ban '!^/IP/([\w.:]+)$!' => 'ip', // view ip address diff --git a/templates/mod/log.html b/templates/mod/log.html index fe1c5c1f..61243202 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -31,9 +31,11 @@ {% endfor %} -

- {% for i in range(0, count / config.mod.modlog_page) %} - [{{ i + 1 }}] - {% endfor %} -

+{% if count > logs|count %} +

+ {% for i in range(0, count / config.mod.modlog_page) %} + [{{ i + 1 }}] + {% endfor %} +

+{% endif %} -- cgit v1.3 From e49ece459e2ee225ba677f8e0758a38a98b930f5 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 22:00:40 +1000 Subject: new PM --- inc/mod/auth.php | 13 ++++++++++++ inc/mod/pages.php | 33 +++++++++++++++++++++++++++-- mod.php | 2 +- templates/mod/new_pm.html | 22 +++++++++++++++++++ templates/mod/users.html | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 templates/mod/new_pm.html create mode 100644 templates/mod/users.html (limited to 'templates') diff --git a/inc/mod/auth.php b/inc/mod/auth.php index 2e90b757..f9b863c8 100644 --- a/inc/mod/auth.php +++ b/inc/mod/auth.php @@ -122,3 +122,16 @@ if (isset($_COOKIE[$config['cookies']['mod']])) { ); } +function create_pm_header() { + global $mod; + $query = prepare("SELECT `id` FROM `pms` WHERE `to` = :id AND `unread` = 1"); + $query->bindValue(':id', $mod['id'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + if ($pm = $query->fetch()) { + return Array('id' => $pm['id'], 'waiting' => $query->rowCount() - 1); + } + + return false; +} + diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 2b5487fd..4903567a 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -252,13 +252,42 @@ function mod_delete($board, $post) { function mod_users() { global $config; - if(!hasPermission($config['mod']['manageusers'])) + + if (!hasPermission($config['mod']['manageusers'])) error($config['error']['noaccess']); $args = array(); $query = query("SELECT *, (SELECT `time` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM `mods` ORDER BY `type` DESC,`id`") or error(db_error()); $args['users'] = $query->fetchAll(PDO::FETCH_ASSOC); - mod_page("Manage users", 'mod/users.html', $args); + mod_page('Manage users', 'mod/users.html', $args); +} + +function mod_new_pm($username) { + global $config, $mod; + + if (!hasPermission($config['mod']['create_pm'])) + error($config['error']['noaccess']); + + $query = prepare("SELECT `id` FROM `mods` WHERE `username` = :username"); + $query->bindValue(':username', $username); + $query->execute() or error(db_error($query)); + if (!$id = $query->fetchColumn(0)) + error($config['error']['404']); + + if (isset($_POST['message'])) { + markup($_POST['message']); + + $query = prepare("INSERT INTO `pms` VALUES (NULL, :me, :id, :message, :time, 1)"); + $query->bindValue(':me', $mod['id']); + $query->bindValue(':id', $id); + $query->bindValue(':message', $_POST['message']); + $query->bindValue(':time', time()); + $query->execute() or error(db_error($query)); + + header('Location: ?/', true, $config['redirect_http']); + } + + mod_page("New PM for {$username}", 'mod/new_pm.html', array('username' => $username, 'id' => $id)); } diff --git a/mod.php b/mod.php index d95f9552..e7134603 100644 --- a/mod.php +++ b/mod.php @@ -28,7 +28,7 @@ $pages = array( '!^/log/(\d+)$!' => 'log', // modlog '!^/users$!' => 'users', // manage users - + '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm '!^/ban$!' => 'ban', // new ban '!^/IP/([\w.:]+)$!' => 'ip', // view ip address diff --git a/templates/mod/new_pm.html b/templates/mod/new_pm.html new file mode 100644 index 00000000..d694bc26 --- /dev/null +++ b/templates/mod/new_pm.html @@ -0,0 +1,22 @@ +{#{% if id == mod.id %} + {% set username = 'me' %} +{% endif %}#} + +
+ + + + {% if mod|hasPermission(config.mod.editusers) %} + + {% else %} + + {% endif %} + + + + + +
To{{ username|e }}{{ username|e }}
Message
+ +

+
diff --git a/templates/mod/users.html b/templates/mod/users.html new file mode 100644 index 00000000..aeacc8b5 --- /dev/null +++ b/templates/mod/users.html @@ -0,0 +1,54 @@ + + + + + + + + + + + {% for user in users %} + + + + + + + + + {% endfor %} +
IDUsernameTypeBoardsLast action…
{{ user.id }}{{ user.username }} + {% if user.type == constant('JANITOR') %}Janitor + {% elseif user.type == constant('MOD') %}Mod + {% elseif user.type == constant('ADMIN') %}Admin + {% endif %} + + {# This is really messy, but IMO it beats doing it in PHP. #} + {% set boards = user.boards|split(',') %} + {% set _boards = [] %} + {% for board in boards %} + {% set _boards = _boards|push(board == '*' ? '*' : config.board_abbreviation|sprintf(board)) %} + {% endfor %} + {% set _boards = _boards|sort %} + {{ _boards|join(', ') }} + + {% if mod|hasPermission(config.mod.modlog) %} + {{ user.last|ago }} + {% else %} + – + {% endif %} + + {% if mod|hasPermission(config.mod.promoteusers) and user.type < constant('ADMIN') %} + ▲ + {% endif %} + {% if mod|hasPermission(config.mod.promoteusers) and user.type > constant('JANITOR') %} + ▼ + {% endif %} + {% if mod|hasPermission(config.editusers) or (mod|hasPermission(config.change_password) and mod.id == user.id) %} + [edit] + {% endif %} + {% if mod|hasPermission(config.mod.create_pm) %} + [PM] + {% endif %} +
-- cgit v1.3 From 87281687ed3ed06fd76d7bbb6c29404bb883418a Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 14 Apr 2012 22:28:21 +1000 Subject: promote/demote users, started on rebuild --- inc/mod/pages.php | 67 ++++++++++++++++++++++++++++++++++++------- inc/template.php | 2 +- mod.php | 3 ++ templates/mod/rebuild.html | 71 ++++++++++++++++++++++++++++++++++++++++++++++ templates/mod/users.html | 6 +++- 5 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 templates/mod/rebuild.html (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 4903567a..d78ebf0d 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -143,7 +143,12 @@ function mod_page_ip($ip) { } if (isset($_POST['note'])) { - // TODO: permissions + if (hasPermission($config['mod']['create_notes'])) { + $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); + } markup($_POST['note']); $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); @@ -194,20 +199,30 @@ function mod_page_ip($ip) { $args['boards'] = $boards; - $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); - $query = prepare("SELECT `ip_notes`.*, `username` FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); - $query->bindValue(':ip', $ip); - $query->execute() or error(db_error($query)); - $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); + if (hasPermission($config['mod']['view_ban'])) { + $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); + } + + if (hasPermission($config['mod']['view_notes'])) { + $query = prepare("SELECT `ip_notes`.*, `username` FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query->bindValue(':ip', $ip); + $query->execute() or error(db_error($query)); + $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); + } mod_page("IP: $ip", 'mod/view_ip.html', $args); } function mod_ban() { + global $config; + + if (!hasPermission($config['mod']['ban'])) + error($config['error']['noaccess']); + if (!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) { mod_page("New ban", 'mod/ban_form.html', array()); return; @@ -263,6 +278,19 @@ function mod_users() { mod_page('Manage users', 'mod/users.html', $args); } +function mod_user_promote($uid, $action) { + global $config; + + if (!hasPermission($config['mod']['promoteusers'])) + error($config['error']['noaccess']); + + $query = prepare("UPDATE `mods` SET `type` = `type` " . ($action == 'promote' ? "+1 WHERE `type` < " . (int)ADMIN : "-1 WHERE `type` > " . (int)JANITOR) . " AND `id` = :id"); + $query->bindValue(':id', $uid); + $query->execute() or error(db_error($query)); + + header('Location: ?/users', true, $config['redirect_http']); +} + function mod_new_pm($username) { global $config, $mod; @@ -272,8 +300,16 @@ function mod_new_pm($username) { $query = prepare("SELECT `id` FROM `mods` WHERE `username` = :username"); $query->bindValue(':username', $username); $query->execute() or error(db_error($query)); - if (!$id = $query->fetchColumn(0)) - error($config['error']['404']); + if (!$id = $query->fetchColumn(0)) { + // Old style ?/PM: by user ID + $query = prepare("SELECT `username` FROM `mods` WHERE `id` = :username"); + $query->bindValue(':username', $username); + $query->execute() or error(db_error($query)); + if ($username = $query->fetchColumn(0)) + header('Location: ?/new_PM/' . $username, true, $config['redirect_http']); + else + error($config['error']['404']); + } if (isset($_POST['message'])) { markup($_POST['message']); @@ -291,3 +327,12 @@ function mod_new_pm($username) { mod_page("New PM for {$username}", 'mod/new_pm.html', array('username' => $username, 'id' => $id)); } +function mod_rebuild() { + global $config; + + if (!hasPermission($config['mod']['rebuild'])) + error($config['error']['noaccess']); + + mod_page("Rebuild", 'mod/rebuild.html', array('boards' => listBoards())); +} + diff --git a/inc/template.php b/inc/template.php index ab220454..8d679d25 100644 --- a/inc/template.php +++ b/inc/template.php @@ -26,7 +26,7 @@ function load_twig() { $loader->setPaths($config['dir']['template']); $twig = new Twig_Environment($loader, array( 'autoescape' => false, - //'cache' => "{$config['dir']['template']}/cache", + 'cache' => "{$config['dir']['template']}/cache", 'debug' => ($config['debug'] ? true : false), )); $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); diff --git a/mod.php b/mod.php index e7134603..f641d371 100644 --- a/mod.php +++ b/mod.php @@ -28,8 +28,11 @@ $pages = array( '!^/log/(\d+)$!' => 'log', // modlog '!^/users$!' => 'users', // manage users + '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm + '!^/rebuild$!' => 'rebuild', // rebuild static files + '!^/ban$!' => 'ban', // new ban '!^/IP/([\w.:]+)$!' => 'ip', // view ip address '!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address diff --git a/templates/mod/rebuild.html b/templates/mod/rebuild.html new file mode 100644 index 00000000..763eb624 --- /dev/null +++ b/templates/mod/rebuild.html @@ -0,0 +1,71 @@ +
+
    +
  • + + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
+ +
+ +
    +
  • + + + +
  • + {% for board in boards %} +
  • + + +
  • + {% endfor %} +
+ +

+ +

+
diff --git a/templates/mod/users.html b/templates/mod/users.html index aeacc8b5..63d799d5 100644 --- a/templates/mod/users.html +++ b/templates/mod/users.html @@ -30,7 +30,11 @@ {% if mod|hasPermission(config.mod.modlog) %} - {{ user.last|ago }} + {% if user.last %} + {{ user.last|ago }} + {% else %} + never + {% endif %} {% else %} – {% endif %} -- cgit v1.3 From de8cc487d81e7cb9a00acee30962aa1933c0c0c6 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 14 Apr 2012 22:58:36 +1000 Subject: rebuild --- inc/mod/pages.php | 62 ++++++++++++++++++++++++++++++++++++++++------ templates/mod/rebuild.html | 2 +- templates/mod/rebuilt.html | 12 +++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 templates/mod/rebuilt.html (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index d78ebf0d..d8352671 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -117,6 +117,9 @@ function mod_view_thread($boardName, $thread) { function mod_ip_remove_note($ip, $id) { global $config, $mod; + if (!hasPermission($config['mod']['remove_notes'])) + error($config['error']['noaccess']); + if (filter_var($ip, FILTER_VALIDATE_IP) === false) error("Invalid IP address."); @@ -135,6 +138,9 @@ function mod_page_ip($ip) { error("Invalid IP address."); if (isset($_POST['ban_id'], $_POST['unban'])) { + if (!hasPermission($config['mod']['unban'])) + error($config['error']['noaccess']); + require_once 'inc/mod/ban.php'; unban($_POST['ban_id']); @@ -143,12 +149,8 @@ function mod_page_ip($ip) { } if (isset($_POST['note'])) { - if (hasPermission($config['mod']['create_notes'])) { - $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); - } + if (!hasPermission($config['mod']['create_notes'])) + error($config['error']['noaccess']); markup($_POST['note']); $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); @@ -328,11 +330,57 @@ function mod_new_pm($username) { } function mod_rebuild() { - global $config; + global $config, $twig; if (!hasPermission($config['mod']['rebuild'])) error($config['error']['noaccess']); + if (isset($_POST['rebuild'])) { + $log = array(); + $boards = listBoards(); + $rebuilt_scripts = array(); + + if (isset($_POST['rebuild_cache'])) { + $log[] = 'Clearing template cache'; + load_twig(); + $twig->clearCacheFiles(); + } + + if (isset($_POST['rebuild_themes'])) { + $log[] = 'Regenerating theme files'; + rebuildThemes('all'); + } + + if (isset($_POST['rebuild_javascript'])) { + $log[] = 'Rebuilding ' . $config['file_script'] . ''; + buildJavascript(); + $rebuilt_scripts[] = $config['file_script']; + } + + foreach ($boards as $board) { + if (!(isset($_POST['boards_all']) || isset($_POST['boards_' . $board['uri']]))) + continue; + + openBoard($board['uri']); + $log[] = '' . sprintf($config['board_abbreviation'], $board['uri']) . ': Creating index pages'; + + if (!in_array($config['file_script'], $rebuilt_scripts)) { + $log[] = '' . sprintf($config['board_abbreviation'], $board['uri']) . ': Rebuilding ' . $config['file_script'] . ''; + buildJavascript(); + $rebuilt_scripts[] = $config['file_script']; + } + + $query = query(sprintf("SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); + while($post = $query->fetch()) { + $log[] = '' . sprintf($config['board_abbreviation'], $board['uri']) . ': Rebuilding thread #' . $post['id']; + buildThread($post['id']); + } + } + + mod_page("Rebuild", 'mod/rebuilt.html', array('logs' => $log)); + return; + } + mod_page("Rebuild", 'mod/rebuild.html', array('boards' => listBoards())); } diff --git a/templates/mod/rebuild.html b/templates/mod/rebuild.html index 763eb624..7a586b95 100644 --- a/templates/mod/rebuild.html +++ b/templates/mod/rebuild.html @@ -66,6 +66,6 @@

- +

diff --git a/templates/mod/rebuilt.html b/templates/mod/rebuilt.html new file mode 100644 index 00000000..8cc10bf9 --- /dev/null +++ b/templates/mod/rebuilt.html @@ -0,0 +1,12 @@ +
+

Rebuilt

+
    + {% for log in logs %} +
  • {{ log }}
  • + {% endfor %} +
+

+ Go back and rebuild again. +

+
+ -- cgit v1.3 From fb3e8191328c12bc1ab5bce8a3aef58582ee1a64 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 15 Apr 2012 20:06:24 +1000 Subject: styling of ?/rebuild --- templates/mod/rebuild.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/mod/rebuild.html b/templates/mod/rebuild.html index 7a586b95..856855d7 100644 --- a/templates/mod/rebuild.html +++ b/templates/mod/rebuild.html @@ -1,4 +1,4 @@ -
+
  • -- cgit v1.3 From ad55a634bf3f9301489f5371942c73940361a24c Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 16:40:24 +1000 Subject: various improvements --- inc/mod/ban.php | 41 +++++++++-------- inc/mod/pages.php | 105 +++++++++++++++++++++++++++++++++++++++----- mod.php | 4 +- stylesheets/style.css | 15 ++++--- templates/mod/ban_list.html | 74 +++++++++++++++++++++++++++++++ templates/mod/new_pm.html | 4 +- templates/mod/pm.html | 41 +++++++++++++++++ 7 files changed, 247 insertions(+), 37 deletions(-) create mode 100644 templates/mod/ban_list.html create mode 100644 templates/mod/pm.html (limited to 'templates') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 8d86cbcd..e7110edf 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -16,44 +16,45 @@ function parse_time($str) { if (($time = @strtotime($str)) !== false) 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; - $expire = time(); - if (isset($m[2])) { + $expire = 0; + + if (isset($matches[2])) { // Years - $expire += $m[2]*60*60*24*365; + $expire += $matches[2]*60*60*24*365; } - if (isset($m[4])) { + if (isset($matches[4])) { // Months - $expire += $m[4]*60*60*24*30; + $expire += $matches[4]*60*60*24*30; } - if (isset($m[6])) { + if (isset($matches[6])) { // Weeks - $expire += $m[6]*60*60*24*7; + $expire += $matches[6]*60*60*24*7; } - if (isset($m[8])) { + if (isset($matches[8])) { // Days - $expire += $m[8]*60*60*24; + $expire += $matches[8]*60*60*24; } - if (isset($m[10])) { + if (isset($matches[10])) { // Hours - $expire += $m[10]*60*60; + $expire += $matches[10]*60*60; } - if (isset($m[12])) { + if (isset($matches[12])) { // Minutes - $expire += $m[12]*60; + $expire += $matches[12]*60; } - if (isset($m[14])) { + if (isset($matches[14])) { // Seconds - $expire += $m[14]; + $expire += $matches[14]; } - return $expire; + return time() + $expire; } function ban($mask, $reason, $length, $board) { - global $mod; + global $mod, $pdo; // TODO: permissions @@ -78,6 +79,8 @@ function ban($mask, $reason, $length, $board) { $query->bindValue(':board', null, PDO::PARAM_NULL); $query->execute() or error(db_error($query)); + + modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . $reason . '' : 'no reason')); } function unban($id) { @@ -86,5 +89,7 @@ function unban($id) { $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); + + modLog("Removed ban #{$id}"); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 7518b9fb..60f101ea 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -39,7 +39,7 @@ function mod_login() { $args['error'] = $config['error']['invalid']; } else { - modLog("Logged in."); + modLog('Logged in'); // Login successful // Set cookies @@ -101,6 +101,7 @@ function mod_view_board($boardName, $page_no = 1) { $page['btn'] = getPageButtons($page['pages'], true); $page['mod'] = true; $page['config'] = $config; + echo Element('index.html', $page); } @@ -128,6 +129,8 @@ function mod_ip_remove_note($ip, $id) { $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); + modLog("Removed a note for {$ip}"); + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); } @@ -160,6 +163,8 @@ function mod_page_ip($ip) { $query->bindValue(':body', $_POST['note']); $query->execute() or error(db_error($query)); + modLog("Added a note for {$ip}"); + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); return; } @@ -177,8 +182,9 @@ function mod_page_ip($ip) { $query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { if (!$post['thread']) { + // TODO: There is no reason why this should be such a fucking mess. $po = new Thread( $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'], @@ -230,13 +236,6 @@ function mod_ban() { 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'; 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']); } +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) { global $config, $mod; @@ -290,9 +334,48 @@ function mod_user_promote($uid, $action) { $query->bindValue(':id', $uid); $query->execute() or error(db_error($query)); + modLog(($action == 'promote' ? 'Promoted' : 'Demoted') . " user #{$uid}"); + 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 – #$id", 'mod/pm.html', $pm); + } +} + function mod_new_pm($username) { global $config, $mod; @@ -323,6 +406,8 @@ function mod_new_pm($username) { $query->bindValue(':time', time()); $query->execute() or error(db_error($query)); + modLog('Sent a PM to ' . utf8tohtml($username)); + 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()); - while($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $log[] = '' . sprintf($config['board_abbreviation'], $board['uri']) . ': Rebuilding thread #' . $post['id']; buildThread($post['id']); } diff --git a/mod.php b/mod.php index f641d371..6fc216f8 100644 --- a/mod.php +++ b/mod.php @@ -26,16 +26,18 @@ $pages = array( '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) '!^/log$!' => 'log', // modlog '!^/log/(\d+)$!' => 'log', // modlog - + '!^/users$!' => 'users', // manage users '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm + '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm '!^/rebuild$!' => 'rebuild', // rebuild static files '!^/ban$!' => 'ban', // new ban '!^/IP/([\w.:]+)$!' => 'ip', // view 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 diff --git a/stylesheets/style.css b/stylesheets/style.css index d77f05b5..edebf0c1 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -68,15 +68,18 @@ form table input { } input[type="text"], input[type="password"], textarea { border: 1px solid #a9a9a9; - text-indent: 0px; + text-indent: 0; text-shadow: none; text-transform: none; word-spacing: normal; } form table tr td { text-align: left; - margin: 0px; - padding: 0px; + margin: 0; + padding: 0; +} +form table.mod tr td { + padding: 2px; } form table tr th { text-align: left; @@ -102,7 +105,7 @@ form table tr td div label { } p.fileinfo { display: block; - margin: 0px; + margin: 0; padding-right: 7em; } div.banner { @@ -326,7 +329,7 @@ div.pages form input { hr { border: none; border-top: 1px solid #B7C5D9; - height: 0px; + height: 0; clear: left; } div.boardlist { @@ -349,7 +352,7 @@ table.modlog { } table.modlog tr td { text-align: left; - margin: 0px; + margin: 0; padding: 4px 15px 0 0; } table.modlog tr th { diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html new file mode 100644 index 00000000..00b8a0f4 --- /dev/null +++ b/templates/mod/ban_list.html @@ -0,0 +1,74 @@ +{% if bans|count == 0 %} +

    (There are no active bans.)

    +{% else %} + + + + + + + + + + + {% for ban in bans %} + + + + + + + + + {% endfor %} +
    {% trans %}IP address{% endtrans %}{% trans %}Reason{% endtrans %}{% trans %}Board{% endtrans %}{% trans %}Set{% endtrans %}{% trans %}Expires{% endtrans %}{% trans %}Staff{% endtrans %}
    + + {% if ban.real_ip %} + {{ ban.ip }} + {% else %} + {{ ban.ip|e }} + {% endif %} + + {% if ban.reason %} + {{ ban.reason }} + {% else %} + - + {% endif %} + + {% if ban.board %} + {{ config.board_abbreviation|sprintf(ban.board) }} + {% else %} + {% trans %}all boards{% endtrans %} + {% endif %} + + {{ ban.set|date(config.post_date) }} + + {% if ban.expires == 0 %} + never + {% else %} + {{ ban.expires|date(config.post_date) }} + {% if ban.expires > time() %} + ({{ ban.expires|until }}) + {% endif %} + {% endif %} + + {% if ban.username %} + {% if mod|hasPermission(config.mod.view_banstaff) %} + {{ ban.username|e }} + {% else %} + {% if mod|hasPermission(config.mod.view_banquestionmark) %} + ? + {% else %} + + {% endif %} + {% endif %} + {% else %} + deleted? + {% endif %} +
    + +

    + +

    + +{% endif %} diff --git a/templates/mod/new_pm.html b/templates/mod/new_pm.html index d694bc26..ece1325c 100644 --- a/templates/mod/new_pm.html +++ b/templates/mod/new_pm.html @@ -2,7 +2,7 @@ {% set username = 'me' %} {% endif %}#} -
    + @@ -14,7 +14,7 @@ - +
    To
    Message
    diff --git a/templates/mod/pm.html b/templates/mod/pm.html new file mode 100644 index 00000000..511bcfef --- /dev/null +++ b/templates/mod/pm.html @@ -0,0 +1,41 @@ + + + + + {% if username %} + + {% else %} + + {% endif %} + + {% if to != mod.id %} + + + {% if to_username %} + + {% else %} + + {% endif %} + + {% endif %} + + + + + + + + +
    From{{ username|e }}deleted?
    To{{ to_username|e }}deleted?
    Date{{ time|date(config.post_date) }}
    Message{{ message }}
    + + +
    -- cgit v1.3 From 41e1a2481b4d2b3217b667063d9bf5115dfec9ab Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 17:28:57 +1000 Subject: report queue --- inc/mod/pages.php | 121 +++++++++++++++++++++++++++++++++++++++++++++ inc/template.php | 2 +- mod.php | 2 + templates/mod/report.html | 26 ++++++++++ templates/mod/reports.html | 5 ++ 5 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 templates/mod/report.html create mode 100644 templates/mod/reports.html (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 60f101ea..2532e2e7 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -469,3 +469,124 @@ function mod_rebuild() { mod_page("Rebuild", 'mod/rebuild.html', array('boards' => listBoards())); } +function mod_reports() { + global $config, $mod; + + if (!hasPermission($config['mod']['reports'])) + error($config['error']['noaccess']); + + $query = prepare("SELECT * FROM `reports` ORDER BY `time` DESC LIMIT :limit"); + $query->bindValue(':limit', $config['mod']['recent_reports'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $reports = $query->fetchAll(PDO::FETCH_ASSOC); + + $report_queries = array(); + foreach ($reports as $report) { + if (!isset($report_queries[$report['board']])) + $report_queries[$report['board']] = array(); + $report_queries[$report['board']][] = $report['post']; + } + + $report_posts = array(); + foreach ($report_queries as $board => $posts) { + $report_posts[$board] = array(); + + $query = query(sprintf('SELECT * FROM `posts_%s` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error()); + while ($post = $query->fetch()) { + $report_posts[$board][$post['id']] = $post; + } + } + + $body = ''; + foreach ($reports as $report) { + if (!isset($report_posts[$report['board']][$report['post']])) { + // // Invalid report (post has since been deleted) + $query = prepare("DELETE FROM `reports` WHERE `post` = :id AND `board` = :board"); + $query->bindValue(':id', $report['post'], PDO::PARAM_INT); + $query->bindValue(':board', $report['board']); + $query->execute() or error(db_error($query)); + continue; + } + + openBoard($report['board']); + + $post = &$report_posts[$report['board']][$report['post']]; + + if (!$post['thread']) { + // Still need to fix this: + $po = new Thread( + $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['fileheight'], $post['filesize'], $post['filename'], $post['ip'], $post['sticky'], + $post['locked'], $post['sage'], $post['embed'], '?/', $mod, false + ); + } else { + $po = new Post( + $post['id'], $post['thread'], $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['fileheight'], $post['filesize'], $post['filename'], $post['ip'], $post['embed'], '?/', $mod + ); + } + + // a little messy and inefficient + $append_html = Element('mod/report.html', array('report' => $report, 'config' => $config, 'mod' => $mod)); + + // Bug fix for https://github.com/savetheinternet/Tinyboard/issues/21 + $po->body = truncate($po->body, $po->link(), $config['body_truncate'] - substr_count($append_html, '
    ')); + + if (mb_strlen($po->body) + mb_strlen($append_html) > $config['body_truncate_char']) { + // still too long; temporarily increase limit in the config + $__old_body_truncate_char = $config['body_truncate_char']; + $config['body_truncate_char'] = mb_strlen($po->body) + mb_strlen($append_html); + } + + $po->body .= $append_html; + + $body .= $po->build(true) . '
    '; + + if(isset($__old_body_truncate_char)) + $config['body_truncate_char'] = $__old_body_truncate_char; + } + + mod_page("Report queue", 'mod/reports.html', array('reports' => $body)); +} + +function mod_report_dismiss($id, $all = false) { + global $config; + + $query = prepare("SELECT `post`, `board`, `ip` FROM `reports` WHERE `id` = :id"); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + if ($report = $query->fetch(PDO::FETCH_ASSOC)) { + $ip = $report['ip']; + $board = $report['board']; + $post = $report['post']; + } else + error($config['error']['404']); + + if (!$all && !hasPermission($config['mod']['report_dismiss'], $board)) + error($config['error']['noaccess']); + + if ($all && !hasPermission($config['mod']['report_dismiss_ip'], $board)) + error($config['error']['noaccess']); + + if ($all) { + $query = prepare("DELETE FROM `reports` WHERE `ip` = :ip"); + $query->bindValue(':ip', $ip); + } else { + $query = prepare("DELETE FROM `reports` WHERE `id` = :id"); + $query->bindValue(':id', $id); + } + $query->execute() or error(db_error($query)); + + + if ($all) + modLog("Dismissed all reports by $ip"); + else + modLog("Dismissed a report for post #{$id}", $board); + + header('Location: ?/reports', true, $config['redirect_http']); +} + + diff --git a/inc/template.php b/inc/template.php index 8d679d25..5355e18c 100644 --- a/inc/template.php +++ b/inc/template.php @@ -39,7 +39,7 @@ function Element($templateFile, array $options) { if (!$twig) load_twig(); - if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod']))) { + if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod'])) && !preg_match('!^mod/!', $templateFile)) { $options['pm'] = create_pm_header(); } diff --git a/mod.php b/mod.php index 6fc216f8..78205bd3 100644 --- a/mod.php +++ b/mod.php @@ -33,6 +33,8 @@ $pages = array( '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm '!^/rebuild$!' => 'rebuild', // rebuild static files + '!^/reports$!' => 'reports', // report queue + '!^/reports/(\d+)/dismiss(all)?$!' => 'report_dismiss', // dismiss a report '!^/ban$!' => 'ban', // new ban '!^/IP/([\w.:]+)$!' => 'ip', // view ip address diff --git a/templates/mod/report.html b/templates/mod/report.html new file mode 100644 index 00000000..c84e3c89 --- /dev/null +++ b/templates/mod/report.html @@ -0,0 +1,26 @@ +
    +
    + Board: {{ config.board_abbreviation|sprintf(report.board) }} +
    + Reason: {{ report.reason }} +
    + Report date: {{ report.time|date(config.post_date) }} +
    + {% if mod|hasPermission(config.mod.show_ip, report.board) %} + Reported by: {{ report.ip }} +
    + {% endif %} + {% if mod|hasPermission(config.mod.report_dismiss, report.board) or mod|hasPermission(config.mod.report_dismiss_ip, report.board) %} +
    + {% if mod|hasPermission(config.mod.report_dismiss, report.board) %} + Dismiss + {% endif %} + {% if mod|hasPermission(config.mod.report_dismiss_ip, report.board) %} + {% if mod|hasPermission(config.mod.report_dismiss, report.board) %} + | + {% endif %} + Dismiss+ + {% endif %} + {% endif %} +
    + diff --git a/templates/mod/reports.html b/templates/mod/reports.html new file mode 100644 index 00000000..37322e35 --- /dev/null +++ b/templates/mod/reports.html @@ -0,0 +1,5 @@ +{% if reports %} + {{ reports }} +{% else %} +

    (There are no reports.)

    +{% endif %} -- cgit v1.3 From f0412b08140e256056fd1ea41ea1930fcc321d22 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 19:13:30 +1000 Subject: paginate ban list --- inc/config.php | 2 ++ inc/mod/pages.php | 20 ++++++++++++-------- mod.php | 1 + templates/mod/ban_list.html | 9 +++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 0ea25b46..2cbecdc3 100644 --- a/inc/config.php +++ b/inc/config.php @@ -826,6 +826,8 @@ // How many actions to show per page in the moderation log $config['mod']['modlog_page'] = 350; + // How many bans to show per page in the ban list + $config['mod']['banlist_page'] = 350; // Maximum number of results to display for a search, per board $config['mod']['search_results'] = 75; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 98851c52..3c3c08a4 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -246,7 +246,7 @@ function mod_ban() { header('Location: ?/', true, $config['redirect_http']); } -function mod_bans() { +function mod_bans($page_no = 1) { global $config; if (!hasPermission($config['mod']['view_banlist'])) @@ -272,23 +272,27 @@ function mod_bans() { } 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)); + $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 LIMIT :offset, :limit"); } 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)); + $query = prepare("SELECT `bans`.*, `username` FROM `bans` INNER JOIN `mods` ON `mod` = `mods`.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC LIMIT :offset, :limit"); } + $query->bindValue(':time', time(), PDO::PARAM_INT); + $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); $bans = $query->fetchAll(PDO::FETCH_ASSOC); + $query = prepare("SELECT COUNT(*) FROM `bans`"); + $query->execute() or error(db_error($query)); + $count = $query->fetchColumn(0); + 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)); + mod_page('Ban list', 'mod/ban_list.html', array('bans' => $bans, 'count' => $count)); } function mod_delete($board, $post) { diff --git a/mod.php b/mod.php index 78205bd3..86169b59 100644 --- a/mod.php +++ b/mod.php @@ -40,6 +40,7 @@ $pages = array( '!^/IP/([\w.:]+)$!' => 'ip', // view ip address '!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address '!^/bans$!' => 'bans', // ban list + '!^/bans/(\d+)$!' => 'bans', // ban list '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index 00b8a0f4..66471d6d 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -72,3 +72,12 @@

    {% endif %} + +{% if count > bans|count %} +

    + {% for i in range(0, count / config.mod.modlog_page) %} + [{{ i + 1 }}] + {% endfor %} +

    +{% endif %} + -- cgit v1.3 From cc614e36b4135d5b8ac000bad8ed450df0e61ffe Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 20:11:10 +1000 Subject: multiple improvements --- inc/mod/ban.php | 2 +- inc/mod/pages.php | 80 ++++++++++++++++++++++++++++++++++++--- mod.php | 11 +++++- templates/mod/dashboard.html | 10 +++++ templates/mod/debug/antispam.html | 42 ++++++++++++++++++++ templates/page.html | 2 +- 6 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 templates/mod/debug/antispam.html (limited to 'templates') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index e7110edf..4d73488f 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -80,7 +80,7 @@ function ban($mask, $reason, $length, $board) { $query->execute() or error(db_error($query)); - modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . $reason . '' : 'no reason')); + modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . utf8tohtml($reason) . '' : 'no reason')); } function unban($id) { diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 3c3c08a4..7e6cddfe 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -15,6 +15,7 @@ function mod_page($title, $template, $args) { echo Element('page.html', array( 'config' => $config, 'mod' => $mod, + 'hide_dashboard_link' => $template == 'mod/dashboard.html', 'title' => $title, 'body' => Element($template, array_merge( @@ -262,10 +263,12 @@ function mod_bans($page_no = 1) { $unban[] = $match[1]; } - query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); + if (!empty($unban)) { + query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); - foreach ($unban as $id) { - modLog("Removed ban #{$id}"); + foreach ($unban as $id) { + modLog("Removed ban #{$id}"); + } } header('Location: ?/bans', true, $config['redirect_http']); @@ -278,8 +281,8 @@ function mod_bans($page_no = 1) { $query = prepare("SELECT `bans`.*, `username` FROM `bans` INNER JOIN `mods` ON `mod` = `mods`.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC LIMIT :offset, :limit"); } $query->bindValue(':time', time(), PDO::PARAM_INT); - $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); - $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->bindValue(':limit', $config['mod']['banlist_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['banlist_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); $bans = $query->fetchAll(PDO::FETCH_ASSOC); @@ -295,6 +298,58 @@ function mod_bans($page_no = 1) { mod_page('Ban list', 'mod/ban_list.html', array('bans' => $bans, 'count' => $count)); } + +function mod_lock($board, $unlock, $post) { + global $config; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['lock'], $board)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('UPDATE `posts_%s` SET `locked` = :locked WHERE `id` = :id AND `thread` IS NULL', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':locked', $unlock ? 0 : 1); + $query->execute() or error(db_error($query)); + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + +function mod_sticky($board, $unsticky, $post) { + global $config; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['sticky'], $board)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('UPDATE `posts_%s` SET `sticky` = :sticky WHERE `id` = :id AND `thread` IS NULL', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':sticky', $unsticky ? 0 : 1); + $query->execute() or error(db_error($query)); + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + +function mod_bumplock($board, $unbumplock, $post) { + global $config; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['bumplock'], $board)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('UPDATE `posts_%s` SET `sage` = :bumplock WHERE `id` = :id AND `thread` IS NULL', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':bumplock', $unbumplock ? 0 : 1); + $query->execute() or error(db_error($query)); + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + function mod_delete($board, $post) { global $config, $mod; @@ -599,4 +654,19 @@ function mod_report_dismiss($id, $all = false) { header('Location: ?/reports', true, $config['redirect_http']); } +function mod_debug_antispam() { + $args = array(); + + $query = query('SELECT COUNT(*) FROM `antispam`') or error(db_error()); + $args['total'] = number_format($query->fetchColumn(0)); + + $query = query('SELECT COUNT(*) FROM `antispam` WHERE `expires` IS NOT NULL') or error(db_error()); + $args['expiring'] = number_format($query->fetchColumn(0)); + + $query = query('SELECT * FROM `antispam` /* WHERE `passed` > 0 */ ORDER BY `passed` DESC LIMIT 25') or error(db_error()); + $args['top'] = $query->fetchAll(PDO::FETCH_ASSOC); + + mod_page("Debug: Anti-spam", 'mod/debug/antispam.html', $args); +} + diff --git a/mod.php b/mod.php index 86169b59..8af74a7b 100644 --- a/mod.php +++ b/mod.php @@ -43,10 +43,17 @@ $pages = array( '!^/bans/(\d+)$!' => 'bans', // ban list '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post + '!^/(\w+)/(un)?lock/(\d+)$!' => 'lock', // lock thread + '!^/(\w+)/(un)?sticky/(\d+)$!' => 'sticky', // sticky thread + '!^/(\w+)/bump(un)?lock/(\d+)$!' => 'bumplock', // "bumplock" thread + + // these pages aren't listed in the dashboard without $config['debug'] + '!^/debug/antispam$!' => 'debug_antispam', // This should always be at the end: - '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '?$!' => 'view_board', - '!^/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_board', + '!^/(\w+)/$!' => 'view_board', + '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '$!' => 'view_board', + '!^/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_board', '!^/(\w+)/' . preg_quote($config['dir']['res'], '!') . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_thread', ); diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 2a90d709..e9290e12 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -79,3 +79,13 @@ {# TODO #} + +{% if config.debug %} +
    + Debug + +
    +{% endif %} + diff --git a/templates/mod/debug/antispam.html b/templates/mod/debug/antispam.html new file mode 100644 index 00000000..af5354ed --- /dev/null +++ b/templates/mod/debug/antispam.html @@ -0,0 +1,42 @@ +

    + Most used (in active): +

    + + + + + + + + + + {% for hash in top %} + + + + + + + + + {% endfor %} +
    BoardThreadHash (CRC32)CreatedExpiresPassed
    {{ config.board_abbreviation|sprintf(hash.board) }} + {% if hash.thread %} + {{ hash.thread }} + {% else %} + - + {% endif %}{{ hash.hash }} + {{ hash.created|ago }} ago + + {% if hash.expires %} + + {{ hash.expires|until }} + + {% else %} + - + {% endif %} + {{ hash.passed }}
    +

    + Total: {{ total }} ({{ expiring }} set to expire) +

    + diff --git a/templates/page.html b/templates/page.html index 39d73bbd..0c0264d1 100644 --- a/templates/page.html +++ b/templates/page.html @@ -17,7 +17,7 @@ {% if subtitle %} {{ subtitle }} {% endif %} - {% if mod %}

    {% trans %}Return to dashboard{% endtrans %}

    {% endif %} + {% if mod and not hide_dashboard_link %}

    {% trans %}Return to dashboard{% endtrans %}

    {% endif %}
{{ body }} -- cgit v1.3 From a340c5b6eec89d0e023fc606081ec857f44a0b3d Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 23:18:07 +1000 Subject: edit users --- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 2 +- inc/mod/pages.php | 82 ++++++++++++++++++++++ mod.php | 1 + templates/mod/log.html | 2 +- templates/mod/user.html | 93 +++++++++++++++++++++++++ 5 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 templates/mod/user.html (limited to 'templates') diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index 2691cc55..df652444 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -76,7 +76,7 @@ function twig_date_filter($date, $format) { return strftime($format, $date); } -function twig_hasPermission_filter($mod, $permission, $board = false) { +function twig_hasPermission_filter($mod, $permission, $board = null) { return hasPermission($permission, $board, $mod); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 31c78528..e388c509 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -313,6 +313,7 @@ function mod_lock($board, $unlock, $post) { $query->bindValue(':locked', $unlock ? 0 : 1); $query->execute() or error(db_error($query)); if($query->rowCount()) { + modLog(($unlock ? 'Unlocked' : 'Locked') . " thread #{$post}"); buildThread($post); buildIndex(); } @@ -334,6 +335,7 @@ function mod_sticky($board, $unsticky, $post) { $query->bindValue(':sticky', $unsticky ? 0 : 1); $query->execute() or error(db_error($query)); if($query->rowCount()) { + modLog(($unlock ? 'Unstickied' : 'Stickied') . " thread #{$post}"); buildThread($post); buildIndex(); } @@ -355,6 +357,7 @@ function mod_bumplock($board, $unbumplock, $post) { $query->bindValue(':bumplock', $unbumplock ? 0 : 1); $query->execute() or error(db_error($query)); if($query->rowCount()) { + modLog(($unlock ? 'Unbumplocked' : 'Bumplocked') . " thread #{$post}"); buildThread($post); buildIndex(); } @@ -382,6 +385,85 @@ function mod_delete($board, $post) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } +function mod_user($uid) { + global $config, $mod; + + if (!hasPermission($config['mod']['editusers']) && !(hasPermission($config['mod']['change_password']) && $uid == $mod['id'])) + error($config['error']['noaccess']); + + $query = prepare('SELECT * FROM `mods` WHERE `id` = :id'); + $query->bindValue(':id', $uid); + $query->execute() or error(db_error($query)); + if (!$user = $query->fetch(PDO::FETCH_ASSOC)) + error($config['error']['404']); + + if (hasPermission($config['mod']['editusers']) && isset($_POST['username'], $_POST['password'])) { + if (isset($_POST['allboards'])) { + $boards = array('*'); + } else { + $_boards = listBoards(); + foreach ($_boards as &$board) { + $board = $board['uri']; + } + + $boards = array(); + foreach ($_POST as $name => $value) { + if (preg_match('/^board_(\w+)$/', $name, $matches) && in_array($matches[1], $_boards)) + $boards[] = $matches[1]; + } + } + + $query = prepare('UPDATE `mods` SET `username` = :username, `boards` = :boards WHERE `id` = :id'); + $query->bindValue(':id', $uid); + $query->bindValue(':username', $_POST['username']); + $query->bindValue(':boards', implode(',', $boards)); + $query->execute() or error(db_error($query)); + + if ($_POST['password'] != '') { + $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); + $query->bindValue(':id', $uid); + $query->bindValue(':password', $_POST['password']); + $query->execute() or error(db_error($query)); + + if ($uid == $mod['id']) { + login($_POST['username'], $_POST['password']); + setCookies(); + } + } + + header('Location: ?/users', true, $config['redirect_http']); + return; + } + + if (hasPermission($config['mod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { + if ($_POST['password'] != '') { + $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); + $query->bindValue(':id', $uid); + $query->bindValue(':password', $_POST['password']); + $query->execute() or error(db_error($query)); + + login($_POST['username'], $_POST['password']); + setCookies(); + } + + header('Location: ?/users', true, $config['redirect_http']); + return; + } + + if (hasPermission($config['mod']['modlog'])) { + $query = prepare('SELECT * FROM `modlogs` WHERE `mod` = :id ORDER BY `time` DESC LIMIT 5'); + $query->bindValue(':id', $uid); + $query->execute() or error(db_error($query)); + $log = $query->fetchAll(PDO::FETCH_ASSOC); + } else { + $log = array(); + } + + $user['boards'] = explode(',', $user['boards']); + + mod_page('Edit user', 'mod/user.html', array('user' => $user, 'logs' => $log, 'boards' => listBoards())); +} + function mod_users() { global $config; diff --git a/mod.php b/mod.php index 8af74a7b..85d10c6c 100644 --- a/mod.php +++ b/mod.php @@ -28,6 +28,7 @@ $pages = array( '!^/log/(\d+)$!' => 'log', // modlog '!^/users$!' => 'users', // manage users + '!^/users/(\d+)$!' => 'user', // edit user '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm diff --git a/templates/mod/log.html b/templates/mod/log.html index 61243202..19924b1d 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -2,7 +2,7 @@ Staff IP address - Ago + Time Board Action diff --git a/templates/mod/user.html b/templates/mod/user.html new file mode 100644 index 00000000..87a57d92 --- /dev/null +++ b/templates/mod/user.html @@ -0,0 +1,93 @@ +
+ + + + + + + + + + + + + +
Username + {% if mod|hasPermission(config.mod.editusers) %} + + {% else %} + {{ user.username|e }} + {% endif %} +
Password (new; optional) + {% if mod|hasPermission(config.mod.editusers) or (mod|hasPermission(config.mod.change_password) and user.id == mod.id) %} + + {% else %} + - + {% endif %} +
Boards +
    +
  • + + +
  • + {% for board in boards %} +
  • + + +
  • + {% endfor %} +
+
+ +
    +
  • + {% if mod|hasPermission(config.mod.deleteusers) %} +
  • + {% endif %} +
+
+ +{% if logs|count > 0 %} + + + + + + + + {% for log in logs %} + + + + + + + {% endfor %} +
IP addressTimeBoardAction
+ {{ log.ip }} + + {{ log.time|ago }} + + {% if log.board %} + {{ config.board_abbreviation|sprintf(log.board) }} + {% else %} + - + {% endif %} + + {{ log.text }} +
+{% endif %} -- cgit v1.3 From 2c47c2d994adfb71b0f938640e95592d7d1567ac Mon Sep 17 00:00:00 2001 From: Michael Save Date: Thu, 19 Apr 2012 01:37:31 +1000 Subject: CRC32 -> SHA1 --- templates/mod/debug/antispam.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/mod/debug/antispam.html b/templates/mod/debug/antispam.html index af5354ed..c3e70859 100644 --- a/templates/mod/debug/antispam.html +++ b/templates/mod/debug/antispam.html @@ -1,11 +1,11 @@

Most used (in active):

- +
- + -- cgit v1.3 From 4891eae24eac73328ecdc9eb9c5c8a4ab1e9c346 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Thu, 19 Apr 2012 22:40:11 +1000 Subject: added filter/purge controls to ?/debug/antispam --- inc/mod/pages.php | 27 +++++++++++++++++++++++---- templates/mod/debug/antispam.html | 25 ++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 5 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index e388c509..541a7c23 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -435,7 +435,7 @@ function mod_user($uid) { return; } - if (hasPermission($config['mod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { + if (hasPermission($config['dmod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { if ($_POST['password'] != '') { $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); $query->bindValue(':id', $uid); @@ -749,15 +749,34 @@ function mod_report_dismiss($id, $all = false) { } function mod_debug_antispam() { + global $pdo, $config; + $args = array(); - $query = query('SELECT COUNT(*) FROM `antispam`') or error(db_error()); + if (isset($_POST['board'], $_POST['thread'])) { + $where = '`board` = ' . $pdo->quote($_POST['board']); + if($_POST['thread'] != '') + $where .= ' AND `thread` = ' . $pdo->quote($_POST['thread']); + + if (isset($_POST['purge'])) { + $query = prepare('UPDATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE' . $where); + $query->bindValue(':expires', $config['spam']['hidden_inputs_expire']); + $query->execute() or error(db_error()); + } + + $args['board'] = $_POST['board']; + $args['thread'] = $_POST['thread']; + } else { + $where = ''; + } + + $query = query('SELECT COUNT(*) FROM `antispam`' . ($where ? " WHERE $where" : '')) or error(db_error()); $args['total'] = number_format($query->fetchColumn(0)); - $query = query('SELECT COUNT(*) FROM `antispam` WHERE `expires` IS NOT NULL') or error(db_error()); + $query = query('SELECT COUNT(*) FROM `antispam` WHERE `expires` IS NOT NULL' . ($where ? " AND $where" : '')) or error(db_error()); $args['expiring'] = number_format($query->fetchColumn(0)); - $query = query('SELECT * FROM `antispam` /* WHERE `passed` > 0 */ ORDER BY `passed` DESC LIMIT 25') or error(db_error()); + $query = query('SELECT * FROM `antispam` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `passed` DESC LIMIT 40') or error(db_error()); $args['top'] = $query->fetchAll(PDO::FETCH_ASSOC); mod_page("Debug: Anti-spam", 'mod/debug/antispam.html', $args); diff --git a/templates/mod/debug/antispam.html b/templates/mod/debug/antispam.html index c3e70859..99331ed3 100644 --- a/templates/mod/debug/antispam.html +++ b/templates/mod/debug/antispam.html @@ -19,7 +19,9 @@ {% else %} - {% endif %} - + @@ -40,3 +42,24 @@ Total: {{ total }} ({{ expiring }} set to expire)

+ +
Board ThreadHash (CRC32)Hash (SHA1) Created Expires Passed{{ hash.hash }} + {{ hash.hash|upper }} + {{ hash.created|ago }} ago
+ + + + + + + + + + +
BoardThread
+ + + + + + +
+ -- cgit v1.3 From de84ca6f755347b2c3fcf87165704a2d9e899d77 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 20 Apr 2012 21:37:48 +1000 Subject: Multiple improvements: ?/ban/ & ?/ban&delete/ --- inc/mod/pages.php | 47 ++++++++++++++++++++++++++++++++++++++++++--- mod.php | 2 +- templates/mod/ban_form.html | 36 ++++++++++++++++++++++++++++++++-- 3 files changed, 79 insertions(+), 6 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 7bc970b0..78f560ec 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -374,13 +374,54 @@ function mod_ban_post($board, $delete, $post) { if (!hasPermission($config['mod']['delete'], $board)) error($config['error']['noaccess']); - $query = prepare(sprintf('SELECT `ip` FROM `posts_%s` WHERE `id` = :id', $board)); + $query = prepare(sprintf('SELECT `ip`, `thread` FROM `posts_%s` WHERE `id` = :id', $board)); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); - if(!$ip = $query->fetchColumn(0)) + if(!$_post = $query->fetch(PDO::FETCH_ASSOC)) error($config['error']['404']); - mod_page("New ban", 'mod/ban_form.html', array()); + $thread = $_post['thread']; + $ip = $_post['ip']; + + if (isset($_POST['new_ban'], $_POST['reason'], $_POST['length'], $_POST['board'])) { + require_once 'inc/mod/ban.php'; + + if (isset($_POST['ip'])) + $ip = $_POST['ip']; + + ban($ip, $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']); + + if (isset($_POST['public_message'], $_POST['message'])) { + // public ban message + $query = prepare(sprintf('UPDATE `posts_%s` SET `body` = CONCAT(`body`, :body) WHERE `id` = :id', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':body', sprintf($config['mod']['ban_message'], utf8tohtml($_POST['message']))); + $query->execute() or error(db_error($query)); + + modLog("Attached a public ban message to post #{$post}: " . utf8tohtml($_POST['message'])); + buildThread($thread ? $thread : $post); + buildIndex(); + } elseif (isset($_POST['delete'])) { + // Delete post + deletePost($post); + modLog("Deleted post #{$post}"); + // Rebuild board + buildIndex(); + } + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); + } + + $args = array( + 'ip' => $ip, + 'hide_ip' => !hasPermission($config['mod']['show_ip'], $board), + 'post' => $post, + 'board' => $board, + 'delete' => (bool)$delete, + 'boards' => listBoards() + ); + + mod_page("New ban", 'mod/ban_form.html', $args); } function mod_delete($board, $post) { diff --git a/mod.php b/mod.php index 57967da5..b5edd255 100644 --- a/mod.php +++ b/mod.php @@ -44,7 +44,7 @@ $pages = array( '!^/bans/(\d+)$!' => 'bans', // ban list '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post - '!^/(\w+)/ban/(&delete/)?(\d+)$!' => 'ban_post', // ban poster + '!^/(\w+)/ban(&delete)?/(\d+)$!' => 'ban_post', // ban poster '!^/(\w+)/(un)?lock/(\d+)$!' => 'lock', // lock thread '!^/(\w+)/(un)?sticky/(\d+)$!' => 'sticky', // sticky thread '!^/(\w+)/bump(un)?lock/(\d+)$!' => 'bumplock', // "bumplock" thread diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html index 1b94e725..9d4d6728 100644 --- a/templates/mod/ban_form.html +++ b/templates/mod/ban_form.html @@ -1,15 +1,29 @@ -
+{% if post and board %} + {% set action = '?/' ~ board ~ '/ban/' ~ post %} +{% else %} + {% set action = '?/ban' %} +{% endif %} + + {% if redirect %} {% endif %} + {% if post and board %} + + {% endif %} + @@ -20,6 +34,24 @@ + {% if post and board and not delete %} + + + + + {% endif %} - + {% if mod|hasPermission(config.mod.modlog) %} + + {% endif %} @@ -34,17 +36,15 @@ {{ _boards|join(', ') }} {% endif %} - + + {% endif %} - + + @@ -32,10 +33,12 @@
  • -
  • - - {% trans 'Reply with quote' %} - -
  • + {% if mod|hasPermission(config.mod.create_pm) %} +
  • + + {% trans 'Reply with quote' %} + +
  • + {% endif %} -- cgit v1.3 From 970c6cd95bfbb39454531f3990863d19cfbfe0ba Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 19 May 2012 18:27:45 +1000 Subject: [move] --- inc/functions.php | 4 +- inc/mod/pages.php | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ mod.php | 1 + templates/mod/move.html | 41 +++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 templates/mod/move.html (limited to 'templates') diff --git a/inc/functions.php b/inc/functions.php index f21df417..ff255614 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -716,13 +716,13 @@ function post(array $post) { $query->bindValue(':password', $post['password']); $query->bindValue(':ip', isset($post['ip']) ? $post['ip'] : $_SERVER['REMOTE_ADDR']); - if ($post['mod'] && $post['sticky']) { + if ($post['op'] && $post['mod'] && $post['sticky']) { $query->bindValue(':sticky', 1, PDO::PARAM_INT); } else { $query->bindValue(':sticky', 0, PDO::PARAM_INT); } - if ($post['mod'] && $post['locked']) { + if ($post['op'] && $post['mod'] && $post['locked']) { $query->bindValue(':locked', 1, PDO::PARAM_INT); } else { $query->bindValue(':locked', 0, PDO::PARAM_INT); diff --git a/inc/mod/pages.php b/inc/mod/pages.php index d532d9ba..7f78cd0b 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -693,6 +693,189 @@ function mod_bumplock($board, $unbumplock, $post) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } +function mod_move($originBoard, $postID) { + global $board, $config, $mod; + + if (!openBoard($originBoard)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['move'], $originBoard)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `id` = :id AND `thread` IS NULL', $originBoard)); + $query->bindValue(':id', $postID); + $query->execute() or error(db_error($query)); + if (!$post = $query->fetch(PDO::FETCH_ASSOC)) + error($config['error']['404']); + + if (isset($_POST['board'])) { + $targetBoard = $_POST['board']; + $shadow = isset($_POST['shadow']); + + if ($targetBoard === $originBoard) + error(_('Target and source board are the same.')); + + // copy() if leaving a shadow thread behind; else, rename(). + $clone = $shadow ? 'copy' : 'rename'; + + // indicate that the post is a thread + $post['op'] = true; + + if ($post['file']) { + $post['has_file'] = true; + $post['width'] = &$post['filewidth']; + $post['height'] = &$post['fileheight']; + + $file_src = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']; + $file_thumb = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']; + } else { + $post['has_file'] = false; + } + + // allow thread to keep its same traits (stickied, locked, etc.) + $post['mod'] = true; + + if (!openBoard($targetBoard)) + error($config['error']['noboard']); + + // create the new thread + $newID = post($post); + + if($post['has_file']) { + // copy image + $clone($file_src, sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']); + $clone($file_thumb, sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']); + } + + // go back to the original board to fetch replies + openBoard($originBoard); + + $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id`', $originBoard)); + $query->bindValue(':id', $postID, PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + $replies = array(); + + while($post = $query->fetch()) { + $post['mod'] = true; + $post['thread'] = $newID; + + if($post['file']) { + $post['has_file'] = true; + $post['width'] = &$post['filewidth']; + $post['height'] = &$post['fileheight']; + + $post['file_src'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']; + $post['file_thumb'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']; + } else { + $post['has_file'] = false; + } + + $replies[] = $post; + } + + $newIDs = array($postID => $newID); + + openBoard($targetBoard); + + foreach($replies as &$post) { + $query = prepare('SELECT `target` FROM `cites` WHERE `target_board` = :board AND `board` = :board AND `post` = :post'); + $query->bindValue(':board', $originBoard); + $query->bindValue(':post', $post['id'], PDO::PARAM_INT); + $query->execute() or error(db_error($qurey)); + + // correct >>X links + while($cite = $query->fetch(PDO::FETCH_ASSOC)) { + if(isset($newIDs[$cite['target']])) { + $post['body_nomarkup'] = preg_replace( + '/(>>(>\/' . preg_quote($originBoard, '/') . '\/)?)' . preg_quote($cite['target'], '/') . '/', + '>>' . $newIDs[$cite['target']], + $post['body_nomarkup']); + + $post['body'] = $post['body_nomarkup']; + } + } + + $post['body'] = $post['body_nomarkup']; + + $post['op'] = false; + $post['tracked_cites'] = markup($post['body'], true); + + // insert reply + $newIDs[$post['id']] = $newPostID = post($post); + + if($post['has_file']) { + // copy image + $clone($post['file_src'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $post['file']); + $clone($post['file_thumb'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $post['thumb']); + } + + foreach($post['tracked_cites'] as $cite) { + $query = prepare('INSERT INTO `cites` VALUES (:board, :post, :target_board, :target)'); + $query->bindValue(':board', $board['uri']); + $query->bindValue(':post', $newPostID, PDO::PARAM_INT); + $query->bindValue(':target_board',$cite[0]); + $query->bindValue(':target', $cite[1], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + } + } + + // build new hread + buildThread($newID); + buildIndex(); + + // trigger themes + rebuildThemes('post'); + + // return to original board + openBoard($originBoard); + + if($shadow) { + // lock old thread + $query = prepare(sprintf('UPDATE `posts_%s` SET `locked` = 1 WHERE `id` = :id', $originBoard)); + $query->bindValue(':id', $postID, PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + // leave a reply, linking to the new thread + $post = array( + 'mod' => true, + 'subject' => '', + 'email' => '', + 'name' => $config['mod']['shadow_name'], + 'capcode' => $config['mod']['shadow_capcode'], + 'trip' => '', + 'password' => '', + 'has_file' => false, + // attach to original thread + 'thread' => $postID, + 'op' => false + ); + + $post['body'] = $post['body_nomarkup'] = sprintf($config['mod']['shadow_mesage'], '>>>/' . $targetBoard . '/' . $newID); + + markup($post['body']); + + $botID = post($post); + buildThread($postID); + + header('Location: ?/' . sprintf($config['board_path'], $originBoard) . $config['dir']['res'] .sprintf($config['file_page'], $postID) . + '#' . $botID, true, $config['redirect_http']); + } else { + deletePost($postID); + buildIndex(); + + openBoard($targetBoard); + header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . sprintf($config['file_page'], $newID), true, $config['redirect_http']); + } + } + + $boards = listBoards(); + if (count($boards) <= 1) + error(_('Impossible to move thread; there is only one board.')); + + mod_page("Move thread", 'mod/move.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards)); +} + function mod_ban_post($board, $delete, $post) { global $config, $mod; diff --git a/mod.php b/mod.php index b1422b6a..23cacc11 100644 --- a/mod.php +++ b/mod.php @@ -63,6 +63,7 @@ $pages = array( '/(\w+)/(un)?lock/(\d+)' => 'lock', // lock thread '/(\w+)/(un)?sticky/(\d+)' => 'sticky', // sticky thread '/(\w+)/bump(un)?lock/(\d+)' => 'bumplock', // "bumplock" thread + '/(\w+)/move/(\d+)' => 'move', // move thread // these pages aren't listed in the dashboard without $config['debug'] '/debug/antispam' => 'debug_antispam', diff --git a/templates/mod/move.html b/templates/mod/move.html new file mode 100644 index 00000000..802903b2 --- /dev/null +++ b/templates/mod/move.html @@ -0,0 +1,41 @@ +
    +
    - + {% if not hide_ip %} + + {% else %} + hidden + {% endif %}
    + + + + + (public; attached to post) + +
    -- cgit v1.3 From 07fc56b80b36fcf41e8959844d1d8329a8852a99 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 20 Apr 2012 21:54:30 +1000 Subject: Noticeboard on dashboard --- inc/mod/pages.php | 14 +++++++++ templates/mod/dashboard.html | 67 +++++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 19 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 78f560ec..e40dc241 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -61,10 +61,24 @@ function mod_confirm($request) { } function mod_dashboard() { + global $config; + $args = array(); $args['boards'] = listBoards(); + if(hasPermission($config['mod']['noticeboard'])) { + if(!$config['cache']['enabled'] || !$args['noticeboard'] = cache::get('noticeboard_preview')) { + $query = prepare("SELECT `noticeboard`.*, `username` FROM `noticeboard` LEFT JOIN `mods` ON `mods`.`id` = `mod` ORDER BY `id` DESC LIMIT :limit"); + $query->bindValue(':limit', $config['mod']['noticeboard_dashboard'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $args['noticeboard'] = $query->fetchAll(PDO::FETCH_ASSOC); + + if($config['cache']['enabled']) + cache::set('noticeboard_preview', $args['noticeboard']); + } + } + mod_page('Dashboard', 'mod/dashboard.html', $args); } diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index e9290e12..173c0e94 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -1,5 +1,5 @@
    - Boards + {% trans 'Boards' %}
    {% if mod|hasPermission(config.mod.noticeboard) %}
    - Noticeboard - - {# TODO #} + {% trans 'Noticeboard' %} +
    {% endif %}
    - Administration + {% trans 'Administration' %}
    {% if mod|hasPermission(config.mod.themes) %}
    - Themes + {% trans 'Themes' %} {# TODO #}
    {% endif %}
    - Search + {% trans 'Search' %} {# TODO #}
    {% if config.debug %}
    - Debug + {% trans 'Debug' %}
    {% endif %} -- cgit v1.3 From 2c1f14d24b644e02f59758d04e1a029e2e73ed5a Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 21 Apr 2012 12:42:41 +1000 Subject: Improvements to new mod panel --- inc/mod/pages.php | 2 +- templates/mod/dashboard.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index e40dc241..3754268d 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -508,7 +508,7 @@ function mod_user($uid) { return; } - if (hasPermission($config['dmod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { + if (hasPermission($config['mod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { if ($_POST['password'] != '') { $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); $query->bindValue(':id', $uid); diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 173c0e94..984aa03e 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -27,7 +27,7 @@
    {% trans 'Noticeboard' %}
      - {% if noticeboard %} + {% if noticeboard|count > 0 %}
    • {% trans 'Latest posts:' %}
        -- cgit v1.3 From 2a301de29feb08d40a9740a574dbef8b07bd595c Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 21 Apr 2012 15:15:32 +1000 Subject: Paginate ?/noticeboard --- inc/config.php | 4 +- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 1 + inc/mod/pages.php | 55 +++++++++++++++++++-- mod.php | 6 ++- templates/mod/ban_list.html | 2 +- templates/mod/log.html | 2 +- templates/mod/noticeboard.html | 65 +++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 10 deletions(-) create mode 100644 templates/mod/noticeboard.html (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 8d93f266..06e100ea 100644 --- a/inc/config.php +++ b/inc/config.php @@ -832,8 +832,8 @@ // Maximum number of results to display for a search, per board $config['mod']['search_results'] = 75; - // Maximum number of notices to display on the moderator noticeboard - $config['mod']['noticeboard_display'] = 50; + // How many entries to show per page in the moderator noticeboard + $config['mod']['noticeboard_page'] = 50; // Number of entries to summarize and display on the dashboard $config['mod']['noticeboard_dashboard'] = 5; diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index df652444..c4810dad 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -37,6 +37,7 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension { return Array( 'time' => new Twig_Filter_Function('time'), + 'floor' => new Twig_Filter_Function('floor'), 'timezone' => new Twig_Filter_Function('twig_timezone_function'), 'hiddenInputs' => new Twig_Filter_Function('hiddenInputs'), 'hiddenInputsHash' => new Twig_Filter_Function('hiddenInputsHash'), diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 3754268d..d111a480 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -67,14 +67,14 @@ function mod_dashboard() { $args['boards'] = listBoards(); - if(hasPermission($config['mod']['noticeboard'])) { - if(!$config['cache']['enabled'] || !$args['noticeboard'] = cache::get('noticeboard_preview')) { + if (hasPermission($config['mod']['noticeboard'])) { + if (!$config['cache']['enabled'] || !$args['noticeboard'] = cache::get('noticeboard_preview')) { $query = prepare("SELECT `noticeboard`.*, `username` FROM `noticeboard` LEFT JOIN `mods` ON `mods`.`id` = `mod` ORDER BY `id` DESC LIMIT :limit"); $query->bindValue(':limit', $config['mod']['noticeboard_dashboard'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); $args['noticeboard'] = $query->fetchAll(PDO::FETCH_ASSOC); - if($config['cache']['enabled']) + if ($config['cache']['enabled']) cache::set('noticeboard_preview', $args['noticeboard']); } } @@ -82,6 +82,47 @@ function mod_dashboard() { mod_page('Dashboard', 'mod/dashboard.html', $args); } +function mod_noticeboard($page_no = 1) { + global $config, $pdo, $mod; + + if (!hasPermission($config['mod']['noticeboard'])) + error($config['error']['noaccess']); + + if (isset($_POST['subject'], $_POST['body'])) { + if (!hasPermission($config['mod']['noticeboard_post'])) + error($config['error']['noaccess']); + + markup($_POST['body']); + + $query = prepare('INSERT INTO `noticeboard` VALUES (NULL, :mod, :time, :subject, :body)'); + $query->bindValue(':mod', $mod['id']); + $query->bindvalue(':time', time()); + $query->bindValue(':subject', $_POST['subject']); + $query->bindValue(':body', $_POST['body']); + $query->execute() or error(db_error($query)); + + if($config['cache']['enabled']) + cache::delete('noticeboard_preview'); + + header('Location: ?/noticeboard#' . $pdo->lastInsertId(), true, $config['redirect_http']); + } + + $query = prepare("SELECT `noticeboard`.*, `username` FROM `noticeboard` LEFT JOIN `mods` ON `mods`.`id` = `mod` ORDER BY `id` DESC LIMIT :offset, :limit"); + $query->bindValue(':limit', $config['mod']['noticeboard_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['noticeboard_page'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $noticeboard = $query->fetchAll(PDO::FETCH_ASSOC); + + if (empty($noticeboard)) + error($config['error']['404']); + + $query = prepare("SELECT COUNT(*) FROM `noticeboard`"); + $query->execute() or error(db_error($query)); + $count = $query->fetchColumn(0); + + mod_page('Noticeboard', 'mod/noticeboard.html', array('noticeboard' => $noticeboard, 'count' => $count)); +} + function mod_log($page_no = 1) { global $config; @@ -94,7 +135,10 @@ function mod_log($page_no = 1) { $query->execute() or error(db_error($query)); $logs = $query->fetchAll(PDO::FETCH_ASSOC); - $query = prepare("SELECT COUNT(*) AS `count` FROM `modlogs`"); + if (empty($logs)) + error($config['error']['404']); + + $query = prepare("SELECT COUNT(*) FROM `modlogs`"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(0); @@ -300,6 +344,9 @@ function mod_bans($page_no = 1) { $query->execute() or error(db_error($query)); $bans = $query->fetchAll(PDO::FETCH_ASSOC); + if (empty($bans)) + error($config['error']['404']); + $query = prepare("SELECT COUNT(*) FROM `bans`"); $query->execute() or error(db_error($query)); $count = $query->fetchColumn(0); diff --git a/mod.php b/mod.php index b5edd255..4495ae52 100644 --- a/mod.php +++ b/mod.php @@ -24,8 +24,6 @@ $pages = array( '!^$!' => ':?/', // redirect to dashboard '!^/$!' => 'dashboard', // dashboard '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) - '!^/log$!' => 'log', // modlog - '!^/log/(\d+)$!' => 'log', // modlog '!^/users$!' => 'users', // manage users '!^/users/(\d+)$!' => 'user', // edit user @@ -33,6 +31,10 @@ $pages = array( '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm + '!^/noticeboard$!' => 'noticeboard', // view noticeboard + '!^/noticeboard/(\d+)$!' => 'noticeboard', // view noticeboard + '!^/log$!' => 'log', // modlog + '!^/log/(\d+)$!' => 'log', // modlog '!^/rebuild$!' => 'rebuild', // rebuild static files '!^/reports$!' => 'reports', // report queue '!^/reports/(\d+)/dismiss(all)?$!' => 'report_dismiss', // dismiss a report diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index 66471d6d..ea8183d6 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -75,7 +75,7 @@ {% if count > bans|count %}

        - {% for i in range(0, count / config.mod.modlog_page) %} + {% for i in range(0, (count - 1) / config.mod.modlog_page) %} [{{ i + 1 }}] {% endfor %}

        diff --git a/templates/mod/log.html b/templates/mod/log.html index 19924b1d..9b0979cb 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -33,7 +33,7 @@ {% if count > logs|count %}

        - {% for i in range(0, count / config.mod.modlog_page) %} + {% for i in range(0, (count - 1) / config.mod.modlog_page) %} [{{ i + 1 }}] {% endfor %}

        diff --git a/templates/mod/noticeboard.html b/templates/mod/noticeboard.html new file mode 100644 index 00000000..4d764d80 --- /dev/null +++ b/templates/mod/noticeboard.html @@ -0,0 +1,65 @@ +{% if mod|hasPermission(config.mod.noticeboard_post) %} +
        + {% trans 'New post' %} + + + + + + + + + + + + + + +
        {% trans 'Name' %}{{ mod.username|e }}
        {% trans 'Body' %}
        +

        + +

        + +
        +{% endif %} + +{% for post in noticeboard %} +
        + {% if mod|hasPermission(config.mod.noticeboard_delete) %} + + [{% trans 'delete' %}] + + {% endif %} +

        + + # + + {% if post.subject %} + {{ post.subject|e }} + {% else %} + {% trans 'no subject' %} + {% endif %} + + — by + {% if post.username %} + {{ post.username }} + {% else %} + deleted? + {% endif %} + at + {{ notice.time|date(config.post_date) }} + +

        +

        + {{ post.body }} +

        +
        +{% endfor %} + +{% if count > noticeboard|count %} +

        + {% for i in range(0, (count - 1) / config.mod.noticeboard_page) %} + [{{ i + 1 }}] + {% endfor %} +

        +{% endif %} -- cgit v1.3 From 19ea6e3d44186544c15166aa13e4faa1b8804c99 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 21 Apr 2012 15:29:57 +1000 Subject: ?/deletefile --- inc/mod/pages.php | 40 +++++++++++++++++++++++++++++++++++++--- mod.php | 1 + templates/mod/dashboard.html | 3 --- 3 files changed, 38 insertions(+), 6 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index d111a480..5bba5145 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -85,6 +85,9 @@ function mod_dashboard() { function mod_noticeboard($page_no = 1) { global $config, $pdo, $mod; + if ($page_no < 1) + error($config['error']['404']); + if (!hasPermission($config['mod']['noticeboard'])) error($config['error']['noaccess']); @@ -113,7 +116,7 @@ function mod_noticeboard($page_no = 1) { $query->execute() or error(db_error($query)); $noticeboard = $query->fetchAll(PDO::FETCH_ASSOC); - if (empty($noticeboard)) + if (empty($noticeboard) && $page_no > 1) error($config['error']['404']); $query = prepare("SELECT COUNT(*) FROM `noticeboard`"); @@ -126,6 +129,9 @@ function mod_noticeboard($page_no = 1) { function mod_log($page_no = 1) { global $config; + if ($page_no < 1) + error($config['error']['404']); + if (!hasPermission($config['mod']['modlog'])) error($config['error']['noaccess']); @@ -135,7 +141,7 @@ function mod_log($page_no = 1) { $query->execute() or error(db_error($query)); $logs = $query->fetchAll(PDO::FETCH_ASSOC); - if (empty($logs)) + if (empty($logs) && $page_no > 1) error($config['error']['404']); $query = prepare("SELECT COUNT(*) FROM `modlogs`"); @@ -308,6 +314,9 @@ function mod_ban() { function mod_bans($page_no = 1) { global $config; + if ($page_no < 1) + error($config['error']['404']); + if (!hasPermission($config['mod']['view_banlist'])) error($config['error']['noaccess']); @@ -344,7 +353,7 @@ function mod_bans($page_no = 1) { $query->execute() or error(db_error($query)); $bans = $query->fetchAll(PDO::FETCH_ASSOC); - if (empty($bans)) + if (empty($bans) && $page_no > 1) error($config['error']['404']); $query = prepare("SELECT COUNT(*) FROM `bans`"); @@ -505,6 +514,26 @@ function mod_delete($board, $post) { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } +function mod_deletefile($board, $post) { + global $config, $mod; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['deletefile'], $board)) + error($config['error']['noaccess']); + + // Delete file + deleteFile($post); + // Record the action + modLog("Deleted file from post #{$post}"); + // Rebuild board + buildIndex(); + + // Redirect + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + function mod_user($uid) { global $config, $mod; @@ -699,6 +728,11 @@ function mod_rebuild() { $rebuilt_scripts = array(); if (isset($_POST['rebuild_cache'])) { + if ($config['cache']['enabled']) { + $log[] = 'Flushing cache'; + Cache::flush(); + } + $log[] = 'Clearing template cache'; load_twig(); $twig->clearCacheFiles(); diff --git a/mod.php b/mod.php index 4495ae52..f3726c24 100644 --- a/mod.php +++ b/mod.php @@ -47,6 +47,7 @@ $pages = array( '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post '!^/(\w+)/ban(&delete)?/(\d+)$!' => 'ban_post', // ban poster + '!^/(\w+)/deletefile/(\d+)$!' => 'deletefile', // delete file from post '!^/(\w+)/(un)?lock/(\d+)$!' => 'lock', // lock thread '!^/(\w+)/(un)?sticky/(\d+)$!' => 'sticky', // sticky thread '!^/(\w+)/bump(un)?lock/(\d+)$!' => 'bumplock', // "bumplock" thread diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 984aa03e..fc510ac7 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -84,9 +84,6 @@ {% if mod|hasPermission(config.mod.rebuild) %}
      • {% trans 'Rebuild' %}
      • - {% if config.cache.enabled %} -
      • {% trans 'Clear cache' %}
      • - {% endif %} {% endif %} {% if mod|hasPermission(config.mod.show_config) %} -- cgit v1.3 From 54862246cda6e0e3acaa5fefa0da532a3778cb3b Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 22 Apr 2012 16:52:24 +1000 Subject: Stylesheet change. --- stylesheets/style.css | 2 +- templates/themes/basic/index.html | 6 ++++-- templates/themes/categories/news.html | 5 ++++- templates/themes/frameset/news.html | 6 ++++-- templates/themes/recent/recent.html | 6 ++++-- 5 files changed, 17 insertions(+), 8 deletions(-) (limited to 'templates') diff --git a/stylesheets/style.css b/stylesheets/style.css index edebf0c1..0c71ff7c 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -44,7 +44,7 @@ h2 { header { margin: 1em 0; } -header h1 { +h1 { font-family: tahoma; letter-spacing: -2px; font-size: 20pt; diff --git a/templates/themes/basic/index.html b/templates/themes/basic/index.html index 8426e736..89022420 100644 --- a/templates/themes/basic/index.html +++ b/templates/themes/basic/index.html @@ -8,8 +8,10 @@ {{ boardlist.top }} -

        {{ settings.title }}

        -
        {{ settings.subtitle }}
        +
        +

        {{ settings.title }}

        +
        {{ settings.subtitle }}
        +
        {% if news|count == 0 %} diff --git a/templates/themes/categories/news.html b/templates/themes/categories/news.html index 56ddfabb..9c7d8340 100644 --- a/templates/themes/categories/news.html +++ b/templates/themes/categories/news.html @@ -8,7 +8,10 @@

        {{ settings.title }}

        -
        {{ settings.subtitle }}
        +
        +

        {{ settings.title }}

        +
        {{ settings.subtitle }}
        +
        {% if news|count == 0 %} diff --git a/templates/themes/frameset/news.html b/templates/themes/frameset/news.html index 56ddfabb..2af5e10d 100644 --- a/templates/themes/frameset/news.html +++ b/templates/themes/frameset/news.html @@ -7,8 +7,10 @@ -

        {{ settings.title }}

        -
        {{ settings.subtitle }}
        +
        +

        {{ settings.title }}

        +
        {{ settings.subtitle }}
        +
        {% if news|count == 0 %} diff --git a/templates/themes/recent/recent.html b/templates/themes/recent/recent.html index a6daa9e7..a42024c0 100644 --- a/templates/themes/recent/recent.html +++ b/templates/themes/recent/recent.html @@ -9,8 +9,10 @@ {{ boardlist.top }} -

        {{ settings.title }}

        -
        {{ settings.subtitle }}
        +
        +

        {{ settings.title }}

        +
        {{ settings.subtitle }}
        +
        -- cgit v1.3 From f5b4bf93b0ca00bee22dec0222299352256e196c Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 22 Apr 2012 16:52:58 +1000 Subject: ?/debug/antispam formatting --- templates/mod/debug/antispam.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'templates') diff --git a/templates/mod/debug/antispam.html b/templates/mod/debug/antispam.html index 99331ed3..a846bc17 100644 --- a/templates/mod/debug/antispam.html +++ b/templates/mod/debug/antispam.html @@ -20,7 +20,7 @@ - {% endif %}
    - {{ hash.hash|upper }} + {{ hash.hash }} {{ hash.created|ago }} ago -- cgit v1.3 From aeff0a69b100d2cfa5896d043aa1891b993a7a5f Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 4 May 2012 00:21:16 +1000 Subject: minor CSS fixes --- inc/config.php | 8 ++++---- stylesheets/style.css | 28 +++++++++++++++++++++++----- templates/post_thread.html | 8 ++------ 3 files changed, 29 insertions(+), 15 deletions(-) (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 06e100ea..eb70f932 100644 --- a/inc/config.php +++ b/inc/config.php @@ -786,22 +786,22 @@ $config['mod']['link_move'] = '[Move]'; // Moderator capcodes - $config['capcode'] = ' ## %s'; + $config['capcode'] = ' ## %s'; // Custom capcodes, by example: // "## Custom" becomes lightgreen, italic and bold - //$config['custom_capcode']['Custom'] =' ## %s'; + //$config['custom_capcode']['Custom'] =' ## %s'; // "## Mod" makes everything purple, including the name and tripcode //$config['custom_capcode']['Mod'] = array( - // ' ## %s', + // ' ## %s', // 'color:purple', // Change name style; optional // 'color:purple' // Change tripcode style; optional //); // "## Admin" makes everything red and bold, including the name and tripcode //$config['custom_capcode']['Admin'] = array( - // ' ## %s', + // ' ## %s', // 'color:red;font-weight:bold', // Change name style; optional // 'color:red;font-weight:bold' // Change tripcode style; optional //); diff --git a/stylesheets/style.css b/stylesheets/style.css index 0c71ff7c..a46ca3fb 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -10,19 +10,21 @@ body { table * { margin: 0; } -a:link, a:visited { +a, a:visited { text-decoration: underline; color: #34345C; } -a:link:hover, a:visited:hover { +a:hover { color: #ff0000; } a.post_no { - color: black; text-decoration: none; margin: 0; padding: 0; } +a.post_no:not(:hover) { + color: black; +} p.intro a.post_no, p.intro a.email { margin: 0; } @@ -167,7 +169,7 @@ p.intro span.name { color: #117743; font-weight: bold; } -p.intro a.capcode, p.intro a.nametag { +p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { color: #F00000; margin-left: 0; } @@ -314,7 +316,7 @@ div.pages a.selected { color: black; font-weight: bolder; } -div.pages a:link { +div.pages a { text-decoration: none; } div.pages form { @@ -386,3 +388,19 @@ div.blotter { font-weight: bold; text-align: center; } + +/* Uboachan stuff */ +div.styles-sidebar { + text-align: center; + padding-bottom: 0px; +} +div.styles-sidebar a { + margin: 0 5px; +} +div.styles-sidebar a.selected { + text-decoration: none; +} +.category { + background: #98E; + color: black; +} diff --git a/templates/post_thread.html b/templates/post_thread.html index 095c53f9..ac5c786b 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -1,9 +1,7 @@ {% filter remove_whitespace %} {# tabs and new lines will be ignored #} -{% if index %} -
    -{% endif %} +
    {% if post.embed %} {{ post.embed }} @@ -136,6 +134,4 @@ {% include 'post_reply.html' %} {% endfor %}
    {% if hr %}
    {% endif %} -{% if index %} -
    -{% endif %} +
    -- cgit v1.3 From a6104587203f1b1b448e6977066d6e649de91ae8 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 6 May 2012 01:33:10 +1000 Subject: a lot more improvements --- inc/config.php | 5 +- inc/functions.php | 25 +- inc/mod/pages.php | 396 +++++++++++++++++++++++++++++-- install.php | 4 +- js/show-op.js | 2 - mod.php | 39 ++- templates/generic_page.html | 71 ++++++ templates/index.html | 16 +- templates/mod/ban_form.html | 20 +- templates/mod/ban_list.html | 24 +- templates/mod/board.html | 44 ++++ templates/mod/confirm.html | 4 +- templates/mod/dashboard.html | 56 ++++- templates/mod/inbox.html | 36 +++ templates/mod/log.html | 18 +- templates/mod/login.html | 4 +- templates/mod/new_pm.html | 6 +- templates/mod/news.html | 70 ++++++ templates/mod/noticeboard.html | 8 +- templates/mod/pm.html | 14 +- templates/mod/rebuild.html | 20 +- templates/mod/rebuilt.html | 4 +- templates/mod/report.html | 12 +- templates/mod/reports.html | 3 +- templates/mod/user.html | 64 +++-- templates/mod/users.html | 57 +++-- templates/mod/view_ip.html | 72 +++--- templates/page.html | 10 +- templates/themes/basic/info.php | 4 +- templates/themes/basic/theme.php | 2 +- templates/themes/categories/info.php | 4 +- templates/themes/categories/sidebar.html | 2 +- templates/themes/categories/theme.php | 12 +- templates/themes/frameset/sidebar.html | 2 +- templates/themes/frameset/theme.php | 6 +- templates/themes/recent/info.php | 6 +- templates/themes/recent/theme.php | 28 +-- templates/themes/rrdtool/info.php | 16 +- templates/themes/rrdtool/theme.php | 54 +++-- templates/thread.html | 17 +- 40 files changed, 986 insertions(+), 271 deletions(-) create mode 100644 templates/generic_page.html create mode 100644 templates/mod/board.html create mode 100644 templates/mod/inbox.html create mode 100644 templates/mod/news.html (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index 414d5262..c202d8c9 100644 --- a/inc/config.php +++ b/inc/config.php @@ -816,8 +816,6 @@ // Do a DNS lookup on IP addresses to get their hostname on the IP summary page $config['mod']['dns_lookup'] = true; - // Show ban form on the IP summary page - $config['mod']['ip_banform'] = true; // How many recent posts, per board, to show in the IP summary page $config['mod']['ip_recentposts'] = 5; @@ -829,6 +827,9 @@ // How many bans to show per page in the ban list $config['mod']['banlist_page'] = 350; + // Number of news entries to display per page + $config['mod']['news_page'] = 40; + // Maximum number of results to display for a search, per board $config['mod']['search_results'] = 75; diff --git a/inc/functions.php b/inc/functions.php index 3ca5f599..ac0a1c96 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -32,7 +32,30 @@ function loadConfig() { if (!isset($_SERVER['REMOTE_ADDR'])) $_SERVER['REMOTE_ADDR'] = '0.0.0.0'; - $arrays = array('db', 'cache', 'cookies', 'error', 'dir', 'mod', 'spam', 'flood_filters', 'wordfilters', 'custom_capcode', 'custom_tripcode', 'dnsbl', 'dnsbl_exceptions', 'remote', 'allowed_ext', 'allowed_ext_files', 'file_icons', 'footer', 'stylesheets', 'additional_javascript', 'markup'); + $arrays = array( + 'db', + 'cache', + 'cookies', + 'error', + 'dir', + 'mod', + 'spam', + 'flood_filters', + 'wordfilters', + 'custom_capcode', + 'custom_tripcode', + 'dnsbl', + 'dnsbl_exceptions', + 'remote', + 'allowed_ext', + 'allowed_ext_files', + 'file_icons', + 'footer', + 'stylesheets', + 'additional_javascript', + 'markup', + 'custom_pages' + ); $config = array(); foreach ($arrays as $key) { diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 260ad94c..c56570a5 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -9,7 +9,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { exit; } -function mod_page($title, $template, $args) { +function mod_page($title, $template, $args, $subtitle = false) { global $config, $mod; echo Element('page.html', array( @@ -17,6 +17,7 @@ function mod_page($title, $template, $args) { 'mod' => $mod, 'hide_dashboard_link' => $template == 'mod/dashboard.html', 'title' => $title, + 'subtitle' => $subtitle, 'body' => Element($template, array_merge( array('config' => $config, 'mod' => $mod), @@ -28,6 +29,8 @@ function mod_page($title, $template, $args) { } function mod_login() { + global $config; + $args = array(); if (isset($_POST['login'])) { @@ -60,8 +63,14 @@ function mod_confirm($request) { mod_page('Confirm action', 'mod/confirm.html', array('request' => $request)); } +function mod_logout() { + destroyCookies(); + + header('Location: ?/', true, $config['redirect_http']); +} + function mod_dashboard() { - global $config; + global $config, $mod; $args = array(); @@ -79,9 +88,180 @@ function mod_dashboard() { } } + $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :id AND `unread` = 1'); + $query->bindValue(':id', $mod['id']); + $query->execute() or error(db_error($query)); + $args['unread_pms'] = $query->fetchColumn(0); + + if ($mod['type'] >= ADMIN && $config['check_updates']) { + if (!$config['version']) + error(_('Could not find current version! (Check .installed)')); + + if (isset($_COOKIE['update'])) { + $latest = unserialize($_COOKIE['update']); + } else { + $ctx = stream_context_create(array('http' => array('timeout' => 5))); + if ($code = @file_get_contents('http://tinyboard.org/version.txt', 0, $ctx)) { + eval($code); + if (preg_match('/v(\d+)\.(\d)\.(\d+)(-dev.+)?$/', $config['version'], $matches)) { + $current = array( + 'massive' => (int) $matches[1], + 'major' => (int) $matches[2], + 'minor' => (int) $matches[3] + ); + if (isset($m[4])) { + // Development versions are always ahead in the versioning numbers + $current['minor'] --; + } + // Check if it's newer + if (!( $latest['massive'] > $current['massive'] || + $latest['major'] > $current['major'] || + ($latest['massive'] == $current['massive'] && + $latest['major'] == $current['major'] && + $latest['minor'] > $current['minor'] + ))) + $latest = false; + } else { + $latest = false; + } + } else { + // Couldn't get latest version + $latest = false; + } + + setcookie('update', serialize($latest), time() + $config['check_updates_time'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, false, true); + } + + if ($latest) + $args['newer_release'] = $latest; + } + mod_page('Dashboard', 'mod/dashboard.html', $args); } +function mod_edit_board($boardName) { + global $board, $config; + + if (!openBoard($boardName)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['manageboards'], $board['uri'])) + error($config['error']['noaccess']); + + if (isset($_POST['title'], $_POST['subtitle'])) { + if (isset($_POST['delete'])) { + if (!hasPermission($config['mod']['manageboards'], $board['uri'])) + error($config['error']['deleteboard']); + + $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); + $query->bindValue(':uri', $board['uri']); + $query->execute() or error(db_error($query)); + + modLog('Deleted board: ' . sprintf($config['board_abbreviation'], $board['uri']), false); + + // Delete entire board directory + rrmdir($board['uri'] . '/'); + + // Delete posting table + $query = query(sprintf('DROP TABLE IF EXISTS `posts_%s`', $board['uri'])) or error(db_error()); + + // Clear reports + $query = prepare('DELETE FROM `reports` WHERE `board` = :id'); + $query->bindValue(':id', $board['uri'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + // Delete from table + $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); + $query->bindValue(':uri', $board['uri'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + if ($config['cache']['enabled']) { + cache::delete('board_' . $board['uri']); + cache::delete('all_boards'); + } + + $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board"); + $query->bindValue(':board', $board['uri']); + $query->execute() or error(db_error($query)); + while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { + if ($board['uri'] != $cite['board']) { + if (!isset($tmp_board)) + $tmp_board = $board; + openBoard($cite['board']); + rebuildPost($cite['post']); + } + } + + $query = prepare('DELETE FROM `cites` WHERE `board` = :board OR `target_board` = :board'); + $query->bindValue(':board', $board['uri']); + $query->execute() or error(db_error($query)); + + $query = prepare('DELETE FROM `antispam` WHERE `board` = :board'); + $query->bindValue(':board', $board['uri']); + $query->execute() or error(db_error($query)); + } else { + $query = prepare('UPDATE `boards` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); + $query->bindValue(':uri', $board['uri']); + $query->bindValue(':title', $_POST['title']); + $query->bindValue(':subtitle', $_POST['subtitle']); + $query->execute() or error(db_error($query)); + } + + rebuildThemes('boards'); + + header('Location: ?/', true, $config['redirect_http']); + } else { + mod_page('Edit board: ' . sprintf($config['board_abbreviation'], $board['uri']), 'mod/board.html', array('board' => $board)); + } +} + +function mod_new_board() { + global $config, $board; + + if (!hasPermission($config['mod']['newboard'])) + error($config['error']['noaccess']); + + if (isset($_POST['uri'], $_POST['title'], $_POST['subtitle'])) { + if ($_POST['uri'] == '') + error(sprintf($config['error']['required'], 'URI')); + + if ($_POST['title'] == '') + error(sprintf($config['error']['required'], 'title')); + + if (!preg_match('/^\w+$/', $_POST['uri'])) + error(sprintf($config['error']['invalidfield'], 'URI')); + + if (openBoard($_POST['uri'])) { + error(sprintf($config['error']['boardexists'], $board['url'])); + } + + $query = prepare('INSERT INTO `boards` VALUES (:uri, :title, :subtitle)'); + $query->bindValue(':uri', $_POST['uri']); + $query->bindValue(':title', $_POST['title']); + $query->bindValue(':subtitle', $_POST['subtitle']); + $query->execute() or error(db_error($query)); + + modLog('Created a new board: ' . sprintf($config['board_abbreviation'], $_POST['uri'])); + + if (!openBoard($_POST['uri'])) + error(_("Couldn't open board after creation.")); + + query(Element('posts.sql', array('board' => $board['uri']))) or error(db_error()); + + if ($config['cache']['enabled']) + cache::delete('all_boards'); + + // Build the board + buildIndex(); + + rebuildThemes('boards'); + + header('Location: ?/' . $board['uri'] . '/' . $config['file_index'], true, $config['redirect_http']); + } + + mod_page('New board', 'mod/board.html', array('new' => true)); +} + function mod_noticeboard($page_no = 1) { global $config, $pdo, $mod; @@ -104,9 +284,11 @@ function mod_noticeboard($page_no = 1) { $query->bindValue(':body', $_POST['body']); $query->execute() or error(db_error($query)); - if($config['cache']['enabled']) + if ($config['cache']['enabled']) cache::delete('noticeboard_preview'); + modLog('Posted a noticeboard entry'); + header('Location: ?/noticeboard#' . $pdo->lastInsertId(), true, $config['redirect_http']); } @@ -126,6 +308,78 @@ function mod_noticeboard($page_no = 1) { mod_page('Noticeboard', 'mod/noticeboard.html', array('noticeboard' => $noticeboard, 'count' => $count)); } +function mod_noticeboard_delete($id) { + global $config; + + if (!hasPermission($config['mod']['noticeboard_delete'])) + error($config['error']['noaccess']); + + $query = prepare('DELETE FROM `noticeboard` WHERE `id` = :id'); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + modLog('Deleted a noticeboard entry'); + + header('Location: ?/noticeboard', true, $config['redirect_http']); +} + +function mod_news($page_no = 1) { + global $config, $pdo, $mod; + + if ($page_no < 1) + error($config['error']['404']); + + if (isset($_POST['subject'], $_POST['body'])) { + if (!hasPermission($config['mod']['news'])) + error($config['error']['noaccess']); + + markup($_POST['body']); + + $query = prepare('INSERT INTO `news` VALUES (NULL, :name, :time, :subject, :body)'); + $query->bindValue(':name', isset($_POST['name']) && hasPermission($config['mod']['news_custom']) ? $_POST['name'] : $mod['username']); + $query->bindvalue(':time', time()); + $query->bindValue(':subject', $_POST['subject']); + $query->bindValue(':body', $_POST['body']); + $query->execute() or error(db_error($query)); + + modLog('Posted a news entry'); + + rebuildThemes('news'); + + header('Location: ?/news#' . $pdo->lastInsertId(), true, $config['redirect_http']); + } + + $query = prepare("SELECT * FROM `news` ORDER BY `id` DESC LIMIT :offset, :limit"); + $query->bindValue(':limit', $config['mod']['news_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['news_page'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $news = $query->fetchAll(PDO::FETCH_ASSOC); + + if (empty($news) && $page_no > 1) + error($config['error']['404']); + + $query = prepare("SELECT COUNT(*) FROM `news`"); + $query->execute() or error(db_error($query)); + $count = $query->fetchColumn(0); + + mod_page('News', 'mod/news.html', array('news' => $news, 'count' => $count)); +} + +function mod_news_delete($id) { + global $config; + + if (!hasPermission($config['mod']['news_delete'])) + error($config['error']['noaccess']); + + $query = prepare('DELETE FROM `news` WHERE `id` = :id'); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + modLog('Deleted a news entry'); + + header('Location: ?/news', true, $config['redirect_http']); +} + function mod_log($page_no = 1) { global $config; @@ -135,7 +389,7 @@ function mod_log($page_no = 1) { if (!hasPermission($config['mod']['modlog'])) error($config['error']['noaccess']); - $query = prepare("SELECT `username`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -196,7 +450,7 @@ function mod_ip_remove_note($ip, $id) { modLog("Removed a note for {$ip}"); - header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + header('Location: ?/IP/' . $ip . '#notes', true, $config['redirect_http']); } function mod_page_ip($ip) { @@ -212,7 +466,8 @@ function mod_page_ip($ip) { require_once 'inc/mod/ban.php'; unban($_POST['ban_id']); - header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + + header('Location: ?/IP/' . $ip . '#bans', true, $config['redirect_http']); return; } @@ -230,7 +485,7 @@ function mod_page_ip($ip) { modLog("Added a note for {$ip}"); - header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + header('Location: ?/IP/' . $ip . '#notes', true, $config['redirect_http']); return; } @@ -238,6 +493,9 @@ function mod_page_ip($ip) { $args['ip'] = $ip; $args['posts'] = array(); + if ($config['mod']['dns_lookup']) + $args['hostname'] = rDNS($ip); + $boards = listBoards(); foreach ($boards as $board) { openBoard($board['uri']); @@ -287,7 +545,7 @@ function mod_page_ip($ip) { $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); } - mod_page("IP: $ip", 'mod/view_ip.html', $args); + mod_page("IP: $ip", 'mod/view_ip.html', $args, $args['hostname']); } function mod_ban() { @@ -382,7 +640,7 @@ function mod_lock($board, $unlock, $post) { $query->bindValue(':id', $post); $query->bindValue(':locked', $unlock ? 0 : 1); $query->execute() or error(db_error($query)); - if($query->rowCount()) { + if ($query->rowCount()) { modLog(($unlock ? 'Unlocked' : 'Locked') . " thread #{$post}"); buildThread($post); buildIndex(); @@ -404,7 +662,7 @@ function mod_sticky($board, $unsticky, $post) { $query->bindValue(':id', $post); $query->bindValue(':sticky', $unsticky ? 0 : 1); $query->execute() or error(db_error($query)); - if($query->rowCount()) { + if ($query->rowCount()) { modLog(($unlock ? 'Unstickied' : 'Stickied') . " thread #{$post}"); buildThread($post); buildIndex(); @@ -426,7 +684,7 @@ function mod_bumplock($board, $unbumplock, $post) { $query->bindValue(':id', $post); $query->bindValue(':bumplock', $unbumplock ? 0 : 1); $query->execute() or error(db_error($query)); - if($query->rowCount()) { + if ($query->rowCount()) { modLog(($unlock ? 'Unbumplocked' : 'Bumplocked') . " thread #{$post}"); buildThread($post); buildIndex(); @@ -447,7 +705,7 @@ function mod_ban_post($board, $delete, $post) { $query = prepare(sprintf('SELECT `ip`, `thread` FROM `posts_%s` WHERE `id` = :id', $board)); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); - if(!$_post = $query->fetch(PDO::FETCH_ASSOC)) + if (!$_post = $query->fetch(PDO::FETCH_ASSOC)) error($config['error']['404']); $thread = $_post['thread']; @@ -624,25 +882,54 @@ function mod_user($uid) { } } + if (isset($_POST['delete'])) { + if (!hasPermission($config['mod']['deleteusers'])) + error($config['error']['noaccess']); + + $query = prepare('DELETE FROM `mods` WHERE `id` = :id'); + $query->bindValue(':id', $uid); + $query->execute() or error(db_error($query)); + + modLog('Deleted user ' . utf8tohtml($user['username']) . ' (#' . $user['id'] . ')'); + + header('Location: ?/users', true, $config['redirect_http']); + + return; + } + + if ($_POST['username'] == '') + error(sprintf($config['error']['required'], 'username')); + $query = prepare('UPDATE `mods` SET `username` = :username, `boards` = :boards WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':username', $_POST['username']); $query->bindValue(':boards', implode(',', $boards)); $query->execute() or error(db_error($query)); + if ($user['username'] !== $_POST['username']) { + // account was renamed + modLog('Renamed user "' . utf8tohtml($user['username']) . '" (#' . $user['id'] . ') to "' . utf8tohtml($_POST['username']) . '"'); + } + if ($_POST['password'] != '') { $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':password', $_POST['password']); $query->execute() or error(db_error($query)); + modLog('Changed password for ' . utf8tohtml($_POST['username']) . ' (#' . $user['id'] . ')'); + if ($uid == $mod['id']) { login($_POST['username'], $_POST['password']); setCookies(); } } - header('Location: ?/users', true, $config['redirect_http']); + if (hasPermission($config['mod']['manageusers'])) + header('Location: ?/users', true, $config['redirect_http']); + else + header('Location: ?/', true, $config['redirect_http']); + return; } @@ -653,11 +940,17 @@ function mod_user($uid) { $query->bindValue(':password', $_POST['password']); $query->execute() or error(db_error($query)); - login($_POST['username'], $_POST['password']); + modLog('Changed own password'); + + login($user['username'], $_POST['password']); setCookies(); } - header('Location: ?/users', true, $config['redirect_http']); + if (hasPermission($config['mod']['manageusers'])) + header('Location: ?/users', true, $config['redirect_http']); + else + header('Location: ?/', true, $config['redirect_http']); + return; } @@ -675,6 +968,47 @@ function mod_user($uid) { mod_page('Edit user', 'mod/user.html', array('user' => $user, 'logs' => $log, 'boards' => listBoards())); } +function mod_user_new() { + if (isset($_POST['username'], $_POST['password'], $_POST['type'])) { + if ($_POST['username'] == '') + error(sprintf($config['error']['required'], 'username')); + if ($_POST['password'] == '') + error(sprintf($config['error']['required'], 'password')); + + if (isset($_POST['allboards'])) { + $boards = array('*'); + } else { + $_boards = listBoards(); + foreach ($_boards as &$board) { + $board = $board['uri']; + } + + $boards = array(); + foreach ($_POST as $name => $value) { + if (preg_match('/^board_(\w+)$/', $name, $matches) && in_array($matches[1], $_boards)) + $boards[] = $matches[1]; + } + } + + $_POST['type'] = (int) $_POST['type']; + if ($_POST['type'] !== JANITOR && $_POST['type'] !== MOD && $_POST['type'] !== ADMIN) + error(sprintf($config['error']['invalidfield'], 'type')); + + $query = prepare('INSERT INTO `mods` VALUES (NULL, :username, SHA1(:password), :type, :boards)'); + $query->bindValue(':username', $_POST['username']); + $query->bindValue(':password', $_POST['password']); + $query->bindValue(':type', $_POST['type']); + $query->bindValue(':boards', implode(',', $boards)); + $query->execute() or error(db_error($query)); + + header('Location: ?/users', true, $config['redirect_http']); + return; + } + + mod_page('Edit user', 'mod/user.html', array('new' => true, 'boards' => listBoards())); +} + + function mod_users() { global $config; @@ -734,12 +1068,38 @@ function mod_pm($id, $reply = false) { 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']))); + mod_page("New PM for {$pm['to_username']}", 'mod/new_pm.html', array( + 'username' => $pm['username'], 'id' => $pm['sender'], 'message' => quote($pm['message']) + )); } else { mod_page("Private message – #$id", 'mod/pm.html', $pm); } } +function mod_inbox() { + global $config, $mod; + + $query = prepare('SELECT `unread`,`pms`.`id`, `time`, `sender`, `to`, `message`, `username` FROM `pms` LEFT JOIN `mods` ON `mods`.`id` = `sender` WHERE `to` = :mod ORDER BY `unread` DESC, `time` DESC'); + $query->bindValue(':mod', $mod['id']); + $query->execute() or error(db_error($query)); + $messages = $query->fetchAll(PDO::FETCH_ASSOC); + + $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :mod AND `unread` = 1'); + $query->bindValue(':mod', $mod['id']); + $query->execute() or error(db_error($query)); + $unread = $query->fetchColumn(0); + + foreach ($messages as &$message) { + $message['snippet'] = pm_snippet($message['message']); + } + + mod_page('PM inbox (' . (count($messages) > 0 ? $unread . ' unread' : 'empty') . ')', 'mod/inbox.html', array( + 'messages' => $messages, + 'unread' => $unread + )); +} + + function mod_new_pm($username) { global $config, $mod; @@ -920,7 +1280,7 @@ function mod_reports() { $body .= $po->build(true) . '
    '; - if(isset($__old_body_truncate_char)) + if (isset($__old_body_truncate_char)) $config['body_truncate_char'] = $__old_body_truncate_char; } @@ -971,7 +1331,7 @@ function mod_debug_antispam() { if (isset($_POST['board'], $_POST['thread'])) { $where = '`board` = ' . $pdo->quote($_POST['board']); - if($_POST['thread'] != '') + if ($_POST['thread'] != '') $where .= ' AND `thread` = ' . $pdo->quote($_POST['thread']); if (isset($_POST['purge'])) { diff --git a/install.php b/install.php index 2e732c4c..1e872911 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ ':?/', // redirect to dashboard '!^/$!' => 'dashboard', // dashboard '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) + '!^/logout$!' => 'logout', // logout '!^/users$!' => 'users', // manage users '!^/users/(\d+)$!' => 'user', // edit user '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user + '!^/users/new$!' => 'user_new', // create a new user '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm + '!^/inbox$!' => 'inbox', // pm inbox '!^/noticeboard$!' => 'noticeboard', // view noticeboard '!^/noticeboard/(\d+)$!' => 'noticeboard', // view noticeboard + '!^/noticeboard/delete/(\d+)$!' => 'noticeboard_delete',// delete from noticeboard '!^/log$!' => 'log', // modlog '!^/log/(\d+)$!' => 'log', // modlog + '!^/news$!' => 'news', // view news + '!^/news/(\d+)$!' => 'news', // view news + '!^/news/delete/(\d+)$!' => 'news_delete', // delete from news + + '!^/edit/(\w+)$!' => 'edit_board', // edit board details + '!^/new-board$!' => 'new_board', // create a new board + '!^/rebuild$!' => 'rebuild', // rebuild static files '!^/reports$!' => 'reports', // report queue '!^/reports/(\d+)/dismiss(all)?$!' => 'report_dismiss', // dismiss a report @@ -64,8 +75,14 @@ $pages = array( str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_thread', ); -if (!$mod) + +if (!$mod) { $pages = array('//' => 'login'); +} elseif (isset($_GET['status'], $_GET['r'])) { + header('Location: ' . $_GET['r'], true, (int)$_GET['stats']); +} elseif (isset($config['mod']['custom_pages'])) { + $pages = array_merge($pages, $config['mod']['custom_pages']); +} foreach ($pages as $uri => $handler) { if (preg_match($uri, $query, $matches)) { @@ -79,14 +96,20 @@ foreach ($pages as $uri => $handler) { ); } - if ($handler[0] == ':') { - header('Location: ' . substr($handler, 1), true, $config['redirect_http']); - } elseif (is_callable("mod_page_$handler")) { - call_user_func_array("mod_page_$handler", $matches); - } elseif (is_callable("mod_$handler")) { - call_user_func_array("mod_$handler", $matches); + if (is_string($handler)) { + if ($handler[0] == ':') { + header('Location: ' . substr($handler, 1), true, $config['redirect_http']); + } elseif (is_callable("mod_page_$handler")) { + call_user_func_array("mod_page_$handler", $matches); + } elseif (is_callable("mod_$handler")) { + call_user_func_array("mod_$handler", $matches); + } else { + error("Mod page '$handler' not found!"); + } + } elseif (is_callable($handler)) { + call_user_func_array($handler, $matches); } else { - error("Mod page '$handler' not found!"); + error("Mod page '$handler' not a string, and not callable!"); } exit; diff --git a/templates/generic_page.html b/templates/generic_page.html new file mode 100644 index 00000000..e834aad0 --- /dev/null +++ b/templates/generic_page.html @@ -0,0 +1,71 @@ + + + + {% block head %} + + {% if config.url_favicon %}{% endif %} + {{ board.url }} - {{ board.name }} + + + {% if config.meta_keywords %}{% endif %} + {% if config.default_stylesheet.1 != '' %}{% endif %} + {% if not nojavascript %} + + {% if not config.additional_javascript_compile %} + {% for javascript in config.additional_javascript %}{% endfor %} + {% endif %} + {% endif %} + {% if config.recaptcha %}{% endif %} + {% endblock %} + + + {{ boardlist.top }} + {% if pm %}
    You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

    {% endif %} + {% if config.url_banner %}{% endif %} +
    +

    {{ board.url }} - {{ board.name }}

    +
    + {% if board.title %} + {{ board.title|e }} + {% endif %} + {% if mod %}

    {% trans %}Return to dashboard{% endtrans %}

    {% endif %} +
    +
    + + {% include 'post_form.html' %} + + {% if config.blotter %}
    {{ config.blotter }}
    {% endif %} +
    +
    + + {% if mod %}{% endif %} + {{ body }} + {% include 'report_delete.html' %} +
    +
    {{ btn.prev }} {% for page in pages %} + [{{ page.num }}]{% if loop.last %} {% endif %} + {% endfor %} {{ btn.next }}
    + {{ boardlist.bottom }} +
    +

    Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2012 Tinyboard Development Group

    + {% for footer in config.footer %}

    {{ footer }}

    {% endfor %} +
    + + + diff --git a/templates/index.html b/templates/index.html index f12e2517..a28724a1 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,13 +1,13 @@ - - {% if config.url_favicon %}{% endif %} + + + {% if config.url_favicon %}{% endif %} {{ board.url }} - {{ board.name }} - - - {% if config.meta_keywords %}{% endif %} - + + {% if config.meta_keywords %}{% endif %} + {% if config.default_stylesheet.1 != '' %}{% endif %} {% if not nojavascript %} {% if not config.additional_javascript_compile %} @@ -35,10 +35,10 @@ {% if pm %}
    You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

    {% endif %} {% if config.url_banner %}{% endif %}
    -

    {{ board.url }} - {{ board.title }}

    +

    {{ board.url }} - {{ board.title|e }}

    {% if board.subtitle %} - {{ board.subtitle }} + {{ board.subtitle|e }} {% endif %} {% if mod %}

    {% trans %}Return to dashboard{% endtrans %}

    {% endif %}
    diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html index 9d4d6728..5d5f2b81 100644 --- a/templates/mod/ban_form.html +++ b/templates/mod/ban_form.html @@ -16,19 +16,19 @@
    - + {% if not hide_ip %} {% else %} - hidden + {% trans 'hidden' %} {% endif %}
    - + @@ -37,12 +37,12 @@ {% if post and board and not delete %}
    - + - (public; attached to post) + ({% trans 'public; attached to post' %}) {% endif %} diff --git a/templates/themes/basic/info.php b/templates/themes/basic/info.php index b782a6d4..0b8ba98b 100644 --- a/templates/themes/basic/info.php +++ b/templates/themes/basic/info.php @@ -44,9 +44,9 @@ $theme['build_function'] = 'basic_build'; $theme['install_callback'] = 'build_install'; - if(!function_exists('build_install')) { + if (!function_exists('build_install')) { function build_install($settings) { - if(!is_numeric($settings['no_recent']) || $settings['no_recent'] < 0) + if (!is_numeric($settings['no_recent']) || $settings['no_recent'] < 0) return Array(false, '' . utf8tohtml($settings['no_recent']) . ' is not a non-negative integer.'); } } diff --git a/templates/themes/basic/theme.php b/templates/themes/basic/theme.php index a07dc7ec..806a331a 100644 --- a/templates/themes/basic/theme.php +++ b/templates/themes/basic/theme.php @@ -15,7 +15,7 @@ public static function build($action, $settings) { global $config; - if($action == 'all' || $action == 'news') + if ($action == 'all' || $action == 'news') file_write($config['dir']['home'] . $settings['file'], Basic::homepage($settings)); } diff --git a/templates/themes/categories/info.php b/templates/themes/categories/info.php index 5ae3d296..62d8f6bb 100644 --- a/templates/themes/categories/info.php +++ b/templates/themes/categories/info.php @@ -54,11 +54,11 @@ Requires $config[\'categories\'].'; $theme['build_function'] = 'categories_build'; $theme['install_callback'] = 'categories_install'; - if(!function_exists('categories_install')) { + if (!function_exists('categories_install')) { function categories_install($settings) { global $config; - if(!isset($config['categories'])) { + if (!isset($config['categories'])) { return Array(false, '

    Prerequisites not met!

    ' . 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.'); } diff --git a/templates/themes/categories/sidebar.html b/templates/themes/categories/sidebar.html index a4bc28ae..856930ab 100644 --- a/templates/themes/categories/sidebar.html +++ b/templates/themes/categories/sidebar.html @@ -31,7 +31,7 @@ {% for board in boards %}
  • - {{ board.title }} + {{ board.title|e }}
  • {% endfor %} diff --git a/templates/themes/categories/theme.php b/templates/themes/categories/theme.php index 648034e7..11fcbbaf 100644 --- a/templates/themes/categories/theme.php +++ b/templates/themes/categories/theme.php @@ -15,13 +15,13 @@ public static function build($action, $settings) { global $config; - if($action == 'all') + if ($action == 'all') file_write($config['dir']['home'] . $settings['file_main'], Categories::homepage($settings)); - if($action == 'all' || $action == 'boards') + if ($action == 'all' || $action == 'boards') file_write($config['dir']['home'] . $settings['file_sidebar'], Categories::sidebar($settings)); - if($action == 'all' || $action == 'news') + if ($action == 'all' || $action == 'news') file_write($config['dir']['home'] . $settings['file_news'], Categories::news($settings)); } @@ -52,10 +52,10 @@ $categories = $config['categories']; - foreach($categories as &$boards) { - foreach($boards as &$board) { + foreach ($categories as &$boards) { + foreach ($boards as &$board) { $title = boardTitle($board); - if(!$title) + if (!$title) $title = $board; // board doesn't exist, but for some reason you want to display it anyway $board = Array('title' => $title, 'uri' => sprintf($config['board_path'], $board)); } diff --git a/templates/themes/frameset/sidebar.html b/templates/themes/frameset/sidebar.html index 457ecec8..40e2d719 100644 --- a/templates/themes/frameset/sidebar.html +++ b/templates/themes/frameset/sidebar.html @@ -30,7 +30,7 @@ {% for board in boards %}
  • - {{ board.title }} + {{ board.title|e }}
  • {% endfor %} diff --git a/templates/themes/frameset/theme.php b/templates/themes/frameset/theme.php index f3e1b139..015eebaf 100644 --- a/templates/themes/frameset/theme.php +++ b/templates/themes/frameset/theme.php @@ -15,13 +15,13 @@ public static function build($action, $settings) { global $config; - if($action == 'all') + if ($action == 'all') file_write($config['dir']['home'] . $settings['file_main'], Frameset::homepage($settings)); - if($action == 'all' || $action == 'boards') + if ($action == 'all' || $action == 'boards') file_write($config['dir']['home'] . $settings['file_sidebar'], Frameset::sidebar($settings)); - if($action == 'all' || $action == 'news') + if ($action == 'all' || $action == 'news') file_write($config['dir']['home'] . $settings['file_news'], Frameset::news($settings)); } diff --git a/templates/themes/recent/info.php b/templates/themes/recent/info.php index 83d7477a..d4cf1029 100644 --- a/templates/themes/recent/info.php +++ b/templates/themes/recent/info.php @@ -60,11 +60,11 @@ $theme['build_function'] = 'recentposts_build'; $theme['install_callback'] = 'recentposts_install'; - if(!function_exists('recentposts_install')) { + if (!function_exists('recentposts_install')) { function recentposts_install($settings) { - if(!is_numeric($settings['limit_images']) || $settings['limit_images'] < 0) + if (!is_numeric($settings['limit_images']) || $settings['limit_images'] < 0) return Array(false, '' . utf8tohtml($settings['limit_images']) . ' is not a non-negative integer.'); - if(!is_numeric($settings['limit_posts']) || $settings['limit_posts'] < 0) + if (!is_numeric($settings['limit_posts']) || $settings['limit_posts'] < 0) return Array(false, '' . utf8tohtml($settings['limit_posts']) . ' is not a non-negative integer.'); } } diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index 13a5546f..986fac6a 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -17,13 +17,13 @@ public function build($action, $settings) { global $config, $_theme; - if($action == 'all') { + if ($action == 'all') { copy('templates/themes/recent/recent.css', $config['dir']['home'] . $settings['css']); } $this->excluded = explode(' ', $settings['exclude']); - if($action == 'all' || $action == 'post') + if ($action == 'all' || $action == 'post') file_write($config['dir']['home'] . $settings['html'], $this->homepage($settings)); } @@ -38,15 +38,15 @@ $boards = listBoards(); $query = ''; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']); } $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_images'], $query); $query = query($query) or error(db_error()); - while($post = $query->fetch()) { + while ($post = $query->fetch()) { openBoard($post['board']); // board settings won't be available in the template file, so generate links now @@ -58,15 +58,15 @@ $query = ''; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` UNION ALL ", $_board['uri'], $_board['uri']); } $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_posts'], $query); $query = query($query) or error(db_error()); - while($post = $query->fetch()) { + while ($post = $query->fetch()) { openBoard($post['board']); $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; @@ -78,8 +78,8 @@ // Total posts $query = 'SELECT SUM(`top`) AS `count` FROM ('; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT MAX(`id`) AS `top` FROM `posts_%s` UNION ALL ", $_board['uri']); } @@ -90,8 +90,8 @@ // Unique IPs $query = 'SELECT COUNT(DISTINCT(`ip`)) AS `count` FROM ('; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT `ip` FROM `posts_%s` UNION ALL ", $_board['uri']); } @@ -102,8 +102,8 @@ // Active content $query = 'SELECT SUM(`filesize`) AS `count` FROM ('; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT `filesize` FROM `posts_%s` UNION ALL ", $_board['uri']); } diff --git a/templates/themes/rrdtool/info.php b/templates/themes/rrdtool/info.php index 73658a22..46a20587 100644 --- a/templates/themes/rrdtool/info.php +++ b/templates/themes/rrdtool/info.php @@ -28,7 +28,7 @@ $__boards = listBoards(); $__default_boards = Array(); - foreach($__boards as $__board) + foreach ($__boards as $__board) $__default_boards[] = $__board['uri']; $theme['config'][] = Array( @@ -83,31 +83,31 @@ ); $theme['install_callback'] = 'rrdtool_install'; - if(!function_exists('rrdtool_install')) { + if (!function_exists('rrdtool_install')) { function rrdtool_install($settings) { global $config; - if(!is_numeric($settings['interval']) || $settings['interval'] < 1 || $settings['interval'] > 86400) + if (!is_numeric($settings['interval']) || $settings['interval'] < 1 || $settings['interval'] > 86400) return Array(false, 'Invalid interval: ' . $settings['interval'] . '. Must be an integer greater than 1 and less than 86400.'); - if(!is_numeric($settings['width']) || $settings['width'] < 1) + if (!is_numeric($settings['width']) || $settings['width'] < 1) return Array(false, 'Invalid width: ' . $settings['width'] . '!'); - if(!is_numeric($settings['height']) || $settings['height'] < 1) + if (!is_numeric($settings['height']) || $settings['height'] < 1) return Array(false, 'Invalid height: ' . $settings['height'] . '!'); - if(!in_array($settings['rate'], Array('second', 'minute', 'day', 'hour', 'week', 'month', 'year'))) + if (!in_array($settings['rate'], Array('second', 'minute', 'day', 'hour', 'week', 'month', 'year'))) return Array(false, 'Invalid rate: ' . $settings['rate'] . '!'); $job = '*/' . $settings['interval'] . ' * * * * php -q ' . str_replace('\\', '/', dirname(__FILE__)) . '/cron.php' . PHP_EOL; - if(function_exists('system')) { + if (function_exists('system')) { $crontab = tempnam($config['tmp'], 'tinyboard-rrdtool'); file_write($crontab, $job); @system('crontab ' . escapeshellarg($crontab), $ret); unlink($crontab); - if($ret === 0) + if ($ret === 0) return ''; // it seems to install okay? } diff --git a/templates/themes/rrdtool/theme.php b/templates/themes/rrdtool/theme.php index 20a00e76..eed2ac9a 100644 --- a/templates/themes/rrdtool/theme.php +++ b/templates/themes/rrdtool/theme.php @@ -17,7 +17,7 @@ public function build($action, $settings) { global $config, $_theme, $argv; - if(!$settings) { + if (!$settings) { error('This theme is not currently installed.'); } @@ -26,18 +26,18 @@ // exclude boards from the "combined" graph $this->combined_exclude = Array(); - if($action == 'cron') { - if(!file_exists($settings['path'])) + if ($action == 'cron') { + if (!file_exists($settings['path'])) mkdir($settings['path']); - if(!file_exists($settings['images'])) + if (!file_exists($settings['images'])) mkdir($settings['images']); - foreach($this->boards as &$board) { + foreach ($this->boards as &$board) { $file = $settings['path'] . '/' . $board . '.rrd'; - if(!file_exists($file)) { + if (!file_exists($file)) { // Create graph - if(!rrd_create($file, Array( + if (!rrd_create($file, Array( '-s 60', 'DS:posts:COUNTER:86400:0:10000', @@ -59,22 +59,22 @@ } // debug just the graphing (not updating) with the --debug switch - if(!isset($argv[1]) || $argv[1] != '--debug') { + if (!isset($argv[1]) || $argv[1] != '--debug') { // Update graph $query = query(sprintf("SELECT MAX(`id`) AS `count` FROM `posts_%s`", $board)); $count = $query->fetch(); $count = $count['count']; - if(!rrd_update($file, Array( + if (!rrd_update($file, Array( '-t', 'posts', 'N:' . $count))) error('RRDtool failed: ' . htmlentities(rrd_error())); } - foreach($this->spans as &$span) { + foreach ($this->spans as &$span) { // Graph graph - if(!rrd_graph($settings['images'] . '/' . $board . '-' . $span . '.png', Array( + if (!rrd_graph($settings['images'] . '/' . $board . '-' . $span . '.png', Array( '-s -1' . $span, '-t Posts on ' . sprintf($config['board_abbreviation'], $board) .' this ' . $span, '--lazy', @@ -105,7 +105,7 @@ } // combined graph - foreach($this->spans as &$span) { + foreach ($this->spans as &$span) { $options = Array( '-s -1' . $span, '-t Posts this ' . $span, @@ -129,8 +129,8 @@ $c = 1; $cc = 0; $red = 2; - foreach($this->boards as &$board) { - if(in_array($board, $this->combined_exclude)) + foreach ($this->boards as &$board) { + if (in_array($board, $this->combined_exclude)) continue; $color = str_pad(dechex($red*85), 2, '0', STR_PAD_LEFT) . str_pad(dechex($green*85), 2, '0', STR_PAD_LEFT) . @@ -147,31 +147,35 @@ sprintf($config['board_abbreviation'], $board); // Randomize colors using this horrible undocumented algorithm I threw together while debugging - if($c == 0) + if ($c == 0) $red++; - elseif($c == 1) + elseif ($c == 1) $green++; - elseif($c == 2) + elseif ($c == 2) $blue++; - elseif($c == 3) + elseif ($c == 3) $green--; - elseif($c == 4) + elseif ($c == 4) $red--; $cc++; - if($cc > 2) { + if ($cc > 2) { $c++; $cc = 0; } - if($c>4) $c = 0; + if ($c > 4) + $c = 0; - if($red>3) $red = 0; - if($green>3) $green = 0; - if($blue>3) $blue = 0; + if ($red > 3) + $red = 0; + if ($green > 3) + $green = 0; + if ($blue > 3) + $blue = 0; } $options[] = 'HRULE:0#000000'; - if(!rrd_graph($settings['images'] . '/combined-' . $span . '.png', $options)) + if (!rrd_graph($settings['images'] . '/combined-' . $span . '.png', $options)) error('RRDtool failed: ' . htmlentities(rrd_error())); } } diff --git a/templates/thread.html b/templates/thread.html index 9a56a50f..e7c65f9b 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -1,13 +1,13 @@ - - {% if config.url_favicon %}{% endif %} + + + {% if config.url_favicon %}{% endif %} {{ board.url }} - {{ board.name }} - - - {% if config.meta_keywords %}{% endif %} - + + {% if config.meta_keywords %}{% endif %} + {% if config.default_stylesheet.1 != '' %}{% endif %} {% if not nojavascript %} {% if not config.additional_javascript_compile %} @@ -29,17 +29,16 @@ display: block; } {% endraw %}{% endif %} - {{ boardlist.top }} {% if pm %}
    You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

    {% endif %} {% if config.url_banner %}{% endif %}
    -

    {{ board.url }} - {{ board.title }}

    +

    {{ board.url }} - {{ board.title|e }}

    {% if board.subtitle %} - {{ board.subtitle }} + {{ board.subtitle|e }} {% endif %} {% if mod %}

    {% trans %}Return to dashboard{% endtrans %}

    {% endif %}
    -- cgit v1.3 From af61bcaf77204f7bd84ef482c489faa17b13a0b1 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 22 Apr 2012 17:50:53 +1000 Subject: Slightly less crappy stylesheet chooser --- inc/config.php | 2 +- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 1 + stylesheets/default.css | 0 templates/main.js | 110 ++++++++++++++++-------- templates/page.html | 4 +- 5 files changed, 76 insertions(+), 41 deletions(-) delete mode 100644 stylesheets/default.css (limited to 'templates') diff --git a/inc/config.php b/inc/config.php index c202d8c9..baa1d022 100644 --- a/inc/config.php +++ b/inc/config.php @@ -525,7 +525,7 @@ // $config['banner_height'] = 100; // Custom stylesheets available. The prefix for each stylesheet URI is defined below. - $config['stylesheets']['Yotsuba B'] = 'default.css'; + $config['stylesheets']['Yotsuba B'] = ''; // default $config['stylesheets']['Yotsuba'] = 'yotsuba.css'; // $config['stylesheets']['Futaba'] = 'futaba.css'; diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index c4810dad..0a128e7b 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -25,6 +25,7 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension 'until' => new Twig_Filter_Function('until'), 'split' => new Twig_Filter_Function('twig_split_filter'), 'push' => new Twig_Filter_Function('twig_push_filter'), + 'addslashes' => new Twig_Filter_Function('addslashes') ); } diff --git a/stylesheets/default.css b/stylesheets/default.css deleted file mode 100644 index e69de29b..00000000 diff --git a/templates/main.js b/templates/main.js index de62bd8b..b0a96393 100644 --- a/templates/main.js +++ b/templates/main.js @@ -1,12 +1,71 @@ {% raw %} -var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0 }}{% raw %}'; -var styles = [ - {% endraw %}{% for stylesheet in stylesheets %}{% raw %}['{% endraw %}{{ stylesheet.name }}{% raw %}', '{% endraw %}{{ stylesheet.uri }}{% raw %}']{% endraw %}{% if not loop.last %}{% raw %}, - {% endraw %}{% endif %}{% endfor %}{% raw %} -]; var saved = {}; + +var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}'; +var styles = { + {% endraw %} + {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}', + {% endraw %}{% endfor %}{% raw %} +}; + +function changeStyle(styleName, link) { + localStorage.stylesheet = styleName; + + if (!document.getElementById('stylesheet')) { + var s = document.createElement('link'); + s.rel = 'stylesheet'; + s.type = 'text/css'; + s.id = 'stylesheet'; + var x = document.getElementsByTagName('head')[0]; + x.appendChild(s); + } + + document.getElementById('stylesheet').href = styles[styleName]; + selectedstyle = styleName; + + if (document.getElementsByClassName('styles').length != 0) { + var styleLinks = document.getElementsByClassName('styles')[0].childNodes; + for (i = 0; i < styleLinks.length; i++) { + styleLinks[i].className = ''; + } + } + + if (link) { + link.className = 'selected'; + } +} + +if (localStorage.stylesheet) { + for (styleName in styles) { + if (styleName == localStorage.stylesheet) { + changeStyle(styleName); + break; + } + } +} + +function init_stylechooser() { + var newElement = document.createElement('div'); + newElement.className = 'styles'; + + for (styleName in styles) { + var style = document.createElement('a'); + style.innerHTML = '[' + styleName + ']'; + style.onclick = function() { + changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this); + }; + if (styleName == selectedstyle) { + style.className = 'selected'; + } + style.href = 'javascript:void(0);'; + newElement.appendChild(style); + } + + document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling); +} + function get_cookie(cookie_name) { var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)'); if (results) @@ -16,7 +75,7 @@ function get_cookie(cookie_name) { } function highlightReply(id) { - if(typeof window.event != "undefined" && event.which == 2) { + if (typeof window.event != "undefined" && event.which == 2) { // don't highlight on middle click return true; } @@ -57,6 +116,7 @@ function dopost(form) { return form.elements['body'].value != "" || form.elements['file'].value != ""; } + function citeReply(id) { var body = document.getElementById('body'); @@ -76,21 +136,6 @@ function citeReply(id) { } } -function changeStyle(x) { - localStorage.stylesheet = styles[x][1]; - document.getElementById('stylesheet').href = styles[x][1]; - selectedstyle = styles[x][0]; -} - -if(localStorage.stylesheet) { - for(var x = 0; x < styles.length ; x++) { - if(styles[x][1] == localStorage.stylesheet) { - changeStyle(x); - break; - } - } -} - function rememberStuff() { if (document.forms.post) { if (document.forms.post.password) { @@ -112,7 +157,7 @@ function rememberStuff() { if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) { // Remove successful posts var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')); - for(var url in successful) { + for (var url in successful) { saved[url] = null; } sessionStorage.body = JSON.stringify(saved); @@ -132,25 +177,13 @@ function rememberStuff() { } function init() { - var newElement = document.createElement('div'); - newElement.className = 'styles'; + init_stylechooser(); - for(x = 0; x < styles.length; x++) { - var style = document.createElement('a'); - style.innerHTML = '[' + styles[x][0] + ']'; - style.href = 'javascript:changeStyle(' + x + ');'; - if(selectedstyle == styles[x][0]) - style.className = 'selected'; - newElement.appendChild(style); - } - - document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling) - - if(document.forms.postcontrols) { + if (document.forms.postcontrols) { document.forms.postcontrols.password.value = localStorage.password; } - if(window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1)) + if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1)) highlightReply(window.location.hash.substring(1)); } @@ -164,7 +197,7 @@ function onready(fnc) { } function ready() { - for(var i = 0; i < onready_callbacks.length; i++) { + for (var i = 0; i < onready_callbacks.length; i++) { onready_callbacks[i](); } } @@ -174,3 +207,4 @@ onready(init); {% endraw %}{% if config.google_analytics %}{% raw %} var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %} + diff --git a/templates/page.html b/templates/page.html index a5dc3dc0..0f59e6b1 100644 --- a/templates/page.html +++ b/templates/page.html @@ -10,7 +10,7 @@ {% if not nojavascript %}{% endif %} - {% if pm %}
    You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

    {% endif %} + {% if pm %}
    You have an unread PM{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.

    {% endif %}

    {{ title }}

    @@ -21,7 +21,7 @@
    {{ body }} -
    +

    Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2012 Tinyboard Development Group

    -- cgit v1.3 From bdb2f57ce860234ff6c7572654d2774a2e102cf6 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 6 May 2012 12:29:54 +1000 Subject: small bug fixes --- mod.php | 2 +- templates/mod/users.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/mod.php b/mod.php index f1d47e8d..96fd64e8 100644 --- a/mod.php +++ b/mod.php @@ -79,7 +79,7 @@ $pages = array( if (!$mod) { $pages = array('//' => 'login'); } elseif (isset($_GET['status'], $_GET['r'])) { - header('Location: ' . $_GET['r'], true, (int)$_GET['stats']); + header('Location: ' . $_GET['r'], true, (int)$_GET['status']); } elseif (isset($config['mod']['custom_pages'])) { $pages = array_merge($pages, $config['mod']['custom_pages']); } diff --git a/templates/mod/users.html b/templates/mod/users.html index a0d216d3..761d3ddd 100644 --- a/templates/mod/users.html +++ b/templates/mod/users.html @@ -52,7 +52,7 @@ {% if mod|hasPermission(config.mod.promoteusers) and user.type > constant('JANITOR') %} ▼ {% endif %} - {% if mod|hasPermission(config.editusers) or (mod|hasPermission(config.change_password) and mod.id == user.id) %} + {% if mod|hasPermission(config.mod.editusers) or (mod|hasPermission(config.mod.change_password) and mod.id == user.id) %} [{% trans 'edit' %}] {% endif %} {% if mod|hasPermission(config.mod.create_pm) %} -- cgit v1.3 From c2f790ee860eb88f8a3a5f19e9f7412a95e6aa1c Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 6 May 2012 12:31:15 +1000 Subject: Don't show "Last action" in ?/users if you don't have permission --- templates/mod/users.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'templates') diff --git a/templates/mod/users.html b/templates/mod/users.html index 761d3ddd..6ea6248f 100644 --- a/templates/mod/users.html +++ b/templates/mod/users.html @@ -4,7 +4,9 @@
    {% trans 'Username' %} {% trans 'Type' %} {% trans 'Boards' %}{% trans 'Last action' %}{% trans 'Last action' %}…
    - {% if mod|hasPermission(config.mod.modlog) %} + {% if mod|hasPermission(config.mod.modlog) %} + {% if user.last %} {{ user.last|ago }} {% else %} {% trans 'never' %} {% endif %} - {% else %} - – - {% endif %} - {% if mod|hasPermission(config.mod.promoteusers) and user.type < constant('ADMIN') %} ▲ -- cgit v1.3 From e132e4c2b3dc62c2ddb6bdbcc562e67fa61c9fa8 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 7 May 2012 14:08:40 +1000 Subject: a few permissions-related bugs --- inc/mod/pages.php | 12 ++++++++++++ templates/mod/pm.html | 15 +++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index c56570a5..11e89b9a 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -969,6 +969,11 @@ function mod_user($uid) { } function mod_user_new() { + global $pdo; + + if (!hasPermission($config['mod']['createusers'])) + error($config['error']['noaccess']); + if (isset($_POST['username'], $_POST['password'], $_POST['type'])) { if ($_POST['username'] == '') error(sprintf($config['error']['required'], 'username')); @@ -1001,6 +1006,10 @@ function mod_user_new() { $query->bindValue(':boards', implode(',', $boards)); $query->execute() or error(db_error($query)); + $uid = $pdo->lastInsertId(); + + modLog('Created a new user: ' . utf8tohtml($_POST['username']) . ' (#' . $userID . ')'); + header('Location: ?/users', true, $config['redirect_http']); return; } @@ -1040,6 +1049,9 @@ function mod_user_promote($uid, $action) { function mod_pm($id, $reply = false) { global $mod, $config; + if ($reply && !hasPermission($config['mod']['create_pm'])) + error($config['error']['noaccess']); + $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)); diff --git a/templates/mod/pm.html b/templates/mod/pm.html index c66dc883..c62cae58 100644 --- a/templates/mod/pm.html +++ b/templates/mod/pm.html @@ -20,7 +20,8 @@ {% endif %}
    {% trans 'Date' %}{{ time|date(config.post_date) }}{{ time|date(config.post_date) }} ({{ time|ago }} ago)
    {% trans 'Message' %}
    + + + + + + + + + + + + +
    + {% trans 'Thread ID' %} + + >>>{{ config.board_abbreviation|sprintf(board) }}{{ post }} +
    + {% trans 'Leave shadow thread' %} + + + ({% trans 'locks thread; replies to it with a link.' %}) +
    {% trans 'Target board' %} +
      + {% for targetboard in boards if targetboard.uri != board %} +
    • + + +
    • + {% endfor %} +
    +
    + +
      +
    • +
    + + -- cgit v1.3 From 1dedf5deaed5099affbc3785536ddd4efa534fcb Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 19 May 2012 21:00:15 +1000 Subject: ban list formatting changes --- templates/mod/ban_list.html | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'templates') diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index 4a27b8f7..e46d816d 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -4,10 +4,11 @@
    - + + @@ -37,14 +38,22 @@ + -- cgit v1.3 From f0abd961a4221bebfa4f71a2ad44c77d239e5581 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 19 May 2012 21:02:51 +1000 Subject: slightly more compact ban list --- templates/mod/ban_list.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index e46d816d..88b8b7ee 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -37,8 +37,9 @@ {% endif %}
    {% trans 'IP address' %}{% trans 'IP address/mask' %} {% trans 'Reason' %} {% trans 'Board' %} {% trans 'Set' %}{% trans 'Duration' %} {% trans 'Expires' %} {% trans 'Staff' %}
    {{ ban.set|date(config.post_date) }} + ({{ ban.set|ago }} ago) + + {% if ban.expires == 0 %} + - + {% else %} + {{ (ban.expires - ban.set + time()) | until }} + {% endif %} {% if ban.expires == 0 %} {% trans 'never' %} {% else %} - {{ ban.expires|date(config.post_date) }} + {{ ban.expires|date(config.post_date) }} {% if ban.expires > time() %} - ({{ ban.expires|until }}) + ({{ ban.expires|until }}) {% endif %} {% endif %} - {{ ban.set|date(config.post_date) }} - ({{ ban.set|ago }} ago) + + {{ ban.set|ago }} ago + {% if ban.expires == 0 %} -- cgit v1.3 From 4d3184b762efdb78c4a51f93ae68914aaf453e22 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 19 May 2012 21:08:46 +1000 Subject: width: 100% for ban list --- templates/mod/ban_list.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index 88b8b7ee..2edb9cdf 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -2,7 +2,7 @@

    ({% trans 'There are no active bans.' %})

    {% else %} - +
    @@ -54,7 +54,7 @@ {% else %} {{ ban.expires|date(config.post_date) }} {% if ban.expires > time() %} - ({{ ban.expires|until }}) + (in {{ ban.expires|until }}) {% endif %} {% endif %} -- cgit v1.3 From d6a1f16555376fc4b57a572e21758a400db8852a Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sat, 19 May 2012 21:12:40 +1000 Subject: bugfix: noticeboard timestamps --- templates/mod/dashboard.html | 2 +- templates/mod/noticeboard.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'templates') diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 9e50e6ed..a10b0cf2 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -48,7 +48,7 @@ deleted? {% endif %} at - {{ notice.time|date(config.post_date) }} + {{ post.time|date(config.post_date) }} {% endfor %} diff --git a/templates/mod/noticeboard.html b/templates/mod/noticeboard.html index 4a0a068f..463b8430 100644 --- a/templates/mod/noticeboard.html +++ b/templates/mod/noticeboard.html @@ -47,7 +47,7 @@ {% trans 'deleted?' %} {% endif %} {% trans 'at' %} - {{ notice.time|date(config.post_date) }} + {{ post.time|date(config.post_date) }}

    -- cgit v1.3 From d3739c48c2c2deec83e6abf74ed8e03470581750 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Sun, 20 May 2012 20:20:50 +1000 Subject: Config editort --- inc/mod/pages.php | 85 ++++++++++++++++++++++++++++++++++++++++ inc/template.php | 2 +- mod.php | 2 + stylesheets/style.css | 22 +++++------ templates/mod/config-editor.html | 56 ++++++++++++++++++++++++++ templates/mod/view_ip.html | 8 ++-- 6 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 templates/mod/config-editor.html (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 6b644867..a4e2eae1 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1539,6 +1539,91 @@ function mod_report_dismiss($id, $all = false) { header('Location: ?/reports', true, $config['redirect_http']); } + +function mod_config() { + global $config, $mod; + + if (!hasPermission($config['mod']['edit_config'])) + error($config['error']['noaccess']); + + require_once 'inc/mod/config-editor.php'; + + $conf = config_vars(); + + foreach ($conf as &$var) { + if (is_array($var['name'])) { + $c = &$config; + foreach ($var['name'] as $n) + $c = &$c[$n]; + } else { + $c = $config[$var['name']]; + } + + $var['value'] = $c; + } + unset($var); + + if (isset($_POST['save'])) { + $config_append = ''; + + foreach ($conf as $var) { + $field_name = 'cf_' . (is_array($var['name']) ? implode('/', $var['name']) : $var['name']); + + if ($var['type'] == 'boolean') + $value = isset($_POST[$field_name]); + elseif (isset($_POST[$field_name])) + $value = $_POST[$field_name]; + else + continue; // ??? + + if (!settype($value, $var['type'])) + continue; // invalid + + if ($value != $var['value']) { + // This value has been changed. + + $config_append .= '$config'; + + if (is_array($var['name'])) { + foreach ($var['name'] as $name) + $config_append .= '[' . var_export($name, true) . ']'; + } else { + $config_append .= '[' . var_export($var['name'], true) . ']'; + } + + $config_append .= ' = ' . var_export($value, true) . ";\n"; + } + } + + if(!empty($config_append)) { + $config_append = "\n// Changes made via web editor by \"" . $mod['username'] . "\" @ " . date('r') . ":\n" . $config_append . "\n"; + + if(!@file_put_contents('inc/instance-config.php', $config_append, FILE_APPEND)) { + $config_append = htmlentities($config_append); + + if($config['minify_html']) + $config_append = str_replace("\n", ' ', $config_append); + $page = array(); + $page['title'] = 'Cannot write to file!'; + $page['config'] = $config; + $page['body'] = ' +

    Tinyboard could not write to inc/instance-config.php with the ammended configuration, probably due to a permissions error.

    +

    You may proceed with these changes manually by copying and pasting the following code to the end of inc/instance-config.php:

    + + '; + echo Element('page.html', $page); + exit; + } + } + + header('Location: ?/', true, $config['redirect_http']); + + exit; + } + + mod_page('Config editor', 'mod/config-editor.html', array('conf' => $conf)); +} + function mod_debug_antispam() { global $pdo, $config; diff --git a/inc/template.php b/inc/template.php index 5355e18c..351bde62 100644 --- a/inc/template.php +++ b/inc/template.php @@ -27,7 +27,7 @@ function load_twig() { $twig = new Twig_Environment($loader, array( 'autoescape' => false, 'cache' => "{$config['dir']['template']}/cache", - 'debug' => ($config['debug'] ? true : false), + 'debug' => $config['debug'] )); $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); $twig->addExtension(new Twig_Extensions_Extension_I18n()); diff --git a/mod.php b/mod.php index 23cacc11..5fa040ee 100644 --- a/mod.php +++ b/mod.php @@ -65,6 +65,8 @@ $pages = array( '/(\w+)/bump(un)?lock/(\d+)' => 'bumplock', // "bumplock" thread '/(\w+)/move/(\d+)' => 'move', // move thread + '/config' => 'config', // config editor + // these pages aren't listed in the dashboard without $config['debug'] '/debug/antispam' => 'debug_antispam', diff --git a/stylesheets/style.css b/stylesheets/style.css index 16da419c..1913f60a 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -388,19 +388,15 @@ div.blotter { font-weight: bold; text-align: center; } - -/* Uboachan stuff */ -div.styles-sidebar { - text-align: center; - padding-bottom: 0px; -} -div.styles-sidebar a { - margin: 0 5px; +table.mod.config-editor { + font-size: 9pt; + width: 100%; } -div.styles-sidebar a.selected { - text-decoration: none; +table.mod.config-editor td { + text-align: left; + padding: 5px; + border-bottom: 1px solid #98e; } -.category { - background: #98E; - color: black; +table.mod.config-editor input[type="text"] { + width: 98%; } diff --git a/templates/mod/config-editor.html b/templates/mod/config-editor.html new file mode 100644 index 00000000..ec7213bb --- /dev/null +++ b/templates/mod/config-editor.html @@ -0,0 +1,56 @@ + +
    {% trans 'IP address/mask' %} {% trans 'Reason' %}
    + + + + + + + {% for var in conf if var.type != 'array' %} + {% if var.name|count == 1 %} + {% set name = 'cf_' ~ var.name %} + {% else %} + {% set name = 'cf_' ~ var.name|join('/') %} + {% endif %} + + + + + + + + + + + {% endfor %} +
    NameValueTypeDescription
    + {% if var.name|count == 1 %} + {{ var.name }} + {% else %} + {{ var.name|join(' → ') }} + {% endif %} + + {% if var.type == 'string' %} + + {% elseif var.type == 'integer' %} + + {% elseif var.type == 'boolean' %} + + {% else %} + ? + {% endif %} + + {% if var.type == 'integer' or var.type == 'boolean' %} + Default: {{ var.default }} + {% endif %} + + {{ var.type|e }} + + {{ var.comment|join('
    ') }} +
    + +
      +
    • +
    + + diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index e69301fd..c49880ae 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -1,9 +1,11 @@ {% for board_posts in posts %}
    - {{ config.board_abbreviation|sprintf(board_posts.board.uri) }} - - - {{ board_posts.board.title|e }} + + {{ config.board_abbreviation|sprintf(board_posts.board.uri) }} + - + {{ board_posts.board.title|e }} + {{ board_posts.posts|join('
    ') }}
    -- cgit v1.3 From e4b6c89375d60424e1e029cb3d10c8ec2be49620 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 25 May 2012 21:40:01 +1000 Subject: show number of reports from dashboard; translatable mod panel --- inc/mod/pages.php | 57 ++++++++++++++++++++++++-------------------- templates/mod/dashboard.html | 6 ++++- 2 files changed, 36 insertions(+), 27 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 7278afa3..878df92d 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -56,11 +56,11 @@ function mod_login() { if (isset($_POST['username'])) $args['username'] = $_POST['username']; - mod_page('Login', 'mod/login.html', $args); + mod_page(_('Login'), 'mod/login.html', $args); } function mod_confirm($request) { - mod_page('Confirm action', 'mod/confirm.html', array('request' => $request)); + mod_page(_('Confirm action'), 'mod/confirm.html', array('request' => $request)); } function mod_logout() { @@ -98,6 +98,9 @@ function mod_dashboard() { cache::set('pm_unreadcount_' . $mod['id'], $args['unread_pms']); } + $query = query('SELECT COUNT(*) FROM `reports`') or error(db_error($query)); + $args['reports'] = $query->fetchColumn(0); + if ($mod['type'] >= ADMIN && $config['check_updates']) { if (!$config['version']) error(_('Could not find current version! (Check .installed)')); @@ -141,7 +144,7 @@ function mod_dashboard() { $args['newer_release'] = $latest; } - mod_page('Dashboard', 'mod/dashboard.html', $args); + mod_page(_('Dashboard'), 'mod/dashboard.html', $args); } function mod_edit_board($boardName) { @@ -216,7 +219,7 @@ function mod_edit_board($boardName) { header('Location: ?/', true, $config['redirect_http']); } else { - mod_page('Edit board: ' . sprintf($config['board_abbreviation'], $board['uri']), 'mod/board.html', array('board' => $board)); + mod_page(sprintf('%s: ' . $config['board_abbreviation'], _('Edit board'), $board['uri']), 'mod/board.html', array('board' => $board)); } } @@ -264,7 +267,7 @@ function mod_new_board() { header('Location: ?/' . $board['uri'] . '/' . $config['file_index'], true, $config['redirect_http']); } - mod_page('New board', 'mod/board.html', array('new' => true)); + mod_page(_('New board'), 'mod/board.html', array('new' => true)); } function mod_noticeboard($page_no = 1) { @@ -310,7 +313,7 @@ function mod_noticeboard($page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(0); - mod_page('Noticeboard', 'mod/noticeboard.html', array('noticeboard' => $noticeboard, 'count' => $count)); + mod_page(_('Noticeboard'), 'mod/noticeboard.html', array('noticeboard' => $noticeboard, 'count' => $count)); } function mod_noticeboard_delete($id) { @@ -367,7 +370,7 @@ function mod_news($page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(0); - mod_page('News', 'mod/news.html', array('news' => $news, 'count' => $count)); + mod_page(_('News'), 'mod/news.html', array('news' => $news, 'count' => $count)); } function mod_news_delete($id) { @@ -407,7 +410,7 @@ function mod_log($page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(0); - mod_page('Moderation log', 'mod/log.html', array('logs' => $logs, 'count' => $count)); + mod_page(_('Moderation log'), 'mod/log.html', array('logs' => $logs, 'count' => $count)); } function mod_view_board($boardName, $page_no = 1) { @@ -550,7 +553,7 @@ function mod_page_ip($ip) { $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); } - mod_page("IP: $ip", 'mod/view_ip.html', $args, $args['hostname']); + mod_page(sprintf('%s: %s', _('IP'), $ip), 'mod/view_ip.html', $args, $args['hostname']); } function mod_ban() { @@ -560,7 +563,7 @@ function mod_ban() { error($config['error']['noaccess']); if (!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) { - mod_page("New ban", 'mod/ban_form.html', array()); + mod_page(_('New ban'), 'mod/ban_form.html', array()); return; } @@ -628,7 +631,7 @@ function mod_bans($page_no = 1) { $ban['real_ip'] = true; } - mod_page('Ban list', 'mod/ban_list.html', array('bans' => $bans, 'count' => $count)); + mod_page(_('Ban list'), 'mod/ban_list.html', array('bans' => $bans, 'count' => $count)); } @@ -880,7 +883,7 @@ function mod_move($originBoard, $postID) { if (count($boards) <= 1) error(_('Impossible to move thread; there is only one board.')); - mod_page("Move thread", 'mod/move.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards)); + mod_page(_('Move thread'), 'mod/move.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards)); } function mod_ban_post($board, $delete, $post) { @@ -939,7 +942,7 @@ function mod_ban_post($board, $delete, $post) { 'boards' => listBoards() ); - mod_page("New ban", 'mod/ban_form.html', $args); + mod_page(_('New ban'), 'mod/ban_form.html', $args); } function mod_delete($board, $post) { @@ -1155,7 +1158,7 @@ function mod_user($uid) { $user['boards'] = explode(',', $user['boards']); - mod_page('Edit user', 'mod/user.html', array('user' => $user, 'logs' => $log, 'boards' => listBoards())); + mod_page(_('Edit user'), 'mod/user.html', array('user' => $user, 'logs' => $log, 'boards' => listBoards())); } function mod_user_new() { @@ -1204,7 +1207,7 @@ function mod_user_new() { return; } - mod_page('Edit user', 'mod/user.html', array('new' => true, 'boards' => listBoards())); + mod_page(_('Edit user'), 'mod/user.html', array('new' => true, 'boards' => listBoards())); } @@ -1218,7 +1221,7 @@ function mod_users() { $query = query("SELECT *, (SELECT `time` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM `mods` ORDER BY `type` DESC,`id`") or error(db_error()); $args['users'] = $query->fetchAll(PDO::FETCH_ASSOC); - mod_page('Manage users', 'mod/users.html', $args); + mod_page(_('Manage users'), 'mod/users.html', $args); } function mod_user_promote($uid, $action) { @@ -1280,11 +1283,11 @@ function mod_pm($id, $reply = false) { if (!$pm['to_username']) error($config['error']['404']); // deleted? - mod_page("New PM for {$pm['to_username']}", 'mod/new_pm.html', array( + mod_page(sprintf('%s %s', _('New PM for'), $pm['to_username']), 'mod/new_pm.html', array( 'username' => $pm['username'], 'id' => $pm['sender'], 'message' => quote($pm['message']) )); } else { - mod_page("Private message – #$id", 'mod/pm.html', $pm); + mod_page(sprintf('%s – #%d', _('Private message'), $id), 'mod/pm.html', $pm); } } @@ -1305,7 +1308,7 @@ function mod_inbox() { $message['snippet'] = pm_snippet($message['message']); } - mod_page('PM inbox (' . (count($messages) > 0 ? $unread . ' unread' : 'empty') . ')', 'mod/inbox.html', array( + mod_page(sprintf('%s (%s)', _('PM inbox'), count($messages) > 0 ? $unread . ' unread' : 'empty'), 'mod/inbox.html', array( 'messages' => $messages, 'unread' => $unread )); @@ -1352,7 +1355,7 @@ function mod_new_pm($username) { header('Location: ?/', true, $config['redirect_http']); } - mod_page("New PM for {$username}", 'mod/new_pm.html', array('username' => $username, 'id' => $id)); + mod_page(sprintf('%s %s', _('New PM for'), $username), 'mod/new_pm.html', array('username' => $username, 'id' => $id)); } function mod_rebuild() { @@ -1414,11 +1417,11 @@ function mod_rebuild() { } } - mod_page("Rebuild", 'mod/rebuilt.html', array('logs' => $log)); + mod_page(_('Rebuild'), 'mod/rebuilt.html', array('logs' => $log)); return; } - mod_page("Rebuild", 'mod/rebuild.html', array('boards' => listBoards())); + mod_page(_('Rebuild'), 'mod/rebuild.html', array('boards' => listBoards())); } function mod_reports() { @@ -1449,6 +1452,7 @@ function mod_reports() { } } + $count = 0; $body = ''; foreach ($reports as $report) { if (!isset($report_posts[$report['board']][$report['post']])) { @@ -1499,9 +1503,11 @@ function mod_reports() { if (isset($__old_body_truncate_char)) $config['body_truncate_char'] = $__old_body_truncate_char; + + $count++; } - mod_page("Report queue", 'mod/reports.html', array('reports' => $body)); + mod_page(sprintf('%s (%d)', _('Report queue'), $count), 'mod/reports.html', array('reports' => $body, 'count' => $count)); } function mod_report_dismiss($id, $all = false) { @@ -1623,7 +1629,7 @@ function mod_config() { exit; } - mod_page('Config editor', 'mod/config-editor.html', array('conf' => $conf)); + mod_page(_('Config editor'), 'mod/config-editor.html', array('conf' => $conf)); } function mod_debug_antispam() { @@ -1657,7 +1663,6 @@ function mod_debug_antispam() { $query = query('SELECT * FROM `antispam` ' . ($where ? "WHERE $where" : '') . ' ORDER BY `passed` DESC LIMIT 40') or error(db_error()); $args['top'] = $query->fetchAll(PDO::FETCH_ASSOC); - mod_page("Debug: Anti-spam", 'mod/debug/antispam.html', $args); + mod_page(_('Debug: Anti-spam'), 'mod/debug/antispam.html', $args); } - diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index a10b0cf2..1c70bf06 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -74,7 +74,11 @@
      {% if mod|hasPermission(config.mod.reports) %} -
    • {% trans 'Report queue' %}
    • +
    • + {% if reports > 0 %}{% endif %} + {% trans 'Report queue' %} ({{ reports }}) + {% if reports > 0 %}{% endif %} +
    • {% endif %} {% if mod|hasPermission(config.mod.view_banlist) %} -- cgit v1.3 From 8d96bfc3e90dd5293f3b39beac975850822f8a4b Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 28 May 2012 17:08:29 +1000 Subject: minor change --- inc/mod/pages.php | 7 ++++--- templates/mod/dashboard.html | 6 ++---- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 878df92d..72c8c195 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -978,6 +978,8 @@ function mod_deletefile($board, $post) { deleteFile($post); // Record the action modLog("Deleted file from post #{$post}"); + // Rebuild thread + buildThread($post); // Rebuild board buildIndex(); @@ -1217,11 +1219,10 @@ function mod_users() { if (!hasPermission($config['mod']['manageusers'])) error($config['error']['noaccess']); - $args = array(); $query = query("SELECT *, (SELECT `time` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `last`, (SELECT `text` FROM `modlogs` WHERE `mod` = `id` ORDER BY `time` DESC LIMIT 1) AS `action` FROM `mods` ORDER BY `type` DESC,`id`") or error(db_error()); - $args['users'] = $query->fetchAll(PDO::FETCH_ASSOC); + $users = $query->fetchAll(PDO::FETCH_ASSOC); - mod_page(_('Manage users'), 'mod/users.html', $args); + mod_page(sprintf('%s (%d)', _('Manage users'), count($users)), 'mod/users.html', array('users' => $users)); } function mod_user_promote($uid, $action) { diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 1c70bf06..47a25390 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -60,10 +60,8 @@
    • {% trans 'News' %}
    • - {% trans 'PM inbox' %} - {% if unread_pms > 0 %} - ({{ unread_pms }} unread) - {% endif %} + {% trans 'PM inbox' %} + {% if unread_pms > 0 %}{%endif %}({{ unread_pms }} unread){% if unread_pms > 0 %}{%endif %}
    -- cgit v1.3 From c5ec20684e77456fe9377a8cbf62c78cfb580b64 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 13 Aug 2012 00:18:13 +1000 Subject: themes --- inc/mod/pages.php | 127 +++++++++++++++++++++++++++++++++++++ mod.php | 5 ++ templates/mod/dashboard.html | 18 ++---- templates/mod/theme_config.html | 27 ++++++++ templates/mod/theme_installed.html | 9 +++ templates/mod/theme_rebuilt.html | 2 + templates/mod/themes.html | 40 ++++++++++++ 7 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 templates/mod/theme_config.html create mode 100644 templates/mod/theme_installed.html create mode 100644 templates/mod/theme_rebuilt.html create mode 100644 templates/mod/themes.html (limited to 'templates') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 72c8c195..ad69ae39 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1667,3 +1667,130 @@ function mod_debug_antispam() { mod_page(_('Debug: Anti-spam'), 'mod/debug/antispam.html', $args); } +function mod_themes_list() { + global $config; + + if (!hasPermission($config['mod']['themes'])) + error($config['error']['noaccess']); + + if(!is_dir($config['dir']['themes'])) + error(_('Themes directory doesn\'t exist!')); + if(!$dir = opendir($config['dir']['themes'])) + error(_('Cannot open themes directory; check permissions.')); + + $query = query('SELECT `theme` FROM `theme_settings` WHERE `name` IS NULL AND `value` IS NULL') or error(db_error()); + $themes_in_use = $query->fetchAll(PDO::FETCH_COLUMN); + + // Scan directory for themes + $themes = array(); + while ($file = readdir($dir)) { + if ($file[0] != '.' && is_dir($config['dir']['themes'] . '/' . $file)) { + $themes[$file] = loadThemeConfig($file); + } + } + closedir($dir); + + mod_page(_('Manage themes'), 'mod/themes.html', array( + 'themes' => $themes, + 'themes_in_use' => $themes_in_use, + )); +} + +function mod_theme_configure($theme_name) { + global $config; + + if (!hasPermission($config['mod']['themes'])) + error($config['error']['noaccess']); + + if(!$theme = loadThemeConfig($theme_name)) { + error($config['error']['invalidtheme']); + } + + if(isset($_POST['install'])) { + // Check if everything is submitted + foreach($theme['config'] as &$conf) { + if(!isset($_POST[$conf['name']]) && $conf['type'] != 'checkbox') + error(sprintf($config['error']['required'], $c['title'])); + } + + // Clear previous settings + $query = prepare("DELETE FROM `theme_settings` WHERE `theme` = :theme"); + $query->bindValue(':theme', $theme_name); + $query->execute() or error(db_error($query)); + + foreach($theme['config'] as &$conf) { + $query = prepare("INSERT INTO `theme_settings` VALUES(:theme, :name, :value)"); + $query->bindValue(':theme', $theme_name); + $query->bindValue(':name', $conf['name']); + $query->bindValue(':value', $_POST[$conf['name']]); + $query->execute() or error(db_error($query)); + } + + $query = prepare("INSERT INTO `theme_settings` VALUES(:theme, NULL, NULL)"); + $query->bindValue(':theme', $theme_name); + $query->execute() or error(db_error($query)); + + $result = true; + $message = false; + if(isset($theme['install_callback'])) { + $ret = $theme['install_callback'](themeSettings($theme_name)); + if($ret && !empty($ret)) { + if(is_array($ret) && count($ret) == 2) { + $result = $ret[0]; + $message = $ret[1]; + } + } + } + + if(!$result) { + // Install failed + $query = prepare("DELETE FROM `theme_settings` WHERE `theme` = :theme"); + $query->bindValue(':theme', $theme_name); + $query->execute() or error(db_error($query)); + } + + // Build themes + rebuildThemes('all'); + + mod_page(sprintf(_($result ? 'Installed theme: %s' : 'Installation failed: %s'), $theme['name']), 'mod/theme_installed.html', array( + 'theme_name' => $theme_name, + 'theme' => $theme, + 'result' => $result, + 'message' => $message, + )); + } + + $settings = themeSettings($theme_name); + + mod_page(sprintf(_('Configuring theme: %s'), $theme['name']), 'mod/theme_config.html', array( + 'theme_name' => $theme_name, + 'theme' => $theme, + 'settings' => $settings, + )); +} + +function mod_theme_uninstall($theme_name) { + global $config; + + if (!hasPermission($config['mod']['themes'])) + error($config['error']['noaccess']); + + $query = prepare("DELETE FROM `theme_settings` WHERE `theme` = :theme"); + $query->bindValue(':theme', $theme_name); + $query->execute() or error(db_error($query)); + + header('Location: ?/themes', true, $config['redirect_http']); +} + +function mod_theme_rebuild($theme_name) { + global $config; + + if (!hasPermission($config['mod']['themes'])) + error($config['error']['noaccess']); + + rebuildTheme($theme_name, 'all'); + + mod_page(sprintf(_('Rebuilt theme: %s'), $theme_name), 'mod/theme_rebuilt.html', array( + 'theme_name' => $theme_name, + )); +} diff --git a/mod.php b/mod.php index 5fa040ee..52f340d2 100644 --- a/mod.php +++ b/mod.php @@ -65,6 +65,11 @@ $pages = array( '/(\w+)/bump(un)?lock/(\d+)' => 'bumplock', // "bumplock" thread '/(\w+)/move/(\d+)' => 'move', // move thread + '/themes' => 'themes_list', // manage themes + '/themes/(\w+)' => 'theme_configure', // configure/reconfigure theme + '/themes/(\w+)/rebuild' => 'theme_rebuild', // rebuild theme + '/themes/(\w+)/uninstall' => 'theme_uninstall', // uninstall theme + '/config' => 'config', // config editor // these pages aren't listed in the dashboard without $config['debug'] diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 47a25390..30742dc1 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -10,7 +10,6 @@ {% if board.subtitle %} — {{ board.subtitle|e }} {% endif %} - {% if mod|hasPermission(config.mod.manageboards) %} [{% trans 'edit' %}] {% endif %} @@ -78,39 +77,30 @@ {% if reports > 0 %}{% endif %} {% endif %} - {% if mod|hasPermission(config.mod.view_banlist) %}
  • {% trans 'Ban list' %}
  • {% endif %} - {% if mod|hasPermission(config.mod.manageusers) %}
  • {% trans 'Manage users' %}
  • {% elseif mod|hasPermission(config.mod.change_password) %}
  • {% trans 'Change password' %}
  • {% endif %} - + {% if mod|hasPermission(config.mod.themes) %} +
  • {% trans 'Manage themes' %}
  • + {% endif %} {% if mod|hasPermission(config.mod.modlog) %}
  • {% trans 'Moderation log' %}
  • {% endif %} - {% if mod|hasPermission(config.mod.rebuild) %}
  • {% trans 'Rebuild' %}
  • {% endif %} - {% if mod|hasPermission(config.mod.show_config) %}
  • {% trans 'Configuration' %}
  • {% endif %} + -{% if mod|hasPermission(config.mod.themes) %} -
    - {% trans 'Themes' %} - - {# TODO #} -
    -{% endif %} -
    {% trans 'Search' %} diff --git a/templates/mod/theme_config.html b/templates/mod/theme_config.html new file mode 100644 index 00000000..2dbb8397 --- /dev/null +++ b/templates/mod/theme_config.html @@ -0,0 +1,27 @@ +
    + {% if not config %} +

    (No configuration required.)

    + {% else %} + + {% for conf in theme.config %} + + + + + {% endfor %} +
    {{ conf.title }} + + {% if conf.comment %} + {{ conf.comment }} + {% endif %} +
    + {% endif %} +

    + +

    +
    diff --git a/templates/mod/theme_installed.html b/templates/mod/theme_installed.html new file mode 100644 index 00000000..e6beec10 --- /dev/null +++ b/templates/mod/theme_installed.html @@ -0,0 +1,9 @@ +{% if message %} +
    {{ message }}
    +{% endif %} + +{% if result %} +

    {% trans 'Successfully installed and built theme.' %}

    +{% endif %} + +

    {% trans 'Go back to themes' %}.

    diff --git a/templates/mod/theme_rebuilt.html b/templates/mod/theme_rebuilt.html new file mode 100644 index 00000000..b366e7a6 --- /dev/null +++ b/templates/mod/theme_rebuilt.html @@ -0,0 +1,2 @@ +

    {{ 'Successfully rebuilt the %s theme.'|trans|sprintf(theme_name) }}

    +

    {% trans 'Go back to themes' %}.

    diff --git a/templates/mod/themes.html b/templates/mod/themes.html new file mode 100644 index 00000000..b596826d --- /dev/null +++ b/templates/mod/themes.html @@ -0,0 +1,40 @@ +{% if themes|count == 0 %} +

    ({% trans 'There are no themes available.' %})

    +{% else %} + + {% for theme_name, theme in themes %} + + + + + + + + + + + + + + + + + + + + + + + {% endfor %} +
    {% trans 'Name' %}{{ theme.name }}
    {% trans 'Version' %}{{ theme.version }}
    {% trans 'Description' %}{{ theme.description }}
    {% trans 'Thumbnail' %} + +
    {% trans 'Actions' %}

    +{% endif %} -- cgit v1.3