# Comments Blacklist 0.8.2 # by Michael Park Source: http://www.michaelpark.net/b2hacks/blacklist.txt With this hack, you can easily ban specific IPs that leave junk comments from your administrative page. You can also manage them from a seperate "blacklist" page (like the catagory page). You can search by words. Uses a seperate database table to store/retrieve banned IPs. Its greatest feature is the blacklist page where you can list a banned IPs comments and delete them all in three clicks. (Don't believe me? "See comments", "Check all", "Delete") Comments blacklist (aka b2blacklist) is also a feature of b2CRC's b2 Anti-Spam package; http://www.sigg3.net/cafelog/files/b2anti-spam.zip Check source above for newer releases. This one was updated 2nd of January 2006. //Comments Blacklist 0.8.2 for b2 //by Michael Park (www.michaelpark.net) // //Everything in between "//[code]" are actual codes -- old and new. // //CHANGELOG // //0.8.2: Optimized the URL check of Step 4 and fixed a small bug in "Delete Comments" section of Step 6. // //0.8.0: Implemented a smarter URL matching (step 4). // //0.7.9: Added a "Show ALL Comments" action and an associated button to the default action/form (step 6). // //0.7.8: Now blocks one URL per IP // -- added a new field to the database; // -- updated steps: 1, 3, 4, 5, and 6 // Replace the entire contents of your "b2blacklist.php" file. // //BUGFIX: The "addtolist" option of word search wasn't working properly (step 6; "delete comments"). // //0.7.5: Fixed a bug with highlighting multiple words (step 6; "word search"). // Fixed a bug with the pattern for words filter (step 6; "word search"). // Restricted the MySQL version check to be executed only once by passing it to the URI (step 6; "word search"). // Other minor changes. // //0.7.2: Added a MySQL version check // -- if it's 4 or higher, "word search" should be a little faster // and lessen the load on your database (step 6). // Added direct links to comments for both "word search" and "show comments" (step 6). // Replace the entire contents of your "b2blacklist.php" file. // //0.7.0: Totally re-wrote the "word search" action (step 6) // -- implemented a "paging system"; // -- invalid characters are now filtered out automatically; // -- highlights now use b2's CSS; // -- removed the ">2 characters" restriction; // -- other minor changes. // Replace the entire contents of your "b2blacklist.php" file. // //0.6.5: Improved the "word search" by using REGRXP operator (step 6); // other minor changes. // //0.6.3: Added a couple of options: condition and sort (step 6); // //0.6.1: Added an input validation to the "word search" (step 6). // //0.6.r: Major bugs fixed // -- in "delete comments" action (step 6); // -- in JavaScript (step 8). // Replace the entire contents of your "b2blacklist.php" file and JavaScript. // //0.6.0: Added a new "search by words" capability (I got the idea from Steve M.) // -- now you can search using one or more words; // -- deleting comments from a word search automatically adds its IP to the blacklist; // -- you can choose the condition (AND/OR) of the query; // -- other minor changes. // Replace the entire contents of your "b2blacklist.php" file. // //0.5.3: Added step 9 (optional) // -- ban those blacklisted IPs from viewing your blog. // //0.5.2: Slightly improved the "search by IP and name" option by using wildcards [%$name%] (step 6; line 204). // //0.5.1: Added a confirmation box for the "Delete" button under the "default" action (step 6) // -- initial script and troubleshooting by Steve M. (changed the name of the form); // -- added the "deleteip" block to the JavaScript (step 8); // -- modified the JavaScript to take "this.form" method (steps 6 & 8). // //0.5.r: Took out the "datetime" field as it was not needed; instead, // IPs are now sorted by their IDs in the "default" action (step 6) // -- updated steps 1, 3, 4, and 6. // //0.5.0: Fixed the JavaScript (step 8) // -- "check all" box wasn't being checked even when all others were checked. // //0.4.9: Combined all the JavaScripts into one "blacklist" function (step 8) // -- updated the "Show Comments" action accordingly (step 6). // //0.4.8: Added a new field "datetime_added" to the database (step 1) // -- modified the default action so that the most recent entry is shown first (step 6); // -- modified the "banip" action (step 3); // -- and modified the "add" action with now() function to let it automatically insert // the current date and time (step 6). // //0.4.5: Added a new "search by IP and name" checkbox option to the default action (step 6). // Modified the "Show Comment" action to implement the option above (step 6). // Added a new row of "totalbox # comments" in the "Delete Comments" action (step 6). // Minor "bugs" fixed // -- replace the entire contents of your "b2blacklist.php" file. // //0.3.9: Changed the type, and the location, of the "(un)check all" link to a checkbox // within the "Show Comments" action (step 6). // Modified/fixed both JavaScripts (step 8). // Added one more JavaScript and corresponding event handler to checkboxes (steps 6 & 8). // Added more validation codes to the "Delete Comments" action (step 6). // More cosmetic changes. // //0.3.5: Re-worked the "add" action to validate user input (step 6). // Also added a validation code to the "Delete Comments" action (step 6). // Some cosmetic changes. // //0.3.1: Added a new "validate" JavaScript (steps 6 & 8). // //0.3.0: Added a new "page" where you can select which comments to delete (step 6) // -- replace the entire contents of your "b2blacklist.php" file. // Added Step 8: "check all/uncheck all" JavaScript. // //0.2.0: Removed the "Ban & Delete ALL" link (step 5) // Changed the "banip" action to reflect the change above (step 3). // Added a new action (Delete Comments) and a form button on the "blacklist" page (step 6): // 1. now comments can be deleted from that page; // 2. and comments are now displayed in a tabular form before they get deleted. // //0.1.6: Added a new "Ban & Delete ALL" link which will delete all comments (global) // associated with the IP you're banning (step 5). // Changed the behavior of "Ban & Delete" link which now wlll delete comments per post. // Changed the "banip" action to reflect the changes above (step 3). // //0.1.3: Added a confirmation dialog box to the "Ban & Delete" link (step 5). // Other minor stuffs. //---------------------------------------------------------------------------------------------------------------------------------> //Step 1 //Run the following SQL statement within your b2 database via phpMyAdmin -- SQL tab/page/screen (CPanel>Database>phpMyAdmin>SQL): //[code] CREATE TABLE b2blacklist ( ID int(10) NOT NULL auto_increment, IP varchar(20) NOT NULL, name tinytext NULL, URL varchar(100) NULL, PRIMARY KEY (ID), UNIQUE KEY IP (IP) ) TYPE=MyISAM; //[/code] //To upgrade from 0.7.5, use the following queries: //[code] ALTER TABLE `b2blacklist` CHANGE `ID` `ID` INT( 10 ) NOT NULL AUTO_INCREMENT; ALTER TABLE `b2blacklist` ADD `URL` VARCHAR( 100 ) NULL; //[/code] //If you don't have an access to CPanel or phpMyAdmin, save the following in a new PHP file under the b2 directory and run it: //[code] */ function add_magic_quotes($array) { foreach ($array as $k => $v) { if (is_array($v)) { $array[$k] = add_magic_quotes($v); } else { $array[$k] = addslashes($v); } } return $array; } if (!get_magic_quotes_gpc()) { $HTTP_POST_VARS = add_magic_quotes($HTTP_POST_VARS); } $b2varstoreset = array('action','standalone'); for ($i=0; $i
\n\n"; if ($query) { echo "Success!"; } else { echo mysql_error(); } break; default: $standalone=0; require_once ("./b2header.php"); if ($user_level < 9) { die("You have no right to edit the database for this blog."); } ?> COPY & PASTE the MySQL statement here:

