Delete all user comments

I’ve added a way for my registered users to delete their account but Im fairly sure that wp_delete_user() deletes:

  • User posts and all post meta
  • Links
  • User and all user meta

I also want to delete all the comments from that user (which probably means that all replies has to be deleted as well..). Could anyone help me with that? Especially with getting replies of these posts..


This is currently functions.php version but I’ll eventually add it to custom user profile template:

if ( is_user_logged_in() && ! empty( $_GET['delete-my-account'] ) ) {

    add_action( 'init', 'delete_user_account' );
}

function delete_user_account() {

    //Check Nonce
    if ( wp_verify_nonce( 'delete_account' ) ) {

        //Delete user
        $current_user = wp_get_current_user();
        wp_delete_user( $current_user->ID );

        //Just in case - not sure if required
        wp_logout();

        //Redirect to custom "We're sad to see you go.. Your account has been deleted" page
        wp_redirect( 'absolute URI' );
        //Always exit after wp_redirect()
        exit;
    }
}

Solutions Collecting From Web of "Delete all user comments"

Here are a few functions that make use of WP_Comment_Query to pull the user’s Comments, then loop through to find any replies, and trash them all.

$current_user = wp_get_current_user();

$deleteReplies = true;
$force_delete = false;
deleteUserComments ( $current_user->ID, $deleteReplies, $force_delete );

If you want to test this without permanently trashing the items, you can reset the comment status using this little function.

$includeReplies = true;
setUserCommentStatus ( $current_user->ID, $includeReplies, 'approve' );

You can certainly reduce this code to fewer lines but it just made sense to break it out. In general, the first search is for all Comments made that are tied to a User’s ID. The second loop goes through each of those IDs to find any Comments using those as their parent ID and the process continues until all replies are found.

Finally wp_delete_comment() is run for each unique ID in the final list.


/**
 * Return a list of IDs from Comments by Author
 *
 * @param int|string $user_id
 * @param bool       $includeReplies
 * @param array      $args Overrides for WP_Comment_Query
 *
 * @return array list of Comment IDs
 */
function getCommentsByUser( $user_id, $includeReplies = false, $args = array () ) {
    $query    = new WP_Comment_Query;
    $comments = $query->query( wp_parse_args( $args, array (
        'type'    => 'comment',
        'user_id' => $user_id,
        'fields'  => 'ids',
        'status'  => 'any',
    ) ) );

    if ( ! $includeReplies || empty( $comments ) ) {
        return $comments;
    }

    $children = array ();
    foreach ( $comments as $comment ) {
        $children = array_merge( $children, getCommentReplies( $comment ) );
    }
    return array_filter( array_unique( array_merge( $comments, $children ) ) );
}

/**
 * Return a list of IDs from Comment's Replies
 *
 * @param int|string $comment_id
 * @param array      $args
 *
 * @return array list of Comment IDs
 */
function getCommentReplies( $comment_id, $args = array () ) {
    $query    = new WP_Comment_Query;
    $comments = $query->query( wp_parse_args( $args, array (
        'parent' => $comment_id,
        'type'   => 'comment',
        'fields' => 'ids',
        'status' => 'any',
    ) ) );
    if ( empty( $comments ) ) {
        return $comments;
    }
    $children = array ();
    foreach ( $comments as $comment ) {
        $children = array_merge( $children, getCommentReplies( $comment ) );
    }

    return array_filter( array_unique( array_merge( $comments, $children ) ) );
}

/**
 * Deletes Comments from list of IDs
 *
 * @param array $commentList List of Comment IDs
 * @param bool  $force_delete
 */
function deleteComments( $commentList, $force_delete = false ) {
    $commentList = array_filter( $commentList );
    foreach ( $commentList as $comment ) {
        wp_delete_comment( $comment, $force_delete );
    }
}

/**
 * Deletes all the comments associated with a User
 * @param int|string $userId
 * @param bool       $deleteReplies
 * @param bool       $force_delete
 */
function deleteUserComments( $userId, $deleteReplies = true, $force_delete = false ) {
    $comments = getCommentsByUser( $userId, $deleteReplies, array (
        'status' => array (
            // including 'trash' will permanently delete any trashed items in this operation
            // regardless of force_delete
            'hold', 'approve', 'spam', ( $force_delete ? 'trash' : '' ),
        ),
    ) );
    if ( ! empty( $comments ) ) {
        deleteComments( $comments, $force_delete );
    }
}

/**
 * Set's the status of User's Comments
 * @param int|string $userId
 * @param bool       $includeReplies
 * @param string     $status ['hold', 'approve', 'spam', 'trash']
 */
function setUserCommentStatus( $userId, $includeReplies = true, $status = 'approve' ) {
    $comments = getCommentsByUser( $userId, $includeReplies, array ( 'status' => 'any' ) ); 
    if ( ! empty( $comments ) ) {
        foreach ( $comments as $comment ) { 
            wp_set_comment_status( $comment, $status );
        }
    }
}

Version 2

This one is a bit more condensed.

function getCommentReplies( $comment_id ) {
    $query    = new WP_Comment_Query;
    $comments = $query->query( array (
        'parent' => $comment_id,
        'type'   => 'comment',
        'fields' => 'ids',
        'status' => 'any',
    ) );
    if ( empty( $comments ) ) {
        return $comments;
    }
    $children = array ();
    foreach ( $comments as $comment ) {
        $children = array_merge( $children, getCommentReplies( $comment ) );
    }
    return array_filter( array_unique( array_merge( $comments, $children ) ) );
}

$query    = new WP_Comment_Query;
$comments = $query->query( array (
    'user_id' => get_current_user_id(),
    'type'    => 'comment',
    'fields'  => 'ids',
    'status'  => 'any',
) );

$children = array ();
foreach ( $comments as $comment ) {
    $children = array_merge( $children, getCommentReplies( $comment ) );
}

$final = array_filter( array_unique( array_merge( $comments, $children ) ) );
foreach ( $final as $comment ) {
    wp_delete_comment( $comment, true );
}