Delete/Spam Comment Button

Update

So, I need to do an Ajax call to spam/delete/trash the comment

I would actually also use AJAX, and secondly, I would use JS instead to add the action links — and personally, I think an edit_comment_link callback should return just one link (i.e. one a element).. but anyway,

There are many ways to do the AJAX, but I would use the REST API: https://developer.wordpress.org/rest-api/reference/comments/.

You can find a full working example here on GitHub where the script file name is comment-ajax-actions.js, but the main parts that you need to know are:

  • Part 1:

    // Removes the spam/trashed/deleted comment's element from the DOM. Make sure
    // the selectors like LI.comment and .comment-body exist in your comments list.
    function removeComment( link ) {
        ... see code on GitHub.
    }
    
    // Updates a comment's status, or delete the comment, via the REST API.
    function commentApiRequest( link ) {
        var action     = $( link ).data( 'action' );
        var comment_id = $( link ).data( 'id' );
        var isDeleting = ( 'delete' === action );
    
        if ( confirmDeleteText && isDeleting && ! confirm( confirmDeleteText ) ) {
            return false;
        }
    
        wp.apiRequest( {
            path: 'wp/v2/comments/' + comment_id,
            method: isDeleting ? 'DELETE' : 'POST',
            data: isDeleting ? { force: true } : { status: action }
        } ).done( function () {
            removeComment( link );
        } );
    }
    
  • Part 2:

    // If you changed the action link's class (default: comment-ajax-action),
    // then be sure to also change the one below!
    $( '.comment-ajax-action' ).on( 'click', function ( e ) {
        e.preventDefault();
        commentApiRequest( this );
    } );
    

And note that the script uses jQuery and wp.apiRequest() (see wp-includes/js/api-request.js), so be sure to add jquery and wp-api-request as dependencies when enqueueing that AJAX script. E.g. where the script file is placed inside wp-content/themes/your-theme/assets/js:

wp_enqueue_script(
    'your-theme-comment-ajax-actions',
    get_template_directory_uri() . '/assets/js/comment-ajax-actions.js',
    array( 'jquery', 'wp-api-request' ),
    wp_get_theme()->get( 'Version' ),
    true
);

Last but not least, the script has been tested with WordPress v6.0 and the Twenty Twenty-One and Twenty Twenty-Two themes (the latter is a block-based theme and as of writing, it uses wp-includes/theme-compat/comments.php which is deprecated, but Twenty Twenty-Two suppressed the deprecation notice).

Original Answer

In the comments list table at wp-admin/edit-comments.php, the URL for the “Spam” link as of writing looks like this:

https://example.com/wp-admin/comment.php?c=123&action=spamcomment&_wpnonce=xxxxxxxxxx

where 123 is the comment ID and the _wpnonce value is a nonce with delete-comment_<comment ID> being the action.

And the “Trash” and “Delete” links also follow the same format, except that the action value is trashcomment and deletecomment respectively.

So you should use the same format and visiting the link would just ‘do it’, i.e. bypassing the “Moderate Comment” admin page. And by default, after successfully marking the comment as spam or after trashing/deleting the comment, you would be sent back to where you were or otherwise then it defaults to wp-admin/edit-comments.php.

And with your code, you’d just need to change this part:

$link = $link . ' <a href="'.admin_url("comment.php?action=cdc&dt=deletecomment&c=$id").'">Delete/Trash</a> ';

$link = $link . ' <a href="'.admin_url("comment.php?action=cdc&dt=spam&c=$id").'">Spam</a>';

to the following, but note that you should always escape a URL when displaying it to the user:

$del_nonce = wp_create_nonce( "delete-comment_$id" );

$link = $link . ' <a href="'.admin_url("comment.php?c=$id&action=deletecomment&_wpnonce=$del_nonce").'">Delete/Trash</a> ';

$link = $link . ' <a href="'.admin_url("comment.php?c=$id&action=spamcomment&_wpnonce=$del_nonce").'">Spam</a>';

See WP_Comments_List_Table::handle_row_actions() for the current URL format for the above links.

And just for reference, this is the full code I used:

add_filter( 'edit_comment_link', function ( $link, $comment_id ) {
    if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
        return $link;
    }

    $del_nonce = wp_create_nonce( "delete-comment_$comment_id" );

    $url = admin_url( "comment.php?c=$comment_id&action=spamcomment&_wpnonce=$del_nonce" );
    $link .= ' | <a href="' . esc_url( $url ) . '">Spam</a>';

    $url = admin_url( "comment.php?c=$comment_id&action=trashcomment&_wpnonce=$del_nonce" );
    $link .= ' | <a href="' . esc_url( $url ) . '">Trash</a>';

    $url = admin_url( "comment.php?c=$comment_id&action=deletecomment&_wpnonce=$del_nonce" );
    $link .= ' | <a href="' . esc_url( $url ) . '">Delete</a>';

    return $link;
}, 10, 2 );