Paid Memberships Pro - Version 2.5.1

Version Description

  • 2020-10-16 =
  • SECURITY: Fixed XSS vulnerability on the Members List page of the dashboard. (Thanks, Ron Masas from Checkmarx.com)
  • ENHANCEMENT: Add Ukrainian Hryvnia currency. (Thanks, Mirco Babini)
  • ENHANCEMENT: Added a "non-members" option to the Beaver Build module.
  • BUG FIX: Fixed issue where only USD and US were allowed with Stripe's GooglePay/ApplePay buttons.
  • BUG FIX: Fixed issue where some profile fields, e.g. those added with Register Helper, were accidentally updated or removed when accessing the frontend profile page.
  • BUG FIX: Fixed issue with tracking discount code uses when using the 2Checkout gateway. (Thanks, karambk on GitHub)
  • BUG FIX: No longer running excerpts through wpautop when a more tag is used.
Download this release

Release Info

Developer strangerstudios
Plugin Icon 128x128 Paid Memberships Pro
Version 2.5.1
Comparing to
See all releases

Code changes from version 2.5 to 2.5.1

CHANGELOG.txt CHANGED
@@ -1,4 +1,13 @@
1
  == Changelog ==
 
 
 
 
 
 
 
 
 
2
  = 2.5 - 2020-10-02 =
3
  * FEATURE: When using the Stripe Gateway, you may now allow users to pay using Apple Pay, Google Pay, or Microsoft Pay depending on their browser. Enable this feature from the payment settings page.
4
  * FEATURE: Added Divi Builder compatibility.
1
  == Changelog ==
2
+ = 2.5.1 - 2020-10-16 =
3
+ * SECURITY: Fixed XSS vulnerability on the Members List page of the dashboard. (Thanks, Ron Masas from Checkmarx.com)
4
+ * ENHANCEMENT: Add Ukrainian Hryvnia currency. (Thanks, Mirco Babini)
5
+ * ENHANCEMENT: Added a "non-members" option to the Beaver Build module.
6
+ * BUG FIX: Fixed issue where only USD and US were allowed with Stripe's GooglePay/ApplePay buttons.
7
+ * BUG FIX: Fixed issue where some profile fields, e.g. those added with Register Helper, were accidentally updated or removed when accessing the frontend profile page.
8
+ * BUG FIX: Fixed issue with tracking discount code uses when using the 2Checkout gateway. (Thanks, karambk on GitHub)
9
+ * BUG FIX: No longer running excerpts through wpautop when a more tag is used.
10
+
11
  = 2.5 - 2020-10-02 =
12
  * FEATURE: When using the Stripe Gateway, you may now allow users to pay using Apple Pay, Google Pay, or Microsoft Pay depending on their browser. Enable this feature from the payment settings page.
13
  * FEATURE: Added Divi Builder compatibility.
adminpages/memberslist.php CHANGED
@@ -23,7 +23,7 @@ if ( isset( $_REQUEST['l'] ) ) {
23
 
24
  <?php do_action( 'pmpro_memberslist_before_table' ); ?>
25
  <form id="member-list-form" method="get">
26
- <input type="hidden" name="page" value="<?php echo $_REQUEST['page']; ?>" />
27
  <?php
28
  $user_list_table->search_box( __( 'Search Members', 'paid-memberships-pro' ), 'paid-memberships-pro' );
29
  $user_list_table->display();
23
 
24
  <?php do_action( 'pmpro_memberslist_before_table' ); ?>
25
  <form id="member-list-form" method="get">
26
+ <input type="hidden" name="page" value="pmpro-memberslist" />
27
  <?php
28
  $user_list_table->search_box( __( 'Search Members', 'paid-memberships-pro' ), 'paid-memberships-pro' );
29
  $user_list_table->display();
classes/gateways/class.pmprogateway_stripe.php CHANGED
@@ -12,6 +12,7 @@ use Stripe\Subscription as Stripe_Subscription;
12
  use Stripe\ApplePayDomain as Stripe_ApplePayDomain;
13
  use Stripe\WebhookEndpoint as Stripe_Webhook;
14
  use Stripe\StripeClient as Stripe_Client; // Used for deleting webhook as of 2.4
 
15
 
16
  define( "PMPRO_STRIPE_API_VERSION", "2020-03-02" );
17
 
@@ -304,6 +305,9 @@ class PMProGateway_stripe extends PMProGateway {
304
  self::update_webhook_events();
305
  }
306
  }
 
 
 
