<?php
/*
Plugin Name: Anti Spam Image MySQL mod
Plugin URI: http://www.infor96.com/~nio/archives/369
Description: This plugin inserts a security image for the WP comment page, requiring the poster to enter the right characters in the image.
Author: Krazy Nio
Version: 0.5_mysql_mod
Author URI: http://www.infor96.com/~nio/
Change Log:
2006-08-06 _ck_ : mysql mod to avoid sessions and needing cookies - also bug fix for comment_type null check against pingbacks/trackbacks
2006-07-01 Fixed bug: Trackback and pingback can't work fine (thanks to Patrick & John).
2006-04-10 Fixed bug: In WordPress 1.5, update comment count will cause a database error, because the field 'comment_count' doesn't exist.
2006-04-03 Fixed bug: When zlib.output_compression is 'On', it will cause ob_start() warning. I have removed 'ob_clean()' to avoid this warning.
2006-03-15 Fixed bug: Some PHP server don't support PNG format, and I add more format(such as PNG, GIF & JPEG) supported.
Fixed bug: When security code is wrong, comment count of the post isn't rollback.
2006-01-17 The first version.
*/
if (!class_exists('AntiSpamImage')) {
// @session_start();
class AntiSpamImage
{
function AntiSpamImage()
{
global $wpdb, $table_prefix;
$wpdb->anti_spam_image = $table_prefix . 'anti_spam_image';
add_action('activate_'.preg_replace('/^.*wp-content[\\\\\/]plugins[\\\\\/]/', '',__FILE__),array(&$this, 'create_anti_spam_image_table'));
add_action('comment_form', array(&$this, 'comment_form')); //add image and input field to comment form
add_action('comment_post', array(&$this, 'comment_post')); //add post comment post security code check
}
function comment_form()
{
global $wpdb, $user_ID, $_SERVER;
// If the user is logged in, dont prompt for code
if (isset($user_ID)) {
return $post_ID;
}
?>
<div style="display: left" id="secureimgdiv">
<p>
<input type="text" name="securitycode" id="securitycode" size="30" tabindex="4" />
<label for="securitycode"><img src="<?php echo $_SERVER['PHP_SELF']; ?>?image=<?php echo time(); ?>" width="80" height="20" alt="Security Image" /> <small> (required)</small></label>
</p>
</div>
<script language="JavaScript" type="text/javascript">
var urlinput = document.getElementById("url");
var submitp = urlinput.parentNode;
var substitution2 = document.getElementById("secureimgdiv");
submitp.appendChild(substitution2, urlinput);
</script>
<?php
return $post_ID;
}
function comment_post($post_ID)
{
global $wpdb, $user_ID, $_POST, $_SESSION, $comment_type;
$securitycode = $_POST['securitycode'];
// If the user is not logged in check the security code
if ( !$user_ID && ($comment_type === '')) {
if ( '' == $securitycode ) {
$this->comment_rollback($post_ID); //roll back
die( __('Error: please enter the security code.') );
}
// if ( $_SESSION['IMAGE_CODE'] != $securitycode ) {
// if ( $_SESSION[IMAGE_CODE] != md5($securitycode) ){
if (!$this->check_anti_spam_image_code(md5($securitycode))) {
$this->comment_rollback($post_ID); //roll back
die( __('Invalid security code. Press your browsers back button and try again.') );
} else {
// unset($_SESSION['IMAGE_CODE']);
$this->delete_anti_spam_image_code(md5($securitycode));
}
}
return $post_ID;
}
function comment_rollback($post_ID)
{
global $wpdb, $wp_version;
$pid = $wpdb->get_var("SELECT comment_post_ID FROM {$wpdb->comments} WHERE comment_ID = {$post_ID}");
$wpdb->query("DELETE FROM {$wpdb->comments} WHERE comment_ID = {$post_ID}"); //roll back
if ($wp_version >= '2.0') {
$count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_post_ID = {$pid} AND comment_approved = '1'");
$wpdb->query( "UPDATE {$wpdb->posts} SET comment_count = {$count} WHERE ID = {$pid}" );
}
}
function check_anti_spam_image_code($md5_submitted_code) {
global $wpdb;
$timeout = (current_time('timestamp')-1800); // give 'em a half hour to be nice - lower if desired
$wpdb->query("DELETE FROM $wpdb->anti_spam_image WHERE timestamp < $timeout ");
$ip = $_SERVER["REMOTE_ADDR"];
// todo: add check for a single IP submitting too many codes within certain time limit
return intval($wpdb->get_var("SELECT COUNT(*) FROM $wpdb->anti_spam_image WHERE ((ip = '$ip') AND (code ='$md5_submitted_code')) LIMIT 1"));
}
function create_anti_spam_image_code($md5_generated_code) {
global $wpdb;
$ip = $_SERVER["REMOTE_ADDR"];
$timestamp = (current_time('timestamp'));
// todo: add check for a single IP requesting too many images within certain time limit
return $wpdb->query("INSERT INTO $wpdb->anti_spam_image VALUES ('$timestamp', '$ip', '$md5_generated_code')");
}
function delete_anti_spam_image_code($md5_submitted_code) {
global $wpdb;
$ip = $_SERVER["REMOTE_ADDR"];
return $wpdb->query("DELETE FROM $wpdb->anti_spam_image WHERE ((ip = '$ip') AND (code ='$md5_submitted_code'))");
}
function create_anti_spam_image_table() {
global $wpdb;
include_once(ABSPATH.'/wp-admin/upgrade-functions.php');
$wpdb->query("DROP TABLE IF EXISTS $wpdb->anti_spam_image");
$create_table = "CREATE TABLE $wpdb->anti_spam_image (".
" timestamp int(15) NOT NULL default '0',".
" ip varchar(40) NOT NULL default '',".
" code varchar(255) NOT NULL default '')";
maybe_create_table($wpdb->anti_spam_image, $create_table);
}
} ///:~
} //end if
$secimg = new AntiSpamImage();
if (isset($_GET['image']) && preg_match('/^[0-9]+$/', $_GET['image'])) { //display image
//@ob_clean();
//@session_start();
// $_SESSION['IMAGE_CODE'] = str_replace(array('0', 'o'), array('1', 'p'), strtolower(substr(md5(rand()), 20, 4)));
// $char = $_SESSION['IMAGE_CODE'];
$char = str_replace(array('0', 'o'), array('1', 'p'), strtolower(substr(md5(rand()), 20, 4)));
// $_SESSION[IMAGE_CODE] = md5($char);
$secimg->create_anti_spam_image_code(md5($char));
$im = @imagecreate (80, 20)
or die ("Cannot initialize new GD image stream!");
$background_color = imagecolorallocate ($im, 232, 238, 247);
//random points
for ($i = 0; $i <= 128; $i++) {
$point_color = imagecolorallocate ($im, rand(0,255), rand(0,255), rand(0,255));
imagesetpixel($im, rand(2,128), rand(2,38), $point_color);
}
//output characters
for ($i = 0; $i < strlen($char); $i++) {
$text_color = imagecolorallocate ($im, rand(0,255), rand(0,128), rand(0,255));
$x = 5 + $i * 20;
$y = rand(1, 4);
imagechar ($im, 5, $x, $y, $char{$i}, $text_color);
}
//ouput PNG
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// HTTP/1.1
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
// HTTP/1.0
header("Pragma: no-cache");
// Let it more flexible!
if (function_exists("imagepng")) {
header("Content-type: image/png");
imagepng($im);
} elseif (function_exists("imagegif")) {
header("Content-type: image/gif");
imagegif($im);
} elseif (function_exists("imagejpeg")) {
header("Content-type: image/jpeg");
imagejpeg($im);
} else {
die("No image support in this PHP server!");
}
imagedestroy ($im);
exit;
} //end if
?>