1

Goal

Every time an admin clicks on the "Trash" button below a comment, refresh the page. If the comment was trashed while the admin was in the "All" category, he should be in the "All" category again after the refresh. If he was in the "Pending" category, he should be there again after the refresh.

Why

I'm developing a plugin that has a function hooked on init and will trash comments that are past a certain age. The init hook runs when the button "Trash" below a comment is clicked so as the admin is e.g. in the "Pending" category and trashes a comment, it is possible other comments shown in the table have been trashed in the meantime by my function so the admin should no longer see those other comments after he has trashed the comment.

Things tried

  1. Tried hooking the script mentioned in this answer on the trashed_comment action with no success.
add_action( 'trashed_comment', 'my_refresh_function', 10, 2 );

function my_refresh_function( $comment_ID, $comment_obj ) {
    echo '<script>location.reload();</script>';
}
  1. Also tried using set_current_screen( 'edit-comments' ) on the trashed_comment action with no success.
add_action( 'trashed_comment', 'my_refresh_function', 10, 2 );

function my_refresh_function( $comment_ID, $comment_obj ) {
    set_current_screen( 'edit-comments' );
}
  1. Tried hooking the script mentioned in this answer on the trashed_comment action with no success.
add_action( 'trashed_comment', 'my_refresh_function', 10, 2 );

function my_refresh_function( $comment_ID, $comment_obj ) {
    Header('Location: '.$_SERVER['PHP_SELF']);
}
  1. Tried hooking the script mentioned in this answer on the trashed_comment action with no success.
add_action( 'trashed_comment', 'my_refresh_function', 10, 2 );

function my_refresh_function( $comment_ID, $comment_obj ) {
    $page = $_SERVER['PHP_SELF'];
    echo '<meta http-equiv="Refresh" content="0;' . $page . '">;
}
3
  • You're referring to the wp-admin/edit-comments.php page, right? Have you found a solution?
    – Sally CJ
    Commented Aug 27, 2021 at 9:49
  • @SallyCJ yes I'm referring to that page, no i haven't found a solution yet, i don't understand why it is so difficult to issue a refresh order
    – PantelD
    Commented Aug 27, 2021 at 11:13
  • Sorry for the late reply ( my computer is driving me crazy :( and I'm having a hard time in using it at the moment ), and there is a JS solution that worked for me, but why bother, there's a simple PHP solution to make the "Trash" link works normally, i.e. without using AJAX, which then would incur page reload. Let me know. :)
    – Sally CJ
    Commented Aug 28, 2021 at 9:29

2 Answers 2

2

The Comments admin page uses AJAX when trashing a comment via the "Trash" link, but only if the link element (the <a> tag) contains an attribute named data-wp-listssee the delBefore() function in /wp-admin/js/edit-comments.js.

So because the attribute is added via PHP (see line 764 in wp-admin/includes/class-wp-comments-list-table.php), then you can use the comment_row_actions filter to remove that attribute, like so:

add_filter( 'comment_row_actions', 'wpse_393799' );
function wpse_393799( $actions ) {
    if ( isset( $actions['trash'] ) ) {
        $actions['trash'] = preg_replace( '/ data-wp-lists="(.+?)"/', '', $actions['trash'] );
    }

    return $actions;
}
2
  • 1
    Tested this and it works, good extra with this implementation is that it gives the option to Undo the trashing in the error messages at the top of the screen. How did you know about the "data-wp-lists" detail?
    – PantelD
    Commented Aug 28, 2021 at 11:05
  • 1
    I inspected the element via the browser's dev tools (I used Chrome, btw) and then I checked the relevant code in wp-admin/js/edit-comments.js. ( I had long known about that file, though. I just never really looked at the delBefore(). )
    – Sally CJ
    Commented Aug 28, 2021 at 11:53
2

Here's a solution that uses PHP instead of a JS approach. (I wasn't able to get anywhere with JS).

This code will replace WP's Trash action with a new action that simply trashes the comment and reloads the page.


/**
 * Replace the Trash action in the comment list with a link that will trash the comment and reload the page.
 *
 * @see https://wordpress.stackexchange.com/questions/268236/edit-comments-php-comment-row-actions-ajax-problem
 *
 * @param array      $actions
 * @param WP_Comment $comment
 *
 * @return array Comment actions
 */
function wpse_comment_row_actions( $actions, $comment ) {

    // Don't do anything for comments that are already in the trash or marked as spam.
    // You may want to customize this behavior.
    if (
        'trash' === $comment->comment_approved ||
        'spam' === $comment->comment_approved ) {
        return $actions;
    }

    // Remove WP's Trash action.
    if ( isset( $actions['trash'] ) ) {
        unset( $actions['trash'] );
    }

    $screen = get_current_screen();

    $args = [
        'comment_id' => $comment->comment_ID,
        'action'     => 'trash_comment_and_reload',
        '_wpnonce'   => wp_create_nonce( 'do-comment-action-and-reload' ),
        'referer'    => $screen->parent_file,
    ];

    // Add args so that we redirect to the same tab that the user was on.
    if ( ! empty( $_REQUEST['comment_status'] ) ) {
        $args['comment_status'] = $_REQUEST['comment_status'];
    }

    if ( ! empty( $_REQUEST['user_id'] ) ) {
        $args['user_id'] = $_REQUEST['user_id'];
    }

    $link = esc_url(
        add_query_arg(
            $args,
            admin_url( 'admin-ajax.php' )
        )
    );

    // Add our own Trash action.
    $actions['trash_and_reload'] = sprintf(
        '<a href="%s" style="color:#b32d2e" class="delete">Trash</a>',
        $link
    );

    return $actions;
}
add_filter( 'comment_row_actions', 'wpse_comment_row_actions', 10, 2 );

/**
 * Trash comment and reload the page.
 */
function wpse_trash_comment_and_reload() {
    if ( wp_verify_nonce( $_REQUEST['_wpnonce'], 'do-comment-action-and-reload' ) ) {
        wp_trash_comment( $_REQUEST['comment_id'] );

        $args = [];
        if ( ! empty( $_REQUEST['comment_status'] ) ) {
            $args['comment_status'] = $_REQUEST['comment_status'];
        }

        if ( ! empty( $_REQUEST['user_id'] ) ) {
            $args['user_id'] = $_REQUEST['user_id'];
        }

        wp_safe_redirect(
            add_query_arg(
                $args,
                admin_url( $_REQUEST['referer'] )
            )
        );
    }

    exit;
}
add_action( 'wp_ajax_trash_comment_and_reload', 'wpse_trash_comment_and_reload' );

2
  • 1
    Tested this and it works, would be the accepted answer if the other answer wasn't much shorter while also retaining the ability to "Undo" the trashing of a comment. You write beautiful code btw.
    – PantelD
    Commented Aug 28, 2021 at 11:00
  • 1
    Thank you PantelD. Sally CJ's answer is definitely better imho! Commented Aug 28, 2021 at 17:43

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.