delete_metadata_by_mid( 'comment', $mid );
if ( ! $wpdb->delete( $wpdb->comments, array( 'comment_ID' => $comment->comment_ID ) ) ) {
* Fires immediately after a comment is deleted from the database.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The deleted comment.
do_action( 'deleted_comment', $comment->comment_ID, $comment );
$post_id = $comment->comment_post_ID;
if ( $post_id && 1 == $comment->comment_approved ) {
wp_update_comment_count( $post_id );
clean_comment_cache( $comment->comment_ID );
/** This action is documented in wp-includes/comment.php */
do_action( 'wp_set_comment_status', $comment->comment_ID, 'delete' );
wp_transition_comment_status( 'delete', $comment->comment_approved, $comment );
* Moves a comment to the Trash
* If Trash is disabled, comment is permanently deleted.
* @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
* @return bool True on success, false on failure.
function wp_trash_comment( $comment_id ) {
if ( ! EMPTY_TRASH_DAYS ) {
return wp_delete_comment( $comment_id, true );
$comment = get_comment( $comment_id );
* Fires immediately before a comment is sent to the Trash.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The comment to be trashed.
do_action( 'trash_comment', $comment->comment_ID, $comment );
if ( wp_set_comment_status( $comment, 'trash' ) ) {
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' );
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' );
add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved );
add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() );
* Fires immediately after a comment is sent to Trash.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The trashed comment.
do_action( 'trashed_comment', $comment->comment_ID, $comment );
* Removes a comment from the Trash
* @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
* @return bool True on success, false on failure.
function wp_untrash_comment( $comment_id ) {
$comment = get_comment( $comment_id );
* Fires immediately before a comment is restored from the Trash.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The comment to be untrashed.
do_action( 'untrash_comment', $comment->comment_ID, $comment );
$status = (string) get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true );
if ( empty( $status ) ) {
if ( wp_set_comment_status( $comment, $status ) ) {
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' );
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' );
* Fires immediately after a comment is restored from the Trash.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The untrashed comment.
do_action( 'untrashed_comment', $comment->comment_ID, $comment );
* Marks a comment as Spam
* @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
* @return bool True on success, false on failure.
function wp_spam_comment( $comment_id ) {
$comment = get_comment( $comment_id );
* Fires immediately before a comment is marked as Spam.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The comment to be marked as spam.
do_action( 'spam_comment', $comment->comment_ID, $comment );
if ( wp_set_comment_status( $comment, 'spam' ) ) {
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' );
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' );
add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved );
add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() );
* Fires immediately after a comment is marked as Spam.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The comment marked as spam.
do_action( 'spammed_comment', $comment->comment_ID, $comment );
* Removes a comment from the Spam
* @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
* @return bool True on success, false on failure.
function wp_unspam_comment( $comment_id ) {
$comment = get_comment( $comment_id );
* Fires immediately before a comment is unmarked as Spam.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The comment to be unmarked as spam.
do_action( 'unspam_comment', $comment->comment_ID, $comment );
$status = (string) get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true );
if ( empty( $status ) ) {
if ( wp_set_comment_status( $comment, $status ) ) {
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' );
delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' );
* Fires immediately after a comment is unmarked as Spam.
* @since 4.9.0 Added the `$comment` parameter.
* @param int $comment_id The comment ID.
* @param WP_Comment $comment The comment unmarked as spam.
do_action( 'unspammed_comment', $comment->comment_ID, $comment );
* The status of a comment by ID.
* @param int|WP_Comment $comment_id Comment ID or WP_Comment object
* @return string|false Status might be 'trash', 'approved', 'unapproved', 'spam'. False on failure.
function wp_get_comment_status( $comment_id ) {
$comment = get_comment( $comment_id );
$approved = $comment->comment_approved;
if ( null == $approved ) {
} elseif ( '1' == $approved ) {
} elseif ( '0' == $approved ) {
} elseif ( 'spam' === $approved ) {
} elseif ( 'trash' === $approved ) {
* Call hooks for when a comment status transition occurs.
* Calls hooks for comment status transitions. If the new comment status is not the same
* as the previous comment status, then two hooks will be ran, the first is
* {@see 'transition_comment_status'} with new status, old status, and comment data.
* The next action called is {@see 'comment_$old_status_to_$new_status'}. It has
* The final action will run whether or not the comment statuses are the same.
* The action is named {@see 'comment_$new_status_$comment->comment_type'}.
* @param string $new_status New comment status.
* @param string $old_status Previous comment status.
* @param WP_Comment $comment Comment object.
function wp_transition_comment_status( $new_status, $old_status, $comment ) {
* Translate raw statuses to human-readable formats for the hooks.
* This is not a complete list of comment status, it's only the ones
* that need to be renamed.
$comment_statuses = array(
'hold' => 'unapproved', // wp_set_comment_status() uses "hold".
'approve' => 'approved', // wp_set_comment_status() uses "approve".
if ( isset( $comment_statuses[ $new_status ] ) ) {
$new_status = $comment_statuses[ $new_status ];
if ( isset( $comment_statuses[ $old_status ] ) ) {
$old_status = $comment_statuses[ $old_status ];
if ( $new_status != $old_status ) {
* Fires when the comment status is in transition.
* @param int|string $new_status The new comment status.
* @param int|string $old_status The old comment status.
* @param WP_Comment $comment Comment object.
do_action( 'transition_comment_status', $new_status, $old_status, $comment );
* Fires when the comment status is in transition from one specific status to another.
* The dynamic portions of the hook name, `$old_status`, and `$new_status`,
* refer to the old and new comment statuses, respectively.
* @param WP_Comment $comment Comment object.
do_action( "comment_{$old_status}_to_{$new_status}", $comment );
* Fires when the status of a specific comment type is in transition.
* The dynamic portions of the hook name, `$new_status`, and `$comment->comment_type`,
* refer to the new comment status, and the type of comment, respectively.
* Typical comment types include an empty string (standard comment), 'pingback',
* @param int $comment_ID The comment ID.
* @param WP_Comment $comment Comment object.
do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment );
* Clear the lastcommentmodified cached value when a comment status is changed.
* Deletes the lastcommentmodified cache key when a comment enters or leaves
* @param string $new_status The new comment status.
* @param string $old_status The old comment status.
function _clear_modified_cache_on_transition_comment_status( $new_status, $old_status ) {
if ( 'approved' === $new_status || 'approved' === $old_status ) {
foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
wp_cache_delete( "lastcommentmodified:$timezone", 'timeinfo' );
* Get current commenter's name, email, and URL.
* Expects cookies content to already be sanitized. User of this function might
* wish to recheck the returned array for validity.
* @see sanitize_comment_cookies() Use to sanitize cookies
* An array of current commenter variables.
* @type string $comment_author The name of the current commenter, or an empty string.
* @type string $comment_author_email The email address of the current commenter, or an empty string.
* @type string $comment_author_url The URL address of the current commenter, or an empty string.
function wp_get_current_commenter() {
// Cookies should already be sanitized.
if ( isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ) {
$comment_author = $_COOKIE[ 'comment_author_' . COOKIEHASH ];
$comment_author_email = '';
if ( isset( $_COOKIE[ 'comment_author_email_' . COOKIEHASH ] ) ) {
$comment_author_email = $_COOKIE[ 'comment_author_email_' . COOKIEHASH ];
$comment_author_url = '';
if ( isset( $_COOKIE[ 'comment_author_url_' . COOKIEHASH ] ) ) {
$comment_author_url = $_COOKIE[ 'comment_author_url_' . COOKIEHASH ];
* Filters the current commenter's name, email, and URL.
* @param array $comment_author_data {
* An array of current commenter variables.
* @type string $comment_author The name of the current commenter, or an empty string.
* @type string $comment_author_email The email address of the current commenter, or an empty string.
* @type string $comment_author_url The URL address of the current commenter, or an empty string.
return apply_filters( 'wp_get_current_commenter', compact( 'comment_author', 'comment_author_email', 'comment_author_url' ) );
* Get unapproved comment author's email.
* Used to allow the commenter to see their pending comment.
* @since 5.7.0 The window within which the author email for an unapproved comment
* can be retrieved was extended to 10 minutes.
* @return string The unapproved comment author's email (when supplied).
function wp_get_unapproved_comment_author_email() {
if ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) {
$comment_id = (int) $_GET['unapproved'];
$comment = get_comment( $comment_id );
if ( $comment && hash_equals( $_GET['moderation-hash'], wp_hash( $comment->comment_date_gmt ) ) ) {
// The comment will only be viewable by the comment author for 10 minutes.
$comment_preview_expires = strtotime( $comment->comment_date_gmt . '+10 minutes' );
if ( time() < $comment_preview_expires ) {
$commenter_email = $comment->comment_author_email;
if ( ! $commenter_email ) {
$commenter = wp_get_current_commenter();
$commenter_email = $commenter['comment_author_email'];
* Inserts a comment into the database.
* @since 4.4.0 Introduced the `$comment_meta` argument.
* @since 5.5.0 Default value for `$comment_type` argument changed to `comment`.
* @global wpdb $wpdb WordPress database abstraction object.
* @param array $commentdata {
* Array of arguments for inserting a new comment.
* @type string $comment_agent The HTTP user agent of the `$comment_author` when
* the comment was submitted. Default empty.
* @type int|string $comment_approved Whether the comment has been approved. Default 1.
* @type string $comment_author The name of the author of the comment. Default empty.
* @type string $comment_author_email The email address of the `$comment_author`. Default empty.
* @type string $comment_author_IP The IP address of the `$comment_author`. Default empty.
* @type string $comment_author_url The URL address of the `$comment_author`. Default empty.
* @type string $comment_content The content of the comment. Default empty.
* @type string $comment_date The date the comment was submitted. To set the date
* manually, `$comment_date_gmt` must also be specified.
* Default is the current time.
* @type string $comment_date_gmt The date the comment was submitted in the GMT timezone.
* Default is `$comment_date` in the site's GMT timezone.
* @type int $comment_karma The karma of the comment. Default 0.
* @type int $comment_parent ID of this comment's parent, if any. Default 0.
* @type int $comment_post_ID ID of the post that relates to the comment, if any.
* @type string $comment_type Comment type. Default 'comment'.
* @type array $comment_meta Optional. Array of key/value pairs to be stored in commentmeta for the
* @type int $user_id ID of the user who submitted the comment. Default 0.
* @return int|false The new comment's ID on success, false on failure.
function wp_insert_comment( $commentdata ) {
$data = wp_unslash( $commentdata );
$comment_author = ! isset( $data['comment_author'] ) ? '' : $data['comment_author'];
$comment_author_email = ! isset( $data['comment_author_email'] ) ? '' : $data['comment_author_email'];
$comment_author_url = ! isset( $data['comment_author_url'] ) ? '' : $data['comment_author_url'];
$comment_author_IP = ! isset( $data['comment_author_IP'] ) ? '' : $data['comment_author_IP'];
$comment_date = ! isset( $data['comment_date'] ) ? current_time( 'mysql' ) : $data['comment_date'];