*/ include($b2inc."/b2footer.php"); ?> //[/code] //Step 2 //Add the following line in the "b2config" file (database tables' names section): //[code] $tableblacklist = 'b2blacklist'; //[/code] //right after //[code] $tablecomments = 'b2comments'; //[/code] //Step 3 //Add a new action to the "b2edit" file: //[code] case "banip": $standalone = 1; require_once("./b2header.php"); if ($user_level == 0) { die ("Cheatin' uh ?"); } $commentIP = $HTTP_GET_VARS['commentIP']; $name = $HTTP_GET_VARS['name']; $url = $HTTP_GET_VARS['url']; $p = $HTTP_GET_VARS['p']; $iquery = "INSERT INTO $tableblacklist (IP,name,URL) VALUES ('$commentIP','$name','$url')"; mysql_query($iquery) or die("Couldn't add $commentIP: ".mysql_error()); $dquery = "DELETE FROM $tablecomments WHERE comment_post_ID='$p' AND comment_author_IP='$commentIP'"; mysql_query($dquery) or die("Oops, ".mysql_error()); header ("Location: b2edit.php?p=$p&c=1#comments"); break; //[/code] //right before //[code] default: //[/code] //Step 4 //Implement a blacklist check in the "b2comments.post" file: //[code] /* blacklist */ $blquery = "SELECT ID FROM $tableblacklist WHERE IP='$user_ip'"; if (!empty($comment_author_url)) { preg_match("/[0-9a-z]*\.?[0-9a-z]+\.[a-z]{2,4}/i", $comment_author_url, $match); $blquery .= " OR URL LIKE '%$match[0]%'"; } $blquery .= " ORDER BY ID DESC LIMIT 1"; $blresult = mysql_query($blquery); if (mysql_num_rows($blresult)) { exit("You're banned from leaving comments on this blog!"); } /* end blacklist */ //[/code] //right before //[code] /* flood-protection */ //[/code] //Step 5: Put a "Ban & Delete" link on the administrative page where comments are displayed (b2edit.showposts file): //[code] echo " - post_title."\'.\\n\\nClick OK to proceed.')\">Ban & Delete ]"; //[/code] //right after //[code] echo " - Delete]"; //[/code] //NOTE: The line above may not match exactly. Also, you might want to take the "]" (close angle bracket) out from near the end of the line above. //Step 6 //Create a new administrative page named "b2blacklist.php" with the following: //[code] */ function add_magic_quotes($array) { foreach ($array as $k => $v) { if (is_array($v)) { $array[$k] = add_magic_quotes($v); } else { $array[$k] = addslashes($v); } } return $array; } if (!get_magic_quotes_gpc()) { $HTTP_POST_VARS = add_magic_quotes($HTTP_POST_VARS); $HTTP_GET_VARS = add_magic_quotes($HTTP_GET_VARS); } $b2varstoreset = array('action','standalone','words'); for ($i=0; $i= 0)) { $valid = true; } else { $valid = false; break; } } } if ($valid) { mysql_query("INSERT INTO $tableblacklist (IP,name,URL) VALUES ('$IP','$name','$url')") or die("Couldn't add $IP: ".mysql_error()); } header("Location: $PHP_SELF"); break; case "Delete": $standalone = 1; require_once("./b2header.php"); if ($user_level < 3) { die ("Cheatin' uh ?"); } $ID = $HTTP_POST_VARS["ID"]; mysql_query("DELETE FROM $tableblacklist WHERE ID='$ID'") or die("Couldn't delete ID #$ID: ".mysql_error()); header("Location: $PHP_SELF"); break; case "Rename": require_once ("./b2header.php"); $ID = $HTTP_POST_VARS["ID"]; $query = mysql_query("SELECT * FROM $tableblacklist WHERE ID = '$ID'") or die(mysql_error()); $row = mysql_fetch_object($query); $IP = $row->IP; $name = $row->name; $url = $row->URL; $name = addslashes($name); ?>