307
  }
308
 
309
  ?>
@@ -638,7 +642,7 @@ class PMProGateway_stripe extends PMProGateway {
638
  */
639
  static function pmpro_checkout_after_preheader( $order ) {
640
 
641
- global $gateway, $pmpro_level, $current_user, $pmpro_requirebilling, $pmpro_pages;
642
 
643
  $default_gateway = pmpro_getOption( "gateway" );
644
 
@@ -657,6 +661,8 @@ class PMProGateway_stripe extends PMProGateway {
657
  'restUrl' => get_rest_url(),
658
  'siteName' => get_bloginfo( 'name' ),
659
  'updatePaymentRequestButton' => apply_filters( 'pmpro_stripe_update_payment_request_button', true ),
 
 
660
  );
661
 
662
  if ( ! empty( $order ) ) {
@@ -3181,6 +3187,37 @@ class PMProGateway_stripe extends PMProGateway {
3181
  }
3182
  }
3183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3184
  function clean_up( &$order ) {
3185
  if ( ! empty( $this->payment_intent ) && 'succeeded' == $this->payment_intent->status ) {
3186
  $order->payment_transaction_id = $this->payment_intent->charges->data[0]->id;
12
  use Stripe\ApplePayDomain as Stripe_ApplePayDomain;
13
  use Stripe\WebhookEndpoint as Stripe_Webhook;
14
  use Stripe\StripeClient as Stripe_Client; // Used for deleting webhook as of 2.4
15
+ use Stripe\Account as Stripe_Account;
16
 
17
  define( "PMPRO_STRIPE_API_VERSION", "2020-03-02" );
18
 
305
  self::update_webhook_events();
306
  }
307
  }
308
+
309
+ // Break the country cache in case new credentials were saved.
310
+ delete_transient( 'pmpro_stripe_account_country' );
311
  }
312
 
313
  ?>
642
  */
643
  static function pmpro_checkout_after_preheader( $order ) {
644
 
645
+ global $gateway, $pmpro_level, $current_user, $pmpro_requirebilling, $pmpro_pages, $pmpro_currency;
646
 
647
  $default_gateway = pmpro_getOption( "gateway" );
648
 
661
  'restUrl' => get_rest_url(),
662
  'siteName' => get_bloginfo( 'name' ),
663
  'updatePaymentRequestButton' => apply_filters( 'pmpro_stripe_update_payment_request_button', true ),
664
+ 'currency' => strtolower( $pmpro_currency ),
665
+ 'accountCountry' => self::get_account_country(),
666
  );
667
 
668
  if ( ! empty( $order ) ) {
3187
  }
3188
  }
3189
 
