Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save eighty20results/f892cda6326c56eded60 to your computer and use it in GitHub Desktop.
Save eighty20results/f892cda6326c56eded60 to your computer and use it in GitHub Desktop.
add_action( "pmpro_after_change_membership_level", "e20r_cancel_at_end_of_period", 10, 2 );
add_filter( "pmpro_email_body", "e20r_email_body_for_cancel_msg", 10, 2 );
/**
* Change cancellation to set expiration date for next payment instead of cancelling immediately.
* Assumes monthly membership levels.
* Assumes orders are generated for each payment (i.e. your webhooks/etc are setup correctly).
*
* @param (int) $level_id -- The membership levelId we're changing
* @param (int) $user_id -- The member we're changing levels for.
*/
function e20r_cancel_at_end_of_period( $level_id, $user_id ) {
global $pmpro_pages, $wpdb;
// Make sure we're on the 'cancel' page (for PMPro).
if ( is_page( $pmpro_pages['cancel'] ) ) {
/*
* okay, let's give the user his old level back with an expiration based on his subscription date
*/
/* Fetch the last order */
$order = new MemberOrder();
$order->getLastMemberOrder( $user_id, "cancelled" );
// Fetch the levelId representing their most recent (old) membership level.
$level = $wpdb->get_row( $wpdb->prepare("
SELECT *
FROM {$wpdb->pmpro_memberships_users}
WHERE membership_id = %d AND user_id = %d
ORDER BY id DESC
LIMIT 1
",
$order->membership_id,
$user_id )
);
// Not allowed to do this unless there's both a levelId and an order located in the system
// This is probably wrong since $order rarely (never?) is empty.
if ( ( ! isset( $order->user_id ) ) || empty( $level ) ) {
return false;
}
if ( empty( $level->cylcle_number ) ) {
return false;
}
// Calculate the "last payment date" (using "today").
$lastdate = date("Y-m-d", $order->timestamp);
//Calculating the "next scheduled date"
$nextdate = $wpdb->get_var( $wpdb->prepare("
SELECT UNIX_TIMESTAMP(%s + INTERVAL %d {$level->cycle_period})
",
$lastdate,
$level->cycle_number
)
);
//if the date in the future?
if ( $nextdate - current_time('timestamp') > 0 ) {
// Set their level to the one they're currently at, but leave the expiration date set to their next billing date.
$sql = $wpdb->prepare("
SELECT *
FROM $wpdb->pmpro_memberships_users
WHERE ( membership_id = %d ) AND ( user_id = %d )
ORDER BY id
DESC LIMIT 1
",
$order->membership_id,
$user_id
);
$old_level = $wpdb->get_row( $sql, ARRAY_A );
$old_level['enddate'] = date( "Y-m-d H:i:s", $nextdate );
//disable this hook so we don't loop
remove_action( "pmpro_after_change_membership_level", "e20r_cancel_at_end_of_period", 10, 2 );
remove_action( "pmpro_after_change_membership_level", "e20r_membership_level_config", 10, 2 );
remove_action( "pmpro_after_change_membership_level", "e20r_clear_upcoming_appointments", 11, 2 );
remove_action( "pmpro_after_change_membership_level", "e20r_after_change_membership_level", 10, 2);
//change level
pmpro_changeMembershipLevel( $old_level, $user_id );
//add the action back just in case
add_action( "pmpro_after_change_membership_level", "e20r_cancel_at_end_of_period", 10, 2 );
add_action( "pmpro_after_change_membership_level", "e20r_membership_level_config", 10, 2 );
add_action( "pmpro_after_change_membership_level", "e20r_clear_upcoming_appointments", 11, 2 );
add_action( "pmpro_after_change_membership_level", "e20r_after_change_membership_level", 10, 2);
//change message shown on cancel page
add_filter( "gettext", "e20r_gettext_cancel_text", 10, 3 );
}
}
}
/**
* @param $translated_text -- Text to replace/update
* @param $text -- The text
* @param $domain
*
* @return string
*/
function e20r_gettext_cancel_text( $translated_text, $text, $domain ) {
if ( ( $domain == "pmpro" ) &&
( $text == "Your membership has been cancelled." ) ) {
global $current_user;
$translated_text = "Your membership has been cancelled. Your access to schedule and join new sessions will expire on " .
date_i18n( get_option( "date_format" ), pmpro_next_payment( $current_user->ID, "cancelled" ) ) .
", but you may schedule new sessions until then. Once your membership expires, any scheduled sessions " .
"will be removed automatically.";
}
return $translated_text;
}
/**
* If the user cancels, send a message about when the cancellation will actually occur.
*
* @param (string) $body - The content of the message (we'll append the cancellation date to it)
* @param (object) $email -- The email object.
*
* @return string -- The new body of the email message.
*/
function e20r_email_body_for_cancel_msg( $body, $email ) {
if ( $email->template == "cancel" ) {
global $wpdb;
$user_id = $wpdb->get_var("
SELECT ID
FROM $wpdb->users
WHERE user_email = '" . esc_sql( $email->email ) . "' LIMIT 1"
);
if( ! empty( $user_id ) ) {
$expiration_date = pmpro_next_payment( $user_id );
// Only update the body of the message if the date is in the future.
if ( $expiration_date - current_time('timestamp') > 0 ) {
$body .= "<p>Your access will expire on " . date( get_option( "date_format" ), $expiration_date ) . ".</p>";
}
}
}
return $body;
}
@developerarj-zz
Copy link

I have added this code in theme functions but not working at all, any suggestions ??
PMP - 1.8.6.7
WP - 4.4.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment