PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.1
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.4.1, at inc/custom-post-types/order.php

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