函数文档

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 $args is an integer, then it is treated as the response code.

  • response int
    The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
  • link_url string
    A URL to include a link to. Only works in combination with $link_text.
  • link_text string
    A label for the link to include. Only works in combination with $link_url.
  • back_link bool
    Whether to include a link to go back. Default false.
  • text_direction string
    The 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() .
  • charset string
    Character set of the HTML output. Default 'utf-8'.
  • code string
    Error code to use. Default is 'wp_die', or the main error code if $message is a WP_Error.
  • exit bool
    Whether to exit the process after completion. Default true.

Default:false

Return

int|string|WP_Error Allowed comments return the approval status (0|1|<code>'spam'|'trash').
If $wp_error is true, disallowed comments return a WP_Error.

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.

Changelog

Version Description
5.5.0 The $avoid_die parameter was renamed to $wp_error.
4.7.0 The $avoid_die parameter was added, allowing the function to return a WP_Error object instead of dying.
2.0.0 Introduced.