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

1,010 lines 28.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_Order_Post_Type
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 1.0.1
8 */
9
10 if ( ! class_exists( 'LP_Order_Post_Type' ) ) {
11 final class LP_Order_Post_Type extends LP_Abstract_Post_Type {
12 /**
13 * Type of post
14 *
15 * @var string
16 */
17 protected $_post_type = LP_ORDER_CPT;
18 /**
19 * @var null
20 */
21 protected static $_instance = null;
22
23 /**
24 * LP_Order_Post_Type constructor.
25 *
26 * @param $post_type
27 */
28 public function __construct() {
29 add_action( 'admin_init', array( $this, 'register_post_statues' ) );
30 add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
31 add_action( 'admin_init', array( $this, 'remove_box' ) );
32 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
33 // add_action( 'transition_post_status', array( $this, 'restore_order' ), 1, 3 );
34 add_filter( 'wp_untrash_post_status', array( $this, 'restore_status_order' ), 11, 3 );
35 // add_action( 'save_post', array( $this, 'recount_enrolled_users' ), 11, 3 );
36
37 add_filter( 'admin_footer', array( $this, 'admin_footer' ) );
38
39 // $this->add_map_method( 'save', 'save_order' );
40
41 // Hungkv => Fix error child order not show in trash
42 // add_filter( 'wp_count_posts', array( $this, 'filter_count_posts' ), 100, 3 );
43 add_filter( 'views_edit-lp_order', array( $this, 'filter_views' ) );
44 // add_filter( 'posts_where_paged', array( $this, 'filter_orders' ) );
45 // LP Order title
46 add_filter( 'the_title', array( $this, 'order_title' ), 5, 2 );
47
48 parent::__construct();
49 }
50
51 /**
52 * Re-count enrolled users to the courses in current order
53 * is being changed status
54 *
55 * @param int $post_id
56 * @since 3.0.10
57 * @editor tungnx
58 * @reason not use
59 */
60 /*
61 public function recount_enrolled_users( int $post_id ) {
62 $order = learn_press_get_order( $post_id );
63 $curd = new LP_Course_CURD();
64 $items = $order->get_items();
65
66 if ( $items ) {
67 foreach ( $items as $item ) {
68 if ( ! isset( $item['course_id'] ) ) {
69 continue;
70 }
71
72 $course_id = $item['course_id'];
73 LP_Repair_Database::instance()->sync_course_orders( $course_id );
74 $count = $curd->count_enrolled_users_by_orders( $course_id );
75 update_post_meta( $course_id, 'count_enrolled_users', $count );
76 }
77 }
78 }*/
79
80 /**
81 * Filter the counts of posts when wp counting orders by statuses.
82 * Maybe there are some orders are created for multiple users,
83 * and each user in main order will be assigned to a separated
84 * order with post_parent is ID of main order. And, we do not
85 * want to show these orders in the list.
86 *
87 * @param array $counts
88 * @param string $type
89 * @param string $perm
90 *
91 * @return array|object
92 */
93 public function filter_count_posts( $counts, $type, $perm ) {
94 if ( LP_ORDER_CPT === $type ) {
95 $cache_key = 'lp-' . _count_posts_cache_key( $type, $perm );
96
97 $counts = LP_Object_Cache::get( $cache_key, 'counts' );
98
99 if ( false !== $counts ) {
100 return $counts;
101 }
102
103 global $wpdb;
104 $query = "
105 SELECT post_status, COUNT( ID ) AS num_posts
106 FROM {$wpdb->posts}
107 WHERE post_type = %s
108 AND post_parent = %d
109 ";
110
111 if ( 'readable' == $perm && is_user_logged_in() ) {
112 $post_type_object = get_post_type_object( $type );
113 if ( ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
114 $query .= $wpdb->prepare(
115 " AND (post_status != 'private' OR ( post_author = %d AND post_status = 'private' ))",
116 get_current_user_id()
117 );
118 }
119 }
120 $query .= ' GROUP BY post_status';
121 $query = $wpdb->prepare( $query, $type, 0 );
122 $results = (array) $wpdb->get_results( $query, ARRAY_A );
123 $counts = array_fill_keys( get_post_stati(), 0 );
124
125 foreach ( $results as $row ) {
126 $counts[ $row['post_status'] ] = $row['num_posts'];
127 }
128
129 $counts = (object) $counts;
130 LP_Object_Cache::set( $cache_key, $counts, 'counts' );
131 }
132
133 return $counts;
134 }
135
136 /**
137 * Unset value in 'mine' key in views of LP Orders.
138 * The 'mine' is present in some case when 'user_posts_count'
139 * is not the same with total posts then wp add it to the views
140 * of WP Posts List table.
141 *
142 * @param array $views
143 *
144 * @return mixed
145 */
146 public function filter_views( $views ) {
147 if ( isset( $views['mine'] ) ) {
148 unset( $views['mine'] );
149 }
150
151 return $views;
152 }
153
154 /**
155 * Filter to hide orders are created by one order for multiple users.
156 *
157 * @param string $where
158 *
159 * @return string
160 */
161 public function filter_orders( string $where ): string {
162 if ( ! $this->is_page_list_posts_on_backend() ) {
163 return $where;
164 }
165
166 global $wpdb;
167
168 if ( isset( $_REQUEST['parent'] ) ) {
169 $where .= sprintf( ' AND post_parent = %d ', absint( $_REQUEST['parent'] ) );
170 } else {
171 // $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 );
172 $where .= ' AND post_parent = 0 ';
173 }
174
175 return $where;
176 }
177
178 public function enqueue_scripts() {
179 if ( get_post_type() != $this->_post_type ) {
180 return;
181 }
182 wp_enqueue_script( 'user-suggest' );
183 }
184
185 /**
186 * Restore user course item when the order is stored (usually from trash).
187 *
188 * @param string $new
189 * @param string $old
190 * @param WP_Post $post
191 *
192 * @editor tungnx
193 * @modify 4.1.3 - commnet - not use
194 */
195 /*
196 public function restore_order( $new, $old, $post ) {
197
198 if ( ! ( 'trash' === $old ) ) {
199 return;
200 }
201
202 $order = learn_press_get_order( $post->ID );
203 if ( ! $order ) {
204 return;
205 }
206
207 $user_item_data = get_post_meta( $post->ID, '_lp_user_data', true );
208 if ( ! $user_item_data ) {
209 return;
210 }
211
212 $items = $order->get_items();
213 if ( ! $items ) {
214 return;
215 }
216
217 $users = $order->get_users();
218 if ( ! $users ) {
219 return;
220 }
221
222 // Restore child order if current order is for multi users
223 $child_orders = $order->get_child_orders();
224 if ( $order->is_multi_users() && $child_orders ) {
225 foreach ( $child_orders as $child_order ) {
226 wp_untrash_post( $child_order );
227 }
228 }
229
230 $user_curd = new LP_User_CURD();
231
232 foreach ( $user_item_data as $user_item_id => $data ) {
233 $item_course = $user_curd->get_user_item_by_id( $user_item_id );
234
235 if ( ! $item_course ) {
236 continue;
237 }
238
239 $order_status = $order->get_order_status();
240 $last_status = ( $order_status != '' && $order_status != 'completed' ) ? 'pending' : 'in-progress';
241 $user_curd->update_user_item_status( $user_item_id, $last_status );
242 // Restore data
243 $user_curd->update_user_item_by_id(
244 $user_item_id,
245 $data
246 );
247 }
248
249 // Delete data
250 delete_post_meta( $post->ID, '_lp_user_data' );
251 }*/
252
253 /**
254 * Restore user course item when the order is stored (usually from trash).
255 *
256 * @param string $new_status
257 * @param int $post_id
258 * @param string $previous_status
259 * @return string
260 */
261 public function restore_status_order( string $new_status, int $post_id, string $previous_status ): string {
262 if ( LP_ORDER_CPT != get_post_type( $post_id ) ) {
263 return $new_status;
264 }
265
266 return $previous_status;
267 }
268
269 /**
270 * @param LP_Order $order
271 * @param array $user_ids
272 * @param bool $trigger_action
273 *
274 * @throws Exception
275 * @editor tungnx
276 * @reason comment - not use
277 */
278 /*
279 protected function _update_child( $order, $user_ids, $trigger_action = false ) {
280 $new_orders = array();
281 $child_orders = $order->get_child_orders( true );
282
283 if ( $child_orders ) {
284 foreach ( $child_orders as $child_id ) {
285 $child_order = learn_press_get_order( $child_id );
286 $child_order_user_id = $child_order->get_user( 'id' );
287
288 if ( ! in_array( $child_order_user_id, $user_ids ) ) {
289 wp_delete_post( $child_id );
290 continue;
291 }
292
293 $order->cln_items( $child_order->get_id() );
294 $new_orders[ $child_order_user_id ] = $child_order;
295 }
296 }
297
298 foreach ( $user_ids as $uid ) {
299 if ( empty( $new_orders[ $uid ] ) ) {
300 $new_order = $order->cln();
301 $new_orders[ $uid ] = $new_order;
302 } else {
303 $new_order = $new_orders[ $uid ];
304 }
305
306 $old_status = get_post_status( $new_order->get_id() );
307 $new_order->set_order_date( $order->get_order_date( 'edit' ) );
308 $new_order->set_parent_id( $order->get_id() );
309 $new_order->set_user_id( $uid );
310 $new_order->set_total( $order->get_total() );
311 $new_order->set_subtotal( $order->get_subtotal() );
312
313 $new_order->set_status( learn_press_get_request( 'order-status' ) );
314 $new_order->save();
315 $new_status = get_post_status( $new_order->get_id() );
316
317 if ( ( $new_status == $old_status ) && $trigger_action ) {
318 $status = str_replace( 'lp-', '', $new_status );
319 $old_status = str_replace( 'lp-', '', $new_status );
320 do_action( 'learn-press/order/status-' . $status, $new_order->get_id(), $status );
321 do_action( 'learn-press/order/status-' . $old_status . '-to-' . $status, $new_order->get_id() );
322 do_action( 'learn-press/order/status-changed', $new_order->get_id(), $status, $old_status );
323 }
324 }
325 }*/
326
327 /**
328 * Save order post.
329 *
330 * @param int $post_id
331 * @param WP_Post $post
332 * @throws Exception
333 * @editor tungnx
334 * @version 1.0.3
335 */
336 public function save( int $post_id, WP_Post $post ) {
337 global $action;
338
339 if ( wp_is_post_revision( $post_id ) ) {
340 return;
341 }
342
343 if ( $action == 'editpost' ) {
344 $order = learn_press_get_order( $post_id );
345 if ( ! $order ) {
346 return;
347 }
348
349 $created_via = $order->get_created_via();
350 if ( empty( $created_via ) ) {
351 $order->set_created_via( 'manual' );
352 }
353
354 if ( isset( $_POST['order-customer'] ) ) {
355 $user_id = LP_Request::get_param( 'order-customer' );
356 $order->set_user_id( $user_id );
357 }
358
359 $status = LP_Request::get_param( 'order-status' );
360 if ( ! empty( $status ) ) {
361 $order->update_status( $status );
362 }
363 }
364 }
365
366 /**
367 * Remove unused boxes
368 */
369 public function remove_box() {
370 remove_post_type_support( LP_ORDER_CPT, 'title' );
371 remove_post_type_support( LP_ORDER_CPT, 'editor' );
372 }
373
374 public function admin_footer() {
375 if ( ! $this->is_page_list_posts_on_backend() ) {
376 return;
377 }
378 ?>
379 <script type="text/javascript">
380 jQuery(function ($) {
381 $('#post-search-input').prop('placeholder',
382 '<?php esc_attr_e( 'Order number, course name, etc.', 'learnpress' ); ?>').css('width', 300)
383 })
384 </script>
385 <?php
386 }
387
388 /**
389 * Hook to filter LP orders by some conditions.
390 *
391 * @param string $where
392 *
393 * @return mixed
394 */
395 public function posts_where_paged( $where ) {
396 global $wpdb, $wp_query;
397 if ( is_admin() && $this->is_page_list_posts_on_backend() &&
398 ( ! isset( $wp_query->query['post_status'] ) || ! $wp_query->query['post_status'] ) ) {
399 $statuses = array_keys( LP_Order::get_order_statuses() );
400 $search = "{$wpdb->posts}.post_status = 'publish' ";
401 $tmps = array( $search );
402 $tmp = "{$wpdb->posts}.post_status = %s ";
403 foreach ( $statuses as $status ) {
404 $tmps[] = $wpdb->prepare( $tmp, $status );
405 }
406 $replace = implode( ' OR ', $tmps );
407 $where = str_replace( $search, $replace, $where );
408 }
409
410 if ( ! $this->is_page_list_posts_on_backend() || ! $this->_is_search() ) {
411 return $where;
412 }
413
414 // filter by user id
415 preg_match( "#{$wpdb->posts}\.post_author IN\s*\((\d+)\)#", $where, $matches );
416 if ( ! empty( $matches ) && isset( $matches[1] ) ) {
417 $author_id = intval( $matches[1] );
418 $author_id_str = $wpdb->prepare( '%"%d"%', $author_id );
419 // $sql = ' ( pm1.meta_value = %d OR pm1.meta_value LIKE %s)';
420
421 $sql = " {$wpdb->posts}.ID IN ( SELECT
422 IF( p.post_parent >0, p.post_parent, p.ID)
423 FROM
424 {$wpdb->posts} AS p
425 INNER JOIN
426 {$wpdb->postmeta} m ON p.ID = m.post_id and p.post_type = %s
427 AND m.meta_key = %s AND (meta_value = %d OR meta_value like %s )
428 )
429 ";
430
431 $sql = $wpdb->prepare( $sql, array( LP_ORDER_CPT, '_user_id', $author_id, $author_id_str ) );
432 $where = str_replace( $matches[0], $sql, $where );
433 }
434
435 $s = $wp_query->get( 's' );
436
437 if ( $s ) {
438 $s = '%' . $wpdb->esc_like( $s ) . '%';
439 preg_match( "#{$wpdb->posts}\.post_title LIKE#", $where, $matches2 );
440 $sql = " {$wpdb->posts}.ID IN (
441 SELECT
442 IF( p.post_parent >0, p.post_parent, p.ID)
443 FROM
444 {$wpdb->posts} AS p
445 INNER JOIN
446 {$wpdb->postmeta} m ON p.ID = m.post_id and p.post_type = %s
447 AND m.meta_key = %s
448 INNER JOIN
449 {$wpdb->users} u on m.meta_value = u.ID
450 WHERE
451 u.user_login LIKE %s
452 OR u.user_nicename LIKE %s
453 OR u.user_email LIKE %s
454 OR u.display_name LIKE %s
455 OR {$wpdb->posts}.ID LIKE %s
456 ) ";
457 $sql = $wpdb->prepare( $sql, array( LP_ORDER_CPT, '_user_id', $s, $s, $s, $s, $s ) );
458 // print_r($sql);die('ccc');
459 // search order via course name
460 $sql .= ' OR ' . $wpdb->prepare(
461 " {$wpdb->posts}.ID IN (
462 SELECT DISTINCT order_id FROM {$wpdb->learnpress_order_items} loi
463 INNER JOIN {$wpdb->learnpress_order_itemmeta} loim ON loi.order_item_id = loim.learnpress_order_item_id AND loim.meta_key LIKE %s
464 WHERE `order_item_name` LIKE %s OR loim.meta_value LIKE %s
465 )",
466 array( '_course_id', $s, $s )
467 );
468 if ( ! empty( $matches2 ) && isset( $matches2[0] ) ) {
469 $sql .= $wpdb->prepare( ' OR loi.order_item_name LIKE %s', $s );
470 $where = str_replace( $matches2[0], $sql . ' OR ' . $matches2[0], $where );
471 } else {
472 $where .= ' AND ' . $sql;
473 }
474 }
475
476 return $where;
477 }
478
479 public function posts_fields( $fields ) {
480 global $wp_query;
481
482 if ( ! $this->is_page_list_posts_on_backend() || ! $this->_is_search() ) {
483 return $fields;
484 }
485 $fields .= ', uu.ID as user_ID, uu.display_name as user_display_name';
486
487 return $fields;
488 }
489
490 public function posts_orderby( $orderby ) {
491 global $wpdb;
492
493 if ( ! $this->is_page_list_posts_on_backend() ) {
494 return $orderby;
495 }
496 global $wpdb;
497
498 $order = $this->get_order_sort();
499
500 switch ( $this->get_order_by() ) {
501 case 'title':
502 $orderby = "{$wpdb->posts}.ID {$order}";
503 break;
504 case 'student':
505 $orderby = "uu.user_login {$order}";
506 break;
507 case 'date':
508 $orderby = "{$wpdb->posts}.post_date {$order}";
509 break;
510 case 'order_total':
511 $orderby = " pm2.meta_value {$order}";
512 break;
513 }
514
515 return $orderby;
516 }
517
518 public function posts_join_paged( $join ) {
519 global $wpdb, $wp_query;
520 if ( ! $this->is_page_list_posts_on_backend() ) {
521 return $join;
522 }
523
524 $s = $wp_query->get( 's' );
525 if ( $s ) {
526 $join .= " INNER JOIN {$wpdb->learnpress_order_items} loi ON {$wpdb->posts}.ID = loi.order_id";
527 }
528
529 if ( isset( $_REQUEST['author'] ) ) {
530 $join .= " INNER JOIN {$wpdb->postmeta} pm1 ON {$wpdb->posts}.ID = pm1.post_id AND pm1.meta_key = '_user_id'";
531 $join .= " INNER JOIN {$wpdb->postmeta} pm2 ON {$wpdb->posts}.ID = pm2.post_id AND pm2.meta_key = '_order_total'";
532 $join .= " LEFT JOIN {$wpdb->users} uu ON pm1.meta_value = uu.ID";
533 }
534
535 return $join;
536 }
537
538 /**
539 * Make our custom columns can be sortable
540 *
541 * @param $columns
542 *
543 * @return mixed
544 */
545 public function sortable_columns( $columns ) {
546 $columns['order_student'] = 'student';
547 $columns['order_date'] = 'date';
548 $columns['order_total'] = 'order_total';
549
550 return $columns;
551 }
552
553 public function update_status() {
554 $order_id = ! empty( $_REQUEST['order_id'] ) ? absint( $_REQUEST['order_id'] ) : 0;
555 $status = ! empty( $_REQUEST['status'] ) ? LP_Helper::sanitize_params_submitted( $_REQUEST['status'] ) : 'Pending';
556
557 learn_press_update_order_status( $order_id, $status );
558
559 wp_send_json(
560 array(
561 'status' => $status,
562 'class' => sanitize_title( $status ),
563 )
564 );
565 }
566
567 /**
568 * Custom row's actions.
569 *
570 * @param array $actions
571 * @param WP_Post $post
572 *
573 * @return mixed
574 * @since 2.1.7
575 */
576 public function row_actions( $actions, $post ) {
577 if ( ! empty( $actions['inline hide-if-no-js'] ) ) {
578 unset( $actions['inline hide-if-no-js'] );
579 }
580 if ( ! empty( $actions['edit'] ) ) {
581 $actions['edit'] = preg_replace( '/>(.*?)<\/a>/', '>' . __( 'View Order', 'learnpress' ) . '</a>', $actions['edit'] );
582 }
583
584 $order = learn_press_get_order( $post->ID );
585 if ( $order->is_multi_users() ) {
586 $actions['child-orders'] = sprintf(
587 '<a href="%s">%s</a>',
588 esc_url_raw(
589 add_query_arg(
590 array(
591 'post_type' => LP_ORDER_CPT,
592 'parent' => $post->ID,
593 ),
594 admin_url( 'edit.php' )
595 )
596 ),
597 __( 'View child orders', 'learnpress' )
598 );
599 }
600
601 return $actions;
602 }
603
604 /**
605 * re-order the orders by newest
606 *
607 * @param $wp_query
608 * @editor tungnx
609 * @reason comment this function - because default sort by id
610 *
611 * @return mixed
612 */
613 public function pre_get_posts( $wp_query ) {
614 if ( is_admin() && isset( $wp_query->query['post_type'] ) && LP_ORDER_CPT == $wp_query->query['post_type'] ) {
615 $wp_query->set( 'orderby', 'date' );
616 $wp_query->set( 'order', 'desc' );
617 }
618
619 return $wp_query;
620 }
621
622 /**
623 *
624 */
625 public function columns_head( $existing ) {
626
627 // Remove Checkbox - adding it back below
628 if ( isset( $existing['cb'] ) ) {
629 $check = $existing['cb'];
630 unset( $existing['cb'] );
631 }
632
633 // Remove Title - adding it back below
634 if ( isset( $existing['title'] ) ) {
635 unset( $existing['title'] );
636 }
637
638 // Remove Format
639 if ( isset( $existing['format'] ) ) {
640 unset( $existing['format'] );
641 }
642
643 // Remove Author
644 if ( isset( $existing['author'] ) ) {
645 unset( $existing['author'] );
646 }
647
648 // Remove Comments
649 if ( isset( $existing['comments'] ) ) {
650 unset( $existing['comments'] );
651 }
652
653 // Remove Date
654 if ( isset( $existing['date'] ) ) {
655 unset( $existing['date'] );
656 }
657
658 // Remove Builder
659 if ( isset( $existing['builder_layout'] ) ) {
660 unset( $existing['builder_layout'] );
661 }
662
663 $columns['cb'] = '<input type="checkbox" />';
664 $columns['title'] = esc_html__( 'Order', 'learnpress' );
665 $columns['order_student'] = esc_html__( 'Student', 'learnpress' );
666 $columns['order_items'] = esc_html__( 'Purchased', 'learnpress' );
667 $columns['order_date'] = esc_html__( 'Date', 'learnpress' );
668 $columns['order_total'] = esc_html__( 'Total', 'learnpress' );
669 $columns['order_status'] = '<span class="status_head tips" data-tip="' . esc_attr__( 'Status', 'learnpress' ) . '">' . esc_attr__( 'Status', 'learnpress' ) . '</span>';
670
671 $columns = array_merge( $columns, $existing );
672
673 return $columns;
674 }
675
676 public function order_title( $title, $post_id ) {
677 $order = learn_press_get_order( $post_id );
678 if ( $order ) {
679 $title = $order->get_order_number();
680 }
681
682 return $title;
683 }
684
685 /**
686 * Render column data
687 *
688 * @since 3.0.0
689 * @version 1.0.1
690 */
691 public function columns_content( $column, $post_id = 0 ) {
692 global $post;
693 $lp_order = learn_press_get_order( $post->ID );
694
695 switch ( $column ) {
696 case 'order_student':
697 $user_ids = $lp_order->get_users();
698 if ( $user_ids ) {
699 $outputs = array();
700 foreach ( $user_ids as $user_id ) {
701 if ( get_user_by( 'id', $user_id ) ) {
702 $user = learn_press_get_user( $user_id );
703 $outputs[] = sprintf(
704 '<a href="user-edit.php?user_id=%d">%s (%s)</a><span>%s</span>',
705 $user_id,
706 $user->get_data( 'user_login' ),
707 $user->get_data( 'display_name' ),
708 $user->get_data( 'user_email' )
709 );
710 } else {
711 if ( sizeof( $user_ids ) == 1 ) {
712 $outputs[] = $lp_order->get_customer_name();
713 }
714 }
715 }
716 echo join( ', ', $outputs );
717 } else {
718 echo esc_html__( '(Guest)', 'learnpress' );
719 }
720 break;
721 case 'order_status':
722 $lp_order_icons = LP_Order::get_icons_status();
723 $icon = $lp_order_icons[ $lp_order->get_status() ] ?? '';
724 echo sprintf(
725 '<span class="lp-order-status %s">%s%s</span>',
726 $lp_order->get_status(),
727 $icon,
728 LP_Order::get_status_label( $lp_order->get_status() )
729 );
730 break;
731 case 'order_date':
732 $t_time = get_the_time( 'Y/m/d g:i:s a' );
733 $m_time = $post->post_date;
734 $time = get_post_time( 'G', true, $post );
735 $time_diff = time() - $time;
736
737 if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
738 $h_time = sprintf( __( '%s ago', 'learnpress' ), human_time_diff( $time ) );
739 } else {
740 $h_time = mysql2date( 'Y/m/d', $m_time );
741 }
742
743 echo '<abbr title="' . esc_attr( $t_time ) . '">' . esc_html( apply_filters( 'learn_press_order_column_time', $h_time, $lp_order ) ) . '</abbr>';
744
745 break;
746 case 'order_items':
747 $links = array();
748 $items = $lp_order->get_items();
749 $count = sizeof( $items );
750
751 foreach ( $items as $item ) {
752 if ( empty( $item['course_id'] ) || get_post_type( $item['course_id'] ) !== LP_COURSE_CPT ) {
753 $links[] = apply_filters( 'learn-press/order-item-not-course-id', esc_html__( 'The course does not exist', 'learnpress' ), $item );
754 } elseif ( get_post_status( $item['course_id'] ) !== 'publish' ) {
755 $links[] = get_the_title( $item['course_id'] ) . sprintf( ' (#%d - %s)', $item['course_id'], esc_html__( 'Deleted', 'learnpress' ) );
756 } else {
757 $link = '<a href="' . get_the_permalink( $item['course_id'] ) . '">' . get_the_title( $item['course_id'] ) . ' (#' . $item['course_id'] . ')' . '</a>';
758 if ( $count > 1 ) {
759 $link = sprintf( '<li>%s</li>', $link );
760 }
761 $links[] = apply_filters( 'learn-press/order-item-link', $link, $item );
762
763 }
764 }
765
766 if ( $count > 1 ) {
767 echo sprintf( '<ol>%s</ol>', join( '', $links ) );
768 } elseif ( 1 == $count ) {
769 echo join( '', $links );
770 } else {
771 echo esc_html__( '(No item)', 'learnpress' );
772 }
773 break;
774 case 'order_total':
775 echo wp_kses_post( $lp_order->get_formatted_order_total() );
776 $method_title = $lp_order->get_payment_method_title();
777
778 if ( $method_title ) {
779 ?>
780 <div class="payment-method-title">
781 <?php echo wp_kses_post( $lp_order->get_total() == 0 ? $method_title : sprintf( __( 'Pay via <strong>%s</strong>', 'learnpress' ), apply_filters( 'learn-press/order-payment-method-title', $method_title, $lp_order ), $lp_order ) ); ?>
782 </div>
783 <?php
784 }
785 break;
786 }
787 }
788
789 private function _is_search() {
790 return is_search();
791 }
792
793 /**
794 * Register order post type
795 */
796 public function args_register_post_type(): array {
797 return array(
798 'labels' => array(
799 'name' => __( 'Orders', 'learnpress' ),
800 'menu_name' => __( 'Orders', 'learnpress' ),
801 'singular_name' => __( 'Order', 'learnpress' ),
802 'add_new_item' => __( 'Add A New Order', 'learnpress' ),
803 'edit_item' => __( 'Order Details', 'learnpress' ),
804 'all_items' => __( 'Orders', 'learnpress' ),
805 'view_item' => __( 'View Order', 'learnpress' ),
806 'add_new' => __( 'Add New', 'learnpress' ),
807 'update_item' => __( 'Update Order', 'learnpress' ),
808 'search_items' => __( 'Search Orders', 'learnpress' ),
809 'not_found' => __( 'No order found', 'learnpress' ),
810 'not_found_in_trash' => __( 'There was no order found in the trash', 'learnpress' ),
811 ),
812 'public' => false,
813 'show_ui' => true,
814 'show_in_nav_menus' => false,
815 'show_in_admin_bar' => false,
816 'publicly_queryable' => false,
817 'show_in_menu' => 'learn_press',
818 'map_meta_cap' => true,
819 'capability_type' => LP_ORDER_CPT,
820 'hierarchical' => true,
821 'rewrite' => array(
822 'slug' => LP_ORDER_CPT,
823 'hierarchical' => true,
824 'with_front' => true,
825 ),
826 'supports' => array(
827 'title',
828 'custom-fields',
829 ),
830 );
831 }
832
833 /**
834 * Remove some unwanted metaboxes
835 */
836 public static function register_metabox() {
837 // Remove Publish metabox
838 remove_meta_box( 'submitdiv', LP_ORDER_CPT, 'side' );
839 remove_meta_box( 'commentstatusdiv', LP_ORDER_CPT, 'normal' );
840 }
841
842 // /**
843 // * Order details view.
844 // *
845 // * @param WP_Post $post
846 // */
847 // public static function order_details( $post ) {
848 // learn_press_admin_view( 'meta-boxes/order/details.php', array( 'order' => new LP_Order( $post ) ) );
849 // }
850
851 // /**
852 // * Order actions view.
853 // *
854 // * @param WP_Post $post
855 // */
856 // public static function order_actions( $post ) {
857 // learn_press_admin_view( 'meta-boxes/order/actions.php', array( 'order' => new LP_Order( $post ) ) );
858 // }
859
860 public function preparing_to_trash_order( $post_id ) {
861 if ( LP_ORDER_CPT != learn_press_get_post_type( $post_id ) ) {
862 return;
863 }
864 }
865
866 /**
867 * Register new post status for order
868 *
869 * @Todo when rewrite API, will remove this function
870 * will be not use learn_press_get_register_order_statuses
871 */
872 public function register_post_statues() {
873 $statuses = learn_press_get_register_order_statuses();
874 foreach ( $statuses as $status => $args ) {
875 register_post_status( $status, $args );
876 }
877 }
878
879 public static function instance() {
880 if ( ! self::$_instance ) {
881 self::$_instance = new self();
882 }
883
884 return self::$_instance;
885 }
886
887 /**
888 * Order export view.
889 *
890 * @param WP_Post $post
891 *
892 * @throws Exception
893 * @since 3.2.7.8
894 *
895 * @author hungkv
896 */
897 // public static function order_exports( $post ) {
898 // learn_press_admin_view( 'meta-boxes/order/exports-invoice.php', array( 'order' => new LP_Order( $post ) ) );
899 // }
900
901 /**
902 * Before post deleted
903 *
904 * @author tungnx
905 * @since 4.1.4
906 * @version 1.0.0
907 */
908 public function before_delete( int $order_id ) {
909 $lp_order_db = LP_Order_DB::getInstance();
910 $lp_user_items_db = LP_User_Items_DB::getInstance();
911
912 try {
913 $order = learn_press_get_order( $order_id );
914
915 if ( ! $order ) {
916 return;
917 }
918
919 $order_item_ids = $lp_order_db->get_order_item_ids( $order_id );
920
921 if ( empty( $order_item_ids ) ) {
922 return;
923 }
924
925 $user_ids = $order->get_users();
926
927 foreach ( $user_ids as $user_id ) {
928 delete_user_meta( $user_id, 'orders' );
929
930 foreach ( $order->get_item_ids() as $course_id ) {
931 // Check this order is the latest by user and course_id
932 $last_order_id = $lp_order_db->get_last_lp_order_id_of_user_course( $user_id, $course_id );
933 if ( $last_order_id && $last_order_id != $order->get_id() ) {
934 continue;
935 }
936
937 $lp_user_items_db->delete_user_items_old( $user_id, $course_id );
938 }
939 }
940
941 // Delete lp_order_item, lp_order_itemmeta
942 $filter_delete = new LP_Order_Filter();
943 $filter_delete->order_item_ids = $order_item_ids;
944 $lp_order_db->delete_order_item( $filter_delete );
945 $lp_order_db->delete_order_itemmeta( $filter_delete );
946 // End
947
948 // $this->remove_user_items_by_order_id( $order_id );
949
950 if ( ! empty( $data['child'] ) ) {
951 // $this->remove_child_orders( $data['child'] );
952 }
953 } catch ( Throwable $e ) {
954 error_log( $e->getMessage() . '>' . __FILE__ );
955 }
956 }
957
958 /**
959 * Action delete Order
960 *
961 * @param int $order_id
962 * @author tungnx
963 * @since 4.1.4
964 * @version 1.0.0
965 */
966 public function deleted_post( int $order_id ) {
967
968 }
969
970 public function meta_boxes() {
971 return array(
972 'order_details' => array(
973 'title' => esc_html__( 'Order Details', 'learnpress' ),
974 'callback' => function( $post ) {
975 learn_press_admin_view( 'meta-boxes/order/details.php', array( 'order' => new LP_Order( $post ) ) );
976 },
977 'context' => 'normal',
978 'priority' => 'high',
979 ),
980 'submitdiv' => array(
981 'title' => esc_html__( 'Order Actions', 'learnpress' ),
982 'callback' => function( $post ) {
983 learn_press_admin_view( 'meta-boxes/order/actions.php', array( 'order' => new LP_Order( $post ) ) );
984 },
985 'context' => 'side',
986 'priority' => 'high',
987 ),
988 'order_exports' => array(
989 'title' => esc_html__( 'Order Exports', 'learnpress' ),
990 'callback' => function( $post ) {
991 learn_press_admin_view( 'meta-boxes/order/exports-invoice.php', array( 'order' => new LP_Order( $post ) ) );
992 },
993 'context' => 'side',
994 'priority' => 'high',
995 ),
996 );
997 }
998 }
999
1000 // end LP_Order_Post_Type
1001
1002 $order_post_type = LP_Order_Post_Type::instance();
1003
1004 // Todo: Nhamdv see to rewrite
1005 // $order_post_type
1006 // ->add_meta_box( 'order_details', esc_html__( 'Order Details', 'learnpress' ), 'order_details', 'normal', 'high' )
1007 // ->add_meta_box( 'submitdiv', esc_html__( 'Order Actions', 'learnpress' ), 'order_actions', 'side', 'high' )
1008 // ->add_meta_box( 'order_export', esc_html__( 'Order Exports', 'learnpress' ), 'order_exports', 'side', 'high' );
1009 }
1010