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 +608 -573 4.3.84.4.8 View file →
@@ -1,573 +1,608 @@
1 -<?php
2 -/**
3 - * Class LP_Checkout
4 - *
5 - * @author ThimPress <Nhamdv>
6 - * @package LearnPress/Classes
7 - * @version 4.0.0
8 - */
9 -
10 -use LearnPress\Helpers\Singleton;
11 -use LearnPress\Models\CourseModel;
12 -use LearnPress\Models\UserModel;
13 -
14 -defined( 'ABSPATH' ) || exit;
15 -
16 -class LP_Checkout {
17 - use Singleton;
18 -
19 - /**
20 - * Payment method
21 - *
22 - * @var LP_Gateway_Abstract
23 - */
24 - public $payment_method = null;
25 - /**
26 - * Payment method string when user choice
27 - *
28 - * @var string $payment_method_str
29 - */
30 - public $payment_method_str = '';
31 - /**
32 - * @var null
33 - */
34 - public $user_login = null;
35 - /**
36 - * @var null
37 - */
38 - public $user_pass = null;
39 - /**
40 - * @var null
41 - */
42 - public $order_comment = null;
43 - /**
44 - * Handle the errors when checking out.
45 - *
46 - * @var array
47 - */
48 - public $errors = array();
49 - /**
50 - * @var string
51 - */
52 - protected $_checkout_email = '';
53 - /**
54 - * @var string
55 - * @since 4.0.0
56 - */
57 - protected $guest_email = '';
58 - /**
59 - * @var string
60 - * @since 4.0.0
61 - */
62 - protected $checkout_action = '';
63 -
64 - public function init() {
65 - if ( ! is_null( LearnPress::instance()->session ) ) {
66 - $this->_checkout_email = LearnPress::instance()->session->get( 'checkout-email' );
67 - }
68 - }
69 -
70 - /**
71 - * Create account when checking out with user guest and tick create account.
72 - *
73 - * @return int|WP_Error
74 - */
75 - protected function create_account(): int {
76 - $user_id = 0;
77 -
78 - try {
79 - $email = $this->get_checkout_email();
80 - $password = wp_generate_password();
81 - $user_id = wp_create_user( $email, $password, $email );
82 - } catch ( Throwable $e ) {
83 - error_log( $e->getMessage() );
84 - }
85 -
86 - return $user_id;
87 - }
88 -
89 - /**
90 - * Check valid fields login/register/guest checkout.
91 - * Store session guest before login success.
92 - * When user login success, will update session data of guest for user.
93 - *
94 - * @throws Exception
95 - */
96 - public function check_validate_fields() {
97 - $session = LearnPress::instance()->session;
98 - $data_session_before_user_login = $session->get_session_data();
99 - $checkout_account_type = LP_Request::get_param( 'checkout-account-switch-form' );
100 - $this->checkout_action = $checkout_account_type;
101 -
102 - switch ( $this->checkout_action ) {
103 - case 'login':
104 - $user = wp_signon(
105 - array(
106 - 'user_login' => LP_Request::get_param( 'username' ),
107 - 'user_password' => LP_Request::get_param( 'password' ),
108 - 'remember' => LP_Request::get_param( 'remember', false ),
109 - ),
110 - is_ssl()
111 - );
112 -
113 - if ( is_wp_error( $user ) ) {
114 - throw new Exception( $user->get_error_message() );
115 - } else {
116 - wp_set_current_user( $user->ID );
117 - }
118 - break;
119 - case 'register':
120 - $default_fields = array(
121 - 'reg_email' => LP_Request::get_param( 'reg_email' ),
122 - 'reg_username' => LP_Request::get_param( 'reg_username' ),
123 - 'reg_password' => LP_Request::get_param( 'reg_password' ),
124 - 'reg_password2' => LP_Request::get_param( 'reg_password2' ),
125 - );
126 -
127 - if ( isset( $_POST['reg_first_name'] ) ) {
128 - $default_fields['first_name'] = LP_Request::get_param( 'reg_first_name' );
129 - }
130 -
131 - if ( isset( $_POST['reg_last_name'] ) ) {
132 - $default_fields['last_name'] = LP_Request::get_param( 'reg_last_name' );
133 - }
134 -
135 - if ( isset( $_POST['reg_display_name'] ) ) {
136 - $default_fields['display_name'] = LP_Request::get_param( 'reg_display_name' );
137 - }
138 -
139 - $update_meta = isset( $_POST['_lp_custom_register_form'] ) ? LP_Helper::sanitize_params_submitted( $_POST['_lp_custom_register_form'] ) : array();
140 -
141 - $user_id = LP_Forms_Handler::learnpress_create_new_customer(
142 - $default_fields['reg_email'],
143 - $default_fields['reg_username'],
144 - $default_fields['reg_password'],
145 - $default_fields['reg_password2'],
146 - $default_fields,
147 - $update_meta
148 - );
149 -
150 - if ( is_wp_error( $user_id ) ) {
151 - throw new Exception( $user_id->get_error_message() );
152 - } else {
153 - $user = wp_signon(
154 - array(
155 - 'user_login' => $default_fields['reg_email'],
156 - 'user_password' => $default_fields['reg_password'],
157 - 'remember' => 1,
158 - ),
159 - is_ssl()
160 - );
161 -
162 - if ( is_wp_error( $user ) ) {
163 - throw new Exception( $user->get_error_message() );
164 - } else {
165 - wp_set_current_user( $user->ID );
166 - }
167 - }
168 - break;
169 - case 'guest':
170 - $email_guest = LP_Request::get_param( 'guest_email' );
171 - if ( ! is_email( $email_guest ) ) {
172 - throw new Exception( __( 'Your email is not valid!', 'learnpress' ) );
173 - }
174 -
175 - $this->guest_email = $email_guest;
176 - $this->_checkout_email = $email_guest;
177 - break;
178 - }
179 -
180 - // Set session, cart for user have just login/register success.
181 - if ( in_array( $this->checkout_action, [ 'login', 'register' ] ) ) {
182 - foreach ( $data_session_before_user_login as $key => $item ) {
183 - $session->set( $key, maybe_unserialize( $item ) );
184 - }
185 - $session->save_data();
186 - }
187 - }
188 -
189 - /**
190 - * Get email of user is being checkout.
191 - *
192 - * @return string
193 - */
194 - public function get_checkout_email() {
195 - if ( $this->_checkout_email ) {
196 - return $this->_checkout_email;
197 - } elseif ( is_user_logged_in() ) {
198 - $userModel = UserModel::find( get_current_user_id(), true );
199 - if ( $userModel instanceof UserModel ) {
200 - return $userModel->get_email();
201 - }
202 - }
203 -
204 - return false;
205 - }
206 -
207 - /**
208 - * @return bool|int
209 - */
210 - public function checkout_email_exists() {
211 - $email = $this->get_checkout_email();
212 -
213 - if ( ! $email ) {
214 - return false;
215 - }
216 -
217 - $user = get_user_by( 'email', $email );
218 - if ( ! $user ) {
219 - return false;
220 - }
221 -
222 - return $user->ID;
223 - }
224 -
225 - /**
226 - * Create LP Order.
227 - *
228 - * @return mixed|string
229 - * @throws Exception
230 - * @since 3.0.0
231 - * @version 4.0.3
232 - */
233 - public function create_order() {
234 - $cart = LearnPress::instance()->cart;
235 - $cart_total = $cart->calculate_totals();
236 - $order = new LP_Order();
237 - $user_id = 0;
238 - $user_can_register = get_option( 'users_can_register' );
239 -
240 - if ( is_user_logged_in() ) {
241 - $user_id = get_current_user_id();
242 - } elseif ( $user_can_register ) {
243 - $checkout_option = LP_Request::get_param( 'checkout-email-option' );
244 - // Set user id for Order if buy with Guest and email exists on the user
245 - $user_id = $this->checkout_email_exists();
246 -
247 - // Create new user if buy with Guest and tick "Create new Account"
248 - if ( $checkout_option === 'new-account' ) {
249 - if ( $user_id ) {
250 - throw new Exception( __( 'New account email is existed', 'learnpress' ), 0 );
251 - }
252 -
253 - //$order->set_meta( '_create_account', 'yes' );
254 -
255 - $user_id = $this->create_account();
256 - if ( $user_id ) {
257 - // Notify mail create user success
258 - wp_new_user_notification( $user_id, null, apply_filters( 'learn-press/email-create-new-user-when-checkout', 'user' ) );
259 - } else {
260 - throw new Exception( __( 'Create account failed', 'learnpress' ), 0 );
261 - }
262 - }
263 -
264 - // Get user_id Guest
265 - if ( ! $user_id ) {
266 - /**
267 - * @var LP_User_Guest $user_guest
268 - */
269 - $user_guest = learn_press_get_user();
270 - $user_id = $user_guest->get_id();
271 - }
272 - }
273 -
274 - if ( $this->is_enable_guest_checkout() && $this->get_checkout_email() ) {
275 - $order->set_checkout_email( $this->get_checkout_email() );
276 - // Check email exists on the user will get user_id to set
277 - if ( ! $user_id ) {
278 - $user_id = $this->checkout_email_exists();
279 - }
280 - }
281 -
282 - $order->set_customer_note( $this->order_comment );
283 - $order->set_status( LP_ORDER_PENDING );
284 - $order->set_total( $cart_total->total );
285 - $order->set_subtotal( $cart_total->subtotal );
286 - $order->set_user_ip_address( learn_press_get_ip() );
287 - $order->set_user_agent( learn_press_get_user_agent() );
288 - $order->set_created_via( 'checkout' );
289 - $order->set_user_id( apply_filters( 'learn-press/checkout/default-user', $user_id ) );
290 - if ( $this->payment_method instanceof LP_Gateway_Abstract ) {
291 - $order->set_data( 'payment_method', $this->payment_method->get_id() );
292 - $order->set_data( 'payment_method_title', $this->payment_method->get_title() );
293 - }
294 -
295 - $order_id = $order->save();
296 -
297 - // Store the line items to the order
298 - foreach ( $cart->get_items() as $item ) {
299 - $item_type = get_post_type( $item['item_id'] );
300 - if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
301 - continue;
302 - }
303 -
304 - $item_id = $order->add_item( $item );
305 - if ( ! $item_id ) {
306 - throw new Exception( sprintf( __( 'Error %d: Unable to add item to order. Please try again.', 'learnpress' ), 402 ) );
307 - }
308 -
309 - do_action( 'learn-press/checkout/add-order-item-meta', $item_id, $item );
310 - }
311 -
312 - if ( ! empty( $this->user_id ) ) {
313 - do_action( 'learn-press/checkout/update-user-meta', $this->user_id );
314 - }
315 -
316 - do_action( 'learn-press/checkout/update-order-meta', $order_id );
317 -
318 - return $order_id;
319 - }
320 -
321 - /**
322 - * Guest checkout is enable?
323 - *
324 - * @return bool
325 - * @since 3.0.0
326 - */
327 - public function is_enable_guest_checkout(): bool {
328 - return apply_filters(
329 - 'learn-press/checkout/enable-guest',
330 - LP_Settings::get_option( 'guest_checkout', 'no' ) === 'yes'
331 - );
332 - }
333 -
334 - /**
335 - * Enable user can log in checkout page?
336 - *
337 - * @return bool
338 - * @since 3.0.0
339 - */
340 - public function is_enable_login(): bool {
341 - return apply_filters(
342 - 'learn-press/checkout/enable-login',
343 - 'yes' === LP_Settings::get_option( 'enable_login_checkout', 'yes' )
344 - );
345 - }
346 -
347 - /**
348 - * Enable user can register in checkout page?
349 - *
350 - * @return bool
351 - * @since 3.0.0
352 - */
353 - public function is_enable_register(): bool {
354 - return apply_filters(
355 - 'learn-press/checkout/enable-register',
356 - 'yes' === LP_Settings::get_option( 'enable_registration_checkout', 'yes' )
357 - && get_option( 'users_can_register' )
358 - );
359 - }
360 -
361 - /**
362 - * Process checkout from request.
363 - *
364 - * @return void
365 - * @throws Exception
366 - */
367 - public function process_checkout_handler() {
368 - if ( strtolower( $_SERVER['REQUEST_METHOD'] ) != 'post' ) {
369 - return;
370 - }
371 -
372 - /**
373 - * Set default fields from request.
374 - */
375 - $this->payment_method_str = LP_Request::get_param( 'payment_method' );
376 - $this->order_comment = LP_Request::get_param( 'order_comments' );
377 - $this->_checkout_email = LP_Request::get_param( 'checkout-email' );
378 - if ( $this->_checkout_email ) {
379 - LearnPress::instance()->session->set( 'checkout-email', $this->_checkout_email );
380 - }
381 -
382 - $this->process_checkout();
383 - }
384 -
385 - /**
386 - * Validate fields.
387 - *
388 - * Addon Upsell 4.0.1 use argument $errors
389 - * Must update to 4.0.2 to use throw Error instead.
390 - *
391 - * @throws Exception
392 - */
393 - public function validate_checkout_fields() {
394 - $this->errors = array();
395 -
396 - // Check nonce
397 - $nonce = LP_Request::get_param( 'learn-press-checkout-nonce' );
398 - if ( ! wp_verify_nonce( $nonce, 'learn-press-checkout' ) ) {
399 - throw new Exception( __( 'Your session has expired.', 'learnpress' ) );
400 - }
401 -
402 - $this->check_validate_fields();
403 -
404 - do_action( 'learn-press/validate-checkout-fields', $this );
405 - }
406 -
407 - /**
408 - * Validate checkout payment.
409 - *
410 - * @throws Exception
411 - */
412 - public function validate_payment() {
413 - $cart = LearnPress::instance()->cart;
414 - //$validate = true;
415 -
416 - if ( $cart->needs_payment() ) {
417 - if ( ! $this->payment_method instanceof LP_Gateway_Abstract ) {
418 - $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
419 -
420 - if ( ! isset( $available_gateways[ $this->payment_method_str ] ) ) {
421 - throw new Exception( __( 'No payment method is selected', 'learnpress' ), LP_ERROR_NO_PAYMENT_METHOD_SELECTED );
422 - } else {
423 - $this->payment_method = $available_gateways[ $this->payment_method_str ];
424 - }
425 -
426 - $this->payment_method->validate_fields();
427 - }
428 - }
429 - }
430 -
431 - /**
432 - * Process checkout.
433 - *
434 - * @throws Exception
435 - */
436 - public function process_checkout() {
437 - ini_set( 'max_execution_time', HOUR_IN_SECONDS );
438 - $result = array(
439 - 'result' => 'fail',
440 - 'message' => '',
441 - );
442 -
443 - try {
444 - $lp_session = LearnPress::instance()->session;
445 -
446 - do_action( 'learn-press/before-checkout' );
447 -
448 - $cart = LearnPress::instance()->cart;
449 - if ( $cart->is_empty() ) {
450 - throw new Exception( __( 'Your cart is currently empty.', 'learnpress' ) );
451 - }
452 -
453 - foreach ( $cart->get_items() as $item ) {
454 - $item_type = get_post_type( $item['item_id'] );
455 -
456 - if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
457 - throw new Exception( __( 'Type item buy invalid!', 'learnpress' ) );
458 - }
459 - }
460 -
461 - // Validate fields
462 - $this->validate_checkout_fields();
463 - // Validate payment method
464 - $this->validate_payment();
465 -
466 - $user_id = $this->checkout_email_exists();
467 - if ( ! $user_id ) {
468 - $user_id = 0;
469 - }
470 -
471 - // Check user can purchase, enrolled course
472 - foreach ( $cart->get_items() as $item ) {
473 - $item_type = get_post_type( $item['item_id'] );
474 - if ( LP_COURSE_CPT === $item_type ) {
475 - $courseModel = CourseModel::find( $item['item_id'], true );
476 - if ( ! $courseModel ) {
477 - throw new Exception( __( 'Course is invalid!', 'learnpress' ) );
478 - }
479 -
480 - $userModel = UserModel::find( $user_id, true );
481 -
482 - // Check user can purchase course
483 - if ( ! $courseModel->is_free() ) {
484 - $can_purchase = $courseModel->can_purchase( $userModel );
485 - if ( is_wp_error( $can_purchase ) ) {
486 - //throw new Exception( $can_purchase->get_error_message() );
487 - learn_press_set_message(
488 - [
489 - 'status' => 'error',
490 - 'content' => $can_purchase->get_error_message(),
491 - ]
492 - );
493 - $result['redirect'] = LP_Page_Controller::get_link_page( 'checkout', [], true );
494 - $result['message'] = $can_purchase->get_error_message();
495 - learn_press_send_json( $result );
496 - }
497 - } else {
498 - // Check user can enroll course
499 - $can_enroll = $courseModel->can_enroll( $userModel );
500 - if ( is_wp_error( $can_enroll ) ) {
501 - learn_press_set_message(
502 - [
503 - 'status' => 'error',
504 - 'content' => $can_enroll->get_error_message(),
505 - ]
506 - );
507 - $result['redirect'] = LP_Page_Controller::get_link_page( 'checkout', [], true );
508 - $result['message'] = $can_enroll->get_error_message();
509 - learn_press_send_json( $result );
510 - }
511 - }
512 - }
513 - }
514 -
515 - // Create order if not handle done.
516 - $order_id = $lp_session->get( 'order_awaiting_payment', 0 );
517 - if ( ! $order_id ) {
518 - $order_id = $this->create_order();
519 - if ( is_wp_error( $order_id ) ) {
520 - throw new Exception( $order_id->get_error_message() );
521 - }
522 -
523 - $lp_session->set( 'order_awaiting_payment', $order_id, true );
524 - }
525 -
526 - // allow Third-party hook: send email and more...
527 - do_action( 'learn-press/checkout-order-processed', $order_id, $this );
528 -
529 - if ( $this->payment_method instanceof LP_Gateway_Abstract ) {
530 - // Process Payment
531 - $result = $this->payment_method->process_payment( $order_id );
532 - if ( isset( $result['result'] ) ) {
533 - if ( 'success' === $result['result'] ) {
534 - // Clear cart.
535 - LearnPress::instance()->get_cart()->empty_cart();
536 - $result = apply_filters( 'learn-press/payment-successful-result', $result, $order_id );
537 - }
538 -
539 - if ( ! learn_press_is_ajax() ) {
540 - ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
541 - wp_redirect( $result['redirect'] );
542 - exit;
543 - }
544 - }
545 - } else {
546 - // For case enroll a course free.
547 - $order = new LP_Order( $order_id );
548 - if ( $order->payment_complete() ) {
549 - $redirect = $order->get_checkout_order_received_url();
550 -
551 - // Clear cart.
552 - LearnPress::instance()->get_cart()->empty_cart();
553 -
554 - $result = array(
555 - 'result' => 'success',
556 - 'redirect' => $redirect,
557 - );
558 -
559 - if ( ! learn_press_is_ajax() ) {
560 - ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
561 - wp_redirect( $result['redirect'] );
562 - exit;
563 - }
564 - }
565 - }
566 - } catch ( Throwable $e ) {
567 - $result['message'] = $e->getMessage();
568 - }
569 -
570 - ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
571 - learn_press_send_json( $result );
572 - }
573 -}
1 +<?php
2 +/**
3 + * Class LP_Checkout
4 + *
5 + * @author ThimPress <Nhamdv>
6 + * @package LearnPress/Classes
7 + * @version 4.0.0
8 + */
9 +
10 +use LearnPress\Helpers\Singleton;
11 +use LearnPress\Models\CourseModel;
12 +use LearnPress\Models\UserModel;
13 +
14 +defined( 'ABSPATH' ) || exit;
15 +
16 +class LP_Checkout {
17 + use Singleton;
18 +
19 + /**
20 + * Payment method
21 + *
22 + * @var LP_Gateway_Abstract
23 + */
24 + public $payment_method = null;
25 + /**
26 + * Payment method string when user choice
27 + *
28 + * @var string $payment_method_str
29 + */
30 + public $payment_method_str = '';
31 + /**
32 + * @var null
33 + */
34 + public $user_login = null;
35 + /**
36 + * @var null
37 + */
38 + public $user_pass = null;
39 + /**
40 + * @var null
41 + */
42 + public $order_comment = null;
43 + /**
44 + * Handle the errors when checking out.
45 + *
46 + * @var array
47 + */
48 + public $errors = array();
49 + /**
50 + * @var string
51 + */
52 + protected $_checkout_email = '';
53 + /**
54 + * @var string
55 + * @since 4.0.0
56 + */
57 + protected $guest_email = '';
58 + /**
59 + * @var string
60 + * @since 4.0.0
61 + */
62 + protected $checkout_action = '';
63 +
64 + public function init(): void {
65 + if ( ! is_null( LearnPress::instance()->session ) ) {
66 + $this->_checkout_email = LearnPress::instance()->session->get( 'checkout-email' );
67 + }
68 +
69 + add_action( 'set_logged_in_cookie', [ $this, 'set_logged_in_cookie' ] );
70 + }
71 +
72 + /**
73 + * Create account when checking out with user guest and tick create account.
74 + *
75 + * @return int|WP_Error
76 + */
77 + protected function create_account(): int {
78 + $user_id = 0;
79 +
80 + try {
81 + $email = $this->get_checkout_email();
82 + $password = wp_generate_password();
83 + $user_id = wp_create_user( $email, $password, $email );
84 + } catch ( Throwable $e ) {
85 + error_log( $e->getMessage() );
86 + }
87 +
88 + return $user_id;
89 + }
90 +
91 + /**
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.
95 + *
96 + * @throws Exception
97 + */
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;
102 +
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 + }
110 +
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 + );
121 +
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 + );
135 +
136 + if ( isset( $_POST['reg_first_name'] ) ) {
137 + $default_fields['first_name'] = LP_Request::get_param( 'reg_first_name' );
138 + }
139 +
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' ) );
168 + }
169 +
170 + /*if ( ! wp_check_password( $default_fields['reg_password'], $user->user_pass, $user->ID ) ) {
171 + throw new Exception( __( 'Incorrect password.', 'learnpress' ) );
172 + }*/
173 +
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 + }
184 +
185 + $this->guest_email = $email_guest;
186 + $this->_checkout_email = $email_guest;
187 + break;
188 + }
189 +
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 ) );
194 + }
195 + $session->save_data();
196 + }
197 + }
198 +
199 + /**
200 + * Get email of user is being checkout.
201 + *
202 + * @return string
203 + */
204 + public function get_checkout_email() {
205 + if ( $this->_checkout_email ) {
206 + return $this->_checkout_email;
207 + } elseif ( is_user_logged_in() ) {
208 + $userModel = UserModel::find( get_current_user_id(), true );
209 + if ( $userModel instanceof UserModel ) {
210 + return $userModel->get_email();
211 + }
212 + }
213 +
214 + return false;
215 + }
216 +
217 + /**
218 + * @return bool|int
219 + */
220 + public function checkout_email_exists() {
221 + $email = $this->get_checkout_email();
222 +
223 + if ( ! $email ) {
224 + return false;
225 + }
226 +
227 + $user = get_user_by( 'email', $email );
228 + if ( ! $user ) {
229 + return false;
230 + }
231 +
232 + return $user->ID;
233 + }
234 +
235 + /**
236 + * Create LP Order.
237 + *
238 + * @return mixed|string
239 + * @throws Exception
240 + * @since 3.0.0
241 + * @version 4.0.3
242 + */
243 + public function create_order() {
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' );
249 +
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();
256 +
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 );
261 + }
262 +
263 + //$order->set_meta( '_create_account', 'yes' );
264 +
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 );
275 + }
276 + }
277 +
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();
285 + }
286 + }
287 +
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();
293 + }
294 + }
295 +
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 + }
308 +
309 + $order_id = $order->save();
310 +
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;
316 + }
317 +
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 ) );
321 + }
322 +
323 + do_action( 'learn-press/checkout/add-order-item-meta', $item_id, $item );
324 + }
325 +
326 + if ( ! empty( $this->user_id ) ) {
327 + do_action( 'learn-press/checkout/update-user-meta', $this->user_id );
328 + }
329 +
330 + do_action( 'learn-press/checkout/update-order-meta', $order_id );
331 +
332 + return $order_id;
333 + }
334 +
335 + /**
336 + * Guest checkout is enable?
337 + *
338 + * @return bool
339 + * @since 3.0.0
340 + */
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 + );
346 + }
347 +
348 + /**
349 + * Enable user can log in checkout page?
350 + *
351 + * @return bool
352 + * @since 3.0.0
353 + */
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 + );
359 + }
360 +
361 + /**
362 + * Enable user can register in checkout page?
363 + *
364 + * @return bool
365 + * @since 3.0.0
366 + */
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 + );
373 + }
374 +
375 + /**
376 + * Process checkout from request.
377 + *
378 + * @return void
379 + * @throws Exception
380 + */
381 + public function process_checkout_handler() {
382 + if ( strtolower( $_SERVER['REQUEST_METHOD'] ) != 'post' ) {
383 + return;
384 + }
385 +
386 + /**
387 + * Set default fields from request.
388 + */
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' );
392 + if ( $this->_checkout_email ) {
393 + LearnPress::instance()->session->set( 'checkout-email', $this->_checkout_email );
394 + }
395 +
396 + $this->process_checkout();
397 + }
398 +
399 + /**
400 + * Validate fields.
401 + *
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
406 + */
407 + public function validate_checkout_fields() {
408 + $this->errors = array();
409 +
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' ) );
414 + }
415 +
416 + $this->check_validate_fields();
417 +
418 + do_action( 'learn-press/validate-checkout-fields', $this );
419 + }
420 +
421 + /**
422 + * Validate checkout payment.
423 + *
424 + * @throws Exception
425 + */
426 + public function validate_payment() {
427 + $cart = LearnPress::instance()->cart;
428 + //$validate = true;
429 +
430 + if ( $cart->needs_payment() ) {
431 + if ( ! $this->payment_method instanceof LP_Gateway_Abstract ) {
432 + $available_gateways = LP_Gateways::instance()->get_available_payment_gateways();
433 +
434 + if ( ! isset( $available_gateways[ $this->payment_method_str ] ) ) {
435 + throw new Exception( __( 'No payment method is selected', 'learnpress' ), LP_ERROR_NO_PAYMENT_METHOD_SELECTED );
436 + } else {
437 + $this->payment_method = $available_gateways[ $this->payment_method_str ];
438 + }
439 +
440 + $this->payment_method->validate_fields();
441 + }
442 + }
443 + }
444 +
445 + /**
446 + * Process checkout.
447 + *
448 + * @throws Exception
449 + */
450 + public function process_checkout() {
451 + ini_set( 'max_execution_time', HOUR_IN_SECONDS );
452 + $result = array(
453 + 'result' => 'fail',
454 + 'message' => '',
455 + );
456 +
457 + try {
458 + $lp_session = LearnPress::instance()->session;
459 +
460 + do_action( 'learn-press/before-checkout' );
461 +
462 + $cart = LearnPress::instance()->cart;
463 + if ( $cart->is_empty() ) {
464 + throw new Exception( __( 'Your cart is currently empty.', 'learnpress' ) );
465 + }
466 +
467 + foreach ( $cart->get_items() as $item ) {
468 + $item_type = get_post_type( $item['item_id'] );
469 +
470 + if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
471 + throw new Exception( __( 'Type item buy invalid!', 'learnpress' ) );
472 + }
473 + }
474 +
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' ) );
492 + }
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 + }
526 + }
527 + }
528 +
529 + // Create order if not handle done.
530 + $order_id = $lp_session->get( 'order_awaiting_payment', 0 );
531 + if ( ! $order_id ) {
532 + $order_id = $this->create_order();
533 + if ( is_wp_error( $order_id ) ) {
534 + throw new Exception( $order_id->get_error_message() );
535 + }
536 +
537 + $lp_session->set( 'order_awaiting_payment', $order_id, true );
538 + }
539 +
540 + // allow Third-party hook: send email and more...
541 + do_action( 'learn-press/checkout-order-processed', $order_id, $this );
542 +
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'] ) {
548 + // Clear cart.
549 + LearnPress::instance()->get_cart()->empty_cart();
550 + $result = apply_filters( 'learn-press/payment-successful-result', $result, $order_id );
551 + }
552 +
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;
557 + }
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();
564 +
565 + // Clear cart.
566 + LearnPress::instance()->get_cart()->empty_cart();
567 +
568 + $result = array(
569 + 'result' => 'success',
570 + 'redirect' => $redirect,
571 + );
572 +
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;
577 + }
578 + }
579 + }
580 + } catch ( Throwable $e ) {
581 + $result['message'] = $e->getMessage();
582 + }
583 +
584 + ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
585 + learn_press_send_json( $result );
586 + }
587 +
588 + /**
589 + * Sync $_COOKIE[LOGGED_IN_COOKIE] within the current checkout request.
590 + *
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.
600 + */
601 + public function set_logged_in_cookie( $logged_in_cookie ) {
602 + if ( ! isset( $_POST['learn-press-checkout-nonce'] ) ) {
603 + return;
604 + }
605 +
606 + $_COOKIE[ LOGGED_IN_COOKIE ] = $logged_in_cookie;
607 + }
608 +}