Forked from andrewlimaza/adjust-pmpro-subscription-delay.php
Last active
July 17, 2026 10:23
-
-
Save dwanjuki/0e01e2b9f2b02c1c1726a1e561082f3b to your computer and use it in GitHub Desktop.
Adjust Subscription Delay based on signup date
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 | |
| /** | |
| * Set the subscription profile_start_date to the 1st of a month. | |
| * | |
| * New signups: roughly one year from checkout, snapped to the 1st. | |
| * Renewals extended by the Auto-Renewal Checkbox Add On: keep the extended | |
| * start date it calculated, snapped to the 1st. | |
| * | |
| * NOTE: This is for yearly membership levels. | |
| */ | |
| function my_pmpro_set_annual_profile_start_date( $checkout_level ) { | |
| // Bail if the level isn't recurring. This also covers the case where the | |
| // Auto-Renewal Checkbox Add On has removed recurring billing because the | |
| // member left the auto-renew box unchecked. | |
| if ( ! pmpro_isLevelRecurring( $checkout_level ) ) { | |
| return $checkout_level; | |
| } | |
| if ( ! empty( $checkout_level->profile_start_date ) ) { | |
| // Another plugin already set a start date (e.g. the Auto-Renewal | |
| // Checkbox extending an existing membership). Keep that date, but | |
| // align it to the 1st-of-month rule. | |
| $checkout_level->profile_start_date = my_pmpro_snap_to_first_of_month( strtotime( $checkout_level->profile_start_date ) ); | |
| } else { | |
| // New signup: one year from now, aligned to the 1st-of-month rule. | |
| $checkout_level->profile_start_date = my_pmpro_snap_to_first_of_month( strtotime( '+1 year', current_time( 'timestamp' ) ) ); | |
| } | |
| add_filter( 'pmpro_level_cost_text', 'my_pmpro_annual_startdate_cost_text', 10, 2 ); | |
| return $checkout_level; | |
| } | |
| add_filter( 'pmpro_checkout_level', 'my_pmpro_set_annual_profile_start_date', 99 ); | |
| // Show the updated anniversary date for their renewal | |
| function my_pmpro_annual_startdate_cost_text( $cost, $level ) { | |
| if ( ! empty( $level->profile_start_date ) ) { | |
| $start_date = date_i18n( get_option( 'date_format' ), strtotime( $level->profile_start_date ) ); | |
| $cost .= ' ' . sprintf( '%s %s', esc_html__( 'Billing starts on', 'paid-memberships-pro' ), esc_html( $start_date ) ); | |
| } | |
| return $cost; | |
| } | |
| /** | |
| * Snap a timestamp to the "1st of the month" rule: | |
| * Days 1–14: 1st of that month. | |
| * Days 15+: 1st of the following month. | |
| * | |
| * @param int $timestamp Unix timestamp. | |
| * @return string MySQL-formatted date (Y-m-d H:i:s). | |
| */ | |
| function my_pmpro_snap_to_first_of_month( $timestamp ) { | |
| $day = (int) date( 'j', $timestamp ); | |
| $month = (int) date( 'n', $timestamp ); | |
| $year = (int) date( 'Y', $timestamp ); | |
| $time = date( 'H:i:s', $timestamp ); | |
| if ( $day > 14 ) { | |
| if ( 12 === $month ) { | |
| $month = 1; | |
| $year++; | |
| } else { | |
| $month++; | |
| } | |
| } | |
| return sprintf( '%04d-%02d-01 %s', $year, $month, $time ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment