Version Description
- 2022-01-06 =
- SECURITY: Updated escaping in the pmpro_getLevelAtCheckout and pmpro_checkDiscountCode functions as extra precaution against SQL injections. (Thanks, WPScan)
Download this release
Release Info
Developer | strangerstudios |
Plugin | Paid Memberships Pro |
Version | 2.6.7 |
Comparing to | |
See all releases |
Code changes from version 2.6.6 to 2.6.7
- CHANGELOG.txt +3 -0
- includes/functions.php +12 -12
- paid-memberships-pro.php +2 -2
- readme.txt +4 -1
CHANGELOG.txt
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
== Changelog ==
|
|
|
|
|
|
|
2 |
= 2.6.6 - 2021-11-18 =
|
3 |
* SECURITY: Updated escaping on the discount codes page in the dashboard to prevent XSS attacks. #1867 (Thanks, Erwan from WPScan)
|
4 |
* BUG FIX/ENHANCEMENT: Added code to remove duplicate active rows in the pmpro_memberships_users table after level change. This might have happened e.g. if users were purchasing a level via the WooCommerce Add On multiple times. #1860 (@dlparker1005)
|
1 |
== Changelog ==
|
2 |
+
= 2.6.7 - 2022-01-06 =
|
3 |
+
* SECURITY: Updated escaping in the pmpro_getLevelAtCheckout and pmpro_checkDiscountCode functions as extra precaution against SQL injections. (Thanks, WPScan)
|
4 |
+
|
5 |
= 2.6.6 - 2021-11-18 =
|
6 |
* SECURITY: Updated escaping on the discount codes page in the dashboard to prevent XSS attacks. #1867 (Thanks, Erwan from WPScan)
|
7 |
* BUG FIX/ENHANCEMENT: Added code to remove duplicate active rows in the pmpro_memberships_users table after level change. This might have happened e.g. if users were purchasing a level via the WooCommerce Add On multiple times. #1860 (@dlparker1005)
|
includes/functions.php
CHANGED
@@ -110,7 +110,7 @@ function pmpro_get_slug( $post_id ) {
|
|
110 |
$post_id = intval( $post_id );
|
111 |
|
112 |
if ( ! $pmpro_slugs[ $post_id ] ) {
|
113 |
-
$pmpro_slugs[ $post_id ] = $wpdb->get_var( "SELECT post_name FROM $wpdb->posts WHERE ID = '" . $post_id . "' LIMIT 1" );
|
114 |
}
|
115 |
|
116 |
return $pmpro_slugs[ $post_id ];
|
@@ -1079,7 +1079,7 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
1079 |
if ( $old_levels && $pmpro_deactivate_old_levels ) {
|
1080 |
foreach ( $old_levels as $old_level ) {
|
1081 |
|
1082 |
-
$sql = "UPDATE $wpdb->pmpro_memberships_users SET `status`='$old_level_status', `enddate`='" . current_time( 'mysql' ) . "' WHERE `id`=" . $old_level->subscription_id;
|
1083 |
|
1084 |
if ( ! $wpdb->query( $sql ) ) {
|
1085 |
$pmpro_error = __( 'Error interacting with database', 'paid-memberships-pro' ) . ': ' . ( $wpdb->last_error ? $wpdb->last_error : 'unavailable' );
|
@@ -1093,7 +1093,7 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
1093 |
if ( ! empty( $cancel_level ) ) {
|
1094 |
$pmpro_cancel_previous_subscriptions = true; // don't filter cause we're doing just the one
|
1095 |
|
1096 |
-
$other_order_ids = $wpdb->get_col( "SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . $user_id . "' AND status = 'success' AND membership_id = '" . esc_sql( $cancel_level ) . "' ORDER BY id DESC LIMIT 1" );
|
1097 |
} else {
|
1098 |
$pmpro_cancel_previous_subscriptions = true;
|
1099 |
if ( isset( $_REQUEST['cancel_membership'] ) && $_REQUEST['cancel_membership'] == false ) {
|
@@ -1104,7 +1104,7 @@ function pmpro_changeMembershipLevel( $level, $user_id = null, $old_level_status
|
|
1104 |
$other_order_ids = $wpdb->get_col(
|
1105 |
"SELECT id, IF(subscription_transaction_id = '', CONCAT('UNIQUE_SUB_ID_', id), subscription_transaction_id) as unique_sub_id
|
1106 |
FROM $wpdb->pmpro_membership_orders
|
1107 |
-
WHERE user_id = '" . $user_id . "'
|
1108 |
AND status = 'success'
|
1109 |
GROUP BY unique_sub_id
|
1110 |
ORDER BY id DESC"
|
@@ -1409,7 +1409,7 @@ function pmpro_getMembershipCategories( $level_id ) {
|
|
1409 |
$categories = $wpdb->get_col(
|
1410 |
"SELECT c.category_id
|
1411 |
FROM {$wpdb->pmpro_memberships_categories} AS c
|
1412 |
-
WHERE c.membership_id = '" . $level_id . "'"
|
1413 |
);
|
1414 |
|
1415 |
return $categories;
|
@@ -1788,7 +1788,7 @@ function pmpro_checkDiscountCode( $code, $level_id = null, $return_errors = fals
|
|
1788 |
// have we run out of uses?
|
1789 |
if ( ! $error ) {
|
1790 |
if ( $dbcode->uses > 0 ) {
|
1791 |
-
$used = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . $dbcode->id . "'" );
|
1792 |
if ( $used >= $dbcode->uses ) {
|
1793 |
$error = __( 'This discount code is no longer valid.', 'paid-memberships-pro' );
|
1794 |
}
|
@@ -1806,7 +1806,7 @@ function pmpro_checkDiscountCode( $code, $level_id = null, $return_errors = fals
|
|
1806 |
} else {
|
1807 |
$level_id = intval( $level_id );
|
1808 |
}
|
1809 |
-
$code_level = $wpdb->get_row( "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id WHERE cl.code_id = '" . $dbcode->id . "' AND cl.level_id IN (" . $level_id . ") LIMIT 1" );
|
1810 |
|
1811 |
if ( empty( $code_level ) ) {
|
1812 |
$error = __( 'This discount code does not apply to this membership level.', 'paid-memberships-pro' );
|
@@ -2205,7 +2205,7 @@ function pmpro_getLevel( $level ) {
|
|
2205 |
return $pmpro_levels[ $level_id ];
|
2206 |
} else {
|
2207 |
global $wpdb;
|
2208 |
-
$pmpro_levels[ $level_id ] = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . $level_id . "' LIMIT 1" );
|
2209 |
}
|
2210 |
} else {
|
2211 |
global $wpdb;
|
@@ -2356,7 +2356,7 @@ function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
|
2356 |
|
2357 |
// what level are they purchasing? (discount code passed)
|
2358 |
if ( ! empty( $level_id ) && ! empty( $discount_code ) ) {
|
2359 |
-
$discount_code_id = $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes WHERE code = '" . $discount_code . "' LIMIT 1" );
|
2360 |
|
2361 |
// check code
|
2362 |
global $pmpro_checkout_level_ids; // Set by MMPU.
|
@@ -2366,12 +2366,12 @@ function pmpro_getLevelAtCheckout( $level_id = null, $discount_code = null ) {
|
|
2366 |
$code_check = pmpro_checkDiscountCode( $discount_code, $level_id, true );
|
2367 |
}
|
2368 |
if ( $code_check[0] != false ) {
|
2369 |
-
$sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups, l.confirmation FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . $discount_code . "' AND cl.level_id = '" . $level_id . "' LIMIT 1";
|
2370 |
$pmpro_level = $wpdb->get_row( $sqlQuery );
|
2371 |
|
2372 |
// if the discount code doesn't adjust the level, let's just get the straight level
|
2373 |
if ( empty( $pmpro_level ) ) {
|
2374 |
-
$pmpro_level = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . $level_id . "' LIMIT 1" );
|
2375 |
}
|
2376 |
|
2377 |
// filter adjustments to the level
|
@@ -2532,7 +2532,7 @@ if ( ! function_exists( 'pmpro_getMemberStartdate' ) ) {
|
|
2532 |
if ( ! empty( $level_id ) ) {
|
2533 |
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND membership_id IN(" . esc_sql( $level_id ) . ") AND user_id = '" . $user_id . "' ORDER BY id LIMIT 1";
|
2534 |
} else {
|
2535 |
-
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND user_id = '" . $user_id . "' ORDER BY id LIMIT 1";
|
2536 |
}
|
2537 |
|
2538 |
$startdate = apply_filters( 'pmpro_member_startdate', $wpdb->get_var( $sqlQuery ), $user_id, $level_id );
|
110 |
$post_id = intval( $post_id );
|
111 |
|
112 |
if ( ! $pmpro_slugs[ $post_id ] ) {
|
113 |
+
$pmpro_slugs[ $post_id ] = $wpdb->get_var( "SELECT post_name FROM $wpdb->posts WHERE ID = '" . esc_sql( $post_id ) . "' LIMIT 1" );
|
114 |
}
|
115 |
|
116 |
return $pmpro_slugs[ $post_id ];
|
1079 |
if ( $old_levels && $pmpro_deactivate_old_levels ) {
|
1080 |
foreach ( $old_levels as $old_level ) {
|
1081 |
|
1082 |
+
$sql = "UPDATE $wpdb->pmpro_memberships_users SET `status`='$old_level_status', `enddate`='" . esc_sql( current_time( 'mysql' ) ) . "' WHERE `id`=" . esc_sql( $old_level->subscription_id );
|
1083 |
|
1084 |
if ( ! $wpdb->query( $sql ) ) {
|
1085 |
$pmpro_error = __( 'Error interacting with database', 'paid-memberships-pro' ) . ': ' . ( $wpdb->last_error ? $wpdb->last_error : 'unavailable' );
|
1093 |
if ( ! empty( $cancel_level ) ) {
|
1094 |
$pmpro_cancel_previous_subscriptions = true; // don't filter cause we're doing just the one
|
1095 |
|
1096 |
+
$other_order_ids = $wpdb->get_col( "SELECT id FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . esc_sql( $user_id ) . "' AND status = 'success' AND membership_id = '" . esc_sql( $cancel_level ) . "' ORDER BY id DESC LIMIT 1" );
|
1097 |
} else {
|
1098 |
$pmpro_cancel_previous_subscriptions = true;
|
1099 |
if ( isset( $_REQUEST['cancel_membership'] ) && $_REQUEST['cancel_membership'] == false ) {
|
1104 |
$other_order_ids = $wpdb->get_col(
|
1105 |
"SELECT id, IF(subscription_transaction_id = '', CONCAT('UNIQUE_SUB_ID_', id), subscription_transaction_id) as unique_sub_id
|
1106 |
FROM $wpdb->pmpro_membership_orders
|
1107 |
+
WHERE user_id = '" . esc_sql( $user_id ) . "'
|
1108 |
AND status = 'success'
|
1109 |
GROUP BY unique_sub_id
|
1110 |
ORDER BY id DESC"
|
1409 |
$categories = $wpdb->get_col(
|
1410 |
"SELECT c.category_id
|
1411 |
FROM {$wpdb->pmpro_memberships_categories} AS c
|
1412 |
+
WHERE c.membership_id = '" . esc_sql( $level_id ) . "'"
|
1413 |
);
|
1414 |
|
1415 |
return $categories;
|
1788 |
// have we run out of uses?
|
1789 |
if ( ! $error ) {
|
1790 |
if ( $dbcode->uses > 0 ) {
|
1791 |
+
$used = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . esc_sql( $dbcode->id ) . "'" );
|
1792 |
if ( $used >= $dbcode->uses ) {
|
1793 |
$error = __( 'This discount code is no longer valid.', 'paid-memberships-pro' );
|
1794 |
}
|
1806 |
} else {
|
1807 |
$level_id = intval( $level_id );
|
1808 |
}
|
1809 |
+
$code_level = $wpdb->get_row( "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id WHERE cl.code_id = '" . esc_sql( $dbcode->id ) . "' AND cl.level_id IN (" . esc_sql( $level_id ) . ") LIMIT 1" );
|
1810 |
|
1811 |
if ( empty( $code_level ) ) {
|
1812 |
$error = __( 'This discount code does not apply to this membership level.', 'paid-memberships-pro' );
|
2205 |
return $pmpro_levels[ $level_id ];
|
2206 |
} else {
|
2207 |
global $wpdb;
|
2208 |
+
$pmpro_levels[ $level_id ] = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql( $level_id ) . "' LIMIT 1" );
|
2209 |
}
|
2210 |
} else {
|
2211 |
global $wpdb;
|
2356 |
|
2357 |
// what level are they purchasing? (discount code passed)
|
2358 |
if ( ! empty( $level_id ) && ! empty( $discount_code ) ) {
|
2359 |
+
$discount_code_id = $wpdb->get_var( "SELECT id FROM $wpdb->pmpro_discount_codes WHERE code = '" . esc_sql( $discount_code ) . "' LIMIT 1" );
|
2360 |
|
2361 |
// check code
|
2362 |
global $pmpro_checkout_level_ids; // Set by MMPU.
|
2366 |
$code_check = pmpro_checkDiscountCode( $discount_code, $level_id, true );
|
2367 |
}
|
2368 |
if ( $code_check[0] != false ) {
|
2369 |
+
$sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups, l.confirmation FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . esc_sql( $discount_code ) . "' AND cl.level_id = '" . esc_sql( $level_id ) . "' LIMIT 1";
|
2370 |
$pmpro_level = $wpdb->get_row( $sqlQuery );
|
2371 |
|
2372 |
// if the discount code doesn't adjust the level, let's just get the straight level
|
2373 |
if ( empty( $pmpro_level ) ) {
|
2374 |
+
$pmpro_level = $wpdb->get_row( "SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql( $level_id ) . "' LIMIT 1" );
|
2375 |
}
|
2376 |
|
2377 |
// filter adjustments to the level
|
2532 |
if ( ! empty( $level_id ) ) {
|
2533 |
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND membership_id IN(" . esc_sql( $level_id ) . ") AND user_id = '" . $user_id . "' ORDER BY id LIMIT 1";
|
2534 |
} else {
|
2535 |
+
$sqlQuery = "SELECT UNIX_TIMESTAMP(CONVERT_TZ(startdate, '+00:00', @@global.time_zone)) FROM $wpdb->pmpro_memberships_users WHERE status = 'active' AND user_id = '" . esc_sql( $user_id ) . "' ORDER BY id LIMIT 1";
|
2536 |
}
|
2537 |
|
2538 |
$startdate = apply_filters( 'pmpro_member_startdate', $wpdb->get_var( $sqlQuery ), $user_id, $level_id );
|
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.6.
|
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.6.
|
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.6.7
|
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.6.7' );
|
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
@@ -4,7 +4,7 @@ Tags: memberships, members, subscriptions, ecommerce, user registration, member,
|
|
4 |
Requires at least: 5.2
|
5 |
Tested up to: 5.8.1
|
6 |
Requires PHP: 5.6
|
7 |
-
Stable tag: 2.6.
|
8 |
|
9 |
Get Paid with Paid Memberships Pro: The most complete member management and membership subscriptions plugin for your WordPress site.
|
10 |
|
@@ -156,6 +156,9 @@ Not sure? You can find out by doing a bit a research.
|
|
156 |
9. Membership Account page, display all sections or show specific sections using shortcode attributes.
|
157 |
|
158 |
== Changelog ==
|
|
|
|
|
|
|
159 |
= 2.6.6 - 2021-11-18 =
|
160 |
* SECURITY: Updated escaping on the discount codes page in the dashboard to prevent XSS attacks. #1867 (Thanks, Erwan from WPScan)
|
161 |
* BUG FIX/ENHANCEMENT: Added code to remove duplicate active rows in the pmpro_memberships_users table after level change. This might have happened e.g. if users were purchasing a level via the WooCommerce Add On multiple times. #1860 (@dlparker1005)
|
4 |
Requires at least: 5.2
|
5 |
Tested up to: 5.8.1
|
6 |
Requires PHP: 5.6
|
7 |
+
Stable tag: 2.6.7
|
8 |
|
9 |
Get Paid with Paid Memberships Pro: The most complete member management and membership subscriptions plugin for your WordPress site.
|
10 |
|
156 |
9. Membership Account page, display all sections or show specific sections using shortcode attributes.
|
157 |
|
158 |
== Changelog ==
|
159 |
+
= 2.6.7 - 2022-01-06 =
|
160 |
+
* SECURITY: Updated escaping in the pmpro_getLevelAtCheckout and pmpro_checkDiscountCode functions as extra precaution against SQL injections. (Thanks, WPScan)
|
161 |
+
|
162 |
= 2.6.6 - 2021-11-18 =
|
163 |
* SECURITY: Updated escaping on the discount codes page in the dashboard to prevent XSS attacks. #1867 (Thanks, Erwan from WPScan)
|
164 |
* BUG FIX/ENHANCEMENT: Added code to remove duplicate active rows in the pmpro_memberships_users table after level change. This might have happened e.g. if users were purchasing a level via the WooCommerce Add On multiple times. #1860 (@dlparker1005)
|