WordPress Version: 6.3
/**
* Validates whether this comment is allowed to be made.
*
* @since 2.0.0
* @since 4.7.0 The `$avoid_die` parameter was added, allowing the function
* to return a WP_Error object instead of dying.
* @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param array $commentdata Contains information on the comment.
* @param bool $wp_error When true, a disallowed comment will result in the function
* returning a WP_Error object, rather than executing wp_die().
* Default false.
* @return int|string|WP_Error Allowed comments return the approval status (0|1|'spam'|'trash').
* If `$wp_error` is true, disallowed comments return a WP_Error.
*/
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);
}
if (!empty($commentdata['user_id'])) {
$user = get_userdata($commentdata['user_id']);
$post_author = $wpdb->get_var($wpdb->prepare("SELECT post_author FROM {$wpdb->posts} WHERE ID = %d LIMIT 1", $commentdata['comment_post_ID']));
}
if (isset($user) && ($commentdata['user_id'] == $post_author || $user->has_cap('moderate_comments'))) {
// The author and the admins get respect.
$approved = 1;
} else {
// Everyone else's comments will be checked.
if (check_comment($commentdata['comment_author'], $commentdata['comment_author_email'], $commentdata['comment_author_url'], $commentdata['comment_content'], $commentdata['comment_author_IP'], $commentdata['comment_agent'], $commentdata['comment_type'])) {
$approved = 1;
} else {
$approved = 0;
}
if (wp_check_comment_disallowed_list($commentdata['comment_author'], $commentdata['comment_author_email'], $commentdata['comment_author_url'], $commentdata['comment_content'], $commentdata['comment_author_IP'], $commentdata['comment_agent'])) {
$approved = EMPTY_TRASH_DAYS ? 'trash' : 'spam';
}
}
/**
* Filters a comment's approval status before it is set.
*
* @since 2.1.0
* @since 4.9.0 Returning a WP_Error value from the filter will short-circuit comment insertion
* and allow skipping further processing.
*
* @param int|string|WP_Error $approved The approval status. Accepts 1, 0, 'spam', 'trash',
* or WP_Error.
* @param array $commentdata Comment data.
*/
return apply_filters('pre_comment_approved', $approved, $commentdata);
}