wp/wp-includes/comment.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    95 
    95 
    96 			/*
    96 			/*
    97 			 * Check the comment fields for moderation keywords. If any are found,
    97 			 * Check the comment fields for moderation keywords. If any are found,
    98 			 * fail the check for the given field by returning false.
    98 			 * fail the check for the given field by returning false.
    99 			 */
    99 			 */
   100 			$pattern = "#$word#i";
   100 			$pattern = "#$word#iu";
   101 			if ( preg_match( $pattern, $author ) ) {
   101 			if ( preg_match( $pattern, $author ) ) {
   102 				return false;
   102 				return false;
   103 			}
   103 			}
   104 			if ( preg_match( $pattern, $email ) ) {
   104 			if ( preg_match( $pattern, $email ) ) {
   105 				return false;
   105 				return false;
   134 			} else {
   134 			} else {
   135 				// expected_slashed ($author, $email)
   135 				// expected_slashed ($author, $email)
   136 				$ok_to_comment = $wpdb->get_var( $wpdb->prepare( "SELECT comment_approved FROM $wpdb->comments WHERE comment_author = %s AND comment_author_email = %s and comment_approved = '1' LIMIT 1", $author, $email ) );
   136 				$ok_to_comment = $wpdb->get_var( $wpdb->prepare( "SELECT comment_approved FROM $wpdb->comments WHERE comment_author = %s AND comment_author_email = %s and comment_approved = '1' LIMIT 1", $author, $email ) );
   137 			}
   137 			}
   138 			if ( ( 1 == $ok_to_comment ) &&
   138 			if ( ( 1 == $ok_to_comment ) &&
   139 				( empty( $mod_keys ) || false === strpos( $email, $mod_keys ) ) ) {
   139 				( empty( $mod_keys ) || ! str_contains( $email, $mod_keys ) ) ) {
   140 					return true;
   140 					return true;
   141 			} else {
   141 			} else {
   142 				return false;
   142 				return false;
   143 			}
   143 			}
   144 		} else {
   144 		} else {
   147 	}
   147 	}
   148 	return true;
   148 	return true;
   149 }
   149 }
   150 
   150 
   151 /**
   151 /**
   152  * Retrieves the approved comments for post $post_id.
   152  * Retrieves the approved comments for a post.
   153  *
   153  *
   154  * @since 2.0.0
   154  * @since 2.0.0
   155  * @since 4.1.0 Refactored to leverage WP_Comment_Query over a direct query.
   155  * @since 4.1.0 Refactored to leverage WP_Comment_Query over a direct query.
   156  *
   156  *
   157  * @param int   $post_id The ID of the post.
   157  * @param int   $post_id The ID of the post.
   158  * @param array $args    Optional. See WP_Comment_Query::__construct() for information on accepted arguments.
   158  * @param array $args    {
       
   159  *     Optional. See WP_Comment_Query::__construct() for information on accepted arguments.
       
   160  *
       
   161  *     @type int    $status  Comment status to limit results by. Defaults to approved comments.
       
   162  *     @type int    $post_id Limit results to those affiliated with a given post ID.
       
   163  *     @type string $order   How to order retrieved comments. Default 'ASC'.
       
   164  * }
   159  * @return WP_Comment[]|int[]|int The approved comments, or number of comments if `$count`
   165  * @return WP_Comment[]|int[]|int The approved comments, or number of comments if `$count`
   160  *                                argument is true.
   166  *                                argument is true.
   161  */
   167  */
   162 function get_approved_comments( $post_id, $args = array() ) {
   168 function get_approved_comments( $post_id, $args = array() ) {
   163 	if ( ! $post_id ) {
   169 	if ( ! $post_id ) {
   169 		'post_id' => $post_id,
   175 		'post_id' => $post_id,
   170 		'order'   => 'ASC',
   176 		'order'   => 'ASC',
   171 	);
   177 	);
   172 	$parsed_args = wp_parse_args( $args, $defaults );
   178 	$parsed_args = wp_parse_args( $args, $defaults );
   173 
   179 
   174 	$query = new WP_Comment_Query;
   180 	$query = new WP_Comment_Query();
   175 	return $query->query( $parsed_args );
   181 	return $query->query( $parsed_args );
   176 }
   182 }
   177 
   183 
   178 /**
   184 /**
   179  * Retrieves comment data given a comment ID or comment object.
   185  * Retrieves comment data given a comment ID or comment object.
   234  * The comment list can be for the blog as a whole or for an individual post.
   240  * The comment list can be for the blog as a whole or for an individual post.
   235  *
   241  *
   236  * @since 2.7.0
   242  * @since 2.7.0
   237  *
   243  *
   238  * @param string|array $args Optional. Array or string of arguments. See WP_Comment_Query::__construct()
   244  * @param string|array $args Optional. Array or string of arguments. See WP_Comment_Query::__construct()
   239  *                           for information on accepted arguments. Default empty.
   245  *                           for information on accepted arguments. Default empty string.
   240  * @return WP_Comment[]|int[]|int List of comments or number of found comments if `$count` argument is true.
   246  * @return WP_Comment[]|int[]|int List of comments or number of found comments if `$count` argument is true.
   241  */
   247  */
   242 function get_comments( $args = '' ) {
   248 function get_comments( $args = '' ) {
   243 	$query = new WP_Comment_Query;
   249 	$query = new WP_Comment_Query();
   244 	return $query->query( $args );
   250 	return $query->query( $args );
   245 }
   251 }
   246 
   252 
   247 /**
   253 /**
   248  * Retrieves all of the WordPress supported comment statuses.
   254  * Retrieves all of the WordPress supported comment statuses.
   270  *
   276  *
   271  * @since 4.3.0
   277  * @since 4.3.0
   272  *
   278  *
   273  * @param string $post_type    Optional. Post type. Default 'post'.
   279  * @param string $post_type    Optional. Post type. Default 'post'.
   274  * @param string $comment_type Optional. Comment type. Default 'comment'.
   280  * @param string $comment_type Optional. Comment type. Default 'comment'.
   275  * @return string Expected return value is 'open' or 'closed'.
   281  * @return string Either 'open' or 'closed'.
   276  */
   282  */
   277 function get_default_comment_status( $post_type = 'post', $comment_type = 'comment' ) {
   283 function get_default_comment_status( $post_type = 'post', $comment_type = 'comment' ) {
   278 	switch ( $comment_type ) {
   284 	switch ( $comment_type ) {
   279 		case 'pingback':
   285 		case 'pingback':
   280 		case 'trackback':
   286 		case 'trackback':
   388 	);
   394 	);
   389 
   395 
   390 	$args = array(
   396 	$args = array(
   391 		'count'                     => true,
   397 		'count'                     => true,
   392 		'update_comment_meta_cache' => false,
   398 		'update_comment_meta_cache' => false,
       
   399 		'orderby'                   => 'none',
   393 	);
   400 	);
   394 	if ( $post_id > 0 ) {
   401 	if ( $post_id > 0 ) {
   395 		$args['post_id'] = $post_id;
   402 		$args['post_id'] = $post_id;
   396 	}
   403 	}
   397 	$mapping       = array(
   404 	$mapping       = array(
   447  *
   454  *
   448  * @param int    $comment_id Comment ID.
   455  * @param int    $comment_id Comment ID.
   449  * @param string $meta_key   Metadata name.
   456  * @param string $meta_key   Metadata name.
   450  * @param mixed  $meta_value Optional. Metadata value. If provided,
   457  * @param mixed  $meta_value Optional. Metadata value. If provided,
   451  *                           rows will only be removed that match the value.
   458  *                           rows will only be removed that match the value.
   452  *                           Must be serializable if non-scalar. Default empty.
   459  *                           Must be serializable if non-scalar. Default empty string.
   453  * @return bool True on success, false on failure.
   460  * @return bool True on success, false on failure.
   454  */
   461  */
   455 function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) {
   462 function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) {
   456 	return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value );
   463 	return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value );
   457 }
   464 }
   463  *
   470  *
   464  * @link https://developer.wordpress.org/reference/functions/get_comment_meta/
   471  * @link https://developer.wordpress.org/reference/functions/get_comment_meta/
   465  *
   472  *
   466  * @param int    $comment_id Comment ID.
   473  * @param int    $comment_id Comment ID.
   467  * @param string $key        Optional. The meta key to retrieve. By default,
   474  * @param string $key        Optional. The meta key to retrieve. By default,
   468  *                           returns data for all keys.
   475  *                           returns data for all keys. Default empty string.
   469  * @param bool   $single     Optional. Whether to return a single value.
   476  * @param bool   $single     Optional. Whether to return a single value.
   470  *                           This parameter has no effect if `$key` is not specified.
   477  *                           This parameter has no effect if `$key` is not specified.
   471  *                           Default false.
   478  *                           Default false.
   472  * @return mixed An array of values if `$single` is false.
   479  * @return mixed An array of values if `$single` is false.
   473  *               The value of meta data field if `$single` is true.
   480  *               The value of meta data field if `$single` is true.
   477 function get_comment_meta( $comment_id, $key = '', $single = false ) {
   484 function get_comment_meta( $comment_id, $key = '', $single = false ) {
   478 	return get_metadata( 'comment', $comment_id, $key, $single );
   485 	return get_metadata( 'comment', $comment_id, $key, $single );
   479 }
   486 }
   480 
   487 
   481 /**
   488 /**
       
   489  * Queue comment meta for lazy-loading.
       
   490  *
       
   491  * @since 6.3.0
       
   492  *
       
   493  * @param array $comment_ids List of comment IDs.
       
   494  */
       
   495 function wp_lazyload_comment_meta( array $comment_ids ) {
       
   496 	if ( empty( $comment_ids ) ) {
       
   497 		return;
       
   498 	}
       
   499 	$lazyloader = wp_metadata_lazyloader();
       
   500 	$lazyloader->queue_objects( 'comment', $comment_ids );
       
   501 }
       
   502 
       
   503 /**
   482  * Updates comment meta field based on comment ID.
   504  * Updates comment meta field based on comment ID.
   483  *
   505  *
   484  * Use the $prev_value parameter to differentiate between meta fields with the
   506  * Use the $prev_value parameter to differentiate between meta fields with the
   485  * same key and comment ID.
   507  * same key and comment ID.
   486  *
   508  *
   493  * @param int    $comment_id Comment ID.
   515  * @param int    $comment_id Comment ID.
   494  * @param string $meta_key   Metadata key.
   516  * @param string $meta_key   Metadata key.
   495  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
   517  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
   496  * @param mixed  $prev_value Optional. Previous value to check before updating.
   518  * @param mixed  $prev_value Optional. Previous value to check before updating.
   497  *                           If specified, only update existing metadata entries with
   519  *                           If specified, only update existing metadata entries with
   498  *                           this value. Otherwise, update all entries. Default empty.
   520  *                           this value. Otherwise, update all entries. Default empty string.
   499  * @return int|bool Meta ID if the key didn't exist, true on successful update,
   521  * @return int|bool Meta ID if the key didn't exist, true on successful update,
   500  *                  false on failure or if the value passed to the function
   522  *                  false on failure or if the value passed to the function
   501  *                  is the same as the one that is already in the database.
   523  *                  is the same as the one that is already in the database.
   502  */
   524  */
   503 function update_comment_meta( $comment_id, $meta_key, $meta_value, $prev_value = '' ) {
   525 function update_comment_meta( $comment_id, $meta_key, $meta_value, $prev_value = '' ) {
   504 	return update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value );
   526 	return update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value );
   505 }
       
   506 
       
   507 /**
       
   508  * Queues comments for metadata lazy-loading.
       
   509  *
       
   510  * @since 4.5.0
       
   511  *
       
   512  * @param WP_Comment[] $comments Array of comment objects.
       
   513  */
       
   514 function wp_queue_comments_for_comment_meta_lazyload( $comments ) {
       
   515 	// Don't use `wp_list_pluck()` to avoid by-reference manipulation.
       
   516 	$comment_ids = array();
       
   517 	if ( is_array( $comments ) ) {
       
   518 		foreach ( $comments as $comment ) {
       
   519 			if ( $comment instanceof WP_Comment ) {
       
   520 				$comment_ids[] = $comment->comment_ID;
       
   521 			}
       
   522 		}
       
   523 	}
       
   524 
       
   525 	if ( $comment_ids ) {
       
   526 		$lazyloader = wp_metadata_lazyloader();
       
   527 		$lazyloader->queue_objects( 'comment', $comment_ids );
       
   528 	}
       
   529 }
   527 }
   530 
   528 
   531 /**
   529 /**
   532  * Sets the cookies used to store an unauthenticated commentator's identity. Typically used
   530  * Sets the cookies used to store an unauthenticated commentator's identity. Typically used
   533  * to recall previous comments by this commentator that are still held in moderation.
   531  * to recall previous comments by this commentator that are still held in moderation.
   557 
   555 
   558 	/**
   556 	/**
   559 	 * Filters the lifetime of the comment cookie in seconds.
   557 	 * Filters the lifetime of the comment cookie in seconds.
   560 	 *
   558 	 *
   561 	 * @since 2.8.0
   559 	 * @since 2.8.0
   562 	 *
   560 	 * @since 6.6.0 The default $seconds value changed from 30000000 to YEAR_IN_SECONDS.
   563 	 * @param int $seconds Comment cookie lifetime. Default 30000000.
   561 	 *
   564 	 */
   562 	 * @param int $seconds Comment cookie lifetime. Default YEAR_IN_SECONDS.
   565 	$comment_cookie_lifetime = time() + apply_filters( 'comment_cookie_lifetime', 30000000 );
   563 	 */
       
   564 	$comment_cookie_lifetime = time() + apply_filters( 'comment_cookie_lifetime', YEAR_IN_SECONDS );
   566 
   565 
   567 	$secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
   566 	$secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
   568 
   567 
   569 	setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure );
   568 	setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure );
   570 	setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure );
   569 	setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure );
   652  *                             If `$wp_error` is true, disallowed comments return a WP_Error.
   651  *                             If `$wp_error` is true, disallowed comments return a WP_Error.
   653  */
   652  */
   654 function wp_allow_comment( $commentdata, $wp_error = false ) {
   653 function wp_allow_comment( $commentdata, $wp_error = false ) {
   655 	global $wpdb;
   654 	global $wpdb;
   656 
   655 
   657 	// Simple duplicate check.
   656 	/*
   658 	// expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
   657 	 * Simple duplicate check.
       
   658 	 * expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
       
   659 	 */
   659 	$dupe = $wpdb->prepare(
   660 	$dupe = $wpdb->prepare(
   660 		"SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ",
   661 		"SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ",
   661 		wp_unslash( $commentdata['comment_post_ID'] ),
   662 		wp_unslash( $commentdata['comment_post_ID'] ),
   662 		wp_unslash( $commentdata['comment_parent'] ),
   663 		wp_unslash( $commentdata['comment_parent'] ),
   663 		wp_unslash( $commentdata['comment_author'] )
   664 		wp_unslash( $commentdata['comment_author'] )
   724 	 *
   725 	 *
   725 	 * @since 2.3.0
   726 	 * @since 2.3.0
   726 	 * @since 4.7.0 The `$avoid_die` parameter was added.
   727 	 * @since 4.7.0 The `$avoid_die` parameter was added.
   727 	 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
   728 	 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
   728 	 *
   729 	 *
   729 	 * @param string $comment_author_IP    Comment author's IP address.
   730 	 * @param string $comment_author_ip    Comment author's IP address.
   730 	 * @param string $comment_author_email Comment author's email.
   731 	 * @param string $comment_author_email Comment author's email.
   731 	 * @param string $comment_date_gmt     GMT date the comment was posted.
   732 	 * @param string $comment_date_gmt     GMT date the comment was posted.
   732 	 * @param bool   $wp_error             Whether to return a WP_Error object instead of executing
   733 	 * @param bool   $wp_error             Whether to return a WP_Error object instead of executing
   733 	 *                                     wp_die() or die() if a comment flood is occurring.
   734 	 *                                     wp_die() or die() if a comment flood is occurring.
   734 	 */
   735 	 */
   747 	 *
   748 	 *
   748 	 * @since 4.7.0
   749 	 * @since 4.7.0
   749 	 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
   750 	 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`.
   750 	 *
   751 	 *
   751 	 * @param bool   $is_flood             Is a comment flooding occurring? Default false.
   752 	 * @param bool   $is_flood             Is a comment flooding occurring? Default false.
   752 	 * @param string $comment_author_IP    Comment author's IP address.
   753 	 * @param string $comment_author_ip    Comment author's IP address.
   753 	 * @param string $comment_author_email Comment author's email.
   754 	 * @param string $comment_author_email Comment author's email.
   754 	 * @param string $comment_date_gmt     GMT date the comment was posted.
   755 	 * @param string $comment_date_gmt     GMT date the comment was posted.
   755 	 * @param bool   $wp_error             Whether to return a WP_Error object instead of executing
   756 	 * @param bool   $wp_error             Whether to return a WP_Error object instead of executing
   756 	 *                                     wp_die() or die() if a comment flood is occurring.
   757 	 *                                     wp_die() or die() if a comment flood is occurring.
   757 	 */
   758 	 */
   857  * @param bool   $avoid_die When true, a disallowed comment will result in the function
   858  * @param bool   $avoid_die When true, a disallowed comment will result in the function
   858  *                          returning without executing wp_die() or die(). Default false.
   859  *                          returning without executing wp_die() or die(). Default false.
   859  * @return bool Whether comment flooding is occurring.
   860  * @return bool Whether comment flooding is occurring.
   860  */
   861  */
   861 function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) {
   862 function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) {
   862 
       
   863 	global $wpdb;
   863 	global $wpdb;
   864 
   864 
   865 	// Another callback has declared a flood. Trust it.
   865 	// Another callback has declared a flood. Trust it.
   866 	if ( true === $is_flood ) {
   866 	if ( true === $is_flood ) {
   867 		return $is_flood;
   867 		return $is_flood;
   984  * @uses Walker_Comment
   984  * @uses Walker_Comment
   985  *
   985  *
   986  * @global WP_Query $wp_query WordPress Query object.
   986  * @global WP_Query $wp_query WordPress Query object.
   987  *
   987  *
   988  * @param WP_Comment[] $comments Optional. Array of WP_Comment objects. Defaults to `$wp_query->comments`.
   988  * @param WP_Comment[] $comments Optional. Array of WP_Comment objects. Defaults to `$wp_query->comments`.
   989  * @param int          $per_page Optional. Comments per page.
   989  * @param int          $per_page Optional. Comments per page. Defaults to the value of `comments_per_page`
   990  * @param bool         $threaded Optional. Control over flat or threaded comments.
   990  *                               query var, option of the same name, or 1 (in that order).
       
   991  * @param bool         $threaded Optional. Control over flat or threaded comments. Defaults to the value
       
   992  *                               of `thread_comments` option.
   991  * @return int Number of comment pages.
   993  * @return int Number of comment pages.
   992  */
   994  */
   993 function get_comment_pages_count( $comments = null, $per_page = null, $threaded = null ) {
   995 function get_comment_pages_count( $comments = null, $per_page = null, $threaded = null ) {
   994 	global $wp_query;
   996 	global $wp_query;
   995 
   997 
  1022 	if ( ! isset( $threaded ) ) {
  1024 	if ( ! isset( $threaded ) ) {
  1023 		$threaded = get_option( 'thread_comments' );
  1025 		$threaded = get_option( 'thread_comments' );
  1024 	}
  1026 	}
  1025 
  1027 
  1026 	if ( $threaded ) {
  1028 	if ( $threaded ) {
  1027 		$walker = new Walker_Comment;
  1029 		$walker = new Walker_Comment();
  1028 		$count  = ceil( $walker->get_number_of_root_elements( $comments ) / $per_page );
  1030 		$count  = ceil( $walker->get_number_of_root_elements( $comments ) / $per_page );
  1029 	} else {
  1031 	} else {
  1030 		$count = ceil( count( $comments ) / $per_page );
  1032 		$count = ceil( count( $comments ) / $per_page );
  1031 	}
  1033 	}
  1032 
  1034 
  1033 	return $count;
  1035 	return (int) $count;
  1034 }
  1036 }
  1035 
  1037 
  1036 /**
  1038 /**
  1037  * Calculates what page number a comment will appear on for comment paging.
  1039  * Calculates what page number a comment will appear on for comment paging.
  1038  *
  1040  *
  1039  * @since 2.7.0
  1041  * @since 2.7.0
  1040  *
  1042  *
  1041  * @global wpdb $wpdb WordPress database abstraction object.
  1043  * @global wpdb $wpdb WordPress database abstraction object.
  1042  *
  1044  *
  1043  * @param int   $comment_ID Comment ID.
  1045  * @param int   $comment_id Comment ID.
  1044  * @param array $args {
  1046  * @param array $args {
  1045  *     Array of optional arguments.
  1047  *     Array of optional arguments.
  1046  *
  1048  *
  1047  *     @type string     $type      Limit paginated comments to those matching a given type.
  1049  *     @type string     $type      Limit paginated comments to those matching a given type.
  1048  *                                 Accepts 'comment', 'trackback', 'pingback', 'pings'
  1050  *                                 Accepts 'comment', 'trackback', 'pingback', 'pings'
  1049  *                                 (trackbacks and pingbacks), or 'all'. Default 'all'.
  1051  *                                 (trackbacks and pingbacks), or 'all'. Default 'all'.
  1050  *     @type int        $per_page  Per-page count to use when calculating pagination.
  1052  *     @type int        $per_page  Per-page count to use when calculating pagination.
  1051  *                                 Defaults to the value of the 'comments_per_page' option.
  1053  *                                 Defaults to the value of the 'comments_per_page' option.
  1052  *     @type int|string $max_depth If greater than 1, comment page will be determined
  1054  *     @type int|string $max_depth If greater than 1, comment page will be determined
  1053  *                                 for the top-level parent `$comment_ID`.
  1055  *                                 for the top-level parent `$comment_id`.
  1054  *                                 Defaults to the value of the 'thread_comments_depth' option.
  1056  *                                 Defaults to the value of the 'thread_comments_depth' option.
  1055  * } *
  1057  * }
  1056  * @return int|null Comment page number or null on error.
  1058  * @return int|null Comment page number or null on error.
  1057  */
  1059  */
  1058 function get_page_of_comment( $comment_ID, $args = array() ) {
  1060 function get_page_of_comment( $comment_id, $args = array() ) {
  1059 	global $wpdb;
  1061 	global $wpdb;
  1060 
  1062 
  1061 	$page = null;
  1063 	$page = null;
  1062 
  1064 
  1063 	$comment = get_comment( $comment_ID );
  1065 	$comment = get_comment( $comment_id );
  1064 	if ( ! $comment ) {
  1066 	if ( ! $comment ) {
  1065 		return;
  1067 		return;
  1066 	}
  1068 	}
  1067 
  1069 
  1068 	$defaults      = array(
  1070 	$defaults      = array(
  1112 			'type'       => $args['type'],
  1114 			'type'       => $args['type'],
  1113 			'post_id'    => $comment->comment_post_ID,
  1115 			'post_id'    => $comment->comment_post_ID,
  1114 			'fields'     => 'ids',
  1116 			'fields'     => 'ids',
  1115 			'count'      => true,
  1117 			'count'      => true,
  1116 			'status'     => 'approve',
  1118 			'status'     => 'approve',
       
  1119 			'orderby'    => 'none',
  1117 			'parent'     => 0,
  1120 			'parent'     => 0,
  1118 			'date_query' => array(
  1121 			'date_query' => array(
  1119 				array(
  1122 				array(
  1120 					'column' => "$wpdb->comments.comment_date_gmt",
  1123 					'column' => "$wpdb->comments.comment_date_gmt",
  1121 					'before' => $comment->comment_date_gmt,
  1124 					'before' => $comment->comment_date_gmt,
  1166 		if ( 0 == $older_comment_count ) {
  1169 		if ( 0 == $older_comment_count ) {
  1167 			$page = 1;
  1170 			$page = 1;
  1168 
  1171 
  1169 			// Divide comments older than this one by comments per page to get this comment's page number.
  1172 			// Divide comments older than this one by comments per page to get this comment's page number.
  1170 		} else {
  1173 		} else {
  1171 			$page = ceil( ( $older_comment_count + 1 ) / $args['per_page'] );
  1174 			$page = (int) ceil( ( $older_comment_count + 1 ) / $args['per_page'] );
  1172 		}
  1175 		}
  1173 	}
  1176 	}
  1174 
  1177 
  1175 	/**
  1178 	/**
  1176 	 * Filters the calculated page on which a comment appears.
  1179 	 * Filters the calculated page on which a comment appears.
  1177 	 *
  1180 	 *
  1178 	 * @since 4.4.0
  1181 	 * @since 4.4.0
  1179 	 * @since 4.7.0 Introduced the `$comment_ID` parameter.
  1182 	 * @since 4.7.0 Introduced the `$comment_id` parameter.
  1180 	 *
  1183 	 *
  1181 	 * @param int   $page          Comment page.
  1184 	 * @param int   $page          Comment page.
  1182 	 * @param array $args {
  1185 	 * @param array $args {
  1183 	 *     Arguments used to calculate pagination. These include arguments auto-detected by the function,
  1186 	 *     Arguments used to calculate pagination. These include arguments auto-detected by the function,
  1184 	 *     based on query vars, system settings, etc. For pristine arguments passed to the function,
  1187 	 *     based on query vars, system settings, etc. For pristine arguments passed to the function,
  1195 	 *     @type string $type      Type of comments to count.
  1198 	 *     @type string $type      Type of comments to count.
  1196 	 *     @type int    $page      Current comment page.
  1199 	 *     @type int    $page      Current comment page.
  1197 	 *     @type int    $per_page  Number of comments per page.
  1200 	 *     @type int    $per_page  Number of comments per page.
  1198 	 *     @type int    $max_depth Maximum comment threading depth allowed.
  1201 	 *     @type int    $max_depth Maximum comment threading depth allowed.
  1199 	 * }
  1202 	 * }
  1200 	 * @param int $comment_ID ID of the comment.
  1203 	 * @param int $comment_id ID of the comment.
  1201 	 */
  1204 	 */
  1202 	return apply_filters( 'get_page_of_comment', (int) $page, $args, $original_args, $comment_ID );
  1205 	return apply_filters( 'get_page_of_comment', (int) $page, $args, $original_args, $comment_id );
  1203 }
  1206 }
  1204 
  1207 
  1205 /**
  1208 /**
  1206  * Retrieves the maximum character lengths for the comment form fields.
  1209  * Retrieves the maximum character lengths for the comment form fields.
  1207  *
  1210  *
  1268  */
  1271  */
  1269 function wp_check_comment_data_max_lengths( $comment_data ) {
  1272 function wp_check_comment_data_max_lengths( $comment_data ) {
  1270 	$max_lengths = wp_get_comment_fields_max_lengths();
  1273 	$max_lengths = wp_get_comment_fields_max_lengths();
  1271 
  1274 
  1272 	if ( isset( $comment_data['comment_author'] ) && mb_strlen( $comment_data['comment_author'], '8bit' ) > $max_lengths['comment_author'] ) {
  1275 	if ( isset( $comment_data['comment_author'] ) && mb_strlen( $comment_data['comment_author'], '8bit' ) > $max_lengths['comment_author'] ) {
  1273 		return new WP_Error( 'comment_author_column_length', __( '<strong>Error</strong>: Your name is too long.' ), 200 );
  1276 		return new WP_Error( 'comment_author_column_length', __( '<strong>Error:</strong> Your name is too long.' ), 200 );
  1274 	}
  1277 	}
  1275 
  1278 
  1276 	if ( isset( $comment_data['comment_author_email'] ) && strlen( $comment_data['comment_author_email'] ) > $max_lengths['comment_author_email'] ) {
  1279 	if ( isset( $comment_data['comment_author_email'] ) && strlen( $comment_data['comment_author_email'] ) > $max_lengths['comment_author_email'] ) {
  1277 		return new WP_Error( 'comment_author_email_column_length', __( '<strong>Error</strong>: Your email address is too long.' ), 200 );
  1280 		return new WP_Error( 'comment_author_email_column_length', __( '<strong>Error:</strong> Your email address is too long.' ), 200 );
  1278 	}
  1281 	}
  1279 
  1282 
  1280 	if ( isset( $comment_data['comment_author_url'] ) && strlen( $comment_data['comment_author_url'] ) > $max_lengths['comment_author_url'] ) {
  1283 	if ( isset( $comment_data['comment_author_url'] ) && strlen( $comment_data['comment_author_url'] ) > $max_lengths['comment_author_url'] ) {
  1281 		return new WP_Error( 'comment_author_url_column_length', __( '<strong>Error</strong>: Your URL is too long.' ), 200 );
  1284 		return new WP_Error( 'comment_author_url_column_length', __( '<strong>Error:</strong> Your URL is too long.' ), 200 );
  1282 	}
  1285 	}
  1283 
  1286 
  1284 	if ( isset( $comment_data['comment_content'] ) && mb_strlen( $comment_data['comment_content'], '8bit' ) > $max_lengths['comment_content'] ) {
  1287 	if ( isset( $comment_data['comment_content'] ) && mb_strlen( $comment_data['comment_content'], '8bit' ) > $max_lengths['comment_content'] ) {
  1285 		return new WP_Error( 'comment_content_column_length', __( '<strong>Error</strong>: Your comment is too long.' ), 200 );
  1288 		return new WP_Error( 'comment_content_column_length', __( '<strong>Error:</strong> Your comment is too long.' ), 200 );
  1286 	}
  1289 	}
  1287 
  1290 
  1288 	return true;
  1291 	return true;
  1289 }
  1292 }
  1290 
  1293 
  1352 
  1355 
  1353 		// Skip empty lines.
  1356 		// Skip empty lines.
  1354 		if ( empty( $word ) ) {
  1357 		if ( empty( $word ) ) {
  1355 			continue; }
  1358 			continue; }
  1356 
  1359 
  1357 		// Do some escaping magic so that '#' chars
  1360 		// Do some escaping magic so that '#' chars in the spam words don't break things:
  1358 		// in the spam words don't break things:
       
  1359 		$word = preg_quote( $word, '#' );
  1361 		$word = preg_quote( $word, '#' );
  1360 
  1362 
  1361 		$pattern = "#$word#i";
  1363 		$pattern = "#$word#iu";
  1362 		if ( preg_match( $pattern, $author )
  1364 		if ( preg_match( $pattern, $author )
  1363 			|| preg_match( $pattern, $email )
  1365 			|| preg_match( $pattern, $email )
  1364 			|| preg_match( $pattern, $url )
  1366 			|| preg_match( $pattern, $url )
  1365 			|| preg_match( $pattern, $comment )
  1367 			|| preg_match( $pattern, $comment )
  1366 			|| preg_match( $pattern, $comment_without_html )
  1368 			|| preg_match( $pattern, $comment_without_html )
  1445  * @param bool           $force_delete Whether to bypass Trash and force deletion. Default false.
  1447  * @param bool           $force_delete Whether to bypass Trash and force deletion. Default false.
  1446  * @return bool True on success, false on failure.
  1448  * @return bool True on success, false on failure.
  1447  */
  1449  */
  1448 function wp_delete_comment( $comment_id, $force_delete = false ) {
  1450 function wp_delete_comment( $comment_id, $force_delete = false ) {
  1449 	global $wpdb;
  1451 	global $wpdb;
       
  1452 
  1450 	$comment = get_comment( $comment_id );
  1453 	$comment = get_comment( $comment_id );
  1451 	if ( ! $comment ) {
  1454 	if ( ! $comment ) {
  1452 		return false;
  1455 		return false;
  1453 	}
  1456 	}
  1454 
  1457 
  1835 	 *  - `comment_spam_pingback`
  1838 	 *  - `comment_spam_pingback`
  1836 	 *  - `comment_spam_trackback`
  1839 	 *  - `comment_spam_trackback`
  1837 	 *
  1840 	 *
  1838 	 * @since 2.7.0
  1841 	 * @since 2.7.0
  1839 	 *
  1842 	 *
  1840 	 * @param string     $comment_ID The comment ID as a numeric string.
  1843 	 * @param string     $comment_id The comment ID as a numeric string.
  1841 	 * @param WP_Comment $comment    Comment object.
  1844 	 * @param WP_Comment $comment    Comment object.
  1842 	 */
  1845 	 */
  1843 	do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment );
  1846 	do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment );
  1844 }
  1847 }
  1845 
  1848 
  1989  * }
  1992  * }
  1990  * @return int|false The new comment's ID on success, false on failure.
  1993  * @return int|false The new comment's ID on success, false on failure.
  1991  */
  1994  */
  1992 function wp_insert_comment( $commentdata ) {
  1995 function wp_insert_comment( $commentdata ) {
  1993 	global $wpdb;
  1996 	global $wpdb;
       
  1997 
  1994 	$data = wp_unslash( $commentdata );
  1998 	$data = wp_unslash( $commentdata );
  1995 
  1999 
  1996 	$comment_author       = ! isset( $data['comment_author'] ) ? '' : $data['comment_author'];
  2000 	$comment_author       = ! isset( $data['comment_author'] ) ? '' : $data['comment_author'];
  1997 	$comment_author_email = ! isset( $data['comment_author_email'] ) ? '' : $data['comment_author_email'];
  2001 	$comment_author_email = ! isset( $data['comment_author_email'] ) ? '' : $data['comment_author_email'];
  1998 	$comment_author_url   = ! isset( $data['comment_author_url'] ) ? '' : $data['comment_author_url'];
  2002 	$comment_author_url   = ! isset( $data['comment_author_url'] ) ? '' : $data['comment_author_url'];
  1999 	$comment_author_IP    = ! isset( $data['comment_author_IP'] ) ? '' : $data['comment_author_IP'];
  2003 	$comment_author_ip    = ! isset( $data['comment_author_IP'] ) ? '' : $data['comment_author_IP'];
  2000 
  2004 
  2001 	$comment_date     = ! isset( $data['comment_date'] ) ? current_time( 'mysql' ) : $data['comment_date'];
  2005 	$comment_date     = ! isset( $data['comment_date'] ) ? current_time( 'mysql' ) : $data['comment_date'];
  2002 	$comment_date_gmt = ! isset( $data['comment_date_gmt'] ) ? get_gmt_from_date( $comment_date ) : $data['comment_date_gmt'];
  2006 	$comment_date_gmt = ! isset( $data['comment_date_gmt'] ) ? get_gmt_from_date( $comment_date ) : $data['comment_date_gmt'];
  2003 
  2007 
  2004 	$comment_post_ID  = ! isset( $data['comment_post_ID'] ) ? 0 : $data['comment_post_ID'];
  2008 	$comment_post_id  = ! isset( $data['comment_post_ID'] ) ? 0 : $data['comment_post_ID'];
  2005 	$comment_content  = ! isset( $data['comment_content'] ) ? '' : $data['comment_content'];
  2009 	$comment_content  = ! isset( $data['comment_content'] ) ? '' : $data['comment_content'];
  2006 	$comment_karma    = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma'];
  2010 	$comment_karma    = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma'];
  2007 	$comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved'];
  2011 	$comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved'];
  2008 	$comment_agent    = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent'];
  2012 	$comment_agent    = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent'];
  2009 	$comment_type     = empty( $data['comment_type'] ) ? 'comment' : $data['comment_type'];
  2013 	$comment_type     = empty( $data['comment_type'] ) ? 'comment' : $data['comment_type'];
  2010 	$comment_parent   = ! isset( $data['comment_parent'] ) ? 0 : $data['comment_parent'];
  2014 	$comment_parent   = ! isset( $data['comment_parent'] ) ? 0 : $data['comment_parent'];
  2011 
  2015 
  2012 	$user_id = ! isset( $data['user_id'] ) ? 0 : $data['user_id'];
  2016 	$user_id = ! isset( $data['user_id'] ) ? 0 : $data['user_id'];
  2013 
  2017 
  2014 	$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' );
  2018 	$compacted = array(
       
  2019 		'comment_post_ID'   => $comment_post_id,
       
  2020 		'comment_author_IP' => $comment_author_ip,
       
  2021 	);
       
  2022 
       
  2023 	$compacted += compact(
       
  2024 		'comment_author',
       
  2025 		'comment_author_email',
       
  2026 		'comment_author_url',
       
  2027 		'comment_date',
       
  2028 		'comment_date_gmt',
       
  2029 		'comment_content',
       
  2030 		'comment_karma',
       
  2031 		'comment_approved',
       
  2032 		'comment_agent',
       
  2033 		'comment_type',
       
  2034 		'comment_parent',
       
  2035 		'user_id'
       
  2036 	);
       
  2037 
  2015 	if ( ! $wpdb->insert( $wpdb->comments, $compacted ) ) {
  2038 	if ( ! $wpdb->insert( $wpdb->comments, $compacted ) ) {
  2016 		return false;
  2039 		return false;
  2017 	}
  2040 	}
  2018 
  2041 
  2019 	$id = (int) $wpdb->insert_id;
  2042 	$id = (int) $wpdb->insert_id;
  2020 
  2043 
  2021 	if ( 1 == $comment_approved ) {
  2044 	if ( 1 == $comment_approved ) {
  2022 		wp_update_comment_count( $comment_post_ID );
  2045 		wp_update_comment_count( $comment_post_id );
  2023 
  2046 
  2024 		$data = array();
  2047 		$data = array();
  2025 		foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
  2048 		foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
  2026 			$data[] = "lastcommentmodified:$timezone";
  2049 			$data[] = "lastcommentmodified:$timezone";
  2027 		}
  2050 		}
  2067 function wp_filter_comment( $commentdata ) {
  2090 function wp_filter_comment( $commentdata ) {
  2068 	if ( isset( $commentdata['user_ID'] ) ) {
  2091 	if ( isset( $commentdata['user_ID'] ) ) {
  2069 		/**
  2092 		/**
  2070 		 * Filters the comment author's user ID before it is set.
  2093 		 * Filters the comment author's user ID before it is set.
  2071 		 *
  2094 		 *
  2072 		 * The first time this filter is evaluated, 'user_ID' is checked
  2095 		 * The first time this filter is evaluated, `user_ID` is checked
  2073 		 * (for back-compat), followed by the standard 'user_id' value.
  2096 		 * (for back-compat), followed by the standard `user_id` value.
  2074 		 *
  2097 		 *
  2075 		 * @since 1.5.0
  2098 		 * @since 1.5.0
  2076 		 *
  2099 		 *
  2077 		 * @param int $user_ID The comment author's user ID.
  2100 		 * @param int $user_id The comment author's user ID.
  2078 		 */
  2101 		 */
  2079 		$commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_ID'] );
  2102 		$commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_ID'] );
  2080 	} elseif ( isset( $commentdata['user_id'] ) ) {
  2103 	} elseif ( isset( $commentdata['user_id'] ) ) {
  2081 		/** This filter is documented in wp-includes/comment.php */
  2104 		/** This filter is documented in wp-includes/comment.php */
  2082 		$commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_id'] );
  2105 		$commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_id'] );
  2110 	$commentdata['comment_author_IP'] = apply_filters( 'pre_comment_user_ip', $commentdata['comment_author_IP'] );
  2133 	$commentdata['comment_author_IP'] = apply_filters( 'pre_comment_user_ip', $commentdata['comment_author_IP'] );
  2111 	/** This filter is documented in wp-includes/comment.php */
  2134 	/** This filter is documented in wp-includes/comment.php */
  2112 	$commentdata['comment_author_url'] = apply_filters( 'pre_comment_author_url', $commentdata['comment_author_url'] );
  2135 	$commentdata['comment_author_url'] = apply_filters( 'pre_comment_author_url', $commentdata['comment_author_url'] );
  2113 	/** This filter is documented in wp-includes/comment.php */
  2136 	/** This filter is documented in wp-includes/comment.php */
  2114 	$commentdata['comment_author_email'] = apply_filters( 'pre_comment_author_email', $commentdata['comment_author_email'] );
  2137 	$commentdata['comment_author_email'] = apply_filters( 'pre_comment_author_email', $commentdata['comment_author_email'] );
  2115 	$commentdata['filtered']             = true;
  2138 
       
  2139 	$commentdata['filtered'] = true;
       
  2140 
  2116 	return $commentdata;
  2141 	return $commentdata;
  2117 }
  2142 }
  2118 
  2143 
  2119 /**
  2144 /**
  2120  * Determines whether a comment should be blocked because of comment flood.
  2145  * Determines whether a comment should be blocked because of comment flood.
  2184  * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure.
  2209  * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure.
  2185  */
  2210  */
  2186 function wp_new_comment( $commentdata, $wp_error = false ) {
  2211 function wp_new_comment( $commentdata, $wp_error = false ) {
  2187 	global $wpdb;
  2212 	global $wpdb;
  2188 
  2213 
       
  2214 	/*
       
  2215 	 * Normalize `user_ID` to `user_id`, but pass the old key
       
  2216 	 * to the `preprocess_comment` filter for backward compatibility.
       
  2217 	 */
  2189 	if ( isset( $commentdata['user_ID'] ) ) {
  2218 	if ( isset( $commentdata['user_ID'] ) ) {
  2190 		$commentdata['user_ID'] = (int) $commentdata['user_ID'];
  2219 		$commentdata['user_ID'] = (int) $commentdata['user_ID'];
  2191 		$commentdata['user_id'] = $commentdata['user_ID'];
  2220 		$commentdata['user_id'] = $commentdata['user_ID'];
       
  2221 	} elseif ( isset( $commentdata['user_id'] ) ) {
       
  2222 		$commentdata['user_id'] = (int) $commentdata['user_id'];
       
  2223 		$commentdata['user_ID'] = $commentdata['user_id'];
  2192 	}
  2224 	}
  2193 
  2225 
  2194 	$prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0;
  2226 	$prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0;
  2195 
  2227 
  2196 	if ( ! isset( $commentdata['comment_author_IP'] ) ) {
  2228 	if ( ! isset( $commentdata['comment_author_IP'] ) ) {
  2210 	 * @param array $commentdata Comment data.
  2242 	 * @param array $commentdata Comment data.
  2211 	 */
  2243 	 */
  2212 	$commentdata = apply_filters( 'preprocess_comment', $commentdata );
  2244 	$commentdata = apply_filters( 'preprocess_comment', $commentdata );
  2213 
  2245 
  2214 	$commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
  2246 	$commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID'];
       
  2247 
       
  2248 	// Normalize `user_ID` to `user_id` again, after the filter.
  2215 	if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) {
  2249 	if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) {
  2216 		$commentdata['user_ID'] = (int) $commentdata['user_ID'];
  2250 		$commentdata['user_ID'] = (int) $commentdata['user_ID'];
  2217 		$commentdata['user_id'] = $commentdata['user_ID'];
  2251 		$commentdata['user_id'] = $commentdata['user_ID'];
  2218 	} elseif ( isset( $commentdata['user_id'] ) ) {
  2252 	} elseif ( isset( $commentdata['user_id'] ) ) {
  2219 		$commentdata['user_id'] = (int) $commentdata['user_id'];
  2253 		$commentdata['user_id'] = (int) $commentdata['user_id'];
       
  2254 		$commentdata['user_ID'] = $commentdata['user_id'];
  2220 	}
  2255 	}
  2221 
  2256 
  2222 	$commentdata['comment_parent'] = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0;
  2257 	$commentdata['comment_parent'] = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0;
  2223 
  2258 
  2224 	$parent_status = ( $commentdata['comment_parent'] > 0 ) ? wp_get_comment_status( $commentdata['comment_parent'] ) : '';
  2259 	$parent_status = ( $commentdata['comment_parent'] > 0 ) ? wp_get_comment_status( $commentdata['comment_parent'] ) : '';
  2242 	}
  2277 	}
  2243 
  2278 
  2244 	$commentdata = wp_filter_comment( $commentdata );
  2279 	$commentdata = wp_filter_comment( $commentdata );
  2245 
  2280 
  2246 	$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
  2281 	$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
       
  2282 
  2247 	if ( is_wp_error( $commentdata['comment_approved'] ) ) {
  2283 	if ( is_wp_error( $commentdata['comment_approved'] ) ) {
  2248 		return $commentdata['comment_approved'];
  2284 		return $commentdata['comment_approved'];
  2249 	}
  2285 	}
  2250 
  2286 
  2251 	$comment_ID = wp_insert_comment( $commentdata );
  2287 	$comment_id = wp_insert_comment( $commentdata );
  2252 	if ( ! $comment_ID ) {
  2288 
       
  2289 	if ( ! $comment_id ) {
  2253 		$fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' );
  2290 		$fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' );
  2254 
  2291 
  2255 		foreach ( $fields as $field ) {
  2292 		foreach ( $fields as $field ) {
  2256 			if ( isset( $commentdata[ $field ] ) ) {
  2293 			if ( isset( $commentdata[ $field ] ) ) {
  2257 				$commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] );
  2294 				$commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] );
  2263 		$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
  2300 		$commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error );
  2264 		if ( is_wp_error( $commentdata['comment_approved'] ) ) {
  2301 		if ( is_wp_error( $commentdata['comment_approved'] ) ) {
  2265 			return $commentdata['comment_approved'];
  2302 			return $commentdata['comment_approved'];
  2266 		}
  2303 		}
  2267 
  2304 
  2268 		$comment_ID = wp_insert_comment( $commentdata );
  2305 		$comment_id = wp_insert_comment( $commentdata );
  2269 		if ( ! $comment_ID ) {
  2306 		if ( ! $comment_id ) {
  2270 			return false;
  2307 			return false;
  2271 		}
  2308 		}
  2272 	}
  2309 	}
  2273 
  2310 
  2274 	/**
  2311 	/**
  2275 	 * Fires immediately after a comment is inserted into the database.
  2312 	 * Fires immediately after a comment is inserted into the database.
  2276 	 *
  2313 	 *
  2277 	 * @since 1.2.0
  2314 	 * @since 1.2.0
  2278 	 * @since 4.5.0 The `$commentdata` parameter was added.
  2315 	 * @since 4.5.0 The `$commentdata` parameter was added.
  2279 	 *
  2316 	 *
  2280 	 * @param int        $comment_ID       The comment ID.
  2317 	 * @param int        $comment_id       The comment ID.
  2281 	 * @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
  2318 	 * @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
  2282 	 * @param array      $commentdata      Comment data.
  2319 	 * @param array      $commentdata      Comment data.
  2283 	 */
  2320 	 */
  2284 	do_action( 'comment_post', $comment_ID, $commentdata['comment_approved'], $commentdata );
  2321 	do_action( 'comment_post', $comment_id, $commentdata['comment_approved'], $commentdata );
  2285 
  2322 
  2286 	return $comment_ID;
  2323 	return $comment_id;
  2287 }
  2324 }
  2288 
  2325 
  2289 /**
  2326 /**
  2290  * Sends a comment moderation notification to the comment moderator.
  2327  * Sends a comment moderation notification to the comment moderator.
  2291  *
  2328  *
  2292  * @since 4.4.0
  2329  * @since 4.4.0
  2293  *
  2330  *
  2294  * @param int $comment_ID ID of the comment.
  2331  * @param int $comment_id ID of the comment.
  2295  * @return bool True on success, false on failure.
  2332  * @return bool True on success, false on failure.
  2296  */
  2333  */
  2297 function wp_new_comment_notify_moderator( $comment_ID ) {
  2334 function wp_new_comment_notify_moderator( $comment_id ) {
  2298 	$comment = get_comment( $comment_ID );
  2335 	$comment = get_comment( $comment_id );
  2299 
  2336 
  2300 	// Only send notifications for pending comments.
  2337 	// Only send notifications for pending comments.
  2301 	$maybe_notify = ( '0' == $comment->comment_approved );
  2338 	$maybe_notify = ( '0' == $comment->comment_approved );
  2302 
  2339 
  2303 	/** This filter is documented in wp-includes/comment.php */
  2340 	/** This filter is documented in wp-includes/pluggable.php */
  2304 	$maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_ID );
  2341 	$maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id );
  2305 
  2342 
  2306 	if ( ! $maybe_notify ) {
  2343 	if ( ! $maybe_notify ) {
  2307 		return false;
  2344 		return false;
  2308 	}
  2345 	}
  2309 
  2346 
  2310 	return wp_notify_moderator( $comment_ID );
  2347 	return wp_notify_moderator( $comment_id );
  2311 }
  2348 }
  2312 
  2349 
  2313 /**
  2350 /**
  2314  * Sends a notification of a new comment to the post author.
  2351  * Sends a notification of a new comment to the post author.
  2315  *
  2352  *
  2316  * @since 4.4.0
  2353  * @since 4.4.0
  2317  *
  2354  *
  2318  * Uses the {@see 'notify_post_author'} filter to determine whether the post author
  2355  * Uses the {@see 'notify_post_author'} filter to determine whether the post author
  2319  * should be notified when a new comment is added, overriding site setting.
  2356  * should be notified when a new comment is added, overriding site setting.
  2320  *
  2357  *
  2321  * @param int $comment_ID Comment ID.
  2358  * @param int $comment_id Comment ID.
  2322  * @return bool True on success, false on failure.
  2359  * @return bool True on success, false on failure.
  2323  */
  2360  */
  2324 function wp_new_comment_notify_postauthor( $comment_ID ) {
  2361 function wp_new_comment_notify_postauthor( $comment_id ) {
  2325 	$comment = get_comment( $comment_ID );
  2362 	$comment = get_comment( $comment_id );
  2326 
  2363 
  2327 	$maybe_notify = get_option( 'comments_notify' );
  2364 	$maybe_notify = get_option( 'comments_notify' );
  2328 
  2365 
  2329 	/**
  2366 	/**
  2330 	 * Filters whether to send the post author new comment notification emails,
  2367 	 * Filters whether to send the post author new comment notification emails,
  2331 	 * overriding the site setting.
  2368 	 * overriding the site setting.
  2332 	 *
  2369 	 *
  2333 	 * @since 4.4.0
  2370 	 * @since 4.4.0
  2334 	 *
  2371 	 *
  2335 	 * @param bool $maybe_notify Whether to notify the post author about the new comment.
  2372 	 * @param bool $maybe_notify Whether to notify the post author about the new comment.
  2336 	 * @param int  $comment_ID   The ID of the comment for the notification.
  2373 	 * @param int  $comment_id   The ID of the comment for the notification.
  2337 	 */
  2374 	 */
  2338 	$maybe_notify = apply_filters( 'notify_post_author', $maybe_notify, $comment_ID );
  2375 	$maybe_notify = apply_filters( 'notify_post_author', $maybe_notify, $comment_id );
  2339 
  2376 
  2340 	/*
  2377 	/*
  2341 	 * wp_notify_postauthor() checks if notifying the author of their own comment.
  2378 	 * wp_notify_postauthor() checks if notifying the author of their own comment.
  2342 	 * By default, it won't, but filters can override this.
  2379 	 * By default, it won't, but filters can override this.
  2343 	 */
  2380 	 */
  2348 	// Only send notifications for approved comments.
  2385 	// Only send notifications for approved comments.
  2349 	if ( ! isset( $comment->comment_approved ) || '1' != $comment->comment_approved ) {
  2386 	if ( ! isset( $comment->comment_approved ) || '1' != $comment->comment_approved ) {
  2350 		return false;
  2387 		return false;
  2351 	}
  2388 	}
  2352 
  2389 
  2353 	return wp_notify_postauthor( $comment_ID );
  2390 	return wp_notify_postauthor( $comment_id );
  2354 }
  2391 }
  2355 
  2392 
  2356 /**
  2393 /**
  2357  * Sets the status of a comment.
  2394  * Sets the status of a comment.
  2358  *
  2395  *
  2445 function wp_update_comment( $commentarr, $wp_error = false ) {
  2482 function wp_update_comment( $commentarr, $wp_error = false ) {
  2446 	global $wpdb;
  2483 	global $wpdb;
  2447 
  2484 
  2448 	// First, get all of the original fields.
  2485 	// First, get all of the original fields.
  2449 	$comment = get_comment( $commentarr['comment_ID'], ARRAY_A );
  2486 	$comment = get_comment( $commentarr['comment_ID'], ARRAY_A );
       
  2487 
  2450 	if ( empty( $comment ) ) {
  2488 	if ( empty( $comment ) ) {
  2451 		if ( $wp_error ) {
  2489 		if ( $wp_error ) {
  2452 			return new WP_Error( 'invalid_comment_id', __( 'Invalid comment ID.' ) );
  2490 			return new WP_Error( 'invalid_comment_id', __( 'Invalid comment ID.' ) );
  2453 		} else {
  2491 		} else {
  2454 			return false;
  2492 			return false;
  2462 		} else {
  2500 		} else {
  2463 			return false;
  2501 			return false;
  2464 		}
  2502 		}
  2465 	}
  2503 	}
  2466 
  2504 
       
  2505 	$filter_comment = false;
       
  2506 	if ( ! has_filter( 'pre_comment_content', 'wp_filter_kses' ) ) {
       
  2507 		$filter_comment = ! user_can( isset( $comment['user_id'] ) ? $comment['user_id'] : 0, 'unfiltered_html' );
       
  2508 	}
       
  2509 
       
  2510 	if ( $filter_comment ) {
       
  2511 		add_filter( 'pre_comment_content', 'wp_filter_kses' );
       
  2512 	}
       
  2513 
  2467 	// Escape data pulled from DB.
  2514 	// Escape data pulled from DB.
  2468 	$comment = wp_slash( $comment );
  2515 	$comment = wp_slash( $comment );
  2469 
  2516 
  2470 	$old_status = $comment['comment_approved'];
  2517 	$old_status = $comment['comment_approved'];
  2471 
  2518 
  2472 	// Merge old and new fields with new fields overwriting old ones.
  2519 	// Merge old and new fields with new fields overwriting old ones.
  2473 	$commentarr = array_merge( $comment, $commentarr );
  2520 	$commentarr = array_merge( $comment, $commentarr );
  2474 
  2521 
  2475 	$commentarr = wp_filter_comment( $commentarr );
  2522 	$commentarr = wp_filter_comment( $commentarr );
       
  2523 
       
  2524 	if ( $filter_comment ) {
       
  2525 		remove_filter( 'pre_comment_content', 'wp_filter_kses' );
       
  2526 	}
  2476 
  2527 
  2477 	// Now extract the merged array.
  2528 	// Now extract the merged array.
  2478 	$data = wp_unslash( $commentarr );
  2529 	$data = wp_unslash( $commentarr );
  2479 
  2530 
  2480 	/**
  2531 	/**
  2494 		$data['comment_approved'] = 0;
  2545 		$data['comment_approved'] = 0;
  2495 	} elseif ( 'approve' === $data['comment_approved'] ) {
  2546 	} elseif ( 'approve' === $data['comment_approved'] ) {
  2496 		$data['comment_approved'] = 1;
  2547 		$data['comment_approved'] = 1;
  2497 	}
  2548 	}
  2498 
  2549 
  2499 	$comment_ID      = $data['comment_ID'];
  2550 	$comment_id      = $data['comment_ID'];
  2500 	$comment_post_ID = $data['comment_post_ID'];
  2551 	$comment_post_id = $data['comment_post_ID'];
  2501 
  2552 
  2502 	/**
  2553 	/**
  2503 	 * Filters the comment data immediately before it is updated in the database.
  2554 	 * Filters the comment data immediately before it is updated in the database.
  2504 	 *
  2555 	 *
  2505 	 * Note: data being passed to the filter is already unslashed.
  2556 	 * Note: data being passed to the filter is already unslashed.
  2521 		} else {
  2572 		} else {
  2522 			return false;
  2573 			return false;
  2523 		}
  2574 		}
  2524 	}
  2575 	}
  2525 
  2576 
  2526 	$keys = array( 'comment_post_ID', 'comment_content', 'comment_author', 'comment_author_email', 'comment_approved', 'comment_karma', 'comment_author_url', 'comment_date', 'comment_date_gmt', 'comment_type', 'comment_parent', 'user_id', 'comment_agent', 'comment_author_IP' );
  2577 	$keys = array(
       
  2578 		'comment_post_ID',
       
  2579 		'comment_author',
       
  2580 		'comment_author_email',
       
  2581 		'comment_author_url',
       
  2582 		'comment_author_IP',
       
  2583 		'comment_date',
       
  2584 		'comment_date_gmt',
       
  2585 		'comment_content',
       
  2586 		'comment_karma',
       
  2587 		'comment_approved',
       
  2588 		'comment_agent',
       
  2589 		'comment_type',
       
  2590 		'comment_parent',
       
  2591 		'user_id',
       
  2592 	);
       
  2593 
  2527 	$data = wp_array_slice_assoc( $data, $keys );
  2594 	$data = wp_array_slice_assoc( $data, $keys );
  2528 
  2595 
  2529 	$rval = $wpdb->update( $wpdb->comments, $data, compact( 'comment_ID' ) );
  2596 	$result = $wpdb->update( $wpdb->comments, $data, array( 'comment_ID' => $comment_id ) );
  2530 
  2597 
  2531 	if ( false === $rval ) {
  2598 	if ( false === $result ) {
  2532 		if ( $wp_error ) {
  2599 		if ( $wp_error ) {
  2533 			return new WP_Error( 'db_update_error', __( 'Could not update comment in the database.' ), $wpdb->last_error );
  2600 			return new WP_Error( 'db_update_error', __( 'Could not update comment in the database.' ), $wpdb->last_error );
  2534 		} else {
  2601 		} else {
  2535 			return false;
  2602 			return false;
  2536 		}
  2603 		}
  2537 	}
  2604 	}
  2538 
  2605 
  2539 	// If metadata is provided, store it.
  2606 	// If metadata is provided, store it.
  2540 	if ( isset( $commentarr['comment_meta'] ) && is_array( $commentarr['comment_meta'] ) ) {
  2607 	if ( isset( $commentarr['comment_meta'] ) && is_array( $commentarr['comment_meta'] ) ) {
  2541 		foreach ( $commentarr['comment_meta'] as $meta_key => $meta_value ) {
  2608 		foreach ( $commentarr['comment_meta'] as $meta_key => $meta_value ) {
  2542 			update_comment_meta( $comment_ID, $meta_key, $meta_value );
  2609 			update_comment_meta( $comment_id, $meta_key, $meta_value );
  2543 		}
  2610 		}
  2544 	}
  2611 	}
  2545 
  2612 
  2546 	clean_comment_cache( $comment_ID );
  2613 	clean_comment_cache( $comment_id );
  2547 	wp_update_comment_count( $comment_post_ID );
  2614 	wp_update_comment_count( $comment_post_id );
  2548 
  2615 
  2549 	/**
  2616 	/**
  2550 	 * Fires immediately after a comment is updated in the database.
  2617 	 * Fires immediately after a comment is updated in the database.
  2551 	 *
  2618 	 *
  2552 	 * The hook also fires immediately before comment status transition hooks are fired.
  2619 	 * The hook also fires immediately before comment status transition hooks are fired.
  2553 	 *
  2620 	 *
  2554 	 * @since 1.2.0
  2621 	 * @since 1.2.0
  2555 	 * @since 4.6.0 Added the `$data` parameter.
  2622 	 * @since 4.6.0 Added the `$data` parameter.
  2556 	 *
  2623 	 *
  2557 	 * @param int   $comment_ID The comment ID.
  2624 	 * @param int   $comment_id The comment ID.
  2558 	 * @param array $data       Comment data.
  2625 	 * @param array $data       Comment data.
  2559 	 */
  2626 	 */
  2560 	do_action( 'edit_comment', $comment_ID, $data );
  2627 	do_action( 'edit_comment', $comment_id, $data );
  2561 
  2628 
  2562 	$comment = get_comment( $comment_ID );
  2629 	$comment = get_comment( $comment_id );
  2563 
  2630 
  2564 	wp_transition_comment_status( $comment->comment_approved, $old_status, $comment );
  2631 	wp_transition_comment_status( $comment->comment_approved, $old_status, $comment );
  2565 
  2632 
  2566 	return $rval;
  2633 	return $result;
  2567 }
  2634 }
  2568 
  2635 
  2569 /**
  2636 /**
  2570  * Determines whether to defer comment counting.
  2637  * Determines whether to defer comment counting.
  2571  *
  2638  *
  2634 		$_deferred[] = $post_id;
  2701 		$_deferred[] = $post_id;
  2635 		return true;
  2702 		return true;
  2636 	} elseif ( $post_id ) {
  2703 	} elseif ( $post_id ) {
  2637 		return wp_update_comment_count_now( $post_id );
  2704 		return wp_update_comment_count_now( $post_id );
  2638 	}
  2705 	}
  2639 
       
  2640 }
  2706 }
  2641 
  2707 
  2642 /**
  2708 /**
  2643  * Updates the comment count for the post.
  2709  * Updates the comment count for the post.
  2644  *
  2710  *
  2649  * @param int $post_id Post ID
  2715  * @param int $post_id Post ID
  2650  * @return bool True on success, false if the post does not exist.
  2716  * @return bool True on success, false if the post does not exist.
  2651  */
  2717  */
  2652 function wp_update_comment_count_now( $post_id ) {
  2718 function wp_update_comment_count_now( $post_id ) {
  2653 	global $wpdb;
  2719 	global $wpdb;
       
  2720 
  2654 	$post_id = (int) $post_id;
  2721 	$post_id = (int) $post_id;
       
  2722 
  2655 	if ( ! $post_id ) {
  2723 	if ( ! $post_id ) {
  2656 		return false;
  2724 		return false;
  2657 	}
  2725 	}
  2658 
  2726 
  2659 	wp_cache_delete( 'comments-0', 'counts' );
  2727 	wp_cache_delete( 'comments-0', 'counts' );
  2660 	wp_cache_delete( "comments-{$post_id}", 'counts' );
  2728 	wp_cache_delete( "comments-{$post_id}", 'counts' );
  2661 
  2729 
  2662 	$post = get_post( $post_id );
  2730 	$post = get_post( $post_id );
       
  2731 
  2663 	if ( ! $post ) {
  2732 	if ( ! $post ) {
  2664 		return false;
  2733 		return false;
  2665 	}
  2734 	}
  2666 
  2735 
  2667 	$old = (int) $post->comment_count;
  2736 	$old = (int) $post->comment_count;
  2712 //
  2781 //
  2713 
  2782 
  2714 /**
  2783 /**
  2715  * Finds a pingback server URI based on the given URL.
  2784  * Finds a pingback server URI based on the given URL.
  2716  *
  2785  *
  2717  * Checks the HTML for the rel="pingback" link and x-pingback headers. It does
  2786  * Checks the HTML for the rel="pingback" link and X-Pingback headers. It does
  2718  * a check for the x-pingback headers first and returns that, if available. The
  2787  * a check for the X-Pingback headers first and returns that, if available.
  2719  * check for the rel="pingback" has more overhead than just the header.
  2788  * The check for the rel="pingback" has more overhead than just the header.
  2720  *
  2789  *
  2721  * @since 1.5.0
  2790  * @since 1.5.0
  2722  *
  2791  *
  2723  * @param string $url        URL to ping.
  2792  * @param string $url        URL to ping.
  2724  * @param string $deprecated Not Used.
  2793  * @param string $deprecated Not Used.
  2739 		return false;
  2808 		return false;
  2740 	}
  2809 	}
  2741 
  2810 
  2742 	// Do not search for a pingback server on our own uploads.
  2811 	// Do not search for a pingback server on our own uploads.
  2743 	$uploads_dir = wp_get_upload_dir();
  2812 	$uploads_dir = wp_get_upload_dir();
  2744 	if ( 0 === strpos( $url, $uploads_dir['baseurl'] ) ) {
  2813 	if ( str_starts_with( $url, $uploads_dir['baseurl'] ) ) {
  2745 		return false;
  2814 		return false;
  2746 	}
  2815 	}
  2747 
  2816 
  2748 	$response = wp_safe_remote_head(
  2817 	$response = wp_safe_remote_head(
  2749 		$url,
  2818 		$url,
  2755 
  2824 
  2756 	if ( is_wp_error( $response ) ) {
  2825 	if ( is_wp_error( $response ) ) {
  2757 		return false;
  2826 		return false;
  2758 	}
  2827 	}
  2759 
  2828 
  2760 	if ( wp_remote_retrieve_header( $response, 'x-pingback' ) ) {
  2829 	if ( wp_remote_retrieve_header( $response, 'X-Pingback' ) ) {
  2761 		return wp_remote_retrieve_header( $response, 'x-pingback' );
  2830 		return wp_remote_retrieve_header( $response, 'X-Pingback' );
  2762 	}
  2831 	}
  2763 
  2832 
  2764 	// Not an (x)html, sgml, or xml page, no use going further.
  2833 	// Not an (x)html, sgml, or xml page, no use going further.
  2765 	if ( preg_match( '#(image|audio|video|model)/#is', wp_remote_retrieve_header( $response, 'content-type' ) ) ) {
  2834 	if ( preg_match( '#(image|audio|video|model)/#is', wp_remote_retrieve_header( $response, 'Content-Type' ) ) ) {
  2766 		return false;
  2835 		return false;
  2767 	}
  2836 	}
  2768 
  2837 
  2769 	// Now do a GET since we're going to look in the HTML headers (and we're sure it's not a binary file).
  2838 	// Now do a GET since we're going to look in the HTML headers (and we're sure it's not a binary file).
  2770 	$response = wp_safe_remote_get(
  2839 	$response = wp_safe_remote_get(
  2884 
  2953 
  2885 /**
  2954 /**
  2886  * Performs trackbacks.
  2955  * Performs trackbacks.
  2887  *
  2956  *
  2888  * @since 1.5.0
  2957  * @since 1.5.0
  2889  * @since 4.7.0 `$post_id` can be a WP_Post object.
  2958  * @since 4.7.0 `$post` can be a WP_Post object.
  2890  *
  2959  *
  2891  * @global wpdb $wpdb WordPress database abstraction object.
  2960  * @global wpdb $wpdb WordPress database abstraction object.
  2892  *
  2961  *
  2893  * @param int|WP_Post $post_id Post object or ID to do trackbacks on.
  2962  * @param int|WP_Post $post Post ID or object to do trackbacks on.
  2894  */
  2963  * @return void|false Returns false on failure.
  2895 function do_trackbacks( $post_id ) {
  2964  */
       
  2965 function do_trackbacks( $post ) {
  2896 	global $wpdb;
  2966 	global $wpdb;
  2897 	$post = get_post( $post_id );
  2967 
       
  2968 	$post = get_post( $post );
       
  2969 
  2898 	if ( ! $post ) {
  2970 	if ( ! $post ) {
  2899 		return false;
  2971 		return false;
  2900 	}
  2972 	}
  2901 
  2973 
  2902 	$to_ping = get_to_ping( $post );
  2974 	$to_ping = get_to_ping( $post );
  2903 	$pinged  = get_pung( $post );
  2975 	$pinged  = get_pung( $post );
       
  2976 
  2904 	if ( empty( $to_ping ) ) {
  2977 	if ( empty( $to_ping ) ) {
  2905 		$wpdb->update( $wpdb->posts, array( 'to_ping' => '' ), array( 'ID' => $post->ID ) );
  2978 		$wpdb->update( $wpdb->posts, array( 'to_ping' => '' ), array( 'ID' => $post->ID ) );
  2906 		return;
  2979 		return;
  2907 	}
  2980 	}
  2908 
  2981 
  2945  * Sends pings to all of the ping site services.
  3018  * Sends pings to all of the ping site services.
  2946  *
  3019  *
  2947  * @since 1.2.0
  3020  * @since 1.2.0
  2948  *
  3021  *
  2949  * @param int $post_id Post ID.
  3022  * @param int $post_id Post ID.
  2950  * @return int Same as Post ID from parameter
  3023  * @return int Same post ID as provided.
  2951  */
  3024  */
  2952 function generic_ping( $post_id = 0 ) {
  3025 function generic_ping( $post_id = 0 ) {
  2953 	$services = get_option( 'ping_sites' );
  3026 	$services = get_option( 'ping_sites' );
  2954 
  3027 
  2955 	$services = explode( "\n", $services );
  3028 	$services = explode( "\n", $services );
  2965 
  3038 
  2966 /**
  3039 /**
  2967  * Pings back the links found in a post.
  3040  * Pings back the links found in a post.
  2968  *
  3041  *
  2969  * @since 0.71
  3042  * @since 0.71
  2970  * @since 4.7.0 `$post_id` can be a WP_Post object.
  3043  * @since 4.7.0 `$post` can be a WP_Post object.
  2971  *
  3044  *
  2972  * @param string      $content Post content to check for links. If empty will retrieve from post.
  3045  * @param string      $content Post content to check for links. If empty will retrieve from post.
  2973  * @param int|WP_Post $post_id Post Object or ID.
  3046  * @param int|WP_Post $post    Post ID or object.
  2974  */
  3047  */
  2975 function pingback( $content, $post_id ) {
  3048 function pingback( $content, $post ) {
  2976 	include_once ABSPATH . WPINC . '/class-IXR.php';
  3049 	require_once ABSPATH . WPINC . '/class-IXR.php';
  2977 	include_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
  3050 	require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
  2978 
  3051 
  2979 	// Original code by Mort (http://mort.mine.nu:8080).
  3052 	// Original code by Mort (http://mort.mine.nu:8080).
  2980 	$post_links = array();
  3053 	$post_links = array();
  2981 
  3054 
  2982 	$post = get_post( $post_id );
  3055 	$post = get_post( $post );
       
  3056 
  2983 	if ( ! $post ) {
  3057 	if ( ! $post ) {
  2984 		return;
  3058 		return;
  2985 	}
  3059 	}
  2986 
  3060 
  2987 	$pung = get_pung( $post );
  3061 	$pung = get_pung( $post );
  3030 	 *
  3104 	 *
  3031 	 * @since 2.0.0
  3105 	 * @since 2.0.0
  3032 	 *
  3106 	 *
  3033 	 * @param string[] $post_links Array of link URLs to be checked (passed by reference).
  3107 	 * @param string[] $post_links Array of link URLs to be checked (passed by reference).
  3034 	 * @param string[] $pung       Array of link URLs already pinged (passed by reference).
  3108 	 * @param string[] $pung       Array of link URLs already pinged (passed by reference).
  3035 	 * @param int      $post_ID    The post ID.
  3109 	 * @param int      $post_id    The post ID.
  3036 	 */
  3110 	 */
  3037 	do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post->ID ) );
  3111 	do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post->ID ) );
  3038 
  3112 
  3039 	foreach ( (array) $post_links as $pagelinkedto ) {
  3113 	foreach ( (array) $post_links as $pagelinkedto ) {
  3040 		$pingback_server_url = discover_pingback_server_uri( $pagelinkedto );
  3114 		$pingback_server_url = discover_pingback_server_uri( $pagelinkedto );
  3041 
  3115 
  3042 		if ( $pingback_server_url ) {
  3116 		if ( $pingback_server_url ) {
  3043 			set_time_limit( 60 );
  3117 			if ( function_exists( 'set_time_limit' ) ) {
       
  3118 				set_time_limit( 60 );
       
  3119 			}
       
  3120 
  3044 			// Now, the RPC call.
  3121 			// Now, the RPC call.
  3045 			$pagelinkedfrom = get_permalink( $post );
  3122 			$pagelinkedfrom = get_permalink( $post );
  3046 
  3123 
  3047 			// Using a timeout of 3 seconds should be enough to cover slow servers.
  3124 			// Using a timeout of 3 seconds should be enough to cover slow servers.
  3048 			$client          = new WP_HTTP_IXR_Client( $pingback_server_url );
  3125 			$client          = new WP_HTTP_IXR_Client( $pingback_server_url );
  3096  * @global wpdb $wpdb WordPress database abstraction object.
  3173  * @global wpdb $wpdb WordPress database abstraction object.
  3097  *
  3174  *
  3098  * @param string $trackback_url URL to send trackbacks.
  3175  * @param string $trackback_url URL to send trackbacks.
  3099  * @param string $title         Title of post.
  3176  * @param string $title         Title of post.
  3100  * @param string $excerpt       Excerpt of post.
  3177  * @param string $excerpt       Excerpt of post.
  3101  * @param int    $ID            Post ID.
  3178  * @param int    $post_id       Post ID.
  3102  * @return int|false|void Database query from update.
  3179  * @return int|false|void Database query from update.
  3103  */
  3180  */
  3104 function trackback( $trackback_url, $title, $excerpt, $ID ) {
  3181 function trackback( $trackback_url, $title, $excerpt, $post_id ) {
  3105 	global $wpdb;
  3182 	global $wpdb;
  3106 
  3183 
  3107 	if ( empty( $trackback_url ) ) {
  3184 	if ( empty( $trackback_url ) ) {
  3108 		return;
  3185 		return;
  3109 	}
  3186 	}
  3110 
  3187 
  3111 	$options            = array();
  3188 	$options            = array();
  3112 	$options['timeout'] = 10;
  3189 	$options['timeout'] = 10;
  3113 	$options['body']    = array(
  3190 	$options['body']    = array(
  3114 		'title'     => $title,
  3191 		'title'     => $title,
  3115 		'url'       => get_permalink( $ID ),
  3192 		'url'       => get_permalink( $post_id ),
  3116 		'blog_name' => get_option( 'blogname' ),
  3193 		'blog_name' => get_option( 'blogname' ),
  3117 		'excerpt'   => $excerpt,
  3194 		'excerpt'   => $excerpt,
  3118 	);
  3195 	);
  3119 
  3196 
  3120 	$response = wp_safe_remote_post( $trackback_url, $options );
  3197 	$response = wp_safe_remote_post( $trackback_url, $options );
  3121 
  3198 
  3122 	if ( is_wp_error( $response ) ) {
  3199 	if ( is_wp_error( $response ) ) {
  3123 		return;
  3200 		return;
  3124 	}
  3201 	}
  3125 
  3202 
  3126 	$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET pinged = CONCAT(pinged, '\n', %s) WHERE ID = %d", $trackback_url, $ID ) );
  3203 	$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET pinged = CONCAT(pinged, '\n', %s) WHERE ID = %d", $trackback_url, $post_id ) );
  3127 	return $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $trackback_url, $ID ) );
  3204 	return $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $trackback_url, $post_id ) );
  3128 }
  3205 }
  3129 
  3206 
  3130 /**
  3207 /**
  3131  * Sends a pingback.
  3208  * Sends a pingback.
  3132  *
  3209  *
  3134  *
  3211  *
  3135  * @param string $server Host of blog to connect to.
  3212  * @param string $server Host of blog to connect to.
  3136  * @param string $path Path to send the ping.
  3213  * @param string $path Path to send the ping.
  3137  */
  3214  */
  3138 function weblog_ping( $server = '', $path = '' ) {
  3215 function weblog_ping( $server = '', $path = '' ) {
  3139 	include_once ABSPATH . WPINC . '/class-IXR.php';
  3216 	require_once ABSPATH . WPINC . '/class-IXR.php';
  3140 	include_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
  3217 	require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
  3141 
  3218 
  3142 	// Using a timeout of 3 seconds should be enough to cover slow servers.
  3219 	// Using a timeout of 3 seconds should be enough to cover slow servers.
  3143 	$client             = new WP_HTTP_IXR_Client( $server, ( ( ! strlen( trim( $path ) ) || ( '/' === $path ) ) ? false : $path ) );
  3220 	$client             = new WP_HTTP_IXR_Client( $server, ( ( ! strlen( trim( $path ) ) || ( '/' === $path ) ) ? false : $path ) );
  3144 	$client->timeout    = 3;
  3221 	$client->timeout    = 3;
  3145 	$client->useragent .= ' -- WordPress/' . get_bloginfo( 'version' );
  3222 	$client->useragent .= ' -- WordPress/' . get_bloginfo( 'version' );
  3209 		 * @param int $id Comment ID.
  3286 		 * @param int $id Comment ID.
  3210 		 */
  3287 		 */
  3211 		do_action( 'clean_comment_cache', $id );
  3288 		do_action( 'clean_comment_cache', $id );
  3212 	}
  3289 	}
  3213 
  3290 
  3214 	wp_cache_set( 'last_changed', microtime(), 'comment' );
  3291 	wp_cache_set_comments_last_changed();
  3215 }
  3292 }
  3216 
  3293 
  3217 /**
  3294 /**
  3218  * Updates the comment cache of given comments.
  3295  * Updates the comment cache of given comments.
  3219  *
  3296  *
  3246 
  3323 
  3247 /**
  3324 /**
  3248  * Adds any comments from the given IDs to the cache that do not already exist in cache.
  3325  * Adds any comments from the given IDs to the cache that do not already exist in cache.
  3249  *
  3326  *
  3250  * @since 4.4.0
  3327  * @since 4.4.0
  3251  * @access private
  3328  * @since 6.1.0 This function is no longer marked as "private".
       
  3329  * @since 6.3.0 Use wp_lazyload_comment_meta() for lazy-loading of comment meta.
  3252  *
  3330  *
  3253  * @see update_comment_cache()
  3331  * @see update_comment_cache()
  3254  * @global wpdb $wpdb WordPress database abstraction object.
  3332  * @global wpdb $wpdb WordPress database abstraction object.
  3255  *
  3333  *
  3256  * @param int[] $comment_ids       Array of comment IDs.
  3334  * @param int[] $comment_ids       Array of comment IDs.
  3261 
  3339 
  3262 	$non_cached_ids = _get_non_cached_ids( $comment_ids, 'comment' );
  3340 	$non_cached_ids = _get_non_cached_ids( $comment_ids, 'comment' );
  3263 	if ( ! empty( $non_cached_ids ) ) {
  3341 	if ( ! empty( $non_cached_ids ) ) {
  3264 		$fresh_comments = $wpdb->get_results( sprintf( "SELECT $wpdb->comments.* FROM $wpdb->comments WHERE comment_ID IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) );
  3342 		$fresh_comments = $wpdb->get_results( sprintf( "SELECT $wpdb->comments.* FROM $wpdb->comments WHERE comment_ID IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) );
  3265 
  3343 
  3266 		update_comment_cache( $fresh_comments, $update_meta_cache );
  3344 		update_comment_cache( $fresh_comments, false );
       
  3345 	}
       
  3346 
       
  3347 	if ( $update_meta_cache ) {
       
  3348 		wp_lazyload_comment_meta( $comment_ids );
  3267 	}
  3349 	}
  3268 }
  3350 }
  3269 
  3351 
  3270 //
  3352 //
  3271 // Internal.
  3353 // Internal.
  3375  *     @type string     $_wp_unfiltered_html_comment The nonce value for allowing unfiltered HTML.
  3457  *     @type string     $_wp_unfiltered_html_comment The nonce value for allowing unfiltered HTML.
  3376  * }
  3458  * }
  3377  * @return WP_Comment|WP_Error A WP_Comment object on success, a WP_Error object on failure.
  3459  * @return WP_Comment|WP_Error A WP_Comment object on success, a WP_Error object on failure.
  3378  */
  3460  */
  3379 function wp_handle_comment_submission( $comment_data ) {
  3461 function wp_handle_comment_submission( $comment_data ) {
  3380 
  3462 	$comment_post_id      = 0;
  3381 	$comment_post_ID      = 0;
  3463 	$comment_author       = '';
       
  3464 	$comment_author_email = '';
       
  3465 	$comment_author_url   = '';
       
  3466 	$comment_content      = '';
  3382 	$comment_parent       = 0;
  3467 	$comment_parent       = 0;
  3383 	$user_ID              = 0;
  3468 	$user_id              = 0;
  3384 	$comment_author       = null;
       
  3385 	$comment_author_email = null;
       
  3386 	$comment_author_url   = null;
       
  3387 	$comment_content      = null;
       
  3388 
  3469 
  3389 	if ( isset( $comment_data['comment_post_ID'] ) ) {
  3470 	if ( isset( $comment_data['comment_post_ID'] ) ) {
  3390 		$comment_post_ID = (int) $comment_data['comment_post_ID'];
  3471 		$comment_post_id = (int) $comment_data['comment_post_ID'];
  3391 	}
  3472 	}
  3392 	if ( isset( $comment_data['author'] ) && is_string( $comment_data['author'] ) ) {
  3473 	if ( isset( $comment_data['author'] ) && is_string( $comment_data['author'] ) ) {
  3393 		$comment_author = trim( strip_tags( $comment_data['author'] ) );
  3474 		$comment_author = trim( strip_tags( $comment_data['author'] ) );
  3394 	}
  3475 	}
  3395 	if ( isset( $comment_data['email'] ) && is_string( $comment_data['email'] ) ) {
  3476 	if ( isset( $comment_data['email'] ) && is_string( $comment_data['email'] ) ) {
  3400 	}
  3481 	}
  3401 	if ( isset( $comment_data['comment'] ) && is_string( $comment_data['comment'] ) ) {
  3482 	if ( isset( $comment_data['comment'] ) && is_string( $comment_data['comment'] ) ) {
  3402 		$comment_content = trim( $comment_data['comment'] );
  3483 		$comment_content = trim( $comment_data['comment'] );
  3403 	}
  3484 	}
  3404 	if ( isset( $comment_data['comment_parent'] ) ) {
  3485 	if ( isset( $comment_data['comment_parent'] ) ) {
  3405 		$comment_parent = absint( $comment_data['comment_parent'] );
  3486 		$comment_parent        = absint( $comment_data['comment_parent'] );
  3406 	}
  3487 		$comment_parent_object = get_comment( $comment_parent );
  3407 
  3488 
  3408 	$post = get_post( $comment_post_ID );
  3489 		if (
       
  3490 			0 !== $comment_parent &&
       
  3491 			(
       
  3492 				! $comment_parent_object instanceof WP_Comment ||
       
  3493 				0 === (int) $comment_parent_object->comment_approved
       
  3494 			)
       
  3495 		) {
       
  3496 			/**
       
  3497 			 * Fires when a comment reply is attempted to an unapproved comment.
       
  3498 			 *
       
  3499 			 * @since 6.2.0
       
  3500 			 *
       
  3501 			 * @param int $comment_post_id Post ID.
       
  3502 			 * @param int $comment_parent  Parent comment ID.
       
  3503 			 */
       
  3504 			do_action( 'comment_reply_to_unapproved_comment', $comment_post_id, $comment_parent );
       
  3505 
       
  3506 			return new WP_Error( 'comment_reply_to_unapproved_comment', __( 'Sorry, replies to unapproved comments are not allowed.' ), 403 );
       
  3507 		}
       
  3508 	}
       
  3509 
       
  3510 	$post = get_post( $comment_post_id );
  3409 
  3511 
  3410 	if ( empty( $post->comment_status ) ) {
  3512 	if ( empty( $post->comment_status ) ) {
  3411 
  3513 
  3412 		/**
  3514 		/**
  3413 		 * Fires when a comment is attempted on a post that does not exist.
  3515 		 * Fires when a comment is attempted on a post that does not exist.
  3414 		 *
  3516 		 *
  3415 		 * @since 1.5.0
  3517 		 * @since 1.5.0
  3416 		 *
  3518 		 *
  3417 		 * @param int $comment_post_ID Post ID.
  3519 		 * @param int $comment_post_id Post ID.
  3418 		 */
  3520 		 */
  3419 		do_action( 'comment_id_not_found', $comment_post_ID );
  3521 		do_action( 'comment_id_not_found', $comment_post_id );
  3420 
  3522 
  3421 		return new WP_Error( 'comment_id_not_found' );
  3523 		return new WP_Error( 'comment_id_not_found' );
  3422 
  3524 
  3423 	}
  3525 	}
  3424 
  3526 
  3425 	// get_post_status() will get the parent status for attachments.
  3527 	// get_post_status() will get the parent status for attachments.
  3426 	$status = get_post_status( $post );
  3528 	$status = get_post_status( $post );
  3427 
  3529 
  3428 	if ( ( 'private' === $status ) && ! current_user_can( 'read_post', $comment_post_ID ) ) {
  3530 	if ( ( 'private' === $status ) && ! current_user_can( 'read_post', $comment_post_id ) ) {
  3429 		return new WP_Error( 'comment_id_not_found' );
  3531 		return new WP_Error( 'comment_id_not_found' );
  3430 	}
  3532 	}
  3431 
  3533 
  3432 	$status_obj = get_post_status_object( $status );
  3534 	$status_obj = get_post_status_object( $status );
  3433 
  3535 
  3434 	if ( ! comments_open( $comment_post_ID ) ) {
  3536 	if ( ! comments_open( $comment_post_id ) ) {
  3435 
  3537 
  3436 		/**
  3538 		/**
  3437 		 * Fires when a comment is attempted on a post that has comments closed.
  3539 		 * Fires when a comment is attempted on a post that has comments closed.
  3438 		 *
  3540 		 *
  3439 		 * @since 1.5.0
  3541 		 * @since 1.5.0
  3440 		 *
  3542 		 *
  3441 		 * @param int $comment_post_ID Post ID.
  3543 		 * @param int $comment_post_id Post ID.
  3442 		 */
  3544 		 */
  3443 		do_action( 'comment_closed', $comment_post_ID );
  3545 		do_action( 'comment_closed', $comment_post_id );
  3444 
  3546 
  3445 		return new WP_Error( 'comment_closed', __( 'Sorry, comments are closed for this item.' ), 403 );
  3547 		return new WP_Error( 'comment_closed', __( 'Sorry, comments are closed for this item.' ), 403 );
  3446 
  3548 
  3447 	} elseif ( 'trash' === $status ) {
  3549 	} elseif ( 'trash' === $status ) {
  3448 
  3550 
  3449 		/**
  3551 		/**
  3450 		 * Fires when a comment is attempted on a trashed post.
  3552 		 * Fires when a comment is attempted on a trashed post.
  3451 		 *
  3553 		 *
  3452 		 * @since 2.9.0
  3554 		 * @since 2.9.0
  3453 		 *
  3555 		 *
  3454 		 * @param int $comment_post_ID Post ID.
  3556 		 * @param int $comment_post_id Post ID.
  3455 		 */
  3557 		 */
  3456 		do_action( 'comment_on_trash', $comment_post_ID );
  3558 		do_action( 'comment_on_trash', $comment_post_id );
  3457 
  3559 
  3458 		return new WP_Error( 'comment_on_trash' );
  3560 		return new WP_Error( 'comment_on_trash' );
  3459 
  3561 
  3460 	} elseif ( ! $status_obj->public && ! $status_obj->private ) {
  3562 	} elseif ( ! $status_obj->public && ! $status_obj->private ) {
  3461 
  3563 
  3462 		/**
  3564 		/**
  3463 		 * Fires when a comment is attempted on a post in draft mode.
  3565 		 * Fires when a comment is attempted on a post in draft mode.
  3464 		 *
  3566 		 *
  3465 		 * @since 1.5.1
  3567 		 * @since 1.5.1
  3466 		 *
  3568 		 *
  3467 		 * @param int $comment_post_ID Post ID.
  3569 		 * @param int $comment_post_id Post ID.
  3468 		 */
  3570 		 */
  3469 		do_action( 'comment_on_draft', $comment_post_ID );
  3571 		do_action( 'comment_on_draft', $comment_post_id );
  3470 
  3572 
  3471 		if ( current_user_can( 'read_post', $comment_post_ID ) ) {
  3573 		if ( current_user_can( 'read_post', $comment_post_id ) ) {
  3472 			return new WP_Error( 'comment_on_draft', __( 'Sorry, comments are not allowed for this item.' ), 403 );
  3574 			return new WP_Error( 'comment_on_draft', __( 'Sorry, comments are not allowed for this item.' ), 403 );
  3473 		} else {
  3575 		} else {
  3474 			return new WP_Error( 'comment_on_draft' );
  3576 			return new WP_Error( 'comment_on_draft' );
  3475 		}
  3577 		}
  3476 	} elseif ( post_password_required( $comment_post_ID ) ) {
  3578 	} elseif ( post_password_required( $comment_post_id ) ) {
  3477 
  3579 
  3478 		/**
  3580 		/**
  3479 		 * Fires when a comment is attempted on a password-protected post.
  3581 		 * Fires when a comment is attempted on a password-protected post.
  3480 		 *
  3582 		 *
  3481 		 * @since 2.9.0
  3583 		 * @since 2.9.0
  3482 		 *
  3584 		 *
  3483 		 * @param int $comment_post_ID Post ID.
  3585 		 * @param int $comment_post_id Post ID.
  3484 		 */
  3586 		 */
  3485 		do_action( 'comment_on_password_protected', $comment_post_ID );
  3587 		do_action( 'comment_on_password_protected', $comment_post_id );
  3486 
  3588 
  3487 		return new WP_Error( 'comment_on_password_protected' );
  3589 		return new WP_Error( 'comment_on_password_protected' );
  3488 
  3590 
  3489 	} else {
  3591 	} else {
  3490 
       
  3491 		/**
  3592 		/**
  3492 		 * Fires before a comment is posted.
  3593 		 * Fires before a comment is posted.
  3493 		 *
  3594 		 *
  3494 		 * @since 2.8.0
  3595 		 * @since 2.8.0
  3495 		 *
  3596 		 *
  3496 		 * @param int $comment_post_ID Post ID.
  3597 		 * @param int $comment_post_id Post ID.
  3497 		 */
  3598 		 */
  3498 		do_action( 'pre_comment_on_post', $comment_post_ID );
  3599 		do_action( 'pre_comment_on_post', $comment_post_id );
  3499 
       
  3500 	}
  3600 	}
  3501 
  3601 
  3502 	// If the user is logged in.
  3602 	// If the user is logged in.
  3503 	$user = wp_get_current_user();
  3603 	$user = wp_get_current_user();
  3504 	if ( $user->exists() ) {
  3604 	if ( $user->exists() ) {
  3505 		if ( empty( $user->display_name ) ) {
  3605 		if ( empty( $user->display_name ) ) {
  3506 			$user->display_name = $user->user_login;
  3606 			$user->display_name = $user->user_login;
  3507 		}
  3607 		}
       
  3608 
  3508 		$comment_author       = $user->display_name;
  3609 		$comment_author       = $user->display_name;
  3509 		$comment_author_email = $user->user_email;
  3610 		$comment_author_email = $user->user_email;
  3510 		$comment_author_url   = $user->user_url;
  3611 		$comment_author_url   = $user->user_url;
  3511 		$user_ID              = $user->ID;
  3612 		$user_id              = $user->ID;
       
  3613 
  3512 		if ( current_user_can( 'unfiltered_html' ) ) {
  3614 		if ( current_user_can( 'unfiltered_html' ) ) {
  3513 			if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] )
  3615 			if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] )
  3514 				|| ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_ID )
  3616 				|| ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_id )
  3515 			) {
  3617 			) {
  3516 				kses_remove_filters(); // Start with a clean slate.
  3618 				kses_remove_filters(); // Start with a clean slate.
  3517 				kses_init_filters();   // Set up the filters.
  3619 				kses_init_filters();   // Set up the filters.
  3518 				remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
  3620 				remove_filter( 'pre_comment_content', 'wp_filter_post_kses' );
  3519 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
  3621 				add_filter( 'pre_comment_content', 'wp_filter_kses' );
  3527 
  3629 
  3528 	$comment_type = 'comment';
  3630 	$comment_type = 'comment';
  3529 
  3631 
  3530 	if ( get_option( 'require_name_email' ) && ! $user->exists() ) {
  3632 	if ( get_option( 'require_name_email' ) && ! $user->exists() ) {
  3531 		if ( '' == $comment_author_email || '' == $comment_author ) {
  3633 		if ( '' == $comment_author_email || '' == $comment_author ) {
  3532 			return new WP_Error( 'require_name_email', __( '<strong>Error</strong>: Please fill the required fields.' ), 200 );
  3634 			return new WP_Error( 'require_name_email', __( '<strong>Error:</strong> Please fill the required fields.' ), 200 );
  3533 		} elseif ( ! is_email( $comment_author_email ) ) {
  3635 		} elseif ( ! is_email( $comment_author_email ) ) {
  3534 			return new WP_Error( 'require_valid_email', __( '<strong>Error</strong>: Please enter a valid email address.' ), 200 );
  3636 			return new WP_Error( 'require_valid_email', __( '<strong>Error:</strong> Please enter a valid email address.' ), 200 );
  3535 		}
  3637 		}
  3536 	}
  3638 	}
  3537 
  3639 
  3538 	$commentdata = compact(
  3640 	$commentdata = array(
  3539 		'comment_post_ID',
  3641 		'comment_post_ID' => $comment_post_id,
       
  3642 	);
       
  3643 
       
  3644 	$commentdata += compact(
  3540 		'comment_author',
  3645 		'comment_author',
  3541 		'comment_author_email',
  3646 		'comment_author_email',
  3542 		'comment_author_url',
  3647 		'comment_author_url',
  3543 		'comment_content',
  3648 		'comment_content',
  3544 		'comment_type',
  3649 		'comment_type',
  3545 		'comment_parent',
  3650 		'comment_parent',
  3546 		'user_ID'
  3651 		'user_id'
  3547 	);
  3652 	);
  3548 
  3653 
  3549 	/**
  3654 	/**
  3550 	 * Filters whether an empty comment should be allowed.
  3655 	 * Filters whether an empty comment should be allowed.
  3551 	 *
  3656 	 *
  3554 	 * @param bool  $allow_empty_comment Whether to allow empty comments. Default false.
  3659 	 * @param bool  $allow_empty_comment Whether to allow empty comments. Default false.
  3555 	 * @param array $commentdata         Array of comment data to be sent to wp_insert_comment().
  3660 	 * @param array $commentdata         Array of comment data to be sent to wp_insert_comment().
  3556 	 */
  3661 	 */
  3557 	$allow_empty_comment = apply_filters( 'allow_empty_comment', false, $commentdata );
  3662 	$allow_empty_comment = apply_filters( 'allow_empty_comment', false, $commentdata );
  3558 	if ( '' === $comment_content && ! $allow_empty_comment ) {
  3663 	if ( '' === $comment_content && ! $allow_empty_comment ) {
  3559 		return new WP_Error( 'require_valid_comment', __( '<strong>Error</strong>: Please type your comment text.' ), 200 );
  3664 		return new WP_Error( 'require_valid_comment', __( '<strong>Error:</strong> Please type your comment text.' ), 200 );
  3560 	}
  3665 	}
  3561 
  3666 
  3562 	$check_max_lengths = wp_check_comment_data_max_lengths( $commentdata );
  3667 	$check_max_lengths = wp_check_comment_data_max_lengths( $commentdata );
  3563 	if ( is_wp_error( $check_max_lengths ) ) {
  3668 	if ( is_wp_error( $check_max_lengths ) ) {
  3564 		return $check_max_lengths;
  3669 		return $check_max_lengths;
  3568 	if ( is_wp_error( $comment_id ) ) {
  3673 	if ( is_wp_error( $comment_id ) ) {
  3569 		return $comment_id;
  3674 		return $comment_id;
  3570 	}
  3675 	}
  3571 
  3676 
  3572 	if ( ! $comment_id ) {
  3677 	if ( ! $comment_id ) {
  3573 		return new WP_Error( 'comment_save_error', __( '<strong>Error</strong>: The comment could not be saved. Please try again later.' ), 500 );
  3678 		return new WP_Error( 'comment_save_error', __( '<strong>Error:</strong> The comment could not be saved. Please try again later.' ), 500 );
  3574 	}
  3679 	}
  3575 
  3680 
  3576 	return get_comment( $comment_id );
  3681 	return get_comment( $comment_id );
  3577 }
  3682 }
  3578 
  3683 
  3579 /**
  3684 /**
  3580  * Registers the personal data exporter for comments.
  3685  * Registers the personal data exporter for comments.
  3581  *
  3686  *
  3582  * @since 4.9.6
  3687  * @since 4.9.6
  3583  *
  3688  *
  3584  * @param array $exporters An array of personal data exporters.
  3689  * @param array[] $exporters An array of personal data exporters.
  3585  * @return array An array of personal data exporters.
  3690  * @return array[] An array of personal data exporters.
  3586  */
  3691  */
  3587 function wp_register_comment_personal_data_exporter( $exporters ) {
  3692 function wp_register_comment_personal_data_exporter( $exporters ) {
  3588 	$exporters['wordpress-comments'] = array(
  3693 	$exporters['wordpress-comments'] = array(
  3589 		'exporter_friendly_name' => __( 'WordPress Comments' ),
  3694 		'exporter_friendly_name' => __( 'WordPress Comments' ),
  3590 		'callback'               => 'wp_comments_personal_data_exporter',
  3695 		'callback'               => 'wp_comments_personal_data_exporter',
  3597  * Finds and exports personal data associated with an email address from the comments table.
  3702  * Finds and exports personal data associated with an email address from the comments table.
  3598  *
  3703  *
  3599  * @since 4.9.6
  3704  * @since 4.9.6
  3600  *
  3705  *
  3601  * @param string $email_address The comment author email address.
  3706  * @param string $email_address The comment author email address.
  3602  * @param int    $page          Comment page.
  3707  * @param int    $page          Comment page number.
  3603  * @return array An array of personal data.
  3708  * @return array {
       
  3709  *     An array of personal data.
       
  3710  *
       
  3711  *     @type array[] $data An array of personal data arrays.
       
  3712  *     @type bool    $done Whether the exporter is finished.
       
  3713  * }
  3604  */
  3714  */
  3605 function wp_comments_personal_data_exporter( $email_address, $page = 1 ) {
  3715 function wp_comments_personal_data_exporter( $email_address, $page = 1 ) {
  3606 	// Limit us to 500 comments at a time to avoid timing out.
  3716 	// Limit us to 500 comments at a time to avoid timing out.
  3607 	$number = 500;
  3717 	$number = 500;
  3608 	$page   = (int) $page;
  3718 	$page   = (int) $page;
  3612 	$comments = get_comments(
  3722 	$comments = get_comments(
  3613 		array(
  3723 		array(
  3614 			'author_email'              => $email_address,
  3724 			'author_email'              => $email_address,
  3615 			'number'                    => $number,
  3725 			'number'                    => $number,
  3616 			'paged'                     => $page,
  3726 			'paged'                     => $page,
  3617 			'order_by'                  => 'comment_ID',
  3727 			'orderby'                   => 'comment_ID',
  3618 			'order'                     => 'ASC',
  3728 			'order'                     => 'ASC',
  3619 			'update_comment_meta_cache' => false,
  3729 			'update_comment_meta_cache' => false,
  3620 		)
  3730 		)
  3621 	);
  3731 	);
  3622 
  3732 
  3706 /**
  3816 /**
  3707  * Erases personal data associated with an email address from the comments table.
  3817  * Erases personal data associated with an email address from the comments table.
  3708  *
  3818  *
  3709  * @since 4.9.6
  3819  * @since 4.9.6
  3710  *
  3820  *
       
  3821  * @global wpdb $wpdb WordPress database abstraction object.
       
  3822  *
  3711  * @param string $email_address The comment author email address.
  3823  * @param string $email_address The comment author email address.
  3712  * @param int    $page          Comment page.
  3824  * @param int    $page          Comment page number.
  3713  * @return array
  3825  * @return array {
       
  3826  *     Data removal results.
       
  3827  *
       
  3828  *     @type bool     $items_removed  Whether items were actually removed.
       
  3829  *     @type bool     $items_retained Whether items were retained.
       
  3830  *     @type string[] $messages       An array of messages to add to the personal data export file.
       
  3831  *     @type bool     $done           Whether the eraser is finished.
       
  3832  * }
  3714  */
  3833  */
  3715 function wp_comments_personal_data_eraser( $email_address, $page = 1 ) {
  3834 function wp_comments_personal_data_eraser( $email_address, $page = 1 ) {
  3716 	global $wpdb;
  3835 	global $wpdb;
  3717 
  3836 
  3718 	if ( empty( $email_address ) ) {
  3837 	if ( empty( $email_address ) ) {
  3733 	$comments = get_comments(
  3852 	$comments = get_comments(
  3734 		array(
  3853 		array(
  3735 			'author_email'       => $email_address,
  3854 			'author_email'       => $email_address,
  3736 			'number'             => $number,
  3855 			'number'             => $number,
  3737 			'paged'              => $page,
  3856 			'paged'              => $page,
  3738 			'order_by'           => 'comment_ID',
  3857 			'orderby'            => 'comment_ID',
  3739 			'order'              => 'ASC',
  3858 			'order'              => 'ASC',
  3740 			'include_unapproved' => true,
  3859 			'include_unapproved' => true,
  3741 		)
  3860 		)
  3742 	);
  3861 	);
  3743 
  3862 
  3809  * Sets the last changed time for the 'comment' cache group.
  3928  * Sets the last changed time for the 'comment' cache group.
  3810  *
  3929  *
  3811  * @since 5.0.0
  3930  * @since 5.0.0
  3812  */
  3931  */
  3813 function wp_cache_set_comments_last_changed() {
  3932 function wp_cache_set_comments_last_changed() {
  3814 	wp_cache_set( 'last_changed', microtime(), 'comment' );
  3933 	wp_cache_set_last_changed( 'comment' );
  3815 }
  3934 }
  3816 
  3935 
  3817 /**
  3936 /**
  3818  * Updates the comment type for a batch of comments.
  3937  * Updates the comment type for a batch of comments.
  3819  *
  3938  *