PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9 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 All 140 releases
learnpress / inc / custom-post-types / order.php

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

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