From 53f710060d1437f89291f26b10397a9c6c8bf4d2 Mon Sep 17 00:00:00 2001 From: Fredrick Date: Sun, 17 Mar 2013 07:00:55 -0400 Subject: Fix truncation issue by no longer using HTML entities for Unicode characters --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index 16b16901..cd079141 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1494,7 +1494,7 @@ function markup(&$body, $track_cites = false) { } function utf8tohtml($utf8) { - return mb_encode_numericentity(htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'), array(0x80, 0xffff, 0, 0xffff), 'UTF-8'); + return htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'); } function buildThread($id, $return=false, $mod=false) { -- cgit v1.3 From 6fd6b92fe828824dee408614805b35fe29177cd2 Mon Sep 17 00:00:00 2001 From: Macil Tech Date: Fri, 1 Mar 2013 07:12:17 +0800 Subject: Fix openBoard and boardTitle functions using same caching keys. Added getBoardInfo function that's used by both of the above functions, and can get a board's info without loading it. --- inc/functions.php | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index 16b16901..872c6c23 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -328,11 +328,19 @@ function setupBoard($array) { } function openBoard($uri) { + $board = getBoardInfo($uri); + if ($board) { + setupBoard($board); + return true; + } + return false; +} + +function getBoardInfo($uri) { global $config; if ($config['cache']['enabled'] && ($board = cache::get('board_' . $uri))) { - setupBoard($board); - return true; + return $board; } $query = prepare("SELECT * FROM `boards` WHERE `uri` = :uri LIMIT 1"); @@ -342,27 +350,16 @@ function openBoard($uri) { if ($board = $query->fetch()) { if ($config['cache']['enabled']) cache::set('board_' . $uri, $board); - setupBoard($board); - return true; + return $board; } return false; } function boardTitle($uri) { - global $config; - if ($config['cache']['enabled'] && ($board = cache::get('board_' . $uri))) { + $board = getBoardInfo($uri); + if ($board) return $board['title']; - } - - $query = prepare("SELECT `title` FROM `boards` WHERE `uri` = :uri LIMIT 1"); - $query->bindValue(':uri', $uri); - $query->execute() or error(db_error($query)); - - if ($title = $query->fetch()) { - return $title['title']; - } - return false; } -- cgit v1.3 From b078222ede702b8ecf4b28f5ebd6db5c34b65143 Mon Sep 17 00:00:00 2001 From: Macil Tech Date: Sat, 8 Jun 2013 05:55:13 -0500 Subject: Fix "Undefined index: sticky" and "locked" errors on new thread creation. --- inc/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index 872c6c23..b83d6c86 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -722,13 +722,13 @@ function post(array $post) { $query->bindValue(':password', $post['password']); $query->bindValue(':ip', isset($post['ip']) ? $post['ip'] : $_SERVER['REMOTE_ADDR']); - if ($post['op'] && $post['mod'] && $post['sticky']) { + if ($post['op'] && $post['mod'] && isset($post['sticky']) && $post['sticky']) { $query->bindValue(':sticky', 1, PDO::PARAM_INT); } else { $query->bindValue(':sticky', 0, PDO::PARAM_INT); } - if ($post['op'] && $post['mod'] && $post['locked']) { + if ($post['op'] && $post['mod'] && isset($post['locked']) && $post['locked']) { $query->bindValue(':locked', 1, PDO::PARAM_INT); } else { $query->bindValue(':locked', 0, PDO::PARAM_INT); -- cgit v1.3 From 765e64ee38919c48f840403c4910a37fbce037e9 Mon Sep 17 00:00:00 2001 From: Macil Tech Date: Wed, 13 Feb 2013 01:25:56 +0800 Subject: m and n dash fix --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index b83d6c86..a9afb450 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1362,8 +1362,8 @@ function unicodify($body) { // En and em- dashes are rendered exactly the same in // most monospace fonts (they look the same in code // editors). - $body = str_replace('--', '–', $body); // en dash $body = str_replace('---', '—', $body); // em dash + $body = str_replace('--', '–', $body); // en dash return $body; } -- cgit v1.3 From 3eda5b054361f7312b40a14728b76841c01628d2 Mon Sep 17 00:00:00 2001 From: Macil Tech Date: Tue, 18 Jun 2013 12:21:41 -0500 Subject: Adds image_hard_limit and reply_hard_limit options. Also reworks the numPosts() function and uses it elsewhere too. --- inc/config.php | 7 +++++++ inc/functions.php | 19 ++++++++++--------- post.php | 20 ++++++++++++++------ 3 files changed, 31 insertions(+), 15 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/config.php b/inc/config.php index cedf3e06..93a2fde2 100644 --- a/inc/config.php +++ b/inc/config.php @@ -311,6 +311,11 @@ // Reply limit (stops bumping thread when this is reached) $config['reply_limit'] = 250; + // Image hard limit (stops allowing new image replies when this is reached if not zero) + $config['image_hard_limit'] = 0; + // Reply hard limit (stops allowing new replies when this is reached if not zero) + $config['reply_hard_limit'] = 0; + // Strip repeating characters when making hashes $config['robot_enable'] = false; $config['robot_strip_repeating'] = true; @@ -659,6 +664,8 @@ $config['error']['noboard'] = _('Invalid board!'); $config['error']['nonexistant'] = _('Thread specified does not exist.'); $config['error']['locked'] = _('Thread locked. You may not reply at this time.'); + $config['error']['reply_hard_limit'] = _('Thread has reached its maximum reply limit.'); + $config['error']['image_hard_limit'] = _('Thread has reached its maximum image limit.'); $config['error']['nopost'] = _('You didn\'t make a post.'); $config['error']['flood'] = _('Flood detected; Post discarded.'); $config['error']['spam'] = _('Your request looks automated; Post discarded.'); diff --git a/inc/functions.php b/inc/functions.php index 16b16901..b8dab90b 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -986,12 +986,8 @@ function index($page, $mod=false) { $replies = array_reverse($posts->fetchAll(PDO::FETCH_ASSOC)); if (count($replies) == ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) { - $count = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri'])); - $count->bindValue(':thread', $th['id'], PDO::PARAM_INT); - $count->execute() or error(db_error($count)); - $count = $count->fetchAll(PDO::FETCH_COLUMN); - - $omitted = array('post_count' => $count[0], 'image_count' => $count[1]); + $count = numPosts($th['id']); + $omitted = array('post_count' => $count['replies'], 'image_count' => $count['images']); } else { $omitted = false; } @@ -1134,14 +1130,19 @@ function checkRobot($body) { return false; } +// Returns an associative array with 'replies' and 'images' keys function numPosts($id) { global $board; - $query = prepare(sprintf("SELECT COUNT(*) as `count` FROM `posts_%s` WHERE `thread` = :thread", $board['uri'])); + $query = prepare(sprintf("SELECT COUNT(*) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(*) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $board['uri'], $board['uri'])); $query->bindValue(':thread', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $result = $query->fetch(); - return $result['count']; + $num_posts = $query->fetch(); + $num_posts = $num_posts['num']; + $num_images = $query->fetch(); + $num_images = $num_images['num']; + + return array('replies' => $num_posts, 'images' => $num_images); } function muteTime() { diff --git a/post.php b/post.php index c5e68578..f236e929 100644 --- a/post.php +++ b/post.php @@ -302,13 +302,21 @@ if (isset($_POST['delete'])) { } } - // Check if thread is locked - // but allow mods to post - if (!$post['op'] && !hasPermission($config['mod']['postinlocked'], $board['uri'])) { - if ($thread['locked']) + if (!$post['op']) { + // Check if thread is locked + // but allow mods to post + if ($thread['locked'] && !hasPermission($config['mod']['postinlocked'], $board['uri'])) error($config['error']['locked']); + + $numposts = numPosts($post['thread']); + + if ($config['reply_hard_limit'] != 0 && $config['reply_hard_limit'] <= $numposts['replies']) + error($config['error']['reply_hard_limit']); + + if ($post['has_file'] && $config['image_hard_limit'] != 0 && $config['image_hard_limit'] <= $numposts['images']) + error($config['error']['image_hard_limit']); } - + if ($post['has_file']) { $size = $_FILES['file']['size']; if ($size > $config['max_filesize']) @@ -636,7 +644,7 @@ if (isset($_POST['delete'])) { buildThread($post['op'] ? $id : $post['thread']); - if (!$post['op'] && strtolower($post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || numPosts($post['thread']) < $config['reply_limit'])) { + if (!$post['op'] && strtolower($post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || $numposts['replies']+1 < $config['reply_limit'])) { bumpThread($post['thread']); } -- cgit v1.3 From 74a470bf4ea6c69af4a6e13af5332d6617116056 Mon Sep 17 00:00:00 2001 From: K Date: Tue, 2 Jul 2013 19:52:29 +0200 Subject: Add support for 4chan-compatible json API. --- inc/api.php | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ inc/functions.php | 34 ++++++++++++++- 2 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 inc/api.php (limited to 'inc/functions.php') diff --git a/inc/api.php b/inc/api.php new file mode 100644 index 00000000..5592d8af --- /dev/null +++ b/inc/api.php @@ -0,0 +1,123 @@ + 'no', + 'thread' => 'resto', + 'subject' => 'sub', + 'email' => 'email', + 'name' => 'name', + 'trip' => 'trip', + 'capcode' => 'capcode', + 'body' => 'com', + 'time' => 'time', + 'thumb' => 'thumb', // non-compatible field + 'thumbx' => 'tn_w', + 'thumby' => 'tn_h', + 'file' => 'file', // non-compatible field + 'filex' => 'w', + 'filey' => 'h', + 'filesize' => 'fsize', + //'filename' => 'filename', + 'omitted' => 'omitted_posts', + 'omitted_images' => 'omitted_images', + //'posts' => 'replies', + //'ip' => '', + 'sticky' => 'sticky', + 'locked' => 'locked', + //'bumplocked' => '', + //'embed' => '', + //'root' => '', + //'mod' => '', + //'hr' => '', + ); + + static $ints = array( + 'no' => 1, + 'resto' => 1, + 'time' => 1, + 'tn_w' => 1, + 'tn_h' => 1, + 'w' => 1, + 'h' => 1, + 'fsize' => 1, + 'omitted_posts' => 1, + 'omitted_images' => 1, + 'sticky' => 1, + 'locked' => 1, + ); + + private function translatePost($post) { + $apiPost = array(); + foreach (self::$postFields as $local => $translated) { + if (!isset($post->$local)) + continue; + + $toInt = isset(self::$ints[$translated]); + $val = $post->$local; + if ($val !== null && $val !== '') { + $apiPost[$translated] = $toInt ? (int) $val : $val; + } + } + + if (isset($post->filename)) { + $dotPos = strrpos($post->filename, '.'); + $apiPost['filename'] = substr($post->filename, 0, $dotPos); + $apiPost['ext'] = substr($post->filename, $dotPos); + } + + return $apiPost; + } + + function translateThread(Thread $thread) { + $apiPosts = array(); + $op = $this->translatePost($thread); + $op['resto'] = 0; + $apiPosts['posts'][] = $op; + + foreach ($thread->posts as $p) { + $apiPosts['posts'][] = $this->translatePost($p); + } + + return $apiPosts; + } + + function translatePage(array $threads) { + $apiPage = array(); + foreach ($threads as $thread) { + $apiPage['threads'][] = $this->translateThread($thread); + } + return $apiPage; + } + + function translateCatalogPage(array $threads) { + $apiPage = array(); + foreach ($threads as $thread) { + $ts = $this->translateThread($thread); + $apiPage['threads'][] = current($ts['posts']); + } + return $apiPage; + } + + function translateCatalog($catalog) { + $apiCatalog = array(); + foreach ($catalog as $page => $threads) { + $apiPage = $this->translateCatalogPage($threads); + $apiPage['page'] = $page; + $apiCatalog[] = $apiPage; + } + + return $apiCatalog; + } +} diff --git a/inc/functions.php b/inc/functions.php index 70848468..cd6fdbb6 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -13,6 +13,7 @@ require_once 'inc/display.php'; require_once 'inc/template.php'; require_once 'inc/database.php'; require_once 'inc/events.php'; +require_once 'inc/api.php'; require_once 'inc/lib/gettext/gettext.inc'; // the user is not currently logged in as a moderator @@ -964,6 +965,8 @@ function index($page, $mod=false) { if ($query->rowcount() < 1 && $page > 1) return false; + + $threads = array(); while ($th = $query->fetch()) { $thread = new Thread( $th['id'], $th['subject'], $th['email'], $th['name'], $th['trip'], $th['capcode'], $th['body'], $th['time'], $th['thumb'], @@ -1012,7 +1015,8 @@ function index($page, $mod=false) { $thread->omitted = $omitted['post_count'] - ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']); $thread->omitted_images = $omitted['image_count'] - $num_images; } - + + $threads[] = $thread; $body .= $thread->build(true); } @@ -1021,7 +1025,8 @@ function index($page, $mod=false) { 'body' => $body, 'post_url' => $config['post_url'], 'config' => $config, - 'boardlist' => createBoardlist($mod) + 'boardlist' => createBoardlist($mod), + 'threads' => $threads ); } @@ -1211,6 +1216,9 @@ function buildIndex() { $pages = getPages(); $antibot = create_antibot($board['uri']); + $api = new Api(); + $catalog = array(); + $page = 1; while ($page <= $config['max_pages'] && $content = index($page)) { $filename = $board['dir'] . ($page == 1 ? $config['file_index'] : sprintf($config['file_page'], $page)); @@ -1223,6 +1231,14 @@ function buildIndex() { $content['antibot'] = $antibot; file_write($filename, Element('index.html', $content)); + + // json api + $threads = $content['threads']; + $json = json_encode($api->translatePage($threads)); + $jsonFilename = $board['dir'] . ($page-1) . ".json"; // pages should start from 0 + file_write($jsonFilename, $json); + + $catalog[$page-1] = $threads; $page++; } @@ -1230,8 +1246,16 @@ function buildIndex() { for (;$page<=$config['max_pages'];$page++) { $filename = $board['dir'] . ($page==1 ? $config['file_index'] : sprintf($config['file_page'], $page)); file_unlink($filename); + + $jsonFilename = $board['dir'] . ($page-1) . ".json"; + file_unlink($jsonFilename); } } + + // json api catalog + $json = json_encode($api->translateCatalog($catalog)); + $jsonFilename = $board['dir'] . "catalog.json"; + file_write($jsonFilename, $json); } function buildJavascript() { @@ -1547,6 +1571,12 @@ function buildThread($id, $return=false, $mod=false) { return $body; file_write($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $id), $body); + + // json api + $api = new Api(); + $json = json_encode($api->translateThread($thread)); + $jsonFilename = $board['dir'] . $config['dir']['res'] . $id . ".json"; + file_write($jsonFilename, $json); } function rrmdir($dir) { -- cgit v1.3 From 21f6799617677d536fa4e724212e72a1f2625fde Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 3 Jul 2013 00:25:32 -0400 Subject: js i18n: finish implementation with addition of the compiled locale strings file to additional javascripts --- inc/functions.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index b3471469..158973e2 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1244,6 +1244,12 @@ function buildJavascript() { 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)); } + // Check if we have translation for the javascripts; if yes, we add it to additional javascripts + list($pure_locale) = explode(".", $config['locale']); + if (file_exists ($jsloc = "inc/locale/".$pure_locale."/LC_MESSAGES/javascript.js")) { + array_unshift($config['additional_javascript'], $jsloc); + } + $script = Element('main.js', array( 'config' => $config, 'stylesheets' => $stylesheets -- cgit v1.3 From 77e4d926d9992dd56e1ab3c3af29ffd4bea92b59 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 01:21:06 -0400 Subject: Add "write" (files written to) to debug section --- inc/functions.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index 70848468..67019e0a 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -78,7 +78,7 @@ function loadConfig() { if ($config['debug']) { if (!isset($debug)) { - $debug = array('sql' => array(), 'purge' => array(), 'cached' => array()); + $debug = array('sql' => array(), 'purge' => array(), 'cached' => array(), 'write' => array()); $debug['start'] = microtime(true); } } @@ -392,7 +392,7 @@ function purge($uri) { } function file_write($path, $data, $simple = false, $skip_purge = false) { - global $config; + global $config, $debug; if (preg_match('/^remote:\/\/(.+)\:(.+)$/', $path, $m)) { if (isset($config['remote'][$m[1]])) { @@ -419,7 +419,7 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { error('Unable to truncate file: ' . $path); // Write data - if (fwrite($fp, $data) === false) + if (($bytes = fwrite($fp, $data)) === false) error('Unable to write to file: ' . $path); // Unlock @@ -445,6 +445,10 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { purge($path); } + if ($config['debug']) { + $debug['write'][] = $path . ': ' . $bytes . ' bytes'; + } + event('write', $path); } -- cgit v1.3 From 29b10c88db1ba16210e753e1fcf08d702455a674 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 02:48:20 -0400 Subject: Outputting thread subject in header/title (issue #122) --- inc/config.php | 3 +++ inc/functions.php | 5 +++-- templates/index.html | 2 +- templates/thread.html | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/config.php b/inc/config.php index 83b98c2b..ed4a31f1 100644 --- a/inc/config.php +++ b/inc/config.php @@ -527,6 +527,9 @@ // Number of characters in the poster ID (maximum is 40) $config['poster_id_length'] = 5; + // Show thread subject in page title? + $config['thread_subject_in_title'] = false; + // Page footer $config['footer'][] = 'All trademarks, copyrights, comments, and images on this page are owned by and are the responsibility of their respective parties.'; diff --git a/inc/functions.php b/inc/functions.php index 67019e0a..4b0e56d8 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1537,8 +1537,9 @@ function buildThread($id, $return=false, $mod=false) { error($config['error']['nonexistant']); $body = Element('thread.html', array( - 'board'=>$board, - 'body'=>$thread->build(), + 'board' => $board, + 'thread' => $thread, + 'body' => $thread->build(), 'config' => $config, 'id' => $id, 'mod' => $mod, diff --git a/templates/index.html b/templates/index.html index 112756d1..9b25e1be 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,7 +4,7 @@ {% if config.url_favicon %}{% endif %} - {{ board.url }} - {{ board.name }} + {{ board.url }} - {{ board.title|e }} {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} diff --git a/templates/thread.html b/templates/thread.html index 5442166f..aea8abb5 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -4,7 +4,7 @@ {% if config.url_favicon %}{% endif %} - {{ board.url }} - {{ board.name }} + {{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %} {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} -- cgit v1.3 From c8f30550af861b95a1f475069ad8d10960a613b2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 06:33:37 -0400 Subject: $config['require_ban_view']: Force users to view the "You are banned" page at least once before letting a ban disappear naturally. --- inc/config.php | 3 +++ inc/functions.php | 18 ++++++++++++++---- inc/mod/ban.php | 2 +- install.php | 4 +++- install.sql | 1 + templates/banned.html | 16 +++++++++++++--- 6 files changed, 35 insertions(+), 9 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/config.php b/inc/config.php index ed4a31f1..b7f6d220 100644 --- a/inc/config.php +++ b/inc/config.php @@ -366,6 +366,9 @@ // When true, a blank password will be used for files (not usable for deletion). $config['field_disable_password'] = false; + // Require users to see the ban page at least once for a ban even if it has since expired? + $config['require_ban_view'] = false; + /* * ==================== * Markup settings diff --git a/inc/functions.php b/inc/functions.php index 4b0e56d8..8d6e0a2d 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -579,6 +579,12 @@ function ago($timestamp) { function displayBan($ban) { global $config; + if (!$ban['seen']) { + $query = prepare("UPDATE `bans` SET `seen` = 1 WHERE `id` = :id"); + $query->bindValue(':id', $ban['id'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + } + $ban['ip'] = $_SERVER['REMOTE_ADDR']; // Show banned page and exit @@ -605,12 +611,12 @@ function checkBan($board = 0) { if (event('check-ban', $board)) return true; - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1"); + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board); $query->execute() or error(db_error($query)); if ($query->rowCount() < 1 && $config['ban_range']) { - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1"); + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board); $query->execute() or error(db_error($query)); @@ -618,7 +624,7 @@ function checkBan($board = 0) { if ($query->rowCount() < 1 && $config['ban_cidr'] && !isIPv6()) { // my most insane SQL query yet - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND ( `ip` REGEXP '^(\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+\)\/(\[0-9]+)$' AND @@ -635,10 +641,14 @@ function checkBan($board = 0) { if ($ban = $query->fetch()) { if ($ban['expires'] && $ban['expires'] < time()) { // Ban expired - $query = prepare("DELETE FROM `bans` WHERE `id` = :id LIMIT 1"); + $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $ban['id'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); + if ($config['require_ban_view'] && !$ban['seen']) { + displayBan($ban); + } + return; } diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 30234157..cfc2636f 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -56,7 +56,7 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod, $pdo; - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); + $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board, 0)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); $query->bindValue(':time', time()); diff --git a/install.php b/install.php index 1447c723..71d1c910 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ -

{% trans %}You are banned! ;_;{% endtrans %}

+ {% if ban.expires and time() >= ban.expires %} +

{% trans %}You were banned! ;_;{% endtrans %}

+ {% else %} +

{% trans %}You are banned! ;_;{% endtrans %}

+ {% endif %}

- {% trans %}You have been banned from{% endtrans %} + {% if ban.expires and time() >= ban.expires %} + {% trans %}You were banned from{% endtrans %} + {% else %} + {% trans %}You have been banned from{% endtrans %} + {% endif %} {% if ban.board %} {{ config.board_abbreviation|sprintf(ban.board) }} {% else %} @@ -23,7 +31,9 @@

{% trans %}Your ban was filed on{% endtrans %} {{ ban.set|date(config.ban_date) }} {% trans %}and{% endtrans %} - {% if ban.expires %} + {% if ban.expires and time() >= ban.expires %} + {% trans %} has since expired. Refresh the page to continue.{% endtrans %} + {% elseif ban.expires %} {% trans %}expires{% endtrans %} {{ ban.expires|until }} {% trans %}from now, which is on{% endtrans %} {{ ban.expires|date(config.ban_date) }} -- cgit v1.3 From aadb57f2a2db9210468f25d7dcd45d561ef6ad54 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 08:50:39 -0400 Subject: More ban stuff: Show whether or not user has "seen" a ban yet in the ban list and on IP address pages. Purge useless expired ban records. --- inc/functions.php | 10 ++++++++++ templates/mod/ban_list.html | 8 ++++++++ templates/mod/view_ip.html | 10 ++++++++++ 3 files changed, 28 insertions(+) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index 8d6e0a2d..40a2c1fe 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -654,6 +654,16 @@ function checkBan($board = 0) { displayBan($ban); } + + // I'm not sure where else to put this. It doesn't really matter where; it just needs to be called every now and then to keep the ban list tidy. + purge_bans(); +} + +// No reason to keep expired bans in the database (except those that haven't been viewed yet) +function purge_bans() { + $query = prepare("DELETE FROM `bans` WHERE `expires` IS NOT NULL AND `expires` < :time AND `seen` = 1"); + $query->bindValue(':time', time()); + $query->execute() or error(db_error($query)); } function threadLocked($id) { diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index 2edb9cdf..f8826ade 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -10,6 +10,7 @@ {% trans 'Set' %} {% trans 'Duration' %} {% trans 'Expires' %} + {% trans 'Seen' %} {% trans 'Staff' %} {% for ban in bans %} @@ -58,6 +59,13 @@ {% endif %} {% endif %} + + {% if ban.seen %} + {% trans 'Yes' %} + {% else %} + {% trans 'No' %} + {% endif %} + {% if ban.username %} {% if mod|hasPermission(config.mod.view_banstaff) %} diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index 562a0140..e2dad7af 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -136,6 +136,16 @@ {% endif %} + + {% trans 'Seen' %} + + {% if ban.seen %} + {% trans 'Yes' %} + {% else %} + {% trans 'No' %} + {% endif %} + + {% trans 'Staff' %} -- cgit v1.3 From e4bd9a6886af2a812ccc909d8ad957df1bdc5d2b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Thu, 18 Jul 2013 12:06:26 -0400 Subject: Themes edit: Split "post" into two seperate actions: "post" (replies) and "post-thread". And add a $board variable. --- inc/functions.php | 8 +++--- post.php | 6 ++++- templates/themes/basic/theme.php | 2 +- templates/themes/catalog/theme.php | 50 ++++++++++++++++------------------- templates/themes/categories/theme.php | 2 +- templates/themes/frameset/theme.php | 2 +- templates/themes/recent/theme.php | 5 ++-- templates/themes/rrdtool/theme.php | 2 +- templates/themes/sitemap/theme.php | 6 ++++- 9 files changed, 44 insertions(+), 39 deletions(-) (limited to 'inc/functions.php') diff --git a/inc/functions.php b/inc/functions.php index 40a2c1fe..af810f31 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -239,12 +239,12 @@ function create_antibot($board, $thread = null) { return _create_antibot($board, $thread); } -function rebuildThemes($action) { +function rebuildThemes($action, $board = false) { // List themes $query = query("SELECT `theme` FROM `theme_settings` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error()); while ($theme = $query->fetch()) { - rebuildTheme($theme['theme'], $action); + rebuildTheme($theme['theme'], $action, $board); } } @@ -261,7 +261,7 @@ function loadThemeConfig($_theme) { return $theme; } -function rebuildTheme($theme, $action) { +function rebuildTheme($theme, $action, $board = false) { global $config, $_theme; $_theme = $theme; @@ -270,7 +270,7 @@ function rebuildTheme($theme, $action) { if (file_exists($config['dir']['themes'] . '/' . $_theme . '/theme.php')) { require_once $config['dir']['themes'] . '/' . $_theme . '/theme.php'; - $theme['build_function']($action, themeSettings($_theme)); + $theme['build_function']($action, themeSettings($_theme), $board); } } diff --git a/post.php b/post.php index 3d718786..97fb263d 100644 --- a/post.php +++ b/post.php @@ -677,7 +677,11 @@ if (isset($_POST['delete'])) { _syslog(LOG_INFO, 'New post: /' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['op'] ? $id : $post['thread']) . (!$post['op'] ? '#' . $id : '')); - rebuildThemes('post'); + if ($post['op']) + rebuildThemes('post-thread', $board['uri']); + else + rebuildThemes('post', $board['uri']); + header('Location: ' . $redirect, true, $config['redirect_http']); } else { if (!file_exists($config['has_installed'])) { diff --git a/templates/themes/basic/theme.php b/templates/themes/basic/theme.php index 806a331a..7ba0d1e7 100644 --- a/templates/themes/basic/theme.php +++ b/templates/themes/basic/theme.php @@ -1,7 +1,7 @@ build($action, $settings); - } - - // Wrap functions in a class so they don't interfere with normal Tinyboard operations - class Catalog { - public function build($action, $settings) { - global $config, $_theme; - - if ($action == 'all') { - copy('templates/themes/catalog/catalog.css', $config['dir']['home'] . $settings['css']); - } + $boards = explode(' ', $settings['boards']); + + if ($action == 'all') { + copy('templates/themes/catalog/catalog.css', $config['dir']['home'] . $settings['css']); - $boards = explode(' ', $settings['boards']); foreach ($boards as $board) { - if ($action == 'all' || $action == 'post') - file_write($config['dir']['home'] . $board . '/catalog.html', $this->homepage($settings, $board)); + $b = new Catalog(); + $b->build($settings, $board); } - + } elseif ($action == 'post-thread' && in_array($board, $boards)) { + $b = new Catalog(); + $b->build($settings, $board); } - - public function homepage($settings, $board_name) { + } + + // Wrap functions in a class so they don't interfere with normal Tinyboard operations + class Catalog { + public function build($settings, $board_name) { global $config, $board; + openBoard($board_name); + $recent_images = array(); $recent_posts = array(); $stats = array(); @@ -39,16 +40,13 @@ $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error()); 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['board_name'] = $board['name']; $post['file'] = $config['uri_thumb'] . $post['thumb']; $recent_posts[] = $post; } - - return Element('themes/catalog/catalog.html', Array( + file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', Array( 'settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), @@ -57,8 +55,6 @@ 'stats' => $stats, 'board' => $board_name, 'link' => $config['root'] . $board['dir'] - )); + ))); } }; - -?> diff --git a/templates/themes/categories/theme.php b/templates/themes/categories/theme.php index 11fcbbaf..7d468d0d 100644 --- a/templates/themes/categories/theme.php +++ b/templates/themes/categories/theme.php @@ -1,7 +1,7 @@ build($action, $settings); @@ -23,7 +24,7 @@ $this->excluded = explode(' ', $settings['exclude']); - if ($action == 'all' || $action == 'post') + if ($action == 'all' || $action == 'post' || $action == 'post-thread') file_write($config['dir']['home'] . $settings['html'], $this->homepage($settings)); } diff --git a/templates/themes/rrdtool/theme.php b/templates/themes/rrdtool/theme.php index eed2ac9a..68fc1850 100644 --- a/templates/themes/rrdtool/theme.php +++ b/templates/themes/rrdtool/theme.php @@ -1,7 +1,7 @@