Tag Archives:


Akismet vs. Antispam Bee

How to fight off comment spammers? With a anti-spam plugin, of course. Akismet is quite popular (it’s included with WordPress, after all), but it’s got its drawbacks: It sends all data to its servers – after all, that’s how it works –, which may be a problem if you’re concerned about privacy; despite quite a goot job of detecting manual comment spam, it may cause false positives, i.e. good comments that falsely get treated as spam; newer versions fill(ed) the database with statistics even for deleted comments (latest version probably fixes this); and there are discussions about Akismet no longer being free (especially if you’re new and need an API key).

So I instead chose Antispam Bee now, which does its job very good without sending all data around, etc. (though it’s got options for IP filtering by country and more), and I’m quite satisfied with it, so it will stay.

I elaborated more on all this in the German version of this post (see link above the headline); major reason for writing an English version at all is one more thing about a plugin conflict that might be interesting to non-German-speakers:

Antispam Bee and Ajax Comment Preview

One of the Bee’s most important methods for combating spam bots is changing the name of the comment entry field – it’s no longer called comment but got a number added. (The ID is the same, so no change in accessing it with CSS.) However, this causes Ajax Comment Preview to malfunction – unless you change a bit in its JavaScript code. My solution may not be the most elegant – especially since it has to be adapted for each blog – but it works:

Replace in ajax-comment-preview.js in function send these three lines:

if ( !t.data.comment || t.oldData == $.param( t.data ) ) {
    return false; // Blank || Last AJAX request was the same, so bail on this one.

– they are at line 28 directly before the heavily-indented block that starts with jQuery.post – by these:

if (t.oldData == $.param( t.data )) { return false; } // Last AJAX request was the same, so bail on this one.
if (t.data['comment-12345']) t.data.comment = t.data['comment-12345']; //--ag for Antispam Bee
if ( !t.data.comment ) { return false; } // Blank

In this code, you must replace the highlighted number 12345 in both places with the number used on your blog – you find this by simply looking in the source code (or with FireBug or similar) of a page with a comment field, just search for a textarea with name="comment-, that should do it. (And if it won’t work right away, remember to explicitly reload the page in the browser so it loads the modified JavaScript file.)

Alright, any questions, suggestions, or opinions about my code or the plugins?

WordPress: Hint for False-Positive Spam

Paper spam ?! Another little code for the blog solution of mine that may not be perfect yet helpful…

Many encountered this problem already: A comment was erroneously marked as spam by the spam filter – the well-known Akismet (like here), another plugin or just too strict a blacklist. Such false positives happen on my blog about once every three weeks on average.

The experienced blogger or blog commenter knows that (s)he just has to wait until the blog owner (hopefully) manually approves the comment. The inexperienced commenter, however, may be at a complete loss when confronted with the top of the page that even after scrolling down does not reveal his/her comment; some may try to comment again, some may never return.

A hintful message may help – but (unlike for comments in moderation) WordPress doesn’t offer such a message. The normal loop that outputs the comments actually doesn’t know which current comment is from the caller, since the part of the URL that specifies this – #comment-123, which in particular causes the correct positioning in the browser1 – is not part of the request that’s visible to the server, but remains inside the browser.

Now one might add the comment number during the redirect after the comment posting as an & parameter to the URL (and query this in the output loop), but I somehow don’t like this method – who knows if this doesn’t cause several such URLs floating around the search engines. I found two other solutions I’d like to show you here:

Solution 1: Spam comment from the same IP address?

The first idea: Check during comment output if there’s a spammed comment from the past few minutes from the same IP address that the current request is coming from. In a function for the theme’s functions.php, this looks like this:

function ag_spammed_comment ($gotcomments) {
    global $wpdb, $post;
    $spamcom = $wpdb->get_results ("
        SELECT * FROM $wpdb->comments
        WHERE comment_post_ID = '$post->ID'
          AND comment_author_IP = '".$_SERVER['REMOTE_ADDR']."'
          AND comment_approved = 'spam'
          AND comment_type = ''
          AND TIME_TO_SEC(TIMEDIFF(NOW(),comment_date))<120");
    if ($spamcom) {
        if (!$gotcomments) echo '<ol class="commentlist">';
        foreach ($spamcom as $sc) {
            echo '<li id="comment-'.$sc->comment_ID.'" class="comment caughtasspam">'.
            '<strong>Apparently, the automatic spam filter marked your comment as spam.</strong><br/>'.
            'If this was a mistake, please be patient until the comment is approved manually.'.
        if (!$gotcomments) echo '</ol>';

Call this from comments.php with ag_spammed_comment (true); (wrapped in <?php ?>) after the output of existing comments and with false instead of true in the branch for a yet uncommented post – of course you only need this differentiation if you want to include (and style) the message in the ol/ul comment list; if you want to use a separate div block, you can do without it.

Then of course style the .caughtasspam class in your style.css accordingly (e.g. with a red frame).

However, there’s a little…

Problem: The cache

If you’re using a cache plugin such as WP Super Cache that temporarily stores generated pages, there’s the problem that such a plugin – originally appropriately – doesn’t invalidate the affected page’s cache, i.e. still delivers the same old page without the code above having a chance to print its hint.

One solution: Modify the plugin such that spam comments (not spam trackbacks) do delete the cached page. For WP Super Cache, this can be done in wp-cache-phase2.php in function wp_cache_get_postid_from_comment where after

} elseif ( $comment['comment_approved'] == 'spam' ) { 

you replace these two lines:

if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Spam comment. Don't delete any cache files.", 4 );
return $postid;

with these:

//--ag: for false-positive message
if ( $comment['comment_type'] == '' ) {
    if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Spam comment. But update cache for post $postid to allow for false-positive message.", 4 );
    return wp_cache_post_change($postid);
} else {
    if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Spam trackback. Don't delete any cache files.", 4 );
    return $postid;

Then the hint works. However at the expense of some performance if real spammers happen to try to flood a page with spam comments that is also often viewed by visitors – which, though, won’t happen that often on most blogs, I guess.

The bigger disadvantage in my opinion, however, is that you thus have (another?) plugin where you have to be careful to copy the changes to the new version during an update. Since I’d like to skip such tasks, I’m using another way:

Solution 2: JavaScript (with jQuery)

Of course this solution won’t work if the commenter has disabled JavaScript in his browser – a disadvantage I’m willing to accept, hoping this combination will be rare enough. Moreover, this solution also works if someone is using proxy servers that change on every request.

There are even two variations of this solution, the first of which I’ll only outline briefly: You use the comment_post_redirect filter (which is called in wp-comments-post.php) to modify the redirection’s target URL in case of a spam comment such that #comment-123 is replaced with something like #spammed and then use JavaScript to display (or fill) a block that’s prepared in the theme but originally set to display: none (or empty) if #spammed is part of the URL – which is something that JavaScript, unlike the server, does have access to.

Variation 2 which I’m using here works without such a filter and just looks if there’s an element named #comment-123 on the (complete loaded) page at all. If not, the message is inserted (via JavaScript to avoid it being indexed by search engines):

<div id="spammedhint" class="comment caughtasspam" style="display:none;"></div>
<script type="text/javascript">
var theUrl = document.location.toString();
if (theUrl.match("#comment-")) {
    var theHash = theUrl.substr(theUrl.indexOf("#"));
    if (jQuery(theHash).length==0) {
        jQuery(document).ready(function() {
            jQuery("#spammedhint").html("<strong>Apparently, the automatic spam filter marked your comment as spam.</strong><br/>"+
            "If this was a mistake, please be patient until the comment is approved manually.").fadeIn();
            var targetOfs = jQuery("#spammedhint").offset().top;
            jQuery("html,body").animate({scrollTop: targetOfs-20}, 500);

The presence check is done with if (jQuery(theHash).length==0), since jQuery() always returns an object, which means that if (jQuery(theHash)), which one might think of first, is always true. The last jQuery line then scrolls to the message blog (rather, a little above it) within 500 ms; I had sometimes problems with very short times, maybe because the document wasn’t all readyafter all and the browser jumped back to another position. (Maybe that only happens on a reload, though, which is often used during testing.)

I added this HTML/JS code directly (and of course not wrapped in <?php ?>) to comments.php directly after <?php if ('open' == $post->comment_status) : ?> thus directly before the output of the input fields.

Now this method has a side effect which, on one hand, unfortunately (but probably very rarely) will occur when someone got a link from somewhere with a wrong or nonsensical comment number, but on the other hand fortunately also occurs when someone bookmarked his comment that went through at first but is spammed later, since the message is shown then too.

Which also allows you to test this function easily – I prepared such a link here. :) You can also write a new comment and include “diesisteinspamtest” (German for “thisisaspamtest”) in it since I added this “word” to the blacklist. But don’t overdo it since I got to approve these comments…

So if you don’t use a cache plugin, you can easily use the first solution, otherwise you got to weigh the pros and cons; as I said I chose solution 2.

Any opinions, criticism, ideas, problems, questions…?

  1. if you got a flawed theme that doesn’t add this ID to the comments, thus causing all commenters staring at the top of the page after commenting, now’s finally the time to fix this… []

What to do with all the millions?

money suitcase Well, one keeps receiving lottery winnings from Europe and money transfer provisions from African millionaire heirs or lonely bank accounts all the time, but how to spend all the hundreds of thousands or even millions? The spammers didn’t have an answer to that question yet: No-one can take that many cheap pills to reach noticible sums, and no-one has enough space for shoe-cleaning machines or flagoples at 55% discount either.

But here’s the solution: A luxury villa in Marbella for only 890,000€, allegedly 50% below market value and for a limited time only, according to the phone number via a British estate agent – offered by spam! Your own fault if you don’t buy it, isn’t it?

I should send them the lottery notifications or transfer options, that should suffice for payment…

Photo: mikecco/sxc

Secret Wishing Woo

peek A comment spammer recently advertised something that starts with this introduction:

What enabled Barack Obama to do what was never done before? To do what some said was impossible? To break all the odds and become the first African-American President and the most powerful man in the world?

Whichever may have played a role in this – one thing it surely wasn’t, and that’s what can be purchased there as e-book: The Law of Attraction. And like that former TV producer plays her customers for suckers with her unfortunately very successful “The Secret” based on this very same bullshit1 “law”, this vendor – named Jennifer Anders, according to the Twitter name – aptly names her stuff “TheObamaSecret”. Let’s see what she’s writing:

Exclusive Offer!
For Your Eyes Only!
Never Before Revealed Information!

Wouldn’t have minded if it had stayed that way. Hopefully the “exclusive” is correct and we won’t see this thing elsewhere – though it appears like a more common offer retrofitted with Obama’s name at the beginning and the end.

1:48 PM Monday Afternoon

Dear Friend,

Strange way to date a letter-like address – and no, I’m not a friend of mystic spammers!

What would you say if I told you that there was a way to achieve anything that you had ever wanted from life just by using the power hidden within the depths of your own mind? What if I said that I could teach you how to overcome all of your inhibitions and fears and use the laws of nature to draw success to you rather than you running after it? What would you say if I said that everything that had occurred to you in your life prior to today was entirely the result of your thoughts and actions, and everything that happens to you from here on out is entirely in your hands?

What would you say if I told you that I could teach you the secret handed down from the greatest minds of all time, reaffirmed by the spiritual leaders throughout history, and that with this information you could change your very destiny?

She’s giving the answer herself right away:

You would probably tell me that I’m crazy, that I’ve been watching far too much late night television and that I should get myself to a therapist as soon as possible.

Got it!

But what if it was the truth?

Well, if ifs and ands were pots and pans… if the dog hadn’t shitted, he would’ve caught the rabbit, like my grandpa used to say. However, my dear Jennifer or whatever your name is, things don’t become true simply because as many people as possible believe in it, especially not if the only sensible method to achieve truth as objective as possible – science – says the exact opposite. And that’s what it does, no matter what you’re writing:

[…] Sound too good to be true? I know that it sounds like the kind of thing that science fiction novels are made of, but hear me out. This is an example of the power of the mind firmly rooted in scientific fact. The laws of physics applied to the metaphysical to create the perfect blend of fact and idea. A universal law finally discovered and brought into play for the men and women of earth, applying to everyone, regardless of their age, gender or race, and carrying with it guaranteed results!

The only fact here is that you’re either a liar or empty-headed if you call this balderdash scientifically rooted. Calling it a “law” won’t change that – which, by the way, was made up many decades or even centuries ago and is not at all new.

And guaranteed results? Pshaw! Only under the condition that people wish strongly enough and think the proper thoughts, which gives you secretists (like many faith healers) always a nice excuse which also becomes inhuman when it’s about sorrow and suffering – as indicated in the text:

So much suffering could be averted if the people involved only knew the power they have hidden within their own minds!

Do I have to explicitly remind you that this can also become dangerous in case of severe illness if someone relies on wishing (or any other placebo medicine) instead of getting a proper treatment?

funny-pictures-beaver-cant-hear-you But what to expect from such miracle hucksters anyway? Also when it’s about the pretended truth, you just want to ignore all who say otherwise:

I know this sounds a little hard to believe right now, but it’s the truth, it’s always been the truth and it will always be the truth, no matter how many people try to poke holes in it.

Well, let’s get down to the nitty-gritty, the money:

I don’t want this knowledge to fall back into the hands of the already wealthy and successful just because they are the only ones that can afford it, which is why I’m offering it to you at a price much lower than anything you are going to find from my competitors.

Awww, how noble of you! And even with a 90-day money back guarantee. Hope there will be no heaps of lawsuits from your competition if you happen to have copied a bit too much directly from them.

And you can even choose if that stuff is worth $9 or $14 to you:

Because some cannot afford $14, I am offering this ebook also for $9. This is one of the ways I am using the Law of Attraction to be more like President Obama and to help make this world a better place. […]
Take advantage of this once in a lifetime opportunity to learn what President Barack Obama knows. You’ll never regret it.

And again Obama’s name is abused. Hope he’ll send Jack Bauer to these wish mongers!


Photos: sonfire/sxcicanhascheezburger

  1. in the philosophical meaning according to Harry Frankfurt, see Wikipedia []