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 / custom-post-types / order.php

order.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.8, at inc/custom-post-types/order.php

862 lines 25.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @class LP_Order_Post_Type
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 1.0.2
8 */
9
10 use LearnPress\Ajax\ExportOrderCSVAjax;
11 use LearnPress\Databases\DataBase;
12 use LearnPress\Databases\PostDB;
13 use LearnPress\Filters\OrderPostFilter;
14 use LearnPress\Filters\PostFilter;
15 use LearnPress\Models\UserItems\UserCourseModel;
16 use LearnPress\Models\UserItems\UserItemModel;
17
18 if ( ! class_exists( 'LP_Order_Post_Type' ) ) {
19 final class LP_Order_Post_Type extends LP_Abstract_Post_Type {
20 /**
21 * Type of post
22 *
23 * @var string
24 */
25 protected $_post_type = LP_ORDER_CPT;
26 /**
27 * @var null
28 */
29 protected static $_instance = null;
30
31 /**
32 * LP_Order_Post_Type constructor.
33 *
34 */
35 public function __construct() {
36 add_action( 'admin_init', array( $this, 'register_post_statues' ) );
37 //add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
38 add_action( 'posts_pre_query', array( $this, 'posts_pre_query' ), 999, 2 );
39 //add_action( 'admin_init', array( $this, 'remove_box' ) );
40 //add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
41 add_filter( 'wp_untrash_post_status', array( $this, 'restore_status_order' ), 11, 3 );
42 add_filter( 'admin_footer', array( $this, 'admin_footer' ) );
43 //add_filter( 'views_edit-lp_order', array( $this, 'filter_views' ) );
44 // Download order CSV file
45 $this->download_order_csv_file();
46
47 // Override title of LP Order on Admin
48 if ( is_admin() ) {
49 $can_override_title_order = false;
50 $current_url = LP_Helper::getUrlCurrent();
51 $post_id = LP_Helper::sanitize_params_submitted( $_GET['post'] ?? '' );
52 if ( ! empty( $post_id ) ) {
53 $post = get_post( $post_id );
54 if ( $post && $post->post_type == LP_ORDER_CPT ) {
55 $can_override_title_order = true;
56 }
57 } elseif ( strpos( $current_url, 'post_type=lp_order' ) !== false ) {
58 $can_override_title_order = true;
59 }
60
61 if ( $can_override_title_order ) {
62 add_filter( 'the_title', array( $this, 'order_title' ), 5, 2 );
63 }
64 }
65
66 parent::__construct();
67 }
68
69 /**
70 * Unset value in 'mine' key in views of LP Orders.
71 * The 'mine' is present in some case when 'user_posts_count'
72 * is not the same with total posts then wp add it to the views
73 * of WP Posts List table.
74 *
75 * @param array $views
76 *
77 * @return mixed
78 */
79 public function filter_views( $views ) {
80 if ( isset( $views['mine'] ) ) {
81 unset( $views['mine'] );
82 }
83
84 return $views;
85 }
86
87 /**
88 * Filter to hide orders are created by one order for multiple users.
89 *
90 * @param string $where
91 *
92 * @return string
93 */
94 public function filter_orders( string $where ): string {
95 if ( ! $this->is_page_list_posts_on_backend() ) {
96 return $where;
97 }
98
99 global $wpdb;
100
101 if ( isset( $_REQUEST['parent'] ) ) {
102 $where .= sprintf( ' AND post_parent = %d ', absint( $_REQUEST['parent'] ) );
103 } else {
104 // $where .= $wpdb->prepare( " AND (post_parent = 0 OR {$wpdb->posts}.ID IN( SELECT post_parent FROM {$wpdb->posts} X WHERE X.post_parent <> 0 AND X.post_type = %s) )", LP_ORDER_CPT );
105 $where .= ' AND post_parent = 0 ';
106 }
107
108 return $where;
109 }
110
111 public function enqueue_scripts() {
112 if ( get_post_type() != $this->_post_type ) {
113 return;
114 }
115 wp_enqueue_script( 'user-suggest' );
116 }
117
118 /**
119 * Restore user course item when the order is stored (usually from trash).
120 *
121 * @param string $new_status
122 * @param int $post_id
123 * @param string $previous_status
124 *
125 * @return string
126 */
127 public function restore_status_order( string $new_status, int $post_id, string $previous_status ): string {
128 if ( LP_ORDER_CPT != get_post_type( $post_id ) ) {
129 return $new_status;
130 }
131
132 return $previous_status;
133 }
134
135 /**
136 * Save order post.
137 *
138 * @param int $post_id
139 * @param WP_Post $post
140 * @param bool $is_update
141 *
142 * @editor tungnx
143 * @version 1.0.6
144 */
145 public function save_post( int $post_id, ?WP_Post $post = null, bool $is_update = false ) {
146 try {
147 $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
148 if ( isset( $backtrace[6]['class'] ) && $backtrace[6]['class'] === LP_Order_CURD::class ) {
149 return;
150 }
151
152 if ( wp_is_post_revision( $post_id ) ) {
153 return;
154 }
155
156 // For create LP Order manual on Backend
157 $order = learn_press_get_order( $post_id );
158 if ( ! $order ) {
159 return;
160 }
161
162 $created_via = $order->get_created_via();
163 if ( empty( $created_via ) ) {
164 $created_via = LP_ORDER_CREATED_VIA_MANUAL;
165 $order->set_created_via( $created_via );
166 }
167
168 if ( isset( $_POST['order-customer'] ) && $order->is_manual() ) {
169 $user_id = LP_Request::get_param( 'order-customer' );
170 $order->set_user_id( $user_id );
171 }
172
173 if ( isset( $_POST['order-date'] ) ) {
174 $order_date = LP_Request::get_param( 'order-date' );
175 $order_hour = LP_Request::get_param( 'order-hour', '00' );
176 $order_min = LP_Request::get_param( 'order-minute', '00' );
177 $order->set_order_date( $order_date . ' ' . $order_hour . ':' . $order_min . ':00' );
178 }
179
180 $status = LP_Request::get_param( 'order-status' );
181 if ( ! empty( $status ) ) {
182 $order->update_status( $status );
183 } elseif ( $post->post_status === 'auto-draft' ) {
184 $order->update_status( 'pending' );
185 }
186
187 $order->save();
188 } catch ( Throwable $e ) {
189 error_log( __METHOD__ . ':' . $e->getMessage() );
190 }
191 }
192
193 /**
194 * Remove unused boxes
195 */
196 public function remove_box() {
197 remove_post_type_support( LP_ORDER_CPT, 'title' );
198 remove_post_type_support( LP_ORDER_CPT, 'editor' );
199 }
200
201 public function admin_footer() {
202 if ( ! $this->is_page_list_posts_on_backend() ) {
203 return;
204 }
205 ?>
206 <script type="text/javascript">
207 jQuery(function ($) {
208 $('#post-search-input').prop('placeholder',
209 '<?php esc_attr_e( 'Order number, course name, etc.', 'learnpress' ); ?>').css('width', 300)
210 })
211 </script>
212 <?php
213 }
214
215 /**
216 * Hook to filter LP orders by some conditions.
217 *
218 * @param string $where
219 *
220 * @return string
221 * @throws Exception
222 */
223 /*public function posts_where_paged( $where ) {
224 // Code temporary, when release about 1 week, will remove it.
225 $lp_filter_post = new LP_Post_Type_Filter();
226 $lp_filter_post->post_type = LP_ORDER_CPT;
227 $lp_filter_post->post_status = [ 'lp-trash' ];
228 $orders_trash = LP_Post_DB::getInstance()->get_posts( $lp_filter_post );
229 if ( $orders_trash ) {
230 foreach ( $orders_trash as $order_trash ) {
231 $order = learn_press_get_order( $order_trash->ID );
232 if ( $order ) {
233 $order->update_status( 'trash' );
234 }
235 }
236 }
237 // Change status course from lp_trash to trash.
238
239 // End code temporary
240 global $wpdb, $wp_query;
241 $lp_db = LP_Database::getInstance();
242 if ( is_admin() && $this->is_page_list_posts_on_backend() ) {
243 $where = ' ';
244 $where .= $wpdb->prepare( " AND {$lp_db->tb_posts}.post_type = %s", LP_ORDER_CPT );
245 }
246
247 // Search by keyword
248 if ( ! empty( $wp_query->get( 's' ) ) ) {
249 $s = $wp_query->get( 's' );
250
251 // Check search LP Order ID with format #000[ID] or 000[ID]
252 $pattern = '/^#\d+$/';
253 if ( preg_match( $pattern, $s ) ) {
254 $s = str_replace( '#', '', $s );
255 }
256
257 $pattern2 = '#^0+.*\d+$#';
258 if ( preg_match( $pattern2, $s ) ) {
259 $s = (int) $s;
260 }
261
262 $s = trim( $s );
263
264 $where .= $wpdb->prepare( " AND {$lp_db->tb_posts}.ID = %d", $s );
265 $where .= $wpdb->prepare( ' OR lpori.order_item_name like %s', '%' . $wpdb->esc_like( $s ) . '%' );
266 }
267
268 // Search by author id
269 if ( ! empty( $wp_query->get( 'author' ) ) ) {
270 $user_id = absint( $wp_query->get( 'author' ) );
271 //$where .= $wpdb->prepare( ' AND uu.ID like %s ', $user_id );
272 $where .= " AND ( pm1.meta_value like '%\"$user_id\"%' OR pm1.meta_value = $user_id ) ";
273 }
274
275 if ( ! empty( $wp_query->get( 'm' ) ) ) {
276 $month = $wp_query->get( 'm' );
277 $where .= " AND YEAR({$lp_db->tb_posts}.post_date)=" . substr( $month, 0, 4 );
278 if ( strlen( $month ) > 5 ) {
279 $where .= " AND MONTH({$lp_db->tb_posts}.post_date)=" . substr( $month, 4, 2 );
280 }
281 }
282
283 // Filter by order status
284 if ( ! empty( $wp_query->get( 'post_status' ) ) ) {
285 $status = $wp_query->get( 'post_status' );
286 $where .= $wpdb->prepare( " AND {$lp_db->tb_posts}.post_status = %s", $status );
287 } else {
288 $where .= $wpdb->prepare( " AND {$lp_db->tb_posts}.post_status NOT IN (%s, %s, %s)", LP_ORDER_TRASH_DB, LP_ORDER_TRASH, 'auto-draft' );
289 }
290
291 return $where;
292 }*/
293
294 // public function posts_orderby( $orderby ) {
295 // global $wpdb;
296 //
297 // $order = $this->get_order_sort();
298 //
299 // switch ( $this->get_order_by() ) {
300 // case 'title':
301 // $orderby = "{$wpdb->posts}.ID {$order}";
302 // break;
303 // /*case 'student':
304 // $orderby = "uu.user_login {$order}";
305 // break;*/
306 // case 'date':
307 // $orderby = "{$wpdb->posts}.post_date {$order}";
308 // break;
309 // case 'order_total':
310 // $orderby = "CAST(pm2.meta_value AS UNSIGNED) {$order}";
311 // break;
312 // }
313 //
314 // return $orderby;
315 // }
316
317 /*public function posts_join_paged( $join ) {
318 global $wpdb, $wp_query;
319 $lp_db = LP_Database::getInstance();
320
321 // Search by keyword
322 if ( ! empty( $wp_query->get( 's' ) ) ) {
323 $join .= " INNER JOIN {$lp_db->tb_lp_order_items} lpori ON {$wpdb->posts}.ID = lpori.order_id";
324 }
325
326 if ( ! empty( $wp_query->get( 'author' ) ) ) {
327 $author_id = $wp_query->get( 'author' );
328 $join .= " INNER JOIN {$lp_db->tb_postmeta} pm1 ON {$wpdb->posts}.ID = pm1.post_id AND pm1.meta_key = '_user_id'";
329 $join .= " LEFT JOIN {$lp_db->tb_users} uu ON uu.ID = $author_id";
330 }
331
332 if ( $this->get_order_by() === 'order_total' ) {
333 $join .= " INNER JOIN {$lp_db->tb_postmeta} pm2 ON {$wpdb->posts}.ID = pm2.post_id AND pm2.meta_key = '_order_total'";
334 }
335
336 return $join;
337 }*/
338
339 /**
340 * Make our custom columns can be sortable
341 *
342 * @param $columns
343 *
344 * @return mixed
345 */
346 public function sortable_columns( $columns ) {
347 $columns['order_date'] = 'date';
348 $columns['order_total'] = 'order_total';
349
350 return $columns;
351 }
352
353 public function update_status() {
354 $order_id = ! empty( $_REQUEST['order_id'] ) ? absint( $_REQUEST['order_id'] ) : 0;
355 $status = ! empty( $_REQUEST['status'] ) ? LP_Helper::sanitize_params_submitted( $_REQUEST['status'] ) : 'Pending';
356
357 learn_press_update_order_status( $order_id, $status );
358
359 wp_send_json(
360 array(
361 'status' => $status,
362 'class' => sanitize_title( $status ),
363 )
364 );
365 }
366
367 /**
368 * Custom row's actions.
369 *
370 * @param array $actions
371 * @param WP_Post $post
372 *
373 * @return mixed
374 * @since 2.1.7
375 * @deprecated 4.2.6.4
376 */
377 /*public function row_actions( $actions, $post ) {
378 if ( ! empty( $actions['inline hide-if-no-js'] ) ) {
379 unset( $actions['inline hide-if-no-js'] );
380 }
381 if ( ! empty( $actions['edit'] ) ) {
382 $actions['edit'] = preg_replace( '/>(.*?)<\/a>/', '>' . __( 'View Order', 'learnpress' ) . '</a>', $actions['edit'] );
383 }
384
385 return $actions;
386 }*/
387
388 /**
389 * re-order the orders by newest
390 *
391 * @param WP_Query $wp_query
392 *
393 * @editor tungnx
394 * @reason comment this function - because default sort by id
395 *
396 * @return mixed
397 */
398 public function pre_get_posts( $wp_query ) {
399 if ( ! is_admin() ) {
400 return $wp_query;
401 }
402
403 $post_type = $wp_query->get( 'post_type' );
404
405 if ( empty( $post_type ) || $post_type != LP_ORDER_CPT ) {
406 return $wp_query;
407 }
408
409 if ( is_admin() ) {
410 $wp_query->set( 'orderby', 'date' );
411 $wp_query->set( 'order', 'desc' );
412 }
413
414 $post_status = $wp_query->get( 'post_status' );
415 if ( empty( $post_status ) || $post_status == 'all' ) {
416 $wp_query->set(
417 'post_status',
418 array(
419 LP_ORDER_COMPLETED_DB,
420 LP_ORDER_PROCESSING_DB,
421 LP_ORDER_PENDING_DB,
422 LP_ORDER_FAILED_DB,
423 LP_ORDER_CANCELLED_DB,
424 )
425 );
426 }
427
428 // Search by author id
429 /*if ( ! empty( $wp_query->get( 'author' ) ) ) {
430 $user_id = absint( $wp_query->get( 'author' ) );
431 //$where .= $wpdb->prepare( ' AND uu.ID like %s ', $user_id );
432 $where .= " AND ( pm1.meta_value like '%\"$user_id\"%' OR pm1.meta_value = $user_id ) ";
433 }*/
434
435 $post_author = $wp_query->get( 'author' );
436 if ( ! empty( $post_author ) ) {
437 $user_id = absint( $post_author );
438 $meta_query = array(
439 // 'relation' => 'OR',
440 array(
441 'key' => '_user_id',
442 'value' => '%"' . $user_id . '"%',
443 'compare' => 'LIKE',
444 ),
445 // array(
446 // 'key' => '_user_id',
447 // 'value' => $user_id,
448 // 'compare' => '=',
449 // ),
450 );
451 $wp_query->set( 'meta_query', $meta_query );
452 }
453
454 return $wp_query;
455 }
456
457 /**
458 * Query lp orders in admin via Post DB
459 *
460 * @param array $posts
461 * @param WP_Query $wp_query
462 *
463 * @return array|WP_Query
464 */
465 public function posts_pre_query( $posts, $wp_query ) {
466 try {
467 if ( ! is_admin() ) {
468 return $posts;
469 }
470
471 $post_type = $wp_query->get( 'post_type' );
472
473 if ( empty( $post_type ) || $post_type != LP_ORDER_CPT ) {
474 return $posts;
475 }
476
477 // Convert params from WP_Query to PostFilter
478 $posts_per_page = get_user_option( "edit_{$post_type}_per_page", get_current_user_id() );
479 if ( empty( $posts_per_page ) ) {
480 $posts_per_page = 20;
481 }
482
483 $paged = max( 1, get_query_var( 'paged' ) );
484 $user_of_order = $wp_query->get( 'author' );
485 $status = $wp_query->get( 'post_status' );
486 $key = $wp_query->get( 's' );
487 $month = $wp_query->get( 'm' );
488
489 $filter = new OrderPostFilter();
490 $param = [
491 'paged' => $paged,
492 'posts_per_page' => $posts_per_page,
493 'author' => $user_of_order,
494 'post_status' => $status,
495 's' => $key,
496 'm' => $month,
497 ];
498 LP_Order::handle_params_query_list_orders( $filter, $param );
499
500 // Get lp orders
501 $post_db = PostDB::getInstance();
502 $total_rows = 0;
503 $lp_orders = $post_db->get_posts( $filter, $total_rows );
504
505 $wp_query->post_count = $total_rows;
506 $wp_query->found_posts = $total_rows;
507 $posts = $lp_orders;
508 } catch ( Throwable $e ) {
509 LP_Debug::error_log( $e );
510 }
511
512 return $posts;
513 }
514
515 /**
516 *
517 */
518 public function columns_head( $existing ) {
519
520 // Remove Checkbox - adding it back below
521 if ( isset( $existing['cb'] ) ) {
522 $check = $existing['cb'];
523 unset( $existing['cb'] );
524 }
525
526 // Remove Title - adding it back below
527 if ( isset( $existing['title'] ) ) {
528 unset( $existing['title'] );
529 }
530
531 // Remove Format
532 if ( isset( $existing['format'] ) ) {
533 unset( $existing['format'] );
534 }
535
536 // Remove Author
537 if ( isset( $existing['author'] ) ) {
538 unset( $existing['author'] );
539 }
540
541 // Remove Comments
542 if ( isset( $existing['comments'] ) ) {
543 unset( $existing['comments'] );
544 }
545
546 // Remove Date
547 if ( isset( $existing['date'] ) ) {
548 unset( $existing['date'] );
549 }
550
551 // Remove Builder
552 if ( isset( $existing['builder_layout'] ) ) {
553 unset( $existing['builder_layout'] );
554 }
555
556 $columns['cb'] = '<input type="checkbox" />';
557 $columns['title'] = esc_html__( 'Order', 'learnpress' );
558 $columns['order_student'] = esc_html__( 'Student', 'learnpress' );
559 $columns['order_items'] = esc_html__( 'Purchased', 'learnpress' );
560 $columns['order_date'] = esc_html__( 'Date', 'learnpress' );
561 $columns['order_total'] = esc_html__( 'Total', 'learnpress' );
562 $columns['order_status'] = '<span class="status_head tips" data-tip="' . esc_attr__( 'Status', 'learnpress' ) . '">' . esc_attr__( 'Status', 'learnpress' ) . '</span>';
563
564 $columns = array_merge( $columns, $existing );
565
566 return $columns;
567 }
568
569 public function order_title( $title, $post_id ) {
570 if ( get_post_type( $post_id ) != LP_ORDER_CPT ) {
571 return $title;
572 }
573
574 return learn_press_transaction_order_number( $post_id );
575 }
576
577 /**
578 * Render column data
579 *
580 * @since 3.0.0
581 * @version 1.0.1
582 */
583 public function columns_content( $column, $post_id = 0 ) {
584 global $post;
585 $lp_order = learn_press_get_order( $post->ID );
586
587 switch ( $column ) {
588 case 'order_student':
589 $user_ids = $lp_order->get_users();
590 if ( $user_ids ) {
591 $outputs = array();
592 foreach ( $user_ids as $user_id ) {
593 if ( get_user_by( 'id', $user_id ) ) {
594 $user = learn_press_get_user( $user_id );
595 $outputs[] = sprintf(
596 '<a href="user-edit.php?user_id=%d">%s (%s)</a><span>%s</span>',
597 $user_id,
598 $user->get_data( 'user_login' ),
599 $user->get_data( 'display_name' ),
600 $user->get_data( 'user_email' )
601 );
602 } else {
603 if ( sizeof( $user_ids ) == 1 ) {
604 $outputs[] = $lp_order->get_customer_name();
605 }
606 }
607 }
608 echo join( ', ', $outputs );
609 } else {
610 echo esc_html__( '(Guest)', 'learnpress' );
611 }
612 break;
613 case 'order_status':
614 $lp_order_icons = LP_Order::get_icons_status();
615 $icon = $lp_order_icons[ $lp_order->get_status() ] ?? '';
616 echo sprintf(
617 '<span class="lp-order-status %s">%s%s</span>',
618 $lp_order->get_status(),
619 $icon,
620 LP_Order::get_status_label( $lp_order->get_status() )
621 );
622 break;
623 case 'order_date':
624 $t_time = get_the_time( 'Y/m/d g:i:s a' );
625 $m_time = $post->post_date;
626 $time = get_post_time( 'G', true, $post );
627 $time_diff = current_time( 'U' ) - $time;
628
629 if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
630 $h_time = sprintf( __( '%s ago', 'learnpress' ), human_time_diff( $time, current_time( 'U' ) ) );
631 } else {
632 $h_time = mysql2date( 'Y/m/d', $m_time );
633 }
634
635 echo '<abbr title="' . esc_attr( $t_time ) . '">' . esc_html( apply_filters( 'learn_press_order_column_time', $h_time, $lp_order ) ) . '</abbr>';
636
637 break;
638 case 'order_items':
639 do_action( 'learn-press/admin/order-items/layout', $lp_order );
640 break;
641 case 'order_total':
642 echo wp_kses_post( $lp_order->get_formatted_order_total() );
643 $method_title = $lp_order->get_payment_method_title();
644 $method_title = apply_filters( 'learn-press/order-payment-method-title', $method_title, $lp_order );
645
646 if ( ! empty( $method_title ) ) {
647 $method_title_html = sprintf(
648 __( 'Pay via <strong>%s</strong>', 'learnpress' ),
649 $method_title
650 );
651 ?>
652 <div class="payment-method-title">
653 <?php echo wp_kses_post( $method_title_html ); ?>
654 </div>
655 <?php
656 }
657 break;
658 }
659 }
660
661 /**
662 * Register order post type
663 */
664 public function args_register_post_type(): array {
665 return array(
666 'labels' => array(
667 'name' => __( 'Orders', 'learnpress' ),
668 'menu_name' => __( 'Orders', 'learnpress' ),
669 'singular_name' => __( 'Order', 'learnpress' ),
670 'add_new_item' => __( 'Add A New Order', 'learnpress' ),
671 'edit_item' => __( 'Order Details', 'learnpress' ),
672 'all_items' => __( 'Orders', 'learnpress' ),
673 'view_item' => __( 'View Order', 'learnpress' ),
674 'add_new' => __( 'Add New', 'learnpress' ),
675 'update_item' => __( 'Update Order', 'learnpress' ),
676 'search_items' => __( 'Search Orders', 'learnpress' ),
677 'not_found' => __( 'No order found', 'learnpress' ),
678 'not_found_in_trash' => __( 'There was no order found in the trash', 'learnpress' ),
679 ),
680 'public' => false,
681 'show_ui' => true,
682 'show_in_nav_menus' => false,
683 'show_in_admin_bar' => false,
684 'publicly_queryable' => false,
685 'show_in_menu' => 'learn_press',
686 'map_meta_cap' => true,
687 'capability_type' => LP_ORDER_CPT,
688 'hierarchical' => false,
689 'rewrite' => array(
690 'slug' => LP_ORDER_CPT,
691 'hierarchical' => true,
692 'with_front' => true,
693 ),
694 'supports' => array(
695 'title',
696 'custom-fields',
697 ),
698 'exclude_from_search' => true,
699 );
700 }
701
702 /**
703 * Register new post status for order
704 *
705 * @Todo when rewrite API, will remove this function
706 * will be not use learn_press_get_register_order_statuses
707 */
708 public function register_post_statues() {
709 $statuses = learn_press_get_register_order_statuses();
710 foreach ( $statuses as $status => $args ) {
711 register_post_status( $status, $args );
712 }
713 }
714
715 public static function instance() {
716 if ( ! self::$_instance ) {
717 self::$_instance = new self();
718 }
719
720 return self::$_instance;
721 }
722
723 /**
724 * Before post deleted
725 *
726 * @author tungnx
727 * @since 4.1.4
728 * @version 1.0.1
729 */
730 public function before_delete( int $order_id ) {
731 $lp_order_db = LP_Order_DB::getInstance();
732 $lp_user_items_db = LP_User_Items_DB::getInstance();
733
734 try {
735 ini_set( 'max_execution_time', 0 );
736 $order = learn_press_get_order( $order_id );
737 if ( ! $order ) {
738 return;
739 }
740
741 $items = $order->get_all_items();
742 if ( empty( $items ) ) {
743 return;
744 }
745
746 $order_item_ids = [];
747 $user_ids = $order->get_users();
748 foreach ( $user_ids as $user_id ) {
749 //delete_user_meta( $user_id, 'orders' );
750 foreach ( $items as $itemArr ) {
751 $order_item_ids[] = $itemArr['order_item_id'] ?? 0;
752 $item_type = $itemArr['item_type'] ?? '';
753 $userItemModel = UserItemModel::find_user_item(
754 $user_id,
755 $itemArr['item_id'] ?? 0,
756 $item_type ?? '',
757 $order_id,
758 LP_ORDER_CPT
759 );
760
761 if ( $userItemModel ) {
762 if ( $item_type === LP_COURSE_CPT ) {
763 $userCourseModel = new UserCourseModel( $userItemModel );
764 $userCourseModel->delete();
765 } else {
766 $userItemModel->delete();
767 }
768 }
769 }
770
771 do_action( 'learn-press/order/before-delete', $order, $user_id );
772 }
773
774 // Delete lp_order_item, lp_order_itemmeta
775 $filter_delete = new LP_Order_Filter();
776 $filter_delete->order_item_ids = $order_item_ids;
777 $lp_order_db->delete_order_item( $filter_delete );
778 $lp_order_db->delete_order_itemmeta( $filter_delete );
779 // End
780
781 ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
782 } catch ( Throwable $e ) {
783 error_log( $e->getMessage() . '>' . __FILE__ );
784 }
785 }
786
787 /**
788 * Action delete Order
789 *
790 * @param int $order_id
791 *
792 * @author tungnx
793 * @since 4.1.4
794 * @version 1.0.0
795 */
796 public function deleted_post( int $order_id ) {
797 }
798
799 public function meta_boxes() {
800 return array(
801 'order_details' => array(
802 'title' => esc_html__( 'Order Details', 'learnpress' ),
803 'callback' => function ( $post ) {
804 learn_press_admin_view( 'meta-boxes/order/details.php', array( 'order' => new LP_Order( $post ) ) );
805 },
806 'context' => 'normal',
807 'priority' => 'high',
808 ),
809 'submitdiv' => array(
810 'title' => esc_html__( 'Order Actions', 'learnpress' ),
811 'callback' => function ( $post ) {
812 learn_press_admin_view( 'meta-boxes/order/actions.php', array( 'order' => new LP_Order( $post ) ) );
813 },
814 'context' => 'side',
815 'priority' => 'high',
816 ),
817 'order_exports' => array(
818 'title' => esc_html__( 'Order Exports', 'learnpress' ),
819 'callback' => function ( $post ) {
820 learn_press_admin_view( 'meta-boxes/order/exports-invoice.php', array( 'order' => new LP_Order( $post ) ) );
821 },
822 'context' => 'side',
823 'priority' => 'high',
824 ),
825 );
826 }
827
828 /**
829 * Download order CSV file and delete it after download
830 *
831 * @return void
832 */
833 public function download_order_csv_file() {
834 $export_id = LP_Request::get_param( 'export_id', '', 'key' );
835 if ( ! isset( $_GET['lp_download_order'] ) || empty( $export_id ) ) {
836 return;
837 }
838
839 $file = ExportOrderCSVAjax::get_export_csv_path( $export_id );
840 if ( ! file_exists( $file ) ) {
841 wp_die( __( 'File not found', 'learnpress' ) );
842 } elseif ( ! realpath( $file ) ) {
843 wp_die( __( 'Invalid file path', 'learnpress' ) );
844 }
845
846 $filename = basename( $file );
847
848 header( 'Content-Type: text/csv; charset=UTF-8' );
849 header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
850 header( 'Content-Length: ' . filesize( $file ) );
851
852 readfile( $file );
853 unlink( $file );
854 exit;
855 }
856 }
857
858 // end LP_Order_Post_Type
859
860 $order_post_type = LP_Order_Post_Type::instance();
861 }
862