Inactive Subscribers Cleanup Page
Adds Users > Inactive Subscribers, listing subscriber accounts older than two years that have never commented, with checkboxes to delete the ones you select after a confirmation.
Opens WPIDE on
Code
// Accounts registered more than this many days ago are listed.
$wpide_inactive_days = 730;
add_action( 'admin_menu', function () use ( $wpide_inactive_days ) {
add_users_page( 'Inactive Subscribers', 'Inactive Subscribers', 'delete_users', 'wpide-inactive-subscribers', function () use ( $wpide_inactive_days ) {
global $wpdb;
if ( ! current_user_can( 'delete_users' ) ) {
return;
}
if ( isset( $_POST['wpide_delete_users'] ) && check_admin_referer( 'wpide_inactive_delete' ) ) {
require_once ABSPATH . 'wp-admin/includes/user.php';
$deleted = 0;
foreach ( array_map( 'absint', (array) wp_unslash( $_POST['wpide_delete_users'] ) ) as $user_id ) {
$user = get_userdata( $user_id );
if ( $user && array( 'subscriber' ) === array_values( $user->roles ) && get_current_user_id() !== $user_id && wp_delete_user( $user_id ) ) {
$deleted++;
}
}
printf( '<div class="notice notice-success"><p>%s</p></div>', esc_html( sprintf( 'Deleted %d account(s).', $deleted ) ) );
}
$users = get_users( array(
'role' => 'subscriber',
'number' => 200,
'orderby' => 'registered',
'order' => 'ASC',
'date_query' => array( array( 'column' => 'user_registered', 'before' => $wpide_inactive_days . ' days ago' ) ),
'fields' => array( 'ID', 'user_login', 'user_email', 'user_registered' ),
'count_total' => false,
) );
$with_comments = array();
if ( $users ) {
$ids = implode( ',', array_map( 'intval', wp_list_pluck( $users, 'ID' ) ) );
$with_comments = array_map( 'intval', $wpdb->get_col( "SELECT DISTINCT user_id FROM {$wpdb->comments} WHERE user_id IN ($ids)" ) );
}
echo '<div class="wrap"><h1>Inactive Subscribers</h1>';
echo '<p>' . esc_html( sprintf( 'Subscribers registered more than %d days ago who have never commented (first 200).', $wpide_inactive_days ) ) . '</p>';
echo '<form method="post" onsubmit="return confirm(\'Delete the selected accounts permanently?\');">';
wp_nonce_field( 'wpide_inactive_delete' );
echo '<table class="widefat striped"><thead><tr><td class="check-column"></td><th>User</th><th>Email</th><th>Registered</th></tr></thead><tbody>';
$shown = 0;
foreach ( $users as $user ) {
if ( in_array( (int) $user->ID, $with_comments, true ) ) {
continue;
}
$shown++;
printf(
'<tr><th class="check-column"><input type="checkbox" name="wpide_delete_users[]" value="%1$d" aria-label="%2$s"></th><td>%3$s</td><td>%4$s</td><td>%5$s</td></tr>',
(int) $user->ID,
esc_attr( 'Select ' . $user->user_login ),
esc_html( $user->user_login ),
esc_html( $user->user_email ),
esc_html( mysql2date( get_option( 'date_format' ), $user->user_registered ) )
);
}
if ( ! $shown ) {
echo '<tr><td colspan="4">No inactive subscribers found.</td></tr>';
}
echo '</tbody></table>';
if ( $shown ) {
submit_button( 'Delete selected accounts', 'delete' );
}
echo '</form></div>';
} );
} );
Notes
Only the subscriber role is listed and nothing is deleted without your confirmation; customers of shops and members of membership plugins usually have their own roles.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.