diff --git src/wp-includes/comment.php src/wp-includes/comment.php
index 88508fa..74c81cc 100644
--- src/wp-includes/comment.php
+++ src/wp-includes/comment.php
@@ -2089,52 +2089,63 @@ function wp_get_current_commenter() {
  *
  * @since 2.0.0
  *
+ * @uses apply_filters() Calls 'wp_insert_comment_data' hook with comment data prior to insertion
+ * @uses do_action() Calls 'wp_insert_comment' hook with inserted comment ID and comment object 
  * @global wpdb $wpdb WordPress database abstraction object.
  *
  * @param array $commentdata Contains information on the comment.
- * @return int|bool The new comment's ID on success, false on failure.
+ * @return int|bool|WP_Error The new comment's ID, false on failure, or instance of WP_Error
  */
 function wp_insert_comment( $commentdata ) {
 	global $wpdb;
-	$data = wp_unslash( $commentdata );
+	$commentdata = wp_unslash( $commentdata );
 
-	$comment_author       = ! isset( $data['comment_author'] )       ? '' : $data['comment_author'];
-	$comment_author_email = ! isset( $data['comment_author_email'] ) ? '' : $data['comment_author_email'];
-	$comment_author_url   = ! isset( $data['comment_author_url'] )   ? '' : $data['comment_author_url'];
-	$comment_author_IP    = ! isset( $data['comment_author_IP'] )    ? '' : $data['comment_author_IP'];
-
-	$comment_date     = ! isset( $data['comment_date'] )     ? current_time( 'mysql' )            : $data['comment_date'];
-	$comment_date_gmt = ! isset( $data['comment_date_gmt'] ) ? get_gmt_from_date( $comment_date ) : $data['comment_date_gmt'];
-
-	$comment_post_ID  = ! isset( $data['comment_post_ID'] )  ? '' : $data['comment_post_ID'];
-	$comment_content  = ! isset( $data['comment_content'] )  ? '' : $data['comment_content'];
-	$comment_karma    = ! isset( $data['comment_karma'] )    ? 0  : $data['comment_karma'];
-	$comment_approved = ! isset( $data['comment_approved'] ) ? 1  : $data['comment_approved'];
-	$comment_agent    = ! isset( $data['comment_agent'] )    ? '' : $data['comment_agent'];
-	$comment_type     = ! isset( $data['comment_type'] )     ? '' : $data['comment_type'];
-	$comment_parent   = ! isset( $data['comment_parent'] )   ? 0  : $data['comment_parent'];
+	$defaults = array(
+		'comment_post_ID' => '',
+		'comment_author' => '',
+		'comment_author_email' => '',
+		'comment_author_url' => '',
+		'comment_author_IP' => '',
+		'comment_date' => current_time( 'mysql', false ),
+		'comment_content' => '',
+		'comment_karma' => 0,
+		'comment_approved' => 1,
+		'comment_agent' => '',
+		'comment_type' => '',
+		'comment_parent' => 0,
+		'user_id' => 0,
+	);
+	if ( ! empty( $commentdata['comment_date'] ) ) {
+		$defaults['comment_date_gmt'] = get_gmt_from_date( $commentdata['comment_date'] );
+	} else {
+		$defaults['comment_date_gmt'] = current_time( 'mysql', true );
+	}
+	$commentdata = array_merge( $defaults, $commentdata );
+	$data = array_intersect_key( $commentdata, $defaults );
+	$data = apply_filters( 'wp_insert_comment_data', $data );
 
-	$user_id  = ! isset( $data['user_id'] ) ? 0 : $data['user_id'];
+	if ( empty( $data['comment_post_ID'] ) || ! get_post( $data['comment_post_ID'] ) ) {
+		return new WP_Error( 'invalid_comment_post_id', __( 'Missing or invalid comment_post_ID' ) );
+	}
 
-	$compacted = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_karma', 'comment_approved', 'comment_agent', 'comment_type', 'comment_parent', 'user_id' );
-	if ( ! $wpdb->insert( $wpdb->comments, $compacted ) ) {
+	if ( ! $wpdb->insert( $wpdb->comments, $data ) ) {
 		$fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' );
 
 		foreach( $fields as $field ) {
-			if ( isset( $compacted[ $field ] ) ) {
-				$compacted[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $compacted[ $field ] );
+			if ( isset( $data[ $field ] ) ) {
+				$data[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $data[ $field ] );
 			}
 		}
 
-		if ( ! $wpdb->insert( $wpdb->comments, $compacted ) ) {
+		if ( ! $wpdb->insert( $wpdb->comments, $data ) ) {
 			return false;
 		}
 	}
 
 	$id = (int) $wpdb->insert_id;
 
-	if ( $comment_approved == 1 ) {
-		wp_update_comment_count( $comment_post_ID );
+	if ( intval( $data['comment_approved'] ) === 1 ) {
+		wp_update_comment_count( $data['comment_post_ID'] );
 	}
 	$comment = get_comment( $id );
 
diff --git tests/phpunit/tests/comment/query.php tests/phpunit/tests/comment/query.php
index 1958310..22d45f0 100644
--- tests/phpunit/tests/comment/query.php
+++ tests/phpunit/tests/comment/query.php
@@ -630,7 +630,7 @@ class Tests_Comment_Query extends WP_UnitTestCase {
 	 * @ticket 30478
 	 */
 	public function test_orderby_clause_key() {
-		$comments = $this->factory->comment->create_many( 3 );
+		$comments = $this->factory->comment->create_many( 3, array( 'comment_post_ID' => $this->post_id ) );
 		add_comment_meta( $comments[0], 'foo', 'aaa' );
 		add_comment_meta( $comments[1], 'foo', 'zzz' );
 		add_comment_meta( $comments[2], 'foo', 'jjj' );
@@ -656,12 +656,15 @@ class Tests_Comment_Query extends WP_UnitTestCase {
 	 */
 	public function test_orderby_clause_key_as_secondary_sort() {
 		$c1 = $this->factory->comment->create( array(
+			'comment_post_ID' => $this->post_id,
 			'comment_date' => '2015-01-28 03:00:00',
 		) );
 		$c2 = $this->factory->comment->create( array(
+			'comment_post_ID' => $this->post_id,
 			'comment_date' => '2015-01-28 05:00:00',
 		) );
 		$c3 = $this->factory->comment->create( array(
+			'comment_post_ID' => $this->post_id,
 			'comment_date' => '2015-01-28 03:00:00',
 		) );
 
@@ -691,7 +694,7 @@ class Tests_Comment_Query extends WP_UnitTestCase {
 	 * @ticket 30478
 	 */
 	public function test_orderby_more_than_one_clause_key() {
-		$comments = $this->factory->comment->create_many( 3 );
+		$comments = $this->factory->comment->create_many( 3, array( 'comment_post_ID' => $this->post_id ) );
 
 		add_comment_meta( $comments[0], 'foo', 'jjj' );
 		add_comment_meta( $comments[1], 'foo', 'zzz' );
@@ -1592,7 +1595,7 @@ class Tests_Comment_Query extends WP_UnitTestCase {
 	 * @ticket 24826
 	 */
 	public function test_comment_query_object() {
-		$comment_id = $this->factory->comment->create();
+		$comment_id = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id ) );
 
 		$query1 = new WP_Comment_Query();
 		$this->assertNull( $query1->query_vars );
@@ -1632,4 +1635,35 @@ class Tests_Comment_Query extends WP_UnitTestCase {
 
 		$this->assertSame( $num_queries, $wpdb->num_queries );
 	}
+
+	/**
+	 * Ticket @23931
+	 */
+	function test_wp_insert_comment_data_filter() {
+		$comment_args = array(
+			'comment_post_ID' => $this->post_id,
+			'comment_content' => 'not-filtered',
+		);
+		$filter = function ( $comment_data ) {
+			$comment_data['comment_content'] = 'filtered';
+			return $comment_data;
+		};
+		add_filter( 'wp_insert_comment_data', $filter );
+		$comment_id = $this->factory->comment->create( $comment_args );
+		remove_filter( 'wp_insert_comment_data', $filter );
+		$comment = get_comment( $comment_id );
+		$this->assertEquals( 'filtered', $comment->comment_content );
+	}
+
+	/**
+	 * Ticket @23931
+	 */
+	function test_error_when_not_supplying_comment_post_id() {
+		$r = $this->factory->comment->create( array() );
+		$this->assertInstanceOf( 'WP_Error', $r );
+		$this->assertEquals( 'invalid_comment_post_id', $r->get_error_code() );
+
+		$r = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id ) );
+		$this->assertInternalType( 'int', $r );
+	}
 }
