Paid Memberships Pro - Version 1.7.14.1

Version Description

  • BUG: Fixed warnings in PayPal Express class that could break redirects at checkout. (Thanks, Adam Warner)
  • BUG: Fixed issue where new users who checked out with Braintree weren't having their customerid's saved, which led to subscription syncronization issues if they checked out again or updated their billing.
  • BUG: Fixed warnings in the membership-billing page.
  • BUG: Fixed false positive "There are JavaScript errors on the page. Please contact the webmaster." errors.
  • BUG: Fixed issue where users on some sites running 1.7.14 could not logout.
  • OTHER: Changed the CSS class of the checkout button generated via [checkout_button] shortcode or pmpro_getCheckoutButton() function from "btn btn-primary" to "pmpro_btn" to match other buttons generated with PMPro.
Download this release

Release Info

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

Code changes from version 1.7.14 to 1.7.14.1

classes/gateways/class.pmprogateway_braintree.php CHANGED
@@ -162,7 +162,7 @@
162
{
163
$customer_id = get_user_meta($user_id, "pmpro_braintree_customerid", true);
164
}
165
-
166
//check for an existing stripe customer
167
if(!empty($customer_id))
168
{
@@ -190,7 +190,7 @@
190
);
191
192
if($response->success)
193
- {
194
$this->customer = $response->customer;
195
}
196
else
@@ -200,12 +200,12 @@
200
return false;
201
}
202
}
203
-
204
return $this->customer;
205
}
206
catch (Exception $e)
207
{
208
- //assume no customer found
209
}
210
}
211
@@ -236,7 +236,7 @@
236
)
237
)
238
));
239
-
240
if($result->success)
241
{
242
$this->customer = $result->customer;
@@ -254,8 +254,17 @@
254
$order->shorterror = $order->error;
255
return false;
256
}
257
-
258
- update_user_meta($user_id, "pmpro_braintree_customerid", $this->customer->id);
259
return $this->customer;
260
}
261
@@ -365,8 +374,8 @@
365
function update(&$order)
366
{
367
//we just have to run getCustomer which will look for the customer and update it with the new token
368
- $this->getCustomer($order);
369
-
370
if(!empty($this->customer) && empty($order->error))
371
{
372
return true;
@@ -418,5 +427,17 @@
418
$order->shorterror = $order->error;
419
return false; //no customer found
420
}
421
- }
422
}
162
{
163
$customer_id = get_user_meta($user_id, "pmpro_braintree_customerid", true);
164
}
165
+
166
//check for an existing stripe customer
167
if(!empty($customer_id))
168
{
190
);
191
192
if($response->success)
193
+ {
194
$this->customer = $response->customer;
195
}
196
else
200
return false;
201
}
202
}
203
+
204
return $this->customer;
205
}
206
catch (Exception $e)
207
{
208
+ //assume no customer found
209
}
210
}
211
236
)
237
)
238
));
239
+
240
if($result->success)
241
{
242
$this->customer = $result->customer;
254
$order->shorterror = $order->error;
255
return false;
256
}
257
+
258
+ //if we have no user id, we need to set the customer id after the user is created
259
+ if(empty($user_id))
260
+ {
261
+ global $pmpro_braintree_customerid;
262
+ $pmpro_braintree_customerid = $this->customer->id;
263
+ add_action('user_register', array('PMProGateway_braintree','user_register'));
264
+ }
265
+ else
266
+ update_user_meta($user_id, "pmpro_braintree_customerid", $this->customer->id);
267
+
268
return $this->customer;
269
}
270
374
function update(&$order)
375
{
376
//we just have to run getCustomer which will look for the customer and update it with the new token
377
+ $this->getCustomer($order, true);
378
+
379
if(!empty($this->customer) && empty($order->error))
380
{
381
return true;
427
$order->shorterror = $order->error;
428
return false; //no customer found
429
}
430
+ }
431
+
432
+ /*
433
+ Save Braintree customer id after the user is registered.
434
+ */
435
+ static function user_register($user_id)
436
+ {
437
+ global $pmpro_braintree_customerid;
438
+ if(!empty($pmpro_braintree_customerid))
439
+ {
440
+ update_user_meta($user_id, 'pmpro_braintree_customerid', $pmpro_braintree_customerid);
441
+ }
442
+ }
443
}
classes/gateways/class.pmprogateway_paypalexpress.php CHANGED
@@ -102,9 +102,8 @@
102
103
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
104
$order->status = "token";
105
- $order->paypal_token = urldecode($this->httpParsedResponseAr['TOKEN']);
106
- $order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
107
-
108
//update order
109
$order->saveOrder();
110
@@ -197,7 +196,7 @@
197
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
198
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['TRANSACTIONID']);
199
$order->status = "success";
200
-
201
//update order
202
$order->saveOrder();
203
@@ -244,7 +243,7 @@
244
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
245
246
//if billing cycles are defined
247
- if($order->TotalBillingCycles)
248
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
249
250
//if a trial period is defined
102
103
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
104
$order->status = "token";
105
+ $order->paypal_token = urldecode($this->httpParsedResponseAr['TOKEN']);
106
+
107
//update order
108
$order->saveOrder();
109
196
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
197
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['TRANSACTIONID']);
198
$order->status = "success";
199
+
200
//update order
201
$order->saveOrder();
202
243
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
244
245
//if billing cycles are defined
246
+ if(!empty($order->TotalBillingCycles))
247
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
248
249
//if a trial period is defined
includes/functions.php CHANGED
@@ -1395,7 +1395,7 @@ function pmpro_getCheckoutButton($level_id, $button_text = NULL, $classes = NULL
1395
$button_text = __("Sign Up for !!name!! Now", "pmpro");
1396
1397
if(empty($classes))
1398
- $classes = "btn btn-primary";
1399
1400
if(empty($level_id))
1401
$r = __("Please specify a level id.", "pmpro");
@@ -1555,14 +1555,21 @@ function pmpro_getClassForField($field)
1555
{
1556
global $pmpro_error_fields, $pmpro_required_billing_fields, $pmpro_required_user_fields;
1557
$classes = array();
1558
-
1559
//error on this field?
1560
- if(in_array($field, $pmpro_error_fields))
1561
{
1562
$classes[] = "pmpro_error";
1563
}
1564
1565
- $required_fields = array_merge(array_keys($pmpro_required_billing_fields), array_keys($pmpro_required_user_fields));
1566
1567
//required?
1568
if(in_array($field, $required_fields))
1395
$button_text = __("Sign Up for !!name!! Now", "pmpro");
1396
1397
if(empty($classes))
1398
+ $classes = "pmpro_btn";
1399
1400
if(empty($level_id))
1401
$r = __("Please specify a level id.", "pmpro");
1555
{
1556
global $pmpro_error_fields, $pmpro_required_billing_fields, $pmpro_required_user_fields;
1557
$classes = array();
1558
+
1559
//error on this field?
1560
+ if(!empty($pmpro_error_fields) && in_array($field, $pmpro_error_fields))
1561
{
1562
$classes[] = "pmpro_error";
1563
}
1564
1565
+ if(is_array($pmpro_required_billing_fields) && is_array($pmpro_required_user_fields))
1566
+ $required_fields = array_merge(array_keys($pmpro_required_billing_fields), array_keys($pmpro_required_user_fields));
1567
+ elseif(is_array($pmpro_required_billing_fields))
1568
+ $required_fields = array_keys($pmpro_required_billing_fields);
1569
+ elseif(is_array($pmpro_required_user_fields))
1570
+ $required_fields = array_keys($pmpro_required_user_fields);
1571
+ else
1572
+ $required_fields = array();
1573
1574
//required?
1575
if(in_array($field, $required_fields))
includes/login.php CHANGED
@@ -148,7 +148,7 @@ add_action('login_init', 'pmpro_login_head');
148
*/
149
function pmpro_redirect_to_logged_in()
150
{
151
- if((pmpro_is_login_page() || is_page("login")) && !empty($_REQUEST['redirect_to']) && is_user_logged_in())
152
{
153
wp_redirect($_REQUEST['redirect_to']);
154
exit;
148
*/
149
function pmpro_redirect_to_logged_in()
150
{
151
+ if((pmpro_is_login_page() || is_page("login")) && !empty($_REQUEST['redirect_to']) && is_user_logged_in() && (empty($_REQUEST['action']) || $_REQUEST['action'] == 'login'))
152
{
153
wp_redirect($_REQUEST['redirect_to']);
154
exit;
pages/checkout.php CHANGED
@@ -8,6 +8,8 @@
8
<form id="pmpro_form" class="pmpro_form" action="<?php if(!empty($_REQUEST['review'])) echo pmpro_url("checkout", "?level=" . $pmpro_level->id); ?>" method="post">
9
10
<input type="hidden" id="level" name="level" value="<?php echo esc_attr($pmpro_level->id) ?>" />
11
<?php if($pmpro_msg)
12
{
13
?>
@@ -774,5 +776,5 @@
774
</script>
775
<script>
776
//add javascriptok hidden field to checkout
777
- jQuery("input[name=submit-checkout]").after("<input type=hidden name=javascriptok value=1 />");
778
</script>
8
<form id="pmpro_form" class="pmpro_form" action="<?php if(!empty($_REQUEST['review'])) echo pmpro_url("checkout", "?level=" . $pmpro_level->id); ?>" method="post">
9
10
<input type="hidden" id="level" name="level" value="<?php echo esc_attr($pmpro_level->id) ?>" />
11
+ <input type="hidden" id="checkjavascript" name="checkjavascript" value="1" />
12
+
13
<?php if($pmpro_msg)
14
{
15
?>
776
</script>
777
<script>
778
//add javascriptok hidden field to checkout
779
+ jQuery("input[name=submit-checkout]").after('<input type="hidden" name="javascriptok" value="1" />');
780
</script>
paid-memberships-pro.php CHANGED
@@ -3,7 +3,7 @@
3
Plugin Name: Paid Memberships Pro
4
Plugin URI: http://www.paidmembershipspro.com
5
Description: Plugin to Handle Memberships
6
- Version: 1.7.14
7
Author: Stranger Studios
8
Author URI: http://www.strangerstudios.com
9
*/
@@ -13,7 +13,7 @@ Author URI: http://www.strangerstudios.com
13
*/
14
15
//version constant
16
- define("PMPRO_VERSION", "1.7.14");
17
18
//if the session has been started yet, start it (ignore if running from command line)
19
if(defined('STDIN') )
3
Plugin Name: Paid Memberships Pro
4
Plugin URI: http://www.paidmembershipspro.com
5
Description: Plugin to Handle Memberships
6
+ Version: 1.7.14.1
7
Author: Stranger Studios
8
Author URI: http://www.strangerstudios.com
9
*/
13
*/
14
15
//version constant
16
+ define("PMPRO_VERSION", "1.7.14.1");
17
18
//if the session has been started yet, start it (ignore if running from command line)
19
if(defined('STDIN') )
preheaders/checkout.php CHANGED
@@ -412,7 +412,7 @@ $pmpro_required_user_fields = apply_filters("pmpro_required_user_fields", $pmpro
412
if ($submit && $pmpro_msgt != "pmpro_error") {
413
414
//make sure javascript is ok
415
- if(apply_filters("pmpro_require_javascript_for_checkout", true) && empty($_REQUEST['javascriptok'])) {
416
pmpro_setMessage(__("There are JavaScript errors on the page. Please contact the webmaster.", "pmpro"), "pmpro_error");
417
}
418
@@ -461,8 +461,8 @@ if ($submit && $pmpro_msgt != "pmpro_error") {
461
}
462
}
463
464
- if (!empty($pmpro_error_fields)) {
465
- pmpro_setMessage(__("Please complete all required fields.", "pmpro"), "pmpro_error");
466
}
467
if (!empty($password) && $password != $password2) {
468
pmpro_setMessage(__("Your passwords do not match. Please try again.", "pmpro"), "pmpro_error");
412
if ($submit && $pmpro_msgt != "pmpro_error") {
413
414
//make sure javascript is ok
415
+ if(apply_filters("pmpro_require_javascript_for_checkout", true) && !empty($_REQUEST['checkjavascript']) && empty($_REQUEST['javascriptok'])) {
416
pmpro_setMessage(__("There are JavaScript errors on the page. Please contact the webmaster.", "pmpro"), "pmpro_error");
417
}
418
461
}
462
}
463
464
+ if (!empty($pmpro_error_fields)) {
465
+ pmpro_setMessage(__("Please complete all required fields.", "pmpro"), "pmpro_error");
466
}
467
if (!empty($password) && $password != $password2) {
468
pmpro_setMessage(__("Your passwords do not match. Please try again.", "pmpro"), "pmpro_error");
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: strangerstudios
3
Tags: memberships, membership, authorize.net, ecommerce, paypal, stripe, braintree, restrict access, restrict content, directory site, payflow
4
Requires at least: 3.5
5
Tested up to: 4.0
6
- Stable tag: 1.7.14
7
8
The easiest way to GET PAID with your WordPress site. Flexible content control by Membership Level, Reports, Affiliates and Discounts
9
@@ -102,6 +102,14 @@ Not sure? You can find out by doing a bit a research.
102
4. Offer Membership Discounts with specific price rules (restricted by level, unique pricing for each level, # of uses, expiration date.)
103
104
== Changelog ==
105
= 1.7.14 =
106
* BUG: Fixed bug where level cost would sometimes have incorrect pluralization of months/weeks/etc. (Thanks, Kevin Ackerman)
107
* BUG/ENHANCEMENT: Now checking the child and parent theme for email_header.html and email_footer.html files to use for emails. The child theme is checked first.
3
Tags: memberships, membership, authorize.net, ecommerce, paypal, stripe, braintree, restrict access, restrict content, directory site, payflow
4
Requires at least: 3.5
5
Tested up to: 4.0
6
+ Stable tag: 1.7.14.1
7
8
The easiest way to GET PAID with your WordPress site. Flexible content control by Membership Level, Reports, Affiliates and Discounts
9
102
4. Offer Membership Discounts with specific price rules (restricted by level, unique pricing for each level, # of uses, expiration date.)
103
104
== Changelog ==
105
+ = 1.7.14.1 =
106
+ * BUG: Fixed warnings in PayPal Express class that could break redirects at checkout. (Thanks, Adam Warner)
107
+ * BUG: Fixed issue where new users who checked out with Braintree weren't having their customerid's saved, which led to subscription syncronization issues if they checked out again or updated their billing.
108
+ * BUG: Fixed warnings in the membership-billing page.
109
+ * BUG: Fixed false positive "There are JavaScript errors on the page. Please contact the webmaster." errors.
110
+ * BUG: Fixed issue where users on some sites running 1.7.14 could not logout.
111
+ * OTHER: Changed the CSS class of the checkout button generated via [checkout_button] shortcode or pmpro_getCheckoutButton() function from "btn btn-primary" to "pmpro_btn" to match other buttons generated with PMPro.
112
+
113
= 1.7.14 =
114
* BUG: Fixed bug where level cost would sometimes have incorrect pluralization of months/weeks/etc. (Thanks, Kevin Ackerman)
115
* BUG/ENHANCEMENT: Now checking the child and parent theme for email_header.html and email_footer.html files to use for emails. The child theme is checked first.
services/getfile.php CHANGED
@@ -1,12 +1,23 @@
1
<?php
2
global $isapage;
3
- $isapage = true;
4
-
5
//in case the file is loaded directly
6
if(!function_exists("get_userdata"))
7
{
8
define('WP_USE_THEMES', false);
9
require_once(dirname(__FILE__) . '/../../../../wp-load.php');
10
}
11
12
require_once(dirname(__FILE__) . '/../classes/class.mimetype.php');
@@ -17,6 +28,13 @@
17
if($uri[0] == "/")
18
$uri = substr($uri, 1, strlen($uri) - 1);
19
20
//if WP is installed in a subdirectory, that directory(s) will be in both the PATH and URI
21
$home_url_parts = explode("/", str_replace("//", "", home_url()));
22
if(count($home_url_parts) > 1)
@@ -52,6 +70,8 @@
52
{
53
if(!pmpro_has_membership_access($file_post_parent))
54
{
55
//nope
56
header('HTTP/1.1 503 Service Unavailable', true, 503);
57
echo "HTTP/1.1 503 Service Unavailable";
@@ -67,8 +87,40 @@
67
//in case we want to do something else with the file
68
do_action("pmpro_getfile_before_readfile", $filename, $file_mimetype);
69
70
- //show the file
71
header("Content-type: " . $file_mimetype);
72
readfile($filename);
73
- exit;
74
- ?>
1
<?php
2
global $isapage;
3
+ $isapage = true;
4
+
5
//in case the file is loaded directly
6
if(!function_exists("get_userdata"))
7
{
8
define('WP_USE_THEMES', false);
9
require_once(dirname(__FILE__) . '/../../../../wp-load.php');
10
+ }
11
+
12
+ //this script must be enabled to run
13
+ if(!defined('PMPRO_GETFILE_ENABLED') || !PMPRO_GETFILE_ENABLED)
14
+ die("The getfile script is not enabled.");
15
+
16
+ //prevent loops when redirecting to .php files
17
+ if(!empty($_REQUEST['noloop']))
18
+ {
19
+ status_header( 500 );
20
+ die("This file cannot be loaded through the get file script.");
21
}
22
23
require_once(dirname(__FILE__) . '/../classes/class.mimetype.php');
28
if($uri[0] == "/")
29
$uri = substr($uri, 1, strlen($uri) - 1);
30
31
+ /*
32
+ Remove ../-like strings from the URI.
33
+ Actually removes any combination of two or more ., /, and \.
34
+ This will prevent traversal attacks and loading hidden files.
35
+ */
36
+ $uri = preg_replace("/[\.\/\\\\]{2,}/", "", $uri);
37
+
38
//if WP is installed in a subdirectory, that directory(s) will be in both the PATH and URI
39
$home_url_parts = explode("/", str_replace("//", "", home_url()));
40
if(count($home_url_parts) > 1)
70
{
71
if(!pmpro_has_membership_access($file_post_parent))
72
{
73
+ do_action("pmpro_getfile_before_error", $filename, $file_post_parent);
74
+
75
//nope
76
header('HTTP/1.1 503 Service Unavailable', true, 503);
77
echo "HTTP/1.1 503 Service Unavailable";
87
//in case we want to do something else with the file
88
do_action("pmpro_getfile_before_readfile", $filename, $file_mimetype);
89
90
+ //if file is not found, die
91
+ if(!file_exists($filename))
92
+ {
93
+ status_header( 404 );
94
+ nocache_headers();
95
+ die("File not found.");
96
+ }
97
+
98
+ //if blacklistsed file type, redirect to it instead
99
+ $basename = basename($filename);
100
+ $parts = explode('.', $basename);
101
+ $ext = strtolower($parts[count($parts)-1]);
102
+
103
+ //build blacklist and allow for filtering
104
+ $blacklist = array("inc", "php", "php3", "php4", "php5", "phps", "phtml");
105
+ $blacklist = apply_filters("pmpro_getfile_extension_blacklist", $blacklist);
106
+
107
+ //check
108
+ if(in_array($ext, $blacklist))
109
+ {
110
+ //add a noloop param to avoid infinite loops
111
+ $uri = add_query_arg("noloop", 1, $uri);
112
+
113
+ //guess scheme and add host back to uri
114
+ if(is_ssl())
115
+ $uri = "https://" . $_SERVER['HTTP_HOST'] . "/" . $uri;
116
+ else
117
+ $uri = "http://" . $_SERVER['HTTP_HOST'] . "/" . $uri;
118
+
119
+ wp_redirect($uri);
120
+ exit;
121
+ }
122
+
123
+ //okay show the file
124
header("Content-type: " . $file_mimetype);
125
readfile($filename);
126
+ exit;