Skip to content

Instantly share code, notes, and snippets.

@chrisegg
Created December 12, 2025 17:16
Show Gist options
  • Select an option

  • Save chrisegg/0fd5d157ed1780dba0b8112bb891fb28 to your computer and use it in GitHub Desktop.

Select an option

Save chrisegg/0fd5d157ed1780dba0b8112bb891fb28 to your computer and use it in GitHub Desktop.
This cron-based code runs daily and automatically changes any user with an expired membership_expiration date from the "member" role to the "subscriber" role.
<?php
/**
* Change Role for Expired Memberships
*
* This cron-based code runs daily and automatically changes any user with an expired membership_expiration date from the
* "member" role to the "subscriber" role.
*
*
*
* Author: Chris Eggleston
* Version: 1.0
*
*
*/
// Schedule the daily expiration check if it's not already scheduled
add_action( 'wp', 'pmpro_schedule_expiration_check' );
function pmpro_schedule_expiration_check() {
if ( ! wp_next_scheduled( 'daily_membership_expiration_check' ) ) {
wp_schedule_event( strtotime('midnight'), 'daily', 'daily_membership_expiration_check' );
}
}
// The actual function that runs every day
add_action( 'daily_membership_expiration_check', 'downgrade_expired_members_to_subscriber' );
function downgrade_expired_members_to_subscriber() {
// Change these if your meta key or roles are named differently
$expiration_meta_key = 'membership_expiration'; // the same key you save in both forms
$paid_role = 'member'; // current paid role
$free_role = 'subscriber'; // role after expiration
$users = get_users(); // gets ALL user IDs (very fast)
$today = new DateTime('today'); // midnight today for accurate comparison
foreach ( $users as $user_id ) {
$expiration = get_user_meta( $user_id, $expiration_meta_key, true );
// Skip if no expiration date saved
if ( ! $expiration ) {
continue;
}
try {
$exp_date = DateTime::createFromFormat('m/d/Y', $expiration );
// If expiration date is in the past (or today), downgrade
if ( $exp_date && $exp_date < $today ) {
$user = new WP_User( $user_id );
// Only act if they actually have the paid role
if ( in_array( $paid_role, (array) $user->roles ) ) {
// Remove paid role
$user->remove_role( $paid_role );
// Add free role (in case they don't have it)
$user->add_role( $free_role );
// Optional: log or send email
error_log("Membership expired → downgraded user ID $user_id to subscriber on " . date('Y-m-d'));
}
}
} catch ( Exception $e ) {
// Bad date format – you could clean it up here if you want
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment