WordPressのコメントを完全削除せず、ゴミ箱へ送る仕組みを理解する

コメントID・nonce・権限を確認してWordPress標準のゴミ箱へ送り復元する流れ

WordPressでコメント削除ボタンを作るとき、最初に確認したかったのは「押したら何が起きるか」でした。画面から消えるだけなのか、管理画面のゴミ箱へ移動するのか、データがすぐ消えるのかで意味が変わります。

実際に作った社内向けサイトでは、削除ボタンを押したコメントを完全削除せず、WordPressのゴミ箱へ移動する形にしました。確認文にも「ゴミ箱へ移動し、管理画面から復元できる」と表示しました。

この記事では、その中心にあるwp_trash_comment()を、最小コードから一つずつ理解します。

コメントの「削除」には2つの状態がある

利用者から見ると、コメントが画面から消えれば削除に見えます。しかし、WordPress内部では、ゴミ箱への移動と完全削除を分けて扱えます。

処理結果復元
wp_trash_comment()コメントをゴミ箱へ移す管理画面から戻せる
wp_delete_comment( $id, true )ゴミ箱を経由せず完全削除する通常は戻せない

誤操作から戻せるようにしたかったため、今回はwp_trash_comment()を選びました。

ただし、WordPressでゴミ箱が無効になっている場合は、wp_trash_comment()も完全削除を行います。公式リファレンスでは、EMPTY_TRASH_DAYSが無効な場合に完全削除へ進むことが示されています。使うサイトの設定を先に確認する必要があります。

まず関数だけを最小の形で見る

中心になる処理は次の1行です。

$comment_id = 123;
$result = wp_trash_comment( $comment_id );

$comment_idには、対象コメントを区別する番号を渡します。処理に成功するとtrue、失敗するとfalseが返ります。

この2行だけでも関数の意味は分かりますが、画面の削除ボタンから実行するには足りません。誰が、どのコメントに対して送った操作なのかを確認する必要があります。

実行場所は子テーマかサイト専用プラグインにする

次の例は、検証用サイトの子テーマfunctions.php、またはサイト専用プラグインで動かします。親テーマへ直接書くと、テーマ更新で変更が消える可能性があります。

実制作ではコメント表示の近くにボタンを置き、admin-post.phpへPOSTしました。最小構成は、ボタンを出す部分と、受け取ってゴミ箱へ移す部分に分かれます。

削除ボタンからコメントIDを送る

コメントを表示しているループの中で、次のフォームを出します。$comment_idには、その場所で表示中のコメントIDが入っている前提です。

<?php
$comment_id = get_comment_ID();

if ( current_user_can( 'edit_comment', $comment_id ) ) :
?>
    <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
        <input type="hidden" name="action" value="maniaru_trash_comment">
        <input type="hidden" name="comment_id" value="<?php echo esc_attr( $comment_id ); ?>">
        <?php wp_nonce_field( 'maniaru_trash_comment_' . $comment_id ); ?>
        <button
            type="submit"
            onclick="return confirm('このコメントをゴミ箱へ移動します。管理画面から復元できます。');"
        >ゴミ箱へ移動</button>
    </form>
<?php endif; ?>

current_user_can()は、現在ログイン中の利用者が、そのコメントを編集できるか確認します。権限がなければフォーム自体を表示しません。

wp_nonce_field()は、意図した画面から送られた操作か確認するための値をフォームへ加えます。nonceは権限確認の代わりではないため、表示側と受信側の両方で権限も確認します。

受信側で入力・nonce・権限を確認する

同じfunctions.phpまたはサイト専用プラグインへ、フォームを受け取る処理を追加します。

add_action( 'admin_post_maniaru_trash_comment', 'maniaru_handle_trash_comment' );

function maniaru_handle_trash_comment() {
    $comment_id = isset( $_POST['comment_id'] )
        ? absint( $_POST['comment_id'] )
        : 0;

    if ( ! $comment_id ) {
        wp_die( 'コメントIDを確認できませんでした。' );
    }

    check_admin_referer( 'maniaru_trash_comment_' . $comment_id );

    if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
        wp_die( 'このコメントを操作する権限がありません。', '', array( 'response' => 403 ) );
    }

    if ( ! wp_trash_comment( $comment_id ) ) {
        wp_die( 'コメントをゴミ箱へ移動できませんでした。' );
    }

    $return_url = wp_get_referer() ?: home_url( '/' );
    wp_safe_redirect( $return_url );
    exit;
}

処理の順番は次の通りです。

  1. absint()でコメントIDを0以上の整数として受け取る
  2. check_admin_referer()でフォームのnonceを確認する
  3. current_user_can()で対象コメントを操作できるか確認する
  4. wp_trash_comment()でゴミ箱へ移す
  5. 元の画面へ戻す

ボタンを隠すだけでは、受信先URLへ直接リクエストされる可能性が残ります。実際に状態を変える処理の直前でも、nonceと権限を確認します。

確認文は、実際の処理と合わせる

実制作では、削除ボタンを押した直後に確認メッセージを出しました。当初は「削除しますか」という一般的な表現でしたが、処理内容に合わせて意味を明確にしました。

このコメントをゴミ箱へ移動します。管理画面から復元できます。

「削除」という言葉だけでは、完全に消えるのか、後で戻せるのか分かりません。確認文と実際の処理を一致させることで、利用者は結果を理解してから操作できます。

成功状態を4か所で確認する

コードを保存した後は、検証用コメントで次を確認します。

  1. 権限のある利用者にだけボタンが表示される
  2. ボタンを押すと対象コメントだけが公開画面から消える
  3. WordPress管理画面の「コメント → ゴミ箱」に対象がある
  4. 復元すると、元の投稿へコメントが戻る

実際のサイトでも、削除操作の確認後にコメントがゴミ箱へ移り、管理画面から戻せることを確認しました。ここまで通して、完全削除ではないと判断できます。

うまくいかないときに見る場所

状態確認すること
ボタンが出ないログイン状態とedit_comment権限、コメントID
403になる受信側の権限判定と対象ID
nonceエラーになるwp_nonce_field()とcheck_admin_referer()の文字列
ゴミ箱に残らないEMPTY_TRASH_DAYSでゴミ箱が無効になっていないか
別のコメントが消えるフォームから送ったcomment_id

削除処理は、戻せる状態から考える

wp_trash_comment()を使う理由は、関数名が分かりやすいからだけではありません。誤操作が起きたときに、WordPress標準の管理画面から状態を確認し、復元できるからです。

対象IDを受け取る → 操作の意図を確認する → 権限を確認する → ゴミ箱へ移す → 復元まで試す。

画面から消す処理だけで終わらせず、削除後の状態と戻し方まで理解する。これが、今回コメント削除から学んだことでした。

実際にコメントの返信・編集・添付・削除を整えた流れは、社内ポータルの投稿とコメント機能を作った記録にまとめています。

参考:wp_trash_comment()|WordPress Developer Resources、current_user_can()|WordPress Developer Resources、check_admin_referer()|WordPress Developer Resources