WordPressのコメントのエンドポイントは、home_url( ‘/wp-comments-post.php’ ) であり、これを使用する場合ある程度バリデーションなどを行ってくれたり、そもそもプラグインはこれを前提としているため、基本的にはこのエンドポイントを使用することを想定している。
ただ(フックを使ってある程度は調整できるものの)HTMLの編集性が高くないため、ある程度WordPressに理解がある人であれば、自前で用意したりすることもあるだろう。
今回はそういった方向けに、実装した(けど結局使わなかった)プログラムをメモとしてここに貼り付けておく。
// functions.php
// 投稿ではコメントの表示を常にON
add_filter('comments_open', function($open, $post_id) {
if (get_post_type($post_id) === 'post') {
// return $open; // デフォルトの状態を取得
return true; // 強制的にコメントをON
}
return false; // 強制的にコメントをOFF
}, 10 , 2);
// コメントの名前を自由に変更できるようにする
add_filter('pre_comment_author_name', function ($name){
$user = wp_get_current_user();
if ($user->ID && isset($_POST['author'])) {
$name = trim(strip_tags($_POST['author']));
}
return $name;
});
// コメントのURLを自由に変更できるようにする
add_filter('pre_comment_author_url', function ($url){
$user = wp_get_current_user();
if ($user->ID && isset($_POST['url'])) {
$url = trim(strip_tags($_POST['url']));
}
return $url;
});
// コメントのメールアドレスを自由に変更できるようにする
add_filter('pre_comment_author_email', function ($email){
$user = wp_get_current_user();
if ($user->ID && isset($_POST['email'])) {
$email = trim(strip_tags($_POST['email']));
}
return $email;
});
// コメントフォームのバリデーション
// わざわざ /wp-comments-post.php でやらなくても、このレベルあれば、wp_insert_commentを使用して自前でエンドポイントを用意しPOSTリダイレクトなどを使用したほうがよいかも
add_action('pre_comment_on_post', function ($comment_post_ID) {
if (get_post_type($comment_post_ID) === 'post') {
$nonce = (isset($_POST['nonce']) ? trim($_POST['nonce']) : null);
if ( !$nonce || !wp_verify_nonce( $nonce, 'comment-nonce-' . $comment_post_ID ) ) {
wp_die('不正な操作を検知しました。');
}
// コメントの返信の返信はできないようにする
$parent = (int)$_POST['comment_parent'];
if ($parent !== 0) {
$comments = get_comments([
'comment__in' => $parent,
]);
$comment = $comments[0];
if ( $comment->parent !== 0 ) {
wp_die('不正な操作を検知しました。');
}
}
// 文字数制限
$comment_content = $_POST['comment'];
if (mb_strlen($comment_content) > 1000) {
wp_die('コメントは1000文字以内で入力してください。');
}
}
});
// コメントフォーム送信後のリダイレクト先
// これで http://localhost/2020-03/comment-page-2/#comment-18 みたいにURLにページ数がつかないようにする
add_action('comment_post', function($comment_ID, $comment_approved, $commentdata) {
// ページIDを取得
$comment = get_comment($comment_ID);
$post_id = $comment->comment_post_ID;
wp_safe_redirect(get_permalink($post_id) . '#comment-' . $comment_ID);
exit;
}, 10, 3);
// コメントにHTMLタグを挿入できないようにする
add_filter('preprocess_comment', function($data) {
global $allowedtags;
$allowedtags = array();
return $data;
});
// リンクタグの自動挿入削除
remove_filter('comment_text', 'make_clickable', 9);
// pタグの自動挿入削除
remove_filter( 'comment_text', 'wpautop', 30 );
// コメントにHTMLタグを使った際、そのまま表示
add_filter('comment_text', function($comment_content) {
if ( get_comment_type() == 'comment' ) {
$comment_content = esc_html($comment_content);
$comment_content = nl2br($comment_content);
}
return $comment_content;
}, 9);
// comments.php
// フォーム部分のみ抜粋
<div id="respond">
<form action="<?php echo home_url( '/wp-comments-post.php' ); ?>" method="post">
<?php if (isset($_GET['reply']) && $_GET['reply'] !== ''): // 返信の場合は replay パラメーターがつくかたち ?>
<input type="hidden" name="comment_parent" value="<?php echo esc_attr($_GET['reply']); ?>" />
<h3>
<strong><?php echo get_comment(strip_tags($_GET['reply']))->comment_author; ?>さんへの返信</strong>
<a class="link" href="<?php the_permalink(); ?>#respond">キャンセル</a>
</h3>
<?php else: ?>
<input type="hidden" name="comment_parent" value="0" />
<h3>コメントを書く</h3>
<?php endif; ?>
<div class="form">
<p>コメントするとご登録のユーザー名が公開されます。<br />コメントは1000文字以内で入力してください。</p>
<textarea name="comment" placeholder="コメントを書く"></textarea>
</div>
<div class="btn-outer">
<button type="submit" class="btn">送信する</button>
</div>
<input type="hidden" name="comment_post_ID" value="<?php echo get_the_ID(); ?>" />
<input type="hidden" name="author" value="<?php echo wp_get_current_user()->display_name; ?>" />
<input type="hidden" name="email" value="<?php echo wp_get_current_user()->user_email; ?>" />
<input type="hidden" name="url" value="<?php echo wp_get_current_user()->user_url; ?>" />
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'comment-nonce-' . get_the_ID() ); ?>" />
</form>
</div>
上記のHTMLでは nameが重要で、エンドポイントで処理してくれるようname属性は必ず同じように設定しなくてはならないことに注意。