Old IP:

Old Name:

Old URL:

"> New IP:

New Name:

New URL:

$IP: ".mysql_error()); header("Location: $PHP_SELF"); break; case "Delete Comments": require_once("./b2header.php"); if ($user_level < 3) { die ("Cheatin' uh ?"); } $delete_array = $HTTP_POST_VARS["delete_array"]; $addtolist = $HTTP_POST_VARS["addtolist"]; if ($delete_array) { echo "

Deleting...

\n"; echo "
    \n"; for ($i = 0; $i < count($delete_array); $i++) { if (is_numeric($delete_array[$i]) && $delete_array[$i] > 0) { if ($addtolist) { $squery = mysql_query("SELECT comment_author, comment_author_url, comment_author_IP FROM $tablecomments WHERE comment_ID = $delete_array[$i]"); $srow = mysql_fetch_object($squery); $iquery = mysql_query("INSERT INTO $tableblacklist (IP,name,URL) VALUES ('$srow->comment_author_IP','$srow->comment_author','$srow->comment_author_url')"); if ($iquery) { $insertmsg = " (and added ".$srow->comment_author_IP." [".$srow->comment_author." -- ".$srow->comment_author_url."] to blacklist)"; } else { $insertmsg = " (insert error: ".mysql_error().")"; } } $dquery = mysql_query("DELETE FROM $tablecomments WHERE comment_ID = $delete_array[$i]"); if ($dquery) { echo "
  1. Comment ID #".$delete_array[$i]."".$insertmsg."
  2. \n"; } } } echo "
