PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3.2
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
learnpress / inc / cart / class-lp-cart.php

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

500 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Cart
4 *
5 * Simple Cart object for now. Maybe need to expand later
6 *
7 * @author ThimPress
8 * @package LearnPress/Classes
9 * @version 1.0
10 */
11
12 defined( 'ABSPATH' ) || exit();
13
14 class LP_Cart {
15
16 /**
17 * Unique instance of LP_Cart
18 *
19 * @var LP_Cart object
20 */
21 private static $instances = array();
22
23 /**
24 * Hold the content of the cart
25 *
26 * @var array
27 */
28 protected $_cart_content = array();
29
30 /**
31 * Key of cart content stored in session
32 *
33 * @var string
34 */
35 protected $_cart_session_key = 'cart';
36
37 /**
38 * Cart total
39 *
40 * @var int
41 */
42 public $total = 0;
43
44 /**
45 * Cart subtotal
46 *
47 * @var int
48 */
49 public $subtotal = 0;
50
51 /**
52 * Constructor
53 *
54 * @param string $key . Added since 3.3.0
55 */
56 public function __construct( $key = '' ) {
57 if ( $key ) {
58 $this->_cart_session_key = $key;
59 }
60
61 LP_Request::register( 'add-course-to-cart', array( $this, 'add_to_cart' ), 20 );
62 LP_Request::register( 'remove-cart-item', array( $this, 'remove_item' ), 20 );
63
64 add_action( 'learn-press/add-to-cart', array( $this, 'calculate_totals' ), 10 );
65 //add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 );
66 //add_action( 'shutdown', array( $this, 'maybe_set_cart_cookies' ), 0 );
67 add_action( 'wp_loaded', array( $this, 'init' ) );
68 }
69
70 /**
71 * Init cart.
72 * Get data from session and put to cart content.
73 */
74 function init() {
75 // Only load on checkout page
76 $page_checkout_option = untrailingslashit( get_the_permalink( learn_press_get_page_id( 'checkout' ) ) );
77 $page_checkout_option = str_replace( '/', '\/', $page_checkout_option );
78 $pattern = '/' . $page_checkout_option . '/';
79 if ( ! preg_match( $pattern, LP_Helper::getUrlCurrent() ) ) {
80 return;
81 }
82
83 $this->get_cart_from_session();
84 }
85
86 /**
87 * @deprecated 4.1.7.2
88 */
89 public function maybe_set_cart_cookies() {
90
91 if ( ! headers_sent()/* && did_action( 'wp_loaded' )*/ ) {
92 // $this->set_cart_cookies( ! $this->is_empty() );
93 }
94 }
95
96 private function set_cart_cookies( $set = true ) {
97 if ( $set ) {
98 learn_press_setcookie( 'wordpress_lp_cart', 1 );
99 } elseif ( isset( $_COOKIE['wordpress_lp_cart'] ) ) {
100 learn_press_setcookie( 'wordpress_lp_cart', 0, time() - HOUR_IN_SECONDS );
101 }
102
103 do_action( 'learn_press_set_cart_cookies', $set );
104 }
105
106 /**
107 * Get data from session
108 *
109 * @return array
110 */
111 public function get_cart_for_session() {
112 $cart_session = array();
113
114 if ( $this->get_cart() ) {
115 foreach ( $this->get_cart() as $key => $values ) {
116 $cart_session[ $key ] = $values;
117 unset( $cart_session[ $key ]['data'] );
118 }
119 }
120
121 return $cart_session;
122 }
123
124 /**
125 * Get cart content.
126 *
127 * @return array
128 */
129 public function get_cart() {
130 if ( ! did_action( 'wp_loaded' ) ) {
131 _doing_it_wrong( __FUNCTION__, __( 'Get cart should not be called before the wp_loaded action.', 'learnpress' ), '2.3' );
132 }
133
134 if ( ! did_action( 'learn_press_cart_loaded_from_session' ) ) {
135 $this->get_cart_from_session();
136 }
137
138 return array_filter( (array) $this->_cart_content );
139 }
140
141 /**
142 * Add course to cart.
143 *
144 * @param int $item_id
145 * @param int $quantity
146 * @param array $item_data
147 *
148 * @return mixed
149 */
150 public function add_to_cart( int $item_id = 0, int $quantity = 1, array $item_data = array() ) {
151 try {
152 $item_type = get_post_type( $item_id );
153
154 if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
155 throw new Exception( 'Item type is invalid!', 'learnpress' );
156 }
157
158 switch ( $item_type ) {
159 case LP_COURSE_CPT:
160 $course = learn_press_get_course( $item_id );
161
162 if ( ! $course->is_purchasable() ) {
163 throw new Exception( __( 'Sorry! This course is not purchasable.', 'learnpress' ) );
164 }
165
166 if ( ! $course->is_in_stock() ) {
167 throw new Exception( __( 'Sorry! The number of enrolled students has reached its limit', 'learnpress' ) );
168 }
169
170 $item_data['data'] = $course;
171 break;
172 default:
173 $item_data = apply_filters( 'learnpress/cart/add-item/item_type_' . $item_type, $item_data, $item_id, $quantity );
174 break;
175 }
176
177 // $item_data = apply_filters( 'learnpress/cart/item-data', $item_data, $item_id );
178
179 $cart_id = $this->generate_cart_id( $item_id, $item_data );
180
181 $this->_cart_content[ $cart_id ] = apply_filters(
182 'learn_press_add_cart_item',
183 array_merge(
184 array(
185 'item_id' => $item_id,
186 'quantity' => $quantity,
187 'data' => array(),
188 ),
189 $item_data
190 )
191 );
192
193 $this->set_cart_cookies( true );
194
195 /**
196 * @see LP_Cart::calculate_totals()
197 */
198 do_action( 'learn-press/add-to-cart', $item_id, $quantity, $item_data, $cart_id );
199
200 return $cart_id;
201 } catch ( Exception $e ) {
202 if ( $e->getMessage() ) {
203 learn_press_add_message( $e->getMessage(), 'error' );
204 }
205
206 return false;
207 }
208 }
209
210 /**
211 * Remove an item from cart
212 *
213 * @param $item_id
214 *
215 * @return bool
216 */
217 public function remove_item( $item_id ) {
218 if ( isset( $this->_cart_content['items'][ $item_id ] ) ) {
219
220 do_action( 'learn_press_remove_cart_item', $item_id, $this );
221
222 unset( $this->_cart_content['items'][ $item_id ] );
223
224 do_action( 'learn_press_cart_item_removed', $item_id, $this );
225
226 $this->calculate_totals();
227
228 return true;
229 }
230
231 return false;
232 }
233
234 /**
235 * Re-calculate cart totals and update data to session
236 */
237 public function calculate_totals() {
238 $total = $subtotal = 0;
239 $this->total = $this->subtotal = 0;
240 $items = $this->get_cart();
241
242 if ( $items ) {
243 foreach ( $items as $cart_id => $item ) {
244
245 $item_type = get_post_type( $item['item_id'] );
246
247 if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
248 continue;
249 }
250
251 switch ( $item_type ) {
252 case LP_COURSE_CPT:
253 $course = learn_press_get_course( $item['item_id'] );
254 $subtotal = $course->get_price() * absint( $item['quantity'] );
255 break;
256 default:
257 $subtotal = apply_filters( 'learnpress/cart/calculate_sub_total/item_type_' . $item_type, $subtotal, $item );
258 break;
259 }
260
261 $total = $subtotal;
262
263 $this->_cart_content[ $cart_id ]['subtotal'] = $subtotal;
264 $this->_cart_content[ $cart_id ]['total'] = $total;
265
266 $this->subtotal += $subtotal;
267 $this->total += $total;
268 }
269 }
270
271 $this->update_session();
272 }
273
274 /**
275 * Update cart content to session
276 */
277 public function update_session() {
278 learn_press_session_set( $this->_cart_session_key, $this->get_cart_for_session() );
279 }
280
281 /**
282 * Get cart id
283 *
284 * @return mixed
285 */
286 public function get_cart_id() {
287 return ! empty( $_SESSION['learn_press_cart']['cart_id'] ) ? $_SESSION['learn_press_cart']['cart_id'] : 0;
288 }
289
290 /**
291 * Get all items from cart.
292 *
293 * @return array
294 */
295 public function get_items() {
296 $items = $this->get_cart();
297
298 return $items;
299 }
300
301 /**
302 * Load cart content data from session
303 *
304 * @since 3.0.0
305 * @version 3.0.1
306 */
307 public function get_cart_from_session() {
308 if ( did_action( 'learn_press_get_cart_from_session' ) ) {
309 return;
310 }
311
312 $cart = learn_press_session_get( $this->_cart_session_key );
313 $data = array();
314 if ( $cart ) {
315 foreach ( $cart as $cart_id => $values ) {
316 if ( ! empty( $values['item_id'] ) ) {
317 $item_type = get_post_type( $values['item_id'] );
318 if ( ! in_array( $item_type, learn_press_get_item_types_can_purchase() ) ) {
319 continue;
320 }
321
322 switch ( $item_type ) {
323 case LP_COURSE_CPT:
324 $course = learn_press_get_course( $values['item_id'] );
325 if ( $course && $course->exists() && $values['quantity'] > 0 ) {
326 if ( ! $course->is_purchasable() ) {
327 learn_press_add_message( sprintf( __( '%s has been removed from your cart because it can no longer be purchased.', 'learnpress' ), $course->get_title() ), 'error' );
328 do_action( 'learn-press/remove-cart-item-from-session', $cart, $values );
329 } else {
330 $data = array_merge( $values, array( 'data' => $course ) );
331 $this->_cart_content[ $cart_id ] = $data;
332 }
333 }
334 break;
335 default:
336 $this->_cart_content[ $cart_id ] = apply_filters( 'learn-press/get-cart-item-from-session/item_type_' . $item_type, $data, $values, $cart_id );
337 break;
338 }
339 }
340 }
341 }
342
343 do_action( 'learn_press_cart_loaded_from_session' );
344 LearnPress::instance()->session->set( $this->_cart_session_key, $this->get_cart_for_session() );
345 do_action( 'learn_press_get_cart_from_session' );
346
347 $this->calculate_totals();
348 }
349
350 /**
351 * Get cart sub-total
352 *
353 * @return mixed
354 */
355 public function get_subtotal() {
356 $subtotal = apply_filters( 'learn_press_get_cart_subtotal', learn_press_format_price( $this->subtotal, true ) );
357
358 return apply_filters( 'learn-press/cart-subtotal', $subtotal );
359 }
360
361 /**
362 * Get cart total
363 *
364 * @return mixed
365 */
366 public function get_total() {
367 $total = apply_filters( 'learn_press_get_cart_total', learn_press_format_price( $this->total, true ) );
368
369 return apply_filters( 'learn-press/cart-total', $total );
370 }
371
372 /**
373 * Generate unique cart id from course id and data.
374 *
375 * @param int $course_id
376 * @param mixed $data
377 *
378 * @return string
379 */
380 public function generate_cart_id( $course_id, $data = '' ) {
381 $cart_id = array( $course_id );
382
383 if ( is_array( $data ) ) {
384 foreach ( $data as $key => $value ) {
385 $cart_id[1] = '';
386
387 if ( is_array( $value ) || is_object( $value ) ) {
388 $value = http_build_query( $value );
389 }
390
391 $cart_id[1] .= trim( $key ) . trim( $value );
392 }
393 }
394
395 return apply_filters( 'learn-press/cart-id', md5( join( '_', $cart_id ) ), $cart_id, $data );
396 }
397
398 /**
399 * Return sub-total of cart content
400 *
401 * @param LP_Course $course
402 * @param int $quantity
403 *
404 * @return mixed
405 */
406 public function get_item_subtotal( $course, $quantity = 1 ) {
407 $price = $course->get_price();
408 $row_price = $price * $quantity;
409 $course_subtotal = learn_press_format_price( $row_price, true );
410
411 return apply_filters( 'learn-press/cart/item-subtotal', $course_subtotal, $course, $quantity, $this );
412 }
413
414 /**
415 * Clean all items from cart
416 *
417 * @return $this
418 */
419 public function empty_cart() {
420
421 do_action( 'learn-press/cart/before-empty' );
422
423 $this->_cart_content = array();
424
425 unset( LearnPress::instance()->session->order_awaiting_payment );
426 unset( LearnPress::instance()->session->cart );
427
428 do_action( 'learn-press/cart/emptied' );
429
430 return $this;
431 }
432
433 /**
434 * Check if cart is empty or not
435 *
436 * @return bool
437 */
438 public function is_empty() {
439 return sizeof( $this->get_cart() ) === 0;
440 }
441
442 /**
443 * Get checkout url for checkout page
444 * Return default url of checkout page
445 *
446 * @return mixed
447 */
448 public function get_checkout_url() {
449 $checkout_url = learn_press_get_page_link( 'checkout' );
450
451 return apply_filters( 'learn_press_get_checkout_url', $checkout_url );
452 }
453
454 /**
455 * Checks if need to payment
456 * Return true if cart total greater than 0
457 *
458 * @return mixed
459 */
460 public function needs_payment() {
461 return apply_filters( 'learn_press_cart_needs_payment', $this->total > 0, $this );
462 }
463
464 /**
465 * Destroy cart instance
466 */
467 public function destroy() {
468
469 }
470
471
472 /**
473 * Get unique instance of LP_Cart object
474 *
475 * @return LP_Cart|mixed
476 */
477 public static function instance() {
478 $class = __CLASS__;
479 if ( function_exists( 'get_called_class' ) ) {
480 $class = get_called_class();
481 }
482
483 $backtrace = debug_backtrace();
484
485 if ( isset( $backtrace[2]['function'] ) ) {
486 if ( 'call_user_func' === $backtrace[2]['function'] ) {
487 $class = $backtrace[2]['args'][0][0];
488 }
489 } elseif ( isset( $backtrace[2]['class'] ) ) {
490 $class = $backtrace[2]['class'];
491 }
492
493 if ( empty( self::$instances[ $class ] ) ) {
494 self::$instances[ $class ] = new $class();
495 }
496
497 return self::$instances[ $class ];
498 }
499 }
500