From 67483c3774a032b599a36598b9152fc5f1c55308 Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Mon, 23 Nov 2020 12:44:02 -0800 Subject: [PATCH] Support blocking keywords Resolves #122. --- README.md | 1 + imgboard.php | 104 ++++++++ inc/database/flatfile.php | 47 ++++ inc/database/flatfile_link.php | 14 ++ inc/database/mysql.php | 41 ++++ inc/database/mysql_link.php | 9 + inc/database/mysqli.php | 47 ++++ inc/database/mysqli_link.php | 10 + inc/database/pdo.php | 36 +++ inc/database/pdo_link.php | 18 ++ inc/database/sqlite.php | 36 +++ inc/database/sqlite3.php | 41 ++++ inc/database/sqlite3_link.php | 15 ++ inc/database/sqlite_link.php | 14 ++ inc/functions.php | 10 + inc/html.php | 94 +++++++- locale/en/tinyib.po | 429 +++++++++++++++++++++------------ settings.default.php | 9 +- 18 files changed, 810 insertions(+), 165 deletions(-) diff --git a/README.md b/README.md index 7720d86..963e478 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ See [TinyIB Installations](https://gitlab.com/tslocum/tinyib/wikis/Home) for dem - Reference links. `>>###` - Delete posts via password. - Report posts. + - Block keywords. - Management panel: - Administrators and moderators use separate passwords. - Moderators are only able to sticky threads, lock threads, delete posts, and approve posts when necessary. (See ``TINYIB_REQMOD``) diff --git a/imgboard.php b/imgboard.php index 30cf1f9..f19f7c6 100644 --- a/imgboard.php +++ b/imgboard.php @@ -122,6 +122,13 @@ if (TINYIB_DBMODE == 'pdo' && TINYIB_DBDRIVER == 'pgsql') { "post" integer NOT NULL, PRIMARY KEY ("id") );'; + + $keywords_sql = 'CREATE TABLE "' . TINYIB_DBKEYWORDS . '" ( + "id" bigserial NOT NULL, + "text" varchar(255) NOT NULL, + "action" varchar(255) NOT NULL, + PRIMARY KEY ("id") + );'; } else { $posts_sql = "CREATE TABLE `" . TINYIB_DBPOSTS . "` ( `id` mediumint(7) unsigned NOT NULL auto_increment, @@ -171,6 +178,13 @@ if (TINYIB_DBMODE == 'pdo' && TINYIB_DBDRIVER == 'pgsql') { `post` int(20) NOT NULL, PRIMARY KEY (`id`) )"; + + $keywords_sql = "CREATE TABLE `" . TINYIB_DBKEYWORDS . "` ( + `id` mediumint(7) unsigned NOT NULL auto_increment, + `text` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, + `action` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`id`) + )"; } // Check directories are writable by the script @@ -261,6 +275,57 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name']) if ($rawpost || !in_array('password', $hide_fields)) { $post['password'] = ($_POST['password'] != '') ? hashData($_POST['password']) : ''; } + + $report_post = false; + foreach (array($post['name'], $post['email'], $post['subject'], $post['message']) as $field) { + $keyword = checkKeywords($field); + if (empty($keyword)) { + continue; + } + + $expire = -1; + switch ($keyword['action']) { + case 'report': + $report_post = true; + break; + case 'delete': + fancyDie(__('Your post contains a blocked keyword.')); + case 'ban0': + $expire = 0; + break; + case 'ban1h': + $expire = 3600; + break; + case 'ban1d': + $expire = 86400; + break; + case 'ban2d': + $expire = 172800; + break; + case 'ban1w': + $expire = 604800; + break; + case 'ban2w': + $expire = 1209600; + break; + case 'ban1m': + $expire = 2592000; + break; + } + if ($expire >= 0) { + $ban = array(); + $ban['ip'] = $post['ip']; + $ban['expire'] = $expire > 0 ? (time() + $expire) : 0; + $ban['reason'] = 'Keyword: ' . $keyword['text']; + insertBan($ban); + + $expire_txt = ($ban['expire'] > 0) ? ('
This ban will expire ' . strftime(TINYIB_DATEFMT, $ban['expire'])) : '
This ban is permanent and will not expire.'; + $reason_txt = ($ban['reason'] == '') ? '' : ('
Reason: ' . $ban['reason']); + fancyDie('Your IP address ' . $_SERVER['REMOTE_ADDR'] . ' has been banned from posting on this image board. ' . $expire_txt . $reason_txt); + } + break; + } + $post['nameblock'] = nameBlock($post['name'], $post['tripcode'], $post['email'], time(), $rawposttext); if (isset($_POST['embed']) && trim($_POST['embed']) != '' && ($rawpost || !in_array('embed', $hide_fields))) { @@ -369,6 +434,11 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name']) $post['id'] = insertPost($post); + if ($report_post) { + $report = array('ip' => $post['ip'], 'post' => $post['id']); + insertReport($report); + } + if ($post['moderated'] == '1') { if (TINYIB_ALWAYSNOKO || strtolower($post['email']) == 'noko') { $redirect = 'res/' . ($post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent']) . '.html#' . $post['id']; @@ -495,6 +565,40 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name']) $onload = manageOnLoad('bans'); $text .= manageBanForm(); $text .= manageBansTable(); + } elseif (isset($_GET['keywords'])) { + if (isset($_POST['text']) && $_POST['text'] != '') { + if ($_GET['keywords'] > 0) { + deleteKeyword($_GET['keywords']); + } + + $keyword_exists = keywordByText($_POST['text']); + if ($keyword_exists) { + fancyDie(__('Sorry, that keyword has already been added.')); + } + + $keyword = array(); + $keyword['text'] = $_POST['text']; + $keyword['action'] = $_POST['action']; + + insertKeyword($keyword); + if ($_GET['keywords'] > 0) { + $text .= manageInfo(__('Keyword updated.')); + $_GET['keywords'] = 0; + } else { + $text .= manageInfo(__('Keyword added.')); + } + } elseif (isset($_GET['deletekeyword'])) { + deleteKeyword($_GET['deletekeyword']); + $text .= manageInfo(__('Keyword deleted.')); + } + + $onload = manageOnLoad('keywords'); + if ($_GET['keywords'] > 0) { + $text .= manageEditKeyword($_GET['keywords']); + } else { + $text .= manageEditKeyword(0); + $text .= manageKeywordsTable(); + } } else if (isset($_GET['update'])) { if (is_dir('.git')) { $git_output = shell_exec('git pull 2>&1'); diff --git a/inc/database/flatfile.php b/inc/database/flatfile.php index ac30646..05d2302 100644 --- a/inc/database/flatfile.php +++ b/inc/database/flatfile.php @@ -320,3 +320,50 @@ function deleteReportsByIP($ip) { $GLOBALS['db']->deleteWhere(REPORTS_FILE, $ipClause); } + +// Keyword functions +function keywordByID($id) { + $clause = new SimpleWhereClause(KEYWORD_ID, '=', $id, INTEGER_COMPARISON); + return convertKeywordsToSQLStyle($GLOBALS['db']->selectWhere(KEYWORDS_FILE, $clause, 1), true); +} +function keywordByText($text) { + $text = strtolower($text); + $clause = new SimpleWhereClause(KEYWORD_TEXT, '=', $text, STRING_COMPARISON); + return convertKeywordsToSQLStyle($GLOBALS['db']->selectWhere(KEYWORDS_FILE, $clause, 1), true); +} + +function allKeywords() { + $rows = $GLOBALS['db']->selectWhere(KEYWORDS_FILE, NULL, -1, new OrderBy(KEYWORD_TEXT, ASCENDING, INTEGER_COMPARISON)); + return convertKeywordsToSQLStyle($rows); +} + +function convertKeywordsToSQLStyle($keywords, $singlekeyword = false) { + $newkeywords = array(); + foreach ($keywords as $oldkeyword) { + $keyword = array(); + $keyword['id'] = $oldkeyword[KEYWORD_ID]; + $keyword['text'] = $oldkeyword[KEYWORD_TEXT]; + $keyword['action'] = $oldkeyword[KEYWORD_ACTION]; + + if ($singlekeyword) { + return $keyword; + } + $newkeywords[] = $keyword; + } + return $newkeywords; +} + +function insertKeyword($newkeyword) { + $newkeyword['text'] = strtolower($newkeyword['text']); + + $keyword = array(); + $keyword[KEYWORD_ID] = '0'; + $keyword[KEYWORD_TEXT] = $newkeyword['text']; + $keyword[KEYWORD_ACTION] = $newkeyword['action']; + + $GLOBALS['db']->insertWithAutoId(KEYWORDS_FILE, KEYWORD_ID, $keyword); +} + +function deleteKeyword($id) { + $GLOBALS['db']->deleteWhere(KEYWORDS_FILE, new SimpleWhereClause(KEYWORD_ID, '=', $id, INTEGER_COMPARISON)); +} diff --git a/inc/database/flatfile_link.php b/inc/database/flatfile_link.php index 7c696fd..bd961d7 100644 --- a/inc/database/flatfile_link.php +++ b/inc/database/flatfile_link.php @@ -45,6 +45,12 @@ define('REPORT_ID', 0); define('REPORT_IP', 1); define('REPORT_POST', 2); +// Keywords table +define('KEYWORDS_FILE', '.keywords'); +define('KEYWORD_ID', 0); +define('KEYWORD_TEXT', 1); +define('KEYWORD_ACTION', 2); + require_once 'flatfile/flatfile.php'; $db = new Flatfile(); $db->datadir = 'inc/database/flatfile/'; @@ -101,4 +107,12 @@ if (function_exists('insertPost')) { $report[REPORT_POST] = $newreport['post']; $GLOBALS['db']->insertWithAutoId(REPORTS_FILE, REPORT_ID, $report); } + + function migrateKeyword($newkeyword) { + $keyword = array(); + $keyword[KEYWORD_ID] = $newkeyword['id']; + $keyword[KEYWORD_TEXT] = $newkeyword['text']; + $keyword[KEYWORD_ACTION] = $newkeyword['action']; + $GLOBALS['db']->insertWithAutoId(KEYWORDS_FILE, KEYWORD_ID, $keyword); + } } diff --git a/inc/database/mysql.php b/inc/database/mysql.php index 38b81bc..8babfed 100644 --- a/inc/database/mysql.php +++ b/inc/database/mysql.php @@ -221,3 +221,44 @@ function deleteReportsByPost($post) { function deleteReportsByIP($ip) { mysql_query("DELETE FROM `" . TINYIB_DBREPORTS . "` WHERE `ip` = " . mysql_real_escape_string($ip) . " OR `ip` = " . mysql_real_escape_string(hashData($ip))); } + +// Keyword functions +function keywordByID($id) { + $result = mysql_query("SELECT * FROM `" . TINYIB_DBKEYWORDS . "` WHERE `id` = '" . mysql_real_escape_string($id) . "' LIMIT 1"); + if ($result) { + while ($keyword = mysql_fetch_assoc($result)) { + return $keyword; + } + } +} + +function keywordByText($text) { + $text = strtolower($text); + $result = mysql_query("SELECT * FROM `" . TINYIB_DBKEYWORDS . "` WHERE `text` = '" . mysql_real_escape_string($text) . "'"); + if ($result) { + while ($keyword = mysql_fetch_assoc($result)) { + return $keyword; + } + } + return array(); +} + +function allKeywords() { + $keywords = array(); + $result = mysql_query("SELECT * FROM `" . TINYIB_DBKEYWORDS . "` ORDER BY `text` ASC"); + if ($result) { + while ($keyword = mysql_fetch_assoc($result)) { + $keywords[] = $keyword; + } + } + return $keywords; +} + +function insertKeyword($keyword) { + $keyword['text'] = strtolower($keyword['text']); + mysql_query("INSERT INTO `" . TINYIB_DBKEYWORDS . "` (`text`, `action`) VALUES ('" . mysql_real_escape_string($keyword['text']) . "', '" . mysql_real_escape_string($keyword['action']) . "')"); +} + +function deleteKeyword($id) { + mysql_query("DELETE FROM `" . TINYIB_DBKEYWORDS . "` WHERE `id` = " . mysql_real_escape_string($id)); +} diff --git a/inc/database/mysql_link.php b/inc/database/mysql_link.php index 562000a..3fa73da 100644 --- a/inc/database/mysql_link.php +++ b/inc/database/mysql_link.php @@ -32,6 +32,11 @@ if (mysql_num_rows(mysql_query("SHOW TABLES LIKE '" . TINYIB_DBREPORTS . "'")) = mysql_query($reports_sql); } +// Create the keywords table if it does not exist +if (mysql_num_rows(mysql_query("SHOW TABLES LIKE '" . TINYIB_DBKEYWORDS . "'")) == 0) { + mysql_query($keywords_sql); +} + if (mysql_num_rows(mysql_query("SHOW COLUMNS FROM `" . TINYIB_DBPOSTS . "` LIKE 'stickied'")) == 0) { mysql_query("ALTER TABLE `" . TINYIB_DBPOSTS . "` ADD COLUMN stickied TINYINT(1) NOT NULL DEFAULT '0'"); } @@ -55,4 +60,8 @@ if (function_exists('insertPost')) { function migrateReport($report) { mysql_query("INSERT INTO " . TINYIB_DBREPORTS . " (id, ip, post) VALUES ('" . mysql_real_escape_string($report['id']) . "', '" . mysql_real_escape_string($report['ip']) . "', '" . mysql_real_escape_string($report['post']) . "')"); } + + function migrateKeyword($keyword) { + mysql_query("INSERT INTO " . TINYIB_DBKEYWORDS . " (id, text, action) VALUES ('" . mysql_real_escape_string($keyword['id']) . "', '" . mysql_real_escape_string($keyword['text']) . "', '" . mysql_real_escape_string($keyword['action']) . "')"); + } } diff --git a/inc/database/mysqli.php b/inc/database/mysqli.php index 39348ae..376d9ab 100644 --- a/inc/database/mysqli.php +++ b/inc/database/mysqli.php @@ -251,6 +251,53 @@ function deleteReportsByIP($ip) { mysqli_query($link, "DELETE FROM `" . TINYIB_DBREPORTS . "` WHERE `ip` = '" . mysqli_real_escape_string($link, $ip) . "' OR `ip` = '" . mysqli_real_escape_string($link, hashData($ip)) . "'"); } +// Keyword functions +function keywordByID($id) { + global $link; + $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBKEYWORDS . "` WHERE `id` = '" . mysqli_real_escape_string($link, $id) . "' LIMIT 1"); + if ($result) { + while ($keyword = mysqli_fetch_assoc($result)) { + return $keyword; + } + } + return array(); +} + +function keywordByText($text) { + global $link; + $text = strtolower($text); + $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBKEYWORDS . "` WHERE `text` = '" . mysqli_real_escape_string($link, $text) . "'"); + if ($result) { + while ($keyword = mysqli_fetch_assoc($result)) { + return $keyword; + } + } + return array(); +} + +function allKeywords() { + global $link; + $keywords = array(); + $result = mysqli_query($link, "SELECT * FROM `" . TINYIB_DBKEYWORDS . "` ORDER BY `text` ASC"); + if ($result) { + while ($keyword = mysqli_fetch_assoc($result)) { + $keywords[] = $keyword; + } + } + return $keywords; +} + +function insertKeyword($keyword) { + global $link; + $keyword['text'] = strtolower($keyword['text']); + mysqli_query($link, "INSERT INTO `" . TINYIB_DBKEYWORDS . "` (`text`, `action`) VALUES ('" . mysqli_real_escape_string($link, $keyword['text']) . "', '" . mysqli_real_escape_string($link, $keyword['action']) . "')"); +} + +function deleteKeyword($id) { + global $link; + mysqli_query($link, "DELETE FROM `" . TINYIB_DBKEYWORDS . "` WHERE `id` = '" . mysqli_real_escape_string($link, $id) . "'"); +} + // Utility functions function mysqli_result($res, $row, $field = 0) { $res->data_seek($row); diff --git a/inc/database/mysqli_link.php b/inc/database/mysqli_link.php index 0f6d376..5150108 100644 --- a/inc/database/mysqli_link.php +++ b/inc/database/mysqli_link.php @@ -32,6 +32,11 @@ if (mysqli_num_rows(mysqli_query($link, "SHOW TABLES LIKE '" . TINYIB_DBREPORTS mysqli_query($link, $reports_sql); } +// Create the keywords table if it does not exist +if (mysqli_num_rows(mysqli_query($link, "SHOW TABLES LIKE '" . TINYIB_DBKEYWORDS . "'")) == 0) { + mysqli_query($link, $keywords_sql); +} + if (mysqli_num_rows(mysqli_query($link, "SHOW COLUMNS FROM `" . TINYIB_DBPOSTS . "` LIKE 'stickied'")) == 0) { mysqli_query($link, "ALTER TABLE `" . TINYIB_DBPOSTS . "` ADD COLUMN stickied TINYINT(1) NOT NULL DEFAULT '0'"); } @@ -58,4 +63,9 @@ if (function_exists('insertPost')) { global $link; sqlite_query($GLOBALS["db"], "INSERT INTO " . TINYIB_DBREPORTS . " (id, ip, post) VALUES ('" . mysqli_real_escape_string($link, $report['id']) . "', '" . mysqli_real_escape_string($link, $report['ip']) . "', '" . mysqli_real_escape_string($link, $report['post']) . "')"); } + + function migrateKeyword($keyword) { + global $link; + sqlite_query($GLOBALS["db"], "INSERT INTO " . TINYIB_DBKEYWORDS . " (id, text, action) VALUES ('" . mysqli_real_escape_string($link, $keyword['id']) . "', '" . mysqli_real_escape_string($link, $keyword['text']) . "', '" . mysqli_real_escape_string($link, $keyword['action']) . "')"); + } } diff --git a/inc/database/pdo.php b/inc/database/pdo.php index 8d41165..b2c8e6f 100644 --- a/inc/database/pdo.php +++ b/inc/database/pdo.php @@ -206,3 +206,39 @@ function deleteReportsByPost($post) { function deleteReportsByIP($ip) { pdoQuery("DELETE FROM " . TINYIB_DBREPORTS . " WHERE ip = ? OR ip = ?", array($ip, hashData($ip))); } + +// Keyword functions +function keywordByID($id) { + $result = pdoQuery("SELECT * FROM " . TINYIB_DBKEYWORDS . " WHERE id = ? LIMIT 1", array($id)); + return $result->fetch(PDO::FETCH_ASSOC); +} + +function keywordByText($text) { + $text = strtolower($text); + $keywords = array(); + $results = pdoQuery("SELECT * FROM " . TINYIB_DBKEYWORDS . " WHERE text = ?", array($text)); + while ($row = $results->fetch(PDO::FETCH_ASSOC)) { + $keywords[] = $row; + } + return $keywords; +} + +function allKeywords() { + $keywords = array(); + $results = pdoQuery("SELECT * FROM " . TINYIB_DBKEYWORDS . " ORDER BY text ASC"); + while ($row = $results->fetch(PDO::FETCH_ASSOC)) { + $keywords[] = $row; + } + return $keywords; +} + +function insertKeyword($keyword) { + global $dbh; + $keyword['text'] = strtolower($keyword['text']); + $stm = $dbh->prepare("INSERT INTO " . TINYIB_DBKEYWORDS . " (text, action) VALUES (?, ?)"); + $stm->execute(array($keyword['text'], $keyword['action'])); +} + +function deleteKeyword($id) { + pdoQuery("DELETE FROM " . TINYIB_DBKEYWORDS . " WHERE id = ?", array($id)); +} diff --git a/inc/database/pdo_link.php b/inc/database/pdo_link.php index 0e809d5..60b94d7 100644 --- a/inc/database/pdo_link.php +++ b/inc/database/pdo_link.php @@ -64,6 +64,18 @@ if (!$reports_exists) { $dbh->exec($reports_sql); } +// Create the keywords table if it does not exist +if (TINYIB_DBDRIVER === 'pgsql') { + $query = "SELECT COUNT(*) FROM pg_catalog.pg_tables WHERE tablename LIKE " . $dbh->quote(TINYIB_DBKEYWORDS); + $keywords_exists = $dbh->query($query)->fetchColumn() != 0; +} else { + $dbh->query("SHOW TABLES LIKE " . $dbh->quote(TINYIB_DBKEYWORDS)); + $keywords_exists = $dbh->query("SELECT FOUND_ROWS()")->fetchColumn() != 0; +} +if (!$keywords_exists) { + $dbh->exec($keywords_sql); +} + if (TINYIB_DBDRIVER === 'pgsql') { $query = "SELECT column_name FROM information_schema.columns WHERE table_name='" . TINYIB_DBPOSTS . "' and column_name='moderated'"; $moderated_exists = $dbh->query($query)->fetchColumn() != 0; @@ -142,4 +154,10 @@ if (function_exists('insertPost')) { $stm = $dbh->prepare("INSERT INTO " . TINYIB_DBREPORTS . " (id, ip, post) VALUES (?, ?, ?)"); $stm->execute(array($report['id'], $report['ip'], $report['post'])); } + + function migrateKeyword($keyword) { + global $dbh; + $stm = $dbh->prepare("INSERT INTO " . TINYIB_DBKEYWORDS . " (id, text, action) VALUES (?, ?, ?)"); + $stm->execute(array($keyword['id'], $keyword['text'], $keyword['action'])); + } } diff --git a/inc/database/sqlite.php b/inc/database/sqlite.php index 687d1d0..a538c20 100644 --- a/inc/database/sqlite.php +++ b/inc/database/sqlite.php @@ -192,3 +192,39 @@ function deleteReportsByPost($post) { function deleteReportsByIP($ip) { sqlite_query($GLOBALS["db"], "DELETE FROM " . TINYIB_DBREPORTS . " WHERE ip = '" . sqlite_escape_string($ip) . "' OR ip = '" . sqlite_escape_string(hashData($ip)) . "'"); } + +// Keyword functions +function keywordByID($id) { + $result = sqlite_fetch_all(sqlite_query($GLOBALS["db"], "SELECT * FROM " . TINYIB_DBKEYWORDS . " WHERE id = '" . sqlite_escape_string($id) . "' LIMIT 1"), SQLITE_ASSOC); + foreach ($result as $keyword) { + return $keyword; + } + return array(); +} + +function keywordByText($text) { + $text = strtolower($text); + $result = sqlite_fetch_all(sqlite_query($GLOBALS["db"], "SELECT * FROM " . TINYIB_DBKEYWORDS . " WHERE text = '" . sqlite_escape_string($text) . "'"), SQLITE_ASSOC); + foreach ($result as $keyword) { + return $keyword; + } + return array(); +} + +function allKeywords() { + $keywords = array(); + $result = sqlite_fetch_all(sqlite_query($GLOBALS["db"], "SELECT * FROM " . TINYIB_DBKEYWORDS . " ORDER BY text ASC"), SQLITE_ASSOC); + foreach ($result as $keyword) { + $keywords[] = $keyword; + } + return $keywords; +} + +function insertKeyword($keyword) { + $keyword['text'] = strtolower($keyword['text']); + sqlite_query($GLOBALS["db"], "INSERT INTO " . TINYIB_DBKEYWORDS . " (text, action) VALUES ('" . sqlite_escape_string($keyword['text']) . "', '" . sqlite_escape_string($keyword['action']) . "')"); +} + +function deleteKeyword($id) { + sqlite_query($GLOBALS["db"], "DELETE FROM " . TINYIB_DBKEYWORDS . " WHERE id = " . sqlite_escape_string($id)); +} diff --git a/inc/database/sqlite3.php b/inc/database/sqlite3.php index 8e57131..2edcf1b 100644 --- a/inc/database/sqlite3.php +++ b/inc/database/sqlite3.php @@ -221,3 +221,44 @@ function deleteReportsByIP($ip) { global $db; $db->exec("DELETE FROM " . TINYIB_DBREPORTS . " WHERE ip = '" . $db->escapeString($ip) . "' OR ip = '" . $db->escapeString(hashData($ip)) . "'"); } + +// Keyword functions +function keywordByID($id) { + global $db; + $result = $db->query("SELECT * FROM " . TINYIB_DBKEYWORDS . " WHERE id = '" . $db->escapeString($id) . "' LIMIT 1"); + while ($keyword = $result->fetchArray()) { + return $keyword; + } + return array(); +} + +function keywordByText($text) { + global $db; + $text = strtolower($text); + $result = $db->query("SELECT * FROM " . TINYIB_DBKEYWORDS . " WHERE text = '" . $db->escapeString($text) . "'"); + while ($keyword = $result->fetchArray()) { + return $keyword; + } + return array(); +} + +function allKeywords() { + global $db; + $keywords = array(); + $result = $db->query("SELECT * FROM " . TINYIB_DBKEYWORDS . " ORDER BY text ASC"); + while ($keyword = $result->fetchArray()) { + $keywords[] = $keyword; + } + return $keywords; +} + +function insertKeyword($keyword) { + global $db; + $keyword['text'] = strtolower($keyword['text']); + $db->exec("INSERT INTO " . TINYIB_DBKEYWORDS . " (text, action) VALUES ('" . $db->escapeString($keyword['text']) . "', '" . $db->escapeString($keyword['action']) . "')"); +} + +function deleteKeyword($id) { + global $db; + $db->exec("DELETE FROM " . TINYIB_DBKEYWORDS . " WHERE id = " . $db->escapeString($id)); +} diff --git a/inc/database/sqlite3_link.php b/inc/database/sqlite3_link.php index ff5287a..e64943e 100644 --- a/inc/database/sqlite3_link.php +++ b/inc/database/sqlite3_link.php @@ -66,6 +66,16 @@ if (!$result->fetchArray()) { )"); } +// Create the keywords table if it does not exist +$result = $db->query("SELECT name FROM sqlite_master WHERE type='table' AND name='" . TINYIB_DBKEYWORDS . "'"); +if (!$result->fetchArray()) { + $db->exec("CREATE TABLE " . TINYIB_DBKEYWORDS . " ( + id INTEGER PRIMARY KEY, + text TEXT NOT NULL, + action TEXT NOT NULL + )"); +} + // Add moderated column if it isn't present @$db->exec("ALTER TABLE " . TINYIB_DBPOSTS . " ADD COLUMN moderated INTEGER NOT NULL DEFAULT '0'"); @@ -93,4 +103,9 @@ if (function_exists('insertPost')) { global $db; $db->exec("INSERT INTO " . TINYIB_DBREPORTS . " (id, ip, post) VALUES ('" . $db->escapeString($report['id']) . "', '" . $db->escapeString($report['ip']) . "', '" . $db->escapeString($report['post']) . "')"); } + + function migrateKeyword($keyword) { + global $db; + $db->exec("INSERT INTO " . TINYIB_DBKEYWORDS . " (id, text, action) VALUES ('" . $db->escapeString($keyword['id']) . "', '" . $db->escapeString($keyword['text']) . "', '" . $db->escapeString($keyword['action']) . "')"); + } } diff --git a/inc/database/sqlite_link.php b/inc/database/sqlite_link.php index 0820cca..1b1f6fb 100644 --- a/inc/database/sqlite_link.php +++ b/inc/database/sqlite_link.php @@ -65,6 +65,16 @@ if (sqlite_num_rows($result) == 0) { )"); } +// Create the keywords table if it does not exist +$result = sqlite_query($db, "SELECT name FROM sqlite_master WHERE type='table' AND name='" . TINYIB_DBKEYWORDS . "'"); +if (sqlite_num_rows($result) == 0) { + sqlite_query($db, "CREATE TABLE " . TINYIB_DBKEYWORDS . " ( + id INTEGER PRIMARY KEY, + text TEXT NOT NULL, + action TEXT NOT NULL + )"); +} + // Add moderated column if it isn't present sqlite_query($db, "ALTER TABLE " . TINYIB_DBPOSTS . " ADD COLUMN moderated INTEGER NOT NULL DEFAULT '0'"); @@ -89,4 +99,8 @@ if (function_exists('insertPost')) { function migrateReport($report) { sqlite_query($GLOBALS["db"], "INSERT INTO " . TINYIB_DBREPORTS . " (id, ip, post) VALUES ('" . sqlite_escape_string($report['id']) . "', '" . sqlite_escape_string($report['ip']) . "', '" . sqlite_escape_string($report['post']) . "')"); } + + function migrateKeyword($keyword) { + sqlite_query($GLOBALS["db"], "INSERT INTO " . TINYIB_DBKEYWORDS . " (id, text, action) VALUES ('" . sqlite_escape_string($keyword['id']) . "', '" . sqlite_escape_string($keyword['text']) . "', '" . sqlite_escape_string($keyword['action']) . "')"); + } } diff --git a/inc/functions.php b/inc/functions.php index aefbd9e..41b476a 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -285,6 +285,16 @@ function checkBanned() { } } +function checkKeywords($text) { + $keywords = allKeywords(); + foreach ($keywords as $keyword) { + if (stripos($text, $keyword['text']) !== false) { + return $keyword; + } + } + return array(); +} + function checkFlood() { if (TINYIB_DELAY > 0) { $lastpost = lastPostByIP(); diff --git a/inc/html.php b/inc/html.php index 4e9283a..2694244 100644 --- a/inc/html.php +++ b/inc/html.php @@ -716,6 +716,7 @@ function adminBar() { $output = '[' . __('Status') . '] ['; if ($isadmin) { $output .= '' . __('Bans') . '] ['; + $output .= '' . __('Keywords') . '] ['; } $output .= '' . __('Moderate Post') . '] [' . __('Raw Post') . '] ['; if ($isadmin) { @@ -757,6 +758,8 @@ function manageOnLoad($page) { return ' onload="document.tinyib.managepassword.focus();"'; case 'moderate': return ' onload="document.tinyib.moderate.focus();"'; + case 'keywords': + return ' onload="document.tinyib.text.focus();"'; case 'rawpost': return ' onload="document.tinyib.message.focus();"'; case 'bans': @@ -999,6 +1002,95 @@ EOF; EOF; } +function manageEditKeyword($id) { + $id = intval($id); + + $v_text = ''; + $v_action = ''; + if ($id > 0) { + $keyword = keywordByID($id); + if (empty($keyword)) { + fancyDie(__("Sorry, there doesn't appear to be a keyword with that ID.")); + } + $v_text = htmlentities($keyword['text'], ENT_QUOTES); + $v_action = $keyword['action']; + } + + $txt_keyword = __('Keyword'); + $txt_keywords = __('Keywords'); + $txt_action = __('Action:'); + $txt_submit = $id > 0 ? __('Update') : __('Add'); + + $return = << +
+ $txt_keywords +

+ +
+
+
+EOF; +} + +function manageKeywordsTable() { + $text = ''; + $keywords = allKeywords(); + if (count($keywords) > 0) { + $text .= ''; + foreach ($keywords as $keyword) { + $action = ''; + switch ($keyword['action']) { + case 'report': + $action = __('Report'); + break; + case 'delete': + $action = __('Delete'); + break; + case 'ban0': + $action = __('Delete and ban permanently'); + break; + case 'ban1h': + $action = __('Delete and ban for 1 hour'); + break; + case 'ban1d': + $action = __('Delete and ban for 1 day'); + break; + case 'ban2d': + $action = __('Delete and ban for 2 days'); + break; + case 'ban1w': + $action = __('Delete and ban for 1 week'); + break; + case 'ban2w': + $action = __('Delete and ban for 2 weeks'); + break; + case 'ban1m': + $action = __('Delete and ban for 1 month'); + break; + } + $text .= ''; + } + $text .= '
' . __('Keyword') . '' . __('Action') . ' 
' . htmlentities($keyword['text']) . '' . $action . '' . __('Edit') . ' ' . __('Delete') . '
'; + } + return $text; +} + function manageStatus() { global $isadmin; $threads = countThreads(); @@ -1007,7 +1099,7 @@ function manageStatus() { $info = $threads . ' ' . plural($threads, __('thread'), __('threads')); if (TINYIB_REPORT) { - $info .= ', ' . count($reports). ' ' . plural(count($reports), __('report'), __('reports')); + $info .= ', ' . count($reports) . ' ' . plural(count($reports), __('report'), __('reports')); } $info .= ', ' . $bans . ' ' . plural($bans, __('ban'), __('bans')); diff --git a/locale/en/tinyib.po b/locale/en/tinyib.po index fa7e00f..5170635 100644 --- a/locale/en/tinyib.po +++ b/locale/en/tinyib.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2020-10-22 09:12-0700\n" -"PO-Revision-Date: 2020-10-22 09:12-0700\n" +"POT-Creation-Date: 2020-11-23 12:37-0800\n" +"PO-Revision-Date: 2020-11-23 12:37-0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: en\n" @@ -17,254 +17,290 @@ msgstr "" "X-Poedit-SearchPath-1: inc/functions.php\n" "X-Poedit-SearchPath-2: inc/html.php\n" -#: imgboard.php:60 +#: imgboard.php:46 msgid "Click here to go back" msgstr "" -#: imgboard.php:84 -msgid "TINYIB_TRIPSEED and TINYIB_ADMINPASS must be configured." -msgstr "" - -#: imgboard.php:88 -msgid "TINYIB_RECAPTCHA_SITE and TINYIB_RECAPTCHA_SECRET must be configured." -msgstr "" - -#: imgboard.php:93 imgboard.php:501 +#: imgboard.php:72 imgboard.php:614 msgid "Unknown database mode specified." msgstr "" -#: imgboard.php:190 +#: imgboard.php:183 #, php-format msgid "Directory '%s' can not be written to. Please modify its permissions." msgstr "" -#: imgboard.php:207 +#: imgboard.php:193 +msgid "TINYIB_TRIPSEED and TINYIB_ADMINPASS must be configured." +msgstr "" + +#: imgboard.php:197 +msgid "TINYIB_RECAPTCHA_SITE and TINYIB_RECAPTCHA_SECRET must be configured." +msgstr "" + +#: imgboard.php:210 msgid "Posting is currently disabled.
Please try again in a few moments." msgstr "" -#: imgboard.php:226 inc/functions.php:300 +#: imgboard.php:229 inc/functions.php:346 msgid "Invalid parent thread ID supplied, unable to create post." msgstr "" -#: imgboard.php:228 +#: imgboard.php:231 msgid "Replies are not allowed to locked threads." msgstr "" -#: imgboard.php:265 +#: imgboard.php:278 +msgid "Your post contains a blocked keyword." +msgstr "" + +#: imgboard.php:319 msgid "Embedding a URL and uploading a file at the same time is not supported." msgstr "" -#: imgboard.php:271 +#: imgboard.php:325 #, php-format msgid "Invalid embed URL. Only %s URLs are supported." msgstr "" -#: imgboard.php:275 inc/functions.php:326 inc/functions.php:566 +#: imgboard.php:329 inc/functions.php:372 inc/functions.php:612 #, php-format msgid "That file is larger than %s." msgstr "" -#: imgboard.php:280 imgboard.php:286 +#: imgboard.php:334 imgboard.php:340 msgid "Failed to download file at specified URL." msgstr "" -#: imgboard.php:308 +#: imgboard.php:362 msgid "Error while processing audio/video." msgstr "" -#: imgboard.php:315 inc/functions.php:651 inc/functions.php:662 +#: imgboard.php:369 inc/functions.php:697 inc/functions.php:708 msgid "Could not create thumbnail." msgstr "" -#: imgboard.php:338 +#: imgboard.php:392 msgid "upload a file or embed a URL" msgstr "" -#: imgboard.php:340 +#: imgboard.php:394 msgid "upload a file" msgstr "" -#: imgboard.php:342 +#: imgboard.php:396 msgid "embed a URL" msgstr "" -#: imgboard.php:345 +#: imgboard.php:399 #, php-format msgid "Please %s to start a new thread." msgstr "" -#: imgboard.php:351 +#: imgboard.php:405 #, php-format msgid "Please enter a message and/or %s." msgstr "" -#: imgboard.php:353 +#: imgboard.php:407 msgid "Please enter a message." msgstr "" -#: imgboard.php:355 +#: imgboard.php:409 #, php-format msgid "Please %s." msgstr "" -#: imgboard.php:358 +#: imgboard.php:412 #, php-format msgid "%s uploaded." msgstr "" -#: imgboard.php:363 +#: imgboard.php:417 #, php-format msgid "Your %s will be shown once it has been approved." msgstr "" -#: imgboard.php:376 +#: imgboard.php:435 msgid "Updating thread..." msgstr "" -#: imgboard.php:389 +#: imgboard.php:448 msgid "Updating index..." msgstr "" -#: imgboard.php:395 -msgid "Tick the box next to a post and click \"Delete\" to delete it." +#: imgboard.php:454 +msgid "Reporting is disabled." msgstr "" -#: imgboard.php:399 -msgid "" -"Post deletion is currently disabled.
Please try again in a few moments." -msgstr "" - -#: imgboard.php:416 -msgid "Post deleted." -msgstr "" - -#: imgboard.php:418 -msgid "Invalid password." -msgstr "" - -#: imgboard.php:421 +#: imgboard.php:459 imgboard.php:500 msgid "" "Sorry, an invalid post identifier was sent. Please go back, refresh the " "page, and try again." msgstr "" -#: imgboard.php:445 +#: imgboard.php:464 +msgid "You have already submitted a report for that post." +msgstr "" + +#: imgboard.php:470 +msgid "Post reported." +msgstr "" + +#: imgboard.php:474 +msgid "Tick the box next to a post and click \"Delete\" to delete it." +msgstr "" + +#: imgboard.php:478 +msgid "" +"Post deletion is currently disabled.
Please try again in a few moments." +msgstr "" + +#: imgboard.php:495 +msgid "Post deleted." +msgstr "" + +#: imgboard.php:497 inc/functions.php:326 +msgid "Invalid password." +msgstr "" + +#: imgboard.php:524 msgid "Rebuilt board." msgstr "" -#: imgboard.php:453 +#: imgboard.php:532 msgid "Sorry, there is already a ban on record for that IP address." msgstr "" -#: imgboard.php:462 +#: imgboard.php:541 #, php-format msgid "Ban record added for %s" msgstr "" -#: imgboard.php:468 +#: imgboard.php:547 #, php-format msgid "Ban record lifted for %s" msgstr "" -#: imgboard.php:536 +#: imgboard.php:562 +msgid "Sorry, that keyword has already been added." +msgstr "" + +#: imgboard.php:571 +msgid "Keyword updated." +msgstr "" + +#: imgboard.php:574 +msgid "Keyword added." +msgstr "" + +#: imgboard.php:578 +msgid "Keyword deleted." +msgstr "" + +#: imgboard.php:650 #, php-format msgid "Post No.%d deleted." msgstr "" -#: imgboard.php:538 imgboard.php:554 imgboard.php:563 imgboard.php:578 -#: imgboard.php:592 +#: imgboard.php:652 imgboard.php:668 imgboard.php:677 imgboard.php:692 +#: imgboard.php:706 imgboard.php:719 msgid "Sorry, there doesn't appear to be a post with that ID." msgstr "" -#: imgboard.php:552 +#: imgboard.php:666 #, php-format msgid "Post No.%d approved." msgstr "" -#: imgboard.php:581 imgboard.php:595 +#: imgboard.php:695 imgboard.php:709 msgid "Form data was lost. Please go back and try again." msgstr "" -#: inc/functions.php:127 inc/html.php:1055 +#: imgboard.php:717 +msgid "Reports cleared." +msgstr "" + +#: inc/functions.php:135 inc/html.php:1217 msgid "Anonymous" msgstr "" -#: inc/functions.php:236 +#: inc/functions.php:268 msgid "Please enter the CAPTCHA text." msgstr "" -#: inc/functions.php:238 +#: inc/functions.php:270 msgid "" "Incorrect CAPTCHA text entered. Please try again.
Click the image to " "retrieve a new CAPTCHA." msgstr "" -#: inc/functions.php:269 +#: inc/functions.php:311 #, php-format msgid "" "Please shorten your message, or post it in multiple parts. Your message is " "%1$d characters long, and the maximum allowed is %2$d." msgstr "" -#: inc/functions.php:329 +#: inc/functions.php:375 #, php-format msgid "" "The uploaded file exceeds the upload_max_filesize directive (%s) in php.ini." msgstr "" -#: inc/functions.php:332 +#: inc/functions.php:378 msgid "The uploaded file was only partially uploaded." msgstr "" -#: inc/functions.php:335 +#: inc/functions.php:381 msgid "No file was uploaded." msgstr "" -#: inc/functions.php:338 +#: inc/functions.php:384 msgid "Missing a temporary folder." msgstr "" -#: inc/functions.php:341 +#: inc/functions.php:387 msgid "Failed to write file to disk" msgstr "" -#: inc/functions.php:344 +#: inc/functions.php:390 msgid "Unable to save the uploaded file." msgstr "" -#: inc/functions.php:352 +#: inc/functions.php:398 #, php-format msgid "" "Duplicate file uploaded. That file has already been posted here." msgstr "" -#: inc/functions.php:383 +#: inc/functions.php:429 msgid "" "Unable to read the uploaded file while creating its thumbnail. A common " "cause for this is an incorrect extension when the file is actually of a " "different type." msgstr "" -#: inc/functions.php:560 +#: inc/functions.php:606 msgid "File transfer failure. Please retry the submission." msgstr "" -#: inc/functions.php:582 +#: inc/functions.php:628 msgid "" "Failed to read the MIME type and size of the uploaded file. Please retry the " "submission." msgstr "" -#: inc/functions.php:596 inc/functions.php:601 +#: inc/functions.php:642 inc/functions.php:647 msgid "Could not copy uploaded file." msgstr "" -#: inc/functions.php:607 +#: inc/functions.php:653 msgid "File transfer failure. Please go back and try again." msgstr "" -#: inc/functions.php:626 +#: inc/functions.php:672 msgid "Sorry, your video appears to be corrupt." msgstr "" @@ -278,7 +314,7 @@ msgstr "" msgid "Supported file types are %1$s and %2$s." msgstr "" -#: inc/html.php:77 inc/html.php:781 inc/html.php:819 +#: inc/html.php:77 inc/html.php:820 inc/html.php:858 msgid "Submit" msgstr "" @@ -300,7 +336,7 @@ msgstr "" msgid "Line-breaks must be specified with \"<br>\"." msgstr "" -#: inc/html.php:149 +#: inc/html.php:149 inc/html.php:795 msgid "(enter the text below)" msgstr "" @@ -359,7 +395,7 @@ msgstr "" msgid "Message" msgstr "" -#: inc/html.php:298 inc/html.php:564 +#: inc/html.php:298 inc/html.php:570 msgid "Password" msgstr "" @@ -367,326 +403,399 @@ msgstr "" msgid "(for post and file deletion)" msgstr "" -#: inc/html.php:356 +#: inc/html.php:350 inc/html.php:1033 inc/html.php:1060 +msgid "Report" +msgstr "" + +#: inc/html.php:362 msgid "Stickied" msgstr "" -#: inc/html.php:360 +#: inc/html.php:366 msgid "Locked" msgstr "" -#: inc/html.php:373 +#: inc/html.php:379 msgid "Embed:" msgstr "" -#: inc/html.php:373 +#: inc/html.php:379 msgid "File:" msgstr "" -#: inc/html.php:470 +#: inc/html.php:476 msgid "Reply" msgstr "" -#: inc/html.php:476 +#: inc/html.php:482 msgid "Post truncated. Click Reply to view." msgstr "" -#: inc/html.php:487 +#: inc/html.php:493 msgid "1 post omitted. Click Reply to view." msgstr "" -#: inc/html.php:489 +#: inc/html.php:495 #, php-format msgid "%d posts omitted. Click Reply to view." msgstr "" -#: inc/html.php:505 inc/html.php:540 inc/html.php:552 +#: inc/html.php:511 inc/html.php:546 inc/html.php:558 msgid "Catalog" msgstr "" -#: inc/html.php:515 +#: inc/html.php:521 msgid "Previous" msgstr "" -#: inc/html.php:528 +#: inc/html.php:534 msgid "Next" msgstr "" -#: inc/html.php:552 inc/html.php:554 inc/html.php:701 +#: inc/html.php:558 inc/html.php:560 inc/html.php:711 msgid "Return" msgstr "" -#: inc/html.php:554 +#: inc/html.php:560 msgid "Posting mode: Reply" msgstr "" -#: inc/html.php:562 +#: inc/html.php:568 msgid "Manage" msgstr "" -#: inc/html.php:563 +#: inc/html.php:569 msgid "Style" msgstr "" -#: inc/html.php:565 inc/html.php:979 +#: inc/html.php:571 inc/html.php:1035 inc/html.php:1063 inc/html.php:1087 +#: inc/html.php:1132 msgid "Delete" msgstr "" -#: inc/html.php:566 +#: inc/html.php:572 msgid "Delete Post" msgstr "" -#: inc/html.php:706 inc/html.php:1006 +#: inc/html.php:716 inc/html.php:1172 msgid "Status" msgstr "" -#: inc/html.php:708 +#: inc/html.php:718 msgid "Bans" msgstr "" -#: inc/html.php:710 +#: inc/html.php:719 inc/html.php:1020 +msgid "Keywords" +msgstr "" + +#: inc/html.php:721 msgid "Moderate Post" msgstr "" -#: inc/html.php:710 +#: inc/html.php:721 msgid "Raw Post" msgstr "" -#: inc/html.php:712 +#: inc/html.php:723 msgid "Rebuild All" msgstr "" -#: inc/html.php:715 +#: inc/html.php:726 inc/html.php:1022 msgid "Update" msgstr "" -#: inc/html.php:718 +#: inc/html.php:729 msgid "Migrate Database" msgstr "" -#: inc/html.php:720 +#: inc/html.php:731 msgid "Log Out" msgstr "" -#: inc/html.php:726 +#: inc/html.php:737 msgid "Manage mode" msgstr "" -#: inc/html.php:758 +#: inc/html.php:771 msgid "Log In" msgstr "" -#: inc/html.php:759 +#: inc/html.php:772 msgid "Enter an administrator or moderator password" msgstr "" -#: inc/html.php:775 +#: inc/html.php:814 msgid "Add a ban" msgstr "" -#: inc/html.php:776 inc/html.php:805 +#: inc/html.php:815 inc/html.php:844 msgid "IP Address" msgstr "" -#: inc/html.php:777 +#: inc/html.php:816 msgid "Expire(sec)" msgstr "" -#: inc/html.php:778 inc/html.php:805 +#: inc/html.php:817 inc/html.php:844 msgid "Reason" msgstr "" -#: inc/html.php:779 +#: inc/html.php:818 msgid "never" msgstr "" -#: inc/html.php:780 +#: inc/html.php:819 msgid "optional" msgstr "" -#: inc/html.php:782 +#: inc/html.php:821 msgid "1 hour" msgstr "" -#: inc/html.php:783 +#: inc/html.php:822 msgid "1 day" msgstr "" -#: inc/html.php:784 +#: inc/html.php:823 msgid "2 days" msgstr "" -#: inc/html.php:785 +#: inc/html.php:824 msgid "1 week" msgstr "" -#: inc/html.php:786 +#: inc/html.php:825 msgid "2 weeks" msgstr "" -#: inc/html.php:787 +#: inc/html.php:826 msgid "1 month" msgstr "" -#: inc/html.php:805 +#: inc/html.php:844 msgid "Set At" msgstr "" -#: inc/html.php:805 +#: inc/html.php:844 msgid "Expires" msgstr "" -#: inc/html.php:807 +#: inc/html.php:846 msgid "Does not expire" msgstr "" -#: inc/html.php:809 +#: inc/html.php:848 msgid "lift" msgstr "" -#: inc/html.php:817 +#: inc/html.php:856 msgid "Moderate a post" msgstr "" -#: inc/html.php:818 +#: inc/html.php:857 msgid "Post ID" msgstr "" -#: inc/html.php:820 +#: inc/html.php:859 msgid "Tip:" msgstr "" -#: inc/html.php:821 +#: inc/html.php:860 msgid "" "While browsing the image board, you can easily moderate a post if you are " "logged in." msgstr "" -#: inc/html.php:822 +#: inc/html.php:861 msgid "" "Tick the box next to a post and click \"Delete\" at the bottom of the page " "with a blank password." msgstr "" -#: inc/html.php:841 +#: inc/html.php:880 #, php-format msgid " A ban record already exists for %s" msgstr "" -#: inc/html.php:844 +#: inc/html.php:883 msgid "Only an administrator may ban an IP address." msgstr "" -#: inc/html.php:846 +#: inc/html.php:885 #, php-format msgid "IP address: %s" msgstr "" -#: inc/html.php:849 +#: inc/html.php:888 msgid "This will delete the entire thread below." msgstr "" -#: inc/html.php:849 +#: inc/html.php:888 msgid "This will delete the post below." msgstr "" -#: inc/html.php:850 +#: inc/html.php:889 msgid "Thread" msgstr "" -#: inc/html.php:850 +#: inc/html.php:889 msgid "Post" msgstr "" -#: inc/html.php:856 +#: inc/html.php:895 msgid "Un-sticky" msgstr "" -#: inc/html.php:856 +#: inc/html.php:895 msgid "Sticky" msgstr "" -#: inc/html.php:857 +#: inc/html.php:896 msgid "Return this thread to a normal state." msgstr "" -#: inc/html.php:857 +#: inc/html.php:896 msgid "Keep this thread at the top of the board." msgstr "" -#: inc/html.php:871 +#: inc/html.php:910 msgid "Unlock" msgstr "" -#: inc/html.php:871 +#: inc/html.php:910 msgid "Lock" msgstr "" -#: inc/html.php:872 +#: inc/html.php:911 msgid "Allow replying to this thread." msgstr "" -#: inc/html.php:872 +#: inc/html.php:911 msgid "Disallow replying to this thread." msgstr "" -#: inc/html.php:893 +#: inc/html.php:932 #, php-format msgid "Moderating No.%d" msgstr "" -#: inc/html.php:894 +#: inc/html.php:933 inc/html.php:1055 msgid "Action" msgstr "" -#: inc/html.php:896 +#: inc/html.php:935 msgid "Delete thread" msgstr "" -#: inc/html.php:898 +#: inc/html.php:937 msgid "Delete post" msgstr "" -#: inc/html.php:900 +#: inc/html.php:939 msgid "Ban poster" msgstr "" -#: inc/html.php:951 +#: inc/html.php:944 +msgid "Clear reports" +msgstr "" + +#: inc/html.php:945 inc/html.php:1102 +msgid "report" +msgstr "" + +#: inc/html.php:945 inc/html.php:1102 +msgid "reports" +msgstr "" + +#: inc/html.php:1013 +msgid "Sorry, there doesn't appear to be a keyword with that ID." +msgstr "" + +#: inc/html.php:1019 inc/html.php:1055 +msgid "Keyword" +msgstr "" + +#: inc/html.php:1021 +msgid "Action:" +msgstr "" + +#: inc/html.php:1022 +msgid "Add" +msgstr "" + +#: inc/html.php:1036 inc/html.php:1069 +msgid "Delete and ban for 1 hour" +msgstr "" + +#: inc/html.php:1037 inc/html.php:1072 +msgid "Delete and ban for 1 day" +msgstr "" + +#: inc/html.php:1038 inc/html.php:1075 +msgid "Delete and ban for 2 days" +msgstr "" + +#: inc/html.php:1039 inc/html.php:1078 +msgid "Delete and ban for 1 week" +msgstr "" + +#: inc/html.php:1040 inc/html.php:1081 +msgid "Delete and ban for 2 weeks" +msgstr "" + +#: inc/html.php:1041 inc/html.php:1084 +msgid "Delete and ban for 1 month" +msgstr "" + +#: inc/html.php:1042 inc/html.php:1066 +msgid "Delete and ban permanently" +msgstr "" + +#: inc/html.php:1087 +msgid "Edit" +msgstr "" + +#: inc/html.php:1100 msgid "thread" msgstr "" -#: inc/html.php:951 +#: inc/html.php:1100 msgid "threads" msgstr "" -#: inc/html.php:951 +#: inc/html.php:1104 msgid "ban" msgstr "" -#: inc/html.php:951 +#: inc/html.php:1104 msgid "bans" msgstr "" -#: inc/html.php:975 +#: inc/html.php:1128 msgid "Approve" msgstr "" -#: inc/html.php:977 +#: inc/html.php:1130 msgid "More Info" msgstr "" -#: inc/html.php:985 +#: inc/html.php:1138 msgid "Pending posts" msgstr "" -#: inc/html.php:1003 +#: inc/html.php:1159 +msgid "Reported posts" +msgstr "" + +#: inc/html.php:1162 +msgid "Recent posts" +msgstr "" + +#: inc/html.php:1169 msgid "Moderate" msgstr "" -#: inc/html.php:1007 +#: inc/html.php:1173 msgid "Info" msgstr "" - -#: inc/html.php:1008 -msgid "Recent posts" -msgstr "" diff --git a/settings.default.php b/settings.default.php index eadd20c..6c6e495 100644 --- a/settings.default.php +++ b/settings.default.php @@ -101,10 +101,11 @@ define('TINYIB_RECAPTCHA_SECRET', '');// Secret key // Database // Recommended database modes from best to worst: // pdo, mysqli, mysql, sqlite3, sqlite (deprecated), flatfile (only useful if you need portability or lack any kind of database) -define('TINYIB_DBMODE', 'flatfile'); // Mode -define('TINYIB_DBMIGRATE', false); // Enable database migration tool (see README for instructions) -define('TINYIB_DBBANS', 'bans'); // Bans table name (use the same bans table across boards for global bans) -define('TINYIB_DBPOSTS', TINYIB_BOARD . '_posts'); // Posts table name +define('TINYIB_DBMODE', 'flatfile'); // Mode +define('TINYIB_DBMIGRATE', false); // Enable database migration tool (see README for instructions) +define('TINYIB_DBBANS', 'bans'); // Bans table name (use the same table across boards for global bans) +define('TINYIB_DBKEYWORDS', 'keywords'); // Keywords table name (use the same table across boards for global keywords) +define('TINYIB_DBPOSTS', TINYIB_BOARD . '_posts'); // Posts table name define('TINYIB_DBREPORTS', TINYIB_BOARD . '_reports'); // Reports table name // Database configuration - MySQL / pgSQL