wp_allow_comment()
云策文档标注
概述
wp_allow_comment() 函数用于验证评论是否被允许提交,主要执行重复评论检测和评论洪水检查。它根据参数决定在评论被拒绝时返回 WP_Error 对象或执行 wp_die()。
关键要点
- 函数接收两个参数:$commentdata(必需,包含评论信息的数组)和 $wp_error(可选,布尔值,默认为 false)。
- 通过数据库查询检测重复评论,使用 duplicate_comment_id 过滤器可调整重复评论的判定。
- 触发 check_comment_flood 动作钩子进行评论洪水检查,wp_is_comment_flood 过滤器可自定义洪水检测逻辑。
- 返回值:允许的评论返回批准状态(0、1、'spam' 或 'trash'),若 $wp_error 为 true 且评论被拒绝则返回 WP_Error 对象。
- 相关钩子包括 check_comment_flood、comment_duplicate_message、comment_duplicate_trigger、comment_flood_message、duplicate_comment_id 和 wp_is_comment_flood。
代码示例
function wp_allow_comment( $commentdata, $wp_error = false ) {
global $wpdb;
// 重复评论检测代码
$dupe = $wpdb->prepare(
"SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ",
wp_unslash( $commentdata['comment_post_ID'] ),
wp_unslash( $commentdata['comment_parent'] ),
wp_unslash( $commentdata['comment_author'] )
);
// 更多代码...
if ( $dupe_id ) {
if ( $wp_error ) {
return new WP_Error( 'comment_duplicate', $comment_duplicate_message, 409 );
} else {
wp_die( $comment_duplicate_message, 409 );
}
}
// 评论洪水检查
do_action( 'check_comment_flood', $commentdata['comment_author_IP'], $commentdata['comment_author_email'], $commentdata['comment_date_gmt'], $wp_error );
$is_flood = apply_filters( 'wp_is_comment_flood', false, $commentdata['comment_author_IP'], $commentdata['comment_author_email'], $commentdata['comment_date_gmt'], $wp_error );
if ( $is_flood ) {
return new WP_Error( 'comment_flood', $comment_flood_message, 429 );
}
return wp_check_comment_data( $commentdata );
}注意事项
- 在 WordPress 5.5.0 中,参数 $avoid_die 更名为 $wp_error,以提升代码可读性。
- 函数内部使用 wp_die() 处理错误时,可通过 $args 参数控制响应行为,如 HTTP 状态码和链接。
- 开发者可通过相关过滤器和动作钩子自定义重复评论和洪水检查的逻辑及错误消息。
原文内容
Validates whether this comment is allowed to be made.
Parameters
$commentdataarrayrequired-
Contains information on the comment.
$wp_errorbooloptional-
When true, a disallowed comment will result in the function returning a WP_Error object, rather than executing wp_die() .
More Arguments from wp_die( … $args )
Arguments to control behavior. If
$argsis an integer, then it is treated as the response code.responseintThe HTTP response code. Default 200 for Ajax requests, 500 otherwise.link_urlstringA URL to include a link to. Only works in combination with $link_text.link_textstringA label for the link to include. Only works in combination with $link_url.back_linkboolWhether to include a link to go back. Default false.text_directionstringThe text direction. This is only useful internally, when WordPress is still loading and the site’s locale is not set up yet. Accepts'rtl'and'ltr'.
Default is the value of is_rtl() .charsetstringCharacter set of the HTML output. Default'utf-8'.codestringError code to use. Default is'wp_die', or the main error code if $message is a WP_Error.exitboolWhether to exit the process after completion. Default true.
Default:
false
Source
function wp_allow_comment( $commentdata, $wp_error = false ) {
global $wpdb;
/*
* Simple duplicate check.
* expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
*/
$dupe = $wpdb->prepare(
"SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ",
wp_unslash( $commentdata['comment_post_ID'] ),
wp_unslash( $commentdata['comment_parent'] ),
wp_unslash( $commentdata['comment_author'] )
);
if ( $commentdata['comment_author_email'] ) {
$dupe .= $wpdb->prepare(
'AND comment_author_email = %s ',
wp_unslash( $commentdata['comment_author_email'] )
);
}
$dupe .= $wpdb->prepare(
') AND comment_content = %s LIMIT 1',
wp_unslash( $commentdata['comment_content'] )
);
$dupe_id = $wpdb->get_var( $dupe );
/**
* Filters the ID, if any, of the duplicate comment found when creating a new comment.
*
* Return an empty value from this filter to allow what WP considers a duplicate comment.
*
* @since 4.4.0
*
* @param int $dupe_id ID of the comment identified as a duplicate.
* @param array $commentdata Data for the comment being created.
*/
$dupe_id = apply_filters( 'duplicate_comment_id', $dupe_id, $commentdata );
if ( $dupe_id ) {
/**
* Fires immediately after a duplicate comment is detected.
*
* @since 3.0.0
*
* @param array $commentdata Comment data.
*/
do_action( 'comment_duplicate_trigger', $commentdata );
/**
* Filters duplicate comment error message.
*
* @since 5.2.0
*
* @param string $comment_duplicate_message Duplicate comment error message.
*/
$comment_duplicate_message = apply_filters( 'comment_duplicate_message', __( 'Duplicate comment detected; it looks as though you’ve already said that!' ) );
if ( $wp_error ) {
return new WP_Error( 'comment_duplicate', $comment_duplicate_message, 409 );
} else {
if ( wp_doing_ajax() ) {
die( $comment_duplicate_message );
}
wp_die( $comment_duplicate_message, 409 );
}
}
/**
* Fires immediately before a comment is marked approved.
*
* Allows checking for comment flooding.
*
* @since 2.3.0
* @since 4.7.0 The `$avoid_die` parameter was added.
* @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
*
* @param string $comment_author_ip Comment author's IP address.
* @param string $comment_author_email Comment author's email.
* @param string $comment_date_gmt GMT date the comment was posted.
* @param bool $wp_error Whether to return a WP_Error object instead of executing
* wp_die() or die() if a comment flood is occurring.
*/
do_action(
'check_comment_flood',
$commentdata['comment_author_IP'],
$commentdata['comment_author_email'],
$commentdata['comment_date_gmt'],
$wp_error
);
/**
* Filters whether a comment is part of a comment flood.
*
* The default check is wp_check_comment_flood(). See check_comment_flood_db().
*
* @since 4.7.0
* @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
*
* @param bool $is_flood Is a comment flooding occurring? Default false.
* @param string $comment_author_ip Comment author's IP address.
* @param string $comment_author_email Comment author's email.
* @param string $comment_date_gmt GMT date the comment was posted.
* @param bool $wp_error Whether to return a WP_Error object instead of executing
* wp_die() or die() if a comment flood is occurring.
*/
$is_flood = apply_filters(
'wp_is_comment_flood',
false,
$commentdata['comment_author_IP'],
$commentdata['comment_author_email'],
$commentdata['comment_date_gmt'],
$wp_error
);
if ( $is_flood ) {
/** This filter is documented in wp-includes/comment-template.php */
$comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) );
return new WP_Error( 'comment_flood', $comment_flood_message, 429 );
}
return wp_check_comment_data( $commentdata );
}
Hooks
- do_action( ‘check_comment_flood’, string $comment_author_ip, string $comment_author_email, string $comment_date_gmt, bool $wp_error )
-
Fires immediately before a comment is marked approved.
- apply_filters( ‘comment_duplicate_message’, string $comment_duplicate_message )
-
Filters duplicate comment error message.
- do_action( ‘comment_duplicate_trigger’, array $commentdata )
-
Fires immediately after a duplicate comment is detected.
- apply_filters( ‘comment_flood_message’, string $comment_flood_message )
-
Filters the comment flood error message.
- apply_filters( ‘duplicate_comment_id’, int $dupe_id, array $commentdata )
-
Filters the ID, if any, of the duplicate comment found when creating a new comment.
- apply_filters( ‘wp_is_comment_flood’, bool $is_flood, string $comment_author_ip, string $comment_author_email, string $comment_date_gmt, bool $wp_error )
-
Filters whether a comment is part of a comment flood.