Version Description
- Braintree SDK updated for the Braintree payment gateway.
- Google reCAPTCHA enterprise option is now available as a free addon.
Download this release
Release Info
Developer | mra13 |
Plugin | Simple Membership |
Version | 4.2.0 |
Comparing to | |
See all releases |
Code changes from version 4.1.8 to 4.2.0
- classes/class.swpm-ajax.php +2 -0
- classes/class.swpm-auth.php +408 -402
- classes/class.swpm-form.php +1 -1
- classes/class.swpm-front-registration.php +5 -1
- classes/class.swpm-members.php +2 -1
- classes/class.swpm-utils.php +13 -5
- images/addons/swpm-mailerlite-integration.png +0 -0
- ipn/swpm-braintree-buy-now-ipn.php +6 -1
- ipn/swpm-stripe-sca-buy-now-ipn.php +392 -381
- readme.txt +15 -2
- simple-wp-membership.php +2 -2
- views/admin_add_ons_page.php +8 -0
- views/payments/payment-gateway/braintree_button_shortcode_view.php +68 -33
- views/payments/payment-gateway/stripe_sca_button_shortcode_view.php +2 -2
classes/class.swpm-ajax.php
CHANGED
@@ -8,6 +8,8 @@ class SwpmAjax {
|
|
8 |
public static function validate_email_ajax() {
|
9 |
global $wpdb;
|
10 |
$field_value = isset($_GET['fieldValue']) ? sanitize_text_field($_GET['fieldValue']) : '';
|
|
|
|
|
11 |
$field_id = isset($_GET['fieldId']) ? sanitize_text_field($_GET['fieldId']) : '';
|
12 |
$member_id = isset($_GET['member_id']) ? sanitize_text_field($_GET['member_id']) : '';
|
13 |
if (!check_ajax_referer( 'swpm-rego-form-ajax-nonce', 'nonce', false )) {
|
8 |
public static function validate_email_ajax() {
|
9 |
global $wpdb;
|
10 |
$field_value = isset($_GET['fieldValue']) ? sanitize_text_field($_GET['fieldValue']) : '';
|
11 |
+
$field_value = stripslashes($field_value);//Clean the email address value (so it can work with values like: test.de'souz@exaple.com)
|
12 |
+
|
13 |
$field_id = isset($_GET['fieldId']) ? sanitize_text_field($_GET['fieldId']) : '';
|
14 |
$member_id = isset($_GET['member_id']) ? sanitize_text_field($_GET['member_id']) : '';
|
15 |
if (!check_ajax_referer( 'swpm-rego-form-ajax-nonce', 'nonce', false )) {
|
classes/class.swpm-auth.php
CHANGED
@@ -1,402 +1,408 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SwpmAuth {
|
4 |
-
|
5 |
-
public $protected;
|
6 |
-
public $permitted;
|
7 |
-
private $isLoggedIn;
|
8 |
-
private $lastStatusMsg;
|
9 |
-
private static $_this;
|
10 |
-
public $userData;
|
11 |
-
|
12 |
-
private function __construct() {
|
13 |
-
//check if we need to display custom message on the login form
|
14 |
-
$custom_msg = filter_input( INPUT_COOKIE, 'swpm-login-form-custom-msg', FILTER_SANITIZE_STRING );
|
15 |
-
if ( ! empty( $custom_msg ) ) {
|
16 |
-
$this->lastStatusMsg = $custom_msg;
|
17 |
-
//let's 'unset' the cookie
|
18 |
-
setcookie( 'swpm-login-form-custom-msg', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN );
|
19 |
-
}
|
20 |
-
$this->isLoggedIn = false;
|
21 |
-
$this->userData = null;
|
22 |
-
$this->protected = SwpmProtection::get_instance();
|
23 |
-
}
|
24 |
-
|
25 |
-
private function init() {
|
26 |
-
$valid = $this->validate();
|
27 |
-
//SwpmLog::log_auth_debug("init:". ($valid? "valid": "invalid"), true);
|
28 |
-
if ( ! $valid ) {
|
29 |
-
$this->authenticate();
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
public static function get_instance() {
|
34 |
-
if ( empty( self::$_this ) ) {
|
35 |
-
self::$_this = new SwpmAuth();
|
36 |
-
self::$_this->init();
|
37 |
-
}
|
38 |
-
return self::$_this;
|
39 |
-
}
|
40 |
-
|
41 |
-
private function authenticate( $user = null, $pass = null ) {
|
42 |
-
global $wpdb;
|
43 |
-
$swpm_password = empty( $pass ) ? filter_input( INPUT_POST, 'swpm_password' ) : $pass;
|
44 |
-
$swpm_user_name = empty( $user ) ? apply_filters( 'swpm_user_name', filter_input( INPUT_POST, 'swpm_user_name' ) ) : $user;
|
45 |
-
|
46 |
-
if ( ! empty( $swpm_user_name ) && ! empty( $swpm_password ) ) {
|
47 |
-
//SWPM member login request.
|
48 |
-
//Trigger action hook that can be used to check stuff before the login request is processed by the plugin.
|
49 |
-
$args = array(
|
50 |
-
'username' => $swpm_user_name,
|
51 |
-
'password' => $swpm_password,
|
52 |
-
);
|
53 |
-
do_action( 'swpm_before_login_request_is_processed', $args );
|
54 |
-
|
55 |
-
//First, lets make sure this user is not already logged into the site as an "Admin" user. We don't want to override that admin login session.
|
56 |
-
if ( current_user_can( 'administrator' ) ) {
|
57 |
-
//This user is logged in as ADMIN then trying to do another login as a member. Stop the login request processing (we don't want to override your admin login session).
|
58 |
-
$wp_profile_page = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/wp-admin/profile.php';
|
59 |
-
$error_msg = '';
|
60 |
-
$error_msg .= '<p>' . SwpmUtils::_( 'Warning! Simple Membership plugin cannot process this login request to prevent you from getting logged out of WP Admin accidentally.' ) . '</p>';
|
61 |
-
$error_msg .= '<p><a href="' . $wp_profile_page . '" target="_blank">' . SwpmUtils::_( 'Click here' ) . '</a>' . SwpmUtils::_( ' to see the profile you are currently logged into in this browser.' ) . '</p>';
|
62 |
-
$error_msg .= '<p>' . SwpmUtils::_( 'You are logged into the site as an ADMIN user in this browser. First, logout from WP Admin then you will be able to log in as a normal member.' ) . '</p>';
|
63 |
-
$error_msg .= '<p>' . SwpmUtils::_( 'Alternatively, you can use a different browser (where you are not logged-in as ADMIN) to test the membership login.' ) . '</p>';
|
64 |
-
$error_msg .= '<p>' . SwpmUtils::_( 'Your normal visitors or members will never see this message. This message is ONLY for ADMIN user.' ) . '</p>';
|
65 |
-
wp_die( $error_msg );
|
66 |
-
}
|
67 |
-
|
68 |
-
//If captcha is present and validation failed, it returns an error string. If validation succeeds, it returns an empty string.
|
69 |
-
$captcha_validation_output = apply_filters( 'swpm_validate_login_form_submission', '' );
|
70 |
-
if ( ! empty( $captcha_validation_output ) ) {
|
71 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Captcha validation failed on login form.' );
|
72 |
-
return;
|
73 |
-
}
|
74 |
-
|
75 |
-
if ( is_email( $swpm_user_name ) ) {//User is trying to log-in using an email address
|
76 |
-
$email = sanitize_email( $swpm_user_name );
|
77 |
-
$query = $wpdb->prepare( 'SELECT user_name FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE email = %s', $email );
|
78 |
-
$username = $wpdb->get_var( $query );
|
79 |
-
if ( $username ) {//Found a user record
|
80 |
-
$swpm_user_name = $username; //Grab the usrename value so it can be used in the authentication process.
|
81 |
-
SwpmLog::log_auth_debug( 'Authentication request using email address: ' . $email . ', Found a user record with username: ' . $swpm_user_name, true );
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
//Lets process the request. Check username and password
|
86 |
-
$user = sanitize_user( $swpm_user_name );
|
87 |
-
$pass = trim( $swpm_password );
|
88 |
-
SwpmLog::log_auth_debug( 'Authentication request - Username: ' . $swpm_user_name, true );
|
89 |
-
|
90 |
-
$query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
|
91 |
-
$userData = $wpdb->get_row( $wpdb->prepare( $query, $user ) );
|
92 |
-
$this->userData = $userData;
|
93 |
-
if ( ! $userData ) {
|
94 |
-
$this->isLoggedIn = false;
|
95 |
-
$this->userData = null;
|
96 |
-
$this->lastStatusMsg = SwpmUtils::_( 'User Not Found.' );
|
97 |
-
return false;
|
98 |
-
}
|
99 |
-
$check = $this->check_password( $pass, $userData->password );
|
100 |
-
if ( ! $check ) {
|
101 |
-
$this->isLoggedIn = false;
|
102 |
-
$this->userData = null;
|
103 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Password Empty or Invalid.' );
|
104 |
-
return false;
|
105 |
-
}
|
106 |
-
if ( $this->check_constraints() ) {
|
107 |
-
$rememberme = filter_input( INPUT_POST, 'rememberme' );
|
108 |
-
$remember = empty( $rememberme ) ? false : true;
|
109 |
-
$this->set_cookie( $remember );
|
110 |
-
$this->isLoggedIn = true;
|
111 |
-
$this->lastStatusMsg = 'Logged In.';
|
112 |
-
SwpmLog::log_auth_debug( 'Authentication successful for username: ' . $user . '. Executing swpm_login action hook.', true );
|
113 |
-
do_action( 'swpm_login', $user, $pass, $remember );
|
114 |
-
return true;
|
115 |
-
}
|
116 |
-
}
|
117 |
-
return false;
|
118 |
-
}
|
119 |
-
|
120 |
-
private function check_constraints() {
|
121 |
-
if ( empty( $this->userData ) ) {
|
122 |
-
return false;
|
123 |
-
}
|
124 |
-
global $wpdb;
|
125 |
-
$enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
|
126 |
-
|
127 |
-
//Update the last accessed date and IP address for this login attempt. $wpdb->update(table, data, where, format, where format)
|
128 |
-
$last_accessed_date = current_time( 'mysql' );
|
129 |
-
$last_accessed_ip = SwpmUtils::get_user_ip_address();
|
130 |
-
$wpdb->update(
|
131 |
-
$wpdb->prefix . 'swpm_members_tbl',
|
132 |
-
array(
|
133 |
-
'last_accessed' => $last_accessed_date,
|
134 |
-
'last_accessed_from_ip' => $last_accessed_ip,
|
135 |
-
),
|
136 |
-
array( 'member_id' => $this->userData->member_id ),
|
137 |
-
array( '%s', '%s' ),
|
138 |
-
array( '%d' )
|
139 |
-
);
|
140 |
-
|
141 |
-
//Check the member's account status.
|
142 |
-
$can_login = true;
|
143 |
-
if ( $this->userData->account_state == 'inactive' && empty( $enable_expired_login ) ) {
|
144 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Account is inactive.' );
|
145 |
-
$can_login = false;
|
146 |
-
} elseif ( ( $this->userData->account_state == 'expired' ) && empty( $enable_expired_login ) ) {
|
147 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
|
148 |
-
$can_login = false;
|
149 |
-
} elseif ( $this->userData->account_state == 'pending' ) {
|
150 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Account is pending.' );
|
151 |
-
$can_login = false;
|
152 |
-
} elseif ( $this->userData->account_state == 'activation_required' ) {
|
153 |
-
$resend_email_url = add_query_arg(
|
154 |
-
array(
|
155 |
-
'swpm_resend_activation_email' => '1',
|
156 |
-
'swpm_member_id' => $this->userData->member_id,
|
157 |
-
),
|
158 |
-
get_home_url()
|
159 |
-
);
|
160 |
-
$msg = sprintf( SwpmUtils::_( 'You need to activate your account. If you didn\'t receive an email then %s to resend the activation email.' ), '<a href="' . $resend_email_url . '">' . SwpmUtils::_( 'click here' ) . '</a>' );
|
161 |
-
$this->lastStatusMsg = $msg;
|
162 |
-
$can_login = false;
|
163 |
-
}
|
164 |
-
|
165 |
-
if ( ! $can_login ) {
|
166 |
-
$this->isLoggedIn = false;
|
167 |
-
$this->userData = null;
|
168 |
-
return false;
|
169 |
-
}
|
170 |
-
|
171 |
-
if ( SwpmUtils::is_subscription_expired( $this->userData ) ) {
|
172 |
-
if ( $this->userData->account_state == 'active' ) {
|
173 |
-
$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'account_state' => 'expired' ), array( 'member_id' => $this->userData->member_id ), array( '%s' ), array( '%d' ) );
|
174 |
-
}
|
175 |
-
if ( empty( $enable_expired_login ) ) {
|
176 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
|
177 |
-
$this->isLoggedIn = false;
|
178 |
-
$this->userData = null;
|
179 |
-
return false;
|
180 |
-
}
|
181 |
-
}
|
182 |
-
|
183 |
-
$this->permitted = SwpmPermission::get_instance( $this->userData->membership_level );
|
184 |
-
$this->lastStatusMsg = SwpmUtils::_( 'You are logged in as:' ) . $this->userData->user_name;
|
185 |
-
$this->isLoggedIn = true;
|
186 |
-
return true;
|
187 |
-
}
|
188 |
-
|
189 |
-
private function check_password( $plain_password, $hashed_pw ) {
|
190 |
-
global $wp_hasher;
|
191 |
-
if ( empty( $plain_password ) ) {
|
192 |
-
return false;
|
193 |
-
}
|
194 |
-
if ( empty( $wp_hasher ) ) {
|
195 |
-
require_once ABSPATH . 'wp-includes/class-phpass.php';
|
196 |
-
$wp_hasher = new PasswordHash( 8, true );
|
197 |
-
}
|
198 |
-
return $wp_hasher->CheckPassword( $plain_password, $hashed_pw );
|
199 |
-
}
|
200 |
-
|
201 |
-
public function match_password( $password ) {
|
202 |
-
if ( ! $this->is_logged_in() ) {
|
203 |
-
return false;
|
204 |
-
}
|
205 |
-
return $this->check_password( $password, $this->get( 'password' ) );
|
206 |
-
}
|
207 |
-
|
208 |
-
public function login_to_swpm_using_wp_user( $user ) {
|
209 |
-
if ( $this->isLoggedIn ) {
|
210 |
-
return false;
|
211 |
-
}
|
212 |
-
$email = $user->user_email;
|
213 |
-
$member = SwpmMemberUtils::get_user_by_email( $email );
|
214 |
-
if ( empty( $member ) ) {
|
215 |
-
//There is no swpm profile with this email.
|
216 |
-
return false;
|
217 |
-
}
|
218 |
-
$this->userData = $member;
|
219 |
-
$this->isLoggedIn = true;
|
220 |
-
$this->set_cookie();
|
221 |
-
SwpmLog::log_auth_debug( 'Member has been logged in using WP User object.', true );
|
222 |
-
$this->check_constraints();
|
223 |
-
return true;
|
224 |
-
}
|
225 |
-
|
226 |
-
public function login( $user, $pass, $remember = '', $secure = '' ) {
|
227 |
-
SwpmLog::log_auth_debug( 'SwpmAuth::login()', true );
|
228 |
-
if ( $this->isLoggedIn ) {
|
229 |
-
return;
|
230 |
-
}
|
231 |
-
if ( $this->authenticate( $user, $pass ) && $this->validate() ) {
|
232 |
-
$this->set_cookie( $remember, $secure );
|
233 |
-
} else {
|
234 |
-
$this->isLoggedIn = false;
|
235 |
-
$this->userData = null;
|
236 |
-
}
|
237 |
-
return $this->lastStatusMsg;
|
238 |
-
}
|
239 |
-
|
240 |
-
public function logout() {
|
241 |
-
if ( ! $this->isLoggedIn ) {
|
242 |
-
return;
|
243 |
-
}
|
244 |
-
setcookie( SIMPLE_WP_MEMBERSHIP_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
|
245 |
-
setcookie( SIMPLE_WP_MEMBERSHIP_SEC_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
|
246 |
-
$this->userData = null;
|
247 |
-
$this->isLoggedIn = false;
|
248 |
-
$this->lastStatusMsg = SwpmUtils::_( 'Logged Out Successfully.' );
|
249 |
-
do_action( 'swpm_logout' );
|
250 |
-
}
|
251 |
-
|
252 |
-
private function set_cookie( $remember = '', $secure = '' ) {
|
253 |
-
if ( $remember ) {
|
254 |
-
$expiration = time() + 1209600; //14 days
|
255 |
-
$expire = $expiration + 43200; //12 hours grace period
|
256 |
-
} else {
|
257 |
-
$expiration = time() + 259200; //3 days.
|
258 |
-
$expire = $expiration; //The minimum cookie expiration should be at least a few days.
|
259 |
-
}
|
260 |
-
|
261 |
-
$expire = apply_filters( 'swpm_auth_cookie_expiry_value', $expire );
|
262 |
-
|
263 |
-
setcookie( 'swpm_in_use', 'swpm_in_use', $expire, COOKIEPATH, COOKIE_DOMAIN )
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
$
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
$
|
276 |
-
$
|
277 |
-
$
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
$
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
$
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
}
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
$
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
if (
|
349 |
-
return $this->
|
350 |
-
}
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SwpmAuth {
|
4 |
+
|
5 |
+
public $protected;
|
6 |
+
public $permitted;
|
7 |
+
private $isLoggedIn;
|
8 |
+
private $lastStatusMsg;
|
9 |
+
private static $_this;
|
10 |
+
public $userData;
|
11 |
+
|
12 |
+
private function __construct() {
|
13 |
+
//check if we need to display custom message on the login form
|
14 |
+
$custom_msg = filter_input( INPUT_COOKIE, 'swpm-login-form-custom-msg', FILTER_SANITIZE_STRING );
|
15 |
+
if ( ! empty( $custom_msg ) ) {
|
16 |
+
$this->lastStatusMsg = $custom_msg;
|
17 |
+
//let's 'unset' the cookie
|
18 |
+
setcookie( 'swpm-login-form-custom-msg', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN );
|
19 |
+
}
|
20 |
+
$this->isLoggedIn = false;
|
21 |
+
$this->userData = null;
|
22 |
+
$this->protected = SwpmProtection::get_instance();
|
23 |
+
}
|
24 |
+
|
25 |
+
private function init() {
|
26 |
+
$valid = $this->validate();
|
27 |
+
//SwpmLog::log_auth_debug("init:". ($valid? "valid": "invalid"), true);
|
28 |
+
if ( ! $valid ) {
|
29 |
+
$this->authenticate();
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
public static function get_instance() {
|
34 |
+
if ( empty( self::$_this ) ) {
|
35 |
+
self::$_this = new SwpmAuth();
|
36 |
+
self::$_this->init();
|
37 |
+
}
|
38 |
+
return self::$_this;
|
39 |
+
}
|
40 |
+
|
41 |
+
private function authenticate( $user = null, $pass = null ) {
|
42 |
+
global $wpdb;
|
43 |
+
$swpm_password = empty( $pass ) ? filter_input( INPUT_POST, 'swpm_password' ) : $pass;
|
44 |
+
$swpm_user_name = empty( $user ) ? apply_filters( 'swpm_user_name', filter_input( INPUT_POST, 'swpm_user_name' ) ) : $user;
|
45 |
+
|
46 |
+
if ( ! empty( $swpm_user_name ) && ! empty( $swpm_password ) ) {
|
47 |
+
//SWPM member login request.
|
48 |
+
//Trigger action hook that can be used to check stuff before the login request is processed by the plugin.
|
49 |
+
$args = array(
|
50 |
+
'username' => $swpm_user_name,
|
51 |
+
'password' => $swpm_password,
|
52 |
+
);
|
53 |
+
do_action( 'swpm_before_login_request_is_processed', $args );
|
54 |
+
|
55 |
+
//First, lets make sure this user is not already logged into the site as an "Admin" user. We don't want to override that admin login session.
|
56 |
+
if ( current_user_can( 'administrator' ) ) {
|
57 |
+
//This user is logged in as ADMIN then trying to do another login as a member. Stop the login request processing (we don't want to override your admin login session).
|
58 |
+
$wp_profile_page = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/wp-admin/profile.php';
|
59 |
+
$error_msg = '';
|
60 |
+
$error_msg .= '<p>' . SwpmUtils::_( 'Warning! Simple Membership plugin cannot process this login request to prevent you from getting logged out of WP Admin accidentally.' ) . '</p>';
|
61 |
+
$error_msg .= '<p><a href="' . $wp_profile_page . '" target="_blank">' . SwpmUtils::_( 'Click here' ) . '</a>' . SwpmUtils::_( ' to see the profile you are currently logged into in this browser.' ) . '</p>';
|
62 |
+
$error_msg .= '<p>' . SwpmUtils::_( 'You are logged into the site as an ADMIN user in this browser. First, logout from WP Admin then you will be able to log in as a normal member.' ) . '</p>';
|
63 |
+
$error_msg .= '<p>' . SwpmUtils::_( 'Alternatively, you can use a different browser (where you are not logged-in as ADMIN) to test the membership login.' ) . '</p>';
|
64 |
+
$error_msg .= '<p>' . SwpmUtils::_( 'Your normal visitors or members will never see this message. This message is ONLY for ADMIN user.' ) . '</p>';
|
65 |
+
wp_die( $error_msg );
|
66 |
+
}
|
67 |
+
|
68 |
+
//If captcha is present and validation failed, it returns an error string. If validation succeeds, it returns an empty string.
|
69 |
+
$captcha_validation_output = apply_filters( 'swpm_validate_login_form_submission', '' );
|
70 |
+
if ( ! empty( $captcha_validation_output ) ) {
|
71 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Captcha validation failed on login form.' );
|
72 |
+
return;
|
73 |
+
}
|
74 |
+
|
75 |
+
if ( is_email( $swpm_user_name ) ) {//User is trying to log-in using an email address
|
76 |
+
$email = sanitize_email( $swpm_user_name );
|
77 |
+
$query = $wpdb->prepare( 'SELECT user_name FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE email = %s', $email );
|
78 |
+
$username = $wpdb->get_var( $query );
|
79 |
+
if ( $username ) {//Found a user record
|
80 |
+
$swpm_user_name = $username; //Grab the usrename value so it can be used in the authentication process.
|
81 |
+
SwpmLog::log_auth_debug( 'Authentication request using email address: ' . $email . ', Found a user record with username: ' . $swpm_user_name, true );
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
//Lets process the request. Check username and password
|
86 |
+
$user = sanitize_user( $swpm_user_name );
|
87 |
+
$pass = trim( $swpm_password );
|
88 |
+
SwpmLog::log_auth_debug( 'Authentication request - Username: ' . $swpm_user_name, true );
|
89 |
+
|
90 |
+
$query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
|
91 |
+
$userData = $wpdb->get_row( $wpdb->prepare( $query, $user ) );
|
92 |
+
$this->userData = $userData;
|
93 |
+
if ( ! $userData ) {
|
94 |
+
$this->isLoggedIn = false;
|
95 |
+
$this->userData = null;
|
96 |
+
$this->lastStatusMsg = SwpmUtils::_( 'User Not Found.' );
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
$check = $this->check_password( $pass, $userData->password );
|
100 |
+
if ( ! $check ) {
|
101 |
+
$this->isLoggedIn = false;
|
102 |
+
$this->userData = null;
|
103 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Password Empty or Invalid.' );
|
104 |
+
return false;
|
105 |
+
}
|
106 |
+
if ( $this->check_constraints() ) {
|
107 |
+
$rememberme = filter_input( INPUT_POST, 'rememberme' );
|
108 |
+
$remember = empty( $rememberme ) ? false : true;
|
109 |
+
$this->set_cookie( $remember );
|
110 |
+
$this->isLoggedIn = true;
|
111 |
+
$this->lastStatusMsg = 'Logged In.';
|
112 |
+
SwpmLog::log_auth_debug( 'Authentication successful for username: ' . $user . '. Executing swpm_login action hook.', true );
|
113 |
+
do_action( 'swpm_login', $user, $pass, $remember );
|
114 |
+
return true;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
return false;
|
118 |
+
}
|
119 |
+
|
120 |
+
private function check_constraints() {
|
121 |
+
if ( empty( $this->userData ) ) {
|
122 |
+
return false;
|
123 |
+
}
|
124 |
+
global $wpdb;
|
125 |
+
$enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
|
126 |
+
|
127 |
+
//Update the last accessed date and IP address for this login attempt. $wpdb->update(table, data, where, format, where format)
|
128 |
+
$last_accessed_date = current_time( 'mysql' );
|
129 |
+
$last_accessed_ip = SwpmUtils::get_user_ip_address();
|
130 |
+
$wpdb->update(
|
131 |
+
$wpdb->prefix . 'swpm_members_tbl',
|
132 |
+
array(
|
133 |
+
'last_accessed' => $last_accessed_date,
|
134 |
+
'last_accessed_from_ip' => $last_accessed_ip,
|
135 |
+
),
|
136 |
+
array( 'member_id' => $this->userData->member_id ),
|
137 |
+
array( '%s', '%s' ),
|
138 |
+
array( '%d' )
|
139 |
+
);
|
140 |
+
|
141 |
+
//Check the member's account status.
|
142 |
+
$can_login = true;
|
143 |
+
if ( $this->userData->account_state == 'inactive' && empty( $enable_expired_login ) ) {
|
144 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Account is inactive.' );
|
145 |
+
$can_login = false;
|
146 |
+
} elseif ( ( $this->userData->account_state == 'expired' ) && empty( $enable_expired_login ) ) {
|
147 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
|
148 |
+
$can_login = false;
|
149 |
+
} elseif ( $this->userData->account_state == 'pending' ) {
|
150 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Account is pending.' );
|
151 |
+
$can_login = false;
|
152 |
+
} elseif ( $this->userData->account_state == 'activation_required' ) {
|
153 |
+
$resend_email_url = add_query_arg(
|
154 |
+
array(
|
155 |
+
'swpm_resend_activation_email' => '1',
|
156 |
+
'swpm_member_id' => $this->userData->member_id,
|
157 |
+
),
|
158 |
+
get_home_url()
|
159 |
+
);
|
160 |
+
$msg = sprintf( SwpmUtils::_( 'You need to activate your account. If you didn\'t receive an email then %s to resend the activation email.' ), '<a href="' . $resend_email_url . '">' . SwpmUtils::_( 'click here' ) . '</a>' );
|
161 |
+
$this->lastStatusMsg = $msg;
|
162 |
+
$can_login = false;
|
163 |
+
}
|
164 |
+
|
165 |
+
if ( ! $can_login ) {
|
166 |
+
$this->isLoggedIn = false;
|
167 |
+
$this->userData = null;
|
168 |
+
return false;
|
169 |
+
}
|
170 |
+
|
171 |
+
if ( SwpmUtils::is_subscription_expired( $this->userData ) ) {
|
172 |
+
if ( $this->userData->account_state == 'active' ) {
|
173 |
+
$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'account_state' => 'expired' ), array( 'member_id' => $this->userData->member_id ), array( '%s' ), array( '%d' ) );
|
174 |
+
}
|
175 |
+
if ( empty( $enable_expired_login ) ) {
|
176 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Account has expired.' );
|
177 |
+
$this->isLoggedIn = false;
|
178 |
+
$this->userData = null;
|
179 |
+
return false;
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
$this->permitted = SwpmPermission::get_instance( $this->userData->membership_level );
|
184 |
+
$this->lastStatusMsg = SwpmUtils::_( 'You are logged in as:' ) . $this->userData->user_name;
|
185 |
+
$this->isLoggedIn = true;
|
186 |
+
return true;
|
187 |
+
}
|
188 |
+
|
189 |
+
private function check_password( $plain_password, $hashed_pw ) {
|
190 |
+
global $wp_hasher;
|
191 |
+
if ( empty( $plain_password ) ) {
|
192 |
+
return false;
|
193 |
+
}
|
194 |
+
if ( empty( $wp_hasher ) ) {
|
195 |
+
require_once ABSPATH . 'wp-includes/class-phpass.php';
|
196 |
+
$wp_hasher = new PasswordHash( 8, true );
|
197 |
+
}
|
198 |
+
return $wp_hasher->CheckPassword( $plain_password, $hashed_pw );
|
199 |
+
}
|
200 |
+
|
201 |
+
public function match_password( $password ) {
|
202 |
+
if ( ! $this->is_logged_in() ) {
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
return $this->check_password( $password, $this->get( 'password' ) );
|
206 |
+
}
|
207 |
+
|
208 |
+
public function login_to_swpm_using_wp_user( $user ) {
|
209 |
+
if ( $this->isLoggedIn ) {
|
210 |
+
return false;
|
211 |
+
}
|
212 |
+
$email = $user->user_email;
|
213 |
+
$member = SwpmMemberUtils::get_user_by_email( $email );
|
214 |
+
if ( empty( $member ) ) {
|
215 |
+
//There is no swpm profile with this email.
|
216 |
+
return false;
|
217 |
+
}
|
218 |
+
$this->userData = $member;
|
219 |
+
$this->isLoggedIn = true;
|
220 |
+
$this->set_cookie();
|
221 |
+
SwpmLog::log_auth_debug( 'Member has been logged in using WP User object.', true );
|
222 |
+
$this->check_constraints();
|
223 |
+
return true;
|
224 |
+
}
|
225 |
+
|
226 |
+
public function login( $user, $pass, $remember = '', $secure = '' ) {
|
227 |
+
SwpmLog::log_auth_debug( 'SwpmAuth::login()', true );
|
228 |
+
if ( $this->isLoggedIn ) {
|
229 |
+
return;
|
230 |
+
}
|
231 |
+
if ( $this->authenticate( $user, $pass ) && $this->validate() ) {
|
232 |
+
$this->set_cookie( $remember, $secure );
|
233 |
+
} else {
|
234 |
+
$this->isLoggedIn = false;
|
235 |
+
$this->userData = null;
|
236 |
+
}
|
237 |
+
return $this->lastStatusMsg;
|
238 |
+
}
|
239 |
+
|
240 |
+
public function logout() {
|
241 |
+
if ( ! $this->isLoggedIn ) {
|
242 |
+
return;
|
243 |
+
}
|
244 |
+
setcookie( SIMPLE_WP_MEMBERSHIP_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
|
245 |
+
setcookie( SIMPLE_WP_MEMBERSHIP_SEC_AUTH, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
|
246 |
+
$this->userData = null;
|
247 |
+
$this->isLoggedIn = false;
|
248 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Logged Out Successfully.' );
|
249 |
+
do_action( 'swpm_logout' );
|
250 |
+
}
|
251 |
+
|
252 |
+
private function set_cookie( $remember = '', $secure = '' ) {
|
253 |
+
if ( $remember ) {
|
254 |
+
$expiration = time() + 1209600; //14 days
|
255 |
+
$expire = $expiration + 43200; //12 hours grace period
|
256 |
+
} else {
|
257 |
+
$expiration = time() + 259200; //3 days.
|
258 |
+
$expire = $expiration; //The minimum cookie expiration should be at least a few days.
|
259 |
+
}
|
260 |
+
|
261 |
+
$expire = apply_filters( 'swpm_auth_cookie_expiry_value', $expire );
|
262 |
+
|
263 |
+
setcookie( 'swpm_in_use', 'swpm_in_use', $expire, COOKIEPATH, COOKIE_DOMAIN );//Switch this to the following one.
|
264 |
+
setcookie( 'wp_swpm_in_use', 'wp_swpm_in_use', $expire, COOKIEPATH, COOKIE_DOMAIN );//Prefix the cookie with 'wp' to exclude Batcache caching.
|
265 |
+
if ( function_exists( 'wp_cache_serve_cache_file' ) ) {//WP Super cache workaround
|
266 |
+
$author_value = isset( $this->userData->user_name ) ? $this->userData->user_name : 'wp_swpm';
|
267 |
+
$author_value = apply_filters( 'swpm_comment_author_cookie_value', $author_value );
|
268 |
+
setcookie( "comment_author_", $author_value, $expire, COOKIEPATH, COOKIE_DOMAIN );
|
269 |
+
}
|
270 |
+
|
271 |
+
$expiration_timestamp = SwpmUtils::get_expiration_timestamp( $this->userData );
|
272 |
+
$enable_expired_login = SwpmSettings::get_instance()->get_value( 'enable-expired-account-login', '' );
|
273 |
+
// make sure cookie doesn't live beyond account expiration date.
|
274 |
+
// but if expired account login is enabled then ignore if account is expired
|
275 |
+
$expiration = empty( $enable_expired_login ) ? min( $expiration, $expiration_timestamp ) : $expiration;
|
276 |
+
$pass_frag = substr( $this->userData->password, 8, 4 );
|
277 |
+
$scheme = 'auth';
|
278 |
+
if ( ! $secure ) {
|
279 |
+
$secure = is_ssl();
|
280 |
+
}
|
281 |
+
$key = self::b_hash( $this->userData->user_name . $pass_frag . '|' . $expiration, $scheme );
|
282 |
+
$hash = hash_hmac( 'md5', $this->userData->user_name . '|' . $expiration, $key );
|
283 |
+
$auth_cookie = $this->userData->user_name . '|' . $expiration . '|' . $hash;
|
284 |
+
$auth_cookie_name = $secure ? SIMPLE_WP_MEMBERSHIP_SEC_AUTH : SIMPLE_WP_MEMBERSHIP_AUTH;
|
285 |
+
setcookie( $auth_cookie_name, $auth_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, $secure, true );
|
286 |
+
}
|
287 |
+
|
288 |
+
private function validate() {
|
289 |
+
$auth_cookie_name = is_ssl() ? SIMPLE_WP_MEMBERSHIP_SEC_AUTH : SIMPLE_WP_MEMBERSHIP_AUTH;
|
290 |
+
if ( ! isset( $_COOKIE[ $auth_cookie_name ] ) || empty( $_COOKIE[ $auth_cookie_name ] ) ) {
|
291 |
+
return false;
|
292 |
+
}
|
293 |
+
$cookie_elements = explode( '|', $_COOKIE[ $auth_cookie_name ] );
|
294 |
+
if ( count( $cookie_elements ) != 3 ) {
|
295 |
+
return false;
|
296 |
+
}
|
297 |
+
|
298 |
+
//SwpmLog::log_auth_debug("validate() - " . $_COOKIE[$auth_cookie_name], true);
|
299 |
+
list($username, $expiration, $hmac) = $cookie_elements;
|
300 |
+
$expired = $expiration;
|
301 |
+
// Allow a grace period for POST and AJAX requests
|
302 |
+
if ( defined( 'DOING_AJAX' ) || 'POST' == $_SERVER['REQUEST_METHOD'] ) {
|
303 |
+
$expired += HOUR_IN_SECONDS;
|
304 |
+
}
|
305 |
+
// Quick check to see if an honest cookie has expired
|
306 |
+
if ( $expired < time() ) {
|
307 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Session Expired.' ); //do_action('auth_cookie_expired', $cookie_elements);
|
308 |
+
SwpmLog::log_auth_debug( 'validate() - Session Expired', true );
|
309 |
+
return false;
|
310 |
+
}
|
311 |
+
|
312 |
+
global $wpdb;
|
313 |
+
$query = ' SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE user_name = %s';
|
314 |
+
$user = $wpdb->get_row( $wpdb->prepare( $query, $username ) );
|
315 |
+
if ( empty( $user ) ) {
|
316 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Invalid Username' );
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
|
320 |
+
$pass_frag = substr( $user->password, 8, 4 );
|
321 |
+
$key = self::b_hash( $username . $pass_frag . '|' . $expiration );
|
322 |
+
$hash = hash_hmac( 'md5', $username . '|' . $expiration, $key );
|
323 |
+
if ( $hmac != $hash ) {
|
324 |
+
$this->lastStatusMsg = SwpmUtils::_( 'Please login again.' );
|
325 |
+
SwpmLog::log_auth_debug( 'validate() - Bad Hash', true );
|
326 |
+
do_action('swpm_validate_login_hash_mismatch');
|
327 |
+
wp_logout(); //Force logout of WP user session to clear the bad hash.
|
328 |
+
return false;
|
329 |
+
}
|
330 |
+
|
331 |
+
if ( $expiration < time() ) {
|
332 |
+
$GLOBALS['login_grace_period'] = 1;
|
333 |
+
}
|
334 |
+
$this->userData = $user;
|
335 |
+
return $this->check_constraints();
|
336 |
+
}
|
337 |
+
|
338 |
+
public static function b_hash( $data, $scheme = 'auth' ) {
|
339 |
+
$salt = wp_salt( $scheme ) . 'j4H!B3TA,J4nIn4.';
|
340 |
+
return hash_hmac( 'md5', $data, $salt );
|
341 |
+
}
|
342 |
+
|
343 |
+
public function is_logged_in() {
|
344 |
+
return $this->isLoggedIn;
|
345 |
+
}
|
346 |
+
|
347 |
+
public function get( $key, $default = '' ) {
|
348 |
+
if ( isset( $this->userData->$key ) ) {
|
349 |
+
return $this->userData->$key;
|
350 |
+
}
|
351 |
+
if ( isset( $this->permitted->$key ) ) {
|
352 |
+
return $this->permitted->$key;
|
353 |
+
}
|
354 |
+
if ( ! empty( $this->permitted ) ) {
|
355 |
+
return $this->permitted->get( $key, $default );
|
356 |
+
}
|
357 |
+
return $default;
|
358 |
+
}
|
359 |
+
|
360 |
+
public function get_message() {
|
361 |
+
return $this->lastStatusMsg;
|
362 |
+
}
|
363 |
+
|
364 |
+
public function get_expire_date() {
|
365 |
+
if ( $this->isLoggedIn ) {
|
366 |
+
return SwpmUtils::get_formatted_expiry_date( $this->get( 'subscription_starts' ), $this->get( 'subscription_period' ), $this->get( 'subscription_duration_type' ) );
|
367 |
+
}
|
368 |
+
return '';
|
369 |
+
}
|
370 |
+
|
371 |
+
public function delete() {
|
372 |
+
if ( ! $this->is_logged_in() ) {
|
373 |
+
return;
|
374 |
+
}
|
375 |
+
$user_name = $this->get( 'user_name' );
|
376 |
+
$user_id = $this->get( 'member_id' );
|
377 |
+
$subscr_id = $this->get( 'subscr_id' );
|
378 |
+
$email = $this->get( 'email' );
|
379 |
+
|
380 |
+
$this->logout();
|
381 |
+
wp_clear_auth_cookie();
|
382 |
+
|
383 |
+
SwpmMembers::delete_swpm_user_by_id( $user_id );
|
384 |
+
SwpmMembers::delete_wp_user( $user_name );
|
385 |
+
}
|
386 |
+
|
387 |
+
public function reload_user_data() {
|
388 |
+
if ( ! $this->is_logged_in() ) {
|
389 |
+
return;
|
390 |
+
}
|
391 |
+
global $wpdb;
|
392 |
+
$query = 'SELECT * FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE member_id = %d';
|
393 |
+
$this->userData = $wpdb->get_row( $wpdb->prepare( $query, $this->userData->member_id ) );
|
394 |
+
}
|
395 |
+
|
396 |
+
public function is_expired_account() {
|
397 |
+
if ( ! $this->is_logged_in() ) {
|
398 |
+
return null;
|
399 |
+
}
|
400 |
+
$account_status = $this->get( 'account_state' );
|
401 |
+
if ( $account_status == 'expired' || $account_status == 'inactive' ) {
|
402 |
+
//Expired or Inactive accounts are both considered to be expired.
|
403 |
+
return true;
|
404 |
+
}
|
405 |
+
return false;
|
406 |
+
}
|
407 |
+
|
408 |
+
}
|
classes/class.swpm-form.php
CHANGED
@@ -88,7 +88,7 @@ class SwpmForm {
|
|
88 |
$this->errors['password'] = SwpmUtils::_('Password mismatch');
|
89 |
}
|
90 |
$this->sanitized['plain_password'] = $password;
|
91 |
-
$this->sanitized['password'] = SwpmUtils::encrypt_password(trim($
|
92 |
}
|
93 |
}
|
94 |
|
88 |
$this->errors['password'] = SwpmUtils::_('Password mismatch');
|
89 |
}
|
90 |
$this->sanitized['plain_password'] = $password;
|
91 |
+
$this->sanitized['password'] = SwpmUtils::encrypt_password(trim($saned));
|
92 |
}
|
93 |
}
|
94 |
|
classes/class.swpm-front-registration.php
CHANGED
@@ -221,6 +221,10 @@ class SwpmFrontRegistration extends SwpmRegistration {
|
|
221 |
unset( $member_info['plain_password'] );
|
222 |
|
223 |
if ( SwpmUtils::is_paid_registration() ) {
|
|
|
|
|
|
|
|
|
224 |
$member_info['reg_code'] = '';
|
225 |
$member_id = filter_input( INPUT_GET, 'member_id', FILTER_SANITIZE_NUMBER_INT );
|
226 |
$code = filter_input( INPUT_GET, 'code', FILTER_SANITIZE_STRING );
|
@@ -410,7 +414,7 @@ class SwpmFrontRegistration extends SwpmRegistration {
|
|
410 |
//Trigger a hook
|
411 |
$password = apply_filters( 'swpm_password_reset_generated_pass', $password );
|
412 |
|
413 |
-
$password_hash = SwpmUtils::encrypt_password( trim( $password ) );
|
414 |
$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'password' => $password_hash ), array( 'member_id' => $user->member_id ) );
|
415 |
|
416 |
//Update wp user password
|
221 |
unset( $member_info['plain_password'] );
|
222 |
|
223 |
if ( SwpmUtils::is_paid_registration() ) {
|
224 |
+
//Remove any empty values from the array. This will preserve address information if it was received via the payment gateway.
|
225 |
+
$member_info = array_filter($member_info);
|
226 |
+
|
227 |
+
//Handle DB insert for paid registration scenario.
|
228 |
$member_info['reg_code'] = '';
|
229 |
$member_id = filter_input( INPUT_GET, 'member_id', FILTER_SANITIZE_NUMBER_INT );
|
230 |
$code = filter_input( INPUT_GET, 'code', FILTER_SANITIZE_STRING );
|
414 |
//Trigger a hook
|
415 |
$password = apply_filters( 'swpm_password_reset_generated_pass', $password );
|
416 |
|
417 |
+
$password_hash = SwpmUtils::encrypt_password( trim( $password ) );
|
418 |
$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'password' => $password_hash ), array( 'member_id' => $user->member_id ) );
|
419 |
|
420 |
//Update wp user password
|
classes/class.swpm-members.php
CHANGED
@@ -59,7 +59,8 @@ class SwpmMembers extends WP_List_Table {
|
|
59 |
}
|
60 |
|
61 |
function column_default( $item, $column_name ) {
|
62 |
-
|
|
|
63 |
return $column_data;
|
64 |
}
|
65 |
|
59 |
}
|
60 |
|
61 |
function column_default( $item, $column_name ) {
|
62 |
+
$column_value = isset( $item[ $column_name ] ) ? $item[ $column_name ] : '';
|
63 |
+
$column_data = apply_filters( 'swpm_admin_members_table_column_' . $column_name, $column_value, $item );
|
64 |
return $column_data;
|
65 |
}
|
66 |
|
classes/class.swpm-utils.php
CHANGED
@@ -630,9 +630,9 @@ abstract class SwpmUtils {
|
|
630 |
}
|
631 |
|
632 |
public static function csv_equal_match( $needle, $haystack_csv ) {
|
633 |
-
//converting to lowercase
|
634 |
if($haystack_csv && strlen($haystack_csv)>0) {
|
635 |
-
|
|
|
636 |
$haystack_csv_array = explode(",",$haystack_csv);
|
637 |
|
638 |
foreach($haystack_csv_array as $value) {
|
@@ -647,9 +647,17 @@ abstract class SwpmUtils {
|
|
647 |
|
648 |
public static function csv_pattern_match( $needle, $haystack_csv ) {
|
649 |
if($haystack_csv && strlen($haystack_csv)>0) {
|
650 |
-
|
651 |
-
|
652 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
653 |
}
|
654 |
return false;
|
655 |
}
|
630 |
}
|
631 |
|
632 |
public static function csv_equal_match( $needle, $haystack_csv ) {
|
|
|
633 |
if($haystack_csv && strlen($haystack_csv)>0) {
|
634 |
+
//Converting to lowercase for better matching
|
635 |
+
$haystack_csv = strtolower($haystack_csv);
|
636 |
$haystack_csv_array = explode(",",$haystack_csv);
|
637 |
|
638 |
foreach($haystack_csv_array as $value) {
|
647 |
|
648 |
public static function csv_pattern_match( $needle, $haystack_csv ) {
|
649 |
if($haystack_csv && strlen($haystack_csv)>0) {
|
650 |
+
//For pattern match, we need to check if any of the individual pattern matches with any part/full of the entered user email address.
|
651 |
+
$user_email_address = $needle;//We need to search each pattern entry within this user email address value to see if there is any match.
|
652 |
+
$haystack_csv = strtolower($haystack_csv);
|
653 |
+
$haystack_csv_array = explode(",",$haystack_csv);
|
654 |
+
foreach($haystack_csv_array as $findme) {
|
655 |
+
$findme = trim($findme);
|
656 |
+
if(stripos($user_email_address, $findme)!==false) {
|
657 |
+
//Found a match for the pattern.
|
658 |
+
return true;
|
659 |
+
}
|
660 |
+
}
|
661 |
}
|
662 |
return false;
|
663 |
}
|
images/addons/swpm-mailerlite-integration.png
ADDED
Binary file
|
ipn/swpm-braintree-buy-now-ipn.php
CHANGED
@@ -60,11 +60,14 @@ class SwpmBraintreeBuyNowIpnHandler {
|
|
60 |
|
61 |
$braintree_merc_acc_name = get_post_meta($button_id, 'braintree_merchant_acc_name', true);
|
62 |
|
|
|
63 |
|
64 |
// Create the charge on Braintree's servers - this will charge the user's card
|
65 |
|
66 |
$nonce = sanitize_text_field($_POST['payment_method_nonce']);
|
67 |
|
|
|
|
|
68 |
$result = Braintree_Transaction::sale([
|
69 |
'amount' => $payment_amount,
|
70 |
'paymentMethodNonce' => $nonce,
|
@@ -80,7 +83,9 @@ class SwpmBraintreeBuyNowIpnHandler {
|
|
80 |
}
|
81 |
|
82 |
if (!$result->success) {
|
83 |
-
|
|
|
|
|
84 |
wp_die("Braintree transaction error occurred: " . $result->transaction->status);
|
85 |
} else {
|
86 |
|
60 |
|
61 |
$braintree_merc_acc_name = get_post_meta($button_id, 'braintree_merchant_acc_name', true);
|
62 |
|
63 |
+
|
64 |
|
65 |
// Create the charge on Braintree's servers - this will charge the user's card
|
66 |
|
67 |
$nonce = sanitize_text_field($_POST['payment_method_nonce']);
|
68 |
|
69 |
+
|
70 |
+
|
71 |
$result = Braintree_Transaction::sale([
|
72 |
'amount' => $payment_amount,
|
73 |
'paymentMethodNonce' => $nonce,
|
83 |
}
|
84 |
|
85 |
if (!$result->success) {
|
86 |
+
|
87 |
+
|
88 |
+
SwpmLog::log_simple_debug("Braintree transaction error occurred: " . $result->transaction->status . ", message: ".$result->message." , button ID: " . $button_id, false);
|
89 |
wp_die("Braintree transaction error occurred: " . $result->transaction->status);
|
90 |
} else {
|
91 |
|
ipn/swpm-stripe-sca-buy-now-ipn.php
CHANGED
@@ -1,381 +1,392 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SwpmStripeSCABuyNowIpnHandler {
|
4 |
-
|
5 |
-
public function __construct() {
|
6 |
-
//check if this is session create request
|
7 |
-
if ( wp_doing_ajax() ) {
|
8 |
-
$action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
|
9 |
-
if ( 'swpm_stripe_sca_create_checkout_session' === $action ) {
|
10 |
-
add_action( 'wp_ajax_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
|
11 |
-
add_action( 'wp_ajax_nopriv_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
|
12 |
-
}
|
13 |
-
return;
|
14 |
-
}
|
15 |
-
|
16 |
-
require_once SIMPLE_WP_MEMBERSHIP_PATH . 'ipn/swpm_handle_subsc_ipn.php';
|
17 |
-
$this->handle_stripe_ipn();
|
18 |
-
}
|
19 |
-
|
20 |
-
public function handle_stripe_ipn() {
|
21 |
-
SwpmLog::log_simple_debug( 'Stripe SCA Buy Now IPN received. Processing request...', true );
|
22 |
-
// SwpmLog::log_simple_debug(print_r($_REQUEST, true), true);//Useful for debugging purpose
|
23 |
-
|
24 |
-
// Read and sanitize the request parameters.
|
25 |
-
|
26 |
-
$ref_id = filter_input( INPUT_GET, 'ref_id', FILTER_SANITIZE_STRING );
|
27 |
-
|
28 |
-
if ( empty( $ref_id ) ) {
|
29 |
-
//no ref id provided, cannot proceed
|
30 |
-
SwpmLog::log_simple_debug( 'Fatal Error! No ref_id provied.', false );
|
31 |
-
wp_die( esc_html( 'Fatal Error! No ref_id provied.' ) );
|
32 |
-
|
33 |
-
}
|
34 |
-
|
35 |
-
$trans_info = explode( '|', $ref_id );
|
36 |
-
$button_id = isset( $trans_info[1] ) ? absint( $trans_info[1] ) : false;
|
37 |
-
|
38 |
-
// Retrieve the CPT for this button
|
39 |
-
$button_cpt = get_post( $button_id );
|
40 |
-
if ( ! $button_cpt ) {
|
41 |
-
// Fatal error. Could not find this payment button post object.
|
42 |
-
SwpmLog::log_simple_debug( 'Fatal Error! Failed to retrieve the payment button post object for the given button ID: ' . $button_id, false );
|
43 |
-
wp_die( esc_html( sprintf( 'Fatal Error! Payment button (ID: %d) does not exist. This request will fail.', $button_id ) ) );
|
44 |
-
}
|
45 |
-
|
46 |
-
$settings = SwpmSettings::get_instance();
|
47 |
-
$sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
|
48 |
-
|
49 |
-
//API keys
|
50 |
-
$api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
|
51 |
-
|
52 |
-
// Include the Stripe library.
|
53 |
-
SwpmMiscUtils::load_stripe_lib();
|
54 |
-
|
55 |
-
try {
|
56 |
-
\Stripe\Stripe::setApiKey( $api_keys['secret'] );
|
57 |
-
|
58 |
-
$events = \Stripe\Event::all(
|
59 |
-
array(
|
60 |
-
'type' => 'checkout.session.completed',
|
61 |
-
'created' => array(
|
62 |
-
'gte' => time() - 60 * 60,
|
63 |
-
),
|
64 |
-
)
|
65 |
-
);
|
66 |
-
|
67 |
-
$sess = false;
|
68 |
-
|
69 |
-
foreach ( $events->autoPagingIterator() as $event ) {
|
70 |
-
$session = $event->data->object;
|
71 |
-
if ( isset( $session->client_reference_id ) && $session->client_reference_id === $ref_id ) {
|
72 |
-
$sess = $session;
|
73 |
-
break;
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
if ( false === $sess ) {
|
78 |
-
// Can't find session.
|
79 |
-
$error_msg = sprintf( "Fatal error! Payment with ref_id %s can't be found", $ref_id );
|
80 |
-
SwpmLog::log_simple_debug( $error_msg, false );
|
81 |
-
wp_die( esc_html( $error_msg ) );
|
82 |
-
}
|
83 |
-
|
84 |
-
$pi_id = $sess->payment_intent;
|
85 |
-
|
86 |
-
$pi = \Stripe\PaymentIntent::retrieve( $pi_id );
|
87 |
-
} catch ( Exception $e ) {
|
88 |
-
$error_msg = 'Error occurred: ' . $e->getMessage();
|
89 |
-
SwpmLog::log_simple_debug( $error_msg, false );
|
90 |
-
wp_die( esc_html( $error_msg ) );
|
91 |
-
}
|
92 |
-
|
93 |
-
$charge = $pi->charges;
|
94 |
-
|
95 |
-
// Grab the charge ID and set it as the transaction ID.
|
96 |
-
$txn_id = $charge->data[0]->id;
|
97 |
-
// The charge ID can be used to retrieve the transaction details using hte following call.
|
98 |
-
// \Stripe\Charge::retrieve($charge->$data[0]->id);
|
99 |
-
|
100 |
-
//check if this payment has already been processed
|
101 |
-
$payment = get_posts(
|
102 |
-
array(
|
103 |
-
'meta_key' => 'txn_id',
|
104 |
-
'meta_value' => $txn_id,
|
105 |
-
'posts_per_page' => 1,
|
106 |
-
'offset' => 0,
|
107 |
-
'post_type' => 'swpm_transactions',
|
108 |
-
)
|
109 |
-
);
|
110 |
-
wp_reset_postdata();
|
111 |
-
|
112 |
-
if ( $payment ) {
|
113 |
-
//payment has already been processed. Redirecting user to return_url
|
114 |
-
$return_url = get_post_meta( $button_id, 'return_url', true );
|
115 |
-
if ( empty( $return_url ) ) {
|
116 |
-
$return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
|
117 |
-
}
|
118 |
-
SwpmMiscUtils::redirect_to_url( $return_url );
|
119 |
-
return;
|
120 |
-
}
|
121 |
-
|
122 |
-
$price_in_cents = floatval( $pi->amount_received );
|
123 |
-
$currency_code = strtoupper( $pi->currency );
|
124 |
-
|
125 |
-
$zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
|
126 |
-
if ( in_array( $currency_code, $zero_cents, true ) ) {
|
127 |
-
$payment_amount = $price_in_cents;
|
128 |
-
} else {
|
129 |
-
$payment_amount = $price_in_cents / 100;// The amount (in cents). This value is used in Stripe API.
|
130 |
-
}
|
131 |
-
|
132 |
-
$payment_amount = floatval( $payment_amount );
|
133 |
-
|
134 |
-
$stripe_email = $charge->data[0]->billing_details->email;
|
135 |
-
|
136 |
-
$membership_level_id = get_post_meta( $button_id, 'membership_level_id', true );
|
137 |
-
|
138 |
-
// Validate and verify some of the main values.
|
139 |
-
$true_payment_amount = get_post_meta( $button_id, 'payment_amount', true );
|
140 |
-
$true_payment_amount = apply_filters( 'swpm_payment_amount_filter', $true_payment_amount, $button_id );
|
141 |
-
$true_payment_amount = floatval( $true_payment_amount );
|
142 |
-
|
143 |
-
if ( $payment_amount !== $true_payment_amount ) {
|
144 |
-
// Fatal error. Payment amount may have been tampered with.
|
145 |
-
$error_msg = 'Fatal Error! Received payment amount (' . $payment_amount . ') does not match with the original amount (' . $true_payment_amount . ')';
|
146 |
-
SwpmLog::log_simple_debug( $error_msg, false );
|
147 |
-
wp_die( esc_html( $error_msg ) );
|
148 |
-
}
|
149 |
-
$true_currency_code = get_post_meta( $button_id, 'payment_currency', true );
|
150 |
-
if ( $currency_code !== $true_currency_code ) {
|
151 |
-
// Fatal error. Currency code may have been tampered with.
|
152 |
-
$error_msg = 'Fatal Error! Received currency code (' . $currency_code . ') does not match with the original code (' . $true_currency_code . ')';
|
153 |
-
SwpmLog::log_simple_debug( $error_msg, false );
|
154 |
-
wp_die( esc_html( $error_msg ) );
|
155 |
-
}
|
156 |
-
|
157 |
-
// Everything went ahead smoothly with the charge.
|
158 |
-
SwpmLog::log_simple_debug( 'Stripe SCA Buy Now charge successful.', true );
|
159 |
-
|
160 |
-
$user_ip = SwpmUtils::get_user_ip_address();
|
161 |
-
|
162 |
-
//Custom field data
|
163 |
-
$custom_field_value = 'subsc_ref=' . $membership_level_id;
|
164 |
-
$custom_field_value .= '&user_ip=' . $user_ip;
|
165 |
-
if ( SwpmMemberUtils::is_member_logged_in() ) {
|
166 |
-
$custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
|
167 |
-
}
|
168 |
-
$custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
|
169 |
-
|
170 |
-
$custom = $custom_field_value;
|
171 |
-
|
172 |
-
$custom_var = SwpmTransactions::parse_custom_var( $custom );
|
173 |
-
$swpm_id = isset( $custom_var['swpm_id'] ) ? $custom_var['swpm_id'] : '';
|
174 |
-
|
175 |
-
// Let's try to get first_name and last_name from full name
|
176 |
-
$name = trim( $charge->data[0]->billing_details->name );
|
177 |
-
$last_name = ( strpos( $name, ' ' ) === false ) ? '' : preg_replace( '#.*\s([\w-]*)$#', '$1', $name );
|
178 |
-
$first_name = trim( preg_replace( '#' . $last_name . '#', '', $name ) );
|
179 |
-
|
180 |
-
// Create the $ipn_data array.
|
181 |
-
$ipn_data = array();
|
182 |
-
$ipn_data['mc_gross'] = $payment_amount;
|
183 |
-
$ipn_data['first_name'] = $first_name;
|
184 |
-
$ipn_data['last_name'] = $last_name;
|
185 |
-
$ipn_data['payer_email'] = $stripe_email;
|
186 |
-
$ipn_data['membership_level'] = $membership_level_id;
|
187 |
-
$ipn_data['txn_id'] = $txn_id;
|
188 |
-
$ipn_data['subscr_id'] = $txn_id;/* Set the txn_id as subscriber_id so it is similar to PayPal buy now. Also, it can connect to the profile in the "payments" menu. */
|
189 |
-
$ipn_data['swpm_id'] = $swpm_id;
|
190 |
-
$ipn_data['ip'] = $custom_var['user_ip'];
|
191 |
-
$ipn_data['custom'] = $custom;
|
192 |
-
$ipn_data['gateway'] = 'stripe-sca';
|
193 |
-
$ipn_data['status'] = 'completed';
|
194 |
-
|
195 |
-
$bd_addr = $charge->data[0]->billing_details->address;
|
196 |
-
|
197 |
-
$ipn_data['address_street'] = isset( $bd_addr->line1 ) ? $bd_addr->line1 : '';
|
198 |
-
$ipn_data['address_city'] = isset( $bd_addr->city ) ? $bd_addr->city : '';
|
199 |
-
$ipn_data['address_state'] = isset( $bd_addr->state ) ? $bd_addr->state : '';
|
200 |
-
$ipn_data['address_zipcode'] = isset( $bd_addr->postal_code ) ? $bd_addr->postal_code : '';
|
201 |
-
$ipn_data['address_country'] = isset( $bd_addr->country ) ? $bd_addr->country : '';
|
202 |
-
|
203 |
-
$ipn_data['payment_button_id'] = $button_id;
|
204 |
-
$ipn_data['is_live'] = ! $sandbox_enabled;
|
205 |
-
|
206 |
-
// Handle the membership signup related tasks.
|
207 |
-
swpm_handle_subsc_signup_stand_alone( $ipn_data, $membership_level_id, $txn_id, $swpm_id );
|
208 |
-
|
209 |
-
// Save the transaction record
|
210 |
-
SwpmTransactions::save_txn_record( $ipn_data );
|
211 |
-
SwpmLog::log_simple_debug( 'Transaction data saved.', true );
|
212 |
-
|
213 |
-
// Trigger the stripe IPN processed action hook (so other plugins can can listen for this event).
|
214 |
-
do_action( 'swpm_stripe_sca_ipn_processed', $ipn_data );
|
215 |
-
|
216 |
-
do_action( 'swpm_payment_ipn_processed', $ipn_data );
|
217 |
-
|
218 |
-
// Redirect the user to the return URL (or to the homepage if a return URL is not specified for this payment button).
|
219 |
-
$return_url = get_post_meta( $button_id, 'return_url', true );
|
220 |
-
if ( empty( $return_url ) ) {
|
221 |
-
$return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
|
222 |
-
}
|
223 |
-
SwpmLog::log_simple_debug( 'Redirecting customer to: ' . $return_url, true );
|
224 |
-
SwpmLog::log_simple_debug( 'End of Stripe SCA Buy Now IPN processing.', true, true );
|
225 |
-
SwpmMiscUtils::redirect_to_url( $return_url );
|
226 |
-
|
227 |
-
}
|
228 |
-
|
229 |
-
public function handle_session_create() {
|
230 |
-
$button_id = filter_input( INPUT_POST, 'swpm_button_id', FILTER_SANITIZE_NUMBER_INT );
|
231 |
-
if ( empty( $button_id ) ) {
|
232 |
-
wp_send_json( array( 'error' => 'No button ID provided' ) );
|
233 |
-
}
|
234 |
-
|
235 |
-
$uniqid = filter_input( INPUT_POST, 'swpm_uniqid', FILTER_SANITIZE_STRING );
|
236 |
-
$uniqid = ! empty( $uniqid ) ? $uniqid : '';
|
237 |
-
|
238 |
-
$settings = SwpmSettings::get_instance();
|
239 |
-
$button_cpt = get_post( $button_id ); //Retrieve the CPT for this button
|
240 |
-
$item_name = htmlspecialchars( $button_cpt->post_title );
|
241 |
-
|
242 |
-
$plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
|
243 |
-
|
244 |
-
if ( empty( $plan_id ) ) {
|
245 |
-
//Payment amount and currency
|
246 |
-
$payment_amount = get_post_meta( $button_id, 'payment_amount', true );
|
247 |
-
if ( ! is_numeric( $payment_amount ) ) {
|
248 |
-
wp_send_json( array( 'error' => 'Error! The payment amount value of the button must be a numeric number. Example: 49.50' ) );
|
249 |
-
}
|
250 |
-
|
251 |
-
$payment_currency = get_post_meta( $button_id, 'payment_currency', true );
|
252 |
-
$payment_amount = round( $payment_amount, 2 ); //round the amount to 2 decimal place.
|
253 |
-
|
254 |
-
$payment_amount = apply_filters( 'swpm_payment_amount_filter', $payment_amount, $button_id );
|
255 |
-
|
256 |
-
$zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
|
257 |
-
if ( in_array( $payment_currency, $zero_cents ) ) {
|
258 |
-
//this is zero-cents currency, amount shouldn't be multiplied by 100
|
259 |
-
$price_in_cents = $payment_amount;
|
260 |
-
} else {
|
261 |
-
$price_in_cents = $payment_amount * 100; //The amount (in cents). This value is passed to Stripe API.
|
262 |
-
}
|
263 |
-
$payment_amount_formatted = SwpmMiscUtils::format_money( $payment_amount, $payment_currency );
|
264 |
-
}
|
265 |
-
|
266 |
-
//$button_image_url = get_post_meta($button_id, 'button_image_url', true);//Stripe doesn't currenty support button image for their standard checkout.
|
267 |
-
//User's IP address
|
268 |
-
$user_ip = SwpmUtils::get_user_ip_address();
|
269 |
-
$_SESSION['swpm_payment_button_interaction'] = $user_ip;
|
270 |
-
|
271 |
-
//Custom field data
|
272 |
-
$custom_field_value = 'subsc_ref=' . $membership_level_id;
|
273 |
-
$custom_field_value .= '&user_ip=' . $user_ip;
|
274 |
-
if ( SwpmMemberUtils::is_member_logged_in() ) {
|
275 |
-
$custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
|
276 |
-
}
|
277 |
-
$custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
|
278 |
-
|
279 |
-
//Sandbox settings
|
280 |
-
$sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
|
281 |
-
|
282 |
-
//API keys
|
283 |
-
$api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
|
284 |
-
|
285 |
-
//Billing address
|
286 |
-
$billing_address = isset( $args['billing_address'] ) ? '1' : '';
|
287 |
-
//By default don't show the billing address in the checkout form.
|
288 |
-
//if billing_address parameter is not present in the shortcode, let's check button option
|
289 |
-
if ( $billing_address === '' ) {
|
290 |
-
$collect_address = get_post_meta( $button_id, 'stripe_collect_address', true );
|
291 |
-
if ( $collect_address === '1' ) {
|
292 |
-
//Collect Address enabled in button settings
|
293 |
-
$billing_address = 1;
|
294 |
-
}
|
295 |
-
}
|
296 |
-
|
297 |
-
$ref_id = 'swpm_' . $uniqid . '|' . $button_id;
|
298 |
-
|
299 |
-
//Return, cancel, notifiy URLs
|
300 |
-
if ( empty( $plan_id ) ) {
|
301 |
-
$notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=%s', $ref_id );
|
302 |
-
} else {
|
303 |
-
$notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=%s', $ref_id );
|
304 |
-
}
|
305 |
-
|
306 |
-
$current_url_posted = filter_input( INPUT_POST, 'swpm_page_url', FILTER_SANITIZE_URL );
|
307 |
-
|
308 |
-
$current_url = ! empty( $current_url_posted ) ? $current_url_posted : SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
|
309 |
-
|
310 |
-
//prefill member email
|
311 |
-
$prefill_member_email = $settings->get_value( 'stripe-prefill-member-email' );
|
312 |
-
|
313 |
-
if ( $prefill_member_email ) {
|
314 |
-
$auth = SwpmAuth::get_instance();
|
315 |
-
$member_email = $auth->get( 'email' );
|
316 |
-
}
|
317 |
-
|
318 |
-
SwpmMiscUtils::load_stripe_lib();
|
319 |
-
|
320 |
-
try {
|
321 |
-
\Stripe\Stripe::setApiKey( $api_keys['secret'] );
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
'
|
328 |
-
'
|
329 |
-
'
|
330 |
-
|
331 |
-
|
332 |
-
'
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
'
|
345 |
-
'
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
'
|
351 |
-
'
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
$
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SwpmStripeSCABuyNowIpnHandler {
|
4 |
+
|
5 |
+
public function __construct() {
|
6 |
+
//check if this is session create request
|
7 |
+
if ( wp_doing_ajax() ) {
|
8 |
+
$action = filter_input( INPUT_POST, 'action', FILTER_SANITIZE_STRING );
|
9 |
+
if ( 'swpm_stripe_sca_create_checkout_session' === $action ) {
|
10 |
+
add_action( 'wp_ajax_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
|
11 |
+
add_action( 'wp_ajax_nopriv_swpm_stripe_sca_create_checkout_session', array( $this, 'handle_session_create' ) );
|
12 |
+
}
|
13 |
+
return;
|
14 |
+
}
|
15 |
+
|
16 |
+
require_once SIMPLE_WP_MEMBERSHIP_PATH . 'ipn/swpm_handle_subsc_ipn.php';
|
17 |
+
$this->handle_stripe_ipn();
|
18 |
+
}
|
19 |
+
|
20 |
+
public function handle_stripe_ipn() {
|
21 |
+
SwpmLog::log_simple_debug( 'Stripe SCA Buy Now IPN received. Processing request...', true );
|
22 |
+
// SwpmLog::log_simple_debug(print_r($_REQUEST, true), true);//Useful for debugging purpose
|
23 |
+
|
24 |
+
// Read and sanitize the request parameters.
|
25 |
+
|
26 |
+
$ref_id = filter_input( INPUT_GET, 'ref_id', FILTER_SANITIZE_STRING );
|
27 |
+
|
28 |
+
if ( empty( $ref_id ) ) {
|
29 |
+
//no ref id provided, cannot proceed
|
30 |
+
SwpmLog::log_simple_debug( 'Fatal Error! No ref_id provied.', false );
|
31 |
+
wp_die( esc_html( 'Fatal Error! No ref_id provied.' ) );
|
32 |
+
|
33 |
+
}
|
34 |
+
|
35 |
+
$trans_info = explode( '|', $ref_id );
|
36 |
+
$button_id = isset( $trans_info[1] ) ? absint( $trans_info[1] ) : false;
|
37 |
+
|
38 |
+
// Retrieve the CPT for this button
|
39 |
+
$button_cpt = get_post( $button_id );
|
40 |
+
if ( ! $button_cpt ) {
|
41 |
+
// Fatal error. Could not find this payment button post object.
|
42 |
+
SwpmLog::log_simple_debug( 'Fatal Error! Failed to retrieve the payment button post object for the given button ID: ' . $button_id, false );
|
43 |
+
wp_die( esc_html( sprintf( 'Fatal Error! Payment button (ID: %d) does not exist. This request will fail.', $button_id ) ) );
|
44 |
+
}
|
45 |
+
|
46 |
+
$settings = SwpmSettings::get_instance();
|
47 |
+
$sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
|
48 |
+
|
49 |
+
//API keys
|
50 |
+
$api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
|
51 |
+
|
52 |
+
// Include the Stripe library.
|
53 |
+
SwpmMiscUtils::load_stripe_lib();
|
54 |
+
|
55 |
+
try {
|
56 |
+
\Stripe\Stripe::setApiKey( $api_keys['secret'] );
|
57 |
+
|
58 |
+
$events = \Stripe\Event::all(
|
59 |
+
array(
|
60 |
+
'type' => 'checkout.session.completed',
|
61 |
+
'created' => array(
|
62 |
+
'gte' => time() - 60 * 60,
|
63 |
+
),
|
64 |
+
)
|
65 |
+
);
|
66 |
+
|
67 |
+
$sess = false;
|
68 |
+
|
69 |
+
foreach ( $events->autoPagingIterator() as $event ) {
|
70 |
+
$session = $event->data->object;
|
71 |
+
if ( isset( $session->client_reference_id ) && $session->client_reference_id === $ref_id ) {
|
72 |
+
$sess = $session;
|
73 |
+
break;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
if ( false === $sess ) {
|
78 |
+
// Can't find session.
|
79 |
+
$error_msg = sprintf( "Fatal error! Payment with ref_id %s can't be found", $ref_id );
|
80 |
+
SwpmLog::log_simple_debug( $error_msg, false );
|
81 |
+
wp_die( esc_html( $error_msg ) );
|
82 |
+
}
|
83 |
+
|
84 |
+
$pi_id = $sess->payment_intent;
|
85 |
+
|
86 |
+
$pi = \Stripe\PaymentIntent::retrieve( $pi_id );
|
87 |
+
} catch ( Exception $e ) {
|
88 |
+
$error_msg = 'Error occurred: ' . $e->getMessage();
|
89 |
+
SwpmLog::log_simple_debug( $error_msg, false );
|
90 |
+
wp_die( esc_html( $error_msg ) );
|
91 |
+
}
|
92 |
+
|
93 |
+
$charge = $pi->charges;
|
94 |
+
|
95 |
+
// Grab the charge ID and set it as the transaction ID.
|
96 |
+
$txn_id = $charge->data[0]->id;
|
97 |
+
// The charge ID can be used to retrieve the transaction details using hte following call.
|
98 |
+
// \Stripe\Charge::retrieve($charge->$data[0]->id);
|
99 |
+
|
100 |
+
//check if this payment has already been processed
|
101 |
+
$payment = get_posts(
|
102 |
+
array(
|
103 |
+
'meta_key' => 'txn_id',
|
104 |
+
'meta_value' => $txn_id,
|
105 |
+
'posts_per_page' => 1,
|
106 |
+
'offset' => 0,
|
107 |
+
'post_type' => 'swpm_transactions',
|
108 |
+
)
|
109 |
+
);
|
110 |
+
wp_reset_postdata();
|
111 |
+
|
112 |
+
if ( $payment ) {
|
113 |
+
//payment has already been processed. Redirecting user to return_url
|
114 |
+
$return_url = get_post_meta( $button_id, 'return_url', true );
|
115 |
+
if ( empty( $return_url ) ) {
|
116 |
+
$return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
|
117 |
+
}
|
118 |
+
SwpmMiscUtils::redirect_to_url( $return_url );
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
|
122 |
+
$price_in_cents = floatval( $pi->amount_received );
|
123 |
+
$currency_code = strtoupper( $pi->currency );
|
124 |
+
|
125 |
+
$zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
|
126 |
+
if ( in_array( $currency_code, $zero_cents, true ) ) {
|
127 |
+
$payment_amount = $price_in_cents;
|
128 |
+
} else {
|
129 |
+
$payment_amount = $price_in_cents / 100;// The amount (in cents). This value is used in Stripe API.
|
130 |
+
}
|
131 |
+
|
132 |
+
$payment_amount = floatval( $payment_amount );
|
133 |
+
|
134 |
+
$stripe_email = $charge->data[0]->billing_details->email;
|
135 |
+
|
136 |
+
$membership_level_id = get_post_meta( $button_id, 'membership_level_id', true );
|
137 |
+
|
138 |
+
// Validate and verify some of the main values.
|
139 |
+
$true_payment_amount = get_post_meta( $button_id, 'payment_amount', true );
|
140 |
+
$true_payment_amount = apply_filters( 'swpm_payment_amount_filter', $true_payment_amount, $button_id );
|
141 |
+
$true_payment_amount = floatval( $true_payment_amount );
|
142 |
+
|
143 |
+
if ( $payment_amount !== $true_payment_amount ) {
|
144 |
+
// Fatal error. Payment amount may have been tampered with.
|
145 |
+
$error_msg = 'Fatal Error! Received payment amount (' . $payment_amount . ') does not match with the original amount (' . $true_payment_amount . ')';
|
146 |
+
SwpmLog::log_simple_debug( $error_msg, false );
|
147 |
+
wp_die( esc_html( $error_msg ) );
|
148 |
+
}
|
149 |
+
$true_currency_code = get_post_meta( $button_id, 'payment_currency', true );
|
150 |
+
if ( $currency_code !== $true_currency_code ) {
|
151 |
+
// Fatal error. Currency code may have been tampered with.
|
152 |
+
$error_msg = 'Fatal Error! Received currency code (' . $currency_code . ') does not match with the original code (' . $true_currency_code . ')';
|
153 |
+
SwpmLog::log_simple_debug( $error_msg, false );
|
154 |
+
wp_die( esc_html( $error_msg ) );
|
155 |
+
}
|
156 |
+
|
157 |
+
// Everything went ahead smoothly with the charge.
|
158 |
+
SwpmLog::log_simple_debug( 'Stripe SCA Buy Now charge successful.', true );
|
159 |
+
|
160 |
+
$user_ip = SwpmUtils::get_user_ip_address();
|
161 |
+
|
162 |
+
//Custom field data
|
163 |
+
$custom_field_value = 'subsc_ref=' . $membership_level_id;
|
164 |
+
$custom_field_value .= '&user_ip=' . $user_ip;
|
165 |
+
if ( SwpmMemberUtils::is_member_logged_in() ) {
|
166 |
+
$custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
|
167 |
+
}
|
168 |
+
$custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
|
169 |
+
|
170 |
+
$custom = $custom_field_value;
|
171 |
+
|
172 |
+
$custom_var = SwpmTransactions::parse_custom_var( $custom );
|
173 |
+
$swpm_id = isset( $custom_var['swpm_id'] ) ? $custom_var['swpm_id'] : '';
|
174 |
+
|
175 |
+
// Let's try to get first_name and last_name from full name
|
176 |
+
$name = trim( $charge->data[0]->billing_details->name );
|
177 |
+
$last_name = ( strpos( $name, ' ' ) === false ) ? '' : preg_replace( '#.*\s([\w-]*)$#', '$1', $name );
|
178 |
+
$first_name = trim( preg_replace( '#' . $last_name . '#', '', $name ) );
|
179 |
+
|
180 |
+
// Create the $ipn_data array.
|
181 |
+
$ipn_data = array();
|
182 |
+
$ipn_data['mc_gross'] = $payment_amount;
|
183 |
+
$ipn_data['first_name'] = $first_name;
|
184 |
+
$ipn_data['last_name'] = $last_name;
|
185 |
+
$ipn_data['payer_email'] = $stripe_email;
|
186 |
+
$ipn_data['membership_level'] = $membership_level_id;
|
187 |
+
$ipn_data['txn_id'] = $txn_id;
|
188 |
+
$ipn_data['subscr_id'] = $txn_id;/* Set the txn_id as subscriber_id so it is similar to PayPal buy now. Also, it can connect to the profile in the "payments" menu. */
|
189 |
+
$ipn_data['swpm_id'] = $swpm_id;
|
190 |
+
$ipn_data['ip'] = $custom_var['user_ip'];
|
191 |
+
$ipn_data['custom'] = $custom;
|
192 |
+
$ipn_data['gateway'] = 'stripe-sca';
|
193 |
+
$ipn_data['status'] = 'completed';
|
194 |
+
|
195 |
+
$bd_addr = $charge->data[0]->billing_details->address;
|
196 |
+
|
197 |
+
$ipn_data['address_street'] = isset( $bd_addr->line1 ) ? $bd_addr->line1 : '';
|
198 |
+
$ipn_data['address_city'] = isset( $bd_addr->city ) ? $bd_addr->city : '';
|
199 |
+
$ipn_data['address_state'] = isset( $bd_addr->state ) ? $bd_addr->state : '';
|
200 |
+
$ipn_data['address_zipcode'] = isset( $bd_addr->postal_code ) ? $bd_addr->postal_code : '';
|
201 |
+
$ipn_data['address_country'] = isset( $bd_addr->country ) ? $bd_addr->country : '';
|
202 |
+
|
203 |
+
$ipn_data['payment_button_id'] = $button_id;
|
204 |
+
$ipn_data['is_live'] = ! $sandbox_enabled;
|
205 |
+
|
206 |
+
// Handle the membership signup related tasks.
|
207 |
+
swpm_handle_subsc_signup_stand_alone( $ipn_data, $membership_level_id, $txn_id, $swpm_id );
|
208 |
+
|
209 |
+
// Save the transaction record
|
210 |
+
SwpmTransactions::save_txn_record( $ipn_data );
|
211 |
+
SwpmLog::log_simple_debug( 'Transaction data saved.', true );
|
212 |
+
|
213 |
+
// Trigger the stripe IPN processed action hook (so other plugins can can listen for this event).
|
214 |
+
do_action( 'swpm_stripe_sca_ipn_processed', $ipn_data );
|
215 |
+
|
216 |
+
do_action( 'swpm_payment_ipn_processed', $ipn_data );
|
217 |
+
|
218 |
+
// Redirect the user to the return URL (or to the homepage if a return URL is not specified for this payment button).
|
219 |
+
$return_url = get_post_meta( $button_id, 'return_url', true );
|
220 |
+
if ( empty( $return_url ) ) {
|
221 |
+
$return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
|
222 |
+
}
|
223 |
+
SwpmLog::log_simple_debug( 'Redirecting customer to: ' . $return_url, true );
|
224 |
+
SwpmLog::log_simple_debug( 'End of Stripe SCA Buy Now IPN processing.', true, true );
|
225 |
+
SwpmMiscUtils::redirect_to_url( $return_url );
|
226 |
+
|
227 |
+
}
|
228 |
+
|
229 |
+
public function handle_session_create() {
|
230 |
+
$button_id = filter_input( INPUT_POST, 'swpm_button_id', FILTER_SANITIZE_NUMBER_INT );
|
231 |
+
if ( empty( $button_id ) ) {
|
232 |
+
wp_send_json( array( 'error' => 'No button ID provided' ) );
|
233 |
+
}
|
234 |
+
|
235 |
+
$uniqid = filter_input( INPUT_POST, 'swpm_uniqid', FILTER_SANITIZE_STRING );
|
236 |
+
$uniqid = ! empty( $uniqid ) ? $uniqid : '';
|
237 |
+
|
238 |
+
$settings = SwpmSettings::get_instance();
|
239 |
+
$button_cpt = get_post( $button_id ); //Retrieve the CPT for this button
|
240 |
+
$item_name = htmlspecialchars( $button_cpt->post_title );
|
241 |
+
|
242 |
+
$plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
|
243 |
+
|
244 |
+
if ( empty( $plan_id ) ) {
|
245 |
+
//Payment amount and currency
|
246 |
+
$payment_amount = get_post_meta( $button_id, 'payment_amount', true );
|
247 |
+
if ( ! is_numeric( $payment_amount ) ) {
|
248 |
+
wp_send_json( array( 'error' => 'Error! The payment amount value of the button must be a numeric number. Example: 49.50' ) );
|
249 |
+
}
|
250 |
+
|
251 |
+
$payment_currency = get_post_meta( $button_id, 'payment_currency', true );
|
252 |
+
$payment_amount = round( $payment_amount, 2 ); //round the amount to 2 decimal place.
|
253 |
+
|
254 |
+
$payment_amount = apply_filters( 'swpm_payment_amount_filter', $payment_amount, $button_id );
|
255 |
+
|
256 |
+
$zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
|
257 |
+
if ( in_array( $payment_currency, $zero_cents ) ) {
|
258 |
+
//this is zero-cents currency, amount shouldn't be multiplied by 100
|
259 |
+
$price_in_cents = $payment_amount;
|
260 |
+
} else {
|
261 |
+
$price_in_cents = $payment_amount * 100; //The amount (in cents). This value is passed to Stripe API.
|
262 |
+
}
|
263 |
+
$payment_amount_formatted = SwpmMiscUtils::format_money( $payment_amount, $payment_currency );
|
264 |
+
}
|
265 |
+
|
266 |
+
//$button_image_url = get_post_meta($button_id, 'button_image_url', true);//Stripe doesn't currenty support button image for their standard checkout.
|
267 |
+
//User's IP address
|
268 |
+
$user_ip = SwpmUtils::get_user_ip_address();
|
269 |
+
$_SESSION['swpm_payment_button_interaction'] = $user_ip;
|
270 |
+
|
271 |
+
//Custom field data
|
272 |
+
$custom_field_value = 'subsc_ref=' . $membership_level_id;
|
273 |
+
$custom_field_value .= '&user_ip=' . $user_ip;
|
274 |
+
if ( SwpmMemberUtils::is_member_logged_in() ) {
|
275 |
+
$custom_field_value .= '&swpm_id=' . SwpmMemberUtils::get_logged_in_members_id();
|
276 |
+
}
|
277 |
+
$custom_field_value = apply_filters( 'swpm_custom_field_value_filter', $custom_field_value );
|
278 |
+
|
279 |
+
//Sandbox settings
|
280 |
+
$sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
|
281 |
+
|
282 |
+
//API keys
|
283 |
+
$api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
|
284 |
+
|
285 |
+
//Billing address
|
286 |
+
$billing_address = isset( $args['billing_address'] ) ? '1' : '';
|
287 |
+
//By default don't show the billing address in the checkout form.
|
288 |
+
//if billing_address parameter is not present in the shortcode, let's check button option
|
289 |
+
if ( $billing_address === '' ) {
|
290 |
+
$collect_address = get_post_meta( $button_id, 'stripe_collect_address', true );
|
291 |
+
if ( $collect_address === '1' ) {
|
292 |
+
//Collect Address enabled in button settings
|
293 |
+
$billing_address = 1;
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
$ref_id = 'swpm_' . $uniqid . '|' . $button_id;
|
298 |
+
|
299 |
+
//Return, cancel, notifiy URLs
|
300 |
+
if ( empty( $plan_id ) ) {
|
301 |
+
$notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=%s', $ref_id );
|
302 |
+
} else {
|
303 |
+
$notify_url = sprintf( SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=%s', $ref_id );
|
304 |
+
}
|
305 |
+
|
306 |
+
$current_url_posted = filter_input( INPUT_POST, 'swpm_page_url', FILTER_SANITIZE_URL );
|
307 |
+
|
308 |
+
$current_url = ! empty( $current_url_posted ) ? $current_url_posted : SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
|
309 |
+
|
310 |
+
//prefill member email
|
311 |
+
$prefill_member_email = $settings->get_value( 'stripe-prefill-member-email' );
|
312 |
+
|
313 |
+
if ( $prefill_member_email ) {
|
314 |
+
$auth = SwpmAuth::get_instance();
|
315 |
+
$member_email = $auth->get( 'email' );
|
316 |
+
}
|
317 |
+
|
318 |
+
SwpmMiscUtils::load_stripe_lib();
|
319 |
+
|
320 |
+
try {
|
321 |
+
\Stripe\Stripe::setApiKey( $api_keys['secret'] );
|
322 |
+
\Stripe\Stripe::setApiVersion("2022-08-01");
|
323 |
+
|
324 |
+
if ( empty( $plan_id ) ) {
|
325 |
+
//this is one-off payment
|
326 |
+
$opts = array(
|
327 |
+
'payment_method_types' => array( 'card' ),
|
328 |
+
'client_reference_id' => $ref_id,
|
329 |
+
'billing_address_collection' => $billing_address ? 'required' : 'auto',
|
330 |
+
'line_items' => array(
|
331 |
+
array(
|
332 |
+
'price_data' => array(
|
333 |
+
'currency' => $payment_currency,
|
334 |
+
'unit_amount' => $price_in_cents,
|
335 |
+
'product_data' => array(
|
336 |
+
'name' => $item_name,
|
337 |
+
'description' => $payment_amount_formatted,
|
338 |
+
),
|
339 |
+
),
|
340 |
+
'quantity' => 1
|
341 |
+
)
|
342 |
+
),
|
343 |
+
'mode' => 'payment',
|
344 |
+
'success_url' => $notify_url,
|
345 |
+
'cancel_url' => $current_url,
|
346 |
+
);
|
347 |
+
} else {
|
348 |
+
//this is subscription payment
|
349 |
+
$opts = array(
|
350 |
+
'payment_method_types' => array('card'),
|
351 |
+
'client_reference_id' => $ref_id,
|
352 |
+
'billing_address_collection' => $billing_address ? 'required' : 'auto',
|
353 |
+
'line_items' => array(
|
354 |
+
array(
|
355 |
+
'price' => $plan_id,
|
356 |
+
'quantity' => 1
|
357 |
+
),
|
358 |
+
|
359 |
+
),
|
360 |
+
'mode' => 'subscription',
|
361 |
+
'success_url' => $notify_url,
|
362 |
+
'cancel_url' => $current_url,
|
363 |
+
);
|
364 |
+
|
365 |
+
$trial_period = get_post_meta( $button_id, 'stripe_trial_period', true );
|
366 |
+
$trial_period = absint( $trial_period );
|
367 |
+
if ( $trial_period ) {
|
368 |
+
$opts['subscription_data']['trial_period_days'] = $trial_period;
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
if ( ! empty( $item_logo ) ) {
|
373 |
+
$opts['line_items'][0]["product_data"]['images'] = array( $item_logo );
|
374 |
+
}
|
375 |
+
|
376 |
+
if ( ! empty( $member_email ) ) {
|
377 |
+
$opts['customer_email'] = $member_email;
|
378 |
+
}
|
379 |
+
|
380 |
+
$opts = apply_filters( 'swpm_stripe_sca_session_opts', $opts, $button_id );
|
381 |
+
|
382 |
+
$session = \Stripe\Checkout\Session::create( $opts );
|
383 |
+
} catch ( Exception $e ) {
|
384 |
+
$err = $e->getMessage();
|
385 |
+
wp_send_json( array( 'error' => 'Error occurred: ' . $err ) );
|
386 |
+
}
|
387 |
+
wp_send_json( array( 'session_id' => $session->id ) );
|
388 |
+
}
|
389 |
+
|
390 |
+
}
|
391 |
+
|
392 |
+
new SwpmStripeSCABuyNowIpnHandler();
|
readme.txt
CHANGED
@@ -4,8 +4,8 @@ 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: 5.0
|
6 |
Requires PHP: 5.6
|
7 |
-
Tested up to: 6.
|
8 |
-
Stable tag: 4.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -163,6 +163,19 @@ https://simple-membership-plugin.com/
|
|
163 |
|
164 |
== Changelog ==
|
165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
= 4.1.8 =
|
167 |
- Improved the view debug log operation to check if the file exists before trying to open the file. If the file doesn't exist, it will show a message to reset the debug file.
|
168 |
|
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: 5.0
|
6 |
Requires PHP: 5.6
|
7 |
+
Tested up to: 6.1
|
8 |
+
Stable tag: 4.2.0
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
163 |
|
164 |
== Changelog ==
|
165 |
|
166 |
+
= 4.2.0 =
|
167 |
+
- Braintree SDK updated for the Braintree payment gateway.
|
168 |
+
- Google reCAPTCHA enterprise option is now [available as a free addon](https://simple-membership-plugin.com/simple-membership-google-recaptcha-enterprise-option/).
|
169 |
+
|
170 |
+
= 4.1.9 =
|
171 |
+
- Stripe Button's code updated to use the latest Stripe API version.
|
172 |
+
- Allow apostrophe character in the email address field of the registration form.
|
173 |
+
- Preserve address information of a profile when submitting the registration form (if the data was received from the payment gateway).
|
174 |
+
- Added a workaround for sites using the Batcache caching system.
|
175 |
+
- Updated the swpm_admin_members_table_column_<column_name> filter hook to check if the column value exists.
|
176 |
+
- Fixed an issue with the email address whitelisting pattern feature.
|
177 |
+
- Improved how the current_page URL value is retrieved for the Stripe payment buttons.
|
178 |
+
|
179 |
= 4.1.8 =
|
180 |
- Improved the view debug log operation to check if the file exists before trying to open the file. If the file doesn't exist, it will show a message to reset the debug file.
|
181 |
|
simple-wp-membership.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Simple WordPress Membership
|
4 |
-
Version: 4.
|
5 |
Plugin URI: https://simple-membership-plugin.com/
|
6 |
Author: smp7, wp.insider
|
7 |
Author URI: https://simple-membership-plugin.com/
|
@@ -20,7 +20,7 @@ include_once( 'classes/class.simple-wp-membership.php' );
|
|
20 |
include_once( 'classes/class.swpm-cronjob.php' );
|
21 |
include_once( 'swpm-compat.php' );
|
22 |
|
23 |
-
define( 'SIMPLE_WP_MEMBERSHIP_VER', '4.
|
24 |
define( 'SIMPLE_WP_MEMBERSHIP_DB_VER', '1.3' );
|
25 |
define( 'SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL', home_url() );
|
26 |
define( 'SIMPLE_WP_MEMBERSHIP_PATH', dirname( __FILE__ ) . '/' );
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Simple WordPress Membership
|
4 |
+
Version: 4.2.0
|
5 |
Plugin URI: https://simple-membership-plugin.com/
|
6 |
Author: smp7, wp.insider
|
7 |
Author URI: https://simple-membership-plugin.com/
|
20 |
include_once( 'classes/class.swpm-cronjob.php' );
|
21 |
include_once( 'swpm-compat.php' );
|
22 |
|
23 |
+
define( 'SIMPLE_WP_MEMBERSHIP_VER', '4.2.0' );
|
24 |
define( 'SIMPLE_WP_MEMBERSHIP_DB_VER', '1.3' );
|
25 |
define( 'SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL', home_url() );
|
26 |
define( 'SIMPLE_WP_MEMBERSHIP_PATH', dirname( __FILE__ ) . '/' );
|
views/admin_add_ons_page.php
CHANGED
@@ -238,6 +238,14 @@ echo '<link type="text/css" rel="stylesheet" href="' . SIMPLE_WP_MEMBERSHIP_URL
|
|
238 |
);
|
239 |
array_push($addons_data, $addon_28);
|
240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
/*** Show the addons list ***/
|
242 |
foreach ($addons_data as $addon) {
|
243 |
$output .= '<div class="swpm_addon_item_canvas">';
|
238 |
);
|
239 |
array_push($addons_data, $addon_28);
|
240 |
|
241 |
+
$addon_29 = array(
|
242 |
+
'name' => 'MailerLite Integration',
|
243 |
+
'thumbnail' => SIMPLE_WP_MEMBERSHIP_URL . '/images/addons/swpm-mailerlite-integration.png',
|
244 |
+
'description' => 'Allows you to automatically signup your members to a group in your MailerLite account.',
|
245 |
+
'page_url' => 'https://simple-membership-plugin.com/simple-membership-mailerlite-integration-addon/',
|
246 |
+
);
|
247 |
+
array_push($addons_data, $addon_29);
|
248 |
+
|
249 |
/*** Show the addons list ***/
|
250 |
foreach ($addons_data as $addon) {
|
251 |
$output .= '<div class="swpm_addon_item_canvas">';
|
views/payments/payment-gateway/braintree_button_shortcode_view.php
CHANGED
@@ -40,7 +40,7 @@ function swpm_render_braintree_buy_now_button_sc_output($button_code, $args)
|
|
40 |
$payment_amount = round($payment_amount, 2); //round the amount to 2 decimal place.
|
41 |
$payment_currency = get_post_meta($button_id, 'currency_code', true);
|
42 |
|
43 |
-
$payment_amount_formatted = SwpmMiscUtils::format_money($payment_amount
|
44 |
|
45 |
//Return, cancel, notifiy URLs
|
46 |
$return_url = get_post_meta($button_id, 'return_url', true);
|
@@ -107,54 +107,89 @@ function swpm_render_braintree_buy_now_button_sc_output($button_code, $args)
|
|
107 |
if (!empty($coupon_input)) {
|
108 |
$output .= $coupon_input;
|
109 |
}
|
110 |
-
$output .= '<div id="swpm-braintree-amount-container-' . $uniqid . '" class="swpm-braintree-amount-container"><p>' . $payment_amount_formatted.'</p></div>';
|
111 |
$output .= '</div>';
|
112 |
$output .= '<button id="swpm-show-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-show-form-button-' . $button_id . ' ' . $class . '" type="button" onclick="swpm_braintree_show_form_' . $uniqid . '();"><span>' . $button_text . '</span></button>';
|
113 |
$output .= '<button id="swpm-submit-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-submit-form-button-' . $button_id . ' ' . $class . '" type="submit" style="display: none;"><span>' . $button_text . '</span></button>';
|
114 |
-
|
|
|
|
|
|
|
|
|
115 |
ob_start();
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
117 |
<script>
|
118 |
function swpm_braintree_show_form__uniqid_() {
|
119 |
document.getElementById('swpm-show-form-btn-_uniqid_').style.display = "none";
|
120 |
document.getElementById('swpm-submit-form-btn-_uniqid_').style.display = "block";
|
121 |
document.getElementById('swpm-form-cont-_uniqid_').style.display = "block";
|
122 |
var clientToken = '_token_';
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = false;
|
150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
}
|
|
|
|
|
|
|
152 |
});
|
153 |
-
}
|
154 |
});
|
|
|
155 |
}
|
156 |
</script>
|
157 |
-
|
158 |
|
159 |
$scr = ob_get_clean();
|
160 |
$scr = str_replace(array('_uniqid_', '_token_', '_amount_'), array($uniqid, $clientToken, $payment_amount), $scr);
|
40 |
$payment_amount = round($payment_amount, 2); //round the amount to 2 decimal place.
|
41 |
$payment_currency = get_post_meta($button_id, 'currency_code', true);
|
42 |
|
43 |
+
$payment_amount_formatted = SwpmMiscUtils::format_money($payment_amount, $payment_currency);
|
44 |
|
45 |
//Return, cancel, notifiy URLs
|
46 |
$return_url = get_post_meta($button_id, 'return_url', true);
|
107 |
if (!empty($coupon_input)) {
|
108 |
$output .= $coupon_input;
|
109 |
}
|
110 |
+
$output .= '<div id="swpm-braintree-amount-container-' . $uniqid . '" class="swpm-braintree-amount-container"><p>' . $payment_amount_formatted . '</p></div>';
|
111 |
$output .= '</div>';
|
112 |
$output .= '<button id="swpm-show-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-show-form-button-' . $button_id . ' ' . $class . '" type="button" onclick="swpm_braintree_show_form_' . $uniqid . '();"><span>' . $button_text . '</span></button>';
|
113 |
$output .= '<button id="swpm-submit-form-btn-' . $uniqid . '" class="swpm-braintree-pay-now-button swpm-braintree-submit-form-button-' . $button_id . ' ' . $class . '" type="submit" style="display: none;"><span>' . $button_text . '</span></button>';
|
114 |
+
|
115 |
+
$output .= '<script src="https://js.braintreegateway.com/web/3.88.2/js/client.min.js"></script>';
|
116 |
+
$output .= '<script src="https://js.braintreegateway.com/web/dropin/1.33.4/js/dropin.min.js"></script>';
|
117 |
+
|
118 |
+
|
119 |
ob_start();
|
120 |
+
?>
|
121 |
+
<style>
|
122 |
+
.braintree-sheet__content--form .braintree-form__flexible-fields{
|
123 |
+
display:inherit;
|
124 |
+
}
|
125 |
+
</style>
|
126 |
<script>
|
127 |
function swpm_braintree_show_form__uniqid_() {
|
128 |
document.getElementById('swpm-show-form-btn-_uniqid_').style.display = "none";
|
129 |
document.getElementById('swpm-submit-form-btn-_uniqid_').style.display = "block";
|
130 |
document.getElementById('swpm-form-cont-_uniqid_').style.display = "block";
|
131 |
var clientToken = '_token_';
|
132 |
+
var submitButton = document.getElementById('swpm-submit-form-btn-_uniqid_');
|
133 |
+
var form = document.getElementById('swpm-braintree-payment-form-_uniqid_');
|
134 |
+
var additional_fields = document.getElementById('swpm-braintree-additional-fields-container-_uniqid_');
|
135 |
+
var amount = form.querySelector('[name="item_price"]').value;
|
136 |
+
|
137 |
+
//creating dropin
|
138 |
+
braintree.dropin.create({
|
139 |
+
authorization: clientToken,
|
140 |
+
container: '#swpm-form-cont-_uniqid_',
|
141 |
+
threeDSecure: true
|
142 |
+
}, function(err, dropinInstance) {
|
143 |
+
if (err) {
|
144 |
+
// Handle any errors that might've occurred when creating Drop-in
|
145 |
+
console.error(err);
|
146 |
+
alert("Error creating payment form. Try again or check console logs");
|
147 |
+
return;
|
148 |
+
}
|
149 |
+
|
150 |
+
document.getElementById('swpm-braintree-additional-fields-container-_uniqid_').style.display = "block";
|
151 |
+
|
152 |
+
submitButton.addEventListener('click', function(e) {
|
153 |
+
e.preventDefault();
|
154 |
+
|
155 |
+
var first_name = additional_fields.querySelector('[name="first_name"]').value;
|
156 |
+
var last_name = additional_fields.querySelector('[name="last_name"]').value;
|
157 |
+
var member_email = additional_fields.querySelector('[name="member_email"]').value;
|
158 |
+
|
159 |
+
dropinInstance.requestPaymentMethod({
|
160 |
+
threeDSecure: {
|
161 |
+
amount: amount,
|
162 |
+
email: member_email,
|
163 |
+
billingAddress: {
|
164 |
+
givenName: first_name,
|
165 |
+
surname: last_name,
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}, function(err, payload) {
|
169 |
+
if (err) {
|
170 |
+
// Handle errors in requesting payment method
|
171 |
+
console.log(err);
|
172 |
document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = false;
|
173 |
+
alert("Error in requesting payment. Try again or check console logs");
|
174 |
+
}
|
175 |
+
|
176 |
+
document.getElementById('swpm-submit-form-btn-_uniqid_').disabled = true;
|
177 |
+
|
178 |
+
if (payload.type !== 'CreditCard') {
|
179 |
+
document.getElementById('swpm-braintree-nonce-field-_uniqid_').value = payload.nonce;
|
180 |
+
document.getElementById('swpm-braintree-payment-form-_uniqid_').submit();
|
181 |
+
return true;
|
182 |
}
|
183 |
+
|
184 |
+
document.getElementById('swpm-braintree-nonce-field-_uniqid_').value = payload.nonce;
|
185 |
+
document.getElementById('swpm-braintree-payment-form-_uniqid_').submit();
|
186 |
});
|
187 |
+
});
|
188 |
});
|
189 |
+
|
190 |
}
|
191 |
</script>
|
192 |
+
<?php
|
193 |
|
194 |
$scr = ob_get_clean();
|
195 |
$scr = str_replace(array('_uniqid_', '_token_', '_amount_'), array($uniqid, $clientToken, $payment_amount), $scr);
|
views/payments/payment-gateway/stripe_sca_button_shortcode_view.php
CHANGED
@@ -64,7 +64,7 @@ function swpm_render_stripe_sca_buy_now_button_sc_output( $button_code, $args )
|
|
64 |
//Return, cancel, notifiy URLs
|
65 |
$notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
|
66 |
|
67 |
-
|
68 |
|
69 |
/* === Stripe Buy Now Button Form === */
|
70 |
$output = '';
|
@@ -201,7 +201,7 @@ function swpm_render_stripe_sca_subscription_button_sc_output( $button_code, $ar
|
|
201 |
//Return, cancel, notifiy URLs
|
202 |
$notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
|
203 |
|
204 |
-
$current_url = (
|
205 |
|
206 |
$plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
|
207 |
|
64 |
//Return, cancel, notifiy URLs
|
65 |
$notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_buy_now=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
|
66 |
|
67 |
+
$current_url = SwpmMiscUtils::get_current_page_url();
|
68 |
|
69 |
/* === Stripe Buy Now Button Form === */
|
70 |
$output = '';
|
201 |
//Return, cancel, notifiy URLs
|
202 |
$notify_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL . '/?swpm_process_stripe_sca_subscription=1&ref_id=' . $ref_id; //We are going to use it to do post payment processing.
|
203 |
|
204 |
+
$current_url = SwpmMiscUtils::get_current_page_url();
|
205 |
|
206 |
$plan_id = get_post_meta( $button_id, 'stripe_plan_id', true );
|
207 |
|