Created
December 12, 2025 17:16
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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