PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.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 4.2.1 All 138 releases
learnpress / inc / class-lp-checkout.php

class-lp-checkout.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.8, at inc/class-lp-checkout.php

574 lines 15.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 }
574