<?php
/*
Plugin Name: ThreeStrikesSPAM
Version: 1.1 Beta
Plugin URI: http://weblogtoolscollection.com/archives/2004/09/24/three-strikes-and-out-damned-spam-out-i-say/
Description: Deter Spammers with the three strike rule. If a comment has more than x (wordpress options) number of URIs, if they have no referrer AND if they have at least one match from your spam words, deny the comment from ever touching your blog. No muss, nothing to delete.
Author: Mark Ghosh (LaughingLizard)
Author URI: http://weblogtoolscollection.com/
License: GPL
*/

/*** Configuration: Two things.
                    1) The Delete Threshold. Starts with a 3 for relatively aggresive, increase or decrease to see what works well for you
                    2) The redirect link. Spammers get redirected to http://fbi.gov by default, change as you see fit.
                I suggest using Kitten's Spam words along with this plugin ***/

        
$SpamThreshold 3;
        
$RedirectSite "http://www.fbi.gov";


/*** Nothing more to configure, this is just code ***/

//This is URL Decode, much like javascript unescape
//http://www.yuki-onna.co.uk/html/encode.html
function utf8RawUrlDecode ($source) {
    
$decodedStr '';
    
$pos 0;
    
$len strlen ($source);
    while (
$pos $len) {
        
$charAt substr ($source$pos1);
        if (
$charAt == '%') {
            
$pos++;
            
$charAt substr ($source$pos1);
            if (
$charAt == 'u') {
                
// we got a unicode character
                
$pos++;
                
$unicodeHexVal substr ($source$pos4);
                
$unicode hexdec ($unicodeHexVal);
                
$entity "&#"$unicode ';';
                
$decodedStr .= utf8_encode ($entity);
                
$pos += 4;
            }
            else {
                
// we have an escaped ascii character
                
$hexVal substr ($source$pos2);
                
$decodedStr .= chr (hexdec ($hexVal));
                
$pos += 2;
            }
        }
        else {
            
$decodedStr .= $charAt;
            
$pos++;
        }
    }
    return 
$decodedStr;
}


$strikes 0;
if ((
$_POST['comment'] && !is_array($_POST['comment'])) || ($_POST['url'] && $_POST['title'] && $_POST['excerpt'] && $_POST['blog_name'])) {
    
//Make sure the information received is parsed, cleaned and stripped correctly (from WP codebase)
    
if (!get_magic_quotes_gpc()) {
        
$_POST   add_magic_quotes($_POST);
        
$_COOKIE add_magic_quotes($_COOKIE);
    }
    
$author trim(strip_tags($_POST['author']));
    
$email trim(strip_tags($_POST['email']));
    if (
strlen($email) < 6)
        
$email '';
    
$url trim(strip_tags($_POST['url']));
    
$url = ((!stristr($url'://')) && ($url != '')) ? 'http://'.$url $url;
    if (
strlen($url) < 7)
        
$url '';
    
$comment trim($_POST['comment']);
    
$user_ip $_SERVER['REMOTE_ADDR'];
    
$comment balanceTags($comment1);
    
$comment format_to_post($comment);
    
$comment apply_filters('post_comment_text'$comment);

    
//Make sure that trackbacks are also checked
    
if ($_POST['url'] && $_POST['title'] && $_POST['excerpt'] && $_POST['blog_name']) {
        
$author trim(strip_tags($_POST['blog_name']));
        
$email trim(strip_tags($_POST['title']));
        
$url trim(strip_tags($_POST['url']));
        
$url = ((!stristr($url'://')) && ($url != '')) ? 'http://'.$url $url;
        if (
strlen($url) < 3)
            
$url '';
        
$comment trim($_POST['excerpt']);
        
$user_ip $_SERVER['REMOTE_ADDR'];
        
$comment balanceTags($comment1);
        
$comment format_to_post($comment);
        
$comment apply_filters('post_comment_text'$comment);
    }
    
    
//Make sure we check the encoded version of the comments and the URLs as well
    
$author_encoded utf8RawUrlDecode($author);
    
$email_encoded utf8RawUrlDecode($email);
    
$url_encoded utf8RawUrlDecode($url);
    
$comment_encoded utf8RawUrlDecode($comment);

    
//Strike: Check the number of links in the comment, first strike if more than one
    
if ( (count(explode('http:'$comment)) - 1) >= get_settings('comment_max_links') )
        
$strike += 1;

    
//Strike: If there is a Spam Words Match, you have two strikes
    
$words explode("\n"get_settings('moderation_keys') );
    foreach (
$words as $word) {
    
$word trim($word);
    
$pattern "#$word#i";
        if ( 
preg_match($pattern$author) ) $strike += 1;
        if ( 
preg_match($pattern$email) ) $strike += 1;
        if ( 
preg_match($pattern$url) ) $strike += 1;
        if ( 
preg_match($pattern$comment) ) $strike += 1;
        if ( 
preg_match($pattern$user_ip) ) $strike += 1;
        if ( 
preg_match($pattern$author_encoded) ) $strike += 1;
        if ( 
preg_match($pattern$email_encoded) ) $strike += 1;
        if ( 
preg_match($pattern$url_encoded) ) $strike += 1;
        if ( 
preg_match($pattern$comment_encoded) ) $strike += 1;
    }

    
//This code is from Dougal's Spam Tar Pit
    // If using moderation_keys, get the IPs and add them to the list
    
$modkeys get_settings'moderation_keys' );
    
// Got this monster regexp from http://www.regular-expressions.info/examples.html
    
$ip_regex '/^\s*(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s*$/m';
    
$mcount preg_match_all$ip_regex$modkeys$match_ips );
    
$matches $match_ips[0];
    if ( 
count$matches ) > ) {
        
// Add IP numbers found
        
foreach ( $matches as $ip ) {
            
$ip trim($ip);
            
$spammer_ips[] = "/^$ip$/";
        }
    }

    
// Strike: Match current visitor IP against banned addresses, every match is a major "strike"
    
if ( is_array$spammer_ips ) ) {
        foreach (
$spammer_ips as $ip) {
            if ( 
preg_match$ip$_SERVER['REMOTE_ADDR'] ) ) {
                
$strike += 5;
            }
        }
    }

    
//Strike: If there is no referer for the posted comment, that is, it did not come from the blog, another strike
    
if ('' == $_SERVER['HTTP_REFERER']) {
        
$strike += 1;
    }


    
//This is where the strikes are processed.
    
if ($strike >= $SpamThreshold) {
        
header("Location: $RedirectSite");
        die(
'Too Bad Spammer');
    }
}
?>