PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.7
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 / order / lp-order-functions.php

lp-order-functions.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.7, at inc/order/lp-order-functions.php

446 lines 12.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Defines functions related to order
4 *
5 * @author ThimPress
6 * @package LearnPress/Functions
7 * @version 1.0
8 */
9
10 defined( 'ABSPATH' ) || exit;
11
12 /**
13 * Generate unique key for an order.
14 *
15 * @return mixed
16 */
17 function learn_press_generate_order_key() {
18 return apply_filters( 'learn-press/order-key', strtoupper( uniqid( 'ORDER' ) ) );
19 }
20
21 /**
22 * Update Order status
23 *
24 * @param int
25 * @param string
26 *
27 * @return bool
28 */
29 function learn_press_update_order_status( $order_id, $status = '' ) {
30 $order = new LP_Order( $order_id );
31 if ( $order ) {
32 return $order->update_status( $status );
33 }
34
35 return false;
36 }
37
38 /**
39 * Add order item meta data.
40 *
41 * @param int $item_id
42 * @param string $meta_key
43 * @param mixed $meta_value
44 * @param string $prev_value
45 *
46 * @return false|int
47 */
48 function learn_press_add_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) {
49 return add_metadata( 'learnpress_order_item', $item_id, $meta_key, $meta_value, $prev_value );
50 }
51
52 /**
53 * Update order item meta data.
54 *
55 * @param int $item_id
56 * @param string $meta_key
57 * @param mixed $meta_value
58 * @param string $prev_value
59 *
60 * @return bool|int
61 */
62 function learn_press_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) {
63 return update_metadata( 'learnpress_order_item', $item_id, $meta_key, $meta_value, $prev_value );
64 }
65
66 /**
67 * Delete order item meta data.
68 *
69 * @param int $item_id
70 * @param string $meta_key
71 * @param mixed $meta_value
72 * @param bool $delete_all
73 *
74 * @return bool
75 */
76 function learn_press_delete_order_item_meta( $item_id, $meta_key, $meta_value, $delete_all = false ) {
77 return delete_metadata( 'learnpress_order_item', $item_id, $meta_key, $meta_value, $delete_all );
78 }
79
80 /**
81 * Get order item meta data.
82 *
83 * @param int $item_id
84 * @param string $meta_key
85 * @param bool $single
86 *
87 * @return mixed
88 */
89 function learn_press_get_order_item_meta( $item_id, $meta_key, $single = true ) {
90 return get_metadata( 'learnpress_order_item', $item_id, $meta_key, $single );
91 }
92
93 /**
94 * Get order
95 *
96 * @param mixed $the_order
97 *
98 * @return LP_Order|bool object instance
99 */
100 function learn_press_get_order( $the_order = false ) {
101 global $post;
102 $the_id = 0;
103 if ( false === $the_order && is_a( $post, 'WP_Post' ) && LP_ORDER_CPT === get_post_type( $post ) ) {
104 $the_id = $post->ID;
105 } elseif ( is_numeric( $the_order ) ) {
106 $the_id = $the_order;
107 } elseif ( $the_order instanceof LP_Order ) {
108 $the_id = $the_order->get_id();
109 } elseif ( ! empty( $the_order->ID ) ) {
110 $the_id = $the_order->ID;
111 }
112
113 if ( LP_ORDER_CPT != get_post_type( $the_id ) ) {
114 return false;
115 }
116
117 return new LP_Order( $the_id );
118 }
119
120 /**
121 * Count orders by it's status
122 *
123 * @param array $args
124 * @Todo tungnx review to rewrite query
125 * @return array
126 */
127 function learn_press_count_orders( $args = array() ) {
128 if ( is_string( $args ) ) {
129 $args = array( 'status' => $args );
130 } else {
131 $args = wp_parse_args(
132 $args,
133 array(
134 'status' => '',
135 )
136 );
137 }
138 global $wpdb;
139 $statuses = $args['status'];
140
141 if ( ! $statuses ) {
142 $statuses = array_keys( LP_Order::get_order_statuses() );
143 }
144
145 settype( $statuses, 'array' );
146 $size_of_status = sizeof( $statuses );
147
148 foreach ( $statuses as $k => $status ) {
149 $statuses[ $k ] = ! preg_match( '~^lp-~', $status ) ? 'lp-' . $status : $status;
150 }
151
152 $format = array_fill( 0, $size_of_status, '%s' );
153 $counts = array_fill_keys( $statuses, 0 );
154 $statuses[] = LP_ORDER_CPT;
155 $query = $wpdb->prepare(
156 "
157 SELECT COUNT(ID) AS count, post_status AS status
158 FROM {$wpdb->posts} o
159 WHERE post_status IN(" . join( ',', $format ) . ')
160 AND post_type = %s
161 GROUP BY o.post_status
162 ',
163 $statuses
164 );
165
166 $results = $wpdb->get_results( $query );
167 if ( $results ) {
168 foreach ( $results as $result ) {
169 if ( array_key_exists( $result->status, $counts ) ) {
170 $counts[ $result->status ] = absint( $result->count );
171 }
172 }
173 }
174
175 return $size_of_status > 1 ? $counts : reset( $counts );
176 }
177
178 /**
179 * Format price with currency and other settings.
180 *
181 * @param float $price
182 * @param string $currency
183 *
184 * @return string
185 */
186 function learn_press_format_price( $price = 0, $currency = '' ): string {
187 if ( ! is_numeric( $price ) ) {
188 $price = 0;
189 }
190
191 $before = $after = '';
192
193 $currency = esc_html(
194 is_string( $currency ) && '' !== $currency
195 ? $currency
196 : learn_press_get_currency_symbol()
197 );
198 $thousands_separator = esc_html( LP_Settings::get_option( 'thousands_separator', ',' ) );
199 $number_of_decimals = esc_html( LP_Settings::get_option( 'number_of_decimals', 2 ) );
200 $decimals_separator = esc_html( LP_Settings::get_option( 'decimals_separator', '.' ) );
201
202 switch ( LP_Settings::get_option( 'currency_pos' ) ) {
203 default:
204 $before = $currency;
205 break;
206 case 'left_with_space':
207 $before = $currency . ' ';
208 break;
209 case 'right':
210 $after = $currency;
211 break;
212 case 'right_with_space':
213 $after = ' ' . $currency;
214 }
215
216 return $before . number_format( $price, $number_of_decimals, $decimals_separator, $thousands_separator ) . $after;
217 }
218
219 /**
220 * Update
221 *
222 * @param $order_id
223 *
224 * @return array|bool
225 */
226 function learn_press_update_order_items( $order_id ) {
227 $order = learn_press_get_order( $order_id );
228 if ( ! $order ) {
229 return false;
230 }
231
232 $subtotal = 0;
233 $total = 0;
234 $items = $order->get_items();
235
236 if ( $items ) {
237 foreach ( $items as $item ) {
238 $subtotal += $item['subtotal'];
239 $total += $item['total'];
240 }
241 }
242
243 update_post_meta( $order_id, '_order_currency', learn_press_get_currency() );
244 update_post_meta( $order_id, '_prices_include_tax', 'no' );
245 update_post_meta( $order_id, '_order_subtotal', $subtotal );
246 update_post_meta( $order_id, '_order_total', $total );
247 update_post_meta( $order_id, '_order_key', learn_press_generate_order_key() );
248 update_post_meta( $order_id, '_payment_method', '' );
249 update_post_meta( $order_id, '_payment_method_title', '' );
250 update_post_meta( $order_id, '_order_version', '1.0' );
251
252 return array(
253 'subtotal' => $subtotal,
254 'total' => $total,
255 'currency' => learn_press_get_currency(),
256 );
257 }
258
259 /**
260 * Format order's ID in ten numbers. Eg: 0000000XXX.
261 *
262 * @param int $order_number
263 *
264 * @since 2.0.0
265 *
266 * @return string
267 */
268 function learn_press_transaction_order_number( $order_number ) {
269 $formatted_number = apply_filters( 'learn_press_get_order_number', '#' . sprintf( "%'.010d", $order_number ), $order_number );
270
271 return apply_filters( 'learn-press/order-number-formatted', $formatted_number, $order_number );
272 }
273
274 /**
275 * Get list of registered order's statues for registering with wp post's status.
276 *
277 * @since 2.0.0
278 *
279 * @return array
280 */
281 function learn_press_get_register_order_statuses() {
282 $order_statues = array();
283
284 $order_statues['lp-completed'] = array(
285 'label' => _x( 'Completed', 'Order status', 'learnpress' ),
286 'public' => false,
287 'exclude_from_search' => false,
288 'show_in_admin_all_list' => true,
289 'show_in_admin_status_list' => true,
290 'label_count' => _n_noop( 'Completed <span class="count">(%s)</span>', 'Completed <span class="count">(%s)</span>', 'learnpress' ),
291 );
292 $order_statues['lp-pending'] = array(
293 'label' => _x( 'Pending', 'Order status', 'learnpress' ),
294 'public' => false,
295 'exclude_from_search' => false,
296 'show_in_admin_all_list' => true,
297 'show_in_admin_status_list' => true,
298 'label_count' => _n_noop( 'Pending Payment <span class="count">(%s)</span>', 'Pending Payment <span class="count">(%s)</span>', 'learnpress' ),
299 );
300 $order_statues['lp-processing'] = array(
301 'label' => _x( 'Processing', 'Order status', 'learnpress' ),
302 'public' => false,
303 'exclude_from_search' => false,
304 'show_in_admin_all_list' => true,
305 'show_in_admin_status_list' => true,
306 'label_count' => _n_noop( 'Processing <span class="count">(%s)</span>', 'Processing <span class="count">(%s)</span>', 'learnpress' ),
307 );
308 $order_statues['lp-cancelled'] = array(
309 'label' => _x( 'Cancelled', 'Order status', 'learnpress' ),
310 'public' => false,
311 'exclude_from_search' => false,
312 'show_in_admin_all_list' => true,
313 'show_in_admin_status_list' => true,
314 'label_count' => _n_noop( 'Cancelled <span class="count">(%s)</span>', 'Cancelled <span class="count">(%s)</span>', 'learnpress' ),
315 );
316 $order_statues['lp-failed'] = array(
317 'label' => _x( 'Failed', 'Order status', 'learnpress' ),
318 'public' => false,
319 'exclude_from_search' => false,
320 'show_in_admin_all_list' => true,
321 'show_in_admin_status_list' => true,
322 'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'learnpress' ),
323 );
324 $order_statues['trash'] = array(
325 'label' => _x( 'Trash', 'Order status', 'learnpress' ),
326 'public' => false,
327 'exclude_from_search' => false,
328 'show_in_admin_all_list' => true,
329 'show_in_admin_status_list' => true,
330 'label_count' => _n_noop( 'Trash <span class="count">(%s)</span>', 'Trash <span class="count">(%s)</span>', 'learnpress' ),
331 );
332
333 return $order_statues;
334 }
335
336 function _learn_press_get_order_status_description( $status ) {
337 $descriptions = array(
338 'pending' => __( 'Order received in case a user purchases a course but doesn\'t finalize the order.', 'learnpress' ),
339 'processing' => __( 'Payment received and the order is awaiting fulfillment.', 'learnpress' ),
340 'completed' => __( 'The order is fulfilled and completed.', 'learnpress' ),
341 'cancelled' => __( 'The order is cancelled by an admin or the customer.', 'learnpress' ),
342 );
343
344 return apply_filters( 'learn_press_order_status_description', ! empty( $descriptions[ $status ] ) ? $descriptions[ $status ] : '' );
345 }
346
347 /**
348 * Get status of an order by the ID.
349 *
350 * @param int $order_id
351 *
352 * @return bool|string
353 */
354 function learn_press_get_order_status( $order_id ) {
355 $order = learn_press_get_order( $order_id );
356
357 if ( $order ) {
358 return $order->get_status();
359 }
360
361 return false;
362 }
363
364 if ( ! function_exists( 'learn_press_cancel_order_process' ) ) {
365 /**
366 * Process action allows user to cancel an order is pending
367 * in their profile.
368 */
369 function learn_press_cancel_order_process() {
370 if ( empty( $_REQUEST['cancel-order'] ) || empty( $_REQUEST['lp-nonce'] ) ||
371 ! wp_verify_nonce( $_REQUEST['lp-nonce'], 'cancel-order' ) || is_admin() ) {
372 return;
373 }
374
375 $user_id = get_current_user_id();
376 $profile = LP_Profile::instance( $user_id );
377 $url = $profile->get_tab_link(
378 LP_Settings::instance()->get( 'profile_endpoints.orders', 'orders' )
379 );
380
381 try {
382 $message = [
383 'status' => 'error',
384 'content' => '',
385 ];
386
387 $order_id = absint( $_REQUEST['cancel-order'] );
388 $order = learn_press_get_order( $order_id );
389
390 if ( ! $order ) {
391 throw new Exception( sprintf( __( 'Order number <strong>%s</strong> not found', 'learnpress' ), $order_id ) );
392 }
393
394 $user_ids = (array) $order->get_user_id();
395 if ( ! in_array( $user_id, $user_ids ) ) {
396 throw new Exception( __( 'You do not have permission to cancel this order.', 'learnpress' ) );
397 }
398
399 if ( $order->has_status( LP_ORDER_PENDING ) ) {
400 $order->update_status( LP_ORDER_CANCELLED );
401 $order->add_note( __( 'The order is cancelled by the customer', 'learnpress' ) );
402
403 $message['status'] = 'success';
404 $message['content'] = sprintf( __( 'Order number <strong>%s</strong> has been cancelled', 'learnpress' ), $order->get_order_number() );
405 } else {
406 throw new Exception(
407 __( 'The order number <strong>%s</strong> can not be cancelled.', 'learnpress' ),
408 $order->get_order_number()
409 );
410 }
411 } catch ( Throwable $e ) {
412 $message['content'] = $e->getMessage();
413 }
414
415 learn_press_set_message( $message );
416 wp_safe_redirect( $url );
417 exit();
418 }
419 }
420 add_action( 'init', 'learn_press_cancel_order_process' );
421
422
423 /**
424 * get total price order complete
425 *
426 */
427
428 function learn_press_get_total_price_order_complete() {
429 global $wpdb;
430
431 $query = $wpdb->prepare(
432 "SELECT SUM(meta_value) as order_total From `{$wpdb->prefix}postmeta` as mt
433 INNER JOIN `{$wpdb->prefix}posts` as p ON p.id = mt.post_id
434 WHERE p.post_type = %s AND mt.meta_key = %s
435 AND p.post_status = %s
436 ",
437 LP_ORDER_CPT,
438 '_order_total',
439 'lp-completed'
440 );
441
442 $total = $wpdb->get_results( $query )[0]->order_total;
443
444 return learn_press_format_price( $total, true );
445 }
446