0

I need some help cause I couldn't find any solution for my problem and haven't the knowledge to solve the problem on my own.

What I'm trying to do: I want to delte every WordPress user (subscriber) which is older than X days. For testing purposes I needed short intervals, in production the users should be deleted after 6 months. So each subscriber should be deleted after 6 months, after their registration.

What I've tried for testing purposes:

function wcs_auto_delete_users() {
    global $wpdb;
    $query = $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE datediff( now(), user_registered ) > 0.1" );
    if ( $oldUsers = $wpdb->get_results( $query, ARRAY_N ) ) {
        foreach ( $oldUsers as $user_id ) {
            wp_delete_user( $user_id[0] );
        }
    }
}
add_action( 'wcs_daily_clean_database', 'wcs_auto_delete_users' );
wp_schedule_event( time(), 'hourly', 'wcs_daily_clean_database' );

The snippet above works, but it deletes every user, which I don't want.

So that's what I've tried further for testing purposes:

function auto_delete_users() {
    global $wpdb;
    $userlevel = 0; //0 = subscriber
    $deleteafter = (1/48); //delete User after 30 mins

    $query = $wpdb->prepare("SELECT $wpdb->users.ID FROM $wpdb->users LEFT JOIN $wpdb->usermeta ON $wpdb->users.ID = $wpdb->usermeta.user_id WHERE $wpdb->usermeta.meta_key = %s AND $wpdb->usermeta.meta_value = %d AND DATEDIFF(CURDATE(), $wpdb->users.user_registered) > %d", $wpdb->prefix.'user_level',$userlevel,$deleteafter);

    if($oldUsers = $wpdb->get_results($query, ARRAY_N)){
        foreach ($oldUsers as $user_id) {
            wp_delete_user($user_id[0]);
        }
    }
}
add_action('daily_clean_database', 'auto_delete_users');
wp_schedule_event(time(), 'hourly', 'daily_clean_database');

The snippet above doesn't work and maybe you could explain what I'm doing wrong or what I would have to adjust.

I also tried to schedule the event with "cron_schedules" every 15 minutes to avoid waiting 1 hour to call the function, but that's not important now.

Your help would be much appreciated.

1
  • Is there a reason you're using raw SQL instead of WP_User_Query? datediff( now(), user_registered ) > 0.1 will match everybody who registered more than 0.1 seconds ago
    – Tom J Nowell
    Commented Mar 4, 2022 at 14:40

1 Answer 1

0

You do not need to use raw SQL, WordPress already provides WP_User_Query, and even provides examples of date based queries, for example the official docs say that this will retrieve all users registered within the last 12 hours:

$args = array(
    'date_query' => array( 
        array( 'after' => '12 hours ago', 'inclusive' => true )  
    )
);
$user_query = new WP_User_Query( $args );

Taken from: https://developer.wordpress.org/reference/classes/wp_user_query/#date-parameters

Which suggests this might work:

$args = [
    'date_query' => [
        [
            'before' => '6 months ago',
            'inclusive' => true
        ]
    ]
];
$user_query = new WP_User_Query( $args );
if ( ! empty( $user_query->get_results() ) ) {
    foreach ( $user_query->get_results() as $user ) {
        echo '<p>delete: ' . $user->display_name . '</p>';
    }
} else {
    echo 'No users found.';
}

If you need to use raw SQL to get something in WordPress and you're not working with custom tables, then it generally means you've done something wrong or aren't aware of an important core API or parameter.

Other things to note:

  • This won't scale if your site gets popular as there's no limit on how many users your query fetches, you should run this more often and in batches
  • unless your host has a system level cron job this won't happen exactly every 6 months, there'll be a little variance depending on how busy your site is
  • there may be legal and regulatory obligations that require longer than 6 months, if the goal here is to prevent access after a subscription for example then this isn't the best way (no upsells to re-subscribe? Or message that the 6 months are up?)
2
  • Thank you for the answer. I have to process the information and test some things. Could I use "WP_User_Query" with "WP_Schedule_Event" and "WP_Delete_User" to achive that goal of mine? It wouldn't be that important if the user gets deleted after 179 to 181 days (~6 months). Commented Mar 4, 2022 at 15:47
  • For some additional informations: It's a legal requirement for those users to be deleted after 6 months, but if there would be some discrepancy (1 day), it would be still "OK". Therefore it's important the user loses access to the website and not only access to his subscription (learndash). Commented Mar 4, 2022 at 15:58

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.