\n"; echo "
Done!\n"; } else { echo "No selections were made!\n"; } echo "

go back"; break; case "Show Comments": require_once("./b2header.php"); if ($user_level < 3) { die ("Cheatin' uh ?"); } $blID = $HTTP_POST_VARS["ID"]; $searchboth = $HTTP_POST_VARS["searchboth"]; $query1 = mysql_query("SELECT IP, name FROM $tableblacklist WHERE ID = '$blID' LIMIT 1") or die(mysql_error()); $row = mysql_fetch_object($query1); $IP = $row->IP; $name = $row->name; $query2 = "SELECT comment_ID, comment_author, comment_content, comment_date FROM $tablecomments WHERE comment_author_IP='$IP'"; if ($searchboth && !empty($name)) { $query2 .= " OR comment_author LIKE '%$name%'"; } $query2 .= " ORDER BY comment_ID DESC"; $result = mysql_query($query2) or die(mysql_error()); $numrows = mysql_num_rows($result); if ($numrows > 0) { echo "
"; echo "\n"; echo "\n"; while ($row = mysql_fetch_object($result)) { $ID = $row->comment_ID; $author = $row->comment_author; $content = stripslashes($row->comment_content); $date = $row->comment_date; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; } echo "\n"; echo "
IDAuthorCommentDateDelete?
".$ID."".$author."".$content."".$date."
Total: ".$numrows." comment(s)
\n"; echo "\n"; echo "
\n"; } else { echo "No comments with \"".$IP."\" found!\n\n"; } echo "

go back"; break; case "Show ALL Comments": require_once("./b2header.php"); if ($user_level < 3) { die ("Cheatin' uh ?"); } $query = "SELECT comment_ID, comment_author, comment_content, comment_date FROM $tablecomments ORDER BY comment_ID DESC"; $result = mysql_query($query) or die(mysql_error()); $numrows = mysql_num_rows($result); if ($numrows > 0) { echo "
"; echo "\n"; echo "\n"; while ($row = mysql_fetch_object($result)) { $ID = $row->comment_ID; $author = $row->comment_author; $content = stripslashes($row->comment_content); $date = $row->comment_date; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; } echo "\n"; echo "
IDAuthorCommentDateDelete?
".$ID."".$author."".$content."".$date."
Total: ".$numrows." comment(s)
\n"; echo "\n"; echo "add to blacklist\n"; echo "
\n"; } else { echo "No comments found!\n\n"; } echo "

go back"; break; case "Word Search": require_once("./b2header.php"); if ($user_level < 3) { die ("Cheatin' uh ?"); } $words = $HTTP_GET_VARS["words"]; $words = trim(eregi_replace("[^a-z0-9]+", " ", $words)); if (empty($words)) { echo "Enter at least one word to search for.\n"; echo "

