diff --git a/includes/checkout.php b/includes/checkout.php index 666b0ae..277d7a8 100644 --- a/includes/checkout.php +++ b/includes/checkout.php @@ -168,10 +168,23 @@ function pmprorate_pmpro_checkout_level( $level ) { $level->initial_payment = 0; // If purchasing a subscription, make sure payment date stays the same. - add_filter( 'pmpro_profile_start_date', 'pmprorate_set_startdate_to_next_payment_date', 10, 2 ); - - // Set up the delayed downgrade. - $pmprorate_is_downgrade = true; + // Check if we are using PMPro v3.4+. That version starts supporting the `profile_start_date` property on the level object. + if ( defined( 'PMPRO_VERSION' ) && version_compare( PMPRO_VERSION, '3.4', '>=' ) ) { + // Get the subscription. + $current_subscriptions = PMPro_Subscription::get_subscriptions_for_user( get_current_user_id(), $clevel_id ); + + // Use the new `profile_start_date` property on the level object. + $level->profile_start_date = empty( $current_subscriptions ) ? null : $current_subscriptions[0]->get_next_payment_date( 'Y-m-d H:i:s' ); + + // Remember the fact that this is a downgrade. + $level->pmprorate_is_downgrade = true; + } else { + // Use the old filter. + add_filter( 'pmpro_profile_start_date', 'pmprorate_set_startdate_to_next_payment_date', 10, 2 ); + + // Set up the delayed downgrade. + $pmprorate_is_downgrade = true; + } // Bail to avoid further proration logic. return $level; @@ -262,8 +275,15 @@ function pmprorate_pmpro_checkout_level( $level ) { $remaining_cost_for_new_level = $level->billing_amount * $per_left; $level->initial_payment = min( $level->initial_payment, round( $remaining_cost_for_new_level - $credit, 2 ) ); - //make sure payment date stays the same - add_filter( 'pmpro_profile_start_date', 'pmprorate_set_startdate_to_next_payment_date', 10, 2 ); + // If purchasing a subscription, make sure payment date stays the same. + // Check if we are using PMPro v3.4+. That version starts supporting the `profile_start_date` property on the level object. + if ( defined( 'PMPRO_VERSION' ) && version_compare( PMPRO_VERSION, '3.4', '>=' ) ) { + // Use the new `profile_start_date` property on the level object. + $level->profile_start_date = date_i18n( 'Y-m-d H:i:s', $next_payment_date ); + } else { + // Use the old filter. + add_filter( 'pmpro_profile_start_date', 'pmprorate_set_startdate_to_next_payment_date', 10, 2 ); + } } else { /* Upgrade with different payment periods in a nutshell: diff --git a/includes/delayed-downgrades.php b/includes/delayed-downgrades.php index 2163253..0aee6d3 100644 --- a/includes/delayed-downgrades.php +++ b/includes/delayed-downgrades.php @@ -46,9 +46,14 @@ function pmprorate_added_order_mark_order_as_downgrade( $order ) { return; } + // Get the level for this order. + $level = $order->getMembershipLevelAtCheckout(); + // Update order meta. - if ( ! empty( $pmprorate_is_downgrade ) ) { + if ( ! empty( $pmprorate_is_downgrade ) ) { // This will only ever be set before PMPro v3.4. update_pmpro_membership_order_meta( $order->id, 'pmprorate_is_downgrade', $pmprorate_is_downgrade ); + } elseif( ! empty( $level->pmprorate_is_downgrade ) ) { // This will only ever be set after PMPro v3.4. + update_pmpro_membership_order_meta( $order->id, 'pmprorate_is_downgrade', $level->pmprorate_is_downgrade ); } } @@ -79,10 +84,13 @@ function pmprorate_checkout_before_change_membership_level_remember_downgrade( $ $order->membership_id = $pmpro_level->id; } + // Get the level for the order. + $level = $order->getMembershipLevelAtCheckout(); + // If this order was not marked as a downgrade, bail. // $pmprorate_is_downgrade checks if the checkout started processing on this page load. // Checking order meta checks if the checkout started processing on a previous page load, such as with offsite payment gateways. - if ( empty( get_pmpro_membership_order_meta( $order->id, 'pmprorate_is_downgrade', true ) ) && empty( $pmprorate_is_downgrade) ) { + if ( empty( get_pmpro_membership_order_meta( $order->id, 'pmprorate_is_downgrade', true ) ) && empty( $pmprorate_is_downgrade ) && empty( $level->pmprorate_is_downgrade ) ) { return; }