Akismet de-spam view Hack と呼ばれるハック(プログラムの改造。不正アクセスではない)があります。
WordPeress のスパムブロックプラグイン Akimet の捕獲したスパム一覧で、半角英数記号以外が含まれたスパム(以下、マルチバイトスパムと表記します)が含まれているものだけ表示するようにするというものです。
大概のスパムは半角英数のみです。そして、多くの日本語サイトに届くスパムでないコメントやトラックバックは日本語によるものです。だったら、マルチバイトスパム以外を表示しなければすっきりするじゃないかというのが、このハックのコンセプトです。
また、power source*さんによる、管理画面のダッシュボードにマルチバイトスパムの捕獲数を併記するハックがあります。
今回、スパム対策の一環としてこの2つのハックを試してみました。効果抜群で、すっきりしたスパム一覧とマルチバイトスパムの捕獲数表示に喜んでおります。
お二人への感謝と還元と自分への覚書として、この2つのハックの解説をしてみたいと思います。また、思いつきで追加ハックもしました。
なお、ハックした WordPress のバージョンは2.04です。
Akismet de-spam view Hack
オリジナル
ファイル /wp-content/plugins/akismet/akismet.php の267行目。
$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT 150");
ハック
$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND LENGTH(comment_content) <> CHAR_LENGTH(comment_content) ORDER BY comment_date DESC LIMIT 150");
変更したのは、一覧に表示するデータを得る部分です。データベースサーバにスパム判定されたコメントのデータを要求しています。このハックでは、SQL の条件文(WHERE
節)にマルチバイトではないという条件を AND
で加えています。
追加部分のコード
AND LENGTH(comment_content) <> CHAR_LENGTH(comment_content)
テーブル wp_comments
のフィールド comment_content
に格納されているコメントの本文に対し、関数 LENGTH
と CHAR_LENGTH
の結果が一致していないというものです。LENGTH
はバイト数を、CHAR_LENGTH
は文字数を返します。マルチバイト文字は1文字が1バイトではないため、2つの結果は一致しません。
マルチバイトスパムの捕獲数をダッシュボードに併記するハック
オリジナル
ファイル /wp-content/plugins/akismet/akismet.php の323行目。関数 akismet_stats
付近。
function akismet_stats() {
$count = get_option('akismet_spam_count');
if ( !$count )
return;
$path = plugin_basename(__FILE__);
echo '<h3>'.__('Spam').'</h3>';
echo '<p>'.sprintf(__('<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.'), 'http://akismet.com/', "edit.php?page=$path", number_format($count) ).'</p>';
}
関数 akismet_stats
のハック
function akismet_stats() {
$count = get_option('akismet_spam_count');
// $count = ksd_spam_count();
$mbs_count = mb_spam_count();
if ( !$count )
return;
$path = plugin_basename(__FILE__);
echo '<h3>'.__('Spam').'</h3>';
echo '<p>'.sprintf(__('<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.'), 'http://akismet.com/', "edit.php?page=$path", number_format($count) ).'</p>';
if ( $mbs_count ) {
echo '<p><strong><a href="edit.php?page='.$path.'&akismet_list=mb">要チェック</a></strong>: マルチバイト文字を含むものを '.$mbs_count.' 件捕獲中です。</p>';
} else {
echo '<p>この中にマルチバイト文字を含むものはありません。</p>';
}
}
マルチバイトスパムのカウントと表示を追加しています。4行目がマルチバイトスパムのカウント、10~14行目がダッシュボードに表示する部分です。
もともとのハックではマルチバイトスパム以外も含めた捕獲数を捕獲中のものだけにしてありますが、私の好みで総数に戻してあります。捕獲中のものだけにしたい場合は、2行目のコメントアウトをはずし、3行目をコメントアウトするか削除してください。また、もとのハックではリスト表示にする変更をしてありますが、こちらも好みで段落にしてあります。
4行目で呼び出している関数 mb_spam_count
は、新たに定義したものです。関数 ksd_spam_count
に、マルチバイトであることを条件に加えたものになっています。Akismet de-spam view Hack と同様の変更です。
基本的にはどこに記述しても構いませんが、akismet_stats の近くが良いでしょう。私は akismet_stats の直後にしました。
mb_spam_count
function mb_spam_count() { // マルチバイトスパムの件数
global $wpdb, $comments;
$count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND LENGTH(comment_content) <> CHAR_LENGTH(comment_content)");
return $count;
}
ksd_spam_count
ファイル /wp-content/plugins/akismet/akismet.php の195行目。
function ksd_spam_count() {
global $wpdb, $comments;
$count = $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
return $count;
}
追加ハック
解説は以上ですが、思いつきで従来の一覧表示もできるようにしてみました。
267行目(Akismet de-spam view Hack の場所)
引数を見て、どちらの表示にするか処理を分岐させています。引数の名前は被らなければなんでもいいのですが、とりあえず akismet_spam_list としました。値が mb ならマルチバイトスパムのみ、それ以外なら従来の表示になります。
switch ($_GET['akismet_spam_list'])
{
case 'mb':
$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND LENGTH(comment_content) <> CHAR_LENGTH(comment_content) ORDER BY comment_date DESC LIMIT 150");
break;
default:
$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT 150");
}
関数 akismet_stats
せっかくなので、ダッシュボードのリンクも変更します。マルチバイトスパムがあったときの表示をする行(ハックの11行目)を、次のようにします。
echo '<p><strong><a href="edit.php?page='.$path.'&akismet_spam_list=mb">要チェック</a></strong>: マルチバイト文字を含むものを '.$mbs_count.' 件捕獲中です。</p>';
これで、要チェックのときはマルチバイトスパムだけの表示にでき、最近の傾向を見たいときなどでは従来の表示にすることができます。
参考情報
- Function Reference/wpdb Class « WordPress Codex:
- データベースアクセス用クラス
- Database Description « WordPress Codex:
- データベーステーブル