go back"; break; } $words_array = explode(" ", $words); $condition = $HTTP_GET_VARS["condition"]; $exact = $HTTP_GET_VARS["exact"]; $limit = $HTTP_GET_VARS["limit"]; $sort = $HTTP_GET_VARS["sort"]; $order = $HTTP_GET_VARS["order"]; for ($i = 0; $i < count($words_array); $i++) { if ($i > 0) { $blwhere .= ' '.$condition.' '; } if ($exact) { $query_pattern = '[[:<:]]'.$words_array[$i].'[[:>:]]'; $eregi_pattern[$i] = $query_pattern; $blwhere .= 'comment_content REGEXP \''.$query_pattern.'\''; } else { $query_pattern = $words_array[$i]; $eregi_pattern[$i] = $query_pattern; $blwhere .= 'comment_content LIKE \'%'.$query_pattern.'%\''; } } if (!isset($HTTP_GET_VARS["page"])) { $page = 1; } else { $page = $HTTP_GET_VARS["page"]; } if (!isset($HTTP_GET_VARS["mysql_version"])) { $mysql_version = substr(mysql_result(mysql_query("SELECT VERSION()"),0),0,1); } else { $mysql_version = $HTTP_GET_VARS["mysql_version"]; } $startrow = ($page * $limit) - $limit; $query = "SELECT"; if ($mysql_version > 3) { $query .= " SQL_CALC_FOUND_ROWS"; } $query .= " comment_ID, comment_post_ID, comment_author, comment_author_IP, comment_content, comment_date FROM $tablecomments WHERE ". $blwhere." ORDER BY ".$order." ".$sort." LIMIT ".$startrow.",".$limit; $result = mysql_query($query) or die($query."
".mysql_error()); if ($result) { if ($mysql_version > 3) { $querycount = mysql_result(mysql_query("SELECT FOUND_ROWS()"),0); } else { $querycount = mysql_result(mysql_query("SELECT COUNT(comment_ID) FROM ".$tablecomments." WHERE ".$blwhere),0); } } if ($querycount > 0) { echo "
\n"; echo "\n"; echo "\n"; while ($row = mysql_fetch_object($result)) { $ID = $row->comment_ID; $post_ID = $row->comment_post_ID; $IP = $row->comment_author_IP; $author = $row->comment_author; $content = strip_tags(stripslashes($row->comment_content)); $date = $row->comment_date; for ($i = 0; $i < count($words_array); $i++) { $content = eregi_replace($eregi_pattern[$i], "".$words_array[$i]."", $content); } echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; $count++; } $count += $startrow; echo "\n"; echo "
IPAuthorCommentDateDelete?
".$IP."".$author."".$content."".$date."
"; echo "link
Showing: ".$startrow." - ".$count." of ".$querycount." comment(s)
\n"; echo "\n"; echo "add to blacklist"; echo "
\n\n"; $words = implode("+", $words_array); echo "
\n"; echo "Page(s): "; for ($i = 1; $i <= ceil($querycount / $limit); $i++) { if ($i <> $page) { echo "".$i." "; } else { echo $page." "; } if ($divider == $limit) { $divider = 0; echo "
\n"; } $divider++; } echo "
\n"; } else { echo "No comments with \"".$words."\" found!\n\n"; } echo "

go back"; break; default: $standalone=0; require_once ("./b2header.php"); if ($user_level < 3) { die("You have no right to edit the blacklist for this blog."); } ?>
Edit an IP and/or URL
\n"; while($row = mysql_fetch_object($query)) { echo "\t\n"; } echo "\n"; ?> search by IP & name

Add an IP

IP: | Name:
URL:

Search by word(s)

Word(s):
Condition: AND OR | exact match | show per page
Sort:

b2 Comments Blacklist by Michael Park
*/ include($b2inc."/b2footer.php"); ?> //[/code] //NOTE: Save it under the b2 root directory. //Step 7 //Put up a new link at the top of the administrative page (b2edit) pointing to the new file; //edit "b2menutop.txt" file: //[code] # b2blacklist.php Blacklist //[/code] //NOTE: Read the instructions in that file. //Step 8 //Put the following JavaScript in the "b2header" file: //[code] //[/code] //right before //[code] //[/code] //Step 9 (optional) //If you want to ban those blacklisted IPs from viewing your blog, put the following in the "blog.header" file: //[code] /* blacklist */ $blquery = mysql_query("SELECT ID FROM $tableblacklist WHERE IP='$REMOTE_ADDR' ORDER BY ID DESC LIMIT 1"); if (mysql_num_rows($blquery)) { exit("You're banned from this blog!"); } //[/code] right after //[code] dbconnect(); //[/code] //Done! :)