wp_die

2008年04月18日

mixiチェック
これは本当に私的な技術メモです。
Wordpressに興味のない方、というよりほとんどの方は読み飛ばしてぇ!!

【技術メモ】Wordpressの重複コメント対策

困りました。
どういうことかというと...
Wordpressで、重複コメントなどがあると、強制的にWordPressのエラーページを生成してしまいます。
いろいろと調べると
「comment_flood_filter」というフィルタがあった。
リファレンスを調べてみると、

Runs when a comment flood is detected,
コメントの殺到を検知したときに実行され、
just before wp_die is called to stop the comment from being accepted.
wp_dieが実行される直前にコメントの受け入れを停止する。
Action function arguments:
実行関数の引数:
time of previous comment,time of current comment.
前のコメントの時間,カレントコメントの時間

だそうだ。
でも...重複コメントのときは...やはりwp_dieに一直線!!
困った!!

ということは...
wp_include/functions.phpのwp_dieを調べてみる。
やっぱり

バージョンごとの違いはあるものの最新の2.5を含めて、htmlを生成してdie関数で後の処理を全部殺している。
困った!!

確かにこの方法はエラー対策には確実ではある。
しかし、強制的で融通が利かない。

誰かいいアイデアはないかと調べると、WordPress本家のExtend-Ideaで「Themed Error Pages」(英語)という方法が紹介されていた。
http://hackademix.net/2007/07/31/themed-error-pages/
ドメイン名がちょっと怖いね。

このページを見ると、生成されるページの代わりに別途用意するエラーページに書き換えて、結局 dieする。
でも、この方法ではただエラーメッセージを置換しているだけで、どんなエラーメッセージになるのかは関知していない。
特定のエラーメッセージに対処したいときなどには向いていない。

そこで、同じようにfunctions.phpをハックするならば、別の方法があるのではないかと思った。

もう一度「wp_die filter」でググってみた。
http://trac.wordpress.org/ticket/6589

おぉー!! バージョン2.6用に10日前に「wp_die」が提案されている!!
wpDieFilter.patch を見る。

確かに、この方法でwp_dieフィルタは有効である。
....でも、お披露目は2.6からかぁ

しゃぁない。この方法を先に入れてみるか
これならば、特定のメッセージに対してだけ、適用するフィルタを作ることができる。
でも、ページそのものを書き換えたら、そのままdieしても大丈夫なのだろうか?

これは試すしかない!!

まず、patchの内容を目的のWordPressのfunctions.phpに入れる。
(バージョンが古いので、そのままパッチが使えません(T_T))

で、重複コメントを入れてみる。
まだフィルタを追加していないので、問題なく(?) WordPressのエラーを出した。

次に「wp_die」フィルタをadd_filterで追加してみる。
(引数を一つ増やしました!! $admin_dirです。せっかく管理画面かどうか調べているんだから)

function blv_wp_die( $message="", $title="", $admin_dir=""){
    if( !empty( $admin_dir))
        return $message;
    if( $message == __('Duplicate comment detected; it looks as though you\'ve already said that!')){
        $message = '残念!! もうコメントしたがね!!';
    }
    return $message;
}
add_filter( 'wp_die', 'blv_wp_die');

結果、
残念!! もうコメントしたがね!!

第1関門OK!!

でも、結局はエラーページはWordPressが作っている。
じゃあ、とりあえずdieしてみますか。

function blv_wp_die( $message="", $title="", $admin_dir=""){
    if( !empty( $admin_dir))
        return $message;
    if( $message == __('Duplicate comment detected; it looks as though you\'ve already said that!')){
        $message = '残念!! もうコメントしたがね!!';
        die($message);
    }
    return $message;
}
add_filter( 'wp_die', 'blv_wp_die');

よーし!!

ついでだ!!

function blv_wp_die( $message="", $title="", $admin_dir=""){
    if( !empty( $admin_dir))
        return $message;
    if( $message == __('Duplicate comment detected; it looks as though you\'ve already said that!')){
        header('Location: ../');
        die();
    }
    return $message;
}
add_filter( 'wp_die', 'blv_wp_die');

OK!!

なぜかURLはそのままだったが、行きたいページに逝ってくれた。
使える!!
ただ、もう少しエラー元を特定できればいいのに...
でも、とにかくこの方法を改良していけば、対応可能だろうなぁ

今日はこれでOKとしよう。



(20:33)