wp_new_comment()WP 1.5.0

Adds a new comment to the database.

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

Hooks from the function

Return

Int|false|WP_Error. The ID of the comment on success, false or WP_Error on failure.

Usage

wp_new_comment( $commentdata, $wp_error );
$commentdata(array) (required)

Comment data.

  • comment_author(string)
    The name of the comment author.

  • comment_author_email(string)
    The comment author email address.

  • comment_author_url(string)
    The comment author URL.

  • comment_content(string)
    The content of the comment.

  • comment_date(string)
    The date the comment was submitted.
    Default: current time

  • comment_date_gmt(string)
    The date the comment was submitted in the GMT timezone.
    Default: $comment_date in the GMT timezone

  • comment_type(string)
    Comment type.
    Default: 'comment'

  • comment_parent(int)
    The ID of this comment's parent, if any.

  • comment_post_ID(int)
    The ID of the post that relates to the comment.

  • user_id(int)
    The ID of the user who submitted the comment.

  • user_ID(int)
    Kept for backward-compatibility. Use $user_id instead.

  • comment_agent(string)
    Comment author user agent.
    Default: value of 'HTTP_USER_AGENT' in the $_SERVER superglobal sent in the original request

  • comment_author_IP(string)
    Comment author IP address in IPv4 format.
    Default: value of 'REMOTE_ADDR' in the $_SERVER superglobal sent in the original request
$wp_error(true|false)
Should errors be returned as WP_Error objects instead of executing wp_die()? Default false.
Default: false

Examples

0

#1 Example of adding a new comment

The comment will be added to post 418 and will be a reply to comment 315:

// create a data array for the new comment
$commentdata = [
	'comment_post_ID'      => 418,
	'comment_author'       => 'Check',
	'comment_author_email' => '[email protected]',
	'comment_author_url'   => 'http://example.com',
	'comment_content'      => 'New comment text',
	'comment_type'         => 'comment',
	'comment_parent'       => 315,
	'user_ID'              => 0,
];

// add data to the database
wp_new_comment( $commentdata );
0

#2 Example of adding a comment using the function wp_insert_comment()

In this case, we have to define absolutely all of the comment fields ourselves:

$data = [
	'comment_post_ID'      => 1,
	'comment_author'       => 'admin',
	'comment_author_email' => '[email protected]',
	'comment_author_url'   => 'http://',
	'comment_content'      => 'comment text',
	'comment_type'         => 'comment',
	'comment_parent'       => 0,
	'user_id'              => 1,
	'comment_author_IP'    => '127.0.0.1',
	'comment_agent'        => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)',
	'comment_date'         => current_time('mysql'),
	'comment_approved'     => 1,
];

wp_insert_comment( $data );
0

#3 Warning: Restrictions for comment_type

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 NOT be able 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 the type or type__in argument:

  • all – No comment_type__in clause will be in query.
  • comment or comments'' added to comment_type_in.
  • pings'pingback','trackback' added to comment_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 the WHERE clause. For example, the following will replace the '' inserted instead of comment with comment:

add_filter( 'comments_clauses', 'add_comment_to_clauses', 10, 2 );

function add_comment_to_clauses( $clauses, $WP_Comment_object ) {

	// use regex to find the empty string in where clause
	$clauses['where'] = preg_replace_callback(
		"~(comment_type[ ]*IN[ ]*\(.*)('')~i",
		function ( $matches ) {
			// $matches[1] was everything up to the '' 
			// $matches[2] was the empty string
			return $matches[1] . "'','comment'";
		},
		$clauses['where']
	);

	return $clauses;
}

Notes

Changelog

Since 1.5.0 Introduced.
Since 4.3.0 Introduced the comment_agent and comment_author_IP arguments.
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.
Since 5.5.0 Introduced the comment_type argument.

wp_new_comment() code WP 6.4.3

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 = 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 ) {
		$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;
}