diff --git a/README.md b/README.md index 46cc3a0..f8d7113 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ To allow new threads without requiring an image, see the [Text Board Mode](https For demos see the [TinyIB Installations](https://github.com/tslocum/TinyIB/wiki) page. [![githalytics.com alpha](https://cruel-carlota.pagodabox.com/5135372febbc40bacddbb13c1f0a8333 "githalytics.com")](http://githalytics.com/tslocum/TinyIB) +**Note to those who have recently upgraded:** Are you unable to create new posts? Run the SQL on [this page](https://github.com/tslocum/TinyIB/wiki/NewSQLStructure) to finish the upgrade process. + Features ------------ - GIF, JPG, PNG, SWF and WebA/WebM upload. @@ -16,7 +18,7 @@ Features - Delete post via password. - Management panel: - Administrators and moderators use separate passwords. - - Moderators are only able to delete posts. + - Moderators are only able to delete posts, or approve them when necessary. (See ``TINYIB_REQMOD``) - Ban offensive/abusive posters across all boards. - Post using raw HTML. - Upgrade automatically when installed via git. (Tested on Linux only) @@ -38,6 +40,11 @@ Installing - Ensure your web host is running Linux. - Install [mediainfo](http://mediaarea.net/en/MediaInfo) and [ffmpegthumbnailer](https://code.google.com/p/ffmpegthumbnailer/). On Ubuntu, run ``sudo apt-get install mediainfo ffmpegthumbnailer``. - Set ``TINYIB_WEBM`` to ``true``. + - To require moderation before displaying posts: + - Ensure your ``TINYIB_DBMODE`` is set to ``mysql``, ``mysqli``, or ``pdo``. + - Set ``TINYIB_REQMOD`` to ``files`` to require moderation for posts with files attached. + - Set ``TINYIB_REQMOD`` to ``all`` to require moderation for all posts. + - Moderate posts by visiting the management panel. - When setting ``TINYIB_DBMODE`` to ``pdo``, note that PDO mode has been tested on **MySQL databases only**. Theoretically it will work with any applicable driver, but this is not guaranteed. If you use an alternative driver, please report back regarding how it works. 6. [CHMOD](http://en.wikipedia.org/wiki/Chmod) write permissions to these directories: - ./ (the directory containing TinyIB) diff --git a/imgboard.php b/imgboard.php index 0f80b77..d1db637 100644 --- a/imgboard.php +++ b/imgboard.php @@ -238,28 +238,37 @@ if (isset($_POST['message']) || isset($_POST['file'])) { echo $post['file_original'] . ' uploaded.
'; } + if (!$loggedin && (($post['file'] != '' && TINYIB_REQMOD == 'files') || TINYIB_REQMOD == 'all')) { + $post['moderated'] = '0'; + echo 'Your ' . ($post['parent'] == TINYIB_NEWTHREAD ? 'thread' : 'post') . ' will be shown once it has been approved.
'; + $slow_redirect = true; + } + $post['id'] = insertPost($post); - if (strtolower($post['email']) == 'noko') { - $redirect = 'res/' . ($post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent']) . '.html#' . $post['id']; - } - trimThreads(); - - echo 'Updating thread...
'; - if ($post['parent'] != TINYIB_NEWTHREAD) { - rebuildThread($post['parent']); - - if (strtolower($post['email']) != 'sage') { - if (TINYIB_MAXREPLIES == 0 || numRepliesToThreadByID($post['parent']) <= TINYIB_MAXREPLIES) { - bumpThreadByID($post['parent']); - } + if ($post['moderated'] == '1') { + if (strtolower($post['email']) == 'noko') { + $redirect = 'res/' . ($post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent']) . '.html#' . $post['id']; } - } else { - rebuildThread($post['id']); - } - echo 'Updating index...
'; - rebuildIndexes(); + trimThreads(); + + echo 'Updating thread...
'; + if ($post['parent'] != TINYIB_NEWTHREAD) { + rebuildThread($post['parent']); + + if (strtolower($post['email']) != 'sage') { + if (TINYIB_MAXREPLIES == 0 || numRepliesToThreadByID($post['parent']) <= TINYIB_MAXREPLIES) { + bumpThreadByID($post['parent']); + } + } + } else { + rebuildThread($post['id']); + } + + echo 'Updating index...
'; + rebuildIndexes(); + } // Check if the request is to delete a post and/or its associated image } elseif (isset($_GET['delete']) && !isset($_GET['manage'])) { if (!isset($_POST['delete'])) { @@ -432,6 +441,23 @@ if (isset($_POST['message']) || isset($_POST['file'])) { } else { fancyDie("Sorry, there doesn't appear to be a post with that ID."); } + } elseif (isset($_GET['approve'])) { + if ($_GET['approve'] > 0) { + $post = postByID($_GET['approve']); + if ($post) { + approvePostByID($post['id']); + $thread_id = $post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent']; + + if (strtolower($post['email']) != 'sage' && (TINYIB_MAXREPLIES == 0 || numRepliesToThreadByID($thread_id) <= TINYIB_MAXREPLIES)) { + bumpThreadByID($thread_id); + } + threadUpdated($thread_id); + + $text .= manageInfo('Post No.' . $post['id'] . ' approved.'); + } else { + fancyDie("Sorry, there doesn't appear to be a post with that ID."); + } + } } elseif (isset($_GET['moderate'])) { if ($_GET['moderate'] > 0) { $post = postByID($_GET['moderate']); @@ -466,5 +492,5 @@ if (isset($_POST['message']) || isset($_POST['file'])) { } if ($redirect) { - echo '--> --> -->'; + echo '--> --> -->'; } diff --git a/inc/database_flatfile.php b/inc/database_flatfile.php index c8ed053..7cdf590 100644 --- a/inc/database_flatfile.php +++ b/inc/database_flatfile.php @@ -150,7 +150,7 @@ function numRepliesToThreadByID($id) { return count($rows); } -function postsInThreadByID($id) { +function postsInThreadByID($id, $moderated_only = true) { $compClause = new OrWhereClause(); $compClause->add(new SimpleWhereClause(POST_ID, '=', $id, INTEGER_COMPARISON)); $compClause->add(new SimpleWhereClause(POST_PARENT, '=', $id, INTEGER_COMPARISON)); @@ -164,13 +164,13 @@ function postsByHex($hex) { return convertPostsToSQLStyle($rows); } -function latestPosts() { +function latestPosts($moderated = true) { $rows = $GLOBALS['db']->selectWhere(POSTS_FILE, NULL, 10, new OrderBy(POST_TIMESTAMP, DESCENDING, INTEGER_COMPARISON)); return convertPostsToSQLStyle($rows); } function deletePostByID($id) { - $posts = postsInThreadByID($id); + $posts = postsInThreadByID($id, false); foreach ($posts as $post) { if ($post['id'] != $id) { deletePostImages($post); diff --git a/inc/database_mysql.php b/inc/database_mysql.php index 34547ae..d7d5e16 100644 --- a/inc/database_mysql.php +++ b/inc/database_mysql.php @@ -42,25 +42,29 @@ function postByID($id) { } function threadExistsByID($id) { - return mysql_result(mysql_query("SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `id` = '" . mysql_real_escape_string($id) . "' AND `parent` = 0 LIMIT 1"), 0, 0) > 0; + return mysql_result(mysql_query("SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `id` = '" . mysql_real_escape_string($id) . "' AND `parent` = 0 AND `moderated` = 1 LIMIT 1"), 0, 0) > 0; } function insertPost($post) { - mysql_query("INSERT INTO `" . TINYIB_DBPOSTS . "` (`parent`, `timestamp`, `bumped`, `ip`, `name`, `tripcode`, `email`, `nameblock`, `subject`, `message`, `password`, `file`, `file_hex`, `file_original`, `file_size`, `file_size_formatted`, `image_width`, `image_height`, `thumb`, `thumb_width`, `thumb_height`) VALUES (" . $post['parent'] . ", " . time() . ", " . time() . ", '" . $_SERVER['REMOTE_ADDR'] . "', '" . mysql_real_escape_string($post['name']) . "', '" . mysql_real_escape_string($post['tripcode']) . "', '" . mysql_real_escape_string($post['email']) . "', '" . mysql_real_escape_string($post['nameblock']) . "', '" . mysql_real_escape_string($post['subject']) . "', '" . mysql_real_escape_string($post['message']) . "', '" . mysql_real_escape_string($post['password']) . "', '" . $post['file'] . "', '" . $post['file_hex'] . "', '" . mysql_real_escape_string($post['file_original']) . "', " . $post['file_size'] . ", '" . $post['file_size_formatted'] . "', " . $post['image_width'] . ", " . $post['image_height'] . ", '" . $post['thumb'] . "', " . $post['thumb_width'] . ", " . $post['thumb_height'] . ")"); + mysql_query("INSERT INTO `" . TINYIB_DBPOSTS . "` (`parent`, `timestamp`, `bumped`, `ip`, `name`, `tripcode`, `email`, `nameblock`, `subject`, `message`, `password`, `file`, `file_hex`, `file_original`, `file_size`, `file_size_formatted`, `image_width`, `image_height`, `thumb`, `thumb_width`, `thumb_height`, `moderated`) VALUES (" . $post['parent'] . ", " . time() . ", " . time() . ", '" . $_SERVER['REMOTE_ADDR'] . "', '" . mysql_real_escape_string($post['name']) . "', '" . mysql_real_escape_string($post['tripcode']) . "', '" . mysql_real_escape_string($post['email']) . "', '" . mysql_real_escape_string($post['nameblock']) . "', '" . mysql_real_escape_string($post['subject']) . "', '" . mysql_real_escape_string($post['message']) . "', '" . mysql_real_escape_string($post['password']) . "', '" . $post['file'] . "', '" . $post['file_hex'] . "', '" . mysql_real_escape_string($post['file_original']) . "', " . $post['file_size'] . ", '" . $post['file_size_formatted'] . "', " . $post['image_width'] . ", " . $post['image_height'] . ", '" . $post['thumb'] . "', " . $post['thumb_width'] . ", " . $post['thumb_height'] . ", " . $post['moderated'] . ")"); return mysql_insert_id(); } +function approvePostByID($id) { + mysql_query("UPDATE `" . TINYIB_DBPOSTS . "` SET `moderated` = 1 WHERE `id` = " . $id . " LIMIT 1"); +} + function bumpThreadByID($id) { mysql_query("UPDATE `" . TINYIB_DBPOSTS . "` SET `bumped` = " . time() . " WHERE `id` = " . $id . " LIMIT 1"); } function countThreads() { - return mysql_result(mysql_query("SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0"), 0, 0); + return mysql_result(mysql_query("SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 AND `moderated` = 1"), 0, 0); } function allThreads() { $threads = array(); - $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 ORDER BY `bumped` DESC"); + $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 AND `moderated` = 1 ORDER BY `bumped` DESC"); if ($result) { while ($thread = mysql_fetch_assoc($result)) { $threads[] = $thread; @@ -70,12 +74,12 @@ function allThreads() { } function numRepliesToThreadByID($id) { - return mysql_result(mysql_query("SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = " . $id), 0, 0); + return mysql_result(mysql_query("SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = " . $id . " AND `moderated` = 1"), 0, 0); } -function postsInThreadByID($id) { +function postsInThreadByID($id, $moderated_only = true) { $posts = array(); - $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `id` = " . $id . " OR `parent` = " . $id . " ORDER BY `id` ASC"); + $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE (`id` = " . $id . " OR `parent` = " . $id . ")" . ($moderated_only ? " AND `moderated` = 1" : "") . " ORDER BY `id` ASC"); if ($result) { while ($post = mysql_fetch_assoc($result)) { $posts[] = $post; @@ -86,7 +90,7 @@ function postsInThreadByID($id) { function postsByHex($hex) { $posts = array(); - $result = mysql_query("SELECT `id`, `parent` FROM `" . TINYIB_DBPOSTS . "` WHERE `file_hex` = '" . mysql_real_escape_string($hex) . "' LIMIT 1"); + $result = mysql_query("SELECT `id`, `parent` FROM `" . TINYIB_DBPOSTS . "` WHERE `file_hex` = '" . mysql_real_escape_string($hex) . "' AND `moderated` = 1 LIMIT 1"); if ($result) { while ($post = mysql_fetch_assoc($result)) { $posts[] = $post; @@ -95,9 +99,9 @@ function postsByHex($hex) { return $posts; } -function latestPosts() { +function latestPosts($moderated = true) { $posts = array(); - $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` ORDER BY `timestamp` DESC LIMIT 10"); + $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `moderated` = " . ($moderated ? '1' : '0') . " ORDER BY `timestamp` DESC LIMIT 10"); if ($result) { while ($post = mysql_fetch_assoc($result)) { $posts[] = $post; @@ -107,7 +111,7 @@ function latestPosts() { } function deletePostByID($id) { - $posts = postsInThreadByID($id); + $posts = postsInThreadByID($id, false); foreach ($posts as $post) { if ($post['id'] != $id) { deletePostImages($post); @@ -127,7 +131,7 @@ function deletePostByID($id) { function trimThreads() { if (TINYIB_MAXTHREADS > 0) { - $result = mysql_query("SELECT `id` FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 ORDER BY `bumped` DESC LIMIT " . TINYIB_MAXTHREADS . ", 10"); + $result = mysql_query("SELECT `id` FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 AND `moderated` = 1 ORDER BY `bumped` DESC LIMIT " . TINYIB_MAXTHREADS . ", 10"); if ($result) { while ($post = mysql_fetch_assoc($result)) { deletePostByID($post['id']); diff --git a/inc/database_mysqli.php b/inc/database_mysqli.php index 7806435..1f48b3d 100644 --- a/inc/database_mysqli.php +++ b/inc/database_mysqli.php @@ -45,15 +45,20 @@ function postByID($id) { function threadExistsByID($id) { global $link; - return mysqli_result(mysqli_query($link, "SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `id` = '" . mysqli_real_escape_string($link, $id) . "' AND `parent` = 0 LIMIT 1"), 0, 0) > 0; + return mysqli_result(mysqli_query($link, "SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `id` = '" . mysqli_real_escape_string($link, $id) . "' AND `parent` = 0 AND `moderated` = 0 LIMIT 1"), 0, 0) > 0; } function insertPost($post) { global $link; - mysqli_query($link, "INSERT INTO `" . TINYIB_DBPOSTS . "` (`parent`, `timestamp`, `bumped`, `ip`, `name`, `tripcode`, `email`, `nameblock`, `subject`, `message`, `password`, `file`, `file_hex`, `file_original`, `file_size`, `file_size_formatted`, `image_width`, `image_height`, `thumb`, `thumb_width`, `thumb_height`) VALUES (" . $post['parent'] . ", " . time() . ", " . time() . ", '" . $_SERVER['REMOTE_ADDR'] . "', '" . mysqli_real_escape_string($link, $post['name']) . "', '" . mysqli_real_escape_string($link, $post['tripcode']) . "', '" . mysqli_real_escape_string($link, $post['email']) . "', '" . mysqli_real_escape_string($link, $post['nameblock']) . "', '" . mysqli_real_escape_string($link, $post['subject']) . "', '" . mysqli_real_escape_string($link, $post['message']) . "', '" . mysqli_real_escape_string($link, $post['password']) . "', '" . $post['file'] . "', '" . $post['file_hex'] . "', '" . mysqli_real_escape_string($link, $post['file_original']) . "', " . $post['file_size'] . ", '" . $post['file_size_formatted'] . "', " . $post['image_width'] . ", " . $post['image_height'] . ", '" . $post['thumb'] . "', " . $post['thumb_width'] . ", " . $post['thumb_height'] . ")"); + mysqli_query($link, "INSERT INTO `" . TINYIB_DBPOSTS . "` (`parent`, `timestamp`, `bumped`, `ip`, `name`, `tripcode`, `email`, `nameblock`, `subject`, `message`, `password`, `file`, `file_hex`, `file_original`, `file_size`, `file_size_formatted`, `image_width`, `image_height`, `thumb`, `thumb_width`, `thumb_height`, `moderated`) VALUES (" . $post['parent'] . ", " . time() . ", " . time() . ", '" . $_SERVER['REMOTE_ADDR'] . "', '" . mysqli_real_escape_string($link, $post['name']) . "', '" . mysqli_real_escape_string($link, $post['tripcode']) . "', '" . mysqli_real_escape_string($link, $post['email']) . "', '" . mysqli_real_escape_string($link, $post['nameblock']) . "', '" . mysqli_real_escape_string($link, $post['subject']) . "', '" . mysqli_real_escape_string($link, $post['message']) . "', '" . mysqli_real_escape_string($link, $post['password']) . "', '" . $post['file'] . "', '" . $post['file_hex'] . "', '" . mysqli_real_escape_string($link, $post['file_original']) . "', " . $post['file_size'] . ", '" . $post['file_size_formatted'] . "', " . $post['image_width'] . ", " . $post['image_height'] . ", '" . $post['thumb'] . "', " . $post['thumb_width'] . ", " . $post['thumb_height'] . ", " . $post['moderated'] . ")"); return mysqli_insert_id($link); } +function approvePostByID($id) { + global $link; + mysqli_query($link, "UPDATE `" . TINYIB_DBPOSTS . "` SET `moderated` = 1 WHERE `id` = " . $id . " LIMIT 1"); +} + function bumpThreadByID($id) { global $link; mysqli_query($link, "UPDATE `" . TINYIB_DBPOSTS . "` SET `bumped` = " . time() . " WHERE `id` = " . $id . " LIMIT 1"); @@ -61,13 +66,13 @@ function bumpThreadByID($id) { function countThreads() { global $link; - return mysqli_result(mysqli_query($link, "SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0"), 0, 0); + return mysqli_result(mysqli_query($link, "SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 AND `moderated` = 1"), 0, 0); } function allThreads() { global $link; $threads = array(); - $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 ORDER BY `bumped` DESC"); + $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 AND `moderated` = 1 ORDER BY `bumped` DESC"); if ($result) { while ($thread = mysqli_fetch_assoc($result)) { $threads[] = $thread; @@ -78,13 +83,13 @@ function allThreads() { function numRepliesToThreadByID($id) { global $link; - return mysqli_result(mysqli_query($link, "SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = " . $id), 0, 0); + return mysqli_result(mysqli_query($link, "SELECT COUNT(*) FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = " . $id . " AND `moderated` = 1"), 0, 0); } -function postsInThreadByID($id) { +function postsInThreadByID($id, $moderated_only = true) { global $link; $posts = array(); - $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `id` = " . $id . " OR `parent` = " . $id . " ORDER BY `id` ASC"); + $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE (`id` = " . $id . " OR `parent` = " . $id . ")" . ($moderated_only ? " AND `moderated` = 1" : "") . " ORDER BY `id` ASC"); if ($result) { while ($post = mysqli_fetch_assoc($result)) { $posts[] = $post; @@ -96,7 +101,7 @@ function postsInThreadByID($id) { function postsByHex($hex) { global $link; $posts = array(); - $result = mysqli_query($link, "SELECT `id`, `parent` FROM `" . TINYIB_DBPOSTS . "` WHERE `file_hex` = '" . mysqli_real_escape_string($link, $hex) . "' LIMIT 1"); + $result = mysqli_query($link, "SELECT `id`, `parent` FROM `" . TINYIB_DBPOSTS . "` WHERE `file_hex` = '" . mysqli_real_escape_string($link, $hex) . "' AND `moderated` = 1 LIMIT 1"); if ($result) { while ($post = mysqli_fetch_assoc($result)) { $posts[] = $post; @@ -105,10 +110,10 @@ function postsByHex($hex) { return $posts; } -function latestPosts() { +function latestPosts($moderated = true) { global $link; $posts = array(); - $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBPOSTS . "` ORDER BY `timestamp` DESC LIMIT 10"); + $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBPOSTS . "` WHERE `moderated` = " . ($moderated ? '1' : '0') . " ORDER BY `timestamp` DESC LIMIT 10"); if ($result) { while ($post = mysqli_fetch_assoc($result)) { $posts[] = $post; @@ -119,7 +124,7 @@ function latestPosts() { function deletePostByID($id) { global $link; - $posts = postsInThreadByID($id); + $posts = postsInThreadByID($id, false); foreach ($posts as $post) { if ($post['id'] != $id) { deletePostImages($post); @@ -140,7 +145,7 @@ function deletePostByID($id) { function trimThreads() { global $link; if (TINYIB_MAXTHREADS > 0) { - $result = mysqli_query($link, "SELECT `id` FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 ORDER BY `bumped` DESC LIMIT " . TINYIB_MAXTHREADS . ", 10"); + $result = mysqli_query($link, "SELECT `id` FROM `" . TINYIB_DBPOSTS . "` WHERE `parent` = 0 AND `moderated` = 1 ORDER BY `bumped` DESC LIMIT " . TINYIB_MAXTHREADS . ", 10"); if ($result) { while ($post = mysqli_fetch_assoc($result)) { deletePostByID($post['id']); diff --git a/inc/database_pdo.php b/inc/database_pdo.php index 5af52db..ffe14d9 100644 --- a/inc/database_pdo.php +++ b/inc/database_pdo.php @@ -63,35 +63,39 @@ function postByID($id) { } function threadExistsByID($id) { - $result = pdoQuery("SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE id = ? AND parent = 0", array($id)); + $result = pdoQuery("SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE id = ? AND parent = 0 AND moderated = 1", array($id)); return $result->fetchColumn() != 0; } function insertPost($post) { global $dbh; $now = time(); - $stm = $dbh->prepare("INSERT INTO " . TINYIB_DBPOSTS . " (parent, timestamp, bumped, ip, name, tripcode, email, nameblock, subject, message, password, file, file_hex, file_original, file_size, file_size_formatted, image_width, image_height, thumb, thumb_width, thumb_height) " . - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stm = $dbh->prepare("INSERT INTO " . TINYIB_DBPOSTS . " (parent, timestamp, bumped, ip, name, tripcode, email, nameblock, subject, message, password, file, file_hex, file_original, file_size, file_size_formatted, image_width, image_height, thumb, thumb_width, thumb_height, moderated) " . + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stm->execute(array($post['parent'], $now, $now, $_SERVER['REMOTE_ADDR'], $post['name'], $post['tripcode'], $post['email'], $post['nameblock'], $post['subject'], $post['message'], $post['password'], $post['file'], $post['file_hex'], $post['file_original'], $post['file_size'], $post['file_size_formatted'], - $post['image_width'], $post['image_height'], $post['thumb'], $post['thumb_width'], $post['thumb_height'])); + $post['image_width'], $post['image_height'], $post['thumb'], $post['thumb_width'], $post['thumb_height'], $post['moderated'])); return $dbh->lastInsertId(); } +function approvePostByID($id) { + pdoQuery("UPDATE " . TINYIB_DBPOSTS . " SET moderated = ? WHERE id = ?", array('1', $id)); +} + function bumpThreadByID($id) { $now = time(); pdoQuery("UPDATE " . TINYIB_DBPOSTS . " SET bumped = ? WHERE id = ?", array($now, $id)); } function countThreads() { - $result = pdoQuery("SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE parent = 0"); + $result = pdoQuery("SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE parent = 0 AND moderated = 1"); return (int)$result->fetchColumn(); } function allThreads() { $threads = array(); - $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE parent = 0 ORDER BY bumped DESC"); + $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE parent = 0 AND moderated = 1 ORDER BY bumped DESC"); while ($row = $results->fetch()) { $threads[] = $row; } @@ -99,13 +103,13 @@ function allThreads() { } function numRepliesToThreadByID($id) { - $result = pdoQuery("SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE parent = ?", array($id)); + $result = pdoQuery("SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE parent = ? AND moderated = 1", array($id)); return (int)$result->fetchColumn(); } -function postsInThreadByID($id) { +function postsInThreadByID($id, $moderated_only = true) { $posts = array(); - $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE id = ? OR parent = ? ORDER BY id ASC", array($id, $id)); + $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE (id = ? OR parent = ?)" . ($moderated_only ? " AND moderated = 1" : "") . " ORDER BY id ASC", array($id, $id)); while ($row = $results->fetch(PDO::FETCH_ASSOC)) { $posts[] = $row; } @@ -114,16 +118,16 @@ function postsInThreadByID($id) { function postsByHex($hex) { $posts = array(); - $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE file_hex = ? LIMIT 1", array($hex)); + $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE file_hex = ? AND moderated = 1 LIMIT 1", array($hex)); while ($row = $results->fetch(PDO::FETCH_ASSOC)) { $posts[] = $row; } return $posts; } -function latestPosts() { +function latestPosts($moderated = true) { $posts = array(); - $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " ORDER BY timestamp DESC LIMIT 10"); + $results = pdoQuery("SELECT * FROM " . TINYIB_DBPOSTS . " WHERE moderated = ? ORDER BY timestamp DESC LIMIT 10", array($moderated ? '1' : '0')); while ($row = $results->fetch(PDO::FETCH_ASSOC)) { $posts[] = $row; } @@ -131,7 +135,7 @@ function latestPosts() { } function deletePostByID($id) { - $posts = postsInThreadByID($id); + $posts = postsInThreadByID($id, false); foreach ($posts as $post) { if ($post['id'] != $id) { deletePostImages($post); @@ -152,7 +156,7 @@ function deletePostByID($id) { function trimThreads() { $limit = (int)TINYIB_MAXTHREADS; if ($limit > 0) { - $results = pdoQuery("SELECT id FROM " . TINYIB_DBPOSTS . " WHERE parent = 0 ORDER BY bumped LIMIT 100 OFFSET " . $limit + $results = pdoQuery("SELECT id FROM " . TINYIB_DBPOSTS . " WHERE parent = 0 AND moderated = 1 ORDER BY bumped LIMIT 100 OFFSET " . $limit ); # old mysql, sqlite3: SELECT id FROM $table ORDER BY bumped LIMIT $limit,100 # mysql, postgresql, sqlite3: SELECT id FROM $table ORDER BY bumped LIMIT 100 OFFSET $limit diff --git a/inc/database_sqlite.php b/inc/database_sqlite.php index 4d5145e..5d886a3 100644 --- a/inc/database_sqlite.php +++ b/inc/database_sqlite.php @@ -94,7 +94,7 @@ function numRepliesToThreadByID($id) { return sqlite_fetch_single(sqlite_query($GLOBALS["db"], "SELECT COUNT(*) FROM " . TINYIB_DBPOSTS . " WHERE parent = " . $id)); } -function postsInThreadByID($id) { +function postsInThreadByID($id, $moderated_only = true) { $posts = array(); $result = sqlite_fetch_all(sqlite_query($GLOBALS["db"], "SELECT * FROM " . TINYIB_DBPOSTS . " WHERE id = " . $id . " OR parent = " . $id . " ORDER BY id ASC"), SQLITE_ASSOC); foreach ($result as $post) { @@ -112,7 +112,7 @@ function postsByHex($hex) { return $posts; } -function latestPosts() { +function latestPosts($moderated = true) { $posts = array(); $result = sqlite_fetch_all(sqlite_query($GLOBALS["db"], "SELECT * FROM " . TINYIB_DBPOSTS . " ORDER BY timestamp DESC LIMIT 10"), SQLITE_ASSOC); foreach ($result as $post) { @@ -122,7 +122,7 @@ function latestPosts() { } function deletePostByID($id) { - $posts = postsInThreadByID($id); + $posts = postsInThreadByID($id, false); foreach ($posts as $post) { if ($post['id'] != $id) { deletePostImages($post); diff --git a/inc/defines.php b/inc/defines.php index 1807cfd..2e5ae54 100644 --- a/inc/defines.php +++ b/inc/defines.php @@ -27,6 +27,9 @@ if (!defined('TINYIB_SWF')) { if (!defined('TINYIB_WEBM')) { define('TINYIB_WEBM', false); } +if (!defined('TINYIB_REQMOD')) { + define('TINYIB_REQMOD', 'disable'); +} if (!defined('TINYIB_DBMIGRATE')) { define('TINYIB_DBMIGRATE', false); } diff --git a/inc/functions.php b/inc/functions.php index 39613b5..93e6b34 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -26,6 +26,8 @@ $posts_sql = "CREATE TABLE `" . TINYIB_DBPOSTS . "` ( `thumb` varchar(255) NOT NULL, `thumb_width` smallint(5) unsigned NOT NULL default '0', `thumb_height` smallint(5) unsigned NOT NULL default '0', + `stickied` tinyint(1) NOT NULL default '0', + `moderated` tinyint(1) NOT NULL default '1', PRIMARY KEY (`id`), KEY `parent` (`parent`), KEY `bumped` (`bumped`) @@ -81,7 +83,9 @@ function newPost($parent = TINYIB_NEWTHREAD) { 'image_height' => '0', 'thumb' => '', 'thumb_width' => '0', - 'thumb_height' => '0'); + 'thumb_height' => '0', + 'stickied' => '0', + 'moderated' => '1'); } function convertBytes($number) { diff --git a/inc/html.php b/inc/html.php index 8b2bad9..63eca1e 100644 --- a/inc/html.php +++ b/inc/html.php @@ -8,6 +8,12 @@ function pageHeader() { + + + + + + EOF; $return .= TINYIB_BOARDDESC . <<<EOF @@ -17,12 +23,6 @@ EOF; <link rel="stylesheet" type="text/css" href="css/futaba.css" title="Futaba"> <link rel="alternate stylesheet" type="text/css" href="css/burichan.css" title="Burichan"> <script src="js/tinyib.js"></script> - <meta http-equiv="content-type" content="text/html;charset=UTF-8"> - <meta http-equiv="cache-control" content="max-age=0"> - <meta http-equiv="cache-control" content="no-cache"> - <meta http-equiv="expires" content="0"> - <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT"> - <meta http-equiv="pragma" content="no-cache"> </head> EOF; return $return; @@ -207,10 +207,15 @@ EOF; $max_file_size_input_html = ''; $max_file_size_rules_html = ''; + $reqmod_html = ''; $filetypes_html = ''; $file_input_html = ''; $unique_posts_html = ''; + if (TINYIB_REQMOD != 'disable') { + $reqmod_html = '<li>All posts' . (TINYIB_REQMOD == 'files' ? ' with a file attached' : '') . ' will be moderated before being shown.</li>'; + } + if (TINYIB_PIC || TINYIB_WEBM || TINYIB_SWF) { if (TINYIB_MAXKB > 0) { $max_file_size_input_html = '<input type="hidden" name="MAX_FILE_SIZE" value="' . strval(TINYIB_MAXKB * 1024) . '">'; @@ -303,6 +308,7 @@ EOF; <tr> <td colspan="2" class="rules"> <ul> + $reqmod_html $filetypes_html $max_file_size_rules_html $thumbnails_html @@ -642,8 +648,41 @@ function manageStatus() { EOF; } + $reqmod_html = ''; + + if (TINYIB_REQMOD != 'disable') { + $reqmod_post_html = ''; + + $reqmod_posts = latestPosts(false); + foreach ($reqmod_posts as $post) { + if ($reqmod_post_html != '') { + $reqmod_post_html .= '<tr><td colspan="2"><hr></td></tr>'; + } + $reqmod_post_html .= '<tr><td>' . buildPost($post, TINYIB_INDEXPAGE) . '</td><td valign="top" align="right"> + <table border="0"><tr><td> + <form method="get" action="?"><input type="hidden" name="manage" value=""><input type="hidden" name="approve" value="' . $post['id'] . '"><input type="submit" value="Approve" class="managebutton"></form> + </td><td> + <form method="get" action="?"><input type="hidden" name="manage" value=""><input type="hidden" name="moderate" value="' . $post['id'] . '"><input type="submit" value="More Info" class="managebutton"></form> + </td></tr><tr><td align="right" colspan="2"> + <form method="get" action="?"><input type="hidden" name="manage" value=""><input type="hidden" name="delete" value="' . $post['id'] . '"><input type="submit" value="Delete" class="managebutton"></form> + </td></tr></table> + </td></tr>'; + } + + if ($reqmod_post_html != '') { + $reqmod_html = <<<EOF + <fieldset> + <legend>Pending posts</legend> + <table border="0" cellspacing="0" cellpadding="0" width="100%"> + $reqmod_post_html + </table> + </fieldset> +EOF; + } + } + $post_html = ''; - $posts = latestPosts(); + $posts = latestPosts(true); $i = 0; foreach ($posts as $post) { if ($post_html != '') { @@ -680,6 +719,8 @@ EOF; </tbody> </table> </fieldset> + + $reqmod_html <fieldset> <legend>Recent posts</legend> diff --git a/settings.default.php b/settings.default.php index 6fc6d14..75c56a0 100644 --- a/settings.default.php +++ b/settings.default.php @@ -20,6 +20,7 @@ define('TINYIB_LOGO', ""); // Logo HTML define('TINYIB_TRIPSEED', ""); // Enter some random text - Used when generating secure tripcodes - Must not change once set define('TINYIB_ADMINPASS', ""); // Text entered at the manage prompt to gain administrator access define('TINYIB_MODPASS', ""); // Moderators only have access to delete posts ["" to disable] +define('TINYIB_REQMOD', "disable"); // Require moderation before displaying posts: disable / files / all (see README for instructions, only MySQL is supported) define('TINYIB_DBMODE', "flatfile"); // Choose: flatfile / mysql / mysqli / sqlite / pdo (flatfile is not recommended for popular sites) define('TINYIB_DBMIGRATE', false); // Enable database migration tool (see README for instructions)