Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion src/js/_enqueues/admin/edit-comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/* global commentReply, theExtraList, theList, setCommentsList */

(function($) {
var getCount, updateCount, updateCountText, updatePending, updateApproved,
var getCount, updateCount, updateCountText, updatePending, updateApproved, emptyComments,
updateHtmlTitle, updateDashboardText, updateInModerationText, adminTitle = document.title,
isDashboard = $('#dashboard_right_now').length,
titleDiv, titleRegEx,
Expand Down Expand Up @@ -178,6 +178,80 @@ var getCount, updateCount, updateCountText, updatePending, updateApproved,
}
};

/**
* Empty spam or trash comments in AJAX batches.
*
* @since 6.9.0
*
* @param {Event} event Submit button click event.
*
* @return {void}
*/
emptyComments = function( event ) {
var button = $( event.currentTarget ),
form = button.closest( 'form' ),
status = form.find( 'input[name="comment_status"]' ).val(),
nonce = form.find( 'input[name="_wpnonce"]' ).val(),
timestamp = form.find( 'input[name="pagegen_timestamp"]' ).val(),
originalText = button.val(),
totalDeleted = 0,
notice;

if ( -1 === $.inArray( status, [ 'spam', 'trash' ] ) ) {
return;
}

event.preventDefault();

button.prop( 'disabled', true );
notice = $( '<span />', {
'class': 'empty-comments-progress screen-reader-text',
'aria-live': 'polite'
} ).insertAfter( button );

function runBatch() {
$.post(
ajaxurl,
{
action: 'empty-comments',
_ajax_nonce: nonce,
comment_status: status,
pagegen_timestamp: timestamp
}
).done( function( response ) {
var deleted, message;

if ( ! response.success ) {
button.prop( 'disabled', false ).val( originalText );
notice.remove();
window.alert( response.data && response.data.message ? response.data.message : __( 'An error occurred while emptying comments.' ) );
return;
}

deleted = parseInt( response.data.deleted, 10 ) || 0;
totalDeleted += deleted;
message = __( 'Emptying comments...' ) + ' ' + totalDeleted;

button.val( message );
notice.text( message );
wp.a11y.speak( message );

if ( response.data.done ) {
window.location.reload();
return;
}

runBatch();
} ).fail( function() {
button.prop( 'disabled', false ).val( originalText );
notice.remove();
window.alert( __( 'An error occurred while emptying comments.' ) );
} );
}

runBatch();
};

/**
* Updates the title of the document with the number comments to be approved.
*
Expand Down Expand Up @@ -1258,6 +1332,8 @@ $( function(){
e.preventDefault();
});

$( 'input[name="delete_all"]' ).on( 'click', emptyComments );

if ( typeof $.table_hotkeys != 'undefined' ) {
/**
* Creates a function that navigates to a previous or next page.
Expand Down
1 change: 1 addition & 0 deletions src/wp-admin/admin-ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
'oembed-cache',
'image-editor',
'delete-comment',
'empty-comments',
'delete-tag',
'delete-link',
'delete-meta',
Expand Down
77 changes: 77 additions & 0 deletions src/wp-admin/includes/ajax-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ function _wp_ajax_add_hierarchical_term() {
* @since 3.1.0
*/
function wp_ajax_delete_comment() {

$id = isset( $_POST['id'] ) ? (int) $_POST['id'] : 0;

$comment = get_comment( $id );
Expand Down Expand Up @@ -784,6 +785,82 @@ function wp_ajax_delete_comment() {
wp_die( 0 );
}

/**
* Handles emptying spam or trash comments via AJAX.
*
* @since 6.9.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*/
function wp_ajax_empty_comments() {

global $wpdb;

check_ajax_referer( 'bulk-comments' );

if ( ! current_user_can( 'moderate_comments' ) ) {
wp_send_json_error( array( 'message' => __( 'Sorry, you are not allowed to moderate comments on this site.' ) ), 403 );
}

$comment_status = isset( $_POST['comment_status'] ) ? sanitize_key( wp_unslash( $_POST['comment_status'] ) ) : '';

if ( ! in_array( $comment_status, array( 'spam', 'trash' ), true ) ) {
wp_send_json_error( array( 'message' => __( 'Invalid comment status.' ) ), 400 );
}

$delete_time = isset( $_POST['pagegen_timestamp'] ) ? sanitize_text_field( wp_unslash( $_POST['pagegen_timestamp'] ) ) : '';

if ( '' === $delete_time ) {
wp_send_json_error( array( 'message' => __( 'Missing delete timestamp.' ) ), 400 );
}

$batch_size = (int) apply_filters( 'wp_empty_comments_batch_size', 20, $comment_status );
$batch_size = max( 1, min( 100, $batch_size ) );
$deleted = 0;
$comment_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT comment_ID FROM $wpdb->comments
WHERE comment_approved = %s AND %s > comment_date_gmt
ORDER BY comment_ID ASC
LIMIT %d",
$comment_status,
$delete_time,
$batch_size
)
);

wp_defer_comment_counting( true );

foreach ( $comment_ids as $comment_id ) {
if ( ! current_user_can( 'edit_comment', $comment_id ) ) {
continue;
}

if ( wp_delete_comment( $comment_id ) ) {
++$deleted;
}
}

wp_defer_comment_counting( false );

$remaining = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM $wpdb->comments
WHERE comment_approved = %s AND %s > comment_date_gmt",
$comment_status,
$delete_time
)
);

wp_send_json_success(
array(
'deleted' => $deleted,
'remaining' => $remaining,
'done' => 0 === $remaining || ( 0 === $deleted && ! empty( $comment_ids ) ),
)
);
}

/**
* Handles deleting a tag via AJAX.
*
Expand Down
Loading
Loading