Adds a new comment to the database.
Description
Filters new comment to ensure that the fields are sanitized and valid before inserting comment into database. Calls ‘comment_post’ action with comment ID and whether comment is approved by WordPress. Also has ‘preprocess_comment’ filter for processing the comment data before the function handles it.
We use REMOTE_ADDR
here directly. If you are behind a proxy, you should ensure that it is properly set, such as in wp-config.php, for your environment.
See https://core.trac.wordpress.org/ticket/9235
See also
Parameters
$commentdata
arrayrequired- Comment data.
comment_author
stringThe name of the comment author.comment_author_email
stringThe comment author email address.comment_author_url
stringThe comment author URL.comment_content
stringThe content of the comment.comment_date
stringThe date the comment was submitted. Default is the current time.comment_date_gmt
stringThe date the comment was submitted in the GMT timezone.
Default is$comment_date
in the GMT timezone.comment_type
stringComment type. Default'comment'
.comment_parent
intThe ID of this comment’s parent, if any. Default 0.comment_post_ID
intThe ID of the post that relates to the comment.user_id
intThe ID of the user who submitted the comment. Default 0.user_ID
intKept for backward-compatibility. Use$user_id
instead.comment_agent
stringComment author user agent. Default is the value of'HTTP_USER_AGENT'
in the$_SERVER
superglobal sent in the original request.comment_author_IP
stringComment author IP address in IPv4 format. Default is the value of'REMOTE_ADDR'
in the$_SERVER
superglobal sent in the original request.
$wp_error
booloptional- Should errors be returned as WP_Error objects instead of 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
intThe HTTP response code. Default 200 for Ajax requests, 500 otherwise.link_url
stringA URL to include a link to. Only works in combination with $link_text.
Default empty string.link_text
stringA label for the link to include. Only works in combination with $link_url.
Default empty string.back_link
boolWhether to include a link to go back. Default false.text_direction
stringThe 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
stringCharacter set of the HTML output. Default'utf-8'
.code
stringError code to use. Default is'wp_die'
, or the main error code if $message is a WP_Error.exit
boolWhether to exit the process after completion. Default true.
Default:
false
Source
function wp_new_comment( $commentdata, $wp_error = false ) { global $wpdb; /* * Normalize `user_ID` to `user_id`, but pass the old key * to the `preprocess_comment` filter for backward compatibility. */ if ( isset( $commentdata['user_ID'] ) ) { $commentdata['user_ID'] = (int) $commentdata['user_ID']; $commentdata['user_id'] = $commentdata['user_ID']; } elseif ( isset( $commentdata['user_id'] ) ) { $commentdata['user_id'] = (int) $commentdata['user_id']; $commentdata['user_ID'] = $commentdata['user_id']; } $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; if ( ! isset( $commentdata['comment_author_IP'] ) ) { $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; } if ( ! isset( $commentdata['comment_agent'] ) ) { $commentdata['comment_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : ''; } /** * Filters a comment's data before it is sanitized and inserted into the database. * * @since 1.5.0 * @since 5.6.0 Comment data includes the `comment_agent` and `comment_author_IP` values. * * @param array $commentdata Comment data. */ $commentdata = apply_filters( 'preprocess_comment', $commentdata ); $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID']; // Normalize `user_ID` to `user_id` again, after the filter. if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) { $commentdata['user_ID'] = (int) $commentdata['user_ID']; $commentdata['user_id'] = $commentdata['user_ID']; } elseif ( isset( $commentdata['user_id'] ) ) { $commentdata['user_id'] = (int) $commentdata['user_id']; $commentdata['user_ID'] = $commentdata['user_id']; } $commentdata['comment_parent'] = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0; $parent_status = ( $commentdata['comment_parent'] > 0 ) ? wp_get_comment_status( $commentdata['comment_parent'] ) : ''; $commentdata['comment_parent'] = ( 'approved' === $parent_status || 'unapproved' === $parent_status ) ? $commentdata['comment_parent'] : 0; $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '', $commentdata['comment_author_IP'] ); $commentdata['comment_agent'] = substr( $commentdata['comment_agent'], 0, 254 ); if ( empty( $commentdata['comment_date'] ) ) { $commentdata['comment_date'] = current_time( 'mysql' ); } if ( empty( $commentdata['comment_date_gmt'] ) ) { $commentdata['comment_date_gmt'] = current_time( 'mysql', 1 ); } if ( empty( $commentdata['comment_type'] ) ) { $commentdata['comment_type'] = 'comment'; } $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error ); if ( is_wp_error( $commentdata['comment_approved'] ) ) { return $commentdata['comment_approved']; } $commentdata = wp_filter_comment( $commentdata ); if ( ! in_array( $commentdata['comment_approved'], array( 'trash', 'spam' ), true ) ) { // Validate the comment again after filters are applied to comment data. $commentdata['comment_approved'] = wp_check_comment_data( $commentdata ); } if ( is_wp_error( $commentdata['comment_approved'] ) ) { return $commentdata['comment_approved']; } $comment_id = wp_insert_comment( $commentdata ); if ( ! $comment_id ) { $fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); foreach ( $fields as $field ) { if ( isset( $commentdata[ $field ] ) ) { $commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] ); } } $commentdata = wp_filter_comment( $commentdata ); $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error ); if ( is_wp_error( $commentdata['comment_approved'] ) ) { return $commentdata['comment_approved']; } $comment_id = wp_insert_comment( $commentdata ); if ( ! $comment_id ) { return false; } } /** * Fires immediately after a comment is inserted into the database. * * @since 1.2.0 * @since 4.5.0 The `$commentdata` parameter was added. * * @param int $comment_id The comment ID. * @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam. * @param array $commentdata Comment data. */ do_action( 'comment_post', $comment_id, $commentdata['comment_approved'], $commentdata ); return $comment_id; }
Hooks
- do_action( ‘comment_post’,
int $comment_id ,int|string $comment_approved ,array $commentdata ) Fires immediately after a comment is inserted into the database.
- apply_filters( ‘preprocess_comment’,
array $commentdata ) Filters a comment’s data before it is sanitized and inserted into the database.
Basic Example
Warning: If you set
comment_type
to one of these words:“all”, “comment”, “comments”, “pings”
WordPress will save the comment with that type but you will be unable to retrieve it using normal WordPress comment functions. Here’s what happens to those reserved words inside `WP_Comment_Query`, where types are gathered into
comment_type__in
whether you send them via thetype
ortype__in
argument:'comment_type__in'
clause will be in query''
added tocomment_type_in
'pingback','trackback'
added tocomment_type_in
Because of this, you will not be able to retrieve the comment using “normal” WordPress functions. To get it, you will have to filter
comments_clauses
to ensure your type is added to theWHERE
clause. For example, the following will replace the''
inserted instead of “comment” with'comment'
: