Version Description
- Added a new action hook 'swpm_validate_login_hash_mismatch'
- Ability to manually add a transaction record in the Payments menu of the plugin
- Added a new feature to hide the registration from to logged-in members. The new option is available in the Advanced settings menu.
Download this release
Release Info
Developer | mra13 |
Plugin | Simple Membership |
Version | 3.9.8 |
Comparing to | |
See all releases |
Code changes from version 3.9.7 to 3.9.8
- classes/admin-includes/class.swpm-payments-admin-menu.php +15 -12
- classes/class.swpm-auth.php +1 -0
- classes/class.swpm-cronjob.php +4 -1
- classes/class.swpm-front-registration.php +16 -2
- classes/class.swpm-members.php +16 -12
- classes/class.swpm-settings.php +13 -0
- classes/class.swpm-transactions.php +5 -0
- ipn/swpm_handle_pp_ipn.php +40 -13
- ipn/swpm_handle_subsc_ipn.php +26 -1
- readme.txt +6 -1
- simple-wp-membership.php +2 -2
- views/payments/admin_add_edit_transaction_manually.php +168 -0
- views/payments/admin_all_payment_transactions.php +5 -1
- views/payments/admin_create_payment_buttons.php +0 -1
classes/admin-includes/class.swpm-payments-admin-menu.php
CHANGED
@@ -3,14 +3,14 @@
|
|
3 |
class SwpmPaymentsAdminMenu {
|
4 |
|
5 |
function __construct() {
|
6 |
-
|
7 |
}
|
8 |
|
9 |
function handle_main_payments_admin_menu() {
|
10 |
do_action('swpm_payments_menu_start');
|
11 |
-
|
12 |
//Check current_user_can() or die.
|
13 |
-
SwpmMiscUtils::check_user_permission_and_is_admin('Main Payments Admin Menu');
|
14 |
|
15 |
$output = '';
|
16 |
$tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : '';
|
@@ -31,7 +31,7 @@ class SwpmPaymentsAdminMenu {
|
|
31 |
if ($tab == 'edit_button') {//Only show the "edit button" tab when a button is being edited.
|
32 |
echo '<a class="nav-tab nav-tab-active" href="#">Edit Button</a>';
|
33 |
}
|
34 |
-
|
35 |
//Trigger hooks that allows an extension to add extra nav tabs in the payments menu.
|
36 |
do_action ('swpm_payments_menu_nav_tabs', $selected);
|
37 |
|
@@ -41,15 +41,15 @@ class SwpmPaymentsAdminMenu {
|
|
41 |
<a class="nav-tab <?php echo ($selected == $menu_action) ? 'nav-tab-active' : ''; ?>" href="admin.php?page=simple_wp_membership_payments&tab=<?php echo $menu_action; ?>" ><?php SwpmUtils::e($title); ?></a>
|
42 |
<?php
|
43 |
}
|
44 |
-
|
45 |
?>
|
46 |
</h2>
|
47 |
<!-- end nav menu tabs -->
|
48 |
|
49 |
<?php
|
50 |
-
|
51 |
do_action('swpm_payments_menu_after_nav_tabs');
|
52 |
-
|
53 |
//Allows an addon to completely override the body section of the payments admin menu for a given action.
|
54 |
$output = apply_filters('swpm_payments_menu_body_override', '', $tab);
|
55 |
if (!empty($output)) {
|
@@ -57,12 +57,12 @@ class SwpmPaymentsAdminMenu {
|
|
57 |
echo $output;
|
58 |
echo '</div>';//<!-- end of wrap -->
|
59 |
return;
|
60 |
-
}
|
61 |
-
|
62 |
echo '<div id="poststuff"><div id="post-body">';
|
63 |
|
64 |
//TODO - move most of the following includes to functions of this class instead.
|
65 |
-
|
66 |
//Switch case for the various different tabs handled by the core plugin.
|
67 |
switch ($tab) {
|
68 |
case 'payment_buttons':
|
@@ -77,16 +77,19 @@ class SwpmPaymentsAdminMenu {
|
|
77 |
case 'all_txns':
|
78 |
include_once(SIMPLE_WP_MEMBERSHIP_PATH . '/views/payments/admin_all_payment_transactions.php');
|
79 |
break;
|
|
|
|
|
|
|
|
|
80 |
default:
|
81 |
include_once(SIMPLE_WP_MEMBERSHIP_PATH . '/views/payments/admin_all_payment_transactions.php');
|
82 |
break;
|
83 |
}
|
84 |
|
85 |
echo '</div></div>'; //<!-- end of post-body -->
|
86 |
-
|
87 |
echo '</div>'; //<!-- end of .wrap -->
|
88 |
}
|
89 |
|
90 |
}
|
91 |
|
92 |
-
|
3 |
class SwpmPaymentsAdminMenu {
|
4 |
|
5 |
function __construct() {
|
6 |
+
|
7 |
}
|
8 |
|
9 |
function handle_main_payments_admin_menu() {
|
10 |
do_action('swpm_payments_menu_start');
|
11 |
+
|
12 |
//Check current_user_can() or die.
|
13 |
+
SwpmMiscUtils::check_user_permission_and_is_admin('Main Payments Admin Menu');
|
14 |
|
15 |
$output = '';
|
16 |
$tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : '';
|
31 |
if ($tab == 'edit_button') {//Only show the "edit button" tab when a button is being edited.
|
32 |
echo '<a class="nav-tab nav-tab-active" href="#">Edit Button</a>';
|
33 |
}
|
34 |
+
|
35 |
//Trigger hooks that allows an extension to add extra nav tabs in the payments menu.
|
36 |
do_action ('swpm_payments_menu_nav_tabs', $selected);
|
37 |
|
41 |
<a class="nav-tab <?php echo ($selected == $menu_action) ? 'nav-tab-active' : ''; ?>" href="admin.php?page=simple_wp_membership_payments&tab=<?php echo $menu_action; ?>" ><?php SwpmUtils::e($title); ?></a>
|
42 |
<?php
|
43 |
}
|
44 |
+
|
45 |
?>
|
46 |
</h2>
|
47 |
<!-- end nav menu tabs -->
|
48 |
|
49 |
<?php
|
50 |
+
|
51 |
do_action('swpm_payments_menu_after_nav_tabs');
|
52 |
+
|
53 |
//Allows an addon to completely override the body section of the payments admin menu for a given action.
|
54 |
$output = apply_filters('swpm_payments_menu_body_override', '', $tab);
|
55 |
if (!empty($output)) {
|
57 |
echo $output;
|
58 |
echo '</div>';//<!-- end of wrap -->
|
59 |
return;
|
60 |
+
}
|
61 |
+
|
62 |
echo '<div id="poststuff"><div id="post-body">';
|
63 |
|
64 |
//TODO - move most of the following includes to functions of this class instead.
|
65 |
+
|
66 |
//Switch case for the various different tabs handled by the core plugin.
|
67 |
switch ($tab) {
|
68 |
case 'payment_buttons':
|
77 |
case 'all_txns':
|
78 |
include_once(SIMPLE_WP_MEMBERSHIP_PATH . '/views/payments/admin_all_payment_transactions.php');
|
79 |
break;
|
80 |
+
case 'add_new_txn':
|
81 |
+
include_once(SIMPLE_WP_MEMBERSHIP_PATH . '/views/payments/admin_add_edit_transaction_manually.php');
|
82 |
+
swpm_handle_add_new_txn_manually();
|
83 |
+
break;
|
84 |
default:
|
85 |
include_once(SIMPLE_WP_MEMBERSHIP_PATH . '/views/payments/admin_all_payment_transactions.php');
|
86 |
break;
|
87 |
}
|
88 |
|
89 |
echo '</div></div>'; //<!-- end of post-body -->
|
90 |
+
|
91 |
echo '</div>'; //<!-- end of .wrap -->
|
92 |
}
|
93 |
|
94 |
}
|
95 |
|
|
classes/class.swpm-auth.php
CHANGED
@@ -317,6 +317,7 @@ class SwpmAuth {
|
|
317 |
if ( $hmac != $hash ) {
|
318 |
$this->lastStatusMsg = SwpmUtils::_( 'Please login again.' );
|
319 |
SwpmLog::log_auth_debug( 'validate() - Bad Hash', true );
|
|
|
320 |
wp_logout(); //Force logout of WP user session to clear the bad hash.
|
321 |
return false;
|
322 |
}
|
317 |
if ( $hmac != $hash ) {
|
318 |
$this->lastStatusMsg = SwpmUtils::_( 'Please login again.' );
|
319 |
SwpmLog::log_auth_debug( 'validate() - Bad Hash', true );
|
320 |
+
do_action('swpm_validate_login_hash_mismatch');
|
321 |
wp_logout(); //Force logout of WP user session to clear the bad hash.
|
322 |
return false;
|
323 |
}
|
classes/class.swpm-cronjob.php
CHANGED
@@ -17,7 +17,10 @@ class SwpmCronJob {
|
|
17 |
global $wpdb;
|
18 |
for ($counter = 0;; $counter += 100) {
|
19 |
$query = $wpdb->prepare("SELECT member_id, membership_level, subscription_starts, account_state
|
20 |
-
FROM {$wpdb->prefix}swpm_members_tbl
|
|
|
|
|
|
|
21 |
$results = $wpdb->get_results($query);
|
22 |
if (empty($results)) {
|
23 |
break;
|
17 |
global $wpdb;
|
18 |
for ($counter = 0;; $counter += 100) {
|
19 |
$query = $wpdb->prepare("SELECT member_id, membership_level, subscription_starts, account_state
|
20 |
+
FROM {$wpdb->prefix}swpm_members_tbl
|
21 |
+
WHERE membership_level NOT IN ( SELECT id FROM {$wpdb->prefix}swpm_membership_tbl
|
22 |
+
WHERE subscription_period = '' OR subscription_period = '0' )
|
23 |
+
LIMIT %d, 100", $counter);
|
24 |
$results = $wpdb->get_results($query);
|
25 |
if (empty($results)) {
|
26 |
break;
|
classes/class.swpm-front-registration.php
CHANGED
@@ -14,6 +14,21 @@ class SwpmFrontRegistration extends SwpmRegistration {
|
|
14 |
|
15 |
public function regigstration_ui( $level ) {
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
//Trigger the filter to override the registration form (the form builder addon uses this filter)
|
18 |
$form = apply_filters( 'swpm_registration_form_override', '', $level ); //The $level value could be empty also so the code handling the filter need to check for it.
|
19 |
if ( ! empty( $form ) ) {
|
@@ -21,8 +36,7 @@ class SwpmFrontRegistration extends SwpmRegistration {
|
|
21 |
return $form;
|
22 |
}
|
23 |
|
24 |
-
$
|
25 |
-
$joinuspage_url = $settings_configs->get_value( 'join-us-page-url' );
|
26 |
$membership_level = '';
|
27 |
global $wpdb;
|
28 |
|
14 |
|
15 |
public function regigstration_ui( $level ) {
|
16 |
|
17 |
+
$settings_configs = SwpmSettings::get_instance();
|
18 |
+
|
19 |
+
//Check if the hide rego from logged-in users feature is enabled before rendering the registration form.
|
20 |
+
$hide_rego_to_logged_users = $settings_configs->get_value( 'hide-rego-form-to-logged-users' );
|
21 |
+
if ( ! empty( $hide_rego_to_logged_users ) ){
|
22 |
+
//Hide registration form to logged-in users feature is enabled. Check if the form should be hidden.
|
23 |
+
if ( SwpmMemberUtils::is_member_logged_in() ) {
|
24 |
+
|
25 |
+
$rego_hidden_to_logged_users_msg = '<div class="registration_hidden_to_logged_users_msg">';
|
26 |
+
$rego_hidden_to_logged_users_msg .= SwpmUtils::_( "You are already logged in. You don't need to create another account. So the registration form is hidden." );
|
27 |
+
$rego_hidden_to_logged_users_msg .= '</div>';
|
28 |
+
return $rego_hidden_to_logged_users_msg;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
//Trigger the filter to override the registration form (the form builder addon uses this filter)
|
33 |
$form = apply_filters( 'swpm_registration_form_override', '', $level ); //The $level value could be empty also so the code handling the filter need to check for it.
|
34 |
if ( ! empty( $form ) ) {
|
36 |
return $form;
|
37 |
}
|
38 |
|
39 |
+
$joinuspage_url = $settings_configs->get_value( 'join-us-page-url' );
|
|
|
40 |
$membership_level = '';
|
41 |
global $wpdb;
|
42 |
|
classes/class.swpm-members.php
CHANGED
@@ -32,15 +32,15 @@ class SwpmMembers extends WP_List_Table {
|
|
32 |
|
33 |
function get_sortable_columns() {
|
34 |
return array(
|
35 |
-
'member_id'
|
36 |
-
'user_name'
|
37 |
-
'first_name'
|
38 |
-
'last_name'
|
39 |
-
'email'
|
40 |
-
'alias'
|
41 |
-
|
42 |
-
'account_state'
|
43 |
-
'last_accessed'
|
44 |
);
|
45 |
}
|
46 |
|
@@ -94,7 +94,11 @@ class SwpmMembers extends WP_List_Table {
|
|
94 |
|
95 |
$this->process_bulk_action();
|
96 |
|
97 |
-
$
|
|
|
|
|
|
|
|
|
98 |
$query .= ' LEFT JOIN ' . $wpdb->prefix . 'swpm_membership_tbl';
|
99 |
$query .= ' ON ( membership_level = id ) ';
|
100 |
|
@@ -163,7 +167,7 @@ class SwpmMembers extends WP_List_Table {
|
|
163 |
$query .= ' ORDER BY ' . $orderby . ' ' . $order;
|
164 |
|
165 |
//Execute the query
|
166 |
-
$totalitems = $wpdb->
|
167 |
//Pagination setup
|
168 |
$perpage = apply_filters( 'swpm_members_menu_items_per_page', 50 );
|
169 |
$paged = filter_input( INPUT_GET, 'paged' );
|
@@ -188,7 +192,7 @@ class SwpmMembers extends WP_List_Table {
|
|
188 |
$sortable = $this->get_sortable_columns();
|
189 |
|
190 |
$this->_column_headers = array( $columns, $hidden, $sortable );
|
191 |
-
$this->items = $wpdb->get_results( $query, ARRAY_A );
|
192 |
}
|
193 |
|
194 |
function get_user_count_by_account_state() {
|
32 |
|
33 |
function get_sortable_columns() {
|
34 |
return array(
|
35 |
+
'member_id' => array( 'member_id', true ), //True means already sorted
|
36 |
+
'user_name' => array( 'user_name', false ),
|
37 |
+
'first_name' => array( 'first_name', false ),
|
38 |
+
'last_name' => array( 'last_name', false ),
|
39 |
+
'email' => array( 'email', false ),
|
40 |
+
'alias' => array( 'alias', false ),
|
41 |
+
'subscription_starts' => array( 'subscription_starts', false ),
|
42 |
+
'account_state' => array( 'account_state', false ),
|
43 |
+
'last_accessed' => array( 'last_accessed', false ),
|
44 |
);
|
45 |
}
|
46 |
|
94 |
|
95 |
$this->process_bulk_action();
|
96 |
|
97 |
+
$records_query_head = 'SELECT member_id,user_name,first_name,last_name,email,alias,subscription_starts,account_state,last_accessed';
|
98 |
+
$count_query_head = 'SELECT COUNT(member_id)';
|
99 |
+
|
100 |
+
$query = ' ';
|
101 |
+
$query .= ' FROM ' . $wpdb->prefix . 'swpm_members_tbl';
|
102 |
$query .= ' LEFT JOIN ' . $wpdb->prefix . 'swpm_membership_tbl';
|
103 |
$query .= ' ON ( membership_level = id ) ';
|
104 |
|
167 |
$query .= ' ORDER BY ' . $orderby . ' ' . $order;
|
168 |
|
169 |
//Execute the query
|
170 |
+
$totalitems = $wpdb->get_var( $count_query_head . $query );
|
171 |
//Pagination setup
|
172 |
$perpage = apply_filters( 'swpm_members_menu_items_per_page', 50 );
|
173 |
$paged = filter_input( INPUT_GET, 'paged' );
|
192 |
$sortable = $this->get_sortable_columns();
|
193 |
|
194 |
$this->_column_headers = array( $columns, $hidden, $sortable );
|
195 |
+
$this->items = $wpdb->get_results( $records_query_head . $query, ARRAY_A );
|
196 |
}
|
197 |
|
198 |
function get_user_count_by_account_state() {
|
classes/class.swpm-settings.php
CHANGED
@@ -616,6 +616,18 @@ class SwpmSettings {
|
|
616 |
)
|
617 |
);
|
618 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
619 |
add_settings_field(
|
620 |
'after-logout-redirection-url',
|
621 |
SwpmUtils::_( 'After Logout Redirect URL' ),
|
@@ -1127,6 +1139,7 @@ class SwpmSettings {
|
|
1127 |
$output['after-logout-redirection-url'] = esc_url( $input['after-logout-redirection-url'] );
|
1128 |
$output['force-strong-passwords'] = isset( $input['force-strong-passwords'] ) ? esc_attr( $input['force-strong-passwords'] ) : '';
|
1129 |
$output['auto-login-after-rego'] = isset( $input['auto-login-after-rego'] ) ? esc_attr( $input['auto-login-after-rego'] ) : '';
|
|
|
1130 |
$output['force-wp-user-sync'] = isset( $input['force-wp-user-sync'] ) ? esc_attr( $input['force-wp-user-sync'] ) : '';
|
1131 |
$output['payment-notification-forward-url'] = esc_url( $input['payment-notification-forward-url'] );
|
1132 |
|
616 |
)
|
617 |
);
|
618 |
|
619 |
+
add_settings_field(
|
620 |
+
'hide-rego-form-to-logged-users',
|
621 |
+
SwpmUtils::_( 'Hide Registration Form to Logged Users' ),
|
622 |
+
array( &$this, 'checkbox_callback' ),
|
623 |
+
'simple_wp_membership_settings',
|
624 |
+
'advanced-settings',
|
625 |
+
array(
|
626 |
+
'item' => 'hide-rego-form-to-logged-users',
|
627 |
+
'message' => SwpmUtils::_( 'Use this option if you want to hide the registration form to the logged-in members. If logged-in members visit the registration page, they will see a message instead of the registration form.' ),
|
628 |
+
)
|
629 |
+
);
|
630 |
+
|
631 |
add_settings_field(
|
632 |
'after-logout-redirection-url',
|
633 |
SwpmUtils::_( 'After Logout Redirect URL' ),
|
1139 |
$output['after-logout-redirection-url'] = esc_url( $input['after-logout-redirection-url'] );
|
1140 |
$output['force-strong-passwords'] = isset( $input['force-strong-passwords'] ) ? esc_attr( $input['force-strong-passwords'] ) : '';
|
1141 |
$output['auto-login-after-rego'] = isset( $input['auto-login-after-rego'] ) ? esc_attr( $input['auto-login-after-rego'] ) : '';
|
1142 |
+
$output['hide-rego-form-to-logged-users'] = isset( $input['hide-rego-form-to-logged-users'] ) ? esc_attr( $input['hide-rego-form-to-logged-users'] ) : '';
|
1143 |
$output['force-wp-user-sync'] = isset( $input['force-wp-user-sync'] ) ? esc_attr( $input['force-wp-user-sync'] ) : '';
|
1144 |
$output['payment-notification-forward-url'] = esc_url( $input['payment-notification-forward-url'] );
|
1145 |
|
classes/class.swpm-transactions.php
CHANGED
@@ -79,4 +79,9 @@ class SwpmTransactions {
|
|
79 |
return $customvariables;
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
79 |
return $customvariables;
|
80 |
}
|
81 |
|
82 |
+
static function get_transaction_row_by_subscr_id ($subscr_id) {
|
83 |
+
global $wpdb;
|
84 |
+
$query_db = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}swpm_payments_tbl WHERE subscr_id = %s", $subscr_id ), OBJECT );
|
85 |
+
return $query_db;
|
86 |
+
}
|
87 |
}
|
ipn/swpm_handle_pp_ipn.php
CHANGED
@@ -145,25 +145,52 @@ class swpm_paypal_ipn_handler { // phpcs:ignore
|
|
145 |
$expected_amount = round( $expected_amount, 2 );
|
146 |
$expected_amount = apply_filters( 'swpm_payment_amount_filter', $expected_amount, $button_id );
|
147 |
$received_amount = $cart_item_data_total;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
} elseif ( $button_type == 'pp_subscription' ) {// This is a PayPal subscription type button
|
149 |
-
|
150 |
-
|
151 |
$trial_billing_amount = get_post_meta( $button_id, 'trial_billing_amount', true );
|
152 |
-
$billing_amount
|
153 |
-
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
} else {
|
156 |
$this->debug_log( 'Error! Unexpected button type: ' . $button_type, false );
|
157 |
return false;
|
158 |
}
|
159 |
-
|
160 |
-
if ( $received_amount < $expected_amount ) {
|
161 |
-
// Error! amount received is less than expected. This is invalid.
|
162 |
-
$this->debug_log( 'Expected amount: ' . $expected_amount, true );
|
163 |
-
$this->debug_log( 'Received amount: ' . $received_amount, true );
|
164 |
-
$this->debug_log( 'Price check failed. Amount received is less than the amount expected. This payment will not be processed.', false );
|
165 |
-
return false;
|
166 |
-
}
|
167 |
}
|
168 |
|
169 |
// *** Handle Membership Payment ***
|
145 |
$expected_amount = round( $expected_amount, 2 );
|
146 |
$expected_amount = apply_filters( 'swpm_payment_amount_filter', $expected_amount, $button_id );
|
147 |
$received_amount = $cart_item_data_total;
|
148 |
+
|
149 |
+
if ( $received_amount < $expected_amount ) {
|
150 |
+
// Error! amount received is less than expected. This is invalid.
|
151 |
+
$this->debug_log( 'Expected amount: ' . $expected_amount, true );
|
152 |
+
$this->debug_log( 'Received amount: ' . $received_amount, true );
|
153 |
+
$this->debug_log( 'Price check failed. Amount received is less than the amount expected. This payment will not be processed.', false );
|
154 |
+
return false;
|
155 |
+
}
|
156 |
+
|
157 |
} elseif ( $button_type == 'pp_subscription' ) {// This is a PayPal subscription type button
|
158 |
+
//This is a "subscr_payment" type payment notification. The "subscr_signup" type gets handled before.
|
159 |
+
$trial_billing_cycle = get_post_meta( $button_id, 'trial_billing_cycle', true );
|
160 |
$trial_billing_amount = get_post_meta( $button_id, 'trial_billing_amount', true );
|
161 |
+
$billing_amount = get_post_meta( $button_id, 'billing_amount', true );
|
162 |
+
|
163 |
+
if ( empty( $trial_billing_cycle ) ){
|
164 |
+
//No trial billing. Check main billing amount. Only need to check "mc_gross" which should cointain the "amount3" value.
|
165 |
+
$this->debug_log( 'Trial billing is not enabled for this button.', true );
|
166 |
+
$expected_amount = round( $billing_amount, 2 );
|
167 |
+
|
168 |
+
} else {
|
169 |
+
//Trial billing is specified for this button
|
170 |
+
$this->debug_log( 'Trial billing is enabled for this button.', true );
|
171 |
+
if ( swpm_is_paypal_recurring_payment($this->ipn_data) ){
|
172 |
+
//This is a recurring payment of a subscription.
|
173 |
+
$expected_amount = round( $billing_amount, 2 );
|
174 |
+
} else {
|
175 |
+
//This is a trial payment of a subscription
|
176 |
+
$expected_amount = round( $trial_billing_amount, 2 );
|
177 |
+
}
|
178 |
+
|
179 |
+
}
|
180 |
+
$received_amount = $cart_item_data_total;
|
181 |
+
|
182 |
+
if ( $received_amount < $expected_amount ) {
|
183 |
+
// Error! amount received is less than expected. This is invalid.
|
184 |
+
$this->debug_log( 'Expected amount: ' . $expected_amount, true );
|
185 |
+
$this->debug_log( 'Received amount: ' . $received_amount, true );
|
186 |
+
$this->debug_log( 'Price check failed. Amount received is less than the amount expected. This payment will not be processed.', false );
|
187 |
+
return false;
|
188 |
+
}
|
189 |
+
|
190 |
} else {
|
191 |
$this->debug_log( 'Error! Unexpected button type: ' . $button_type, false );
|
192 |
return false;
|
193 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
}
|
195 |
|
196 |
// *** Handle Membership Payment ***
|
ipn/swpm_handle_subsc_ipn.php
CHANGED
@@ -291,7 +291,7 @@ function swpm_update_member_subscription_start_date_if_applicable( $ipn_data ) {
|
|
291 |
swpm_debug_log_subsc( 'Updating subscription start date if applicable for this subscription payment. Subscriber ID: ' . $subscr_id . ' Email: ' . $email, true );
|
292 |
|
293 |
// We can also query using the email address or SWPM ID (if present in custom var).
|
294 |
-
|
295 |
//Try to find the profile with the given subscr_id. It will exact match subscr_id or match subscr_id|123
|
296 |
$query_db = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}swpm_members_tbl WHERE subscr_id = %s OR subscr_id LIKE %s", $subscr_id, $subscr_id.'|%' ), OBJECT );
|
297 |
if ( $query_db ) {
|
@@ -322,6 +322,31 @@ function swpm_update_member_subscription_start_date_if_applicable( $ipn_data ) {
|
|
322 |
}
|
323 |
}
|
324 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
function swpm_debug_log_subsc( $message, $success, $end = false ) {
|
326 |
$settings = SwpmSettings::get_instance();
|
327 |
$debug_enabled = $settings->get_value( 'enable-debug' );
|
291 |
swpm_debug_log_subsc( 'Updating subscription start date if applicable for this subscription payment. Subscriber ID: ' . $subscr_id . ' Email: ' . $email, true );
|
292 |
|
293 |
// We can also query using the email address or SWPM ID (if present in custom var).
|
294 |
+
|
295 |
//Try to find the profile with the given subscr_id. It will exact match subscr_id or match subscr_id|123
|
296 |
$query_db = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}swpm_members_tbl WHERE subscr_id = %s OR subscr_id LIKE %s", $subscr_id, $subscr_id.'|%' ), OBJECT );
|
297 |
if ( $query_db ) {
|
322 |
}
|
323 |
}
|
324 |
|
325 |
+
function swpm_is_paypal_recurring_payment($payment_data){
|
326 |
+
$recurring_payment = false;
|
327 |
+
$transaction_type = $payment_data['txn_type'];
|
328 |
+
|
329 |
+
if ($transaction_type == "recurring_payment") {
|
330 |
+
$recurring_payment = true;
|
331 |
+
|
332 |
+
} else if ($transaction_type == "subscr_payment") {
|
333 |
+
$item_number = $payment_data['item_number'];
|
334 |
+
$subscr_id = $payment_data['subscr_id'];
|
335 |
+
swpm_debug_log_subsc('Is recurring payment check debug data: ' . $item_number . "|" . $subscr_id, true);
|
336 |
+
|
337 |
+
$result = SwpmTransactions::get_transaction_row_by_subscr_id($subscr_id);
|
338 |
+
if (isset($result)) {
|
339 |
+
swpm_debug_log_subsc('This subscr_id exists in the transactions db. Recurring payment check flag value is true.', true);
|
340 |
+
$recurring_payment = true;
|
341 |
+
return $recurring_payment;
|
342 |
+
}
|
343 |
+
}
|
344 |
+
if ($recurring_payment) {
|
345 |
+
swpm_debug_log_subsc('Recurring payment check flag value is true.', true);
|
346 |
+
}
|
347 |
+
return $recurring_payment;
|
348 |
+
}
|
349 |
+
|
350 |
function swpm_debug_log_subsc( $message, $success, $end = false ) {
|
351 |
$settings = SwpmSettings::get_instance();
|
352 |
$debug_enabled = $settings->get_value( 'enable-debug' );
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://simple-membership-plugin.com/
|
|
4 |
Tags: member, members, members only, membership, memberships, register, WordPress membership plugin, content, content protection, paypal, restrict, restrict access, Restrict content, admin, access control, subscription, teaser, protection, profile, login, login page, bbpress, stripe, braintree
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.4
|
7 |
-
Stable tag: 3.9.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -158,6 +158,11 @@ https://simple-membership-plugin.com/
|
|
158 |
|
159 |
== Changelog ==
|
160 |
|
|
|
|
|
|
|
|
|
|
|
161 |
= 3.9.7 =
|
162 |
- Added minor improvements to the get_current_page_url() function to increase compatibility with some servers.
|
163 |
- The mini login shortcode will also work with the "Enable Redirect to Last Page" feature from the after login redirection addon.
|
4 |
Tags: member, members, members only, membership, memberships, register, WordPress membership plugin, content, content protection, paypal, restrict, restrict access, Restrict content, admin, access control, subscription, teaser, protection, profile, login, login page, bbpress, stripe, braintree
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.4
|
7 |
+
Stable tag: 3.9.8
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
158 |
|
159 |
== Changelog ==
|
160 |
|
161 |
+
= 3.9.8 =
|
162 |
+
- Added a new action hook 'swpm_validate_login_hash_mismatch'
|
163 |
+
- Ability to manually add a transaction record in the Payments menu of the plugin
|
164 |
+
- Added a new feature to hide the registration from to logged-in members. The new option is available in the Advanced settings menu.
|
165 |
+
|
166 |
= 3.9.7 =
|
167 |
- Added minor improvements to the get_current_page_url() function to increase compatibility with some servers.
|
168 |
- The mini login shortcode will also work with the "Enable Redirect to Last Page" feature from the after login redirection addon.
|
simple-wp-membership.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Simple WordPress Membership
|
4 |
-
Version: 3.9.
|
5 |
Plugin URI: https://simple-membership-plugin.com/
|
6 |
Author: smp7, wp.insider
|
7 |
Author URI: https://simple-membership-plugin.com/
|
@@ -19,7 +19,7 @@ include_once('classes/class.simple-wp-membership.php');
|
|
19 |
include_once('classes/class.swpm-cronjob.php');
|
20 |
include_once('swpm-compat.php');
|
21 |
|
22 |
-
define('SIMPLE_WP_MEMBERSHIP_VER', '3.9.
|
23 |
define('SIMPLE_WP_MEMBERSHIP_DB_VER', '1.3');
|
24 |
define('SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL', home_url());
|
25 |
define('SIMPLE_WP_MEMBERSHIP_PATH', dirname(__FILE__) . '/');
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Simple WordPress Membership
|
4 |
+
Version: 3.9.8
|
5 |
Plugin URI: https://simple-membership-plugin.com/
|
6 |
Author: smp7, wp.insider
|
7 |
Author URI: https://simple-membership-plugin.com/
|
19 |
include_once('classes/class.swpm-cronjob.php');
|
20 |
include_once('swpm-compat.php');
|
21 |
|
22 |
+
define('SIMPLE_WP_MEMBERSHIP_VER', '3.9.8');
|
23 |
define('SIMPLE_WP_MEMBERSHIP_DB_VER', '1.3');
|
24 |
define('SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL', home_url());
|
25 |
define('SIMPLE_WP_MEMBERSHIP_PATH', dirname(__FILE__) . '/');
|
views/payments/admin_add_edit_transaction_manually.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*******************************************************************
|
4 |
+
* Render and process the interface for add new transaction manually
|
5 |
+
******************************************************************/
|
6 |
+
|
7 |
+
function swpm_handle_add_new_txn_manually(){
|
8 |
+
global $wpdb;
|
9 |
+
|
10 |
+
echo '<div class="swpm-grey-box">';
|
11 |
+
SwpmUtils::e( 'You can add a new transaction record manually using this interface. It can be useful if you manually accept cash payment for your memberships.' );
|
12 |
+
echo '</div>';
|
13 |
+
|
14 |
+
if( isset( $_REQUEST['swpm_add_new_txn_save_submit'])){
|
15 |
+
//Check nonce first
|
16 |
+
check_admin_referer( 'swpm_admin_add_new_txn_form_action', 'swpm_admin_add_new_txn_form_field' );
|
17 |
+
|
18 |
+
$current_date = date( 'Y-m-d' );
|
19 |
+
|
20 |
+
$txn_data = array();
|
21 |
+
$txn_data['email'] = sanitize_text_field( $_POST['email_address'] );
|
22 |
+
$txn_data['first_name'] = sanitize_text_field( $_POST['first_name'] );
|
23 |
+
$txn_data['last_name'] = sanitize_text_field( $_POST['last_name'] );
|
24 |
+
$txn_data['ip'] = '';
|
25 |
+
$txn_data['member_id'] = isset ( $_POST['member_id'] ) ? intval( $_POST['member_id' ] ) : '';
|
26 |
+
$txn_data['membership_level'] = isset ( $_POST['membership_level_id'] ) ? intval( $_POST['membership_level_id' ] ) : '';
|
27 |
+
|
28 |
+
$txn_data['txn_date'] = isset ( $_POST['txn_date'] ) ? sanitize_text_field( $_POST['txn_date' ] ) : $current_date;
|
29 |
+
$txn_data['txn_id'] = isset ( $_POST['txn_id'] ) ? sanitize_text_field( $_POST['txn_id' ] ) : '';
|
30 |
+
$txn_data['subscr_id'] = isset ( $_POST['subscriber_id'] ) ? sanitize_text_field( $_POST['subscriber_id' ] ) : '';
|
31 |
+
$txn_data['reference'] = '';
|
32 |
+
$txn_data['payment_amount'] = isset ( $_POST['payment_amount'] ) ? sanitize_text_field( $_POST['payment_amount' ] ) : '';
|
33 |
+
$txn_data['gateway'] = 'manual';
|
34 |
+
$txn_data['status'] = isset ( $_POST['txn_status'] ) ? sanitize_text_field( $_POST['txn_status' ] ) : '';
|
35 |
+
|
36 |
+
//Insert the manual txn to the payments table
|
37 |
+
$txn_data = array_filter( $txn_data );//Remove any null values.
|
38 |
+
$wpdb->insert( $wpdb->prefix . 'swpm_payments_tbl', $txn_data );
|
39 |
+
|
40 |
+
$db_row_id = $wpdb->insert_id;
|
41 |
+
|
42 |
+
//let's also store transactions data in swpm_transactions CPT
|
43 |
+
$post = array();
|
44 |
+
$post['post_title'] = '';
|
45 |
+
$post['post_status'] = 'publish';
|
46 |
+
$post['content'] = '';
|
47 |
+
$post['post_type'] = 'swpm_transactions';
|
48 |
+
$post_id = wp_insert_post( $post );
|
49 |
+
update_post_meta( $post_id, 'db_row_id', $db_row_id );
|
50 |
+
|
51 |
+
SwpmLog::log_simple_debug("Manual transaction added successfully.", true);
|
52 |
+
|
53 |
+
echo '<div class="swpm-orange-box">';
|
54 |
+
SwpmUtils::e('Manual transaction added successfully. ');
|
55 |
+
echo '<a href="admin.php?page=simple_wp_membership_payments">View all transactions</a>';
|
56 |
+
echo '</div>';
|
57 |
+
|
58 |
+
} else {
|
59 |
+
//Show the form to add manual txn record
|
60 |
+
swpm_show_add_new_txn_form();
|
61 |
+
}
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
function swpm_show_add_new_txn_form(){
|
66 |
+
?>
|
67 |
+
<div class="postbox">
|
68 |
+
<h3 class="hndle"><label for="title"><?php echo SwpmUtils::_('Add New Transaction'); ?></label></h3>
|
69 |
+
<div class="inside">
|
70 |
+
|
71 |
+
<form id="pp_button_config_form" method="post">
|
72 |
+
<table class="form-table" width="100%" border="0" cellspacing="0" cellpadding="6">
|
73 |
+
|
74 |
+
<tr valign="top">
|
75 |
+
<th scope="row"><?php echo SwpmUtils::_('Email Address'); ?></th>
|
76 |
+
<td>
|
77 |
+
<input type="text" size="70" name="email_address" value="" required />
|
78 |
+
<p class="description">Email address of the customer.</p>
|
79 |
+
</td>
|
80 |
+
</tr>
|
81 |
+
|
82 |
+
<tr valign="top">
|
83 |
+
<th scope="row"><?php echo SwpmUtils::_('First Name'); ?></th>
|
84 |
+
<td>
|
85 |
+
<input type="text" size="50" name="first_name" value="" required />
|
86 |
+
<p class="description">First name of the customer.</p>
|
87 |
+
</td>
|
88 |
+
</tr>
|
89 |
+
|
90 |
+
<tr valign="top">
|
91 |
+
<th scope="row"><?php echo SwpmUtils::_('Last Name'); ?></th>
|
92 |
+
<td>
|
93 |
+
<input type="text" size="50" name="last_name" value="" required />
|
94 |
+
<p class="description">Last name of the customer.</p>
|
95 |
+
</td>
|
96 |
+
</tr>
|
97 |
+
|
98 |
+
<tr valign="top">
|
99 |
+
<th scope="row"><?php echo SwpmUtils::_('Member ID'); ?></th>
|
100 |
+
<td>
|
101 |
+
<input type="text" size="20" name="member_id" value="" />
|
102 |
+
<p class="description">The Member ID number of the member's profile that corresponds to this transaction.</p>
|
103 |
+
</td>
|
104 |
+
</tr>
|
105 |
+
|
106 |
+
<tr valign="top">
|
107 |
+
<th scope="row"><?php echo SwpmUtils::_('Membership Level'); ?></th>
|
108 |
+
<td>
|
109 |
+
<select id="membership_level_id" name="membership_level_id">
|
110 |
+
<?php echo SwpmUtils::membership_level_dropdown(); ?>
|
111 |
+
</select>
|
112 |
+
<p class="description">Select the membership level this transaction is for.</p>
|
113 |
+
</td>
|
114 |
+
</tr>
|
115 |
+
|
116 |
+
<tr valign="top">
|
117 |
+
<th scope="row"><?php echo SwpmUtils::_('Amount'); ?></th>
|
118 |
+
<td>
|
119 |
+
<input type="text" size="10" name="payment_amount" value="" required />
|
120 |
+
<p class="description">Enter the payment amount. Example values: 10.00 or 19.50 or 299.95 etc (do not put currency symbol).</p>
|
121 |
+
</td>
|
122 |
+
</tr>
|
123 |
+
|
124 |
+
<tr valign="top">
|
125 |
+
<th scope="row"><?php echo SwpmUtils::_('Date'); ?></th>
|
126 |
+
<td>
|
127 |
+
<input type="text" size="20" name="txn_date" value="" />
|
128 |
+
<p class="description">The date for this transaction. Use format YYYY-MM-DD.</p>
|
129 |
+
</td>
|
130 |
+
</tr>
|
131 |
+
|
132 |
+
<tr valign="top">
|
133 |
+
<th scope="row"><?php echo SwpmUtils::_('Transaction ID'); ?></th>
|
134 |
+
<td>
|
135 |
+
<input type="text" size="50" name="txn_id" value="" />
|
136 |
+
<p class="description">The unique transaction ID of this transaction so you can identify it easily.</p>
|
137 |
+
</td>
|
138 |
+
</tr>
|
139 |
+
|
140 |
+
<tr valign="top">
|
141 |
+
<th scope="row"><?php echo SwpmUtils::_('Subscriber ID'); ?></th>
|
142 |
+
<td>
|
143 |
+
<input type="text" size="50" name="subscriber_id" value="" />
|
144 |
+
<p class="description">The subscriber ID (if any) from the member's profile.</p>
|
145 |
+
</td>
|
146 |
+
</tr>
|
147 |
+
|
148 |
+
<tr valign="top">
|
149 |
+
<th scope="row"><?php echo SwpmUtils::_('Status/Note'); ?></th>
|
150 |
+
<td>
|
151 |
+
<input type="text" size="50" name="txn_status" value="" />
|
152 |
+
<p class="description">A status value for this transaction. This will go to the Status/Note column of the transaction record.</p>
|
153 |
+
</td>
|
154 |
+
</tr>
|
155 |
+
|
156 |
+
</table>
|
157 |
+
|
158 |
+
<p class="submit">
|
159 |
+
<?php wp_nonce_field( 'swpm_admin_add_new_txn_form_action', 'swpm_admin_add_new_txn_form_field' ) ?>
|
160 |
+
<input type="submit" name="swpm_add_new_txn_save_submit" class="button-primary" value="<?php echo SwpmUtils::_('Save Transaction Data'); ?>" >
|
161 |
+
</p>
|
162 |
+
|
163 |
+
</form>
|
164 |
+
|
165 |
+
</div>
|
166 |
+
</div>
|
167 |
+
<?php
|
168 |
+
}
|
views/payments/admin_all_payment_transactions.php
CHANGED
@@ -43,4 +43,8 @@ $payments_list_table->prepare_items();
|
|
43 |
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
44 |
<!-- Now we can render the completed list table -->
|
45 |
<?php $payments_list_table->display(); ?>
|
46 |
-
</form>
|
|
|
|
|
|
|
|
43 |
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
44 |
<!-- Now we can render the completed list table -->
|
45 |
<?php $payments_list_table->display(); ?>
|
46 |
+
</form>
|
47 |
+
|
48 |
+
<p class="submit">
|
49 |
+
<a href="admin.php?page=simple_wp_membership_payments&tab=add_new_txn" class="button"><?php echo SwpmUtils::_('Add a Transaction Manually'); ?></a>
|
50 |
+
</p>
|
views/payments/admin_create_payment_buttons.php
CHANGED
@@ -70,4 +70,3 @@ if ( ! isset( $_REQUEST['swpm_button_type_selected'] ) ) {
|
|
70 |
do_action( 'swpm_create_new_button_for_' . $button_type );
|
71 |
//The payment addons will create the button from then redirect to the "edit" interface of that button after save.
|
72 |
}
|
73 |
-
?>
|
70 |
do_action( 'swpm_create_new_button_for_' . $button_type );
|
71 |
//The payment addons will create the button from then redirect to the "edit" interface of that button after save.
|
72 |
}
|
|