PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/class-lp-checkout.php +325 -519 4.2.04.4.8 View file →
@@ -6,45 +6,41 @@
6 6 * @package LearnPress/Classes
7 7 * @version 4.0.0
8 8 */
9 9
10 +use LearnPress\Helpers\Singleton;
11 +use LearnPress\Models\CourseModel;
12 +use LearnPress\Models\UserModel;
13 +
10 14 defined( 'ABSPATH' ) || exit;
11 15
12 16 class LP_Checkout {
17 + use Singleton;
13 18
14 19 /**
15 - * @var LP_Checkout object instance
16 - * @access protected
17 - */
18 - protected static $_instance = null;
19 -
20 - /**
21 20 * Payment method
22 21 *
23 - * @var string|LP_Gateway_Abstract
22 + * @var LP_Gateway_Abstract
24 23 */
25 24 public $payment_method = null;
26 -
27 25 /**
28 - * @var array|mixed|null|void
26 + * Payment method string when user choice
27 + *
28 + * @var string $payment_method_str
29 29 */
30 - protected $checkout_fields = array();
31 -
30 + public $payment_method_str = '';
32 31 /**
33 32 * @var null
34 33 */
35 34 public $user_login = null;
36 -
37 35 /**
38 36 * @var null
39 37 */
40 38 public $user_pass = null;
41 -
42 39 /**
43 40 * @var null
44 41 */
45 42 public $order_comment = null;
46 -
47 43 /**
48 44 * Handle the errors when checking out.
49 45 *
50 46 * @var array
@@ -49,32 +45,17 @@
49 45 *
50 46 * @var array
51 47 */
52 48 public $errors = array();
53 -
54 49 /**
55 50 * @var string
56 51 */
57 52 protected $_checkout_email = '';
58 -
59 53 /**
60 - * @var array
61 - * @since 4.0.0
62 - */
63 - protected $login_data = array();
64 -
65 - /**
66 - * @var array
67 - * @since 4.0.0
68 - */
69 - protected $register_data = array();
70 -
71 - /**
72 54 * @var string
73 55 * @since 4.0.0
74 56 */
75 57 protected $guest_email = '';
76 -
77 58 /**
78 59 * @var string
79 60 * @since 4.0.0
80 61 */
@@ -79,82 +60,17 @@
79 60 * @since 4.0.0
80 61 */
81 62 protected $checkout_action = '';
82 63
83 - /**
84 - * @var array
85 - * @since 4.0.0
86 - */
87 - protected $checkout_form_data = array();
88 -
89 - /**
90 - * Constructor
91 - */
92 - public function __construct() {
93 - add_filter( 'learn-press/validate-checkout-field', array( $this, 'validate_fields' ), 10, 3 );
94 - add_filter( 'learn-press/validate-checkout-fields', array( $this, 'check_validate_fields' ), 10, 3 );
95 - //add_filter( 'learn-press/payment-successful-result', array( $this, 'process_customer' ), 10, 2 );
96 -
64 + public function init(): void {
97 65 if ( ! is_null( LearnPress::instance()->session ) ) {
98 66 $this->_checkout_email = LearnPress::instance()->session->get( 'checkout-email' );
99 67 }
68 +
69 + add_action( 'set_logged_in_cookie', [ $this, 'set_logged_in_cookie' ] );
100 70 }
101 71
102 72 /**
103 - * Process customer when checking out.
104 - *
105 - * @param array $result
106 - * @param int $order_id
107 - *
108 - * @return mixed
109 - * @editor tungnx
110 - * @modify 4.1.4 - merge to function create_order
111 - */
112 - /*public function process_customer( $result, $order_id ) {
113 - try {
114 - if ( ! $this->is_enable_guest_checkout() ) {
115 - throw new Exception( '' );
116 - }
117 -
118 - $order = learn_press_get_order( $order_id );
119 -
120 - if ( ! $order ) {
121 - throw new Exception( '' );
122 - }
123 -
124 - $user_id = 0;
125 - $checkout_option = LP_Request::get_string( 'checkout-email-option' );
126 -
127 - switch ( $checkout_option ) {
128 - case 'new-account':
129 - if ( $this->checkout_email_exists() ) {
130 - throw new Exception( 'NEW ACCOUNT EMAIL IS EXISTED', 0 );
131 - }
132 -
133 - $order->set_meta( '_create_account', 'yes' );
134 -
135 - $user_id = $this->_create_account();
136 -
137 - if ( ! is_wp_error( $user_id ) ) {
138 - wp_new_user_notification( $user_id, null, apply_filters( 'learn-press/email-create-new-user-when-checkout', 'user' ) );
139 - }
140 - break;
141 - }
142 -
143 - if ( $user_id ) {
144 - $order->set_user_id( $user_id );
145 - $order->save();
146 - }
147 - } catch ( Exception $ex ) {
148 - if ( $ex->getCode() && $ex->getMessage() ) {
149 - $result['message'] = $ex->getMessage();
150 - }
151 - }
152 -
153 - return $result;
154 - }*/
155 -
156 - /**
157 73 * Create account when checking out with user guest and tick create account.
158 74 *
159 75 * @return int|WP_Error
160 76 */
@@ -172,75 +88,113 @@
172 88 return $user_id;
173 89 }
174 90
175 91 /**
176 - * @param array $errors
177 - * @param array $fields
178 - * @param LP_Checkout $checkout
92 + * Check valid fields login/register/guest checkout.
93 + * Store session guest before login success.
94 + * When user login success, will update session data of guest for user.
179 95 *
180 - * @return array
96 + * @throws Exception
181 97 */
182 - public function check_validate_fields( $errors, $fields, $checkout ) {
183 - if ( empty( $errors ) ) {
184 - switch ( $this->checkout_action ) {
185 - case 'checkout-login':
186 - $this->checkout_form_data['remember'] = isset( $_POST['rememberme'] ) ? true : false;
98 + public function check_validate_fields() {
99 + $session = LearnPress::instance()->session;
100 + $data_session_before_user_login = $session->get_session_data();
101 + $this->checkout_action = null;
187 102
188 - $login_info = $this->checkout_form_data;
103 + if ( isset( $_POST['reg_email'] ) ) {
104 + $this->checkout_action = 'register';
105 + } elseif ( isset( $_POST['username'] ) ) {
106 + $this->checkout_action = 'login';
107 + } elseif ( isset( $_POST['guest_email'] ) ) {
108 + $this->checkout_action = 'guest';
109 + }
189 110
190 - $user = wp_signon(
191 - array(
192 - 'user_login' => $login_info['username'],
193 - 'user_password' => $login_info['password'],
194 - 'remember' => $login_info['remember'],
195 - ),
196 - is_ssl()
197 - );
111 + switch ( $this->checkout_action ) {
112 + case 'login':
113 + $user = wp_signon(
114 + array(
115 + 'user_login' => LP_Request::get_param( 'username' ),
116 + 'user_password' => LP_Request::get_param( 'password' ),
117 + 'remember' => LP_Request::get_param( 'remember', false ),
118 + ),
119 + is_ssl()
120 + );
198 121
199 - if ( is_wp_error( $user ) ) {
200 - $errors['login_error'] = $user->get_error_message();
201 - } else {
202 - wp_set_current_user( $user->ID );
203 - }
204 - break;
205 - case 'checkout-register':
206 - $default_fields = array();
122 + if ( is_wp_error( $user ) ) {
123 + throw new Exception( $user->get_error_message() );
124 + } else {
125 + wp_set_current_user( $user->ID );
126 + }
127 + break;
128 + case 'register':
129 + $default_fields = array(
130 + 'reg_email' => LP_Request::get_param( 'reg_email' ),
131 + 'reg_username' => LP_Request::get_param( 'reg_username' ),
132 + 'reg_password' => LP_Request::get_param( 'reg_password' ),
133 + 'reg_password2' => LP_Request::get_param( 'reg_password2' ),
134 + );
207 135
208 - if ( isset( $_POST['reg_first_name'] ) ) {
209 - $default_fields['first_name'] = LP_Helper::sanitize_params_submitted( $_POST['reg_first_name'] );
210 - }
136 + if ( isset( $_POST['reg_first_name'] ) ) {
137 + $default_fields['first_name'] = LP_Request::get_param( 'reg_first_name' );
138 + }
211 139
212 - if ( isset( $_POST['reg_last_name'] ) ) {
213 - $default_fields['last_name'] = LP_Helper::sanitize_params_submitted( $_POST['reg_last_name'] );
140 + if ( isset( $_POST['reg_last_name'] ) ) {
141 + $default_fields['last_name'] = LP_Request::get_param( 'reg_last_name' );
142 + }
143 +
144 + if ( isset( $_POST['reg_display_name'] ) ) {
145 + $default_fields['display_name'] = LP_Request::get_param( 'reg_display_name' );
146 + }
147 +
148 + $update_meta = isset( $_POST['_lp_custom_register_form'] ) ? LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register_form'] ) : array();
149 +
150 + $user_id = LP_Forms_Handler::learnpress_create_new_customer(
151 + $default_fields['reg_email'],
152 + $default_fields['reg_username'],
153 + $default_fields['reg_password'],
154 + $default_fields['reg_password2'],
155 + $default_fields,
156 + $update_meta
157 + );
158 +
159 + if ( is_wp_error( $user_id ) ) {
160 + throw new Exception( $user_id->get_error_message() );
161 + } else {
162 + // Directly authenticate the newly created user to bypass captcha plugins
163 + // that hook into 'authenticate'. We already verified the password during registration.
164 + $user = get_user_by( 'id', $user_id );
165 +
166 + if ( ! $user instanceof WP_User ) {
167 + throw new Exception( __( 'User registration succeeded but the user cannot be loaded.', 'learnpress' ) );
214 168 }
215 169
216 - if ( isset( $_POST['reg_display_name'] ) ) {
217 - $default_fields['display_name'] = LP_Helper::sanitize_params_submitted( $_POST['reg_display_name'] );
218 - }
170 + /*if ( ! wp_check_password( $default_fields['reg_password'], $user->user_pass, $user->ID ) ) {
171 + throw new Exception( __( 'Incorrect password.', 'learnpress' ) );
172 + }*/
219 173
220 - $update_meta = isset( $_POST['_lp_custom_register_form'] ) ? LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register_form'] ) : array();
174 + wp_set_current_user( $user->ID );
175 + wp_set_auth_cookie( $user->ID, true, is_ssl() );
176 + do_action( 'wp_login', $user->user_login, $user );
177 + }
178 + break;
179 + case 'guest':
180 + $email_guest = LP_Request::get_param( 'guest_email' );
181 + if ( ! is_email( $email_guest ) ) {
182 + throw new Exception( __( 'Your email is not valid!', 'learnpress' ) );
183 + }
221 184
222 - $user_id = LP_Forms_Handler::learnpress_create_new_customer(
223 - $this->checkout_form_data['reg_email'],
224 - $this->checkout_form_data['reg_username'],
225 - $this->checkout_form_data['reg_password'],
226 - $this->checkout_form_data['reg_password2'],
227 - $default_fields,
228 - $update_meta
229 - );
185 + $this->guest_email = $email_guest;
186 + $this->_checkout_email = $email_guest;
187 + break;
188 + }
230 189
231 - if ( is_wp_error( $user_id ) ) {
232 - $errors['create_user_error'] = $user_id->get_error_message();
233 - } else {
234 - wp_set_current_user( $user_id );
235 - wp_set_auth_cookie( $user_id, true );
236 - }
237 - break;
238 - case 'guest-checkout':
190 + // Set session, cart for user have just login/register success.
191 + if ( in_array( $this->checkout_action, [ 'login', 'register' ] ) ) {
192 + foreach ( $data_session_before_user_login as $key => $item ) {
193 + $session->set( $key, maybe_unserialize( $item ) );
239 194 }
195 + $session->save_data();
240 196 }
241 -
242 - return $errors;
243 197 }
244 198
245 199 /**
246 200 * Get email of user is being checkout.
@@ -250,11 +204,12 @@
250 204 public function get_checkout_email() {
251 205 if ( $this->_checkout_email ) {
252 206 return $this->_checkout_email;
253 207 } elseif ( is_user_logged_in() ) {
254 - $user = learn_press_get_current_user( false );
255 -
256 - return $user->get_email();
208 + $userModel = UserModel::find( get_current_user_id(), true );
209 + if ( $userModel instanceof UserModel ) {
210 + return $userModel->get_email();
211 + }
257 212 }
258 213
259 214 return false;
260 215 }
@@ -276,190 +231,104 @@
276 231
277 232 return $user->ID;
278 233 }
279 234
280 - public function verify_nonce() {
281 - if ( empty( $_POST['learn-press-checkout-nonce'] ) ) {
282 - return false;
283 - }
284 -
285 - if ( ! is_user_logged_in() ) {
286 - $actions = array( 'guest-checkout', 'checkout-register', 'checkout-login' );
287 - } else {
288 - $actions = array( 'guest-checkout', 'checkout-register', 'user-logged' );
289 - }
290 -
291 - foreach ( $actions as $action ) {
292 - if ( wp_verify_nonce( $_REQUEST['learn-press-checkout-nonce'], "learn-press-{$action}" ) ) {
293 - $this->checkout_action = $action;
294 -
295 - return true;
296 - }
297 - }
298 -
299 - return false;
300 - }
301 -
302 235 /**
303 - * Checkout fields.
304 - *
305 - * @return array
306 - */
307 - public function get_checkout_fields() {
308 - if ( ! $this->verify_nonce() ) {
309 - $this->checkout_fields['invalid_request'] = new WP_Error( 'invalid_request', __( 'Your session has expired.', 'learnpress' ) );
310 - } else {
311 - if ( $this->checkout_action === 'checkout-register' ) {
312 - $this->checkout_fields['reg_email'] = esc_html__( 'Email', 'learnpress' );
313 - $this->checkout_fields['reg_username'] = esc_html__( 'Username', 'learnpress' );
314 - $this->checkout_fields['reg_password'] = esc_html__( 'Password', 'learnpress' );
315 - $this->checkout_fields['reg_password2'] = esc_html__( 'Confirm Password', 'learnpress' );
316 - } elseif ( $this->checkout_action === 'checkout-login' ) {
317 - $this->checkout_fields['username'] = esc_html__( 'Username', 'learnpress' );
318 - $this->checkout_fields['password'] = esc_html__( 'Password', 'learnpress' );
319 - } elseif ( $this->checkout_action === 'guest-checkout' ) {
320 - $this->checkout_fields['guest_email'] = esc_html__( 'Email', 'learnpress' );
321 - }
322 - }
323 -
324 - $this->checkout_fields = apply_filters( 'learn_press_checkout_fields', $this->checkout_fields );
325 -
326 - return $this->checkout_fields;
327 - }
328 -
329 - /**
330 - * Check if an order is pending or failed.
331 - *
332 - * @param $order_id
333 - *
334 - * @return LP_Order|bool
335 - */
336 - protected function _is_resume_order( $order_id ) {
337 - $order = learn_press_get_order( $order_id );
338 -
339 - if ( $order_id > 0 && $order && $order->has_status( array( 'pending', 'failed' ) ) ) {
340 - return $order;
341 - }
342 -
343 - return false;
344 - }
345 -
346 - /**
347 236 * Create LP Order.
348 237 *
238 + * @return mixed|string
239 + * @throws Exception
349 240 * @since 3.0.0
350 - * @version 4.0.1
351 - * @return mixed|WP_Error
352 - * @throws Exception
241 + * @version 4.0.3
353 242 */
354 243 public function create_order() {
355 - $cart = LearnPress::instance()->cart;
356 - $cart_total = $cart->calculate_totals();
244 + $cart = LearnPress::instance()->cart;
245 + $cart_total = $cart->calculate_totals();
246 + $order = new LP_Order();
247 + $user_id = 0;
248 + $user_can_register = get_option( 'users_can_register' );
357 249
358 - try {
359 - /*// Insert or update the post data
360 - $order_id = absint( LearnPress::instance()->session->get( 'order_awaiting_payment' ) );
250 + if ( is_user_logged_in() ) {
251 + $user_id = get_current_user_id();
252 + } elseif ( $user_can_register ) {
253 + $checkout_option = LP_Request::get_param( 'checkout-email-option' );
254 + // Set user id for Order if buy with Guest and email exists on the user
255 + $user_id = $this->checkout_email_exists();
361 256
362 - // Resume the unpaid order if its pending
363 - $order = $this->_is_resume_order( $order_id );
364 -
365 - if ( $order ) {
366 - if ( is_wp_error( $order ) ) {
367 - throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'learnpress' ), 401 ) );
257 + // Create new user if buy with Guest and tick "Create new Account"
258 + if ( $checkout_option === 'new-account' ) {
259 + if ( $user_id ) {
260 + throw new Exception( __( 'New account email is existed', 'learnpress' ), 0 );
368 261 }
369 262
370 - $order->remove_order_items();
371 - do_action( 'learn-press/checkout/resume-order', $order_id );
263 + //$order->set_meta( '_create_account', 'yes' );
372 264
373 - } else {
374 - $order = new LP_Order();
375 -
376 - if ( is_wp_error( $order ) ) {
377 - throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'learnpress' ), 400 ) );
265 + $user_id = $this->create_account();
266 + if ( $user_id ) {
267 + // Notify mail create user success
268 + wp_new_user_notification(
269 + $user_id,
270 + null,
271 + apply_filters( 'learn-press/email-create-new-user-when-checkout', 'user' )
272 + );
273 + } else {
274 + throw new Exception( __( 'Create account failed', 'learnpress' ), 0 );
378 275 }
379 -
380 - $order_id = $order->get_id();
381 - do_action( 'learn-press/checkout/new-order', $order_id );
382 - }*/
383 -
384 - $order = new LP_Order();
385 - $user_id = 0;
386 -
387 - if ( is_user_logged_in() ) {
388 - $user_id = get_current_user_id();
389 - } else {
390 - $checkout_option = LP_Request::get_param( 'checkout-email-option' );
391 - // Set user id for Order if buy with Guest and email exists on the user
392 - $user_id = $this->checkout_email_exists();
393 -
394 - // Create new user if buy with Guest and tick "Create new Account"
395 - if ( $checkout_option === 'new-account' ) {
396 - if ( $user_id ) {
397 - throw new Exception( __( 'New account email is existed', 'learnpress' ), 0 );
398 - }
399 -
400 - //$order->set_meta( '_create_account', 'yes' );
401 -
402 - $user_id = $this->create_account();
403 - if ( $user_id ) {
404 - // Notify mail create user success
405 - wp_new_user_notification( $user_id, null, apply_filters( 'learn-press/email-create-new-user-when-checkout', 'user' ) );
406 - } else {
407 - throw new Exception( __( 'Create account failed', 'learnpress' ), 0 );
408 - }
409 - }
410 276 }
411 277
412 - $order->set_customer_note( $this->order_comment );
413 - $order->set_status( LP_ORDER_PENDING );
414 - $order->set_total( $cart_total->total );
415 - $order->set_subtotal( $cart_total->subtotal );
416 - $order->set_user_ip_address( learn_press_get_ip() );
417 - $order->set_user_agent( learn_press_get_user_agent() );
418 - $order->set_created_via( 'checkout' );
419 - $order->set_user_id( apply_filters( 'learn-press/checkout/default-user', $user_id ) );
420 - if ( $this->payment_method instanceof LP_Gateway_Abstract ) {
421 - $order->set_data( 'payment_method', $this->payment_method->get_id() );
422 - $order->set_data( 'payment_method_title', $this->payment_method->get_title() );
278 + // Get user_id Guest
279 + if ( ! $user_id ) {
280 + /**
281 + * @var LP_User_Guest $user_guest
282 + */
283 + $user_guest = learn_press_get_user();
284 + $user_id = $user_guest->get_id();
423 285 }
286 + }
424 287
425 - if ( $this->is_enable_guest_checkout() && $this->get_checkout_email() ) {
426 - $order->set_checkout_email( $this->get_checkout_email() );
288 + if ( $this->is_enable_guest_checkout() && $this->get_checkout_email() ) {
289 + $order->set_checkout_email( $this->get_checkout_email() );
290 + // Check email exists on the user will get user_id to set
291 + if ( ! $user_id ) {
292 + $user_id = $this->checkout_email_exists();
427 293 }
294 + }
428 295
429 - $order_id = $order->save();
296 + $order->set_customer_note( $this->order_comment );
297 + $order->set_status( LP_ORDER_PENDING );
298 + $order->set_total( $cart_total->total );
299 + $order->set_subtotal( $cart_total->subtotal );
300 + $order->set_user_ip_address( learn_press_get_ip() );
301 + $order->set_user_agent( learn_press_get_user_agent() );
302 + $order->set_created_via( 'checkout' );
303 + $order->set_user_id( apply_filters( 'learn-press/checkout/default-user', $user_id ) );
304 + if ( $this->payment_method instanceof LP_Gateway_Abstract ) {
305 + $order->set_data( 'payment_method', $this->payment_method->get_id() );
306 + $order->set_data( 'payment_method_title', $this->payment_method->get_title() );
307 + }
430 308
431 - // Store the line items to the order
432 - foreach ( $cart->get_items() as $item ) {
433 - $item_type = get_post_type( $item['item_id'] );
309 + $order_id = $order->save();
434 310
435 - if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
436 - continue;
437 - }
438 -
439 - $item_id = $order->add_item( $item );
440 -
441 - if ( ! $item_id ) {
442 - throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'learnpress' ), 402 ) );
443 - }
444 -
445 - do_action( 'learn-press/checkout/add-order-item-meta', $item_id, $item );
311 + // Store the line items to the order
312 + foreach ( $cart->get_items() as $item ) {
313 + $item_type = get_post_type( $item['item_id'] );
314 + if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
315 + continue;
446 316 }
447 317
448 - if ( ! empty( $this->user_id ) ) {
449 - do_action( 'learn-press/checkout/update-user-meta', $this->user_id );
318 + $item_id = $order->add_item( $item );
319 + if ( ! $item_id ) {
320 + throw new Exception( sprintf( __( 'Error %d: Unable to add item to order. Please try again.', 'learnpress' ), 402 ) );
450 321 }
451 322
452 - do_action( 'learn-press/checkout/update-order-meta', $order_id );
323 + do_action( 'learn-press/checkout/add-order-item-meta', $item_id, $item );
324 + }
453 325
454 - if ( ! $order_id || is_wp_error( $order_id ) ) {
455 - learn_press_add_message( __( 'Unable to checkout. Order creation failed.', 'learnpress' ) );
456 - }
457 - } catch ( Exception $e ) {
458 - learn_press_add_message( $e->getMessage() );
326 + if ( ! empty( $this->user_id ) ) {
327 + do_action( 'learn-press/checkout/update-user-meta', $this->user_id );
328 + }
459 329
460 - return false;
461 - }
330 + do_action( 'learn-press/checkout/update-order-meta', $order_id );
462 331
463 332 return $order_id;
464 333 }
465 334
@@ -465,23 +334,29 @@
465 334
466 335 /**
467 336 * Guest checkout is enable?
468 337 *
469 - * @return mixed
338 + * @return bool
470 339 * @since 3.0.0
471 340 */
472 - public function is_enable_guest_checkout() {
473 - return apply_filters( 'learn-press/checkout/enable-guest', LP_Settings::instance()->get( 'guest_checkout', 'no' ) == 'yes' );
341 + public function is_enable_guest_checkout(): bool {
342 + return apply_filters(
343 + 'learn-press/checkout/enable-guest',
344 + LP_Settings::get_option( 'guest_checkout', 'no' ) === 'yes'
345 + );
474 346 }
475 347
476 348 /**
477 - * Enable user can login in checkout page?
349 + * Enable user can log in checkout page?
478 350 *
479 351 * @return bool
480 352 * @since 3.0.0
481 353 */
482 - public function is_enable_login() {
483 - return apply_filters( 'learn-press/checkout/enable-login', in_array( LP_Settings::instance()->get( 'enable_login_checkout' ), array( '', 'yes' ) ) );
354 + public function is_enable_login(): bool {
355 + return apply_filters(
356 + 'learn-press/checkout/enable-login',
357 + 'yes' === LP_Settings::get_option( 'enable_login_checkout', 'yes' )
358 + );
484 359 }
485 360
486 361 /**
487 362 * Enable user can register in checkout page?
@@ -488,175 +363,84 @@
488 363 *
489 364 * @return bool
490 365 * @since 3.0.0
491 366 */
492 - public function is_enable_register() {
493 - return apply_filters( 'learn-press/checkout/enable-register', in_array( LP_Settings::instance()->get( 'enable_registration_checkout' ), array( '', 'yes' ) ) && get_option( 'users_can_register' ) );
367 + public function is_enable_register(): bool {
368 + return apply_filters(
369 + 'learn-press/checkout/enable-register',
370 + 'yes' === LP_Settings::get_option( 'enable_registration_checkout', 'yes' )
371 + && get_option( 'users_can_register' )
372 + );
494 373 }
495 374
496 375 /**
497 - * Validate fields
498 - *
499 - * @param bool $validate
500 - * @param mixed $field
501 - * @param string $name
502 - *
503 - * @return bool|WP_Error
504 - */
505 - public function validate_fields( $validate, $field, $name ) {
506 - switch ( $this->checkout_action ) {
507 - case 'checkout-register':
508 - if ( $name === 'reg_username' ) {
509 - if ( empty( $_POST['reg_username'] ) ) {
510 - return new WP_Error( 'username_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
511 - } elseif ( username_exists( $_POST['reg_username'] ) ) {
512 - return new WP_Error( 'username_exists', sprintf( __( '%s is exists.', 'learnpress' ), $_POST['reg_username'] ) );
513 - } elseif ( ! validate_username( $_POST['reg_username'] ) ) {
514 - return new WP_Error( 'username_invalid', sprintf( __( '%s is not a valid username.', 'learnpress' ), $_POST['reg_username'] ) );
515 - }
516 - } elseif ( $name === 'reg_email' ) {
517 - if ( empty( $_POST['reg_email'] ) ) {
518 - return new WP_Error( 'email_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
519 - } elseif ( email_exists( $_POST['reg_email'] ) ) {
520 - return new WP_Error( 'email_exists', sprintf( __( '%s is exists.', 'learnpress' ), $_POST['reg_email'] ) );
521 - } elseif ( ! is_email( $_POST['reg_email'] ) ) {
522 - return new WP_Error( 'email_invalid', sprintf( __( '%s is not a valid email.', 'learnpress' ), $_POST['reg_email'] ) );
523 - }
524 - } elseif ( $name === 'reg_password' ) {
525 - if ( empty( $_POST['reg_password'] ) ) {
526 - return new WP_Error( 'password_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
527 - }
528 - } elseif ( $name === 'reg_password2' ) {
529 - if ( empty( $_POST['reg_password2'] ) ) {
530 - return new WP_Error( 'password2_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
531 - }
532 - }
533 -
534 - $this->checkout_form_data[ $name ] = LP_Helper::maybe_unserialize( $_POST[ $name ] );
535 -
536 - break;
537 - case 'checkout-login':
538 - if ( $name === 'username' ) {
539 - if ( empty( $_POST['username'] ) ) {
540 - return new WP_Error( 'email_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
541 - }
542 -
543 - if ( ! username_exists( $_POST['username'] ) && ! email_exists( $_POST['username'] ) ) {
544 - return new WP_Error( 'username_exists', sprintf( __( '%s is not exist.', 'learnpress' ), $field ) );
545 - }
546 - } elseif ( $name === 'password' ) {
547 - if ( empty( $_POST['password'] ) ) {
548 - return new WP_Error( 'email_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
549 - }
550 - }
551 -
552 - $this->checkout_form_data[ $name ] = LP_Helper::maybe_unserialize( $_POST[ $name ] );
553 - break;
554 - case 'guest-checkout':
555 - if ( empty( $_POST['guest_email'] ) ) {
556 - return new WP_Error( 'email_empty', sprintf( __( '%s is required field.', 'learnpress' ), $field ) );
557 - } elseif ( ! is_email( $_POST['guest_email'] ) ) {
558 - return new WP_Error( 'email_invalid', __( 'Your email is not valid.', 'learnpress' ) );
559 - }
560 -
561 - $this->guest_email = LP_Helper::maybe_unserialize( $_POST[ $name ] );
562 - $this->_checkout_email = LP_Helper::maybe_unserialize( $_POST[ $name ] );
563 - }
564 -
565 - return $validate;
566 - }
567 -
568 - /**
569 376 * Process checkout from request.
570 377 *
571 - * @return mixed
378 + * @return void
572 379 * @throws Exception
573 380 */
574 381 public function process_checkout_handler() {
575 382 if ( strtolower( $_SERVER['REQUEST_METHOD'] ) != 'post' ) {
576 - return false;
383 + return;
577 384 }
578 385
579 386 /**
580 387 * Set default fields from request.
581 388 */
582 - $this->payment_method = LP_Request::get_string( 'payment_method' );
583 - $this->user_login = LP_Request::get_string( 'username' );
584 - $this->user_pass = LP_Request::get_string( 'password' );
585 - $this->order_comment = LP_Request::get_string( 'order_comments' );
586 - $this->_checkout_email = LP_Request::get_email( 'checkout-email' );
587 -
588 - if ( LP_Request::get_int( 'terms_conditions_field', 0 ) ) {
589 - $this->checkout_fields['terms_conditions'] = LP_Request::get_string( 'terms_conditions', '' );
590 - }
591 -
389 + $this->payment_method_str = LP_Request::get_param( 'payment_method' );
390 + $this->order_comment = LP_Request::get_param( 'order_comments' );
391 + $this->_checkout_email = LP_Request::get_param( 'checkout-email' );
592 392 if ( $this->_checkout_email ) {
593 393 LearnPress::instance()->session->set( 'checkout-email', $this->_checkout_email );
594 394 }
595 395
596 396 $this->process_checkout();
597 -
598 - return true;
599 397 }
600 398
601 399 /**
602 400 * Validate fields.
603 401 *
604 - * @return bool
402 + * Addon Upsell 4.0.1 use argument $errors
403 + * Must update to 4.0.2 to use throw Error instead.
404 + *
405 + * @throws Exception
605 406 */
606 407 public function validate_checkout_fields() {
607 408 $this->errors = array();
608 - $fields = $this->get_checkout_fields();
609 409
610 - if ( $fields ) {
611 - foreach ( $fields as $name => $field ) {
612 - if ( ! is_wp_error( $field ) ) {
613 - $error = apply_filters( 'learn-press/validate-checkout-field', true, $field, $name );
614 - } else {
615 - $error = $field;
616 - }
617 -
618 - if ( is_wp_error( $error ) ) {
619 - $this->errors[ $name ] = $error;
620 - } elseif ( ! $error ) {
621 - $this->errors[ $name ] = new WP_Error( 'invalid_field', __( 'Invalid field', 'learnpress' ) );
622 - }
623 - }
410 + // Check nonce
411 + $nonce = LP_Request::get_param( 'learn-press-checkout-nonce' );
412 + if ( ! wp_verify_nonce( $nonce, 'learn-press-checkout' ) ) {
413 + throw new Exception( __( 'Your session has expired.', 'learnpress' ) );
624 414 }
625 415
626 - $this->errors = apply_filters( 'learn-press/validate-checkout-fields', $this->errors, $fields, $this );
416 + $this->check_validate_fields();
627 417
628 - return ! sizeof( $this->errors );
418 + do_action( 'learn-press/validate-checkout-fields', $this );
629 419 }
630 420
631 421 /**
632 422 * Validate checkout payment.
633 423 *
634 - * @return bool
635 424 * @throws Exception
636 425 */
637 426 public function validate_payment() {
638 - $cart = LearnPress::instance()->cart;
639 - $validate = true;
427 + $cart = LearnPress::instance()->cart;
428 + //$validate = true;
640 429
641 430 if ( $cart->needs_payment() ) {
642 431 if ( ! $this->payment_method instanceof LP_Gateway_Abstract ) {
643 432 $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
644 433
645 - if ( ! isset( $available_gateways[ $this->payment_method ] ) ) {
646 - $this->payment_method = '';
434 + if ( ! isset( $available_gateways[ $this->payment_method_str ] ) ) {
647 435 throw new Exception( __( 'No payment method is selected', 'learnpress' ), LP_ERROR_NO_PAYMENT_METHOD_SELECTED );
648 436 } else {
649 - $this->payment_method = $available_gateways[ $this->payment_method ];
437 + $this->payment_method = $available_gateways[ $this->payment_method_str ];
650 438 }
651 - }
652 439
653 - if ( $this->payment_method ) {
654 - $validate = $this->payment_method->validate_fields();
440 + $this->payment_method->validate_fields();
655 441 }
656 442 }
657 -
658 - return $validate;
659 443 }
660 444
661 445 /**
662 446 * Process checkout.
@@ -663,14 +447,16 @@
663 447 *
664 448 * @throws Exception
665 449 */
666 450 public function process_checkout() {
667 - $has_error = false;
451 + ini_set( 'max_execution_time', HOUR_IN_SECONDS );
452 + $result = array(
453 + 'result' => 'fail',
454 + 'message' => '',
455 + );
668 456
669 457 try {
670 - if ( function_exists( 'set_time_limit' ) ) {
671 - @set_time_limit( 0 ); // @codingStandardsIgnoreLine
672 - }
458 + $lp_session = LearnPress::instance()->session;
673 459
674 460 do_action( 'learn-press/before-checkout' );
675 461
676 462 $cart = LearnPress::instance()->cart;
@@ -677,10 +463,8 @@
677 463 if ( $cart->is_empty() ) {
678 464 throw new Exception( __( 'Your cart is currently empty.', 'learnpress' ) );
679 465 }
680 466
681 - $messages = array();
682 -
683 467 foreach ( $cart->get_items() as $item ) {
684 468 $item_type = get_post_type( $item['item_id'] );
685 469
686 470 if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
@@ -687,116 +471,138 @@
687 471 throw new Exception( __( 'Type item buy invalid!', 'learnpress' ) );
688 472 }
689 473 }
690 474
691 - if ( ! $this->validate_checkout_fields() ) {
692 - foreach ( $this->errors as $key => $error ) {
693 - if ( is_wp_error( $error ) ) {
694 - $error = $error->get_error_message();
475 + // Validate fields
476 + $this->validate_checkout_fields();
477 + // Validate payment method
478 + $this->validate_payment();
479 +
480 + $user_id = $this->checkout_email_exists();
481 + if ( ! $user_id ) {
482 + $user_id = 0;
483 + }
484 +
485 + // Check user can purchase, enrolled course
486 + foreach ( $cart->get_items() as $item ) {
487 + $item_type = get_post_type( $item['item_id'] );
488 + if ( LP_COURSE_CPT === $item_type ) {
489 + $courseModel = CourseModel::find( $item['item_id'], true );
490 + if ( ! $courseModel ) {
491 + throw new Exception( __( 'Course is invalid!', 'learnpress' ) );
695 492 }
696 - $messages[ $key ] = array( $error, 'error' );
493 +
494 + $userModel = UserModel::find( $user_id, true );
495 +
496 + // Check user can purchase course
497 + if ( ! $courseModel->is_free() ) {
498 + $can_purchase = $courseModel->can_purchase( $userModel );
499 + if ( is_wp_error( $can_purchase ) ) {
500 + //throw new Exception( $can_purchase->get_error_message() );
501 + learn_press_set_message(
502 + [
503 + 'status' => 'error',
504 + 'content' => $can_purchase->get_error_message(),
505 + ]
506 + );
507 + $result['redirect'] = LP_Page_Controller::get_link_page( 'checkout', [], true );
508 + $result['message'] = $can_purchase->get_error_message();
509 + learn_press_send_json( $result );
510 + }
511 + } else {
512 + // Check user can enroll course
513 + $can_enroll = $courseModel->can_enroll( $userModel );
514 + if ( is_wp_error( $can_enroll ) ) {
515 + learn_press_set_message(
516 + [
517 + 'status' => 'error',
518 + 'content' => $can_enroll->get_error_message(),
519 + ]
520 + );
521 + $result['redirect'] = LP_Page_Controller::get_link_page( 'checkout', [], true );
522 + $result['message'] = $can_enroll->get_error_message();
523 + learn_press_send_json( $result );
524 + }
525 + }
697 526 }
698 - } else {
699 - //LearnPress::instance()->cart->calculate_totals();
700 - // maybe throw new exception
701 - $this->validate_payment();
527 + }
702 528
703 - // Create order.
529 + // Create order if not handle done.
530 + $order_id = $lp_session->get( 'order_awaiting_payment', 0 );
531 + if ( ! $order_id ) {
704 532 $order_id = $this->create_order();
705 533 if ( is_wp_error( $order_id ) ) {
706 534 throw new Exception( $order_id->get_error_message() );
707 535 }
708 536
709 - // allow Third-party hook: send email and more...
710 - do_action( 'learn-press/checkout-order-processed', $order_id, $this );
537 + $lp_session->set( 'order_awaiting_payment', $order_id, true );
538 + }
711 539
712 - if ( $this->payment_method instanceof LP_Gateway_Abstract ) {
713 - //LearnPress::instance()->session->set( 'order_awaiting_payment', $order_id );
714 - // Process Payment
715 - $result = $this->payment_method->process_payment( $order_id );
540 + // allow Third-party hook: send email and more...
541 + do_action( 'learn-press/checkout-order-processed', $order_id, $this );
716 542
717 - if ( isset( $result['result'] ) ) {
543 + if ( $this->payment_method instanceof LP_Gateway_Abstract ) {
544 + // Process Payment
545 + $result = $this->payment_method->process_payment( $order_id );
546 + if ( isset( $result['result'] ) ) {
547 + if ( 'success' === $result['result'] ) {
718 548 // Clear cart.
719 549 LearnPress::instance()->get_cart()->empty_cart();
550 + $result = apply_filters( 'learn-press/payment-successful-result', $result, $order_id );
551 + }
720 552
721 - if ( 'success' === $result['result'] ) {
722 - $result = apply_filters( 'learn-press/payment-successful-result', $result, $order_id );
723 - }
724 -
725 - if ( learn_press_is_ajax() ) {
726 - learn_press_send_json( $result );
727 - } else {
728 - wp_redirect( $result['redirect'] );
729 - exit;
730 - }
553 + if ( ! learn_press_is_ajax() ) {
554 + ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
555 + wp_redirect( $result['redirect'] );
556 + exit;
731 557 }
732 - } else {
733 - // For case enroll course free.
734 - $order = new LP_Order( $order_id );
735 - if ( $order->payment_complete() ) {
736 - $is_guest_checkout = (bool) $this->guest_email;
737 - $redirect = $order->get_checkout_order_received_url();
558 + }
559 + } else {
560 + // For case enroll a course free.
561 + $order = new LP_Order( $order_id );
562 + if ( $order->payment_complete() ) {
563 + $redirect = $order->get_checkout_order_received_url();
738 564
739 - if ( ! $is_guest_checkout ) {
740 - $course_id = get_transient( 'checkout_enroll_course_id' );
565 + // Clear cart.
566 + LearnPress::instance()->get_cart()->empty_cart();
741 567
742 - if ( ! $course_id ) {
743 - if ( ! empty( $_REQUEST['enroll-course'] ) ) {
744 - $course_id = absint( $_REQUEST['enroll-course'] );
745 - }
746 - }
568 + $result = array(
569 + 'result' => 'success',
570 + 'redirect' => $redirect,
571 + );
747 572
748 - if ( $course_id ) {
749 - delete_transient( 'checkout_enroll_course_id' );
750 - $redirect = get_the_permalink( $course_id );
751 - }
752 - }
753 -
754 - // Clear cart.
755 - LearnPress::instance()->get_cart()->empty_cart();
756 -
757 - $result = array(
758 - 'result' => 'success',
759 - 'redirect' => $redirect,
760 - );
761 -
762 - if ( learn_press_is_ajax() ) {
763 - learn_press_send_json( $result );
764 - } else {
765 - wp_redirect( $result['redirect'] );
766 - exit;
767 - }
573 + if ( ! learn_press_is_ajax() ) {
574 + ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
575 + wp_redirect( $result['redirect'] );
576 + exit;
768 577 }
769 578 }
770 579 }
771 - } catch ( Exception $e ) {
772 - $has_error = $e->getMessage();
773 - $messages[] = array( $has_error, 'error' );
580 + } catch ( Throwable $e ) {
581 + $result['message'] = $e->getMessage();
774 582 }
775 583
776 - $is_error = sizeof( $messages );
777 -
778 - $result = apply_filters(
779 - 'learn-press/checkout-error',
780 - array(
781 - 'result' => ! $is_error ? 'success' : 'fail',
782 - 'messages' => $messages,
783 - )
784 - );
785 -
786 - wp_send_json( $result );
584 + ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
585 + learn_press_send_json( $result );
787 586 }
788 587
789 588 /**
790 - * Get unique instance for this object
589 + * Sync $_COOKIE[LOGGED_IN_COOKIE] within the current checkout request.
791 590 *
792 - * @return LP_Checkout
591 + * Checkout runs over AJAX. When login/register succeeds, wp_signon() only
592 + * sends a Set-Cookie header to the browser (effective on the next request)
593 + * and does not update $_COOKIE for the current request. Hooking into
594 + * 'set_logged_in_cookie' lets us grab the newly generated cookie value and
595 + * assign it to $_COOKIE manually, so subsequent code in the same request
596 + * (e.g. creating the order) correctly recognizes the logged-in user.
597 + * LPBackgroundAjax use $_COOKIE to send mails.
598 + *
599 + * @param string $logged_in_cookie The newly generated logged_in cookie value.
793 600 */
794 - public static function instance() {
795 - if ( empty( self::$_instance ) ) {
796 - self::$_instance = new LP_Checkout();
601 + public function set_logged_in_cookie( $logged_in_cookie ) {
602 + if ( ! isset( $_POST['learn-press-checkout-nonce'] ) ) {
603 + return;
797 604 }
798 605
799 - return self::$_instance;
606 + $_COOKIE[ LOGGED_IN_COOKIE ] = $logged_in_cookie;
800 607 }
801 608 }
802 -