3190
+ function get_account() {
3191
+ try {
3192
+ $account = Stripe_Account::retrieve();
3193
+ } catch ( Stripe\Error\Base $e ) {
3194
+ return false;
3195
+ } catch ( \Throwable $e ) {
3196
+ return false;
3197
+ } catch ( \Exception $e ) {
3198
+ return false;
3199
+ }
3200
+
3201
+ if ( empty( $account ) ) {
3202
+ return false;
3203
+ }
3204
+
3205
+ return $account;
3206
+ }
3207
+
3208
+ static function get_account_country() {
3209
+ $account_country = get_transient( 'pmpro_stripe_account_country' );
3210
+ if ( empty( $account_country ) ) {
3211
+ $stripe = new PMProGateway_stripe();
3212
+ $account = $stripe->get_account();
3213
+ if ( ! empty( $account ) && ! empty( $account->country ) ) {
3214
+ $account_country = $account->country;
3215
+ set_transient( 'pmpro_stripe_account_country', $account_country );
3216
+ }
3217
+ }
3218
+ return $account_country ?: 'US';
3219
+ }
3220
+
3221
  function clean_up( &$order ) {
3222
  if ( ! empty( $this->payment_intent ) && 'succeeded' == $this->payment_intent->status ) {
3223
  $order->payment_transaction_id = $this->payment_intent->charges->data[0]->id;
classes/gateways/class.pmprogateway_twocheckout.php CHANGED
@@ -217,7 +217,7 @@
217
  */
218
  static function pmpro_checkout_before_change_membership_level($user_id, $morder)
219
  {
220
- global $wpdb, $discount_code_id;
221
 
222
  //if no order, no need to pay
223
  if(empty($morder))
@@ -227,9 +227,11 @@
227
  $morder->saveOrder();
228
 
229
  //save discount code use
230
- if(!empty($discount_code_id))
 
 
231
  $wpdb->query("INSERT INTO $wpdb->pmpro_discount_codes_uses (code_id, user_id, order_id, timestamp) VALUES('" . $discount_code_id . "', '" . $user_id . "', '" . $morder->id . "', now())");
232
-
233
  do_action("pmpro_before_send_to_twocheckout", $user_id, $morder);
234
 
235
  $morder->Gateway->sendToTwocheckout($morder);
217
  */
218
  static function pmpro_checkout_before_change_membership_level($user_id, $morder)
219
  {
220
+ global $wpdb;
221
 
222
  //if no order, no need to pay
223
  if(empty($morder))
227
  $morder->saveOrder();
228
 
229
  //save discount code use
230
+ if(isset($morder->membership_level) && !empty($morder->membership_level->code_id))
231
+ {
232
+ $discount_code_id = (int)$morder->membership_level->code_id;
233
  $wpdb->query("INSERT INTO $wpdb->pmpro_discount_codes_uses (code_id, user_id, order_id, timestamp) VALUES('" . $discount_code_id . "', '" . $user_id . "', '" . $morder->id . "', now())");
234
+ }
235
  do_action("pmpro_before_send_to_twocheckout", $user_id, $morder);
236
 
237
  $morder->Gateway->sendToTwocheckout($morder);
includes/compatibility/beaver-builder.php CHANGED
@@ -26,9 +26,11 @@ function pmpro_beaver_builder_settings_form( $form, $id ) {
26
  }
27
  global $membership_levels;
28
  $levels = array();
 
29
  foreach ( $membership_levels as $level ) {
30
  $levels[ $level->id ] = $level->name;
31
  }
 
32
  $row_settings_pmpro = array(
33
  'title' => __( 'PMPro', 'paid-memberships-pro' ),
34
  'sections' => array(
@@ -83,6 +85,7 @@ function pmpro_beaver_builder_check_field_connections( $is_visible, $node ) {
83
  if ( ! defined( 'PMPRO_VERSION' ) ) {
84
  return $is_visible;
85
  }
 
86
  if ( 'row' === $node->type ) {
87
  if ( isset( $node->settings->pmpro_enable ) && 'yes' === $node->settings->pmpro_enable ) {
88
  if ( pmpro_hasMembershipLevel( $node->settings->pmpro_memberships ) || empty( $node->settings->pmpro_memberships ) ) {
@@ -120,6 +123,7 @@ function pmpro_beaver_builder_add_custom_tab_all_modules( $form, $slug ) {
120
  if ( in_array( $slug, $modules, true ) ) {
121
  global $membership_levels;
122
  $levels = array();
 
123
  foreach ( $membership_levels as $level ) {
124
  $levels[ $level->id ] = $level->name;
125
  }
26
  }
27
  global $membership_levels;
28
  $levels = array();
29
+ $levels[0] = __( 'Non-members', 'paid-memberships-pro' );
30
  foreach ( $membership_levels as $level ) {
31
  $levels[ $level->id ] = $level->name;
32
  }
33
+
34
  $row_settings_pmpro = array(
35
  'title' => __( 'PMPro', 'paid-memberships-pro' ),
36
  'sections' => array(
85
  if ( ! defined( 'PMPRO_VERSION' ) ) {
86
  return $is_visible;
87
  }
88
+
89
  if ( 'row' === $node->type ) {
90
  if ( isset( $node->settings->pmpro_enable ) && 'yes' === $node->settings->pmpro_enable ) {
91
  if ( pmpro_hasMembershipLevel( $node->settings->pmpro_memberships ) || empty( $node->settings->pmpro_memberships ) ) {
123
  if ( in_array( $slug, $modules, true ) ) {
124
  global $membership_levels;
125
  $levels = array();
126
+ $levels[0] = __( 'Non-members', 'paid-memberships-pro' );
127
  foreach ( $membership_levels as $level ) {
128
  $levels[ $level->id ] = $level->name;
129
  }
includes/content.php CHANGED
@@ -313,18 +313,18 @@ function pmpro_membership_content_filter( $content, $skipcheck = false ) {
313
  } elseif(strpos($content, "<span id=\"more-" . $post->ID . "\"></span>") !== false) {
314
  //more tag
315
  $pos = strpos($content, "<span id=\"more-" . $post->ID . "\"></span>");
316
- $content = wpautop(substr($content, 0, $pos));
317
  } elseif(strpos($content, 'class="more-link">') !== false) {
318
  //more link
319
  $content = preg_replace("/\<a.*class\=\"more\-link\".*\>.*\<\/a\>/", "", $content);
320
  } elseif(strpos($content, "<!-- wp:more -->") !== false) {
321
  //more block
322
  $pos = strpos($content, "<!-- wp:more -->");
323
- $content = wpautop(substr($content, 0, $pos));
324
  } elseif(strpos($content, "<!--more-->") !== false) {
325
  //more tag
326
  $pos = strpos($content, "<!--more-->");
327
- $content = wpautop(substr($content, 0, $pos));
328
  } else {
329
  //auto generated excerpt. pulled from wp_trim_excerpt
330
  $content = strip_shortcodes( $content );
313
  } elseif(strpos($content, "<span id=\"more-" . $post->ID . "\"></span>") !== false) {
314
  //more tag
315
  $pos = strpos($content, "<span id=\"more-" . $post->ID . "\"></span>");
316
+ $content = substr($content, 0, $pos);
317
  } elseif(strpos($content, 'class="more-link">') !== false) {
318
  //more link
319
  $content = preg_replace("/\<a.*class\=\"more\-link\".*\>.*\<\/a\>/", "", $content);
320
  } elseif(strpos($content, "<!-- wp:more -->") !== false) {
321
  //more block
322
  $pos = strpos($content, "<!-- wp:more -->");
323
+ $content = substr($content, 0, $pos);
324
  } elseif(strpos($content, "<!--more-->") !== false) {
325
  //more tag
326
  $pos = strpos($content, "<!--more-->");
327
+ $content = substr($content, 0, $pos);
328
  } else {
329
  //auto generated excerpt. pulled from wp_trim_excerpt
330
  $content = strip_shortcodes( $content );
includes/currencies.php CHANGED
@@ -99,6 +99,14 @@
99
  'TWD' => __('Taiwan New Dollars', 'paid-memberships-pro' ),
100
  'THB' => __('Thai Baht', 'paid-memberships-pro' ),
101
  'TRY' => __('Turkish Lira', 'paid-memberships-pro' ),
 
 
 
 
 
 
 
 
102
  'VND' => array(
103
  'name' => __('Vietnamese Dong', 'paid-memberships-pro' ),
104
  'decimals' => 0,
99
  'TWD' => __('Taiwan New Dollars', 'paid-memberships-pro' ),
100
  'THB' => __('Thai Baht', 'paid-memberships-pro' ),
101
  'TRY' => __('Turkish Lira', 'paid-memberships-pro' ),
102
+ 'UAH' => array(
103
+ 'name' => __('Ukrainian Hryvnia (&#8372;)', 'paid-memberships-pro' ),
104
+ 'decimals' => 0,
105
+ 'thousands_separator' => '',
106
+ 'decimal_separator' => ',',
107
+ 'symbol' => '&#8372;',
108
+ 'position' => 'right'
109
+ ),
110
  'VND' => array(
111
  'name' => __('Vietnamese Dong', 'paid-memberships-pro' ),
112
  'decimals' => 0,
includes/profile.php CHANGED
@@ -405,13 +405,12 @@ function pmpro_member_profile_edit_form() {
405
  return;
406
  }
407
 
408
- do_action( 'pmpro_personal_options_update', $current_user->ID );
409
-
410
  // Saving profile updates.
411
  if ( isset( $_POST['action'] ) && $_POST['action'] == 'update-profile' && $current_user->ID == $_POST['user_id'] && wp_verify_nonce( $_POST['update_user_nonce'], 'update-user_' . $current_user->ID ) ) {
412
  $update = true;
413
  $user = new stdClass;
414
  $user->ID = $_POST[ 'user_id' ];
 
415
  } else {
416
  $update = false;
417
  }
405
  return;
406
  }
407
 
 
 
408
  // Saving profile updates.
409
  if ( isset( $_POST['action'] ) && $_POST['action'] == 'update-profile' && $current_user->ID == $_POST['user_id'] && wp_verify_nonce( $_POST['update_user_nonce'], 'update-user_' . $current_user->ID ) ) {
410
  $update = true;
411
  $user = new stdClass;
412
  $user->ID = $_POST[ 'user_id' ];
413
+ do_action( 'pmpro_personal_options_update', $user->ID );
414
  } else {
415
  $update = false;
416
  }
js/pmpro-stripe.js CHANGED
@@ -106,8 +106,8 @@ jQuery( document ).ready( function( $ ) {
106
  success: function(data) {
107
  if ( data.hasOwnProperty('initial_payment') ) {
108
  paymentRequest = stripe.paymentRequest({
109
- country: 'US',
110
- currency: 'usd',
111
  total: {
112
  label: pmproStripe.siteName,
113
  amount: data.initial_payment * 100,
106
  success: function(data) {
107
  if ( data.hasOwnProperty('initial_payment') ) {
108
  paymentRequest = stripe.paymentRequest({
109
+ country: pmproStripe.accountCountry,
110
+ currency: pmproStripe.currency,
111
  total: {
112
  label: pmproStripe.siteName,
113
  amount: data.initial_payment * 100,
languages/gettext.sh CHANGED
@@ -16,6 +16,12 @@ xgettext -j -o languages/paid-memberships-pro.pot \
16
  --keyword=_ex \
17
  --keyword=_n \
18
  --keyword=_x \
 
 
 
 
 
 
19
  --sort-by-file \
20
  --package-version=1.0 \
21
  --msgid-bugs-address="jason@strangerstudios.com" \
16
  --keyword=_ex \
17
  --keyword=_n \
18
  --keyword=_x \
19
+ --keyword=esc_html__ \
20
+ --keyword=esc_html_e \
21
+ --keyword=esc_html_x \
22
+ --keyword=esc_attr__ \
23
+ --keyword=esc_attr_e \
24
+ --keyword=esc_attr_x \
25
  --sort-by-file \
26
  --package-version=1.0 \
27
  --msgid-bugs-address="jason@strangerstudios.com" \
paid-memberships-pro.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Paid Memberships Pro
4
  * Plugin URI: https://www.paidmembershipspro.com
5
  * Description: The most complete member management and membership subscriptions plugin for WordPress.
6
- * Version: 2.5
7
  * Author: Stranger Studios
8
  * Author URI: https://www.strangerstudios.com
9
  * Text Domain: paid-memberships-pro
@@ -16,7 +16,7 @@
16
  */
17
 
18
  // version constant
19
- define( 'PMPRO_VERSION', '2.5' );
20
  define( 'PMPRO_USER_AGENT', 'Paid Memberships Pro v' . PMPRO_VERSION . '; ' . site_url() );
21
  define( 'PMPRO_MIN_PHP_VERSION', '5.6' );
22
 
3
  * Plugin Name: Paid Memberships Pro
4
  * Plugin URI: https://www.paidmembershipspro.com
5
  * Description: The most complete member management and membership subscriptions plugin for WordPress.
6
+ * Version: 2.5.1
7
  * Author: Stranger Studios
8
  * Author URI: https://www.strangerstudios.com
9
  * Text Domain: paid-memberships-pro
16
  */
17
 
18
  // version constant
19
+ define( 'PMPRO_VERSION', '2.5.1' );
20
  define( 'PMPRO_USER_AGENT', 'Paid Memberships Pro v' . PMPRO_VERSION . '; ' . site_url() );
21
  define( 'PMPRO_MIN_PHP_VERSION', '5.6' );
22
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: strangerstudios, kimannwall, andrewza, dlparker1005, paidmembershipspro
3
  Tags: memberships, members, subscriptions, ecommerce, user registration, member, membership, e-commerce, paypal, stripe, braintree, authorize.net, payflow, restrict access, restrict content, directory
4
  Requires at least: 4
5
- Tested up to: 5.5
6
- Stable tag: 2.5
7
 
8
  Get Paid with Paid Memberships Pro: The most complete member management and membership subscriptions plugin for your WordPress site.
9
 
@@ -153,6 +153,15 @@ Not sure? You can find out by doing a bit a research.
153
  9. Membership Account page, display all sections or show specific sections using shortcode attributes.
154
 
155
  == Changelog ==
 
 
 
 
 
 
 
 
 
156
  = 2.5 - 2020-10-02 =
157
  * FEATURE: When using the Stripe Gateway, you may now allow users to pay using Apple Pay, Google Pay, or Microsoft Pay depending on their browser. Enable this feature from the payment settings page.
158
  * FEATURE: Added Divi Builder compatibility.
2
  Contributors: strangerstudios, kimannwall, andrewza, dlparker1005, paidmembershipspro
3
  Tags: memberships, members, subscriptions, ecommerce, user registration, member, membership, e-commerce, paypal, stripe, braintree, authorize.net, payflow, restrict access, restrict content, directory
4
  Requires at least: 4
5
+ Tested up to: 5.5.3
6
+ Stable tag: 2.5.1
7
 
8
  Get Paid with Paid Memberships Pro: The most complete member management and membership subscriptions plugin for your WordPress site.
9
 
153
  9. Membership Account page, display all sections or show specific sections using shortcode attributes.
154
 
155
  == Changelog ==
156
+ = 2.5.1 - 2020-10-16 =
157
+ * SECURITY: Fixed XSS vulnerability on the Members List page of the dashboard. (Thanks, Ron Masas from Checkmarx.com)
158
+ * ENHANCEMENT: Add Ukrainian Hryvnia currency. (Thanks, Mirco Babini)
159
+ * ENHANCEMENT: Added a "non-members" option to the Beaver Build module.
160
+ * BUG FIX: Fixed issue where only USD and US were allowed with Stripe's GooglePay/ApplePay buttons.
161
+ * BUG FIX: Fixed issue where some profile fields, e.g. those added with Register Helper, were accidentally updated or removed when accessing the frontend profile page.
162
+ * BUG FIX: Fixed issue with tracking discount code uses when using the 2Checkout gateway. (Thanks, karambk on GitHub)
163
+ * BUG FIX: No longer running excerpts through wpautop when a more tag is used.
164
+
165
  = 2.5 - 2020-10-02 =
166
  * FEATURE: When using the Stripe Gateway, you may now allow users to pay using Apple Pay, Google Pay, or Microsoft Pay depending on their browser. Enable this feature from the payment settings page.
167
  * FEATURE: Added Divi Builder compatibility.
services/twocheckout-ins.php CHANGED
@@ -274,6 +274,17 @@
274
  //set the start date to current_time('mysql') but allow filters (documented in preheaders/checkout.php)
275
  $startdate = apply_filters("pmpro_checkout_start_date", "'" . current_time('mysql') . "'", $morder->user_id, $morder->membership_level);
276
 
 
 
 
 
 
 
 
 
 
 
 
277
  //fix expiration date
278
  if(!empty($morder->membership_level->expiration_number))
279
  {
@@ -287,19 +298,6 @@
287
  //filter the enddate (documented in preheaders/checkout.php)
288
  $enddate = apply_filters("pmpro_checkout_end_date", $enddate, $morder->user_id, $morder->membership_level, $startdate);
289
 
290
- //get discount code
291
- $morder->getDiscountCode();
292
- if(!empty($morder->discount_code))
293
- {
294
- //update membership level
295
- $morder->getMembershipLevel(true);
296
- $discount_code_id = $morder->discount_code->id;
297
- }
298
- else
299
- $discount_code_id = "";
300
-
301
-
302
-
303
  //custom level to change user to
304
  $custom_level = array(
305
  'user_id' => $morder->user_id,
274
  //set the start date to current_time('mysql') but allow filters (documented in preheaders/checkout.php)
275
  $startdate = apply_filters("pmpro_checkout_start_date", "'" . current_time('mysql') . "'", $morder->user_id, $morder->membership_level);
276
 
277
+ //get discount code
278
+ $morder->getDiscountCode();
279
+ if(!empty($morder->discount_code))
280
+ {
281
+ //update membership level
282
+ $morder->getMembershipLevel(true);
283
+ $discount_code_id = $morder->discount_code->id;
284
+ }
285
+ else
286
+ $discount_code_id = "";
287
+
288
  //fix expiration date
289
  if(!empty($morder->membership_level->expiration_number))
290
  {
298
  //filter the enddate (documented in preheaders/checkout.php)
299
  $enddate = apply_filters("pmpro_checkout_end_date", $enddate, $morder->user_id, $morder->membership_level, $startdate);
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  //custom level to change user to
302
  $custom_level = array(
303
  'user_id' => $morder->user_id,