Auto EOT not working consistently

This should do it as a cronjob (now modified so as to work with any database prefix):

if ( !wp_next_scheduled( 'my_hourly_event' ) ) {
	wp_schedule_event( time(), 'hourly', 'my_hourly_event' );

function kts_delete_members_at_eot() {
	global $wpdb;
	$args = array(
		'role__in' => array( 's2member_level1', 's2member_level2', 's2member_level3', 's2member_level4' ),
		'meta_key' => $wpdb->prefix . 's2member_auto_eot_time',
		'fields' => 'all_with_meta',
	$users = get_users( $args );
	if ( empty( $users ) ) {
	$time = time();

	foreach ( $users as $user ) {
		$eot = get_user_option( $wpdb->prefix . 's2member_auto_eot_time', $user->ID );
		if ( empty( $eot ) ) {
		if ( $time > $eot ) {
			//wp_delete_user( $user->ID );
			$user->set_role( 'subscriber' );
add_action( 'my_hourly_event', 'kts_delete_members_at_eot' );

@bask, It looks like the EOT cronjob sometimes just unsets itself. I don’t know why. But you might be able to get it working simply by resetting it again.

that’s not a new problem - I reported it a couple of times since over 4 years. It’s the only cronjob on my websites ever deleting itself - I guess there is some memory leak on that job and even if you setup php to jun jobs for a couple of hours and attribute a couple of GB to each job (my server to 128GB so I don’t care) it will disable itself at some point. S2member should either fix it or set up a second cron job that runs daily and checks if the cron job got deleted and then reset it…

Could I just run this by loading a PHP page through my web browser? I tried this, but it didn’t work:

<?php require_once("wp-load.php"); $args = array( 'role__in' => array( 's2member_level1', 's2member_level2', 's2member_level3', 's2member_level4' ), 'meta_key' => 'wp_s2member_auto_eot_time', 'fields' => 'all_with_meta', ); $users = get_users( $args ); if ( empty( $users ) ) { return; } $time = time(); foreach ( $users as $user ) { $eot = get_user_option( 'wp_s2member_auto_eot_time', $user->ID ); if ( empty( $eot ) ) { return; } if ( $time > $eot ) { //wp_delete_user( $user->ID ); // deletes member $user->set_role( 'subscriber' ); // changes member's role } } ?>

You could use my original code, and just add it to a different hook (e.g 'save_post') then perform the action associated with the hook (in this case, save a post) and then remove the code (or you could leave it there to be used in future).

Is possible to run it as a standalone PHP page that I can load through a web browser?

I tried the code this way, and I get no users found ($users is empty).

I tried it with save_post hook, but it did not expire the members. Is there some way to check if the code is working correctly?

Here’s the hook that I modified:
add_action( ‘init’, ‘kts_delete_members_at_eot’ );
changed to
add_action( ‘save_post’, ‘kts_delete_members_at_eot’ );

That code works for me. I think you have got something else happening on your site.

We’re stuck on Wordpress 4.2.2 because of customizations that were made – we can’t update. We also have an older version of s2Member. Do you think the code isn’t working for us because some of the functions aren’t supported by the older version of WP, or such?

Ah, that would be it. The code role__in was added in WP 4.4. You could try modifying this line:

'role__in' => array( 's2member_level1', 's2member_level2', 's2member_level3', 's2member_level4' ),

to this:

'role' => 's2member_level1',

and see if it works for members with that role. If so, you could then replace 1 with 2 and repeat to demote those at level 2 (or just repeat the code with 2 substituted for 1, and give the function a slightly different name).

Thanks, Tim, much appreciated.

I tried that, too, and it still didn’t find any users. I tried level 2 also, and no luck.

My client on this job has decided to stop pursuing this for the time being. They asked me to extend their gratitude for your assistance. Thank you!

1 Like