0

I'm trying to add a button to my comments that allows a user to delete them.

I have a form declared like so:

<form method="post">
  <input type="submit" name="btn-delete" value="try-delete">
</form>

and above it the following php:

<?php
  if (isset($_POST["btn-delete"])) {
    wp_delete_comment(get_comment_ID(), true);
  }
?>

Note this is in my comments.php, and I use the standard API for looping through the comments.

When I click on the button (from the input tag), it reloads the page and does nothing. If I click it again, it deletes all of the comments on the page, rather than just the one comment. How can I fix this?

Thanks in advance.

6
  • 2
    can you expand your code blocks? Not enough of the code is showing. Also, there is no comment ID so it does not know which comment it's meant to delete. If your wp_delete_comment call is inside your comment display template then it will run for all comments, and, it will display the comment even if it has been deleted because it has already fetched the comments from the database
    – Tom J Nowell
    Commented May 31, 2022 at 17:39
  • The code above is in my comment list callback function, where I specify the html for each comment. How can I delete only a specific comment and refetch the comments from the database? Commented May 31, 2022 at 19:52
  • I do not believe that you should be doing this inside your comment templates and callbacks, this is better done on a hook that happens before templates are displayed. It is also not possible to do this without passing the comment ID
    – Tom J Nowell
    Commented May 31, 2022 at 20:08
  • I'm creating a button that allows users to delete their comments. How can I do this if the button isn't in the template? Commented May 31, 2022 at 20:09
  • The button needs to be in the template, and it needs to include the comment ID too, but the PHP code that checks for the form and does the deletion should not be in the template
    – Tom J Nowell
    Commented May 31, 2022 at 20:27

1 Answer 1

1

The Insecure Way

You need to change your form so that it includes the ID of the comment you want to delete, e.g.:

<form method="post">
  <input type="hidden" name="comment_id" value="<?php echo get_comment_ID(); ?>" />
  <input type="submit" name="btn-delete" value="try-delete"/>
</form>

Without this, you have no idea which comment the user wanted to delete.

Then, you need to move the code that deletes the comment to a hook in functions.php e.g.:

add_action( 'init', 'i_am_not_safe_to_use' );
function i_am_not_safe_to_use() {
    if ( is_admin() ) {
        return;
    }

    // only run if we're deleting a comment
    if ( empty( $_POST['btn-delete'] ) || empty( $_POST['comment_id'] ) ) {
        return;
    }

    // TODO, security checks

    // delete the comment
    $comment_id = intval( $_POST['comment_id'] );
    wp_delete_comment( $comment_id, true );
}

This will work however it is insecure! Now anybody can delete any comment they want by submitting the form!!!

Security

The code needs to also do the following:

  • check that the user has the necessary capability required to delete that comment
  • add a nonce to the form
  • check the nonce in the hook

At a minimum, you need this check:

if ( current_user_can( 'moderate_comments' ) || current_user_can( 'edit_comment', $comment_id ) ) {
    // then the user has permission to delete the comment
} else {
    wp_die( 'sneaky hackers! You are not allowed to delete this comment' );
}

The REST API

If you send an authenticated DELETE request to the comments REST API at yoursite.com/wp-json/wp/v2/comments/<COMMENT ID GOES HERE> then refresh the page, your comment will be gone.

1
  • 1
    Thank you so much (especially for your patience). This is exactly what I was looking for, and it worked perfectly. Commented May 31, 2022 at 20:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.