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 = <<
+
+
+EOF;
+}
+
+function manageKeywordsTable() {
+ $text = '';
+ $keywords = allKeywords();
+ if (count($keywords) > 0) {
+ $text .= '
' . __('Keyword') . '
' . __('Action') . '
';
+ 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 .= '