PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / custom-post-types / order.php

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

1,031 lines 29.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.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( '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
46 parent::__construct();
47 }
48
49 /**
50 * Re-count enrolled users to the courses in current order
51 * is being changed status
52 *
53 * @param int $post_id
54 * @since 3.0.10
55 * @editor tungnx
56 * @reason not use
57 */
58 /*
59 public function recount_enrolled_users( int $post_id ) {
60 $order = learn_press_get_order( $post_id );
61 $curd = new LP_Course_CURD();
62 $items = $order->get_items();
63
64 if ( $items ) {
65 foreach ( $items as $item ) {
66 if ( ! isset( $item['course_id'] ) ) {
67 continue;
68 }
69
70 $course_id = $item['course_id'];
71 LP_Repair_Database::instance()->sync_course_orders( $course_id );
72 $count = $curd->count_enrolled_users_by_orders( $course_id );
73 update_post_meta( $course_id, 'count_enrolled_users', $count );
74 }
75 }
76 }*/
77
78 /**
79 * Filter the counts of posts when wp counting orders by statuses.
80 * Maybe there are some orders are created for multiple users,
81 * and each user in main order will be assigned to a separated
82 * order with post_parent is ID of main order. And, we do not
83 * want to show these orders in the list.
84 *
85 * @param array $counts
86 * @param string $type
87 * @param string $perm
88 *
89 * @return array|object
90 */
91 public function filter_count_posts( $counts, $type, $perm ) {
92 if ( LP_ORDER_CPT === $type ) {
93 $cache_key = 'lp-' . _count_posts_cache_key( $type, $perm );
94
95 $counts = LP_Object_Cache::get( $cache_key, 'counts' );
96
97 if ( false !== $counts ) {
98 return $counts;
99 }
100
101 global $wpdb;
102 $query = "
103 SELECT post_status, COUNT( ID ) AS num_posts
104 FROM {$wpdb->posts}
105 WHERE post_type = %s
106 AND post_parent = %d
107 ";
108
109 if ( 'readable' == $perm && is_user_logged_in() ) {
110 $post_type_object = get_post_type_object( $type );
111 if ( ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
112 $query .= $wpdb->prepare(
113 " AND (post_status != 'private' OR ( post_author = %d AND post_status = 'private' ))",
114 get_current_user_id()
115 );
116 }
117 }
118 $query .= ' GROUP BY post_status';
119 $query = $wpdb->prepare( $query, $type, 0 );
120 $results = (array) $wpdb->get_results( $query, ARRAY_A );
121 $counts = array_fill_keys( get_post_stati(), 0 );
122
123 foreach ( $results as $row ) {
124 $counts[ $row['post_status'] ] = $row['num_posts'];
125 }
126
127 $counts = (object) $counts;
128 LP_Object_Cache::set( $cache_key, $counts, 'counts' );
129 }
130
131 return $counts;
132 }
133
134 /**
135 * Unset value in 'mine' key in views of LP Orders.
136 * The 'mine' is present in some case when 'user_posts_count'
137 * is not the same with total posts then wp add it to the views
138 * of WP Posts List table.
139 *
140 * @param array $views
141 *
142 * @return mixed
143 */
144 public function filter_views( $views ) {
145 if ( isset( $views['mine'] ) ) {
146 unset( $views['mine'] );
147 }
148
149 return $views;
150 }
151
152 /**
153 * Filter to hide orders are created by one order for multiple users.
154 *
155 * @param string $where
156 *
157 * @return string
158 */
159 public function filter_orders( string $where ): string {
160 if ( ! $this->is_page_list_posts_on_backend() ) {
161 return $where;
162 }
163
164 global $wpdb;
165
166 if ( isset( $_REQUEST['parent'] ) ) {
167 $where .= sprintf( ' AND post_parent = %d ', absint( $_REQUEST['parent'] ) );
168 } else {
169 // $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 );
170 $where .= ' AND post_parent = 0 ';
171 }
172
173 return $where;
174 }
175
176 public function enqueue_scripts() {
177 if ( get_post_type() != $this->_post_type ) {
178 return;
179 }
180 wp_enqueue_script( 'user-suggest' );
181 }
182
183 /**
184 * Restore user course item when the order is stored (usually from trash).
185 *
186 * @param string $new
187 * @param string $old
188 * @param WP_Post $post
189 *
190 * @editor tungnx
191 * @modify 4.1.3 - commnet - not use
192 */
193 /*
194 public function restore_order( $new, $old, $post ) {
195
196 if ( ! ( 'trash' === $old ) ) {
197 return;
198 }
199
200 $order = learn_press_get_order( $post->ID );
201 if ( ! $order ) {
202 return;
203 }
204
205 $user_item_data = get_post_meta( $post->ID, '_lp_user_data', true );
206 if ( ! $user_item_data ) {
207 return;
208 }
209
210 $items = $order->get_items();
211 if ( ! $items ) {
212 return;
213 }
214
215 $users = $order->get_users();
216 if ( ! $users ) {
217 return;
218 }
219
220 // Restore child order if current order is for multi users
221 $child_orders = $order->get_child_orders();
222 if ( $order->is_multi_users() && $child_orders ) {
223 foreach ( $child_orders as $child_order ) {
224 wp_untrash_post( $child_order );
225 }
226 }
227
228 $user_curd = new LP_User_CURD();
229
230 foreach ( $user_item_data as $user_item_id => $data ) {
231 $item_course = $user_curd->get_user_item_by_id( $user_item_id );
232
233 if ( ! $item_course ) {
234 continue;
235 }
236
237 $order_status = $order->get_order_status();
238 $last_status = ( $order_status != '' && $order_status != 'completed' ) ? 'pending' : 'in-progress';
239 $user_curd->update_user_item_status( $user_item_id, $last_status );
240 // Restore data
241 $user_curd->update_user_item_by_id(
242 $user_item_id,
243 $data
244 );
245 }
246
247 // Delete data
248 delete_post_meta( $post->ID, '_lp_user_data' );
249 }*/
250
251 /**
252 * Restore user course item when the order is stored (usually from trash).
253 *
254 * @param string $new_status
255 * @param int $post_id
256 * @param string $previous_status
257 * @return string
258 */
259 public function restore_status_order( string $new_status, int $post_id, string $previous_status ): string {
260 if ( LP_ORDER_CPT != get_post_type( $post_id ) ) {
261 return $new_status;
262 }
263
264 return $previous_status;
265 }
266
267 /**
268 * @param LP_Order $order
269 * @param array $user_ids
270 * @param bool $trigger_action
271 *
272 * @throws Exception
273 * @editor tungnx
274 * @reason comment - not use
275 */
276 /*
277 protected function _update_child( $order, $user_ids, $trigger_action = false ) {
278 $new_orders = array();
279 $child_orders = $order->get_child_orders( true );
280
281 if ( $child_orders ) {
282 foreach ( $child_orders as $child_id ) {
283 $child_order = learn_press_get_order( $child_id );
284 $child_order_user_id = $child_order->get_user( 'id' );
285
286 if ( ! in_array( $child_order_user_id, $user_ids ) ) {
287 wp_delete_post( $child_id );
288 continue;
289 }
290
291 $order->cln_items( $child_order->get_id() );
292 $new_orders[ $child_order_user_id ] = $child_order;
293 }
294 }
295
296 foreach ( $user_ids as $uid ) {
297 if ( empty( $new_orders[ $uid ] ) ) {
298 $new_order = $order->cln();
299 $new_orders[ $uid ] = $new_order;
300 } else {
301 $new_order = $new_orders[ $uid ];
302 }
303
304 $old_status = get_post_status( $new_order->get_id() );
305 $new_order->set_order_date( $order->get_order_date( 'edit' ) );
306 $new_order->set_parent_id( $order->get_id() );
307 $new_order->set_user_id( $uid );
308 $new_order->set_total( $order->get_total() );
309 $new_order->set_subtotal( $order->get_subtotal() );
310
311 $new_order->set_status( learn_press_get_request( 'order-status' ) );
312 $new_order->save();
313 $new_status = get_post_status( $new_order->get_id() );
314
315 if ( ( $new_status == $old_status ) && $trigger_action ) {
316 $status = str_replace( 'lp-', '', $new_status );
317 $old_status = str_replace( 'lp-', '', $new_status );
318 do_action( 'learn-press/order/status-' . $status, $new_order->get_id(), $status );
319 do_action( 'learn-press/order/status-' . $old_status . '-to-' . $status, $new_order->get_id() );
320 do_action( 'learn-press/order/status-changed', $new_order->get_id(), $status, $old_status );
321 }
322 }
323 }*/
324
325 /**
326 * Save order post.
327 *
328 * @param int $post_id
329 * @param WP_Post $post
330 * @throws Exception
331 * @editor tungnx
332 * @version 1.0.2
333 */
334 public function save( int $post_id, WP_Post $post ) {
335 global $action;
336
337 if ( wp_is_post_revision( $post_id ) ) {
338 return;
339 }
340
341 if ( $action == 'editpost' ) {
342 $order = learn_press_get_order( $post_id );
343 if ( ! $order ) {
344 return;
345 }
346
347 $created_via = $order->get_created_via();
348 if ( empty( $created_via ) ) {
349 $order->set_created_via( 'manual' );
350 }
351
352 if ( isset( $_POST['order-customer'] ) ) {
353 $user_id = LP_Helper::sanitize_params_submitted( $_POST['order-customer'] );
354 $order->set_user_id( $user_id );
355 }
356
357 $status = LP_Helper::sanitize_params_submitted( $_POST['order-status'] ?? '' );
358 if ( $status ) {
359 $order->set_status( learn_press_get_request( 'order-status' ) );
360 }
361
362 $order->save();
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( learn_press_get_register_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 add_filter( 'the_title', array( $this, 'order_title' ), 5, 2 );
664
665 $columns['cb'] = '<input type="checkbox" />';
666 $columns['title'] = esc_html__( 'Order', 'learnpress' );
667 $columns['order_student'] = esc_html__( 'Student', 'learnpress' );
668 $columns['order_items'] = esc_html__( 'Purchased', 'learnpress' );
669 $columns['order_date'] = esc_html__( 'Date', 'learnpress' );
670 $columns['order_total'] = esc_html__( 'Total', 'learnpress' );
671 $columns['order_status'] = '<span class="status_head tips" data-tip="' . esc_attr__( 'Status', 'learnpress' ) . '">' . esc_attr__( 'Status', 'learnpress' ) . '</span>';
672
673 $columns = array_merge( $columns, $existing );
674
675 return $columns;
676 }
677
678 public function order_title( $title, $post_id ) {
679 $order = learn_press_get_order( $post_id );
680
681 if ( $order ) {
682 $title = $order->get_order_number();
683 }
684
685 return $title;
686 }
687
688 /**
689 * Render column data
690 *
691 * @param string
692 * @param int
693 */
694 public function columns_content( $column, $post_id = 0 ) {
695 global $post;
696 $the_order = learn_press_get_order( $post->ID );
697
698 switch ( $column ) {
699 case 'order_student':
700 $user_ids = $the_order->get_users();
701 if ( $user_ids ) {
702 $outputs = array();
703 foreach ( $user_ids as $user_id ) {
704 if ( get_user_by( 'id', $user_id ) ) {
705 $user = learn_press_get_user( $user_id );
706 $outputs[] = sprintf(
707 '<a href="user-edit.php?user_id=%d">%s (%s)</a><span>%s</span>',
708 $user_id,
709 $user->get_data( 'user_login' ),
710 $user->get_data( 'display_name' ),
711 $user->get_data( 'user_email' )
712 );
713 } else {
714 if ( sizeof( $user_ids ) == 1 ) {
715 $outputs[] = $the_order->get_customer_name();
716 }
717 }
718 }
719 echo join( ', ', $outputs );
720 } else {
721 echo esc_html__( '(Guest)', 'learnpress' );
722 }
723 break;
724 case 'order_status':
725 $icon = '';
726 switch ( $the_order->get_status() ) {
727 case 'pending':
728 $icon = '<i class="fas fa-flag"></i>';
729 break;
730 case 'processing':
731 $icon = '<i class="far fa-clock"></i>';
732 break;
733 case 'completed':
734 $icon = '<i class="far fa-check-circle"></i>';
735 break;
736 case 'failed':
737 $icon = '<i class="far fa-times-circle"></i>';
738 break;
739 case 'cancelled':
740 $icon = '<i class="fas fa-ban"></i>';
741 break;
742 }
743
744 $icon = apply_filters( 'learn-press/order-status-icon', $icon, $the_order->get_status() );
745 $label = learn_press_get_order_status_label( $the_order->get_id() );
746 echo sprintf(
747 '<span class="learn-press-tooltip %s" data-tooltip="%s">%s %s</span>',
748 $the_order->get_status(),
749 $label,
750 $icon,
751 $label
752 );
753 break;
754 case 'order_date':
755 $t_time = get_the_time( 'Y/m/d g:i:s a' );
756 $m_time = $post->post_date;
757 $time = get_post_time( 'G', true, $post );
758
759 $time_diff = current_time( 'timestamp' ) - $time;
760
761 if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
762 $h_time = sprintf( __( '%s ago', 'learnpress' ), human_time_diff( $time ) );
763 } else {
764 $h_time = mysql2date( 'Y/m/d', $m_time );
765 }
766
767 echo '<abbr title="' . esc_attr( $t_time ) . '">' . esc_html( apply_filters( 'learn_press_order_column_time', $h_time, $the_order ) ) . '</abbr>';
768
769 break;
770 case 'order_items':
771 $links = array();
772 $items = $the_order->get_items();
773 $count = sizeof( $items );
774
775 foreach ( $items as $item ) {
776 if ( empty( $item['course_id'] ) || get_post_type( $item['course_id'] ) !== LP_COURSE_CPT ) {
777 $links[] = apply_filters( 'learn-press/order-item-not-course-id', esc_html__( 'Course does not exist', 'learnpress' ), $item );
778 } elseif ( get_post_status( $item['course_id'] ) !== 'publish' ) {
779 $links[] = get_the_title( $item['course_id'] ) . sprintf( ' (#%d - %s)', $item['course_id'], esc_html__( 'Deleted', 'learnpress' ) );
780 } else {
781 $link = '<a href="' . get_the_permalink( $item['course_id'] ) . '">' . get_the_title( $item['course_id'] ) . ' (#' . $item['course_id'] . ')' . '</a>';
782 if ( $count > 1 ) {
783 $link = sprintf( '<li>%s</li>', $link );
784 }
785 $links[] = apply_filters( 'learn-press/order-item-link', $link, $item );
786
787 }
788 }
789
790 if ( $count > 1 ) {
791 echo sprintf( '<ol>%s</ol>', join( '', $links ) );
792 } elseif ( 1 == $count ) {
793 echo join( '', $links );
794 } else {
795 echo esc_html__( '(No item)', 'learnpress' );
796 }
797 break;
798 case 'order_total':
799 echo wp_kses_post( $the_order->get_formatted_order_total() );
800 $title = $the_order->get_payment_method_title();
801
802 if ( $title ) {
803 ?>
804 <div class="payment-method-title">
805 <?php echo wp_kses_post( $the_order->order_total == 0 ? $title : sprintf( __( 'Pay via <strong>%s</strong>', 'learnpress' ), apply_filters( 'learn-press/order-payment-method-title', $title, $the_order ), $the_order ) ); ?>
806 </div>
807 <?php
808 }
809 break;
810 }
811 }
812
813 private function _is_search() {
814 return is_search();
815 }
816
817 /**
818 * Register order post type
819 */
820 public function args_register_post_type(): array {
821 return array(
822 'labels' => array(
823 'name' => __( 'Orders', 'learnpress' ),
824 'menu_name' => __( 'Orders', 'learnpress' ),
825 'singular_name' => __( 'Order', 'learnpress' ),
826 'add_new_item' => __( 'Add New Order', 'learnpress' ),
827 'edit_item' => __( 'Order Details', 'learnpress' ),
828 'all_items' => __( 'Orders', 'learnpress' ),
829 'view_item' => __( 'View Order', 'learnpress' ),
830 'add_new' => __( 'Add New', 'learnpress' ),
831 'update_item' => __( 'Update Order', 'learnpress' ),
832 'search_items' => __( 'Search Orders', 'learnpress' ),
833 'not_found' => __( 'No order found', 'learnpress' ),
834 'not_found_in_trash' => __( 'No order found in Trash', 'learnpress' ),
835 ),
836 'public' => false,
837 'show_ui' => true,
838 'show_in_nav_menus' => false,
839 'show_in_admin_bar' => false,
840 'publicly_queryable' => false,
841 'show_in_menu' => 'learn_press',
842 'map_meta_cap' => true,
843 'capability_type' => LP_ORDER_CPT,
844 'hierarchical' => true,
845 'rewrite' => array(
846 'slug' => LP_ORDER_CPT,
847 'hierarchical' => true,
848 'with_front' => true,
849 ),
850 'supports' => array(
851 'title',
852 'custom-fields',
853 ),
854 );
855 }
856
857 /**
858 * Remove some unwanted metaboxes
859 */
860 public static function register_metabox() {
861 // Remove Publish metabox
862 remove_meta_box( 'submitdiv', LP_ORDER_CPT, 'side' );
863 remove_meta_box( 'commentstatusdiv', LP_ORDER_CPT, 'normal' );
864 }
865
866 // /**
867 // * Order details view.
868 // *
869 // * @param WP_Post $post
870 // */
871 // public static function order_details( $post ) {
872 // learn_press_admin_view( 'meta-boxes/order/details.php', array( 'order' => new LP_Order( $post ) ) );
873 // }
874
875 // /**
876 // * Order actions view.
877 // *
878 // * @param WP_Post $post
879 // */
880 // public static function order_actions( $post ) {
881 // learn_press_admin_view( 'meta-boxes/order/actions.php', array( 'order' => new LP_Order( $post ) ) );
882 // }
883
884 public function preparing_to_trash_order( $post_id ) {
885 if ( LP_ORDER_CPT != learn_press_get_post_type( $post_id ) ) {
886 return;
887 }
888 }
889
890 /**
891 * Register new post status for order
892 */
893 public function register_post_statues() {
894 $statuses = learn_press_get_register_order_statuses();
895 foreach ( $statuses as $status => $args ) {
896 register_post_status( $status, $args );
897 }
898 }
899
900 public static function instance() {
901 if ( ! self::$_instance ) {
902 self::$_instance = new self();
903 }
904
905 return self::$_instance;
906 }
907
908 /**
909 * Order export view.
910 *
911 * @param WP_Post $post
912 *
913 * @throws Exception
914 * @since 3.2.7.8
915 *
916 * @author hungkv
917 */
918 // public static function order_exports( $post ) {
919 // learn_press_admin_view( 'meta-boxes/order/exports-invoice.php', array( 'order' => new LP_Order( $post ) ) );
920 // }
921
922 /**
923 * Before post deleted
924 *
925 * @author tungnx
926 * @since 4.1.4
927 * @version 1.0.0
928 */
929 public function before_delete( int $order_id ) {
930 $lp_order_db = LP_Order_DB::getInstance();
931 $lp_user_items_db = LP_User_Items_DB::getInstance();
932
933 try {
934 $order = learn_press_get_order( $order_id );
935
936 if ( ! $order ) {
937 return;
938 }
939
940 $order_item_ids = $lp_order_db->get_order_item_ids( $order_id );
941
942 if ( empty( $order_item_ids ) ) {
943 return;
944 }
945
946 $user_ids = $order->get_users();
947
948 foreach ( $user_ids as $user_id ) {
949 delete_user_meta( $user_id, 'orders' );
950
951 foreach ( $order->get_item_ids() as $course_id ) {
952 // Check this order is the latest by user and course_id
953 $last_order_id = $lp_order_db->get_last_lp_order_id_of_user_course( $user_id, $course_id );
954 if ( $last_order_id && $last_order_id != $order->get_id() ) {
955 continue;
956 }
957
958 $lp_user_items_db->delete_user_items_old( $user_id, $course_id );
959 }
960 }
961
962 // Delete lp_order_item, lp_order_itemmeta
963 $filter_delete = new LP_Order_Filter();
964 $filter_delete->order_item_ids = $order_item_ids;
965 $lp_order_db->delete_order_item( $filter_delete );
966 $lp_order_db->delete_order_itemmeta( $filter_delete );
967 // End
968
969 // $this->remove_user_items_by_order_id( $order_id );
970
971 if ( ! empty( $data['child'] ) ) {
972 // $this->remove_child_orders( $data['child'] );
973 }
974 } catch ( Throwable $e ) {
975 error_log( $e->getMessage() . '>' . __FILE__ );
976 }
977 }
978
979 /**
980 * Action delete Order
981 *
982 * @param int $order_id
983 * @author tungnx
984 * @since 4.1.4
985 * @version 1.0.0
986 */
987 public function deleted_post( int $order_id ) {
988
989 }
990
991 public function meta_boxes() {
992 return array(
993 'order_details' => array(
994 'title' => esc_html__( 'Order Details', 'learnpress' ),
995 'callback' => function( $post ) {
996 learn_press_admin_view( 'meta-boxes/order/details.php', array( 'order' => new LP_Order( $post ) ) );
997 },
998 'context' => 'normal',
999 'priority' => 'high',
1000 ),
1001 'submitdiv' => array(
1002 'title' => esc_html__( 'Order Actions', 'learnpress' ),
1003 'callback' => function( $post ) {
1004 learn_press_admin_view( 'meta-boxes/order/actions.php', array( 'order' => new LP_Order( $post ) ) );
1005 },
1006 'context' => 'side',
1007 'priority' => 'high',
1008 ),
1009 'order_exports' => array(
1010 'title' => esc_html__( 'Order Exports', 'learnpress' ),
1011 'callback' => function( $post ) {
1012 learn_press_admin_view( 'meta-boxes/order/exports-invoice.php', array( 'order' => new LP_Order( $post ) ) );
1013 },
1014 'context' => 'side',
1015 'priority' => 'high',
1016 ),
1017 );
1018 }
1019 }
1020
1021 // end LP_Order_Post_Type
1022
1023 $order_post_type = LP_Order_Post_Type::instance();
1024
1025 // Todo: Nhamdv see to rewrite
1026 // $order_post_type
1027 // ->add_meta_box( 'order_details', esc_html__( 'Order Details', 'learnpress' ), 'order_details', 'normal', 'high' )
1028 // ->add_meta_box( 'submitdiv', esc_html__( 'Order Actions', 'learnpress' ), 'order_actions', 'side', 'high' )
1029 // ->add_meta_box( 'order_export', esc_html__( 'Order Exports', 'learnpress' ), 'order_exports', 'side', 'high' );
1030 }
1031