Simple Membership - Version 3.9.8

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 Icon 128x128 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 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 LIMIT %d, 100", $counter);
 
 
 
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
- $settings_configs = SwpmSettings::get_instance();
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' => 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,7 +94,11 @@ class SwpmMembers extends WP_List_Table {
94
 
95
  $this->process_bulk_action();
96
 
97
- $query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl';
 
 
 
 
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->query( $query ); //return the total number of affected rows
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
- // Trial payment or recurring payment?
150
- // TODO - is_recurring_payment() check to determine if it is a recurring payment
151
  $trial_billing_amount = get_post_meta( $button_id, 'trial_billing_amount', true );
152
- $billing_amount = get_post_meta( $button_id, 'billing_amount', true );
153
- $expected_amount = 0;
154
- $received_amount = $cart_item_data_total;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.7
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.7
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.7');
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
  }