Guest User

Untitled

a guest
May 20th, 2018
646
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.40 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4. Change cancellation to set expiration date for next payment instead of cancelling immediately.
  5.  
  6. Assumes orders are generated for each payment (i.e. your webhooks/etc are setup correctly).
  7.  
  8. Since 2015-09-21 and PMPro v1.8.5.6 contains code to look up next payment dates via Stripe and PayPal Express APIs.
  9. */
  10. //before cancelling, save the next_payment_timestamp to a global for later use. (Requires PMPro 1.8.5.6 or higher.)
  11. function my_pmpro_before_change_membership_level($level_id, $user_id) {
  12. //are we on the cancel page?
  13. global $pmpro_pages, $wpdb, $pmpro_stripe_event, $pmpro_next_payment_timestamp;
  14. if($level_id == 0 && (is_page($pmpro_pages['cancel']) || (is_admin() && (empty($_REQUEST['from']) || $_REQUEST['from'] != 'profile')))) {
  15. //get last order
  16. $order = new MemberOrder();
  17. $order->getLastMemberOrder($user_id, "success");
  18.  
  19. //get level to check if it already has an end date
  20. if(!empty($order) && !empty($order->membership_id))
  21. $level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_memberships_users WHERE membership_id = '" . $order->membership_id . "' AND user_id = '" . $user_id . "' ORDER BY id DESC LIMIT 1");
  22.  
  23. //figure out the next payment timestamp
  24. if(empty($level) || (!empty($level->enddate) && $level->enddate != '0000-00-00 00:00:00')) {
  25. //level already has an end date. set to false so we really cancel.
  26. $pmpro_next_payment_timestamp = false;
  27. } elseif(!empty($order) && $order->gateway == "payflowpro") {
  28. //if PayPal, try to use the API
  29. if(!empty($_POST['next_payment_date']) && $_POST['next_payment_date'] != 'N/A') {
  30. //cancel initiated from IPN
  31. $pmpro_next_payment_timestamp = strtotime($_POST['next_payment_date'], current_time('timestamp'));
  32. } else {
  33. //cancel initiated from PMPro
  34. $pmpro_next_payment_timestamp = PMProGateway_payflowpro::pmpro_next_payment("", $user_id, "success");
  35. }
  36. } else {
  37. //use built in PMPro function to guess next payment date
  38. $pmpro_next_payment_timestamp = pmpro_next_payment($user_id);
  39. }
  40. }
  41. }
  42. add_action('pmpro_before_change_membership_level', 'my_pmpro_before_change_membership_level', 10, 2);
  43.  
  44. //give users their level back with an expiration
  45. function my_pmpro_after_change_membership_level($level_id, $user_id) {
  46. global $pmpro_pages, $wpdb, $pmpro_next_payment_timestamp;
  47.  
  48. if($pmpro_next_payment_timestamp !== false && //this is false if the level already has an enddate
  49. $level_id == 0 && //make sure we're cancelling
  50. (is_page($pmpro_pages['cancel']) || (is_admin() && (empty($_REQUEST['from']) || $_REQUEST['from'] != 'profile')))) { //on the cancel page or in admin/adminajax/webhook and not the edit user page
  51. /*
  52. okay, let's give the user his old level back with an expiration based on his subscription date
  53. */
  54. //get last order
  55. $order = new MemberOrder();
  56. $order->getLastMemberOrder($user_id, "cancelled");
  57.  
  58. //can't do this if we can't find the order
  59. if(empty($order->id))
  60. return false;
  61.  
  62. //get the last level they had
  63. $level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_memberships_users WHERE membership_id = '" . $order->membership_id . "' AND user_id = '" . $user_id . "' ORDER BY id DESC LIMIT 1");
  64.  
  65. //can't do if we can't find an old level
  66. if(empty($level))
  67. return false;
  68.  
  69. //last payment date
  70. $lastdate = date("Y-m-d", $order->timestamp);
  71.  
  72. /*
  73. next payment date
  74. */
  75. //if stripe or PayPal, try to use the API
  76. if(!empty($pmpro_next_payment_timestamp)) {
  77. $nextdate = $pmpro_next_payment_timestamp;
  78. } else {
  79. $nextdate = $wpdb->get_var("SELECT UNIX_TIMESTAMP('" . $lastdate . "' + INTERVAL " . $level->cycle_number . " " . $level->cycle_period . ")");
  80. }
  81.  
  82. //if the date in the future?
  83. if($nextdate - time() > 0) {
  84. //give them their level back with the expiration date set
  85. $old_level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_memberships_users WHERE membership_id = '" . $order->membership_id . "' AND user_id = '" . $user_id . "' ORDER BY id DESC LIMIT 1", ARRAY_A);
  86. $old_level['enddate'] = date("Y-m-d H:i:s", $nextdate);
  87.  
  88. //disable this hook so we don't loop
  89. remove_action("pmpro_after_change_membership_level", "my_pmpro_after_change_membership_level", 10, 2);
  90. remove_filter('pmpro_cancel_previous_subscriptions', 'my_pmpro_before_change_membership_level', 10, 2);
  91.  
  92. //disable the action to set the default level on cancels
  93. remove_action('pmpro_after_change_membership_level', 'pmpro_after_change_membership_level_default_level', 10, 2);
  94.  
  95. //change level
  96. pmpro_changeMembershipLevel($old_level, $user_id);
  97.  
  98. //add the action back just in case
  99. add_action("pmpro_after_change_membership_level", "my_pmpro_after_change_membership_level", 10, 2);
  100. add_filter('pmpro_cancel_previous_subscriptions', 'my_pmpro_before_change_membership_level', 10, 2);
  101.  
  102. //add the action back to set the default level on cancels
  103. remove_action('pmpro_after_change_membership_level', 'pmpro_after_change_membership_level_default_level', 10, 2);
  104.  
  105. //change message shown on cancel page
  106. add_filter("gettext", "my_gettext_cancel_text", 10, 3);
  107. }
  108. }
  109.  
  110. //clear up this global in case we're changing many levels at once (e.g. expiration script running)
  111. unset($pmpro_next_payment_timestamp);
  112. }
  113. add_action("pmpro_after_change_membership_level", "my_pmpro_after_change_membership_level", 10, 2);
  114.  
  115. //this replaces the cancellation text so people know they'll still have access for a certain amount of time
  116. function my_gettext_cancel_text($translated_text, $text, $domain) {
  117. if(($domain == "pmpro" || $domain == "paid-memberships-pro") && $text == "Your membership has been cancelled.") {
  118. global $current_user;
  119. $translated_text = "Your recurring subscription has been cancelled. Your active membership will expire on " . date(get_option("date_format"), pmpro_next_payment($current_user->ID, "cancelled")) . ".";
  120. }
  121.  
  122. return $translated_text;
  123. }
  124.  
  125. //want to update the cancellation email as well
  126. function my_pmpro_email_body($body, $email) {
  127. if($email->template == "cancel") {
  128. global $wpdb;
  129. $user_id = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_email = '" . esc_sql($email->email) . "' LIMIT 1");
  130. if(!empty($user_id)) {
  131. $expiration_date = pmpro_next_payment($user_id);
  132.  
  133. //if the date in the future?
  134. if($expiration_date - time() > 0) {
  135. $body .= "<p>Your access will expire on " . date(get_option("date_format"), $expiration_date) . ".</p>";
  136. }
  137. }
  138. }
  139.  
  140. return $body;
  141. }
  142. add_filter("pmpro_email_body", "my_pmpro_email_body", 10, 2);
Add Comment
Please, Sign In to add comment